diff --git a/stl/inc/chrono b/stl/inc/chrono index 4a8e089c91a..67593076fb1 100644 --- a/stl/inc/chrono +++ b/stl/inc/chrono @@ -1944,65 +1944,75 @@ namespace chrono { return _Elapsed_offset; } - private: - sys_seconds _Date; - bool _Is_positive; - seconds _Elapsed_offset; - }; + _NODISCARD friend constexpr bool operator==(const leap_second& _Left, const leap_second& _Right) noexcept { + return _Left.date() == _Right.date(); + } + template + _NODISCARD friend constexpr bool operator==( + const leap_second& _Left, const sys_time<_Duration>& _Right) noexcept { + return _Left.date() == _Right; + } - _EXPORT_STD _NODISCARD constexpr bool operator==(const leap_second& _Left, const leap_second& _Right) noexcept { - return _Left.date() == _Right.date(); - } - _EXPORT_STD template - _NODISCARD constexpr bool operator==(const leap_second& _Left, const sys_time<_Duration>& _Right) noexcept { - return _Left.date() == _Right; - } + template + _NODISCARD friend constexpr bool operator<( + const leap_second& _Left, const sys_time<_Duration>& _Right) noexcept { + return _Left.date() < _Right; + } + template + _NODISCARD friend constexpr bool operator<( + const sys_time<_Duration>& _Left, const leap_second& _Right) noexcept { + return _Left < _Right.date(); + } - _EXPORT_STD template - _NODISCARD constexpr bool operator<(const leap_second& _Left, const sys_time<_Duration>& _Right) noexcept { - return _Left.date() < _Right; - } - _EXPORT_STD template - _NODISCARD constexpr bool operator<(const sys_time<_Duration>& _Left, const leap_second& _Right) noexcept { - return _Left < _Right.date(); - } + template + _NODISCARD friend constexpr bool operator>( + const leap_second& _Left, const sys_time<_Duration>& _Right) noexcept { + return _Right < _Left.date(); + } + template + _NODISCARD friend constexpr bool operator>( + const sys_time<_Duration>& _Left, const leap_second& _Right) noexcept { + return _Right.date() < _Left; + } - _EXPORT_STD template - _NODISCARD constexpr bool operator>(const leap_second& _Left, const sys_time<_Duration>& _Right) noexcept { - return _Right < _Left.date(); - } - _EXPORT_STD template - _NODISCARD constexpr bool operator>(const sys_time<_Duration>& _Left, const leap_second& _Right) noexcept { - return _Right.date() < _Left; - } + template + _NODISCARD friend constexpr bool operator<=( + const leap_second& _Left, const sys_time<_Duration>& _Right) noexcept { + return !(_Right < _Left.date()); + } + template + _NODISCARD friend constexpr bool operator<=( + const sys_time<_Duration>& _Left, const leap_second& _Right) noexcept { + return !(_Right.date() < _Left); + } - _EXPORT_STD template - _NODISCARD constexpr bool operator<=(const leap_second& _Left, const sys_time<_Duration>& _Right) noexcept { - return !(_Right < _Left.date()); - } - _EXPORT_STD template - _NODISCARD constexpr bool operator<=(const sys_time<_Duration>& _Left, const leap_second& _Right) noexcept { - return !(_Right.date() < _Left); - } + template + _NODISCARD friend constexpr bool operator>=( + const leap_second& _Left, const sys_time<_Duration>& _Right) noexcept { + return !(_Left.date() < _Right); + } + template + _NODISCARD friend constexpr bool operator>=( + const sys_time<_Duration>& _Left, const leap_second& _Right) noexcept { + return !(_Left < _Right.date()); + } - _EXPORT_STD template - _NODISCARD constexpr bool operator>=(const leap_second& _Left, const sys_time<_Duration>& _Right) noexcept { - return !(_Left.date() < _Right); - } - _EXPORT_STD template - _NODISCARD constexpr bool operator>=(const sys_time<_Duration>& _Left, const leap_second& _Right) noexcept { - return !(_Left < _Right.date()); - } + template + requires three_way_comparable_with> + _NODISCARD friend constexpr auto operator<=>( + const leap_second& _Left, const sys_time<_Duration>& _Right) noexcept { + return _Left.date() <=> _Right; + } + _NODISCARD friend constexpr strong_ordering operator<=>( + const leap_second& _Left, const leap_second& _Right) noexcept { + return _Left.date() <=> _Right.date(); + } - _EXPORT_STD template - requires three_way_comparable_with> - _NODISCARD constexpr auto operator<=>(const leap_second& _Left, const sys_time<_Duration>& _Right) noexcept { - return _Left.date() <=> _Right; - } - _EXPORT_STD _NODISCARD constexpr strong_ordering operator<=>( - const leap_second& _Left, const leap_second& _Right) noexcept { - return _Left.date() <=> _Right.date(); - } + private: + sys_seconds _Date; + bool _Is_positive; + seconds _Elapsed_offset; + }; // [time.zone.link] diff --git a/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp b/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp index a0b24b0b320..eb4812739ba 100644 --- a/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp +++ b/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp @@ -7,10 +7,12 @@ #include #include #include +#include #include #include #include +#include #include using namespace std; @@ -475,6 +477,63 @@ void test() { } } +// LWG-4139 "[time.zone.leap] recursive constraint in <=>" +namespace lwg_4139 { + struct conv_to_leap_second : local_t { + operator leap_second() const noexcept; + }; + + static_assert(equality_comparable == is_permissive); + static_assert(equality_comparable_with == is_permissive); + static_assert(totally_ordered == is_permissive); + static_assert(totally_ordered_with == is_permissive); + static_assert(three_way_comparable == is_permissive); + static_assert(three_way_comparable_with == is_permissive); + + using ref_leap_second = reference_wrapper; + + static_assert(equality_comparable); + static_assert(equality_comparable_with); + static_assert(totally_ordered); + static_assert(totally_ordered_with); + static_assert(three_way_comparable); + static_assert(three_way_comparable_with); + + template + concept can_equality_compare_with = requires(const remove_reference_t& t, const remove_reference_t& u) { + t == u; + t != u; + u == t; + u != t; + }; + + template + concept can_relation_compare_with = requires(const remove_reference_t& t, const remove_reference_t& u) { + t < u; + t > u; + t <= u; + t >= u; + u < t; + u > t; + u <= t; + u >= t; + }; + + template + concept can_three_way_compare_with = requires(const remove_reference_t& t, const remove_reference_t& u) { + t <=> u; + u <=> t; + }; + + static_assert(!can_equality_compare_with); + static_assert(!can_relation_compare_with); + static_assert(!can_three_way_compare_with); + + static_assert(can_equality_compare_with); + static_assert(can_relation_compare_with); + static_assert(can_three_way_compare_with); +} // namespace lwg_4139 + int main() { run_tz_test([] { test(); }); }