191 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
		
		
			
		
	
	
			191 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
|  | //
 | ||
|  | // detail/chrono_time_traits.hpp
 | ||
|  | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | ||
|  | //
 | ||
|  | // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 | ||
|  | //
 | ||
|  | // Distributed under the Boost Software License, Version 1.0. (See accompanying
 | ||
|  | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 | ||
|  | //
 | ||
|  | 
 | ||
|  | #ifndef ASIO_DETAIL_CHRONO_TIME_TRAITS_HPP
 | ||
|  | #define ASIO_DETAIL_CHRONO_TIME_TRAITS_HPP
 | ||
|  | 
 | ||
|  | #if defined(_MSC_VER) && (_MSC_VER >= 1200)
 | ||
|  | # pragma once
 | ||
|  | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 | ||
|  | 
 | ||
|  | #include "asio/detail/cstdint.hpp"
 | ||
|  | 
 | ||
|  | #include "asio/detail/push_options.hpp"
 | ||
|  | 
 | ||
|  | namespace asio { | ||
|  | namespace detail { | ||
|  | 
 | ||
|  | // Helper template to compute the greatest common divisor.
 | ||
|  | template <int64_t v1, int64_t v2> | ||
|  | struct gcd { enum { value = gcd<v2, v1 % v2>::value }; }; | ||
|  | 
 | ||
|  | template <int64_t v1> | ||
|  | struct gcd<v1, 0> { enum { value = v1 }; }; | ||
|  | 
 | ||
|  | // Adapts std::chrono clocks for use with a deadline timer.
 | ||
|  | template <typename Clock, typename WaitTraits> | ||
|  | struct chrono_time_traits | ||
|  | { | ||
|  |   // The clock type.
 | ||
|  |   typedef Clock clock_type; | ||
|  | 
 | ||
|  |   // The duration type of the clock.
 | ||
|  |   typedef typename clock_type::duration duration_type; | ||
|  | 
 | ||
|  |   // The time point type of the clock.
 | ||
|  |   typedef typename clock_type::time_point time_type; | ||
|  | 
 | ||
|  |   // The period of the clock.
 | ||
|  |   typedef typename duration_type::period period_type; | ||
|  | 
 | ||
|  |   // Get the current time.
 | ||
|  |   static time_type now() | ||
|  |   { | ||
|  |     return clock_type::now(); | ||
|  |   } | ||
|  | 
 | ||
|  |   // Add a duration to a time.
 | ||
|  |   static time_type add(const time_type& t, const duration_type& d) | ||
|  |   { | ||
|  |     const time_type epoch; | ||
|  |     if (t >= epoch) | ||
|  |     { | ||
|  |       if ((time_type::max)() - t < d) | ||
|  |         return (time_type::max)(); | ||
|  |     } | ||
|  |     else // t < epoch
 | ||
|  |     { | ||
|  |       if (-(t - (time_type::min)()) > d) | ||
|  |         return (time_type::min)(); | ||
|  |     } | ||
|  | 
 | ||
|  |     return t + d; | ||
|  |   } | ||
|  | 
 | ||
|  |   // Subtract one time from another.
 | ||
|  |   static duration_type subtract(const time_type& t1, const time_type& t2) | ||
|  |   { | ||
|  |     const time_type epoch; | ||
|  |     if (t1 >= epoch) | ||
|  |     { | ||
|  |       if (t2 >= epoch) | ||
|  |       { | ||
|  |         return t1 - t2; | ||
|  |       } | ||
|  |       else if (t2 == (time_type::min)()) | ||
|  |       { | ||
|  |         return (duration_type::max)(); | ||
|  |       } | ||
|  |       else if ((time_type::max)() - t1 < epoch - t2) | ||
|  |       { | ||
|  |         return (duration_type::max)(); | ||
|  |       } | ||
|  |       else | ||
|  |       { | ||
|  |         return t1 - t2; | ||
|  |       } | ||
|  |     } | ||
|  |     else // t1 < epoch
 | ||
|  |     { | ||
|  |       if (t2 < epoch) | ||
|  |       { | ||
|  |         return t1 - t2; | ||
|  |       } | ||
|  |       else if (t1 == (time_type::min)()) | ||
|  |       { | ||
|  |         return (duration_type::min)(); | ||
|  |       } | ||
|  |       else if ((time_type::max)() - t2 < epoch - t1) | ||
|  |       { | ||
|  |         return (duration_type::min)(); | ||
|  |       } | ||
|  |       else | ||
|  |       { | ||
|  |         return -(t2 - t1); | ||
|  |       } | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   // Test whether one time is less than another.
 | ||
|  |   static bool less_than(const time_type& t1, const time_type& t2) | ||
|  |   { | ||
|  |     return t1 < t2; | ||
|  |   } | ||
|  | 
 | ||
|  |   // Implement just enough of the posix_time::time_duration interface to supply
 | ||
|  |   // what the timer_queue requires.
 | ||
|  |   class posix_time_duration | ||
|  |   { | ||
|  |   public: | ||
|  |     explicit posix_time_duration(const duration_type& d) | ||
|  |       : d_(d) | ||
|  |     { | ||
|  |     } | ||
|  | 
 | ||
|  |     int64_t ticks() const | ||
|  |     { | ||
|  |       return d_.count(); | ||
|  |     } | ||
|  | 
 | ||
|  |     int64_t total_seconds() const | ||
|  |     { | ||
|  |       return duration_cast<1, 1>(); | ||
|  |     } | ||
|  | 
 | ||
|  |     int64_t total_milliseconds() const | ||
|  |     { | ||
|  |       return duration_cast<1, 1000>(); | ||
|  |     } | ||
|  | 
 | ||
|  |     int64_t total_microseconds() const | ||
|  |     { | ||
|  |       return duration_cast<1, 1000000>(); | ||
|  |     } | ||
|  | 
 | ||
|  |   private: | ||
|  |     template <int64_t Num, int64_t Den> | ||
|  |     int64_t duration_cast() const | ||
|  |     { | ||
|  |       const int64_t num1 = period_type::num / gcd<period_type::num, Num>::value; | ||
|  |       const int64_t num2 = Num / gcd<period_type::num, Num>::value; | ||
|  | 
 | ||
|  |       const int64_t den1 = period_type::den / gcd<period_type::den, Den>::value; | ||
|  |       const int64_t den2 = Den / gcd<period_type::den, Den>::value; | ||
|  | 
 | ||
|  |       const int64_t num = num1 * den2; | ||
|  |       const int64_t den = num2 * den1; | ||
|  | 
 | ||
|  |       if (num == 1 && den == 1) | ||
|  |         return ticks(); | ||
|  |       else if (num != 1 && den == 1) | ||
|  |         return ticks() * num; | ||
|  |       else if (num == 1 && period_type::den != 1) | ||
|  |         return ticks() / den; | ||
|  |       else | ||
|  |         return ticks() * num / den; | ||
|  |     } | ||
|  | 
 | ||
|  |     duration_type d_; | ||
|  |   }; | ||
|  | 
 | ||
|  |   // Convert to POSIX duration type.
 | ||
|  |   static posix_time_duration to_posix_duration(const duration_type& d) | ||
|  |   { | ||
|  |     return posix_time_duration(WaitTraits::to_wait_duration(d)); | ||
|  |   } | ||
|  | }; | ||
|  | 
 | ||
|  | } // namespace detail
 | ||
|  | } // namespace asio
 | ||
|  | 
 | ||
|  | #include "asio/detail/pop_options.hpp"
 | ||
|  | 
 | ||
|  | #endif // ASIO_DETAIL_CHRONO_TIME_TRAITS_HPP
 |