diff --git a/libcxx/include/concepts b/libcxx/include/concepts --- a/libcxx/include/concepts +++ b/libcxx/include/concepts @@ -214,7 +214,7 @@ template concept assignable_from = is_lvalue_reference_v<_Lhs> && - common_reference_with&, const remove_reference_t<_Rhs>&> && + common_reference_with<__make_const_lvalue_ref<_Lhs>, __make_const_lvalue_ref<_Rhs>> && requires (_Lhs __lhs, _Rhs&& __rhs) { { __lhs = _VSTD::forward<_Rhs>(__rhs) } -> same_as<_Lhs>; }; @@ -346,7 +346,7 @@ // [concept.equalitycomparable] template concept __weakly_equality_comparable_with = - requires(const remove_reference_t<_Tp>& __t, const remove_reference_t<_Up>& __u) { + requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { { __t == __u } -> __boolean_testable; { __t != __u } -> __boolean_testable; { __u == __t } -> __boolean_testable; @@ -359,13 +359,41 @@ template concept equality_comparable_with = equality_comparable<_Tp> && equality_comparable<_Up> && - common_reference_with&, const remove_reference_t<_Up>&> && + common_reference_with<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>> && equality_comparable< common_reference_t< - const remove_reference_t<_Tp>&, - const remove_reference_t<_Up>&>> && + __make_const_lvalue_ref<_Tp>, + __make_const_lvalue_ref<_Up>>> && __weakly_equality_comparable_with<_Tp, _Up>; +// [concept.totallyordered] + +template +concept __partially_ordered_with = + requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { + { __t < __u } -> __boolean_testable; + { __t > __u } -> __boolean_testable; + { __t <= __u } -> __boolean_testable; + { __t >= __u } -> __boolean_testable; + { __u < __t } -> __boolean_testable; + { __u > __t } -> __boolean_testable; + { __u <= __t } -> __boolean_testable; + { __u >= __t } -> __boolean_testable; + }; + +template +concept totally_ordered = equality_comparable<_Tp> && __partially_ordered_with<_Tp, _Tp>; + +template +concept totally_ordered_with = + totally_ordered<_Tp> && totally_ordered<_Up> && + equality_comparable_with<_Tp, _Up> && + totally_ordered< + common_reference_t< + __make_const_lvalue_ref<_Tp>, + __make_const_lvalue_ref<_Up>>> && + __partially_ordered_with<_Tp, _Up>; + // [concepts.object] template concept movable = diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits --- a/libcxx/include/type_traits +++ b/libcxx/include/type_traits @@ -4505,6 +4505,9 @@ template using _IsCharLikeType = _And, is_trivial<_CharT> >; +template +using __make_const_lvalue_ref = const typename remove_reference<_Tp>::type&; + _LIBCPP_END_NAMESPACE_STD #if _LIBCPP_STD_VER > 14 diff --git a/libcxx/test/std/concepts/concepts.compare/concept.equalitycomparable/equality_comparable.compile.pass.cpp b/libcxx/test/std/concepts/concepts.compare/concept.equalitycomparable/equality_comparable.compile.pass.cpp --- a/libcxx/test/std/concepts/concepts.compare/concept.equalitycomparable/equality_comparable.compile.pass.cpp +++ b/libcxx/test/std/concepts/concepts.compare/concept.equalitycomparable/equality_comparable.compile.pass.cpp @@ -112,14 +112,23 @@ static_assert(std::equality_comparable); static_assert(std::equality_comparable); static_assert(std::equality_comparable); -static_assert(std::equality_comparable); +static_assert(std::equality_comparable); static_assert(std::equality_comparable); static_assert(std::equality_comparable); static_assert(!std::equality_comparable); static_assert(!std::equality_comparable); +static_assert(std::equality_comparable); +static_assert(std::equality_comparable); +static_assert(std::equality_comparable); +static_assert(std::equality_comparable); + static_assert(!std::equality_comparable); static_assert(!std::equality_comparable); +static_assert(std::equality_comparable); +static_assert(std::equality_comparable); +static_assert(std::equality_comparable); +static_assert(std::equality_comparable); static_assert(!std::equality_comparable); static_assert( !std::equality_comparable); @@ -134,9 +143,13 @@ static_assert( !std::equality_comparable); -static_assert(!std::equality_comparable); +static_assert(!std::equality_comparable); +static_assert(!std::equality_comparable); +static_assert(std::equality_comparable); +static_assert(std::equality_comparable); +static_assert(std::equality_comparable); +static_assert(std::equality_comparable); static_assert(std::equality_comparable); -static_assert(std::equality_comparable); static_assert(std::equality_comparable); } // namespace types_fit_for_purpose diff --git a/libcxx/test/std/concepts/concepts.compare/concept.equalitycomparable/equality_comparable_with.compile.pass.cpp b/libcxx/test/std/concepts/concepts.compare/concept.equalitycomparable/equality_comparable_with.compile.pass.cpp --- a/libcxx/test/std/concepts/concepts.compare/concept.equalitycomparable/equality_comparable_with.compile.pass.cpp +++ b/libcxx/test/std/concepts/concepts.compare/concept.equalitycomparable/equality_comparable_with.compile.pass.cpp @@ -1097,12 +1097,12 @@ check_equality_comparable_with()); static_assert(check_equality_comparable_with()); -static_assert(check_equality_comparable_with()); +static_assert(check_equality_comparable_with()); static_assert(check_equality_comparable_with()); static_assert(check_equality_comparable_with()); + different_return_types>()); static_assert(check_equality_comparable_with()); static_assert( diff --git a/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered.pass.cpp b/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered.pass.cpp @@ -0,0 +1,175 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: libcpp-no-concepts + +// template +// concept totally_ordered; + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../types.h" +#include "test_macros.h" + +// `models_totally_ordered` checks that `std::totally_ordered` subsumes +// `std::equality_comparable`. This overload should *never* be called. +template +constexpr bool models_totally_ordered() noexcept { + return false; +} + +template +constexpr bool models_totally_ordered() noexcept { + return true; +} + +namespace fundamentals { +static_assert(models_totally_ordered()); +static_assert(models_totally_ordered()); +static_assert(models_totally_ordered()); +static_assert(models_totally_ordered()); +static_assert(models_totally_ordered()); +static_assert(models_totally_ordered()); +static_assert(models_totally_ordered()); +static_assert(models_totally_ordered()); +static_assert(models_totally_ordered()); +static_assert(models_totally_ordered()); +static_assert(models_totally_ordered()); +static_assert(models_totally_ordered()); +static_assert(models_totally_ordered()); +static_assert(models_totally_ordered()); +static_assert(models_totally_ordered()); +static_assert(models_totally_ordered()); +static_assert(models_totally_ordered()); +static_assert(models_totally_ordered()); +static_assert(models_totally_ordered()); +static_assert(models_totally_ordered()); + +#ifndef TEST_COMPILER_GCC +static_assert(!std::totally_ordered); +#endif + +struct S {}; +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered < int (S::*)() && noexcept >); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered < int (S::*)() const&& noexcept >); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered < int (S::*)() volatile&& noexcept >); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered < int (S::*)() const volatile&& noexcept >); + +static_assert(!std::totally_ordered); +} // namespace fundamentals + +namespace standard_types { +static_assert(models_totally_ordered >()); +static_assert(models_totally_ordered >()); +static_assert(models_totally_ordered >()); +static_assert(models_totally_ordered >()); +static_assert(models_totally_ordered >()); +static_assert(models_totally_ordered >()); +static_assert(models_totally_ordered >()); +static_assert(models_totally_ordered >()); + +static_assert(!std::totally_ordered >); +static_assert(!std::totally_ordered >); + +struct A {}; +// FIXME(cjdb): uncomment when operator<=> is implemented for each of these types. +// static_assert(!std::totally_ordered >); +// static_assert(!std::totally_ordered >); +// static_assert(!std::totally_ordered >); +// static_assert(!std::totally_ordered >); +static_assert(!std::totally_ordered >); +// static_assert(!std::totally_ordered >); +// static_assert(!std::totally_ordered >); +} // namespace standard_types + +namespace types_fit_for_purpose { +static_assert(models_totally_ordered()); +static_assert(models_totally_ordered()); +static_assert(models_totally_ordered()); +static_assert(models_totally_ordered()); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); + +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); + +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); + +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert( + !std::totally_ordered); +static_assert( + !std::totally_ordered); +static_assert( + !std::totally_ordered); +static_assert( + !std::totally_ordered); + +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(std::totally_ordered); +static_assert(std::totally_ordered); + +static_assert(std::totally_ordered); +static_assert(std::totally_ordered); +static_assert(std::totally_ordered); +} // namespace types_fit_for_purpose + +int main(int, char**) { return 0; } diff --git a/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered_with.pass.cpp b/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered_with.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered_with.pass.cpp @@ -0,0 +1,1142 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: libcpp-no-concepts + +// template +// concept totally_ordered_with; + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../types.h" +#include "test_macros.h" + +template +constexpr bool check_totally_ordered_with() noexcept { + constexpr bool result = std::totally_ordered_with; + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + return result; +} + +namespace fundamentals { +static_assert(check_totally_ordered_with()); +static_assert(check_totally_ordered_with()); +static_assert(check_totally_ordered_with()); +static_assert(check_totally_ordered_with()); +static_assert(check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); + +struct S {}; +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int, int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int, + int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int, + int (S::*)() volatile&& noexcept > ()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(check_totally_ordered_with()); +static_assert(check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int*, + int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int*, + int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int*, + int (S::*)() volatile&& noexcept > ()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int*, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< + int[5], int (S::*)() const volatile noexcept>()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int[5], + int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int[5], + int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int[5], + int (S::*)() volatile&& noexcept > ()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int[5], + int (S::*)() const volatile&& noexcept > ()); + +static_assert(check_totally_ordered_with()); +static_assert(check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< + int (*)(), int (S::*)() const volatile noexcept>()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< + int (*)(), int (S::*)() const volatile & noexcept>()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (*)(), + int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (*)(), + int (S::*)() const&& noexcept > ()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (*)(), + int (S::*)() volatile&& noexcept > ()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (*)(), + int (S::*)() const volatile&& noexcept > ()); + +static_assert(check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< + int (&)(), int (S::*)() const volatile noexcept>()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< + int (&)(), int (S::*)() const volatile & noexcept>()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (&)(), + int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (&)(), + int (S::*)() const&& noexcept > ()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (&)(), + int (S::*)() volatile&& noexcept > ()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (&)(), + int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< + int (S::*)(), int (S::*)() const volatile noexcept>()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< + int (S::*)(), int (S::*)() const volatile & noexcept>()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)(), + int (S::*)() && noexcept > ()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)(), + int (S::*)() const&& noexcept > ()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)(), + int (S::*)() volatile&& noexcept > ()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)(), + int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< + int (S::*)() noexcept, int (S::*)() const volatile noexcept>()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< + int (S::*)() noexcept, int (S::*)() const volatile & noexcept>()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() noexcept, + int (S::*)() && noexcept > ()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() noexcept, + int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() noexcept, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() noexcept, + int (S::*)() const volatile&& noexcept > ()); + +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< + int (S::*)() const, int (S::*)() const volatile noexcept>()); +static_assert( + !check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< + int (S::*)() const, int (S::*)() const volatile & noexcept>()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() const, + int (S::*)() && noexcept > ()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() const, + int (S::*)() const&& noexcept > ()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() const, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() const, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() const noexcept, + int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() const noexcept, + int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() const noexcept, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() const noexcept, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< + int (S::*)() volatile, int (S::*)() const volatile noexcept>()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< + int (S::*)() volatile, int (S::*)() const volatile & noexcept>()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() volatile, + int (S::*)() && noexcept > ()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() volatile, + int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() volatile, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() volatile, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() volatile noexcept, + int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() volatile noexcept, + int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() volatile noexcept, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() volatile noexcept, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() const volatile, + int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() const volatile, + int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() const volatile, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() const volatile, + int (S::*)() const volatile&& noexcept > ()); + +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() + const volatile noexcept, + int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() + const volatile noexcept, + int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() + const volatile noexcept, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() + const volatile noexcept, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< + int (S::*)() &, int (S::*)() const volatile & noexcept>()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() &, + int (S::*)() && noexcept > ()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() &, + int (S::*)() const&& noexcept > ()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() &, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() &, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() & noexcept, + int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() & noexcept, + int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() & noexcept, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() & noexcept, + int (S::*)() const volatile&& noexcept > ()); + +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< + int (S::*)() const&, int (S::*)() const volatile & noexcept>()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() const&, + int (S::*)() && noexcept > ()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() const&, + int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() const&, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() const&, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() const& noexcept, + int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() const& noexcept, + int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() const& noexcept, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() const& noexcept, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() volatile&, + int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() volatile&, + int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() volatile&, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() volatile&, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() volatile& noexcept, + int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() volatile& noexcept, + int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() volatile& noexcept, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() volatile& noexcept, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() const volatile&, + int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() const volatile&, + int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() const volatile&, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() const volatile&, + int (S::*)() const volatile&& noexcept > ()); + +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< + int (S::*)() const volatile & noexcept, int (S::*)() &&>()); +static_assert(!check_totally_ordered_with < int (S::*)() + const volatile& noexcept, + int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with< + int (S::*)() const volatile & noexcept, int (S::*)() const&&>()); +static_assert(!check_totally_ordered_with < int (S::*)() + const volatile& noexcept, + int (S::*)() const&& noexcept > ()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() + const volatile& noexcept, + int (S::*)() volatile&& noexcept > ()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() + const volatile& noexcept, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() &&, + int (S::*)() && noexcept > ()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() &&, + int (S::*)() const&& noexcept > ()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() &&, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() &&, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with < int (S::*)() && noexcept, + int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with < int (S::*)() && noexcept, + int (S::*)() const&& > ()); +static_assert(!check_totally_ordered_with < int (S::*)() && noexcept, + int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with < int (S::*)() && noexcept, + int (S::*)() volatile&& > ()); +static_assert(!check_totally_ordered_with < int (S::*)() && noexcept, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with < int (S::*)() && noexcept, + int (S::*)() const volatile&& > ()); +static_assert(!check_totally_ordered_with < int (S::*)() && noexcept, + int (S::*)() const volatile&& noexcept > ()); + +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() const&&, + int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() const&&, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() const&&, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with < int (S::*)() const&& noexcept, + int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with < int (S::*)() const&& noexcept, + int (S::*)() volatile&& > ()); +static_assert(!check_totally_ordered_with < int (S::*)() const&& noexcept, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with < int (S::*)() const&& noexcept, + int (S::*)() const volatile&& > ()); +static_assert(!check_totally_ordered_with < int (S::*)() const&& noexcept, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() volatile&&, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() volatile&&, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with < int (S::*)() volatile&& noexcept, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with < int (S::*)() volatile&& noexcept, + int (S::*)() const volatile&& > ()); +static_assert(!check_totally_ordered_with < int (S::*)() volatile&& noexcept, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (S::*)() const volatile&&, + int (S::*)() const volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with < int (S::*)() + const volatile&& noexcept, + int (S::*)() const volatile&& noexcept > ()); + +#if !defined(TEST_COMPILER_GCC) +static_assert(!check_totally_ordered_with()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +#endif + +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< + std::nullptr_t, int (S::*)() const volatile noexcept>()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< + std::nullptr_t, int (S::*)() const volatile & noexcept>()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < std::nullptr_t, + int (S::*)() && noexcept > ()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < std::nullptr_t, + int (S::*)() const&& noexcept > ()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < std::nullptr_t, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < std::nullptr_t, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert( + !std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert( + !std::equality_comparable_with); +static_assert( + !std::equality_comparable_with); +static_assert( + !std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert( + !std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert( + !std::equality_comparable_with); +static_assert( + !std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with < void, + int (S::*)() && noexcept >); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with < void, + int (S::*)() const&& noexcept >); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with < void, + int (S::*)() volatile&& noexcept >); +static_assert( + !std::equality_comparable_with); +static_assert(!std::equality_comparable_with < void, + int (S::*)() const volatile&& noexcept >); +} // namespace fundamentals + +namespace standard_types { +static_assert( + check_totally_ordered_with, std::array >()); +static_assert(!check_totally_ordered_with, + std::array >()); +static_assert(check_totally_ordered_with, std::deque >()); +static_assert( + !check_totally_ordered_with, std::vector >()); +static_assert(check_totally_ordered_with, + std::forward_list >()); +static_assert( + !check_totally_ordered_with, std::vector >()); +static_assert(check_totally_ordered_with, std::list >()); +static_assert(!check_totally_ordered_with, std::vector >()); + +static_assert( + check_totally_ordered_with, std::map >()); +static_assert( + !check_totally_ordered_with, std::vector >()); +static_assert(check_totally_ordered_with >, + std::optional > >()); +static_assert(check_totally_ordered_with >, + std::vector >()); +static_assert( + check_totally_ordered_with, std::vector >()); +static_assert(!check_totally_ordered_with, int>()); + +struct A {}; +// FIXME(cjdb): uncomment when operator<=> is implemented for each of these types. +// static_assert(!check_totally_ordered_with >, +// std::optional > >()); +// static_assert(!check_totally_ordered_with >, +// std::vector >()); +struct B {}; +static_assert(!check_totally_ordered_with, std::vector >()); +static_assert( + !check_totally_ordered_with, std::optional >()); +} // namespace standard_types + +namespace types_fit_for_purpose { +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); + +static_assert(check_totally_ordered_with()); +static_assert(check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); + +static_assert( + check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + check_totally_ordered_with()); + +static_assert(!check_totally_ordered_with()); +static_assert( + std::common_reference_with && + !check_totally_ordered_with()); + +static_assert(!check_totally_ordered_with()); +static_assert( + std::common_reference_with && + !check_totally_ordered_with()); + +static_assert( + check_totally_ordered_with()); +static_assert(check_totally_ordered_with()); +static_assert( + check_totally_ordered_with()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(std::equality_comparable_with && + !check_totally_ordered_with()); +static_assert(std::equality_comparable_with && + !check_totally_ordered_with()); +static_assert(std::equality_comparable_with && + !check_totally_ordered_with()); +static_assert(std::equality_comparable_with && + !check_totally_ordered_with()); +static_assert(check_totally_ordered_with()); +static_assert( + check_totally_ordered_with()); + +static_assert( + std::totally_ordered&& + std::equality_comparable_with && + !check_totally_ordered_with()); +static_assert( + std::totally_ordered&& + std::equality_comparable_with && + !check_totally_ordered_with()); +static_assert( + std::totally_ordered&& + std::equality_comparable_with && + !check_totally_ordered_with()); +static_assert( + std::totally_ordered&& + std::equality_comparable_with && + !check_totally_ordered_with()); +} // namespace types_fit_for_purpose + +int main(int, char**) { return 0; } diff --git a/libcxx/test/std/concepts/concepts.compare/types.h b/libcxx/test/std/concepts/concepts.compare/types.h --- a/libcxx/test/std/concepts/concepts.compare/types.h +++ b/libcxx/test/std/concepts/concepts.compare/types.h @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -#ifndef TEST_STD_CONCEPTS_COMPARISON_EQUALITYCOMPARABLE_H -#define TEST_STD_CONCEPTS_COMPARISON_EQUALITYCOMPARABLE_H +#ifndef TEST_STD_CONCEPTS_COMPARISON_TYPES_H +#define TEST_STD_CONCEPTS_COMPARISON_TYPES_H #include #include @@ -39,6 +39,11 @@ struct explicit_operators { friend bool operator==(explicit_operators, explicit_operators) noexcept; friend bool operator!=(explicit_operators, explicit_operators) noexcept; + friend bool operator<(explicit_operators, explicit_operators) noexcept; + friend bool operator>(explicit_operators, explicit_operators) noexcept; + friend bool operator<=(explicit_operators, explicit_operators) noexcept; + friend bool operator>=(explicit_operators, explicit_operators) noexcept; + friend bool operator<=>(explicit_operators, explicit_operators) noexcept; friend bool operator==(explicit_operators const&, equality_comparable_with_ec1 const&) noexcept; @@ -50,15 +55,18 @@ explicit_operators const&) noexcept; }; -struct eq_neq_different_return_types { - int operator==(eq_neq_different_return_types) const noexcept; - friend long operator!=(eq_neq_different_return_types, - eq_neq_different_return_types) noexcept; +struct different_return_types { + bool operator==(different_return_types) const noexcept; + char operator!=(different_return_types) const noexcept; + short operator<(different_return_types) const noexcept; + int operator>(different_return_types) const noexcept; + long operator<=(different_return_types) const noexcept; + long long operator>=(different_return_types) const noexcept; - friend int operator==(explicit_operators, eq_neq_different_return_types); - friend int operator==(eq_neq_different_return_types, explicit_operators); - friend long operator!=(explicit_operators, eq_neq_different_return_types); - friend long operator!=(eq_neq_different_return_types, explicit_operators); + friend signed char operator==(explicit_operators, different_return_types); + friend unsigned char operator==(different_return_types, explicit_operators); + friend float operator!=(explicit_operators, different_return_types); + friend double operator!=(different_return_types, explicit_operators); operator explicit_operators() const; }; @@ -73,7 +81,7 @@ boolean operator!=(one_member_one_friend) const noexcept; operator explicit_operators() const noexcept; - operator eq_neq_different_return_types() const noexcept; + operator different_return_types() const noexcept; }; struct equality_comparable_with_ec1 { @@ -83,27 +91,120 @@ }; struct no_eq { + friend bool operator==(no_eq, no_eq) = delete; friend bool operator!=(no_eq, no_eq) noexcept; + friend bool operator<(no_eq, no_eq) noexcept; + friend bool operator>(no_eq, no_eq) noexcept; + friend bool operator>=(no_eq, no_eq) noexcept; + friend bool operator<=(no_eq, no_eq) noexcept; }; struct no_neq { friend bool operator==(no_neq, no_neq) noexcept; friend bool operator!=(no_neq, no_neq) = delete; + friend bool operator<(no_eq, no_eq) noexcept; + friend bool operator>(no_eq, no_eq) noexcept; + friend bool operator>=(no_eq, no_eq) noexcept; + friend bool operator<=(no_eq, no_eq) noexcept; +}; + +struct no_lt { + friend bool operator==(no_lt, no_lt) noexcept; + friend bool operator!=(no_lt, no_lt) noexcept; + friend bool operator<(no_lt, no_lt) = delete; + friend bool operator>(no_lt, no_lt) noexcept; + friend bool operator>=(no_lt, no_lt) noexcept; + friend bool operator<=(no_lt, no_lt) noexcept; +}; + +struct no_gt { + friend bool operator==(no_gt, no_gt) noexcept; + friend bool operator!=(no_gt, no_gt) noexcept; + friend bool operator<(no_gt, no_gt) noexcept; + friend bool operator>(no_gt, no_gt) = delete; + friend bool operator>=(no_gt, no_gt) noexcept; + friend bool operator<=(no_gt, no_gt) noexcept; +}; + +struct no_le { + friend bool operator==(no_le, no_le) noexcept; + friend bool operator!=(no_le, no_le) noexcept; + friend bool operator<(no_le, no_le) noexcept; + friend bool operator>(no_le, no_le) noexcept; + friend bool operator>=(no_le, no_le) = delete; + friend bool operator<=(no_le, no_le) noexcept; +}; + +struct no_ge { + friend bool operator==(no_ge, no_ge) noexcept; + friend bool operator!=(no_ge, no_ge) noexcept; + friend bool operator<(no_ge, no_ge) noexcept; + friend bool operator>(no_ge, no_ge) noexcept; + friend bool operator>=(no_ge, no_ge) noexcept; + friend bool operator<=(no_ge, no_ge) = delete; }; struct wrong_return_type_eq { void operator==(wrong_return_type_eq) const noexcept; bool operator!=(wrong_return_type_eq) const noexcept; + bool operator<(wrong_return_type_eq) const noexcept; + bool operator>(wrong_return_type_eq) const noexcept; + bool operator>=(wrong_return_type_eq) const noexcept; + bool operator<=(wrong_return_type_eq) const noexcept; }; struct wrong_return_type_ne { bool operator==(wrong_return_type_ne) const noexcept; void operator!=(wrong_return_type_ne) const noexcept; + bool operator<(wrong_return_type_ne) const noexcept; + bool operator>(wrong_return_type_ne) const noexcept; + bool operator>=(wrong_return_type_ne) const noexcept; + bool operator<=(wrong_return_type_ne) const noexcept; +}; + +struct wrong_return_type_lt { + bool operator==(wrong_return_type_lt) const noexcept; + bool operator!=(wrong_return_type_lt) const noexcept; + void operator<(wrong_return_type_lt) const noexcept; + bool operator>(wrong_return_type_lt) const noexcept; + bool operator>=(wrong_return_type_lt) const noexcept; + bool operator<=(wrong_return_type_lt) const noexcept; +}; + +struct wrong_return_type_gt { + bool operator==(wrong_return_type_gt) const noexcept; + bool operator!=(wrong_return_type_gt) const noexcept; + bool operator<(wrong_return_type_gt) const noexcept; + void operator>(wrong_return_type_gt) const noexcept; + bool operator>=(wrong_return_type_gt) const noexcept; + bool operator<=(wrong_return_type_gt) const noexcept; +}; + +struct wrong_return_type_le { + bool operator==(wrong_return_type_le) const noexcept; + bool operator!=(wrong_return_type_le) const noexcept; + bool operator<(wrong_return_type_le) const noexcept; + bool operator>(wrong_return_type_le) const noexcept; + void operator>=(wrong_return_type_le) const noexcept; + bool operator<=(wrong_return_type_le) const noexcept; +}; + +struct wrong_return_type_ge { + bool operator==(wrong_return_type_ge) const noexcept; + bool operator!=(wrong_return_type_ge) const noexcept; + bool operator<(wrong_return_type_ge) const noexcept; + bool operator>(wrong_return_type_ge) const noexcept; + bool operator>=(wrong_return_type_ge) const noexcept; + void operator<=(wrong_return_type_ge) const noexcept; }; struct wrong_return_type { void operator==(wrong_return_type) const noexcept; void operator!=(wrong_return_type) const noexcept; + void operator<(wrong_return_type) const noexcept; + void operator>(wrong_return_type) const noexcept; + void operator>=(wrong_return_type) const noexcept; + void operator<=(wrong_return_type_ge) const noexcept; }; struct cxx20_member_eq_operator_with_deleted_ne { @@ -177,24 +278,296 @@ explicit operator bool() const noexcept; }; -struct returns_explicit_bool { - friend explicit_bool operator==(returns_explicit_bool, returns_explicit_bool); - friend explicit_bool operator!=(returns_explicit_bool, returns_explicit_bool); +struct totally_ordered_with_others { + auto operator<=>(totally_ordered_with_others const&) const = default; +}; + +struct no_lt_not_totally_ordered_with { + [[nodiscard]] bool + operator==(no_lt_not_totally_ordered_with const&) const = default; + [[nodiscard]] auto + operator<=>(no_lt_not_totally_ordered_with const&) const = default; + operator totally_ordered_with_others() const noexcept; + + [[nodiscard]] bool operator==(totally_ordered_with_others const&) const; + [[nodiscard]] auto operator<=>(totally_ordered_with_others const&) const; + [[nodiscard]] auto operator<(totally_ordered_with_others const&) const; +}; + +struct no_gt_not_totally_ordered_with { + [[nodiscard]] bool + operator==(no_gt_not_totally_ordered_with const&) const = default; + [[nodiscard]] auto + operator<=>(no_gt_not_totally_ordered_with const&) const = default; + operator totally_ordered_with_others() const noexcept; + + [[nodiscard]] bool operator==(totally_ordered_with_others const&) const; + [[nodiscard]] auto operator<=>(totally_ordered_with_others const&) const; + [[nodiscard]] auto operator>(totally_ordered_with_others const&) const; +}; + +struct no_le_not_totally_ordered_with { + [[nodiscard]] bool + operator==(no_le_not_totally_ordered_with const&) const = default; + [[nodiscard]] auto + operator<=>(no_le_not_totally_ordered_with const&) const = default; + operator totally_ordered_with_others() const noexcept; + + [[nodiscard]] bool operator==(totally_ordered_with_others const&) const; + [[nodiscard]] auto operator<=>(totally_ordered_with_others const&) const; + [[nodiscard]] auto operator<=(totally_ordered_with_others const&) const; +}; + +struct no_ge_not_totally_ordered_with { + [[nodiscard]] bool + operator==(no_ge_not_totally_ordered_with const&) const = default; + [[nodiscard]] auto + operator<=>(no_ge_not_totally_ordered_with const&) const = default; + operator totally_ordered_with_others() const noexcept; + + [[nodiscard]] bool operator==(totally_ordered_with_others const&) const; + [[nodiscard]] auto operator<=>(totally_ordered_with_others const&) const; + [[nodiscard]] auto operator>=(totally_ordered_with_others const&) const; +}; + +struct partial_ordering_totally_ordered_with { + [[nodiscard]] auto operator<=>( + partial_ordering_totally_ordered_with const&) const noexcept = default; + [[nodiscard]] std::partial_ordering + operator<=>(totally_ordered_with_others const&) const noexcept; + + operator totally_ordered_with_others() const; +}; + +struct weak_ordering_totally_ordered_with { + [[nodiscard]] auto operator<=>( + weak_ordering_totally_ordered_with const&) const noexcept = default; + [[nodiscard]] std::weak_ordering + operator<=>(totally_ordered_with_others const&) const noexcept; + + operator totally_ordered_with_others() const; +}; + +struct strong_ordering_totally_ordered_with { + [[nodiscard]] auto operator<=>( + strong_ordering_totally_ordered_with const&) const noexcept = default; + [[nodiscard]] std::strong_ordering + operator<=>(totally_ordered_with_others const&) const noexcept; + + operator totally_ordered_with_others() const; +}; + +struct eq_returns_explicit_bool { + friend explicit_bool operator==(eq_returns_explicit_bool, + eq_returns_explicit_bool); + friend bool operator!=(eq_returns_explicit_bool, eq_returns_explicit_bool); + friend bool operator<(eq_returns_explicit_bool, eq_returns_explicit_bool); + friend bool operator>(eq_returns_explicit_bool, eq_returns_explicit_bool); + friend bool operator<=(eq_returns_explicit_bool, eq_returns_explicit_bool); + friend bool operator>=(eq_returns_explicit_bool, eq_returns_explicit_bool); + + operator totally_ordered_with_others() const; + + friend explicit_bool operator==(eq_returns_explicit_bool, + totally_ordered_with_others); + friend explicit_bool operator==(totally_ordered_with_others, + eq_returns_explicit_bool); + friend bool operator!=(eq_returns_explicit_bool, totally_ordered_with_others); + friend bool operator!=(totally_ordered_with_others, eq_returns_explicit_bool); + friend bool operator<(eq_returns_explicit_bool, totally_ordered_with_others); + friend bool operator<(totally_ordered_with_others, eq_returns_explicit_bool); + friend bool operator>(eq_returns_explicit_bool, totally_ordered_with_others); + friend bool operator>(totally_ordered_with_others, eq_returns_explicit_bool); + friend bool operator<=(eq_returns_explicit_bool, totally_ordered_with_others); + friend bool operator<=(totally_ordered_with_others, eq_returns_explicit_bool); + friend bool operator>=(eq_returns_explicit_bool, totally_ordered_with_others); + friend bool operator>=(totally_ordered_with_others, eq_returns_explicit_bool); +}; + +struct ne_returns_explicit_bool { + friend bool operator==(ne_returns_explicit_bool, ne_returns_explicit_bool); + friend explicit_bool operator!=(ne_returns_explicit_bool, + ne_returns_explicit_bool); + friend bool operator<(ne_returns_explicit_bool, ne_returns_explicit_bool); + friend bool operator>(ne_returns_explicit_bool, ne_returns_explicit_bool); + friend bool operator<=(ne_returns_explicit_bool, ne_returns_explicit_bool); + friend bool operator>=(ne_returns_explicit_bool, ne_returns_explicit_bool); + + operator totally_ordered_with_others() const; + + friend bool operator==(ne_returns_explicit_bool, totally_ordered_with_others); + friend explicit_bool operator!=(ne_returns_explicit_bool, + totally_ordered_with_others); + friend explicit_bool operator!=(totally_ordered_with_others, + ne_returns_explicit_bool); + friend bool operator<(ne_returns_explicit_bool, totally_ordered_with_others); + friend bool operator<(totally_ordered_with_others, ne_returns_explicit_bool); + friend bool operator>(ne_returns_explicit_bool, totally_ordered_with_others); + friend bool operator>(totally_ordered_with_others, ne_returns_explicit_bool); + friend bool operator<=(ne_returns_explicit_bool, totally_ordered_with_others); + friend bool operator<=(totally_ordered_with_others, ne_returns_explicit_bool); + friend bool operator>=(ne_returns_explicit_bool, totally_ordered_with_others); + friend bool operator>=(totally_ordered_with_others, ne_returns_explicit_bool); +}; + +struct lt_returns_explicit_bool { + friend bool operator==(lt_returns_explicit_bool, lt_returns_explicit_bool); + friend bool operator!=(lt_returns_explicit_bool, lt_returns_explicit_bool); + friend explicit_bool operator<(lt_returns_explicit_bool, + lt_returns_explicit_bool); + friend bool operator>(lt_returns_explicit_bool, lt_returns_explicit_bool); + friend bool operator<=(lt_returns_explicit_bool, lt_returns_explicit_bool); + friend bool operator>=(lt_returns_explicit_bool, lt_returns_explicit_bool); + + operator totally_ordered_with_others() const; + + friend bool operator==(lt_returns_explicit_bool, totally_ordered_with_others); + friend bool operator!=(lt_returns_explicit_bool, totally_ordered_with_others); + friend bool operator!=(totally_ordered_with_others, lt_returns_explicit_bool); + friend explicit_bool operator<(lt_returns_explicit_bool, + totally_ordered_with_others); + friend bool operator<(totally_ordered_with_others, lt_returns_explicit_bool); + friend bool operator>(lt_returns_explicit_bool, totally_ordered_with_others); + friend bool operator>(totally_ordered_with_others, lt_returns_explicit_bool); + friend bool operator<=(lt_returns_explicit_bool, totally_ordered_with_others); + friend bool operator<=(totally_ordered_with_others, lt_returns_explicit_bool); + friend bool operator>=(lt_returns_explicit_bool, totally_ordered_with_others); + friend bool operator>=(totally_ordered_with_others, lt_returns_explicit_bool); +}; + +struct gt_returns_explicit_bool { + friend bool operator==(gt_returns_explicit_bool, gt_returns_explicit_bool); + friend bool operator!=(gt_returns_explicit_bool, gt_returns_explicit_bool); + friend bool operator<(gt_returns_explicit_bool, gt_returns_explicit_bool); + friend explicit_bool operator>(gt_returns_explicit_bool, + gt_returns_explicit_bool); + friend bool operator<=(gt_returns_explicit_bool, gt_returns_explicit_bool); + friend bool operator>=(gt_returns_explicit_bool, gt_returns_explicit_bool); + + operator totally_ordered_with_others() const; + + friend bool operator==(gt_returns_explicit_bool, totally_ordered_with_others); + friend bool operator!=(gt_returns_explicit_bool, totally_ordered_with_others); + friend bool operator!=(totally_ordered_with_others, gt_returns_explicit_bool); + friend bool operator<(gt_returns_explicit_bool, totally_ordered_with_others); + friend bool operator<(totally_ordered_with_others, gt_returns_explicit_bool); + friend explicit_bool operator>(gt_returns_explicit_bool, + totally_ordered_with_others); + friend bool operator>(totally_ordered_with_others, gt_returns_explicit_bool); + friend bool operator<=(gt_returns_explicit_bool, totally_ordered_with_others); + friend bool operator<=(totally_ordered_with_others, gt_returns_explicit_bool); + friend bool operator>=(gt_returns_explicit_bool, totally_ordered_with_others); + friend bool operator>=(totally_ordered_with_others, gt_returns_explicit_bool); +}; + +struct le_returns_explicit_bool { + friend bool operator==(le_returns_explicit_bool, le_returns_explicit_bool); + friend bool operator!=(le_returns_explicit_bool, le_returns_explicit_bool); + friend bool operator<(le_returns_explicit_bool, le_returns_explicit_bool); + friend bool operator>(le_returns_explicit_bool, le_returns_explicit_bool); + friend explicit_bool operator<=(le_returns_explicit_bool, + le_returns_explicit_bool); + friend bool operator>=(le_returns_explicit_bool, le_returns_explicit_bool); + + operator totally_ordered_with_others() const; + + friend bool operator==(le_returns_explicit_bool, totally_ordered_with_others); + friend bool operator!=(le_returns_explicit_bool, totally_ordered_with_others); + friend bool operator!=(totally_ordered_with_others, le_returns_explicit_bool); + friend bool operator<(le_returns_explicit_bool, totally_ordered_with_others); + friend bool operator<(totally_ordered_with_others, le_returns_explicit_bool); + friend bool operator>(le_returns_explicit_bool, totally_ordered_with_others); + friend bool operator>(totally_ordered_with_others, le_returns_explicit_bool); + friend bool operator<=(le_returns_explicit_bool, totally_ordered_with_others); + friend explicit_bool operator<=(totally_ordered_with_others, + le_returns_explicit_bool); + friend bool operator>=(le_returns_explicit_bool, totally_ordered_with_others); + friend bool operator>=(totally_ordered_with_others, le_returns_explicit_bool); +}; + +struct ge_returns_explicit_bool { + friend bool operator==(ge_returns_explicit_bool, ge_returns_explicit_bool); + friend bool operator!=(ge_returns_explicit_bool, ge_returns_explicit_bool); + friend bool operator<(ge_returns_explicit_bool, ge_returns_explicit_bool); + friend bool operator>(ge_returns_explicit_bool, ge_returns_explicit_bool); + friend bool operator<=(ge_returns_explicit_bool, ge_returns_explicit_bool); + friend explicit_bool operator>=(ge_returns_explicit_bool, + ge_returns_explicit_bool); + + operator totally_ordered_with_others() const; + + friend bool operator==(ge_returns_explicit_bool, totally_ordered_with_others); + friend bool operator!=(ge_returns_explicit_bool, totally_ordered_with_others); + friend bool operator!=(totally_ordered_with_others, ge_returns_explicit_bool); + friend bool operator<(ge_returns_explicit_bool, totally_ordered_with_others); + friend bool operator<(totally_ordered_with_others, ge_returns_explicit_bool); + friend bool operator>(ge_returns_explicit_bool, totally_ordered_with_others); + friend bool operator>(totally_ordered_with_others, ge_returns_explicit_bool); + friend bool operator<=(ge_returns_explicit_bool, totally_ordered_with_others); + friend bool operator<=(totally_ordered_with_others, ge_returns_explicit_bool); + friend bool operator>=(ge_returns_explicit_bool, totally_ordered_with_others); + friend explicit_bool operator>=(totally_ordered_with_others, + ge_returns_explicit_bool); }; struct returns_true_type { friend std::true_type operator==(returns_true_type, returns_true_type); friend std::true_type operator!=(returns_true_type, returns_true_type); -}; - -struct returns_false_type { - friend std::false_type operator==(returns_false_type, returns_false_type); - friend std::false_type operator!=(returns_false_type, returns_false_type); + friend std::true_type operator<(returns_true_type, returns_true_type); + friend std::true_type operator>(returns_true_type, returns_true_type); + friend std::true_type operator<=(returns_true_type, returns_true_type); + friend std::true_type operator>=(returns_true_type, returns_true_type); + + operator totally_ordered_with_others() const; + + friend std::true_type operator==(returns_true_type, + totally_ordered_with_others); + friend std::true_type operator==(totally_ordered_with_others, + returns_true_type); + friend std::true_type operator!=(returns_true_type, + totally_ordered_with_others); + friend std::true_type operator!=(totally_ordered_with_others, + returns_true_type); + friend std::true_type operator<(returns_true_type, + totally_ordered_with_others); + friend std::true_type operator<(totally_ordered_with_others, + returns_true_type); + friend std::true_type operator>(returns_true_type, + totally_ordered_with_others); + friend std::true_type operator>(totally_ordered_with_others, + returns_true_type); + friend std::true_type operator<=(returns_true_type, + totally_ordered_with_others); + friend std::true_type operator<=(totally_ordered_with_others, + returns_true_type); + friend std::true_type operator>=(returns_true_type, + totally_ordered_with_others); + friend std::true_type operator>=(totally_ordered_with_others, + returns_true_type); }; struct returns_int_ptr { friend int* operator==(returns_int_ptr, returns_int_ptr); friend int* operator!=(returns_int_ptr, returns_int_ptr); + friend int* operator<(returns_int_ptr, returns_int_ptr); + friend int* operator>(returns_int_ptr, returns_int_ptr); + friend int* operator<=(returns_int_ptr, returns_int_ptr); + friend int* operator>=(returns_int_ptr, returns_int_ptr); + + operator totally_ordered_with_others() const; + + friend int* operator==(returns_int_ptr, totally_ordered_with_others); + friend int* operator==(totally_ordered_with_others, returns_int_ptr); + friend int* operator!=(returns_int_ptr, totally_ordered_with_others); + friend int* operator!=(totally_ordered_with_others, returns_int_ptr); + friend int* operator<(returns_int_ptr, totally_ordered_with_others); + friend int* operator<(totally_ordered_with_others, returns_int_ptr); + friend int* operator>(returns_int_ptr, totally_ordered_with_others); + friend int* operator>(totally_ordered_with_others, returns_int_ptr); + friend int* operator<=(returns_int_ptr, totally_ordered_with_others); + friend int* operator<=(totally_ordered_with_others, returns_int_ptr); + friend int* operator>=(returns_int_ptr, totally_ordered_with_others); + friend int* operator>=(totally_ordered_with_others, returns_int_ptr); }; -#endif // TEST_STD_CONCEPTS_COMPARISON_EQUALITYCOMPARABLE_H +#endif // TEST_STD_CONCEPTS_COMPARISON_TYPES_H