forked from OSchip/llvm-project
[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
This commit is contained in:
parent
15be0c41d2
commit
879cbac08b
|
@ -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
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
#include "../types.h"
|
||||
#include "compare_types.h"
|
||||
|
||||
namespace fundamentals {
|
||||
static_assert(std::equality_comparable<int>);
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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 different_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
|
|
@ -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
|
Loading…
Reference in New Issue