diff --git a/libcxx/include/__chrono/duration.h b/libcxx/include/__chrono/duration.h --- a/libcxx/include/__chrono/duration.h +++ b/libcxx/include/__chrono/duration.h @@ -343,6 +343,8 @@ return __duration_eq, duration<_Rep2, _Period2> >()(__lhs, __rhs); } +#if _LIBCPP_STD_VER <= 17 + // Duration != template @@ -354,6 +356,8 @@ return !(__lhs == __rhs); } +#endif // _LIBCPP_STD_VER <= 17 + // Duration < template @@ -417,6 +421,19 @@ return !(__lhs < __rhs); } +#if _LIBCPP_STD_VER >= 20 + +template + requires three_way_comparable +inline _LIBCPP_HIDE_FROM_ABI +constexpr auto operator<=>(const duration& __lhs, + const duration& __rhs) +{ + return _Ct(lhs).count() <=> _Ct(rhs).count(); +} + +#endif // _LIBCPP_STD_VER >= 20 + // Duration + template diff --git a/libcxx/include/chrono b/libcxx/include/chrono --- a/libcxx/include/chrono +++ b/libcxx/include/chrono @@ -182,7 +182,7 @@ bool operator==(const duration& lhs, const duration& rhs); template constexpr - bool operator!=(const duration& lhs, const duration& rhs); + bool operator!=(const duration& lhs, const duration& rhs); // removed in C++20 template constexpr bool operator< (const duration& lhs, const duration& rhs); @@ -195,6 +195,10 @@ template constexpr bool operator>=(const duration& lhs, const duration& rhs); +template + requires three_way_comparable + constexpr auto operator<=>(const duration& lhs, + const duration& rhs); // since C++20 // duration_cast template diff --git a/libcxx/test/std/time/time.duration/time.duration.comparisons/compare.three_way.pass.cpp b/libcxx/test/std/time/time.duration/time.duration.comparisons/compare.three_way.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/time/time.duration/time.duration.comparisons/compare.three_way.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// + +// duration + +// template +// requires ThreeWayComparable +// constexpr auto operator<=>(const duration& lhs, +// const duration& rhs); + +#include +#include + +#include "test_comparisons.h" + +int main(int, char**) { + { + constexpr std::chrono::seconds s1(3); + constexpr std::chrono::seconds s2(3); + static_assert((s1 <=> s2) == std::strong_ordering::equal); + static_assert(testOrder(s1, s2, std::strong_ordering::equal)); + } + { + constexpr std::chrono::seconds s1(3); + constexpr std::chrono::seconds s2(4); + static_assert((s1 <=> s2) == std::strong_ordering::less); + static_assert(testOrder(s1, s2, std::strong_ordering::less)); + } + { + constexpr std::chrono::milliseconds s1(3); + constexpr std::chrono::microseconds s2(3000); + static_assert((s1 <=> s2) == std::strong_ordering::equal); + static_assert(testOrder(s1, s2, std::strong_ordering::equal)); + } + { + constexpr std::chrono::milliseconds s1(3); + constexpr std::chrono::microseconds s2(4000); + static_assert((s1 <=> s2) == std::strong_ordering::less); + static_assert(testOrder(s1, s2, std::strong_ordering::less)); + } + { + constexpr std::chrono::duration> s1(9); + constexpr std::chrono::duration> s2(10); + static_assert((s1 <=> s2) == std::strong_ordering::equal); + static_assert(testOrder(s1, s2, std::strong_ordering::equal)); + } + { + constexpr std::chrono::duration> s1(10); + constexpr std::chrono::duration> s2(9); + static_assert((s1 <=> s2) == std::strong_ordering::greater); + static_assert(testOrder(s1, s2, std::strong_ordering::greater)); + } + { + constexpr std::chrono::duration> s1(9); + constexpr std::chrono::duration> s2(10); + static_assert((s1 <=> s2) == std::strong_ordering::equal); + static_assert(testOrder(s1, s2, std::strong_ordering::equal)); + } + + return 0; +}