Horizon
compare.hpp
Go to the documentation of this file.
1 // CPP, the Concepts PreProcessor library
3 //
4 // Copyright Eric Niebler 2018-present
5 // Copyright (c) 2020-present, Google LLC.
6 //
7 // Use, modification and distribution is subject to the
8 // Boost Software License, Version 1.0. (See accompanying
9 // file LICENSE_1_0.txt or copy at
10 // http://www.boost.org/LICENSE_1_0.txt)
11 //
12 // This source code is licensed under the MIT license found in the
13 // LICENSE file in the root directory of this source tree.
14 //
15 // Project home: https://github.com/ericniebler/range-v3
16 //
17 #ifndef CPP_COMPARE_HPP
18 #define CPP_COMPARE_HPP
19 
20 #if __cplusplus > 201703L && __has_include(<compare>) && \
21  defined(__cpp_concepts) && defined(__cpp_impl_three_way_comparison)
22 
23 #include <compare>
24 #include <concepts/concepts.hpp>
25 #include <range/v3/compare.hpp>
26 
27 // clang-format off
28 
29 namespace concepts
30 {
31  // Note: concepts in this file can use C++20 concepts, since operator<=> isn't available in
32  // compilers that don't support core concepts.
33  namespace detail
34  {
35  template<typename T, typename Cat>
36  concept compares_as = same_as<ranges::common_comparison_category_t<T, Cat>, Cat>;
37  } // namespace detail
38 
39  inline namespace defs
40  {
41  template<typename T, typename Cat = std::partial_ordering>
42  concept three_way_comparable =
43  detail::weakly_equality_comparable_with_<T, T> &&
44  detail::partially_ordered_with_<T ,T> &&
45  requires(detail::as_cref_t<T>& a, detail::as_cref_t<T>& b) {
46  { a <=> b } -> detail::compares_as<Cat>;
47  };
48 
49  template<typename T, typename U, typename Cat = std::partial_ordering>
50  concept three_way_comparable_with =
51  three_way_comparable<T, Cat> &&
52  three_way_comparable<U, Cat> &&
53  common_reference_with<detail::as_cref_t<T>&, detail::as_cref_t<U>&> &&
54  three_way_comparable<common_reference_t<detail::as_cref_t<T>&, detail::as_cref_t<U>&>> &&
55  detail::partially_ordered_with_<T, U> &&
56  requires(detail::as_cref_t<T>& t, detail::as_cref_t<U>& u) {
57  { t <=> u } -> detail::compares_as<Cat>;
58  { u <=> t } -> detail::compares_as<Cat>;
59  };
60  } // inline namespace defs
61 } // namespace concepts
62 
63 // clang-format on
64 
65 #endif // __cplusplus
66 #endif // CPP_COMPARE_HPP