[libcxx-commits] [libcxx] WIP - [libc++][functional] P2944R3 (partial): Comparisons for ``reference_wrapper`` (``reference_wrapper`` operators only) (PR #88384)
Hristo Hristov via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Apr 17 11:48:18 PDT 2024
https://github.com/H-G-Hristov updated https://github.com/llvm/llvm-project/pull/88384
>From d08f17c8406fb12c302d94c77f7aacb8726c27f9 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Thu, 11 Apr 2024 10:20:05 +0300
Subject: [PATCH 1/3] [libc++][functional] P2944R3 (partial): Comparisons for
``reference_wrapper`` (``reference_wrapper`` operators only)
Implements parially https://wg21.link/P2944R3
---
libcxx/docs/FeatureTestMacroTable.rst | 2 +-
libcxx/docs/ReleaseNotes/19.rst | 1 +
libcxx/docs/Status/Cxx2c.rst | 1 +
libcxx/docs/Status/Cxx2cPapers.csv | 2 +-
.../include/__functional/reference_wrapper.h | 52 +++++++++++++++++++
libcxx/include/functional | 9 ++++
libcxx/include/version | 2 +-
.../functional.version.compile.pass.cpp | 16 ++----
.../version.version.compile.pass.cpp | 16 ++----
.../compare.three_way.pass.cpp | 33 ++++++++++++
.../refwrap.comparissons/equal.pass.cpp | 48 +++++++++++++++++
.../generate_feature_test_macro_components.py | 1 -
12 files changed, 157 insertions(+), 26 deletions(-)
create mode 100644 libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/compare.three_way.pass.cpp
create mode 100644 libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/equal.pass.cpp
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 3197d2cd1b271c0..83d8213ec29f9eb 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -444,7 +444,7 @@ Status
---------------------------------------------------------- -----------------
``__cpp_lib_rcu`` *unimplemented*
---------------------------------------------------------- -----------------
- ``__cpp_lib_reference_wrapper`` *unimplemented*
+ ``__cpp_lib_reference_wrapper`` ``202403L``
---------------------------------------------------------- -----------------
``__cpp_lib_saturation_arithmetic`` ``202311L``
---------------------------------------------------------- -----------------
diff --git a/libcxx/docs/ReleaseNotes/19.rst b/libcxx/docs/ReleaseNotes/19.rst
index e5db17daa482335..8da421de050e355 100644
--- a/libcxx/docs/ReleaseNotes/19.rst
+++ b/libcxx/docs/ReleaseNotes/19.rst
@@ -46,6 +46,7 @@ Implemented Papers
- P2869R4 - Remove Deprecated ``shared_ptr`` Atomic Access APIs from C++26
- P2872R3 - Remove ``wstring_convert`` From C++26
- P3142R0 - Printing Blank Lines with ``println`` (as DR against C++23)
+- P2944R3 - Comparisons for ``reference_wrapper`` (comparison operators for ``reference_wrapper`` only)
- P2302R4 - ``std::ranges::contains``
- P1659R3 - ``std::ranges::starts_with`` and ``std::ranges::ends_with``
- P3029R1 - Better ``mdspan``'s CTAD
diff --git a/libcxx/docs/Status/Cxx2c.rst b/libcxx/docs/Status/Cxx2c.rst
index a7ebc4662f517cc..b6f1714a182a6c0 100644
--- a/libcxx/docs/Status/Cxx2c.rst
+++ b/libcxx/docs/Status/Cxx2c.rst
@@ -40,6 +40,7 @@ Paper Status
.. note::
.. [#note-P2510R3] This paper is applied as DR against C++20. (MSVC STL and libstdc++ will do the same.)
+ .. [#note-P2944R3] Implemented comparisons for ``reference_wrapper`` only.
.. _issues-status-cxx2c:
diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index 1b00a05ad3d6fdb..31314a209dfe8db 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -59,7 +59,7 @@
"`P2248R8 <https://wg21.link/P2248R8>`__","LWG","Enabling list-initialization for algorithms","Tokyo March 2024","","",""
"`P2810R4 <https://wg21.link/P2810R4>`__","LWG","``is_debugger_present`` ``is_replaceable``","Tokyo March 2024","","",""
"`P1068R11 <https://wg21.link/P1068R11>`__","LWG","Vector API for random number generation","Tokyo March 2024","","",""
-"`P2944R3 <https://wg21.link/P2944R3>`__","LWG","Comparisons for ``reference_wrapper``","Tokyo March 2024","","",""
+"`P2944R3 <https://wg21.link/P2944R3>`__","LWG","Comparisons for ``reference_wrapper``","Tokyo March 2024","|Partial|","19.0",""
"`P2642R6 <https://wg21.link/P2642R6>`__","LWG","Padded ``mdspan`` layouts","Tokyo March 2024","","",""
"`P3029R1 <https://wg21.link/P3029R1>`__","LWG","Better ``mdspan``'s CTAD","Tokyo March 2024","|Complete|","19.0",""
"","","","","","",""
diff --git a/libcxx/include/__functional/reference_wrapper.h b/libcxx/include/__functional/reference_wrapper.h
index 94b39e3bc786168..8c7ba9e36da0946 100644
--- a/libcxx/include/__functional/reference_wrapper.h
+++ b/libcxx/include/__functional/reference_wrapper.h
@@ -10,11 +10,14 @@
#ifndef _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H
#define _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H
+#include <__compare/synth_three_way.h>
#include <__config>
#include <__functional/invoke.h>
#include <__functional/weak_result_type.h>
#include <__memory/addressof.h>
#include <__type_traits/enable_if.h>
+#include <__type_traits/is_const.h>
+#include <__type_traits/is_convertible.h>
#include <__type_traits/remove_cvref.h>
#include <__type_traits/void_t.h>
#include <__utility/declval.h>
@@ -64,6 +67,55 @@ class _LIBCPP_TEMPLATE_VIS reference_wrapper : public __weak_result_type<_Tp> {
{
return std::__invoke(get(), std::forward<_ArgTypes>(__args)...);
}
+
+#if _LIBCPP_STD_VER >= 26
+
+ // [refwrap.comparisons], comparisons
+
+ friend constexpr bool operator==(reference_wrapper __x, reference_wrapper __y) {
+ // Mandates: The expression x.get() == y.get() is well-formed and its result is convertible to bool.
+ static_assert(is_convertible_v<decltype(__x.get() == __y.get()), bool>);
+
+ return __x.get() == __y.get();
+ }
+
+ friend constexpr bool operator==(reference_wrapper __x, const _Tp& __y) {
+ // Mandates: The expression x.get() == y is well-formed and its result is convertible to bool.
+ static_assert(is_convertible_v<decltype(__x.get() == __y), bool>);
+
+ return __x.get() == __y;
+ }
+
+ friend constexpr bool operator==(reference_wrapper __x, reference_wrapper<const _Tp> __y)
+ requires(!is_const_v<_Tp>)
+ {
+ // Constraints: is_const_v<T> is false.
+ // Mandates: The expression x.get() == y.get() is well-formed and its result is convertible to bool.
+ static_assert(is_convertible_v<decltype(__x.get() == __y.get()), bool>);
+
+ return __x.get() == __y.get();
+ }
+
+ friend constexpr __synth_three_way_result<_Tp> operator<=>(reference_wrapper __x, reference_wrapper __y) {
+ // return __synth_three_way_result(x.get(), y.get());
+ return std::__synth_three_way(__x.get(), __y.get());
+ }
+
+ friend constexpr __synth_three_way_result<_Tp> operator<=>(reference_wrapper __x, const _Tp& __y) {
+ // return __synth_three_way_result(__x.get(), __y);
+ return std::__synth_three_way(__x.get(), __y.get());
+ }
+
+ friend constexpr __synth_three_way_result<_Tp> operator<=>(reference_wrapper __x, reference_wrapper<const _Tp> __y)
+ requires(!is_const_v<_Tp>)
+ {
+ // Constraints: is_const_v<T> is false.
+
+ // return __synth_three_way_result(__x.get(), __y.get());
+ return std::__synth_three_way(__x.get(), __y.get());
+ }
+
+#endif // _LIBCPP_STD_VER >= 26
};
#if _LIBCPP_STD_VER >= 17
diff --git a/libcxx/include/functional b/libcxx/include/functional
index a2476c93ad1b430..1da953f82241b55 100644
--- a/libcxx/include/functional
+++ b/libcxx/include/functional
@@ -77,6 +77,15 @@ template <class T> struct unwrap_ref_decay : unwrap_reference<decay_t<T>> { };
template <class T> using unwrap_reference_t = typename unwrap_reference<T>::type; // since C++20
template <class T> using unwrap_ref_decay_t = typename unwrap_ref_decay<T>::type; // since C++20
+// [refwrap.comparisons], comparisons
+friend constexpr bool operator==(reference_wrapper, reference_wrapper); // Since C++26
+friend constexpr bool operator==(reference_wrapper, const T&); // Since C++26
+friend constexpr bool operator==(reference_wrapper, reference_wrapper<const T>); // Since C++26
+
+friend constexpr synth-three-way-result<T> operator<=>(reference_wrapper, reference_wrapper); // Since C++26
+friend constexpr synth-three-way-result<T> operator<=>(reference_wrapper, const T&); // Since C++26
+friend constexpr synth-three-way-result<T> operator<=>(reference_wrapper, reference_wrapper<const T>); // Since C++26
+
template <class T> // <class T=void> in C++14
struct plus {
T operator()(const T& x, const T& y) const;
diff --git a/libcxx/include/version b/libcxx/include/version
index 0ed77345baa71d7..0ce262462eb3ee4 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -524,7 +524,7 @@ __cpp_lib_within_lifetime 202306L <type_traits>
// # define __cpp_lib_ranges_concat 202403L
# define __cpp_lib_ratio 202306L
// # define __cpp_lib_rcu 202306L
-// # define __cpp_lib_reference_wrapper 202403L
+# define __cpp_lib_reference_wrapper 202403L
# define __cpp_lib_saturation_arithmetic 202311L
// # define __cpp_lib_smart_ptr_owner_equality 202306L
# define __cpp_lib_span_at 202311L
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/functional.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/functional.version.compile.pass.cpp
index aeb09a30b42591d..27e76e5b2b05a31 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/functional.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/functional.version.compile.pass.cpp
@@ -535,17 +535,11 @@
# error "__cpp_lib_ranges should have the value 202207L in c++26"
# endif
-# if !defined(_LIBCPP_VERSION)
-# ifndef __cpp_lib_reference_wrapper
-# error "__cpp_lib_reference_wrapper should be defined in c++26"
-# endif
-# if __cpp_lib_reference_wrapper != 202403L
-# error "__cpp_lib_reference_wrapper should have the value 202403L in c++26"
-# endif
-# else // _LIBCPP_VERSION
-# ifdef __cpp_lib_reference_wrapper
-# error "__cpp_lib_reference_wrapper should not be defined because it is unimplemented in libc++!"
-# endif
+# ifndef __cpp_lib_reference_wrapper
+# error "__cpp_lib_reference_wrapper should be defined in c++26"
+# endif
+# if __cpp_lib_reference_wrapper != 202403L
+# error "__cpp_lib_reference_wrapper should have the value 202403L in c++26"
# endif
# ifndef __cpp_lib_result_of_sfinae
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index 3ec548f56cea1d1..54fb538680ebadf 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -7433,17 +7433,11 @@
# endif
# endif
-# if !defined(_LIBCPP_VERSION)
-# ifndef __cpp_lib_reference_wrapper
-# error "__cpp_lib_reference_wrapper should be defined in c++26"
-# endif
-# if __cpp_lib_reference_wrapper != 202403L
-# error "__cpp_lib_reference_wrapper should have the value 202403L in c++26"
-# endif
-# else // _LIBCPP_VERSION
-# ifdef __cpp_lib_reference_wrapper
-# error "__cpp_lib_reference_wrapper should not be defined because it is unimplemented in libc++!"
-# endif
+# ifndef __cpp_lib_reference_wrapper
+# error "__cpp_lib_reference_wrapper should be defined in c++26"
+# endif
+# if __cpp_lib_reference_wrapper != 202403L
+# error "__cpp_lib_reference_wrapper should have the value 202403L in c++26"
# endif
# ifndef __cpp_lib_remove_cvref
diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/compare.three_way.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/compare.three_way.pass.cpp
new file mode 100644
index 000000000000000..cbf5d8830200b58
--- /dev/null
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/compare.three_way.pass.cpp
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20, c++23
+
+// <functional>
+
+// class reference_wrapper
+
+// // [refwrap.comparisons], comparisons
+
+// friend constexpr synth-three-way-result<T> operator<=>(reference_wrapper, reference_wrapper); // Since C++26
+// friend constexpr synth-three-way-result<T> operator<=>(reference_wrapper, const T&); // Since C++26
+// friend constexpr synth-three-way-result<T> operator<=>(reference_wrapper, reference_wrapper<const T>); // Since C++26
+
+#include <cassert>
+#include <functional>
+
+#include "test_macros.h"
+
+constexpr bool test() { return true; }
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/equal.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/equal.pass.cpp
new file mode 100644
index 000000000000000..fb5c122b41d79ce
--- /dev/null
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/equal.pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20, c++23
+
+// <functional>
+
+// class reference_wrapper
+
+// // [refwrap.comparisons], comparisons
+// friend constexpr bool operator==(reference_wrapper, reference_wrapper); // Since C++26
+// friend constexpr bool operator==(reference_wrapper, const T&); // Since C++26
+// friend constexpr bool operator==(reference_wrapper, reference_wrapper<const T>); // Since C++26
+
+#include <cassert>
+#include <functional>
+
+#include "test_macros.h"
+
+constexpr bool test() {
+ {
+ int i = 92;
+ std::reference_wrapper<int> lhs{i};
+ std::reference_wrapper<int> rhs = lhs;
+ assert(lhs == rhs);
+ }
+ {
+ int i = 92;
+ std::reference_wrapper<int> lhs{i};
+ int j = 84;
+ std::reference_wrapper<int> rhs{j};
+ assert(lhs != rhs);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index f2b8d55c0e11b0d..5f127bd1213c14c 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -1040,7 +1040,6 @@ def add_version_header(tc):
"name": "__cpp_lib_reference_wrapper",
"values": {"c++26": 202403}, # P2944R3: Comparisons for reference_wrapper
"headers": ["functional"],
- "unimplemented": True,
},
{
"name": "__cpp_lib_remove_cvref",
>From 7386cebedb562afb99b23d6f0f2d8a6521df2d43 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Thu, 11 Apr 2024 15:31:18 +0300
Subject: [PATCH 2/3] Tests: operator== WIP
---
.../include/__functional/reference_wrapper.h | 11 +---
.../refwrap.comparissons/equal.pass.cpp | 51 +++++++++++++++----
2 files changed, 43 insertions(+), 19 deletions(-)
diff --git a/libcxx/include/__functional/reference_wrapper.h b/libcxx/include/__functional/reference_wrapper.h
index 8c7ba9e36da0946..738d57e32efe381 100644
--- a/libcxx/include/__functional/reference_wrapper.h
+++ b/libcxx/include/__functional/reference_wrapper.h
@@ -73,14 +73,12 @@ class _LIBCPP_TEMPLATE_VIS reference_wrapper : public __weak_result_type<_Tp> {
// [refwrap.comparisons], comparisons
friend constexpr bool operator==(reference_wrapper __x, reference_wrapper __y) {
- // Mandates: The expression x.get() == y.get() is well-formed and its result is convertible to bool.
static_assert(is_convertible_v<decltype(__x.get() == __y.get()), bool>);
return __x.get() == __y.get();
}
friend constexpr bool operator==(reference_wrapper __x, const _Tp& __y) {
- // Mandates: The expression x.get() == y is well-formed and its result is convertible to bool.
static_assert(is_convertible_v<decltype(__x.get() == __y), bool>);
return __x.get() == __y;
@@ -89,29 +87,22 @@ class _LIBCPP_TEMPLATE_VIS reference_wrapper : public __weak_result_type<_Tp> {
friend constexpr bool operator==(reference_wrapper __x, reference_wrapper<const _Tp> __y)
requires(!is_const_v<_Tp>)
{
- // Constraints: is_const_v<T> is false.
- // Mandates: The expression x.get() == y.get() is well-formed and its result is convertible to bool.
static_assert(is_convertible_v<decltype(__x.get() == __y.get()), bool>);
return __x.get() == __y.get();
}
friend constexpr __synth_three_way_result<_Tp> operator<=>(reference_wrapper __x, reference_wrapper __y) {
- // return __synth_three_way_result(x.get(), y.get());
return std::__synth_three_way(__x.get(), __y.get());
}
friend constexpr __synth_three_way_result<_Tp> operator<=>(reference_wrapper __x, const _Tp& __y) {
- // return __synth_three_way_result(__x.get(), __y);
- return std::__synth_three_way(__x.get(), __y.get());
+ return std::__synth_three_way(__x.get(), __y);
}
friend constexpr __synth_three_way_result<_Tp> operator<=>(reference_wrapper __x, reference_wrapper<const _Tp> __y)
requires(!is_const_v<_Tp>)
{
- // Constraints: is_const_v<T> is false.
-
- // return __synth_three_way_result(__x.get(), __y.get());
return std::__synth_three_way(__x.get(), __y.get());
}
diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/equal.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/equal.pass.cpp
index fb5c122b41d79ce..9f0d4b7adb5a1ad 100644
--- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/equal.pass.cpp
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/equal.pass.cpp
@@ -23,18 +23,51 @@
#include "test_macros.h"
constexpr bool test() {
+ int i = 92;
+ int j = 84;
+
+ // ==
+ {
+ // refwrap, refwrap
+ std::reference_wrapper<int> rw1{i};
+ std::reference_wrapper<int> rw2 = rw1;
+ assert(rw1 == rw2);
+ assert(rw2 == rw1);
+ }
+ {
+ // refwrap, const&
+ std::reference_wrapper<int> rw{i};
+ assert(rw == i);
+ assert(i == rw);
+ }
+ {
+ // refwrap, refwrap<const>
+ std::reference_wrapper<int> rw1{i};
+ std::reference_wrapper<const int> rw2 = rw1;
+ assert(rw1 == rw2);
+ assert(rw2 == rw1);
+ }
+
+ // !=
+ {
+ // refwrap, refwrap
+ std::reference_wrapper<int> rw1{i};
+ std::reference_wrapper<int> rw2{j};
+ assert(rw1 != rw2);
+ assert(rw2 != rw1);
+ }
{
- int i = 92;
- std::reference_wrapper<int> lhs{i};
- std::reference_wrapper<int> rhs = lhs;
- assert(lhs == rhs);
+ // refwrap, const&
+ std::reference_wrapper<int> rw{i};
+ assert(rw != j);
+ assert(j != rw);
}
{
- int i = 92;
- std::reference_wrapper<int> lhs{i};
- int j = 84;
- std::reference_wrapper<int> rhs{j};
- assert(lhs != rhs);
+ // refwrap, refwrap<const>
+ std::reference_wrapper<int> rw1{i};
+ std::reference_wrapper<const int> rw2{j};
+ assert(rw1 != rw2);
+ assert(rw2 != rw1);
}
return true;
>From 7616aee155482db49ea77e200ed45b1d55c473e4 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Wed, 17 Apr 2024 21:47:54 +0300
Subject: [PATCH 3/3] =?UTF-8?q?Test:=20operator<=3D=3F>=20WIP?=
---
.../compare.three_way.pass.cpp | 36 ++++++++++++++++++-
1 file changed, 35 insertions(+), 1 deletion(-)
diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/compare.three_way.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/compare.three_way.pass.cpp
index cbf5d8830200b58..bc158c74f3738e6 100644
--- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/compare.three_way.pass.cpp
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/compare.three_way.pass.cpp
@@ -21,9 +21,43 @@
#include <cassert>
#include <functional>
+#include "test_comparisons.h"
#include "test_macros.h"
-constexpr bool test() { return true; }
+template <typename Order>
+constexpr void test() {
+ int integer = 47;
+
+ int bigger = 94;
+ int smaller = 82;
+
+ // Identical contents
+ {
+ std::reference_wrapper<int> rw1{integer};
+ std::reference_wrapper<int> rw2{integer};
+ assert(testOrder(rw1, rw2, Order::equivalent));
+ }
+ // Less
+ {
+ std::reference_wrapper<int> rw1{smaller};
+ std::reference_wrapper<int> rw2{bigger};
+ assert(testOrder(rw1, rw2, Order::less));
+ }
+ // Greater
+ {
+ std::reference_wrapper<int> rw1{bigger};
+ std::reference_wrapper<int> rw2{smaller};
+ assert(testOrder(rw1, rw2, Order::greater));
+ }
+}
+
+constexpr bool test() {
+ test<std::strong_ordering>();
+ test<std::weak_ordering>();
+ test<std::partial_ordering>();
+
+ return true;
+}
int main(int, char**) {
test();
More information about the libcxx-commits
mailing list