Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:28:37

0001 //
0002 // detail/chrono_time_traits.hpp
0003 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
0006 //
0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 //
0010 
0011 #ifndef BOOST_ASIO_DETAIL_CHRONO_TIME_TRAITS_HPP
0012 #define BOOST_ASIO_DETAIL_CHRONO_TIME_TRAITS_HPP
0013 
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
0017 
0018 #include <boost/asio/detail/cstdint.hpp>
0019 
0020 #include <boost/asio/detail/push_options.hpp>
0021 
0022 namespace boost {
0023 namespace asio {
0024 namespace detail {
0025 
0026 // Helper template to compute the greatest common divisor.
0027 template <int64_t v1, int64_t v2>
0028 struct gcd { enum { value = gcd<v2, v1 % v2>::value }; };
0029 
0030 template <int64_t v1>
0031 struct gcd<v1, 0> { enum { value = v1 }; };
0032 
0033 // Adapts std::chrono clocks for use with a deadline timer.
0034 template <typename Clock, typename WaitTraits>
0035 struct chrono_time_traits
0036 {
0037   // The clock type.
0038   typedef Clock clock_type;
0039 
0040   // The duration type of the clock.
0041   typedef typename clock_type::duration duration_type;
0042 
0043   // The time point type of the clock.
0044   typedef typename clock_type::time_point time_type;
0045 
0046   // The period of the clock.
0047   typedef typename duration_type::period period_type;
0048 
0049   // Get the current time.
0050   static time_type now()
0051   {
0052     return clock_type::now();
0053   }
0054 
0055   // Add a duration to a time.
0056   static time_type add(const time_type& t, const duration_type& d)
0057   {
0058     const time_type epoch;
0059     if (t >= epoch)
0060     {
0061       if ((time_type::max)() - t < d)
0062         return (time_type::max)();
0063     }
0064     else // t < epoch
0065     {
0066       if (-(t - (time_type::min)()) > d)
0067         return (time_type::min)();
0068     }
0069 
0070     return t + d;
0071   }
0072 
0073   // Subtract one time from another.
0074   static duration_type subtract(const time_type& t1, const time_type& t2)
0075   {
0076     const time_type epoch;
0077     if (t1 >= epoch)
0078     {
0079       if (t2 >= epoch)
0080       {
0081         return t1 - t2;
0082       }
0083       else if (t2 == (time_type::min)())
0084       {
0085         return (duration_type::max)();
0086       }
0087       else if ((time_type::max)() - t1 < epoch - t2)
0088       {
0089         return (duration_type::max)();
0090       }
0091       else
0092       {
0093         return t1 - t2;
0094       }
0095     }
0096     else // t1 < epoch
0097     {
0098       if (t2 < epoch)
0099       {
0100         return t1 - t2;
0101       }
0102       else if (t1 == (time_type::min)())
0103       {
0104         return (duration_type::min)();
0105       }
0106       else if ((time_type::max)() - t2 < epoch - t1)
0107       {
0108         return (duration_type::min)();
0109       }
0110       else
0111       {
0112         return -(t2 - t1);
0113       }
0114     }
0115   }
0116 
0117   // Test whether one time is less than another.
0118   static bool less_than(const time_type& t1, const time_type& t2)
0119   {
0120     return t1 < t2;
0121   }
0122 
0123   // Implement just enough of the posix_time::time_duration interface to supply
0124   // what the timer_queue requires.
0125   class posix_time_duration
0126   {
0127   public:
0128     explicit posix_time_duration(const duration_type& d)
0129       : d_(d)
0130     {
0131     }
0132 
0133     int64_t ticks() const
0134     {
0135       return d_.count();
0136     }
0137 
0138     int64_t total_seconds() const
0139     {
0140       return duration_cast<1, 1>();
0141     }
0142 
0143     int64_t total_milliseconds() const
0144     {
0145       return duration_cast<1, 1000>();
0146     }
0147 
0148     int64_t total_microseconds() const
0149     {
0150       return duration_cast<1, 1000000>();
0151     }
0152 
0153   private:
0154     template <int64_t Num, int64_t Den>
0155     int64_t duration_cast() const
0156     {
0157       const int64_t num1 = period_type::num / gcd<period_type::num, Num>::value;
0158       const int64_t num2 = Num / gcd<period_type::num, Num>::value;
0159 
0160       const int64_t den1 = period_type::den / gcd<period_type::den, Den>::value;
0161       const int64_t den2 = Den / gcd<period_type::den, Den>::value;
0162 
0163       const int64_t num = num1 * den2;
0164       const int64_t den = num2 * den1;
0165 
0166       if (num == 1 && den == 1)
0167         return ticks();
0168       else if (num != 1 && den == 1)
0169         return ticks() * num;
0170       else if (num == 1 && period_type::den != 1)
0171         return ticks() / den;
0172       else
0173         return ticks() * num / den;
0174     }
0175 
0176     duration_type d_;
0177   };
0178 
0179   // Convert to POSIX duration type.
0180   static posix_time_duration to_posix_duration(const duration_type& d)
0181   {
0182     return posix_time_duration(WaitTraits::to_wait_duration(d));
0183   }
0184 };
0185 
0186 } // namespace detail
0187 } // namespace asio
0188 } // namespace boost
0189 
0190 #include <boost/asio/detail/pop_options.hpp>
0191 
0192 #endif // BOOST_ASIO_DETAIL_CHRONO_TIME_TRAITS_HPP