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.
This commit is contained in:
Howard Hinnant
2017-11-30 15:40:37 -05:00
parent 443a29df53
commit a3e8f399c4

View File

@@ -2197,33 +2197,37 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
return is; return is;
} }
template<typename DestClock, typename SourceClock> #if !defined(_MSC_VER) || _MSC_VER > 1912
// clock_time_conversion
template <class DstClock, class SrcClock>
struct clock_time_conversion struct clock_time_conversion
{}; {};
template<> template <>
struct clock_time_conversion<std::chrono::system_clock, std::chrono::system_clock> struct clock_time_conversion<std::chrono::system_clock, std::chrono::system_clock>
{ {
template <class Duration> template <class Duration>
auto operator()(const sys_time<Duration>& st) const sys_time<Duration>
-> sys_time<Duration> operator()(const sys_time<Duration>& st) const
{ {
return st; return st;
} }
}; };
template<> template <>
struct clock_time_conversion<utc_clock, utc_clock> struct clock_time_conversion<utc_clock, utc_clock>
{ {
template <class Duration> template <class Duration>
auto operator()(const utc_time<Duration>& ut) const utc_time<Duration>
-> utc_time<Duration> operator()(const utc_time<Duration>& ut) const
{ {
return ut; return ut;
} }
}; };
template<> template <>
struct clock_time_conversion<utc_clock, std::chrono::system_clock> struct clock_time_conversion<utc_clock, std::chrono::system_clock>
{ {
template <class Duration> template <class Duration>
@@ -2234,7 +2238,7 @@ struct clock_time_conversion<utc_clock, std::chrono::system_clock>
} }
}; };
template<> template <>
struct clock_time_conversion<std::chrono::system_clock, utc_clock> struct clock_time_conversion<std::chrono::system_clock, utc_clock>
{ {
template <class Duration> template <class Duration>
@@ -2245,12 +2249,12 @@ struct clock_time_conversion<std::chrono::system_clock, utc_clock>
} }
}; };
template<typename Clock> template <class Clock>
struct clock_time_conversion<Clock, Clock> struct clock_time_conversion<Clock, Clock>
{ {
template <class Duration> template <class Duration>
auto operator()(const std::chrono::time_point<Clock, Duration>& tp) const std::chrono::time_point<Clock, Duration>
-> std::chrono::time_point<Clock, Duration> operator()(const std::chrono::time_point<Clock, Duration>& tp) const
{ {
return tp; return tp;
} }
@@ -2258,164 +2262,217 @@ struct clock_time_conversion<Clock, Clock>
namespace ctc_detail namespace ctc_detail
{ {
//Check if TimePoint is time for given clock,
//if not emits hard error template <class Clock, class Duration>
template<typename Clock, typename TimePoint> using time_point = std::chrono::time_point<Clock, Duration>;
struct return_clock_time
{ using std::declval;
using clock_time_point = std::chrono::time_point<Clock, typename TimePoint::duration>; using std::chrono::system_clock;
static_assert(std::is_same<TimePoint, clock_time_point>::value, "time point with appropariate clock shall be returned");
//Check if TimePoint is time for given clock,
//if not emits hard error
template <class Clock, class TimePoint>
struct return_clock_time
{
using clock_time_point = time_point<Clock, typename TimePoint::duration>;
using type = TimePoint; using type = TimePoint;
};
// Check if Clock has to_sys method accepting TimePoint with given duration const& and returning sys_time static_assert(std::is_same<TimePoint, clock_time_point>::value,
// If so has nested type member equal to return type to_sys. "time point with appropariate clock shall be returned");
template<typename Clock, typename Duration, typename = void> };
struct return_to_sys
{};
template<typename Clock, typename Duration> // Check if Clock has to_sys method accepting TimePoint with given duration const& and
struct return_to_sys<Clock, Duration, decltype(Clock::to_sys(std::declval<std::chrono::time_point<Clock, Duration> const&>()), void())> // returning sys_time. If so has nested type member equal to return type to_sys.
: return_clock_time<std::chrono::system_clock, decltype(Clock::to_sys(std::declval<std::chrono::time_point<Clock, Duration> const&>()))> template <class Clock, class Duration, class = void>
{}; struct return_to_sys
{};
// Similiar to above template <class Clock, class Duration>
template<typename Clock, typename Duration, typename = void> struct return_to_sys
struct return_from_sys <
{}; Clock, Duration,
decltype(Clock::to_sys(declval<time_point<Clock, Duration> const&>()), void())
>
: return_clock_time
<
system_clock,
decltype(Clock::to_sys(declval<time_point<Clock, Duration> const&>()))
>
{};
template<typename Clock, typename Duration> // Similiar to above
struct return_from_sys<Clock, Duration, decltype(Clock::from_sys(std::declval<std::chrono::time_point<std::chrono::system_clock, Duration> const&>()), void())> template <class Clock, class Duration, class = void>
: return_clock_time<Clock, decltype(Clock::from_sys(std::declval<std::chrono::time_point<std::chrono::system_clock, Duration> const&>()))> struct return_from_sys
{}; {};
// Similiar to above template <class Clock, class Duration>
template<typename Clock, typename Duration, typename = void> struct return_from_sys
struct return_to_utc <
{}; Clock, Duration,
decltype(Clock::from_sys(declval<time_point<system_clock, Duration> const&>()),
void())
>
: return_clock_time
<
Clock,
decltype(Clock::from_sys(declval<time_point<system_clock, Duration> const&>()))
>
{};
template<typename Clock, typename Duration> // Similiar to above
struct return_to_utc<Clock, Duration, decltype(Clock::to_utc(std::declval<std::chrono::time_point<Clock, Duration> const&>()), void())> template <class Clock, class Duration, class = void>
: return_clock_time<utc_clock, decltype(Clock::to_utc(std::declval<std::chrono::time_point<Clock, Duration> const&>()))> struct return_to_utc
{}; {};
// Similiar to above template <class Clock, class Duration>
template<typename Clock, typename Duration, typename = void> struct return_to_utc
struct return_from_utc <
{}; Clock, Duration,
decltype(Clock::to_utc(declval<time_point<Clock, Duration> const&>()), void())
>
: return_clock_time
<
utc_clock,
decltype(Clock::to_utc(declval<time_point<Clock, Duration> const&>()))>
{};
template<typename Clock, typename Duration> // Similiar to above
struct return_from_utc<Clock, Duration, decltype(Clock::from_utc(std::declval<std::chrono::time_point<utc_clock, Duration> const&>()), void())> template <class Clock, class Duration, class = void>
: return_clock_time<Clock, decltype(Clock::from_utc(std::declval<std::chrono::time_point<utc_clock, Duration> const&>()))> struct return_from_utc
{}; {};
}
template<typename SourceClock> template <class Clock, class Duration>
struct clock_time_conversion<std::chrono::system_clock, SourceClock> struct return_from_utc
<
Clock, Duration,
decltype(Clock::from_utc(declval<time_point<utc_clock, Duration> const&>()),
void())
>
: return_clock_time
<
Clock,
decltype(Clock::from_utc(declval<time_point<utc_clock, Duration> const&>()))
>
{};
} // namespace ctc_detail
template <class SrcClock>
struct clock_time_conversion<std::chrono::system_clock, SrcClock>
{ {
template <class Duration> template <class Duration>
auto operator()(const std::chrono::time_point<SourceClock, Duration>& tp) const typename ctc_detail::return_to_sys<SrcClock, Duration>::type
-> typename ctc_detail::return_to_sys<SourceClock, Duration>::type operator()(const std::chrono::time_point<SrcClock, Duration>& tp) const
{ {
return SourceClock::to_sys(tp); return SrcClock::to_sys(tp);
} }
}; };
template<typename DestClock> template <class DstClock>
struct clock_time_conversion<DestClock, std::chrono::system_clock> struct clock_time_conversion<DstClock, std::chrono::system_clock>
{ {
template <class Duration> template <class Duration>
auto operator()(const sys_time<Duration>& st) const typename ctc_detail::return_from_sys<DstClock, Duration>::type
-> typename ctc_detail::return_from_sys<DestClock, Duration>::type operator()(const sys_time<Duration>& st) const
{ {
return DestClock::from_sys(st); return DstClock::from_sys(st);
} }
}; };
template<typename SourceClock> template <class SrcClock>
struct clock_time_conversion<utc_clock, SourceClock> struct clock_time_conversion<utc_clock, SrcClock>
{ {
template <class Duration> template <class Duration>
auto operator()(const std::chrono::time_point<SourceClock, Duration>& tp) const typename ctc_detail::return_to_utc<SrcClock, Duration>::type
-> typename ctc_detail::return_to_utc<SourceClock, Duration>::type operator()(const std::chrono::time_point<SrcClock, Duration>& tp) const
{ {
return SourceClock::to_utc(tp); return SrcClock::to_utc(tp);
} }
}; };
template<typename DestClock> template <class DstClock>
struct clock_time_conversion<DestClock, utc_clock> struct clock_time_conversion<DstClock, utc_clock>
{ {
template <class Duration> template <class Duration>
auto operator()(const utc_time<Duration>& ut) const typename ctc_detail::return_from_utc<DstClock, Duration>::type
-> typename ctc_detail::return_from_utc<DestClock, Duration>::type operator()(const utc_time<Duration>& ut) const
{ {
return DestClock::from_utc(ut); return DstClock::from_utc(ut);
} }
}; };
namespace clock_cast_detail namespace clock_cast_detail
{ {
template<typename DestClock, typename SourceClock, typename Duration>
auto conv_clock(const std::chrono::time_point<SourceClock, Duration>& st)
-> decltype(std::declval<clock_time_conversion<DestClock, SourceClock>>()(st))
{
return clock_time_conversion<DestClock, SourceClock>{}(st);
}
//direct triat conversion, 2nd candidate template <class Clock, class Duration>
template<typename DestClock, typename SourceClock, typename Duration> using time_point = std::chrono::time_point<Clock, Duration>;
auto cc_impl(const std::chrono::time_point<SourceClock, Duration>& st, using std::chrono::system_clock;
const std::chrono::time_point<SourceClock, Duration>* /* 1st */)
-> decltype(conv_clock<DestClock>(st))
{
return conv_clock<DestClock>(st);
}
//conversion trought sys, 3rd candidate template <class DstClock, class SrcClock, class Duration>
template<typename DestClock, typename SourceClock, typename Duration> auto
auto cc_impl(const std::chrono::time_point<SourceClock, Duration>& st, conv_clock(const time_point<SrcClock, Duration>& t)
const void* /* 2nd */) -> decltype(std::declval<clock_time_conversion<DstClock, SrcClock>>()(t))
-> decltype(conv_clock<DestClock>(conv_clock<std::chrono::system_clock>(st)))
{
return conv_clock<DestClock>(conv_clock<std::chrono::system_clock>(st));
}
//conversion trought utc, 3rd candidate
template<typename DestClock, typename SourceClock, typename Duration>
auto cc_impl(const std::chrono::time_point<SourceClock, Duration>& st,
const void* /* 2nd */)
-> decltype(conv_clock<DestClock>(conv_clock<utc_clock>(st)))
{
return conv_clock<DestClock>(conv_clock<utc_clock>(st));
}
//conversion trought sys and utc, 4th candidate
template<typename DestClock, typename SourceClock, typename Duration>
auto cc_impl(const std::chrono::time_point<SourceClock, Duration>& st,
... /* 3rd */)
-> decltype(conv_clock<DestClock>(conv_clock<utc_clock>(conv_clock<std::chrono::system_clock>(st))))
{
return conv_clock<DestClock>(conv_clock<utc_clock>(conv_clock<std::chrono::system_clock>(st)));
}
//conversion trought utc and sys, 4th candidate
template<typename DestClock, typename SourceClock, typename Duration>
auto cc_impl(const std::chrono::time_point<SourceClock, Duration>& st,
... /* 3rd */)
-> decltype(conv_clock<DestClock>(conv_clock<std::chrono::system_clock>(conv_clock<utc_clock>(st))))
{
return conv_clock<DestClock>(conv_clock<std::chrono::system_clock>(conv_clock<utc_clock>(st)));
}
}
template<typename DestClock, typename SourceClock, typename Duration>
auto clock_cast(const std::chrono::time_point<SourceClock, Duration>& st)
-> decltype(clock_cast_detail::cc_impl<DestClock>(st, &st))
{ {
return clock_cast_detail::cc_impl<DestClock>(st, &st); return clock_time_conversion<DstClock, SrcClock>{}(t);
} }
//direct trait conversion, 1st candidate
template <class DstClock, class SrcClock, class Duration>
auto
cc_impl(const time_point<SrcClock, Duration>& t, const time_point<SrcClock, Duration>*)
-> decltype(conv_clock<DstClock>(t))
{
return conv_clock<DstClock>(t);
}
//conversion through sys, 2nd candidate
template <class DstClock, class SrcClock, class Duration>
auto
cc_impl(const time_point<SrcClock, Duration>& t, const void*)
-> decltype(conv_clock<DstClock>(conv_clock<system_clock>(t)))
{
return conv_clock<DstClock>(conv_clock<system_clock>(t));
}
//conversion through utc, 2nd candidate
template <class DstClock, class SrcClock, class Duration>
auto
cc_impl(const time_point<SrcClock, Duration>& t, const void*)
-> decltype(conv_clock<DstClock>(conv_clock<utc_clock>(t)))
{
return conv_clock<DstClock>(conv_clock<utc_clock>(t));
}
//conversion through sys and utc, 3rd candidate
template <class DstClock, class SrcClock, class Duration>
auto
cc_impl(const time_point<SrcClock, Duration>& t, ...)
-> decltype(conv_clock<DstClock>(conv_clock<utc_clock>(conv_clock<system_clock>(t))))
{
return conv_clock<DstClock>(conv_clock<utc_clock>(conv_clock<system_clock>(t)));
}
//conversion through utc and sys, 3rd candidate
template <class DstClock, class SrcClock, class Duration>
auto
cc_impl(const time_point<SrcClock, Duration>& t, ...)
-> decltype(conv_clock<DstClock>(conv_clock<system_clock>(conv_clock<utc_clock>(t))))
{
return conv_clock<DstClock>(conv_clock<system_clock>(conv_clock<utc_clock>(t)));
}
} // namespace clock_cast_detail
template <class DstClock, class SrcClock, class Duration>
auto
clock_cast(const std::chrono::time_point<SrcClock, Duration>& tp)
-> decltype(clock_cast_detail::cc_impl<DstClock>(tp, &tp))
{
return clock_cast_detail::cc_impl<DstClock>(tp, &tp);
}
#endif // !defined(_MSC_VER) || _MSC_VER > 1912
// Deprecated API // Deprecated API
template <class Duration> template <class Duration>
@@ -2423,7 +2480,7 @@ inline
sys_time<typename std::common_type<Duration, std::chrono::seconds>::type> sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
to_sys_time(const utc_time<Duration>& t) to_sys_time(const utc_time<Duration>& t)
{ {
return clock_cast<std::chrono::system_clock>(t); return utc_clock::to_sys(t);
} }
template <class Duration> template <class Duration>
@@ -2431,7 +2488,7 @@ inline
sys_time<typename std::common_type<Duration, std::chrono::seconds>::type> sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
to_sys_time(const tai_time<Duration>& t) to_sys_time(const tai_time<Duration>& t)
{ {
return clock_cast<std::chrono::system_clock>(t); return utc_clock::to_sys(tai_clock::to_utc(t));
} }
template <class Duration> template <class Duration>
@@ -2439,7 +2496,7 @@ inline
sys_time<typename std::common_type<Duration, std::chrono::seconds>::type> sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
to_sys_time(const gps_time<Duration>& t) to_sys_time(const gps_time<Duration>& t)
{ {
return clock_cast<std::chrono::system_clock>(t); return utc_clock::to_sys(gps_clock::to_utc(t));
} }
@@ -2448,7 +2505,7 @@ inline
utc_time<typename std::common_type<Duration, std::chrono::seconds>::type> utc_time<typename std::common_type<Duration, std::chrono::seconds>::type>
to_utc_time(const sys_time<Duration>& t) to_utc_time(const sys_time<Duration>& t)
{ {
return clock_cast<utc_clock>(t); return utc_clock::from_sys(t);
} }
template <class Duration> template <class Duration>
@@ -2456,7 +2513,7 @@ inline
utc_time<typename std::common_type<Duration, std::chrono::seconds>::type> utc_time<typename std::common_type<Duration, std::chrono::seconds>::type>
to_utc_time(const tai_time<Duration>& t) to_utc_time(const tai_time<Duration>& t)
{ {
return clock_cast<utc_clock>(t); return tai_clock::to_utc(t);
} }
template <class Duration> template <class Duration>
@@ -2464,7 +2521,7 @@ inline
utc_time<typename std::common_type<Duration, std::chrono::seconds>::type> utc_time<typename std::common_type<Duration, std::chrono::seconds>::type>
to_utc_time(const gps_time<Duration>& t) to_utc_time(const gps_time<Duration>& t)
{ {
return clock_cast<utc_clock>(t); return gps_clock::to_utc(t);
} }
@@ -2473,7 +2530,7 @@ inline
tai_time<typename std::common_type<Duration, std::chrono::seconds>::type> tai_time<typename std::common_type<Duration, std::chrono::seconds>::type>
to_tai_time(const sys_time<Duration>& t) to_tai_time(const sys_time<Duration>& t)
{ {
return clock_cast<tai_clock>(t); return tai_clock::from_utc(utc_clock::from_sys(t));
} }
template <class Duration> template <class Duration>
@@ -2481,7 +2538,7 @@ inline
tai_time<typename std::common_type<Duration, std::chrono::seconds>::type> tai_time<typename std::common_type<Duration, std::chrono::seconds>::type>
to_tai_time(const utc_time<Duration>& t) to_tai_time(const utc_time<Duration>& t)
{ {
return clock_cast<tai_clock>(t); return tai_clock::from_utc(t);
} }
template <class Duration> template <class Duration>
@@ -2489,7 +2546,7 @@ inline
tai_time<typename std::common_type<Duration, std::chrono::seconds>::type> tai_time<typename std::common_type<Duration, std::chrono::seconds>::type>
to_tai_time(const gps_time<Duration>& t) to_tai_time(const gps_time<Duration>& t)
{ {
return clock_cast<tai_clock>(t); return tai_clock::from_utc(gps_clock::to_utc(t));
} }
@@ -2498,7 +2555,7 @@ inline
gps_time<typename std::common_type<Duration, std::chrono::seconds>::type> gps_time<typename std::common_type<Duration, std::chrono::seconds>::type>
to_gps_time(const sys_time<Duration>& t) to_gps_time(const sys_time<Duration>& t)
{ {
return clock_cast<gps_clock>(t); return gps_clock::from_utc(utc_clock::from_sys(t));
} }
template <class Duration> template <class Duration>
@@ -2506,7 +2563,7 @@ inline
gps_time<typename std::common_type<Duration, std::chrono::seconds>::type> gps_time<typename std::common_type<Duration, std::chrono::seconds>::type>
to_gps_time(const utc_time<Duration>& t) to_gps_time(const utc_time<Duration>& t)
{ {
return clock_cast<gps_clock>(t); return gps_clock::from_utc(t);
} }
template <class Duration> template <class Duration>
@@ -2514,7 +2571,7 @@ inline
gps_time<typename std::common_type<Duration, std::chrono::seconds>::type> gps_time<typename std::common_type<Duration, std::chrono::seconds>::type>
to_gps_time(const tai_time<Duration>& t) to_gps_time(const tai_time<Duration>& t)
{ {
return clock_cast<gps_clock>(t); return gps_clock::from_utc(tai_clock::to_utc(t));
} }
#endif // !MISSING_LEAP_SECONDS #endif // !MISSING_LEAP_SECONDS