diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -6,6 +6,7 @@ __bsd_locale_fallbacks.h __config __debug + __detail/noexcept_helpers.h __errc __functional_03 __functional_base diff --git a/libcxx/include/__detail/noexcept_helpers.h b/libcxx/include/__detail/noexcept_helpers.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__detail/noexcept_helpers.h @@ -0,0 +1,32 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// 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 _LIBCPP___DETAIL_NOEXCEPT_HELPERS_H +#define _LIBCPP___DETAIL_NOEXCEPT_HELPERS_H + +#include <__config> +#include <__iterator/concepts.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#define _LIBCPP_NOEXCEPT_RETURN(...) \ + noexcept(noexcept(__VA_ARGS__)) { return __VA_ARGS__; } + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___DETAIL_NOEXCEPT_HELPERS_H diff --git a/libcxx/include/functional b/libcxx/include/functional --- a/libcxx/include/functional +++ b/libcxx/include/functional @@ -507,6 +507,8 @@ */ #include <__config> +#include +#include <__detail/noexcept_helpers.h> #include #include #include @@ -3222,6 +3224,80 @@ }; #endif // _LIBCPP_STD_VER > 17 +#if !defined(_LIBCPP_HAS_NO_RANGES) + +namespace ranges { + +struct equal_to { + template + requires equality_comparable_with<_Tp, _Up> + [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const + _LIBCPP_NOEXCEPT_RETURN( + _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) + ) + + using is_transparent = void; +}; + +struct not_equal_to { + template + requires equality_comparable_with<_Tp, _Up> + [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const + _LIBCPP_NOEXCEPT_RETURN( + !(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u)) + ) + + using is_transparent = void; +}; + +struct greater { + template + requires totally_ordered_with<_Tp, _Up> + [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const + _LIBCPP_NOEXCEPT_RETURN( + _VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t) + ) + + using is_transparent = void; +}; + +struct less { + template + requires totally_ordered_with<_Tp, _Up> + [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const + _LIBCPP_NOEXCEPT_RETURN( + _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) + ) + + using is_transparent = void; +}; + +struct greater_equal { + template + requires totally_ordered_with<_Tp, _Up> + [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const + _LIBCPP_NOEXCEPT_RETURN( + !(_VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u)) + ) + + using is_transparent = void; +}; + +struct less_equal { + template + requires totally_ordered_with<_Tp, _Up> + [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const + _LIBCPP_NOEXCEPT_RETURN( + !(_VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t)) + ) + + using is_transparent = void; +}; + +} // namespace ranges + +#endif // !defined(_LIBCPP_HAS_NO_RANGES) + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_FUNCTIONAL diff --git a/libcxx/include/tuple b/libcxx/include/tuple --- a/libcxx/include/tuple +++ b/libcxx/include/tuple @@ -150,6 +150,7 @@ */ #include <__config> +#include <__detail/noexcept_helpers.h> #include <__tuple> #include #include @@ -1465,8 +1466,6 @@ template _LIBCPP_INLINE_VAR constexpr size_t tuple_size_v = tuple_size<_Tp>::value; -#define _LIBCPP_NOEXCEPT_RETURN(...) noexcept(noexcept(__VA_ARGS__)) { return __VA_ARGS__; } - template inline _LIBCPP_INLINE_VISIBILITY constexpr decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t, @@ -1501,8 +1500,6 @@ typename __make_tuple_indices>>::type{}) ) -#undef _LIBCPP_NOEXCEPT_RETURN - #endif // _LIBCPP_STD_VER > 14 #endif // !defined(_LIBCPP_CXX03_LANG) 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 @@ -27,7 +27,7 @@ #include #include -#include "../types.h" +#include "compare_types.h" namespace fundamentals { static_assert(std::equality_comparable); 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 @@ -27,7 +27,7 @@ #include #include -#include "../types.h" +#include "compare_types.h" template constexpr bool check_equality_comparable_with() { 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 --- 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 @@ -26,7 +26,7 @@ #include #include -#include "../types.h" +#include "compare_types.h" #include "test_macros.h" // `models_totally_ordered` checks that `std::totally_ordered` subsumes 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 --- 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 @@ -26,7 +26,7 @@ #include #include -#include "../types.h" +#include "compare_types.h" #include "test_macros.h" template diff --git a/libcxx/test/std/utilities/function.objects/comparisons/greater.pass.cpp b/libcxx/test/std/utilities/function.objects/comparisons/greater.pass.cpp --- a/libcxx/test/std/utilities/function.objects/comparisons/greater.pass.cpp +++ b/libcxx/test/std/utilities/function.objects/comparisons/greater.pass.cpp @@ -30,7 +30,7 @@ { // test total ordering of int* for greater and // greater. - do_pointer_comparison_test(); + do_pointer_comparison_test(); } #if TEST_STD_VER > 11 typedef std::greater<> F2; diff --git a/libcxx/test/std/utilities/function.objects/comparisons/greater_equal.pass.cpp b/libcxx/test/std/utilities/function.objects/comparisons/greater_equal.pass.cpp --- a/libcxx/test/std/utilities/function.objects/comparisons/greater_equal.pass.cpp +++ b/libcxx/test/std/utilities/function.objects/comparisons/greater_equal.pass.cpp @@ -30,7 +30,7 @@ { // test total ordering of int* for greater_equal and // greater_equal. - do_pointer_comparison_test(); + do_pointer_comparison_test(); } #if TEST_STD_VER > 11 typedef std::greater_equal<> F2; diff --git a/libcxx/test/std/utilities/function.objects/comparisons/less.pass.cpp b/libcxx/test/std/utilities/function.objects/comparisons/less.pass.cpp --- a/libcxx/test/std/utilities/function.objects/comparisons/less.pass.cpp +++ b/libcxx/test/std/utilities/function.objects/comparisons/less.pass.cpp @@ -29,7 +29,7 @@ assert(f(6, 36)); { // test total ordering of int* for less and less. - do_pointer_comparison_test(); + do_pointer_comparison_test(); } #if TEST_STD_VER > 11 typedef std::less<> F2; diff --git a/libcxx/test/std/utilities/function.objects/comparisons/less_equal.pass.cpp b/libcxx/test/std/utilities/function.objects/comparisons/less_equal.pass.cpp --- a/libcxx/test/std/utilities/function.objects/comparisons/less_equal.pass.cpp +++ b/libcxx/test/std/utilities/function.objects/comparisons/less_equal.pass.cpp @@ -30,7 +30,7 @@ { // test total ordering of int* for less_equal and // less_equal. - do_pointer_comparison_test(); + do_pointer_comparison_test(); } #if TEST_STD_VER > 11 typedef std::less_equal<> F2; diff --git a/libcxx/test/std/utilities/function.objects/comparisons/pointer_comparison_test_helper.h b/libcxx/test/std/utilities/function.objects/comparisons/pointer_comparison_test_helper.h deleted file mode 100644 --- a/libcxx/test/std/utilities/function.objects/comparisons/pointer_comparison_test_helper.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef POINTER_COMPARISON_TEST_HELPER_H -#define POINTER_COMPARISON_TEST_HELPER_H - -#include -#include -#include -#include - -#include "test_macros.h" - -template class CompareTemplate> -void do_pointer_comparison_test() { - typedef CompareTemplate Compare; - typedef CompareTemplate UIntCompare; -#if TEST_STD_VER > 11 - typedef CompareTemplate VoidCompare; -#else - typedef Compare VoidCompare; -#endif - std::vector > pointers; - const std::size_t test_size = 100; - for (size_t i=0; i < test_size; ++i) - pointers.push_back(std::shared_ptr(new T())); - Compare comp; - UIntCompare ucomp; - VoidCompare vcomp; - for (size_t i=0; i < test_size; ++i) { - for (size_t j=0; j < test_size; ++j) { - T* lhs = pointers[i].get(); - T* rhs = pointers[j].get(); - std::uintptr_t lhs_uint = reinterpret_cast(lhs); - std::uintptr_t rhs_uint = reinterpret_cast(rhs); - assert(comp(lhs, rhs) == ucomp(lhs_uint, rhs_uint)); - assert(vcomp(lhs, rhs) == ucomp(lhs_uint, rhs_uint)); - } - } -} - -#endif // POINTER_COMPARISON_TEST_HELPER_H diff --git a/libcxx/test/std/utilities/function.objects/range.cmp/equal_to.pass.cpp b/libcxx/test/std/utilities/function.objects/range.cmp/equal_to.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/function.objects/range.cmp/equal_to.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// ranges::equal_to + +#include +#include +#include + +#include "test_macros.h" +#include "compare_types.h" +#include "MoveOnly.h" +#include "pointer_comparison_test_helper.h" + +struct NotEqualityComparable { + friend bool operator==(const NotEqualityComparable&, const NotEqualityComparable&); + friend bool operator!=(const NotEqualityComparable&, const NotEqualityComparable&) = delete; +}; + +static_assert(!std::is_invocable_v); +static_assert(!std::is_invocable_v); +static_assert(std::is_invocable_v); + +static_assert(requires { typename std::ranges::equal_to::is_transparent; }); + +constexpr bool test() { + auto fn = std::ranges::equal_to(); + + assert(fn(MoveOnly(42), MoveOnly(42))); + + ForwardingTestObject a; + ForwardingTestObject b; + assert(!fn(a, b)); + assert(fn(std::move(a), std::move(b))); + + assert(!fn(1, 2)); + assert(!fn(2, 1)); + assert(fn(2, 2)); + + assert(!fn(2, 1L)); + + return true; +} + +int main(int, char**) { + + test(); + static_assert(test()); + + // test total ordering of int* for equal_to and equal_to. + do_pointer_comparison_test(); + + return 0; +} diff --git a/libcxx/test/std/utilities/function.objects/range.cmp/greater.pass.cpp b/libcxx/test/std/utilities/function.objects/range.cmp/greater.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/function.objects/range.cmp/greater.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// ranges::greater + +#include +#include +#include + +#include "test_macros.h" +#include "compare_types.h" +#include "MoveOnly.h" +#include "pointer_comparison_test_helper.h" + +struct NotTotallyOrdered { + friend bool operator<(const NotTotallyOrdered&, const NotTotallyOrdered&); +}; + +static_assert(!std::is_invocable_v); +static_assert(!std::is_invocable_v); +static_assert(std::is_invocable_v); + +static_assert(requires { typename std::ranges::greater::is_transparent; }); + +constexpr bool test() { + auto fn = std::ranges::greater(); + + assert(fn(MoveOnly(42), MoveOnly(41))); + + ForwardingTestObject a; + ForwardingTestObject b; + assert(!fn(a, b)); + assert(fn(std::move(a), std::move(b))); + + assert(!fn(2, 2)); + assert(!fn(1, 2)); + assert(fn(2, 1)); + + assert(fn(2, 1L)); + + return true; +} + +int main(int, char**) { + + test(); + static_assert(test()); + + // test total ordering of int* for greater and greater. + do_pointer_comparison_test(); + + return 0; +} diff --git a/libcxx/test/std/utilities/function.objects/range.cmp/greater_equal.pass.cpp b/libcxx/test/std/utilities/function.objects/range.cmp/greater_equal.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/function.objects/range.cmp/greater_equal.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// ranges::greater_equal + +#include +#include +#include + +#include "test_macros.h" +#include "compare_types.h" +#include "MoveOnly.h" +#include "pointer_comparison_test_helper.h" + +struct NotTotallyOrdered { + friend bool operator<(const NotTotallyOrdered&, const NotTotallyOrdered&); +}; + +static_assert(!std::is_invocable_v); +static_assert(!std::is_invocable_v); +static_assert(std::is_invocable_v); + +static_assert(requires { typename std::ranges::greater_equal::is_transparent; }); + +constexpr bool test() { + auto fn = std::ranges::greater_equal(); + + assert(fn(MoveOnly(42), MoveOnly(42))); + + ForwardingTestObject a; + ForwardingTestObject b; + assert(fn(a, b)); + assert(!fn(std::move(a), std::move(b))); + + assert(fn(2, 2)); + assert(fn(2, 1)); + assert(!fn(1, 2)); + + assert(fn(2, 1L)); + + return true; +} + +int main(int, char**) { + + test(); + static_assert(test()); + + // test total ordering of int* for greater_equal and greater_equal. + do_pointer_comparison_test(); + + return 0; +} diff --git a/libcxx/test/std/utilities/function.objects/range.cmp/less.pass.cpp b/libcxx/test/std/utilities/function.objects/range.cmp/less.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/function.objects/range.cmp/less.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// ranges::less + +#include +#include +#include + +#include "test_macros.h" +#include "compare_types.h" +#include "MoveOnly.h" +#include "pointer_comparison_test_helper.h" + +struct NotTotallyOrdered { + friend bool operator<(const NotTotallyOrdered&, const NotTotallyOrdered&); +}; + +static_assert(!std::is_invocable_v); +static_assert(!std::is_invocable_v); +static_assert(std::is_invocable_v); + +static_assert(requires { typename std::ranges::less::is_transparent; }); + +constexpr bool test() { + auto fn = std::ranges::less(); + + assert(fn(MoveOnly(41), MoveOnly(42))); + + ForwardingTestObject a; + ForwardingTestObject b; + assert(!fn(a, b)); + assert(fn(std::move(a), std::move(b))); + + assert(fn(1, 2)); + assert(!fn(2, 2)); + assert(!fn(2, 1)); + + assert(!fn(2, 1L)); + + return true; +} + +int main(int, char**) { + + test(); + static_assert(test()); + + // test total ordering of int* for less and less. + do_pointer_comparison_test(); + + return 0; +} diff --git a/libcxx/test/std/utilities/function.objects/range.cmp/less_equal.pass.cpp b/libcxx/test/std/utilities/function.objects/range.cmp/less_equal.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/function.objects/range.cmp/less_equal.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// ranges::less_equal + +#include +#include +#include + +#include "test_macros.h" +#include "compare_types.h" +#include "MoveOnly.h" +#include "pointer_comparison_test_helper.h" + +struct NotTotallyOrdered { + friend bool operator<(const NotTotallyOrdered&, const NotTotallyOrdered&); +}; + +static_assert(!std::is_invocable_v); +static_assert(!std::is_invocable_v); +static_assert(std::is_invocable_v); + +static_assert(requires { typename std::ranges::less_equal::is_transparent; }); + +constexpr bool test() { + auto fn = std::ranges::less_equal(); + + assert(fn(MoveOnly(41), MoveOnly(42))); + + // These are the opposite of other tests. + ForwardingTestObject a; + ForwardingTestObject b; + assert(fn(a, b)); + assert(!fn(std::move(a), std::move(b))); + + assert(fn(1, 2)); + assert(fn(2, 2)); + assert(!fn(2, 1)); + + assert(!fn(2, 1L)); + + return true; +} + +int main(int, char**) { + + test(); + static_assert(test()); + + // test total ordering of int* for less_equal and less_equal. + do_pointer_comparison_test(); + + return 0; +} diff --git a/libcxx/test/std/utilities/function.objects/range.cmp/not_equal_to.pass.cpp b/libcxx/test/std/utilities/function.objects/range.cmp/not_equal_to.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/function.objects/range.cmp/not_equal_to.pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// ranges::not_equal_to + +#include +#include +#include + +#include "test_macros.h" +#include "compare_types.h" +#include "MoveOnly.h" +#include "pointer_comparison_test_helper.h" + +struct NotEqualityComparable { + friend bool operator==(const NotEqualityComparable&, const NotEqualityComparable&); + friend bool operator!=(const NotEqualityComparable&, const NotEqualityComparable&) = delete; +}; + +static_assert(!std::is_invocable_v); +static_assert(!std::is_invocable_v); +static_assert(std::is_invocable_v); + +static_assert(requires { typename std::ranges::not_equal_to::is_transparent; }); + +constexpr bool test() { + auto fn = std::ranges::not_equal_to(); + + assert(fn(MoveOnly(41), MoveOnly(42))); + + // These are the opposite of other tests. + ForwardingTestObject a; + ForwardingTestObject b; + assert(fn(a, b)); + assert(!fn(std::move(a), std::move(b))); + + assert(fn(1, 2)); + assert(!fn(2, 2)); + assert(fn(2, 1)); + + assert(fn(2, 1L)); + + return true; +} + +int main(int, char**) { + + test(); + static_assert(test()); + + // test total ordering of int* for not_equal_to and not_equal_to. + do_pointer_comparison_test(); + + return 0; +} diff --git a/libcxx/test/std/concepts/concepts.compare/types.h b/libcxx/test/support/compare_types.h rename from libcxx/test/std/concepts/concepts.compare/types.h rename to libcxx/test/support/compare_types.h --- a/libcxx/test/std/concepts/concepts.compare/types.h +++ b/libcxx/test/support/compare_types.h @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -#ifndef TEST_STD_CONCEPTS_COMPARISON_TYPES_H -#define TEST_STD_CONCEPTS_COMPARISON_TYPES_H +#ifndef TEST_SUPPORT_COMPARISON_TYPES_H +#define TEST_SUPPORT_COMPARISON_TYPES_H #include #include @@ -23,8 +23,7 @@ }; struct cxx20_friend_eq { - friend bool operator==(cxx20_friend_eq const&, - cxx20_friend_eq const&) = default; + friend bool operator==(cxx20_friend_eq const&, cxx20_friend_eq const&) = default; }; struct member_three_way_comparable { @@ -32,8 +31,7 @@ }; struct friend_three_way_comparable { - friend auto operator<=>(friend_three_way_comparable const&, - friend_three_way_comparable const&) = default; + friend auto operator<=>(friend_three_way_comparable const&, friend_three_way_comparable const&) = default; }; struct explicit_operators { @@ -43,16 +41,11 @@ 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; - 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; + 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 different_return_types { @@ -76,8 +69,7 @@ }; struct one_member_one_friend { - friend boolean operator==(one_member_one_friend, - one_member_one_friend) noexcept; + 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; @@ -208,51 +200,39 @@ }; 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; + 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; + 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; - bool - operator==(member_three_way_comparable_with_deleted_eq const&) const = delete; + auto operator<=>(member_three_way_comparable_with_deleted_eq const&) const = default; + bool 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; - bool - operator!=(member_three_way_comparable_with_deleted_ne const&) const = delete; + auto operator<=>(member_three_way_comparable_with_deleted_ne const&) const = default; + bool 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 bool - operator==(friend_three_way_comparable_with_deleted_eq const&, - friend_three_way_comparable_with_deleted_eq const&) = delete; + friend auto operator<=>(friend_three_way_comparable_with_deleted_eq const&, + friend_three_way_comparable_with_deleted_eq const&) = default; + friend bool 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 bool - operator!=(friend_three_way_comparable_with_deleted_ne const&, - friend_three_way_comparable_with_deleted_ne const&) = delete; + friend auto operator<=>(friend_three_way_comparable_with_deleted_ne const&, + friend_three_way_comparable_with_deleted_ne const&) = default; + friend bool operator!=(friend_three_way_comparable_with_deleted_ne const&, + friend_three_way_comparable_with_deleted_ne const&) = delete; }; struct one_way_eq { @@ -270,9 +250,7 @@ operator explicit_operators() const; }; -static_assert(requires(explicit_operators const x, one_way_ne const y) { - x != y; -}); +static_assert(requires(explicit_operators const x, one_way_ne const y) { x != y; }); struct explicit_bool { explicit operator bool() const noexcept; @@ -283,10 +261,8 @@ }; 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; + [[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; @@ -295,10 +271,8 @@ }; 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; + [[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; @@ -307,10 +281,8 @@ }; 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; + [[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; @@ -319,10 +291,8 @@ }; 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; + [[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; @@ -331,35 +301,28 @@ }; 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; + [[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; + [[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; + [[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 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); @@ -368,10 +331,8 @@ 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 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); @@ -386,8 +347,7 @@ 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 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); @@ -396,10 +356,8 @@ 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 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); @@ -413,8 +371,7 @@ 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 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); @@ -424,8 +381,7 @@ 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 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); @@ -439,8 +395,7 @@ 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 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); @@ -451,8 +406,7 @@ 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 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); @@ -465,8 +419,7 @@ 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 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; @@ -479,8 +432,7 @@ 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 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); }; @@ -491,8 +443,7 @@ 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); + friend explicit_bool operator>=(ge_returns_explicit_bool, ge_returns_explicit_bool); operator totally_ordered_with_others() const; @@ -506,8 +457,7 @@ 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); + friend explicit_bool operator>=(totally_ordered_with_others, ge_returns_explicit_bool); }; struct returns_true_type { @@ -520,30 +470,18 @@ 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); + 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 { @@ -570,4 +508,24 @@ friend int* operator>=(totally_ordered_with_others, returns_int_ptr); }; -#endif // TEST_STD_CONCEPTS_COMPARISON_TYPES_H +struct ForwardingTestObject { + constexpr bool operator<(ForwardingTestObject&&) && { return true; } + constexpr bool operator<(const ForwardingTestObject&) const& { return false; } + + constexpr bool operator==(ForwardingTestObject&&) && { return true; } + constexpr bool operator==(const ForwardingTestObject&) const& { return false; } + + constexpr bool operator!=(ForwardingTestObject&&) && { return true; } + constexpr bool operator!=(const ForwardingTestObject&) const& { return false; } + + constexpr bool operator<=(ForwardingTestObject&&) && { return true; } + constexpr bool operator<=(const ForwardingTestObject&) const& { return false; } + + constexpr bool operator>(ForwardingTestObject&&) && { return true; } + constexpr bool operator>(const ForwardingTestObject&) const& { return false; } + + constexpr bool operator>=(ForwardingTestObject&&) && { return true; } + constexpr bool operator>=(const ForwardingTestObject&) const& { return false; } +}; + +#endif // TEST_SUPPORT_COMPARISON_TYPES_H diff --git a/libcxx/test/support/pointer_comparison_test_helper.h b/libcxx/test/support/pointer_comparison_test_helper.h new file mode 100644 --- /dev/null +++ b/libcxx/test/support/pointer_comparison_test_helper.h @@ -0,0 +1,56 @@ +#ifndef POINTER_COMPARISON_TEST_HELPER_H +#define POINTER_COMPARISON_TEST_HELPER_H + +#include +#include +#include +#include + +#include "test_macros.h" + +template