1 #ifndef DATE_TIME_TIME_RESOLUTION_TRAITS_HPP 2 #define DATE_TIME_TIME_RESOLUTION_TRAITS_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 <ctime> 13 #include <boost/cstdint.hpp> 14 #include <boost/date_time/time_defs.hpp> 15 #include <boost/date_time/int_adapter.hpp> 16 #include <boost/date_time/compiler_config.hpp> 17 18 namespace boost { 19 namespace date_time { 20 21 //! Simple function to calculate absolute value of a numeric type 22 template <typename T> 23 // JDG [7/6/02 made a template], 24 // moved here from time_duration.hpp 2003-Sept-4. absolute_value(T x)25 inline BOOST_CXX14_CONSTEXPR T absolute_value(T x) 26 { 27 return x < 0 ? -x : x; 28 } 29 30 //! traits struct for time_resolution_traits implementation type 31 struct time_resolution_traits_bi32_impl { 32 typedef boost::int32_t int_type; 33 typedef boost::int32_t impl_type; as_numberboost::date_time::time_resolution_traits_bi32_impl34 static BOOST_CXX14_CONSTEXPR int_type as_number(impl_type i){ return i;} 35 //! Used to determine if implemented type is int_adapter or int is_adaptedboost::date_time::time_resolution_traits_bi32_impl36 static BOOST_CXX14_CONSTEXPR bool is_adapted() { return false;} 37 }; 38 //! traits struct for time_resolution_traits implementation type 39 struct time_resolution_traits_adapted32_impl { 40 typedef boost::int32_t int_type; 41 typedef boost::date_time::int_adapter<boost::int32_t> impl_type; as_numberboost::date_time::time_resolution_traits_adapted32_impl42 static BOOST_CXX14_CONSTEXPR int_type as_number(impl_type i){ return i.as_number();} 43 //! Used to determine if implemented type is int_adapter or int is_adaptedboost::date_time::time_resolution_traits_adapted32_impl44 static BOOST_CXX14_CONSTEXPR bool is_adapted() { return true;} 45 }; 46 //! traits struct for time_resolution_traits implementation type 47 struct time_resolution_traits_bi64_impl { 48 typedef boost::int64_t int_type; 49 typedef boost::int64_t impl_type; as_numberboost::date_time::time_resolution_traits_bi64_impl50 static BOOST_CXX14_CONSTEXPR int_type as_number(impl_type i){ return i;} 51 //! Used to determine if implemented type is int_adapter or int is_adaptedboost::date_time::time_resolution_traits_bi64_impl52 static BOOST_CXX14_CONSTEXPR bool is_adapted() { return false;} 53 }; 54 //! traits struct for time_resolution_traits implementation type 55 struct time_resolution_traits_adapted64_impl { 56 typedef boost::int64_t int_type; 57 typedef boost::date_time::int_adapter<boost::int64_t> impl_type; as_numberboost::date_time::time_resolution_traits_adapted64_impl58 static BOOST_CXX14_CONSTEXPR int_type as_number(impl_type i){ return i.as_number();} 59 //! Used to determine if implemented type is int_adapter or int is_adaptedboost::date_time::time_resolution_traits_adapted64_impl60 static BOOST_CXX14_CONSTEXPR bool is_adapted() { return true;} 61 }; 62 63 // 64 // Note about var_type, which is used to define the variable that 65 // stores hours, minutes, and seconds values: 66 // 67 // In Boost 1.65.1 and earlier var_type was boost::int32_t which suffers 68 // the year 2038 problem. Binary serialization of posix_time uses 69 // 32-bit values, and uses serialization version 0. 70 // 71 // In Boost 1.66.0 the var_type changed to std::time_t, however 72 // binary serialization was not properly versioned, so on platforms 73 // where std::time_t is 32-bits, it remains compatible, however on 74 // platforms where std::time_t is 64-bits, binary serialization ingest 75 // will be incompatible with previous versions. Furthermore, binary 76 // serialized output from 1.66.0 will not be compatible with future 77 // versions. Yes, it's a mess. Static assertions were not present 78 // in the serialization code to protect against this possibility. 79 // 80 // In Boost 1.67.0 the var_type was changed to boost::int64_t, 81 // ensuring the output size is 64 bits, and the serialization version 82 // was bumped. Static assertions were added as well, protecting 83 // future changes in this area. 84 // 85 86 template<typename frac_sec_type, 87 time_resolutions res, 88 #if (defined(BOOST_MSVC) && (_MSC_VER < 1300)) 89 boost::int64_t resolution_adjust, 90 #else 91 typename frac_sec_type::int_type resolution_adjust, 92 #endif 93 unsigned short frac_digits, 94 typename var_type = boost::int64_t > // see note above 95 class time_resolution_traits { 96 public: 97 typedef typename frac_sec_type::int_type fractional_seconds_type; 98 typedef typename frac_sec_type::int_type tick_type; 99 typedef typename frac_sec_type::impl_type impl_type; 100 typedef var_type day_type; 101 typedef var_type hour_type; 102 typedef var_type min_type; 103 typedef var_type sec_type; 104 105 // bring in function from frac_sec_type traits structs as_number(impl_type i)106 static BOOST_CXX14_CONSTEXPR fractional_seconds_type as_number(impl_type i) 107 { 108 return frac_sec_type::as_number(i); 109 } is_adapted()110 static BOOST_CXX14_CONSTEXPR bool is_adapted() 111 { 112 return frac_sec_type::is_adapted(); 113 } 114 115 //Would like this to be frac_sec_type, but some compilers complain 116 #if (defined(BOOST_MSVC) && (_MSC_VER < 1300)) 117 BOOST_STATIC_CONSTANT(boost::int64_t, ticks_per_second = resolution_adjust); 118 #else 119 BOOST_STATIC_CONSTANT(fractional_seconds_type, ticks_per_second = resolution_adjust); 120 #endif 121 resolution()122 static BOOST_CXX14_CONSTEXPR time_resolutions resolution() 123 { 124 return res; 125 } num_fractional_digits()126 static BOOST_CXX14_CONSTEXPR unsigned short num_fractional_digits() 127 { 128 return frac_digits; 129 } res_adjust()130 static BOOST_CXX14_CONSTEXPR fractional_seconds_type res_adjust() 131 { 132 return resolution_adjust; 133 } 134 //! Any negative argument results in a negative tick_count to_tick_count(hour_type hours,min_type minutes,sec_type seconds,fractional_seconds_type fs)135 static BOOST_CXX14_CONSTEXPR tick_type to_tick_count(hour_type hours, 136 min_type minutes, 137 sec_type seconds, 138 fractional_seconds_type fs) 139 { 140 if(hours < 0 || minutes < 0 || seconds < 0 || fs < 0) 141 { 142 hours = absolute_value(hours); 143 minutes = absolute_value(minutes); 144 seconds = absolute_value(seconds); 145 fs = absolute_value(fs); 146 return static_cast<tick_type>(((((fractional_seconds_type(hours)*3600) 147 + (fractional_seconds_type(minutes)*60) 148 + seconds)*res_adjust()) + fs) * -1); 149 } 150 151 return static_cast<tick_type>((((fractional_seconds_type(hours)*3600) 152 + (fractional_seconds_type(minutes)*60) 153 + seconds)*res_adjust()) + fs); 154 } 155 156 }; 157 158 typedef time_resolution_traits<time_resolution_traits_adapted32_impl, milli, 1000, 3 > milli_res; 159 typedef time_resolution_traits<time_resolution_traits_adapted64_impl, micro, 1000000, 6 > micro_res; 160 typedef time_resolution_traits<time_resolution_traits_adapted64_impl, nano, 1000000000, 9 > nano_res; 161 162 163 } } //namespace date_time 164 165 166 167 #endif 168