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