[libcxx-commits] [libcxx] 879cbac - [libc++][ranges] Add range.cmp: equal_to, not_equal_to, less, etc.
via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Apr 22 18:06:56 PDT 2021
Author: zoecarver
Date: 2021-04-22T17:33:04-07:00
New Revision: 879cbac08ba17566ad61ff2b9d7180bcab4a0d1e
URL: https://github.com/llvm/llvm-project/commit/879cbac08ba17566ad61ff2b9d7180bcab4a0d1e
DIFF: https://github.com/llvm/llvm-project/commit/879cbac08ba17566ad61ff2b9d7180bcab4a0d1e.diff
LOG: [libc++][ranges] Add range.cmp: equal_to, not_equal_to, less, etc.
Adds the six new concept constrained comparisons.
Differential Revision: https://reviews.llvm.org/D100429
Added:
libcxx/test/std/utilities/function.objects/range.cmp/equal_to.pass.cpp
libcxx/test/std/utilities/function.objects/range.cmp/greater.pass.cpp
libcxx/test/std/utilities/function.objects/range.cmp/greater_equal.pass.cpp
libcxx/test/std/utilities/function.objects/range.cmp/less.pass.cpp
libcxx/test/std/utilities/function.objects/range.cmp/less_equal.pass.cpp
libcxx/test/std/utilities/function.objects/range.cmp/not_equal_to.pass.cpp
libcxx/test/support/compare_types.h
libcxx/test/support/pointer_comparison_test_helper.h
Modified:
libcxx/include/functional
libcxx/test/std/concepts/concepts.compare/concept.equalitycomparable/equality_comparable.compile.pass.cpp
libcxx/test/std/concepts/concepts.compare/concept.equalitycomparable/equality_comparable_with.compile.pass.cpp
libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered.pass.cpp
libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered_with.pass.cpp
libcxx/test/std/utilities/function.objects/comparisons/greater.pass.cpp
libcxx/test/std/utilities/function.objects/comparisons/greater_equal.pass.cpp
libcxx/test/std/utilities/function.objects/comparisons/less.pass.cpp
libcxx/test/std/utilities/function.objects/comparisons/less_equal.pass.cpp
Removed:
libcxx/test/std/concepts/concepts.compare/types.h
libcxx/test/std/utilities/function.objects/comparisons/pointer_comparison_test_helper.h
################################################################################
diff --git a/libcxx/include/functional b/libcxx/include/functional
index 62e9373ad14d0..19d74a3ec6bb8 100644
--- a/libcxx/include/functional
+++ b/libcxx/include/functional
@@ -507,6 +507,7 @@ POLICY: For non-variadic implementations, the number of arguments is limited
*/
#include <__config>
+#include <concepts>
#include <type_traits>
#include <typeinfo>
#include <exception>
@@ -3222,6 +3223,80 @@ struct identity {
};
#endif // _LIBCPP_STD_VER > 17
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+namespace ranges {
+
+struct equal_to {
+ template <class _Tp, class _Up>
+ requires equality_comparable_with<_Tp, _Up>
+ [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
+ noexcept(noexcept(bool(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u)))) {
+ return _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u);
+ }
+
+ using is_transparent = void;
+};
+
+struct not_equal_to {
+ template <class _Tp, class _Up>
+ requires equality_comparable_with<_Tp, _Up>
+ [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
+ noexcept(noexcept(bool(!(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u))))) {
+ return !(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u));
+ }
+
+ using is_transparent = void;
+};
+
+struct greater {
+ template <class _Tp, class _Up>
+ requires totally_ordered_with<_Tp, _Up>
+ [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
+ noexcept(noexcept(bool(_VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t)))) {
+ return _VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t);
+ }
+
+ using is_transparent = void;
+};
+
+struct less {
+ template <class _Tp, class _Up>
+ requires totally_ordered_with<_Tp, _Up>
+ [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
+ noexcept(noexcept(bool(_VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u)))) {
+ return _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u);
+ }
+
+ using is_transparent = void;
+};
+
+struct greater_equal {
+ template <class _Tp, class _Up>
+ requires totally_ordered_with<_Tp, _Up>
+ [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
+ noexcept(noexcept(bool(!(_VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u))))) {
+ return !(_VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u));
+ }
+
+ using is_transparent = void;
+};
+
+struct less_equal {
+ template <class _Tp, class _Up>
+ requires totally_ordered_with<_Tp, _Up>
+ [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
+ noexcept(noexcept(bool(!(_VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t))))) {
+ 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/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
index 0211ee3d531ec..5290e06dc8280 100644
--- 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 <unordered_set>
#include <vector>
-#include "../types.h"
+#include "compare_types.h"
namespace fundamentals {
static_assert(std::equality_comparable<int>);
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
index a65e47f936da8..a9caf8dc6e9bf 100644
--- 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 <unordered_set>
#include <vector>
-#include "../types.h"
+#include "compare_types.h"
template <class T, class U>
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
index fce1efc0cd5d3..03d82ec97557e 100644
--- 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 <unordered_set>
#include <vector>
-#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
index 345abac552fed..199f022f58836 100644
--- 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 <unordered_set>
#include <vector>
-#include "../types.h"
+#include "compare_types.h"
#include "test_macros.h"
template <class T, class U>
diff --git a/libcxx/test/std/utilities/function.objects/comparisons/greater.pass.cpp b/libcxx/test/std/utilities/function.objects/comparisons/greater.pass.cpp
index b1f1fe65667f8..1f79d2351327d 100644
--- 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 @@ int main(int, char**)
{
// test total ordering of int* for greater<int*> and
// greater<void>.
- do_pointer_comparison_test<int, std::greater>();
+ do_pointer_comparison_test<std::greater>();
}
#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
index 30cf7e0bca115..f259b5d27ddb8 100644
--- 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 @@ int main(int, char**)
{
// test total ordering of int* for greater_equal<int*> and
// greater_equal<void>.
- do_pointer_comparison_test<int, std::greater_equal>();
+ do_pointer_comparison_test<std::greater_equal>();
}
#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
index 88b7c784ea7e1..c5da63c1f41ea 100644
--- 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 @@ int main(int, char**)
assert(f(6, 36));
{
// test total ordering of int* for less<int*> and less<void>.
- do_pointer_comparison_test<int, std::less>();
+ do_pointer_comparison_test<std::less>();
}
#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
index 5aa6d799577a3..fe91f2728fd88 100644
--- 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 @@ int main(int, char**)
{
// test total ordering of int* for less_equal<int*> and
// less_equal<void>.
- do_pointer_comparison_test<int, std::less_equal>();
+ do_pointer_comparison_test<std::less_equal>();
}
#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
index ac4df550a3364..0000000000000
--- 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 <vector>
-#include <memory>
-#include <cstdint>
-#include <cassert>
-
-#include "test_macros.h"
-
-template <class T, template<class> class CompareTemplate>
-void do_pointer_comparison_test() {
- typedef CompareTemplate<T*> Compare;
- typedef CompareTemplate<std::uintptr_t> UIntCompare;
-#if TEST_STD_VER > 11
- typedef CompareTemplate<void> VoidCompare;
-#else
- typedef Compare VoidCompare;
-#endif
- std::vector<std::shared_ptr<T> > pointers;
- const std::size_t test_size = 100;
- for (size_t i=0; i < test_size; ++i)
- pointers.push_back(std::shared_ptr<T>(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<std::uintptr_t>(lhs);
- std::uintptr_t rhs_uint = reinterpret_cast<std::uintptr_t>(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
index 0000000000000..c27159407bb5f
--- /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
+
+// <functional>
+
+// ranges::equal_to
+
+#include <functional>
+#include <type_traits>
+#include <cassert>
+
+#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<std::ranges::equal_to, NotEqualityComparable, NotEqualityComparable>);
+static_assert(!std::is_invocable_v<std::ranges::equal_to, int, MoveOnly>);
+static_assert(std::is_invocable_v<std::ranges::equal_to, explicit_operators, explicit_operators>);
+
+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<int*> and equal_to<void>.
+ do_pointer_comparison_test(std::ranges::equal_to());
+
+ 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
index 0000000000000..95f490d951023
--- /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
+
+// <functional>
+
+// ranges::greater
+
+#include <functional>
+#include <type_traits>
+#include <cassert>
+
+#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<std::ranges::greater, NotTotallyOrdered, NotTotallyOrdered>);
+static_assert(!std::is_invocable_v<std::ranges::greater, int, MoveOnly>);
+static_assert(std::is_invocable_v<std::ranges::greater, explicit_operators, explicit_operators>);
+
+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<int*> and greater<void>.
+ do_pointer_comparison_test(std::ranges::greater());
+
+ 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
index 0000000000000..a3e8ff215bb75
--- /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
+
+// <functional>
+
+// ranges::greater_equal
+
+#include <functional>
+#include <type_traits>
+#include <cassert>
+
+#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<std::ranges::greater_equal, NotTotallyOrdered, NotTotallyOrdered>);
+static_assert(!std::is_invocable_v<std::ranges::greater_equal, int, MoveOnly>);
+static_assert(std::is_invocable_v<std::ranges::greater_equal, explicit_operators, explicit_operators>);
+
+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<int*> and greater_equal<void>.
+ do_pointer_comparison_test(std::ranges::greater_equal());
+
+ 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
index 0000000000000..72f54b7b923fb
--- /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
+
+// <functional>
+
+// ranges::less
+
+#include <functional>
+#include <type_traits>
+#include <cassert>
+
+#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<std::ranges::less, NotTotallyOrdered, NotTotallyOrdered>);
+static_assert(!std::is_invocable_v<std::ranges::less, int, MoveOnly>);
+static_assert(std::is_invocable_v<std::ranges::less, explicit_operators, explicit_operators>);
+
+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<int*> and less<void>.
+ do_pointer_comparison_test(std::ranges::less());
+
+ 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
index 0000000000000..05cc56e89d403
--- /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
+
+// <functional>
+
+// ranges::less_equal
+
+#include <functional>
+#include <type_traits>
+#include <cassert>
+
+#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<std::ranges::less_equal, NotTotallyOrdered, NotTotallyOrdered>);
+static_assert(!std::is_invocable_v<std::ranges::less_equal, int, MoveOnly>);
+static_assert(std::is_invocable_v<std::ranges::less_equal, explicit_operators, explicit_operators>);
+
+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<int*> and less_equal<void>.
+ do_pointer_comparison_test(std::ranges::less_equal());
+
+ 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
index 0000000000000..142aaf1f74286
--- /dev/null
+++ b/libcxx/test/std/utilities/function.objects/range.cmp/not_equal_to.pass.cpp
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <functional>
+
+// ranges::not_equal_to
+
+#include <functional>
+#include <type_traits>
+#include <cassert>
+
+#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<std::ranges::equal_to, NotEqualityComparable, NotEqualityComparable>);
+static_assert(!std::is_invocable_v<std::ranges::equal_to, int, MoveOnly>);
+static_assert(std::is_invocable_v<std::ranges::equal_to, explicit_operators, explicit_operators>);
+
+static_assert(requires { typename std::ranges::not_equal_to::is_transparent; });
+
+struct PtrAndNotEqOperator {
+ constexpr operator void*() const { return nullptr; }
+ // We *don't* want operator!= to be picked here.
+ friend constexpr bool operator!=(PtrAndNotEqOperator, PtrAndNotEqOperator) { return true; }
+};
+
+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));
+
+ // Make sure that "ranges::equal_to(x, y) == !ranges::not_equal_to(x, y)", even here.
+ assert(!fn(PtrAndNotEqOperator(), PtrAndNotEqOperator()));
+ assert(std::ranges::equal_to()(PtrAndNotEqOperator(), PtrAndNotEqOperator()));
+
+ return true;
+}
+
+int main(int, char**) {
+
+ test();
+ static_assert(test());
+
+ // test total ordering of int* for not_equal_to<int*> and not_equal_to<void>.
+ do_pointer_comparison_test(std::ranges::not_equal_to());
+
+ return 0;
+}
diff --git a/libcxx/test/std/concepts/concepts.compare/types.h b/libcxx/test/support/compare_types.h
similarity index 73%
rename from libcxx/test/std/concepts/concepts.compare/types.h
rename to libcxx/test/support/compare_types.h
index de816a371e45e..1d448da5407e1 100644
--- 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_COMPARE_TYPES_H
+#define TEST_SUPPORT_COMPARE_TYPES_H
#include <compare>
#include <concepts>
@@ -23,8 +23,7 @@ struct cxx20_member_eq {
};
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 member_three_way_comparable {
};
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 @@ struct explicit_operators {
friend bool operator>(explicit_operators, explicit_operators) noexcept;
friend bool operator<=(explicit_operators, explicit_operators) noexcept;
friend bool operator>=(explicit_operators, explicit_operators) noexcept;
- friend bool operator<=>(explicit_operators, explicit_operators) noexcept;
- friend bool operator==(explicit_operators 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
diff erent_return_types {
@@ -76,8 +69,7 @@ struct boolean {
};
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 wrong_return_type {
};
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 @@ struct one_way_ne {
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 totally_ordered_with_others {
};
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_lt_not_totally_ordered_with {
};
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_gt_not_totally_ordered_with {
};
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_le_not_totally_ordered_with {
};
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 no_ge_not_totally_ordered_with {
};
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 @@ struct eq_returns_explicit_bool {
operator totally_ordered_with_others() const;
- friend explicit_bool operator==(eq_returns_explicit_bool,
- totally_ordered_with_others);
- friend explicit_bool operator==(totally_ordered_with_others,
- eq_returns_explicit_bool);
+ friend 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 eq_returns_explicit_bool {
struct ne_returns_explicit_bool {
friend bool operator==(ne_returns_explicit_bool, ne_returns_explicit_bool);
- friend explicit_bool operator!=(ne_returns_explicit_bool,
- ne_returns_explicit_bool);
+ friend 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 @@ struct ne_returns_explicit_bool {
operator totally_ordered_with_others() const;
friend bool operator==(ne_returns_explicit_bool, totally_ordered_with_others);
- friend explicit_bool operator!=(ne_returns_explicit_bool,
- totally_ordered_with_others);
- friend explicit_bool operator!=(totally_ordered_with_others,
- ne_returns_explicit_bool);
+ friend 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 ne_returns_explicit_bool {
struct lt_returns_explicit_bool {
friend bool operator==(lt_returns_explicit_bool, lt_returns_explicit_bool);
friend bool operator!=(lt_returns_explicit_bool, lt_returns_explicit_bool);
- friend explicit_bool operator<(lt_returns_explicit_bool,
- lt_returns_explicit_bool);
+ friend 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 @@ struct lt_returns_explicit_bool {
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 @@ struct gt_returns_explicit_bool {
friend bool operator==(gt_returns_explicit_bool, gt_returns_explicit_bool);
friend bool operator!=(gt_returns_explicit_bool, gt_returns_explicit_bool);
friend bool operator<(gt_returns_explicit_bool, gt_returns_explicit_bool);
- friend explicit_bool operator>(gt_returns_explicit_bool,
- gt_returns_explicit_bool);
+ friend 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 @@ struct gt_returns_explicit_bool {
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 @@ struct le_returns_explicit_bool {
friend bool operator!=(le_returns_explicit_bool, le_returns_explicit_bool);
friend bool operator<(le_returns_explicit_bool, le_returns_explicit_bool);
friend bool operator>(le_returns_explicit_bool, le_returns_explicit_bool);
- friend 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 @@ struct le_returns_explicit_bool {
friend bool operator>(le_returns_explicit_bool, totally_ordered_with_others);
friend bool operator>(totally_ordered_with_others, le_returns_explicit_bool);
friend bool operator<=(le_returns_explicit_bool, totally_ordered_with_others);
- friend explicit_bool operator<=(totally_ordered_with_others,
- le_returns_explicit_bool);
+ friend 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 @@ struct ge_returns_explicit_bool {
friend bool operator<(ge_returns_explicit_bool, ge_returns_explicit_bool);
friend bool operator>(ge_returns_explicit_bool, ge_returns_explicit_bool);
friend bool operator<=(ge_returns_explicit_bool, ge_returns_explicit_bool);
- friend 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 @@ struct ge_returns_explicit_bool {
friend bool operator<=(ge_returns_explicit_bool, totally_ordered_with_others);
friend bool operator<=(totally_ordered_with_others, ge_returns_explicit_bool);
friend bool operator>=(ge_returns_explicit_bool, totally_ordered_with_others);
- friend explicit_bool operator>=(totally_ordered_with_others,
- ge_returns_explicit_bool);
+ friend explicit_bool operator>=(totally_ordered_with_others, ge_returns_explicit_bool);
};
struct returns_true_type {
@@ -520,30 +470,18 @@ struct returns_true_type {
operator totally_ordered_with_others() const;
- friend std::true_type operator==(returns_true_type,
- totally_ordered_with_others);
- friend std::true_type operator==(totally_ordered_with_others,
- returns_true_type);
- friend std::true_type operator!=(returns_true_type,
- totally_ordered_with_others);
- friend std::true_type operator!=(totally_ordered_with_others,
- returns_true_type);
- friend std::true_type operator<(returns_true_type,
- totally_ordered_with_others);
- friend std::true_type operator<(totally_ordered_with_others,
- returns_true_type);
- friend std::true_type operator>(returns_true_type,
- totally_ordered_with_others);
- friend std::true_type operator>(totally_ordered_with_others,
- returns_true_type);
- friend std::true_type operator<=(returns_true_type,
- totally_ordered_with_others);
- friend std::true_type operator<=(totally_ordered_with_others,
- returns_true_type);
- friend std::true_type operator>=(returns_true_type,
- totally_ordered_with_others);
- friend std::true_type operator>=(totally_ordered_with_others,
- returns_true_type);
+ 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 @@ struct returns_int_ptr {
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_COMPARE_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
index 0000000000000..c47d9ffd90bd3
--- /dev/null
+++ b/libcxx/test/support/pointer_comparison_test_helper.h
@@ -0,0 +1,54 @@
+#ifndef POINTER_COMPARISON_TEST_HELPER_H
+#define POINTER_COMPARISON_TEST_HELPER_H
+
+#include <cstdint>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <template <class> class CompareTemplate>
+void do_pointer_comparison_test() {
+ typedef CompareTemplate<int*> Compare;
+ typedef CompareTemplate<std::uintptr_t> UIntCompare;
+#if TEST_STD_VER > 11
+ typedef CompareTemplate<void> VoidCompare;
+#else
+ typedef Compare VoidCompare;
+#endif
+
+ Compare comp;
+ UIntCompare ucomp;
+ VoidCompare vcomp;
+ struct {
+ int a, b;
+ } local;
+ int* pointers[] = {&local.a, &local.b, nullptr, &local.a + 1};
+ for (int* lhs : pointers) {
+ for (int* rhs : pointers) {
+ std::uintptr_t lhs_uint = reinterpret_cast<std::uintptr_t>(lhs);
+ std::uintptr_t rhs_uint = reinterpret_cast<std::uintptr_t>(rhs);
+ assert(comp(lhs, rhs) == ucomp(lhs_uint, rhs_uint));
+ assert(vcomp(lhs, rhs) == ucomp(lhs_uint, rhs_uint));
+ }
+ }
+}
+
+template <class Comp>
+void do_pointer_comparison_test(Comp comp) {
+ struct {
+ int a, b;
+ } local;
+ int* pointers[] = {&local.a, &local.b, nullptr, &local.a + 1};
+ for (int* lhs : pointers) {
+ for (int* rhs : pointers) {
+ std::uintptr_t lhs_uint = reinterpret_cast<std::uintptr_t>(lhs);
+ std::uintptr_t rhs_uint = reinterpret_cast<std::uintptr_t>(rhs);
+ void* lhs_void = static_cast<void*>(lhs);
+ void* rhs_void = static_cast<void*>(rhs);
+ assert(comp(lhs, rhs) == comp(lhs_uint, rhs_uint));
+ assert(comp(lhs_void, rhs_void) == comp(lhs_uint, rhs_uint));
+ }
+ }
+}
+
+#endif // POINTER_COMPARISON_TEST_HELPER_H
More information about the libcxx-commits
mailing list