Chris@16: #ifndef DATE_TIME_TIME_DURATION_HPP___ Chris@16: #define DATE_TIME_TIME_DURATION_HPP___ Chris@16: Chris@16: /* Copyright (c) 2002,2003 CrystalClear Software, Inc. Chris@16: * Use, modification and distribution is subject to the Chris@16: * Boost Software License, Version 1.0. (See accompanying Chris@16: * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) Chris@16: * Author: Jeff Garland, Bart Garst Chris@101: * $Date$ Chris@16: */ Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: namespace date_time { Chris@16: Chris@16: Chris@16: //! Represents some amount of elapsed time measure to a given resolution Chris@16: /*! This class represents a standard set of capabilities for all Chris@16: counted time durations. Time duration implementations should derive Chris@16: from this class passing their type as the first template parameter. Chris@16: This design allows the subclass duration types to provide custom Chris@16: construction policies or other custom features not provided here. Chris@16: Chris@16: @param T The subclass type Chris@16: @param rep_type The time resolution traits for this duration type. Chris@16: */ Chris@16: template Chris@16: class time_duration : private Chris@16: boost::less_than_comparable > Chris@16: /* dividable, addable, and subtractable operator templates Chris@16: * won't work with this class (MSVC++ 6.0). return type Chris@16: * from '+=' is different than expected return type Chris@16: * from '+'. multipliable probably wont work Chris@16: * either (haven't tried) */ Chris@16: { Chris@16: public: Chris@101: // A tag for type categorization. Can be used to detect Boost.DateTime duration types in generic code. Chris@101: typedef void _is_boost_date_time_duration; Chris@16: typedef T duration_type; //the subclass Chris@16: typedef rep_type traits_type; Chris@16: typedef typename rep_type::day_type day_type; Chris@16: typedef typename rep_type::hour_type hour_type; Chris@16: typedef typename rep_type::min_type min_type; Chris@16: typedef typename rep_type::sec_type sec_type; Chris@16: typedef typename rep_type::fractional_seconds_type fractional_seconds_type; Chris@16: typedef typename rep_type::tick_type tick_type; Chris@16: typedef typename rep_type::impl_type impl_type; Chris@16: Chris@16: time_duration() : ticks_(0) {} Chris@16: time_duration(hour_type hours_in, Chris@16: min_type minutes_in, Chris@16: sec_type seconds_in=0, Chris@16: fractional_seconds_type frac_sec_in = 0) : Chris@16: ticks_(rep_type::to_tick_count(hours_in,minutes_in,seconds_in,frac_sec_in)) Chris@16: {} Chris@16: // copy constructor required for dividable<> Chris@16: //! Construct from another time_duration (Copy constructor) Chris@16: time_duration(const time_duration& other) Chris@16: : ticks_(other.ticks_) Chris@16: {} Chris@16: //! Construct from special_values Chris@16: time_duration(special_values sv) : ticks_(impl_type::from_special(sv)) Chris@16: {} Chris@16: //! Returns smallest representable duration Chris@16: static duration_type unit() Chris@16: { Chris@16: return duration_type(0,0,0,1); Chris@16: } Chris@16: //! Return the number of ticks in a second Chris@16: static tick_type ticks_per_second() Chris@16: { Chris@16: return rep_type::res_adjust(); Chris@16: } Chris@16: //! Provide the resolution of this duration type Chris@16: static time_resolutions resolution() Chris@16: { Chris@16: return rep_type::resolution(); Chris@16: } Chris@16: //! Returns number of hours in the duration Chris@16: hour_type hours() const Chris@16: { Chris@16: return static_cast(ticks() / (3600*ticks_per_second())); Chris@16: } Chris@16: //! Returns normalized number of minutes Chris@16: min_type minutes() const Chris@16: { Chris@16: return static_cast((ticks() / (60*ticks_per_second())) % 60); Chris@16: } Chris@16: //! Returns normalized number of seconds (0..60) Chris@16: sec_type seconds() const Chris@16: { Chris@16: return static_cast((ticks()/ticks_per_second()) % 60); Chris@16: } Chris@16: //! Returns total number of seconds truncating any fractional seconds Chris@16: sec_type total_seconds() const Chris@16: { Chris@16: return static_cast(ticks() / ticks_per_second()); Chris@16: } Chris@16: //! Returns total number of milliseconds truncating any fractional seconds Chris@16: tick_type total_milliseconds() const Chris@16: { Chris@16: if (ticks_per_second() < 1000) { Chris@16: return ticks() * (static_cast(1000) / ticks_per_second()); Chris@16: } Chris@16: return ticks() / (ticks_per_second() / static_cast(1000)) ; Chris@16: } Chris@16: //! Returns total number of nanoseconds truncating any sub millisecond values Chris@16: tick_type total_nanoseconds() const Chris@16: { Chris@16: if (ticks_per_second() < 1000000000) { Chris@16: return ticks() * (static_cast(1000000000) / ticks_per_second()); Chris@16: } Chris@16: return ticks() / (ticks_per_second() / static_cast(1000000000)) ; Chris@16: } Chris@16: //! Returns total number of microseconds truncating any sub microsecond values Chris@16: tick_type total_microseconds() const Chris@16: { Chris@16: if (ticks_per_second() < 1000000) { Chris@16: return ticks() * (static_cast(1000000) / ticks_per_second()); Chris@16: } Chris@16: return ticks() / (ticks_per_second() / static_cast(1000000)) ; Chris@16: } Chris@16: //! Returns count of fractional seconds at given resolution Chris@16: fractional_seconds_type fractional_seconds() const Chris@16: { Chris@16: return (ticks() % ticks_per_second()); Chris@16: } Chris@16: //! Returns number of possible digits in fractional seconds Chris@16: static unsigned short num_fractional_digits() Chris@16: { Chris@16: return rep_type::num_fractional_digits(); Chris@16: } Chris@16: duration_type invert_sign() const Chris@16: { Chris@16: return duration_type(ticks_ * (-1)); Chris@16: } Chris@16: bool is_negative() const Chris@16: { Chris@16: return ticks_ < 0; Chris@16: } Chris@16: bool operator<(const time_duration& rhs) const Chris@16: { Chris@16: return ticks_ < rhs.ticks_; Chris@16: } Chris@16: bool operator==(const time_duration& rhs) const Chris@16: { Chris@16: return ticks_ == rhs.ticks_; Chris@16: } Chris@16: //! unary- Allows for time_duration td = -td1 Chris@16: duration_type operator-()const Chris@16: { Chris@16: return duration_type(ticks_ * (-1)); Chris@16: } Chris@16: duration_type operator-(const duration_type& d) const Chris@16: { Chris@16: return duration_type(ticks_ - d.ticks_); Chris@16: } Chris@16: duration_type operator+(const duration_type& d) const Chris@16: { Chris@16: return duration_type(ticks_ + d.ticks_); Chris@16: } Chris@16: duration_type operator/(int divisor) const Chris@16: { Chris@16: return duration_type(ticks_ / divisor); Chris@16: } Chris@16: duration_type operator-=(const duration_type& d) Chris@16: { Chris@16: ticks_ = ticks_ - d.ticks_; Chris@16: return duration_type(ticks_); Chris@16: } Chris@16: duration_type operator+=(const duration_type& d) Chris@16: { Chris@16: ticks_ = ticks_ + d.ticks_; Chris@16: return duration_type(ticks_); Chris@16: } Chris@16: //! Division operations on a duration with an integer. Chris@16: duration_type operator/=(int divisor) Chris@16: { Chris@16: ticks_ = ticks_ / divisor; Chris@16: return duration_type(ticks_); Chris@16: } Chris@16: //! Multiplication operations an a duration with an integer Chris@16: duration_type operator*(int rhs) const Chris@16: { Chris@16: return duration_type(ticks_ * rhs); Chris@16: } Chris@16: duration_type operator*=(int divisor) Chris@16: { Chris@16: ticks_ = ticks_ * divisor; Chris@16: return duration_type(ticks_); Chris@16: } Chris@16: tick_type ticks() const Chris@16: { Chris@16: return traits_type::as_number(ticks_); Chris@16: } Chris@16: Chris@16: //! Is ticks_ a special value? Chris@16: bool is_special()const Chris@16: { Chris@16: if(traits_type::is_adapted()) Chris@16: { Chris@16: return ticks_.is_special(); Chris@16: } Chris@16: else{ Chris@16: return false; Chris@16: } Chris@16: } Chris@16: //! Is duration pos-infinity Chris@16: bool is_pos_infinity()const Chris@16: { Chris@16: if(traits_type::is_adapted()) Chris@16: { Chris@16: return ticks_.is_pos_infinity(); Chris@16: } Chris@16: else{ Chris@16: return false; Chris@16: } Chris@16: } Chris@16: //! Is duration neg-infinity Chris@16: bool is_neg_infinity()const Chris@16: { Chris@16: if(traits_type::is_adapted()) Chris@16: { Chris@16: return ticks_.is_neg_infinity(); Chris@16: } Chris@16: else{ Chris@16: return false; Chris@16: } Chris@16: } Chris@16: //! Is duration not-a-date-time Chris@16: bool is_not_a_date_time()const Chris@16: { Chris@16: if(traits_type::is_adapted()) Chris@16: { Chris@16: return ticks_.is_nan(); Chris@16: } Chris@16: else{ Chris@16: return false; Chris@16: } Chris@16: } Chris@16: Chris@16: //! Used for special_values output Chris@16: impl_type get_rep()const Chris@16: { Chris@16: return ticks_; Chris@16: } Chris@16: Chris@16: protected: Chris@16: explicit time_duration(impl_type in) : ticks_(in) {} Chris@16: impl_type ticks_; Chris@16: }; Chris@16: Chris@16: Chris@16: Chris@16: //! Template for instantiating derived adjusting durations Chris@16: /* These templates are designed to work with multiples of Chris@16: * 10 for frac_of_second and resoultion adjustment Chris@16: */ Chris@16: template Chris@16: class subsecond_duration : public base_duration Chris@16: { Chris@16: public: Chris@16: typedef typename base_duration::impl_type impl_type; Chris@16: typedef typename base_duration::traits_type traits_type; Chris@16: Chris@16: private: Chris@16: // To avoid integer overflow we precompute the duration resolution conversion coefficient (ticket #3471) Chris@16: 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,\ Chris@16: "The base duration resolution must be a multiple of the subsecond duration resolution"); Chris@16: 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)); Chris@16: Chris@16: public: Chris@16: explicit subsecond_duration(boost::int64_t ss) : Chris@16: base_duration(impl_type(traits_type::ticks_per_second >= frac_of_second ? ss * adjustment_ratio : ss / adjustment_ratio)) Chris@16: { Chris@16: } Chris@16: }; Chris@16: Chris@16: Chris@16: Chris@16: } } //namespace date_time Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: #endif Chris@16: