Line data Source code
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. 25 0 : inline T absolute_value(T x) 26 : { 27 0 : 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; 34 : static int_type as_number(impl_type i){ return i;} 35 : //! Used to determine if implemented type is int_adapter or int 36 : static 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; 42 : static int_type as_number(impl_type i){ return i.as_number();} 43 : //! Used to determine if implemented type is int_adapter or int 44 : static 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; 50 : static int_type as_number(impl_type i){ return i;} 51 : //! Used to determine if implemented type is int_adapter or int 52 : static 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; 58 0 : static int_type as_number(impl_type i){ return i.as_number();} 59 : //! Used to determine if implemented type is int_adapter or int 60 0 : static 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 106 0 : static fractional_seconds_type as_number(impl_type i) 107 : { 108 0 : return frac_sec_type::as_number(i); 109 : } 110 0 : static 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 : 122 : static time_resolutions resolution() 123 : { 124 : return res; 125 : } 126 0 : static unsigned short num_fractional_digits() 127 : { 128 : return frac_digits; 129 : } 130 0 : static fractional_seconds_type res_adjust() 131 : { 132 : return resolution_adjust; 133 : } 134 : //! Any negative argument results in a negative tick_count 135 0 : static tick_type to_tick_count(hour_type hours, 136 : min_type minutes, 137 : sec_type seconds, 138 : fractional_seconds_type fs) 139 : { 140 0 : if(hours < 0 || minutes < 0 || seconds < 0 || fs < 0) 141 : { 142 0 : hours = absolute_value(hours); 143 0 : minutes = absolute_value(minutes); 144 0 : seconds = absolute_value(seconds); 145 0 : fs = absolute_value(fs); 146 0 : return static_cast<tick_type>(((((fractional_seconds_type(hours)*3600) 147 0 : + (fractional_seconds_type(minutes)*60) 148 0 : + seconds)*res_adjust()) + fs) * -1); 149 : } 150 : 151 0 : return static_cast<tick_type>((((fractional_seconds_type(hours)*3600) 152 0 : + (fractional_seconds_type(minutes)*60) 153 0 : + 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