1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef _LIBCPP___COMPARE_COMMON_COMPARISON_CATEGORY_H
10 #define _LIBCPP___COMPARE_COMMON_COMPARISON_CATEGORY_H
12 #include <__compare/ordering.h>
14 #include <__cstddef/size_t.h>
15 #include <__type_traits/is_same.h>
17 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18 # pragma GCC system_header
21 _LIBCPP_BEGIN_NAMESPACE_STD
23 #if _LIBCPP_STD_VER >= 20
25 namespace __comp_detail
{
27 enum _ClassifyCompCategory
: unsigned { _None
, _PartialOrd
, _WeakOrd
, _StrongOrd
, _CCC_Size
};
30 _LIBCPP_HIDE_FROM_ABI
constexpr _ClassifyCompCategory
__type_to_enum() noexcept
{
31 if (is_same_v
<_Tp
, partial_ordering
>)
33 if (is_same_v
<_Tp
, weak_ordering
>)
35 if (is_same_v
<_Tp
, strong_ordering
>)
40 template <size_t _Size
>
41 _LIBCPP_HIDE_FROM_ABI
constexpr _ClassifyCompCategory
42 __compute_comp_type(const _ClassifyCompCategory (&__types
)[_Size
]) {
43 int __seen
[_CCC_Size
] = {};
44 for (auto __type
: __types
)
48 if (__seen
[_PartialOrd
])
55 template <class... _Ts
, bool _False
= false>
56 _LIBCPP_HIDE_FROM_ABI
constexpr auto __get_comp_type() {
57 using _CCC
= _ClassifyCompCategory
;
58 constexpr _CCC __type_kinds
[] = {_StrongOrd
, __type_to_enum
<_Ts
>()...};
59 constexpr _CCC __cat
= __comp_detail::__compute_comp_type(__type_kinds
);
60 if constexpr (__cat
== _None
)
62 else if constexpr (__cat
== _PartialOrd
)
63 return partial_ordering::equivalent
;
64 else if constexpr (__cat
== _WeakOrd
)
65 return weak_ordering::equivalent
;
66 else if constexpr (__cat
== _StrongOrd
)
67 return strong_ordering::equivalent
;
69 static_assert(_False
, "unhandled case");
71 } // namespace __comp_detail
73 // [cmp.common], common comparison category type
74 template <class... _Ts
>
75 struct _LIBCPP_TEMPLATE_VIS common_comparison_category
{
76 using type
= decltype(__comp_detail::__get_comp_type
<_Ts
...>());
79 template <class... _Ts
>
80 using common_comparison_category_t
= typename common_comparison_category
<_Ts
...>::type
;
82 #endif // _LIBCPP_STD_VER >= 20
84 _LIBCPP_END_NAMESPACE_STD
86 #endif // _LIBCPP___COMPARE_COMMON_COMPARISON_CATEGORY_H