diff --git a/libcxx/include/concepts b/libcxx/include/concepts --- a/libcxx/include/concepts +++ b/libcxx/include/concepts @@ -243,6 +243,38 @@ concept move_constructible = constructible_from<_Tp, _Tp> && convertible_to<_Tp, _Tp>; +// [concept.booleantestable] +template +concept __boolean_testable_impl = convertible_to<_Tp, bool>; + +template +concept __boolean_testable = __boolean_testable_impl<_Tp> && requires(_Tp&& __t) { + { !std::forward<_Tp>(__t) } -> __boolean_testable_impl; +}; + +// [concept.equalitycomparable] +template +concept __weakly_equality_comparable_with = + requires(const remove_reference_t<_Tp>& __t, const remove_reference_t<_Up>& __u) { + { __t == __u } -> __boolean_testable; + { __t != __u } -> __boolean_testable; + { __u == __t } -> __boolean_testable; + { __u != __t } -> __boolean_testable; + }; + +template +concept equality_comparable = __weakly_equality_comparable_with<_Tp, _Tp>; + +template +concept equality_comparable_with = + equality_comparable<_Tp> && equality_comparable<_Up> && + common_reference_with&, const remove_reference_t<_Up>&> && + equality_comparable< + common_reference_t< + const remove_reference_t<_Tp>&, + const remove_reference_t<_Up>&>> && + __weakly_equality_comparable_with<_Tp, _Up>; + // [concept.copyconstructible] template concept copy_constructible = diff --git a/libcxx/test/std/concepts/comparison/concepts.equalitycomparable/equality_comparable.compile.pass.cpp b/libcxx/test/std/concepts/comparison/concepts.equalitycomparable/equality_comparable.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/concepts/comparison/concepts.equalitycomparable/equality_comparable.compile.pass.cpp @@ -0,0 +1,143 @@ +//===----------------------------------------------------------------------===// +// +// 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 equality_comparable = // see below + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../types.h" + +namespace fundamentals { +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); + +struct S {}; +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); +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 fundamentals + +namespace standard_types { +static_assert(std::equality_comparable >); +static_assert(std::equality_comparable >); +static_assert(std::equality_comparable >); +static_assert(std::equality_comparable >); + +#ifndef _LIBCPP_HAS_NO_THREADS +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 >); +#endif + +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 standard_types + +namespace types_fit_for_purpose { +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); +static_assert(std::equality_comparable); +static_assert(std::equality_comparable); +} // namespace types_fit_for_purpose + +int main(int, char**) { return 0; } diff --git a/libcxx/test/std/concepts/comparison/concepts.equalitycomparable/equality_comparable_with.compile.pass.cpp b/libcxx/test/std/concepts/comparison/concepts.equalitycomparable/equality_comparable_with.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/concepts/comparison/concepts.equalitycomparable/equality_comparable_with.compile.pass.cpp @@ -0,0 +1,1120 @@ +//===----------------------------------------------------------------------===// +// +// 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 equality_comparable_with = // see below + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../types.h" + +template +constexpr bool check_equality_comparable_with() { + constexpr bool result = std::equality_comparable_with; + static_assert(std::equality_comparable_with == result); + static_assert(std::equality_comparable_with == result); + static_assert(std::equality_comparable_with == result); + static_assert(std::equality_comparable_with == result); + static_assert(std::equality_comparable_with == result); + static_assert(std::equality_comparable_with == result); + static_assert(std::equality_comparable_with == result); + static_assert(std::equality_comparable_with == result); + static_assert(std::equality_comparable_with == result); + static_assert(std::equality_comparable_with == result); + static_assert(std::equality_comparable_with == result); + static_assert(std::equality_comparable_with == result); + static_assert(std::equality_comparable_with == result); + static_assert(std::equality_comparable_with == result); + static_assert(std::equality_comparable_with == result); + static_assert(std::equality_comparable_with == result); + static_assert(std::equality_comparable_with == result); + static_assert(std::equality_comparable_with == result); + static_assert(std::equality_comparable_with == result); + return result; +} + +namespace fundamentals { +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()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with()); + +struct S {}; +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()); +static_assert(!check_equality_comparable_with()); +static_assert( + !check_equality_comparable_with()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int, int (S::*)() const volatile noexcept>()); +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()); +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 < int, + int (S::*)() && noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int, + int (S::*)() const&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int, + int (S::*)() volatile&& noexcept > ()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int, + int (S::*)() const volatile&& noexcept > ()); + +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()); +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()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int*, int (S::*)() const volatile noexcept>()); +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()); +static_assert( + !check_equality_comparable_with()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int*, int (S::*)() const volatile & noexcept>()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int*, + int (S::*)() && noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int*, + int (S::*)() const&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int*, + int (S::*)() volatile&& noexcept > ()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int*, + int (S::*)() const volatile&& noexcept > ()); + +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()); +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()); +static_assert(!check_equality_comparable_with< + int[5], int (S::*)() const volatile noexcept>()); +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()); +static_assert(!check_equality_comparable_with()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int[5], int (S::*)() const volatile & noexcept>()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int[5], + int (S::*)() && noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int[5], + int (S::*)() const&& noexcept > ()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int[5], + int (S::*)() volatile&& noexcept > ()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int[5], + int (S::*)() const volatile&& noexcept > ()); + +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()); +static_assert( + !check_equality_comparable_with()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int (*)(), int (S::*)() volatile noexcept>()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int (*)(), int (S::*)() const volatile noexcept>()); +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()); +static_assert(!check_equality_comparable_with()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int (*)(), int (S::*)() const volatile & noexcept>()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (*)(), + int (S::*)() && noexcept > ()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (*)(), + int (S::*)() const&& noexcept > ()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (*)(), + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (*)(), + int (S::*)() const volatile&& noexcept > ()); + +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()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int (&)(), int (S::*)() volatile noexcept>()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int (&)(), int (S::*)() const volatile noexcept>()); +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()); +static_assert(!check_equality_comparable_with()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int (&)(), int (S::*)() const volatile & noexcept>()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (&)(), + int (S::*)() && noexcept > ()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (&)(), + int (S::*)() const&& noexcept > ()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (&)(), + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (&)(), + int (S::*)() const volatile&& noexcept > ()); + +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()); +static_assert(!check_equality_comparable_with< + int (S::*)(), int (S::*)() volatile noexcept>()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int (S::*)(), int (S::*)() const volatile noexcept>()); +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()); +static_assert(!check_equality_comparable_with< + int (S::*)(), int (S::*)() volatile & noexcept>()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int (S::*)(), int (S::*)() const volatile & noexcept>()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)(), + int (S::*)() && noexcept > ()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)(), + int (S::*)() const&& noexcept > ()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)(), + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)(), + int (S::*)() const volatile&& noexcept > ()); + +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< + int (S::*)() noexcept, int (S::*)() volatile noexcept>()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int (S::*)() noexcept, int (S::*)() const volatile noexcept>()); +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()); +static_assert(!check_equality_comparable_with< + int (S::*)() noexcept, int (S::*)() volatile & noexcept>()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int (S::*)() noexcept, int (S::*)() const volatile & noexcept>()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() noexcept, + int (S::*)() && noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() noexcept, + int (S::*)() const&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() noexcept, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() noexcept, + int (S::*)() const volatile&& noexcept > ()); + +static_assert( + check_equality_comparable_with()); +static_assert(check_equality_comparable_with()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int (S::*)() const, int (S::*)() volatile noexcept>()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int (S::*)() const, int (S::*)() const volatile noexcept>()); +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()); +static_assert(!check_equality_comparable_with< + int (S::*)() const, int (S::*)() volatile & noexcept>()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int (S::*)() const, int (S::*)() const volatile & noexcept>()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() const, + int (S::*)() && noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() const, + int (S::*)() const&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() const, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() const, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(check_equality_comparable_with()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int (S::*)() const noexcept, int (S::*)() volatile noexcept>()); +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()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int (S::*)() const noexcept, int (S::*)() volatile & noexcept>()); +static_assert(!check_equality_comparable_with()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() const noexcept, + int (S::*)() && noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() const noexcept, + int (S::*)() const&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() const noexcept, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() const noexcept, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(check_equality_comparable_with()); +static_assert(check_equality_comparable_with()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int (S::*)() volatile, int (S::*)() const volatile noexcept>()); +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()); +static_assert(!check_equality_comparable_with< + int (S::*)() volatile, int (S::*)() volatile & noexcept>()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int (S::*)() volatile, int (S::*)() const volatile & noexcept>()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() volatile, + int (S::*)() && noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() volatile, + int (S::*)() const&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() volatile, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() volatile, + int (S::*)() const volatile&& noexcept > ()); + +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()); +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()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() volatile noexcept, + int (S::*)() && noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() volatile noexcept, + int (S::*)() const&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() volatile noexcept, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() volatile noexcept, + int (S::*)() const volatile&& noexcept > ()); + +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()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int (S::*)() const volatile, int (S::*)() volatile & noexcept>()); +static_assert(!check_equality_comparable_with()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() const volatile, + int (S::*)() && noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() const volatile, + int (S::*)() const&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() const volatile, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() const volatile, + int (S::*)() const volatile&& noexcept > ()); + +static_assert( + check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int (S::*)() const volatile noexcept, int (S::*)() &>()); +static_assert(!check_equality_comparable_with< + int (S::*)() const volatile noexcept, int (S::*)() & noexcept>()); +static_assert(!check_equality_comparable_with< + int (S::*)() const volatile noexcept, int (S::*)() const&>()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int (S::*)() const volatile noexcept, int (S::*)() volatile&>()); +static_assert( + !check_equality_comparable_with()); +static_assert( + !check_equality_comparable_with()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int (S::*)() const volatile noexcept, int (S::*)() &&>()); +static_assert(!check_equality_comparable_with < int (S::*)() + const volatile noexcept, + int (S::*)() && noexcept > ()); +static_assert(!check_equality_comparable_with< + int (S::*)() const volatile noexcept, int (S::*)() const&&>()); +static_assert(!check_equality_comparable_with < int (S::*)() + const volatile noexcept, + int (S::*)() const&& noexcept > ()); +static_assert(!check_equality_comparable_with< + int (S::*)() const volatile noexcept, int (S::*)() volatile&&>()); +static_assert(!check_equality_comparable_with < int (S::*)() + const volatile noexcept, + int (S::*)() volatile&& noexcept > ()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() + const volatile noexcept, + int (S::*)() const volatile&& noexcept > ()); + +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()); +static_assert(!check_equality_comparable_with< + int (S::*)() &, int (S::*)() volatile & noexcept>()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int (S::*)() &, int (S::*)() const volatile & noexcept>()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() &, + int (S::*)() && noexcept > ()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() &, + int (S::*)() const&& noexcept > ()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() &, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() &, + int (S::*)() const volatile&& noexcept > ()); + +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< + int (S::*)() & noexcept, int (S::*)() volatile & noexcept>()); +static_assert(!check_equality_comparable_with()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() & noexcept, + int (S::*)() && noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() & noexcept, + int (S::*)() const&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() & noexcept, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() & noexcept, + int (S::*)() const volatile&& noexcept > ()); + +static_assert( + check_equality_comparable_with()); +static_assert(check_equality_comparable_with()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int (S::*)() const&, int (S::*)() volatile & noexcept>()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int (S::*)() const&, int (S::*)() const volatile & noexcept>()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() const&, + int (S::*)() && noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() const&, + int (S::*)() const&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() const&, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() const&, + int (S::*)() const volatile&& noexcept > ()); + +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()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() const& noexcept, + int (S::*)() && noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() const& noexcept, + int (S::*)() const&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() const& noexcept, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() const& noexcept, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(check_equality_comparable_with()); +static_assert(check_equality_comparable_with< + int (S::*)() volatile&, int (S::*)() volatile & noexcept>()); +static_assert(!check_equality_comparable_with()); +static_assert( + !check_equality_comparable_with()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() volatile&, + int (S::*)() && noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() volatile&, + int (S::*)() const&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() volatile&, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() volatile&, + int (S::*)() const volatile&& noexcept > ()); + +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 < int (S::*)() volatile& noexcept, + int (S::*)() && noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() volatile& noexcept, + int (S::*)() const&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() volatile& noexcept, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() volatile& noexcept, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(check_equality_comparable_with()); +static_assert( + check_equality_comparable_with()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() const volatile&, + int (S::*)() && noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() const volatile&, + int (S::*)() const&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() const volatile&, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() const volatile&, + int (S::*)() const volatile&& noexcept > ()); + +static_assert( + check_equality_comparable_with()); +static_assert(!check_equality_comparable_with< + int (S::*)() const volatile & noexcept, int (S::*)() &&>()); +static_assert(!check_equality_comparable_with < int (S::*)() + const volatile& noexcept, + int (S::*)() && noexcept > ()); +static_assert(!check_equality_comparable_with< + int (S::*)() const volatile & noexcept, int (S::*)() const&&>()); +static_assert(!check_equality_comparable_with < int (S::*)() + const volatile& noexcept, + int (S::*)() const&& noexcept > ()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() + const volatile& noexcept, + int (S::*)() volatile&& noexcept > ()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() + const volatile& noexcept, + int (S::*)() const volatile&& noexcept > ()); + +static_assert( + check_equality_comparable_with()); +static_assert(check_equality_comparable_with()); +static_assert( + !check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() &&, + int (S::*)() const&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() &&, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() &&, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() && noexcept, + int (S::*)() const&& > ()); +static_assert(!check_equality_comparable_with < int (S::*)() && noexcept, + int (S::*)() const&& noexcept > ()); +static_assert(!check_equality_comparable_with < int (S::*)() && noexcept, + int (S::*)() volatile&& > ()); +static_assert(!check_equality_comparable_with < int (S::*)() && noexcept, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_equality_comparable_with < int (S::*)() && noexcept, + int (S::*)() const volatile&& > ()); +static_assert(!check_equality_comparable_with < int (S::*)() && noexcept, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(check_equality_comparable_with()); +static_assert(check_equality_comparable_with()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() const&&, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() const&&, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() const&& noexcept, + int (S::*)() volatile&& > ()); +static_assert(!check_equality_comparable_with < int (S::*)() const&& noexcept, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_equality_comparable_with < int (S::*)() const&& noexcept, + int (S::*)() const volatile&& > ()); +static_assert(!check_equality_comparable_with < int (S::*)() const&& noexcept, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(check_equality_comparable_with()); +static_assert(check_equality_comparable_with< + int (S::*)() volatile&&, int (S::*)() volatile && noexcept>()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < int (S::*)() volatile&&, + int (S::*)() const volatile&& noexcept > ()); + +static_assert( + check_equality_comparable_with()); +static_assert(!check_equality_comparable_with < + int (S::*)() volatile&& noexcept, + int (S::*)() const volatile&& > ()); +static_assert(!check_equality_comparable_with < + int (S::*)() volatile&& noexcept, + int (S::*)() const volatile&& noexcept > ()); + +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()); +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()); +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()); +static_assert(check_equality_comparable_with< + std::nullptr_t, int (S::*)() const volatile noexcept>()); +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()); +static_assert(check_equality_comparable_with< + std::nullptr_t, int (S::*)() volatile & noexcept>()); +static_assert(check_equality_comparable_with()); +static_assert(check_equality_comparable_with< + std::nullptr_t, int (S::*)() const volatile & noexcept>()); +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()); +static_assert(check_equality_comparable_with< + std::nullptr_t, int (S::*)() volatile && noexcept>()); +static_assert(check_equality_comparable_with()); +static_assert(check_equality_comparable_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_equality_comparable_with, + std::array >()); +static_assert(!check_equality_comparable_with, + std::array >()); +static_assert( + check_equality_comparable_with, std::deque >()); +static_assert( + !check_equality_comparable_with, std::vector >()); +static_assert(check_equality_comparable_with, + std::forward_list >()); +static_assert(!check_equality_comparable_with, + std::vector >()); +static_assert( + check_equality_comparable_with, std::list >()); +static_assert( + !check_equality_comparable_with, std::vector >()); + +#ifndef _LIBCPP_HAS_NO_THREADS +static_assert(!check_equality_comparable_with, + std::lock_guard >()); +static_assert(!check_equality_comparable_with, + std::vector >()); +static_assert(!check_equality_comparable_with()); +static_assert(!check_equality_comparable_with >()); +#endif + +static_assert(check_equality_comparable_with, + std::map >()); +static_assert( + !check_equality_comparable_with, std::vector >()); +static_assert( + check_equality_comparable_with >, + std::optional > >()); +static_assert(check_equality_comparable_with >, + std::vector >()); +static_assert( + check_equality_comparable_with, std::vector >()); +static_assert(!check_equality_comparable_with, int>()); +} // namespace standard_types + +namespace types_fit_for_purpose { +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()); +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()); +static_assert(check_equality_comparable_with()); + +static_assert(check_equality_comparable_with()); +static_assert( + std::common_reference_with); +static_assert( + !check_equality_comparable_with()); + +static_assert(check_equality_comparable_with()); +static_assert( + std::common_reference_with); +static_assert( + !check_equality_comparable_with()); +} // namespace types_fit_for_purpose + +int main(int, char**) { return 0; } diff --git a/libcxx/test/std/concepts/comparison/types.h b/libcxx/test/std/concepts/comparison/types.h new file mode 100644 --- /dev/null +++ b/libcxx/test/std/concepts/comparison/types.h @@ -0,0 +1,200 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +#ifndef TEST_STD_CONCEPTS_COMPARISON_EQUALITYCOMPARABLE_H +#define TEST_STD_CONCEPTS_COMPARISON_EQUALITYCOMPARABLE_H + +#include +#include +#include + +// `noexcept` specifiers deliberately imperfect since not all programmers bother to put the +// specifiers on their overloads. + +struct equality_comparable_with_ec1; +struct no_neq; + +struct cxx20_member_eq { + bool operator==(cxx20_member_eq const&) const = default; +}; + +struct cxx20_friend_eq { + friend bool operator==(cxx20_friend_eq const&, + cxx20_friend_eq const&) = default; +}; + +struct member_three_way_comparable { + auto operator<=>(member_three_way_comparable const&) const = default; +}; + +struct friend_three_way_comparable { + friend auto operator<=>(friend_three_way_comparable const&, + friend_three_way_comparable const&) = default; +}; + +struct explicit_operators { + 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; + friend bool operator==(equality_comparable_with_ec1 const&, + explicit_operators const&) noexcept; + friend bool operator!=(explicit_operators const&, + equality_comparable_with_ec1 const&) noexcept; + friend bool operator!=(equality_comparable_with_ec1 const&, + 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; + + 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); + + operator explicit_operators() const; +}; + +struct boolean { + operator bool() const noexcept; +}; + +struct one_member_one_friend { + friend boolean operator==(one_member_one_friend, + one_member_one_friend) noexcept; + boolean operator!=(one_member_one_friend) const noexcept; + + operator explicit_operators() const noexcept; + operator eq_neq_different_return_types() const noexcept; +}; + +struct equality_comparable_with_ec1 { + bool operator==(equality_comparable_with_ec1) const noexcept; + bool operator!=(equality_comparable_with_ec1) const noexcept; + operator explicit_operators() const noexcept; +}; + +struct no_eq { + 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; +}; + +struct wrong_return_type_eq { + void 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; +}; + +struct wrong_return_type { + void operator==(wrong_return_type) const noexcept; + void operator!=(wrong_return_type) const noexcept; +}; + +struct cxx20_member_eq_operator_with_deleted_ne { + bool + operator==(cxx20_member_eq_operator_with_deleted_ne const&) const = default; + bool + operator!=(cxx20_member_eq_operator_with_deleted_ne const&) const = delete; +}; + +struct cxx20_friend_eq_operator_with_deleted_ne { + friend bool + operator==(cxx20_friend_eq_operator_with_deleted_ne const&, + cxx20_friend_eq_operator_with_deleted_ne const&) = default; + friend bool + operator!=(cxx20_friend_eq_operator_with_deleted_ne const&, + cxx20_friend_eq_operator_with_deleted_ne const&) = delete; +}; + +struct member_three_way_comparable_with_deleted_eq { + auto operator<=>(member_three_way_comparable_with_deleted_eq const&) const = + default; + auto + operator==(member_three_way_comparable_with_deleted_eq const&) const = delete; +}; + +struct member_three_way_comparable_with_deleted_ne { + auto operator<=>(member_three_way_comparable_with_deleted_ne const&) const = + default; + auto + operator!=(member_three_way_comparable_with_deleted_ne const&) const = delete; +}; + +struct friend_three_way_comparable_with_deleted_eq { + friend auto + operator<=>(friend_three_way_comparable_with_deleted_eq const&, + friend_three_way_comparable_with_deleted_eq const&) = default; + friend auto + operator==(friend_three_way_comparable_with_deleted_eq const&, + friend_three_way_comparable_with_deleted_eq const&) = delete; +}; + +struct friend_three_way_comparable_with_deleted_ne { + friend auto + operator<=>(friend_three_way_comparable_with_deleted_ne const&, + friend_three_way_comparable_with_deleted_ne const&) = default; + friend auto + operator!=(friend_three_way_comparable_with_deleted_ne const&, + friend_three_way_comparable_with_deleted_ne const&) = delete; +}; + +struct one_way_eq { + bool operator==(one_way_eq const&) const = default; + friend bool operator==(one_way_eq, explicit_operators); + friend bool operator==(explicit_operators, one_way_eq) = delete; + + operator explicit_operators() const; +}; + +struct one_way_ne { + bool operator==(one_way_ne const&) const = default; + friend bool operator==(one_way_ne, explicit_operators); + friend bool operator!=(one_way_ne, explicit_operators) = delete; + + operator explicit_operators() const; +}; +static_assert(requires(explicit_operators const x, one_way_ne const y) { + x != y; +}); + +struct explicit_bool { + 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 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); +}; + +struct returns_int_ptr { + friend int* operator==(returns_int_ptr, returns_int_ptr); + friend int* operator!=(returns_int_ptr, returns_int_ptr); +}; + +#endif // TEST_STD_CONCEPTS_COMPARISON_EQUALITYCOMPARABLE_H