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___ALGORITHM_THREE_WAY_COMP_REF_TYPE_H 10 #define _LIBCPP___ALGORITHM_THREE_WAY_COMP_REF_TYPE_H 11 12 #include <__compare/ordering.h> 13 #include <__config> 14 #include <__utility/declval.h> 15 #include <__utility/forward.h> 16 17 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 18 # pragma GCC system_header 19 #endif 20 21 _LIBCPP_BEGIN_NAMESPACE_STD 22 23 #if _LIBCPP_STD_VER >= 20 24 25 template <class _Comp> 26 struct __debug_three_way_comp { 27 _Comp& __comp_; 28 _LIBCPP_HIDE_FROM_ABI constexpr __debug_three_way_comp(_Comp& __c) : __comp_(__c) {} 29 30 template <class _Tp, class _Up> 31 _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(const _Tp& __x, const _Up& __y) { 32 auto __r = __comp_(__x, __y); 33 if constexpr (__comparison_category<decltype(__comp_(__x, __y))>) 34 __do_compare_assert(__y, __x, __r); 35 return __r; 36 } 37 38 template <class _Tp, class _Up> 39 _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp& __x, _Up& __y) { 40 auto __r = __comp_(__x, __y); 41 if constexpr (__comparison_category<decltype(__comp_(__x, __y))>) 42 __do_compare_assert(__y, __x, __r); 43 return __r; 44 } 45 46 template <class _LHS, class _RHS, class _Order> 47 _LIBCPP_HIDE_FROM_ABI constexpr void __do_compare_assert(_LHS& __l, _RHS& __r, _Order __o) { 48 _Order __expected = __o; 49 if (__o == _Order::less) 50 __expected = _Order::greater; 51 if (__o == _Order::greater) 52 __expected = _Order::less; 53 _LIBCPP_ASSERT(__comp_(__l, __r) == __expected, "Comparator does not induce a strict weak ordering"); 54 (void)__l; 55 (void)__r; 56 } 57 }; 58 59 // Pass the comparator by lvalue reference. Or in debug mode, using a 60 // debugging wrapper that stores a reference. 61 # if _LIBCPP_ENABLE_DEBUG_MODE 62 template <class _Comp> 63 using __three_way_comp_ref_type = __debug_three_way_comp<_Comp>; 64 # else 65 template <class _Comp> 66 using __three_way_comp_ref_type = _Comp&; 67 # endif 68 69 #endif // _LIBCPP_STD_VER >= 20 70 71 _LIBCPP_END_NAMESPACE_STD 72 73 #endif // _LIBCPP___ALGORITHM_THREE_WAY_COMP_REF_TYPE_H 74