1#ifndef DATE_TIME_TIME_SYSTEM_COUNTED_HPP
2#define DATE_TIME_TIME_SYSTEM_COUNTED_HPP
3
4/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
5 * Use, modification and distribution is subject to the
6 * Boost Software License, Version 1.0. (See accompanying
7 * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
8 * Author: Jeff Garland, Bart Garst
9 * $Date$
10 */
11
12
13#include <boost/date_time/compiler_config.hpp>
14#include <boost/date_time/time_defs.hpp>
15#include <boost/date_time/special_defs.hpp>
16#include <string>
17
18
19namespace boost {
20namespace date_time {
21
22 //! Time representation that uses a single integer count
23 template<class config>
24 struct counted_time_rep
25 {
26 typedef typename config::int_type int_type;
27 typedef typename config::date_type date_type;
28 typedef typename config::impl_type impl_type;
29 typedef typename date_type::duration_type date_duration_type;
30 typedef typename date_type::calendar_type calendar_type;
31 typedef typename date_type::ymd_type ymd_type;
32 typedef typename config::time_duration_type time_duration_type;
33 typedef typename config::resolution_traits resolution_traits;
34
35 BOOST_CXX14_CONSTEXPR
36 counted_time_rep(const date_type& d, const time_duration_type& time_of_day)
37 : time_count_(1)
38 {
39 if(d.is_infinity() || d.is_not_a_date() || time_of_day.is_special()) {
40 time_count_ = time_of_day.get_rep() + d.day_count();
41 //std::cout << time_count_ << std::endl;
42 }
43 else {
44 time_count_ = (d.day_number() * frac_sec_per_day()) + time_of_day.ticks();
45 }
46 }
47 BOOST_CXX14_CONSTEXPR
48 explicit counted_time_rep(int_type count) :
49 time_count_(count)
50 {}
51 BOOST_CXX14_CONSTEXPR
52 explicit counted_time_rep(impl_type count) :
53 time_count_(count)
54 {}
55 BOOST_CXX14_CONSTEXPR
56 date_type date() const
57 {
58 if(time_count_.is_special()) {
59 return date_type(time_count_.as_special());
60 }
61 else {
62 typename calendar_type::date_int_type dc = static_cast<typename calendar_type::date_int_type>(day_count());
63 //std::cout << "time_rep here:" << dc << std::endl;
64 ymd_type ymd = calendar_type::from_day_number(dc);
65 return date_type(ymd);
66 }
67 }
68 //int_type day_count() const
69 BOOST_CXX14_CONSTEXPR
70 unsigned long day_count() const
71 {
72 /* resolution_traits::as_number returns a boost::int64_t &
73 * frac_sec_per_day is also a boost::int64_t so, naturally,
74 * the division operation returns a boost::int64_t.
75 * The static_cast to an unsigned long is ok (results in no data loss)
76 * because frac_sec_per_day is either the number of
77 * microseconds per day, or the number of nanoseconds per day.
78 * Worst case scenario: resolution_traits::as_number returns the
79 * maximum value an int64_t can hold and frac_sec_per_day
80 * is microseconds per day (lowest possible value).
81 * The division operation will then return a value of 106751991 -
82 * easily fitting in an unsigned long.
83 */
84 return static_cast<unsigned long>(resolution_traits::as_number(time_count_) / frac_sec_per_day());
85 }
86 BOOST_CXX14_CONSTEXPR int_type time_count() const
87 {
88 return resolution_traits::as_number(time_count_);
89 }
90 BOOST_CXX14_CONSTEXPR int_type tod() const
91 {
92 return resolution_traits::as_number(time_count_) % frac_sec_per_day();
93 }
94 static BOOST_CXX14_CONSTEXPR int_type frac_sec_per_day()
95 {
96 int_type seconds_per_day = 60*60*24;
97 int_type fractional_sec_per_sec(resolution_traits::res_adjust());
98 return seconds_per_day*fractional_sec_per_sec;
99 }
100 BOOST_CXX14_CONSTEXPR bool is_pos_infinity()const
101 {
102 return impl_type::is_pos_inf(time_count_.as_number());
103 }
104 BOOST_CXX14_CONSTEXPR bool is_neg_infinity()const
105 {
106 return impl_type::is_neg_inf(time_count_.as_number());
107 }
108 BOOST_CXX14_CONSTEXPR bool is_not_a_date_time()const
109 {
110 return impl_type::is_not_a_number(time_count_.as_number());
111 }
112 BOOST_CXX14_CONSTEXPR bool is_special()const
113 {
114 return time_count_.is_special();
115 }
116 BOOST_CXX14_CONSTEXPR impl_type get_rep()const
117 {
118 return time_count_;
119 }
120 private:
121 impl_type time_count_;
122 };
123
124 //! An unadjusted time system implementation.
125 template<class time_rep>
126 class counted_time_system
127 {
128 public:
129 typedef time_rep time_rep_type;
130 typedef typename time_rep_type::impl_type impl_type;
131 typedef typename time_rep_type::time_duration_type time_duration_type;
132 typedef typename time_duration_type::fractional_seconds_type fractional_seconds_type;
133 typedef typename time_rep_type::date_type date_type;
134 typedef typename time_rep_type::date_duration_type date_duration_type;
135
136
137 template<class T> static BOOST_CXX14_CONSTEXPR void unused_var(const T&) {}
138
139 static BOOST_CXX14_CONSTEXPR
140 time_rep_type get_time_rep(const date_type& day,
141 const time_duration_type& tod,
142 date_time::dst_flags dst=not_dst)
143 {
144 unused_var(dst);
145 return time_rep_type(day, tod);
146 }
147
148 static BOOST_CXX14_CONSTEXPR time_rep_type get_time_rep(special_values sv)
149 {
150 switch (sv) {
151 case not_a_date_time:
152 return time_rep_type(date_type(not_a_date_time),
153 time_duration_type(not_a_date_time));
154 case pos_infin:
155 return time_rep_type(date_type(pos_infin),
156 time_duration_type(pos_infin));
157 case neg_infin:
158 return time_rep_type(date_type(neg_infin),
159 time_duration_type(neg_infin));
160 case max_date_time: {
161 time_duration_type td = time_duration_type(24,0,0,0) - time_duration_type(0,0,0,1);
162 return time_rep_type(date_type(max_date_time), td);
163 }
164 case min_date_time:
165 return time_rep_type(date_type(min_date_time), time_duration_type(0,0,0,0));
166
167 default:
168 return time_rep_type(date_type(not_a_date_time),
169 time_duration_type(not_a_date_time));
170
171 }
172
173 }
174
175 static BOOST_CXX14_CONSTEXPR date_type
176 get_date(const time_rep_type& val)
177 {
178 return val.date();
179 }
180 static BOOST_CXX14_CONSTEXPR
181 time_duration_type get_time_of_day(const time_rep_type& val)
182 {
183 if(val.is_special()) {
184 return time_duration_type(val.get_rep().as_special());
185 }
186 else{
187 return time_duration_type(0,0,0,val.tod());
188 }
189 }
190 static std::string zone_name(const time_rep_type&)
191 {
192 return "";
193 }
194 static BOOST_CXX14_CONSTEXPR bool is_equal(const time_rep_type& lhs, const time_rep_type& rhs)
195 {
196 return (lhs.time_count() == rhs.time_count());
197 }
198 static BOOST_CXX14_CONSTEXPR
199 bool is_less(const time_rep_type& lhs, const time_rep_type& rhs)
200 {
201 return (lhs.time_count() < rhs.time_count());
202 }
203 static BOOST_CXX14_CONSTEXPR
204 time_rep_type add_days(const time_rep_type& base,
205 const date_duration_type& dd)
206 {
207 if(base.is_special() || dd.is_special()) {
208 return(time_rep_type(base.get_rep() + dd.get_rep()));
209 }
210 else {
211 return time_rep_type(base.time_count() + (dd.days() * time_rep_type::frac_sec_per_day()));
212 }
213 }
214 static BOOST_CXX14_CONSTEXPR
215 time_rep_type subtract_days(const time_rep_type& base,
216 const date_duration_type& dd)
217 {
218 if(base.is_special() || dd.is_special()) {
219 return(time_rep_type(base.get_rep() - dd.get_rep()));
220 }
221 else{
222 return time_rep_type(base.time_count() - (dd.days() * time_rep_type::frac_sec_per_day()));
223 }
224 }
225 static BOOST_CXX14_CONSTEXPR
226 time_rep_type subtract_time_duration(const time_rep_type& base,
227 const time_duration_type& td)
228 {
229 if(base.is_special() || td.is_special()) {
230 return(time_rep_type(base.get_rep() - td.get_rep()));
231 }
232 else {
233 return time_rep_type(base.time_count() - td.ticks());
234 }
235 }
236 static BOOST_CXX14_CONSTEXPR
237 time_rep_type add_time_duration(const time_rep_type& base,
238 time_duration_type td)
239 {
240 if(base.is_special() || td.is_special()) {
241 return(time_rep_type(base.get_rep() + td.get_rep()));
242 }
243 else {
244 return time_rep_type(base.time_count() + td.ticks());
245 }
246 }
247 static BOOST_CXX14_CONSTEXPR
248 time_duration_type subtract_times(const time_rep_type& lhs,
249 const time_rep_type& rhs)
250 {
251 if(lhs.is_special() || rhs.is_special()) {
252 return(time_duration_type(
253 impl_type::to_special((lhs.get_rep() - rhs.get_rep()).as_number())));
254 }
255 else {
256 fractional_seconds_type fs = lhs.time_count() - rhs.time_count();
257 return time_duration_type(0,0,0,fs);
258 }
259 }
260
261 };
262
263
264} } //namespace date_time
265
266
267
268#endif
269
270

source code of include/boost/date_time/time_system_counted.hpp