[libc++] [P1614] Implement std::compare_three_way.
Differential Revision: https://reviews.llvm.org/D110735
This commit is contained in:
@@ -4,7 +4,7 @@ Section,Description,Dependencies,Assignee,Complete
|
||||
| `[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|
|
||||
|
||||
|
@@ -102,6 +102,7 @@ set(files
|
||||
__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
|
||||
|
||||
41
libcxx/include/__compare/compare_three_way.h
Normal file
41
libcxx/include/__compare/compare_three_way.h
Normal file
@@ -0,0 +1,41 @@
|
||||
// -*- 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
|
||||
@@ -47,6 +47,9 @@ namespace std {
|
||||
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);
|
||||
@@ -133,6 +136,7 @@ namespace std {
|
||||
*/
|
||||
|
||||
#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>
|
||||
|
||||
@@ -135,6 +135,9 @@ struct less_equal {
|
||||
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;
|
||||
@@ -488,6 +491,7 @@ POLICY: For non-variadic implementations, the number of arguments is limited
|
||||
*/
|
||||
|
||||
#include <__algorithm/search.h>
|
||||
#include <__compare/compare_three_way.h>
|
||||
#include <__config>
|
||||
#include <__debug>
|
||||
#include <__functional/binary_function.h> // TODO: deprecate
|
||||
|
||||
@@ -372,6 +372,7 @@ module std [system] {
|
||||
|
||||
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" }
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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>
|
||||
@@ -0,0 +1,83 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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>);
|
||||
Reference in New Issue
Block a user