1 //===----------------------------------------------------------------------===// 2 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef _LIBCPP___COMPARE_COMMON_COMPARISON_CATEGORY_H 10 #define _LIBCPP___COMPARE_COMMON_COMPARISON_CATEGORY_H 11 12 #include <__compare/ordering.h> 13 #include <__config> 14 #include <type_traits> 15 16 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 17 # pragma GCC system_header 18 #endif 19 20 _LIBCPP_BEGIN_NAMESPACE_STD 21 22 #if _LIBCPP_STD_VER > 17 23 24 namespace __comp_detail { 25 26 enum _ClassifyCompCategory : unsigned { 27 _None, 28 _PartialOrd, 29 _WeakOrd, 30 _StrongOrd, 31 _CCC_Size 32 }; 33 34 template <class _Tp> 35 _LIBCPP_HIDE_FROM_ABI 36 constexpr _ClassifyCompCategory __type_to_enum() noexcept { 37 if (is_same_v<_Tp, partial_ordering>) 38 return _PartialOrd; 39 if (is_same_v<_Tp, weak_ordering>) 40 return _WeakOrd; 41 if (is_same_v<_Tp, strong_ordering>) 42 return _StrongOrd; 43 return _None; 44 } 45 46 template <size_t _Size> 47 _LIBCPP_HIDE_FROM_ABI 48 constexpr _ClassifyCompCategory 49 __compute_comp_type(const _ClassifyCompCategory (&__types)[_Size]) { 50 int __seen[_CCC_Size] = {}; 51 for (auto __type : __types) 52 ++__seen[__type]; 53 if (__seen[_None]) 54 return _None; 55 if (__seen[_PartialOrd]) 56 return _PartialOrd; 57 if (__seen[_WeakOrd]) 58 return _WeakOrd; 59 return _StrongOrd; 60 } 61 62 template <class ..._Ts, bool _False = false> 63 _LIBCPP_HIDE_FROM_ABI 64 constexpr auto __get_comp_type() { 65 using _CCC = _ClassifyCompCategory; 66 constexpr _CCC __type_kinds[] = {_StrongOrd, __type_to_enum<_Ts>()...}; 67 constexpr _CCC _Cat = __compute_comp_type(__type_kinds); 68 if constexpr (_Cat == _None) 69 return void(); 70 else if constexpr (_Cat == _PartialOrd) 71 return partial_ordering::equivalent; 72 else if constexpr (_Cat == _WeakOrd) 73 return weak_ordering::equivalent; 74 else if constexpr (_Cat == _StrongOrd) 75 return strong_ordering::equivalent; 76 else 77 static_assert(_False, "unhandled case"); 78 } 79 } // namespace __comp_detail 80 81 // [cmp.common], common comparison category type 82 template<class... _Ts> 83 struct _LIBCPP_TEMPLATE_VIS common_comparison_category { 84 using type = decltype(__comp_detail::__get_comp_type<_Ts...>()); 85 }; 86 87 template<class... _Ts> 88 using common_comparison_category_t = typename common_comparison_category<_Ts...>::type; 89 90 #endif // _LIBCPP_STD_VER > 17 91 92 _LIBCPP_END_NAMESPACE_STD 93 94 #endif // _LIBCPP___COMPARE_COMMON_COMPARISON_CATEGORY_H 95