| `[cmp.result] <https://wg21.link/cmp.result>`_,| `compare_three_way_result <https://reviews.llvm.org/D103581>`_,None,Arthur O'Dwyer,|Complete|
| `[expos.only.func] <https://wg21.link/expos.only.func>`_,"| `synth-three-way <https://reviews.llvm.org/D107721>`_
| `synth-three-way-result <https://reviews.llvm.org/D107721>`_",[cmp.concept],Kent Ross,|Complete|
-| `[comparisons.three.way] <https://wg21.link/comparisons.three.way>`_,| `compare_three_way <https://reviews.llvm.org/D80899>`_,[cmp.concept],Christopher Di Bella,|In Progress|
+| `[comparisons.three.way] <https://wg21.link/comparisons.three.way>`_,| `compare_three_way <https://reviews.llvm.org/D80899>`_,[cmp.concept],Arthur O'Dwyer,|Complete|
| `[cmp.alg] <https://wg21.link/cmp.alg>`_,"| `strong_order <https://reviews.llvm.org/D107036>`_
| `weak_order <https://reviews.llvm.org/D107036>`_
| `partial_order <https://reviews.llvm.org/D107036>`_",None,Arthur O'Dwyer,|In Progress|
__charconv/from_chars_result.h
__charconv/to_chars_result.h
__compare/common_comparison_category.h
+ __compare/compare_three_way.h
__compare/compare_three_way_result.h
__compare/is_eq.h
__compare/ordering.h
--- /dev/null
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___COMPARE_COMPARE_THREE_WAY_H
+#define _LIBCPP___COMPARE_COMPARE_THREE_WAY_H
+
+#include <__config>
+#include <__compare/three_way_comparable.h>
+#include <__utility/forward.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_SPACESHIP_OPERATOR) && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+
+struct _LIBCPP_TEMPLATE_VIS compare_three_way
+{
+ template<class _T1, class _T2>
+ requires three_way_comparable_with<_T1, _T2>
+ constexpr _LIBCPP_HIDE_FROM_ABI
+ auto operator()(_T1&& __t, _T2&& __u) const
+ noexcept(noexcept(_VSTD::forward<_T1>(__t) <=> _VSTD::forward<_T2>(__u)))
+ { return _VSTD::forward<_T1>(__t) <=> _VSTD::forward<_T2>(__u); }
+
+ using is_transparent = void;
+};
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_SPACESHIP_OPERATOR) && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___COMPARE_COMPARE_THREE_WAY_H
template<class T, class U = T>
using compare_three_way_result_t = typename compare_three_way_result<T, U>::type;
+ // [comparisons.three.way], class compare_three_way
+ struct compare_three_way; // C++20
+
// [cmp.alg], comparison algorithms
template<class T> constexpr strong_ordering strong_order(const T& a, const T& b);
template<class T> constexpr weak_ordering weak_order(const T& a, const T& b);
*/
#include <__compare/common_comparison_category.h>
+#include <__compare/compare_three_way.h>
#include <__compare/compare_three_way_result.h>
#include <__compare/is_eq.h>
#include <__compare/ordering.h>
bool operator()(const T& x, const T& y) const;
};
+// [comparisons.three.way], class compare_three_way
+struct compare_three_way;
+
template <class T> // <class T=void> in C++14
struct logical_and {
bool operator()(const T& x, const T& y) const;
*/
#include <__algorithm/search.h>
+#include <__compare/compare_three_way.h>
#include <__config>
#include <__debug>
#include <__functional/binary_function.h> // TODO: deprecate
module __compare {
module common_comparison_category { private header "__compare/common_comparison_category.h" }
+ module compare_three_way { private header "__compare/compare_three_way.h" }
module compare_three_way_result { private header "__compare/compare_three_way_result.h" }
module is_eq { private header "__compare/is_eq.h" }
module ordering { private header "__compare/ordering.h" }
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: modules-build
+
+// WARNING: This test was generated by 'generate_private_header_tests.py'
+// and should not be edited manually.
+
+// expected-error@*:* {{use of private header from outside its module: '__compare/compare_three_way.h'}}
+#include <__compare/compare_three_way.h>
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <compare>
+// <functional>
+
+// compare_three_way
+
+#include <compare>
+#include <cassert>
+#include <limits>
+#include <type_traits>
+
+#include "pointer_comparison_test_helper.h"
+
+template<class T, class U>
+constexpr auto test_sfinae(T t, U u)
+ -> decltype(std::compare_three_way()(t, u), std::true_type{})
+ { return std::true_type{}; }
+
+constexpr auto test_sfinae(...)
+ { return std::false_type{}; }
+
+struct NotThreeWayComparable {
+ std::strong_ordering operator<=>(const NotThreeWayComparable&) const;
+};
+ASSERT_SAME_TYPE(std::compare_three_way_result_t<NotThreeWayComparable>, std::strong_ordering);
+static_assert(!std::three_way_comparable<NotThreeWayComparable>); // it lacks operator==
+
+struct WeaklyOrdered {
+ int i;
+ friend constexpr std::weak_ordering operator<=>(const WeaklyOrdered&, const WeaklyOrdered&) = default;
+};
+
+constexpr bool test()
+{
+ ASSERT_SAME_TYPE(decltype(std::compare_three_way()(1, 1)), std::strong_ordering);
+ assert(std::compare_three_way()(1, 2) == std::strong_ordering::less);
+ assert(std::compare_three_way()(1, 1) == std::strong_ordering::equal);
+ assert(std::compare_three_way()(2, 1) == std::strong_ordering::greater);
+
+ ASSERT_SAME_TYPE(decltype(std::compare_three_way()(WeaklyOrdered{1}, WeaklyOrdered{2})), std::weak_ordering);
+ assert(std::compare_three_way()(WeaklyOrdered{1}, WeaklyOrdered{2}) == std::weak_ordering::less);
+ assert(std::compare_three_way()(WeaklyOrdered{1}, WeaklyOrdered{1}) == std::weak_ordering::equivalent);
+ assert(std::compare_three_way()(WeaklyOrdered{2}, WeaklyOrdered{1}) == std::weak_ordering::greater);
+
+ ASSERT_SAME_TYPE(decltype(std::compare_three_way()(1.0, 1.0)), std::partial_ordering);
+ double nan = std::numeric_limits<double>::quiet_NaN();
+ assert(std::compare_three_way()(1.0, 2.0) == std::partial_ordering::less);
+ assert(std::compare_three_way()(1.0, 1.0) == std::partial_ordering::equivalent);
+ assert(std::compare_three_way()(2.0, 1.0) == std::partial_ordering::greater);
+ assert(std::compare_three_way()(nan, nan) == std::partial_ordering::unordered);
+
+ // Try heterogeneous comparison.
+ ASSERT_SAME_TYPE(decltype(std::compare_three_way()(42.0, 42)), std::partial_ordering);
+ assert(std::compare_three_way()(42.0, 42) == std::partial_ordering::equivalent);
+ ASSERT_SAME_TYPE(decltype(std::compare_three_way()(42, 42.0)), std::partial_ordering);
+ assert(std::compare_three_way()(42, 42.0) == std::partial_ordering::equivalent);
+
+ return true;
+}
+
+int main(int, char**)
+{
+ test();
+ static_assert(test());
+
+ do_pointer_comparison_test(std::compare_three_way());
+
+ static_assert(test_sfinae(1, 2));
+ static_assert(!test_sfinae(1, nullptr));
+ static_assert(!test_sfinae(NotThreeWayComparable(), NotThreeWayComparable()));
+
+ return 0;
+}
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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>
+
+// Test that std::compare_three_way is defined in <functional>,
+// not only in <compare>.
+
+#include <functional>
+#include <cassert>
+
+int main(int, char**)
+{
+ assert(std::compare_three_way()(1, 2) < 0);
+ assert(std::compare_three_way()(1, 1) == 0);
+ assert(std::compare_three_way()(2, 1) > 0);
+
+ return 0;
+}
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+#include <functional>
+
+template<class T>
+concept Transparent = requires {
+ typename T::is_transparent;
+};
+
+static_assert(Transparent<std::compare_three_way>);