From a3e8f399c455d184a6fd774330927dbb5fa36c87 Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Thu, 30 Nov 2017 15:40:37 -0500 Subject: [PATCH] ifdef out clock_cast for VC-2017 and earlier * Clients report it can't handle the C++11 * Triggered to be enabled on VC-number-next * Deprecated API (to_xxx_time) rewritten to be independent of clock_cast. * Whitespace changes to bring column length down to 90. --- include/date/tz.h | 425 ++++++++++++++++++++++++++-------------------- 1 file changed, 241 insertions(+), 184 deletions(-) diff --git a/include/date/tz.h b/include/date/tz.h index 960bd7f..280a598 100644 --- a/include/date/tz.h +++ b/include/date/tz.h @@ -2197,225 +2197,282 @@ from_stream(std::basic_istream& is, const CharT* fmt, return is; } -template +#if !defined(_MSC_VER) || _MSC_VER > 1912 + +// clock_time_conversion + +template struct clock_time_conversion {}; -template<> +template <> struct clock_time_conversion { - template - auto operator()(const sys_time& st) const - -> sys_time - { - return st; - } + template + sys_time + operator()(const sys_time& st) const + { + return st; + } }; -template<> +template <> struct clock_time_conversion { - template - auto operator()(const utc_time& ut) const - -> utc_time - { - return ut; - } + template + utc_time + operator()(const utc_time& ut) const + { + return ut; + } }; -template<> +template <> struct clock_time_conversion { - template - utc_time::type> - operator()(const sys_time& st) const - { - return utc_clock::from_sys(st); - } + template + utc_time::type> + operator()(const sys_time& st) const + { + return utc_clock::from_sys(st); + } }; -template<> +template <> struct clock_time_conversion { - template - sys_time::type> - operator()(const utc_time& ut) const - { - return utc_clock::to_sys(ut); - } + template + sys_time::type> + operator()(const utc_time& ut) const + { + return utc_clock::to_sys(ut); + } }; -template +template struct clock_time_conversion { - template - auto operator()(const std::chrono::time_point& tp) const - -> std::chrono::time_point - { - return tp; - } + template + std::chrono::time_point + operator()(const std::chrono::time_point& tp) const + { + return tp; + } }; namespace ctc_detail { - //Check if TimePoint is time for given clock, - //if not emits hard error - template - struct return_clock_time - { - using clock_time_point = std::chrono::time_point; - static_assert(std::is_same::value, "time point with appropariate clock shall be returned"); - using type = TimePoint; - }; - // Check if Clock has to_sys method accepting TimePoint with given duration const& and returning sys_time - // If so has nested type member equal to return type to_sys. - template - struct return_to_sys - {}; +template + using time_point = std::chrono::time_point; - template - struct return_to_sys const&>()), void())> - : return_clock_time const&>()))> - {}; +using std::declval; +using std::chrono::system_clock; - // Similiar to above - template - struct return_from_sys - {}; - - template - struct return_from_sys const&>()), void())> - : return_clock_time const&>()))> - {}; - - // Similiar to above - template - struct return_to_utc - {}; - - template - struct return_to_utc const&>()), void())> - : return_clock_time const&>()))> - {}; - - // Similiar to above - template - struct return_from_utc - {}; - - template - struct return_from_utc const&>()), void())> - : return_clock_time const&>()))> - {}; -} - -template -struct clock_time_conversion +//Check if TimePoint is time for given clock, +//if not emits hard error +template +struct return_clock_time { - template - auto operator()(const std::chrono::time_point& tp) const - -> typename ctc_detail::return_to_sys::type - { - return SourceClock::to_sys(tp); - } + using clock_time_point = time_point; + using type = TimePoint; + + static_assert(std::is_same::value, + "time point with appropariate clock shall be returned"); }; -template -struct clock_time_conversion +// Check if Clock has to_sys method accepting TimePoint with given duration const& and +// returning sys_time. If so has nested type member equal to return type to_sys. +template +struct return_to_sys +{}; + +template +struct return_to_sys + < + Clock, Duration, + decltype(Clock::to_sys(declval const&>()), void()) + > + : return_clock_time + < + system_clock, + decltype(Clock::to_sys(declval const&>())) + > +{}; + +// Similiar to above +template +struct return_from_sys +{}; + +template +struct return_from_sys + < + Clock, Duration, + decltype(Clock::from_sys(declval const&>()), + void()) + > + : return_clock_time + < + Clock, + decltype(Clock::from_sys(declval const&>())) + > +{}; + +// Similiar to above +template +struct return_to_utc +{}; + +template +struct return_to_utc + < + Clock, Duration, + decltype(Clock::to_utc(declval const&>()), void()) + > + : return_clock_time + < + utc_clock, + decltype(Clock::to_utc(declval const&>()))> +{}; + +// Similiar to above +template +struct return_from_utc +{}; + +template +struct return_from_utc + < + Clock, Duration, + decltype(Clock::from_utc(declval const&>()), + void()) + > + : return_clock_time + < + Clock, + decltype(Clock::from_utc(declval const&>())) + > +{}; + +} // namespace ctc_detail + +template +struct clock_time_conversion { - template - auto operator()(const sys_time& st) const - -> typename ctc_detail::return_from_sys::type - { - return DestClock::from_sys(st); - } + template + typename ctc_detail::return_to_sys::type + operator()(const std::chrono::time_point& tp) const + { + return SrcClock::to_sys(tp); + } }; -template -struct clock_time_conversion +template +struct clock_time_conversion { - template - auto operator()(const std::chrono::time_point& tp) const - -> typename ctc_detail::return_to_utc::type - { - return SourceClock::to_utc(tp); - } + template + typename ctc_detail::return_from_sys::type + operator()(const sys_time& st) const + { + return DstClock::from_sys(st); + } }; -template -struct clock_time_conversion +template +struct clock_time_conversion { - template - auto operator()(const utc_time& ut) const - -> typename ctc_detail::return_from_utc::type - { - return DestClock::from_utc(ut); - } + template + typename ctc_detail::return_to_utc::type + operator()(const std::chrono::time_point& tp) const + { + return SrcClock::to_utc(tp); + } +}; + +template +struct clock_time_conversion +{ + template + typename ctc_detail::return_from_utc::type + operator()(const utc_time& ut) const + { + return DstClock::from_utc(ut); + } }; namespace clock_cast_detail { - template - auto conv_clock(const std::chrono::time_point& st) - -> decltype(std::declval>()(st)) - { - return clock_time_conversion{}(st); - } - //direct triat conversion, 2nd candidate - template - auto cc_impl(const std::chrono::time_point& st, - const std::chrono::time_point* /* 1st */) - -> decltype(conv_clock(st)) - { - return conv_clock(st); - } +template + using time_point = std::chrono::time_point; +using std::chrono::system_clock; - //conversion trought sys, 3rd candidate - template - auto cc_impl(const std::chrono::time_point& st, - const void* /* 2nd */) - -> decltype(conv_clock(conv_clock(st))) - { - return conv_clock(conv_clock(st)); - } - - //conversion trought utc, 3rd candidate - template - auto cc_impl(const std::chrono::time_point& st, - const void* /* 2nd */) - -> decltype(conv_clock(conv_clock(st))) - { - return conv_clock(conv_clock(st)); - } - - //conversion trought sys and utc, 4th candidate - template - auto cc_impl(const std::chrono::time_point& st, - ... /* 3rd */) - -> decltype(conv_clock(conv_clock(conv_clock(st)))) - { - return conv_clock(conv_clock(conv_clock(st))); - } - - //conversion trought utc and sys, 4th candidate - template - auto cc_impl(const std::chrono::time_point& st, - ... /* 3rd */) - -> decltype(conv_clock(conv_clock(conv_clock(st)))) - { - return conv_clock(conv_clock(conv_clock(st))); - } -} - -template -auto clock_cast(const std::chrono::time_point& st) - -> decltype(clock_cast_detail::cc_impl(st, &st)) +template +auto +conv_clock(const time_point& t) + -> decltype(std::declval>()(t)) { - return clock_cast_detail::cc_impl(st, &st); + return clock_time_conversion{}(t); } +//direct trait conversion, 1st candidate +template +auto +cc_impl(const time_point& t, const time_point*) + -> decltype(conv_clock(t)) +{ + return conv_clock(t); +} + +//conversion through sys, 2nd candidate +template +auto +cc_impl(const time_point& t, const void*) + -> decltype(conv_clock(conv_clock(t))) +{ + return conv_clock(conv_clock(t)); +} + +//conversion through utc, 2nd candidate +template +auto +cc_impl(const time_point& t, const void*) + -> decltype(conv_clock(conv_clock(t))) +{ + return conv_clock(conv_clock(t)); +} + +//conversion through sys and utc, 3rd candidate +template +auto +cc_impl(const time_point& t, ...) + -> decltype(conv_clock(conv_clock(conv_clock(t)))) +{ + return conv_clock(conv_clock(conv_clock(t))); +} + +//conversion through utc and sys, 3rd candidate +template +auto +cc_impl(const time_point& t, ...) + -> decltype(conv_clock(conv_clock(conv_clock(t)))) +{ + return conv_clock(conv_clock(conv_clock(t))); +} + +} // namespace clock_cast_detail + +template +auto +clock_cast(const std::chrono::time_point& tp) + -> decltype(clock_cast_detail::cc_impl(tp, &tp)) +{ + return clock_cast_detail::cc_impl(tp, &tp); +} + +#endif // !defined(_MSC_VER) || _MSC_VER > 1912 + // Deprecated API template @@ -2423,7 +2480,7 @@ inline sys_time::type> to_sys_time(const utc_time& t) { - return clock_cast(t); + return utc_clock::to_sys(t); } template @@ -2431,7 +2488,7 @@ inline sys_time::type> to_sys_time(const tai_time& t) { - return clock_cast(t); + return utc_clock::to_sys(tai_clock::to_utc(t)); } template @@ -2439,7 +2496,7 @@ inline sys_time::type> to_sys_time(const gps_time& t) { - return clock_cast(t); + return utc_clock::to_sys(gps_clock::to_utc(t)); } @@ -2448,7 +2505,7 @@ inline utc_time::type> to_utc_time(const sys_time& t) { - return clock_cast(t); + return utc_clock::from_sys(t); } template @@ -2456,7 +2513,7 @@ inline utc_time::type> to_utc_time(const tai_time& t) { - return clock_cast(t); + return tai_clock::to_utc(t); } template @@ -2464,7 +2521,7 @@ inline utc_time::type> to_utc_time(const gps_time& t) { - return clock_cast(t); + return gps_clock::to_utc(t); } @@ -2473,7 +2530,7 @@ inline tai_time::type> to_tai_time(const sys_time& t) { - return clock_cast(t); + return tai_clock::from_utc(utc_clock::from_sys(t)); } template @@ -2481,7 +2538,7 @@ inline tai_time::type> to_tai_time(const utc_time& t) { - return clock_cast(t); + return tai_clock::from_utc(t); } template @@ -2489,7 +2546,7 @@ inline tai_time::type> to_tai_time(const gps_time& t) { - return clock_cast(t); + return tai_clock::from_utc(gps_clock::to_utc(t)); } @@ -2498,7 +2555,7 @@ inline gps_time::type> to_gps_time(const sys_time& t) { - return clock_cast(t); + return gps_clock::from_utc(utc_clock::from_sys(t)); } template @@ -2506,7 +2563,7 @@ inline gps_time::type> to_gps_time(const utc_time& t) { - return clock_cast(t); + return gps_clock::from_utc(t); } template @@ -2514,7 +2571,7 @@ inline gps_time::type> to_gps_time(const tai_time& t) { - return clock_cast(t); + return gps_clock::from_utc(tai_clock::to_utc(t)); } #endif // !MISSING_LEAP_SECONDS