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