|
1 #ifndef DATE_TIME_TIME_DURATION_HPP___ |
|
2 #define DATE_TIME_TIME_DURATION_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 or http://www.boost.org/LICENSE-1.0) |
|
8 * Author: Jeff Garland, Bart Garst |
|
9 * $Date: 2006/03/20 13:29:15 $ |
|
10 */ |
|
11 |
|
12 #include "boost/operators.hpp" |
|
13 #include "boost/date_time/time_defs.hpp" |
|
14 #include "boost/date_time/special_defs.hpp" |
|
15 #include "boost/date_time/compiler_config.hpp" |
|
16 |
|
17 namespace boost { |
|
18 namespace date_time { |
|
19 |
|
20 |
|
21 //! Represents some amount of elapsed time measure to a given resolution |
|
22 /*! This class represents a standard set of capabilities for all |
|
23 counted time durations. Time duration implementations should derive |
|
24 from this class passing their type as the first template parameter. |
|
25 This design allows the subclass duration types to provide custom |
|
26 construction policies or other custom features not provided here. |
|
27 |
|
28 @param T The subclass type |
|
29 @param rep_type The time resolution traits for this duration type. |
|
30 */ |
|
31 template<class T, typename rep_type> |
|
32 class time_duration : private |
|
33 boost::less_than_comparable<T |
|
34 , boost::equality_comparable<T |
|
35 > > |
|
36 /* dividable, addable, and subtractable operator templates |
|
37 * won't work with this class (MSVC++ 6.0). return type |
|
38 * from '+=' is different than expected return type |
|
39 * from '+'. multipliable probably wont work |
|
40 * either (haven't tried) */ |
|
41 { |
|
42 public: |
|
43 typedef T duration_type; //the subclass |
|
44 typedef rep_type traits_type; |
|
45 typedef typename rep_type::day_type day_type; |
|
46 typedef typename rep_type::hour_type hour_type; |
|
47 typedef typename rep_type::min_type min_type; |
|
48 typedef typename rep_type::sec_type sec_type; |
|
49 typedef typename rep_type::fractional_seconds_type fractional_seconds_type; |
|
50 typedef typename rep_type::tick_type tick_type; |
|
51 typedef typename rep_type::impl_type impl_type; |
|
52 |
|
53 time_duration() : ticks_(0) {} |
|
54 time_duration(hour_type hours_in, |
|
55 min_type minutes_in, |
|
56 sec_type seconds_in=0, |
|
57 fractional_seconds_type frac_sec_in = 0) : |
|
58 ticks_(rep_type::to_tick_count(hours_in,minutes_in,seconds_in,frac_sec_in)) |
|
59 {} |
|
60 // copy constructor required for dividable<> |
|
61 //! Construct from another time_duration (Copy constructor) |
|
62 time_duration(const time_duration<T, rep_type>& other) |
|
63 : ticks_(other.ticks_) |
|
64 {} |
|
65 //! Construct from special_values |
|
66 time_duration(special_values sv) : ticks_(impl_type::from_special(sv)) |
|
67 {} |
|
68 //! Returns smallest representable duration |
|
69 static duration_type unit() |
|
70 { |
|
71 return duration_type(0,0,0,1); |
|
72 } |
|
73 //! Return the number of ticks in a second |
|
74 static tick_type ticks_per_second() |
|
75 { |
|
76 return rep_type::res_adjust(); |
|
77 } |
|
78 //! Provide the resolution of this duration type |
|
79 static time_resolutions resolution() |
|
80 { |
|
81 return rep_type::resolution(); |
|
82 } |
|
83 //! Returns number of hours in the duration |
|
84 hour_type hours() const |
|
85 { |
|
86 return static_cast<hour_type>(ticks() / (3600*ticks_per_second())); |
|
87 } |
|
88 //! Returns normalized number of minutes |
|
89 min_type minutes() const |
|
90 { |
|
91 return static_cast<min_type>((ticks() / (60*ticks_per_second())) % 60); |
|
92 } |
|
93 //! Returns normalized number of seconds (0..60) |
|
94 sec_type seconds() const |
|
95 { |
|
96 return static_cast<sec_type>((ticks()/ticks_per_second()) % 60); |
|
97 } |
|
98 //! Returns total number of seconds truncating any fractional seconds |
|
99 sec_type total_seconds() const |
|
100 { |
|
101 return static_cast<sec_type>(ticks() / ticks_per_second()); |
|
102 } |
|
103 //! Returns total number of milliseconds truncating any fractional seconds |
|
104 tick_type total_milliseconds() const |
|
105 { |
|
106 if (ticks_per_second() < 1000) { |
|
107 return ticks() * (static_cast<tick_type>(1000) / ticks_per_second()); |
|
108 } |
|
109 return ticks() / (ticks_per_second() / static_cast<tick_type>(1000)) ; |
|
110 } |
|
111 //! Returns total number of nanoseconds truncating any sub millisecond values |
|
112 tick_type total_nanoseconds() const |
|
113 { |
|
114 if (ticks_per_second() < 1000000000) { |
|
115 return ticks() * (static_cast<tick_type>(1000000000) / ticks_per_second()); |
|
116 } |
|
117 return ticks() / (ticks_per_second() / static_cast<tick_type>(1000000000)) ; |
|
118 } |
|
119 //! Returns total number of microseconds truncating any sub microsecond values |
|
120 tick_type total_microseconds() const |
|
121 { |
|
122 if (ticks_per_second() < 1000000) { |
|
123 return ticks() * (static_cast<tick_type>(1000000) / ticks_per_second()); |
|
124 } |
|
125 return ticks() / (ticks_per_second() / static_cast<tick_type>(1000000)) ; |
|
126 } |
|
127 //! Returns count of fractional seconds at given resolution |
|
128 fractional_seconds_type fractional_seconds() const |
|
129 { |
|
130 return (ticks() % ticks_per_second()); |
|
131 } |
|
132 //! Returns number of possible digits in fractional seconds |
|
133 static unsigned short num_fractional_digits() |
|
134 { |
|
135 return rep_type::num_fractional_digits(); |
|
136 } |
|
137 duration_type invert_sign() const |
|
138 { |
|
139 return duration_type(ticks_ * (-1)); |
|
140 } |
|
141 bool is_negative() const |
|
142 { |
|
143 return ticks_ < 0; |
|
144 } |
|
145 bool operator<(const time_duration& rhs) const |
|
146 { |
|
147 return ticks_ < rhs.ticks_; |
|
148 } |
|
149 bool operator==(const time_duration& rhs) const |
|
150 { |
|
151 return ticks_ == rhs.ticks_; |
|
152 } |
|
153 //! unary- Allows for time_duration td = -td1 |
|
154 duration_type operator-()const |
|
155 { |
|
156 return duration_type(ticks_ * (-1)); |
|
157 } |
|
158 duration_type operator-(const duration_type& d) const |
|
159 { |
|
160 return duration_type(ticks_ - d.ticks_); |
|
161 } |
|
162 duration_type operator+(const duration_type& d) const |
|
163 { |
|
164 return duration_type(ticks_ + d.ticks_); |
|
165 } |
|
166 duration_type operator/(int divisor) const |
|
167 { |
|
168 return duration_type(ticks_ / divisor); |
|
169 } |
|
170 duration_type operator-=(const duration_type& d) |
|
171 { |
|
172 ticks_ = ticks_ - d.ticks_; |
|
173 return duration_type(ticks_); |
|
174 } |
|
175 duration_type operator+=(const duration_type& d) |
|
176 { |
|
177 ticks_ = ticks_ + d.ticks_; |
|
178 return duration_type(ticks_); |
|
179 } |
|
180 //! Division operations on a duration with an integer. |
|
181 duration_type operator/=(int divisor) |
|
182 { |
|
183 ticks_ = ticks_ / divisor; |
|
184 return duration_type(ticks_); |
|
185 } |
|
186 //! Multiplication operations an a duration with an integer |
|
187 duration_type operator*(int rhs) const |
|
188 { |
|
189 return duration_type(ticks_ * rhs); |
|
190 } |
|
191 duration_type operator*=(int divisor) |
|
192 { |
|
193 ticks_ = ticks_ * divisor; |
|
194 return duration_type(ticks_); |
|
195 } |
|
196 tick_type ticks() const |
|
197 { |
|
198 return traits_type::as_number(ticks_); |
|
199 } |
|
200 |
|
201 //! Is ticks_ a special value? |
|
202 bool is_special()const |
|
203 { |
|
204 if(traits_type::is_adapted()) |
|
205 { |
|
206 return ticks_.is_special(); |
|
207 } |
|
208 else{ |
|
209 return false; |
|
210 } |
|
211 } |
|
212 //! Is duration pos-infinity |
|
213 bool is_pos_infinity()const |
|
214 { |
|
215 if(traits_type::is_adapted()) |
|
216 { |
|
217 return ticks_.is_pos_infinity(); |
|
218 } |
|
219 else{ |
|
220 return false; |
|
221 } |
|
222 } |
|
223 //! Is duration neg-infinity |
|
224 bool is_neg_infinity()const |
|
225 { |
|
226 if(traits_type::is_adapted()) |
|
227 { |
|
228 return ticks_.is_neg_infinity(); |
|
229 } |
|
230 else{ |
|
231 return false; |
|
232 } |
|
233 } |
|
234 //! Is duration not-a-date-time |
|
235 bool is_not_a_date_time()const |
|
236 { |
|
237 if(traits_type::is_adapted()) |
|
238 { |
|
239 return ticks_.is_nan(); |
|
240 } |
|
241 else{ |
|
242 return false; |
|
243 } |
|
244 } |
|
245 |
|
246 //! Used for special_values output |
|
247 impl_type get_rep()const |
|
248 { |
|
249 return ticks_; |
|
250 } |
|
251 |
|
252 protected: |
|
253 explicit time_duration(impl_type in) : ticks_(in) {}; |
|
254 impl_type ticks_; |
|
255 }; |
|
256 |
|
257 |
|
258 |
|
259 //! Template for instantiating derived adjusting durations |
|
260 /* These templates are designed to work with multiples of |
|
261 * 10 for frac_of_second and resoultion adjustment |
|
262 */ |
|
263 template<class base_duration, boost::int64_t frac_of_second> |
|
264 class subsecond_duration : public base_duration |
|
265 { |
|
266 public: |
|
267 typedef typename base_duration::traits_type traits_type; |
|
268 explicit subsecond_duration(boost::int64_t ss) : |
|
269 base_duration(0,0,0,ss*traits_type::res_adjust()/frac_of_second) |
|
270 {} |
|
271 }; |
|
272 |
|
273 |
|
274 |
|
275 } } //namespace date_time |
|
276 |
|
277 |
|
278 |
|
279 |
|
280 #endif |
|
281 |