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_COMP_REF_TYPE_H 10 #define _LIBCPP___ALGORITHM_COMP_REF_TYPE_H 11 12 #include <__assert> 13 #include <__config> 14 #include <__utility/declval.h> 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 template <class _Compare> 23 struct __debug_less { 24 _Compare& __comp_; __debug_less__debug_less25 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI __debug_less(_Compare& __c) : __comp_(__c) {} 26 27 template <class _Tp, class _Up> operator__debug_less28 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Up& __y) { 29 bool __r = __comp_(__x, __y); 30 if (__r) 31 __do_compare_assert(0, __y, __x); 32 return __r; 33 } 34 35 template <class _Tp, class _Up> operator__debug_less36 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(_Tp& __x, _Up& __y) { 37 bool __r = __comp_(__x, __y); 38 if (__r) 39 __do_compare_assert(0, __y, __x); 40 return __r; 41 } 42 43 template <class _LHS, class _RHS> 44 _LIBCPP_CONSTEXPR_SINCE_CXX14 inline 45 _LIBCPP_HIDE_FROM_ABI decltype((void)std::declval<_Compare&>()(std::declval<_LHS&>(), std::declval<_RHS&>())) __do_compare_assert__debug_less46 __do_compare_assert(int, _LHS& __l, _RHS& __r) { 47 _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(!__comp_(__l, __r), "Comparator does not induce a strict weak ordering"); 48 (void)__l; 49 (void)__r; 50 } 51 52 template <class _LHS, class _RHS> __do_compare_assert__debug_less53 _LIBCPP_CONSTEXPR_SINCE_CXX14 inline _LIBCPP_HIDE_FROM_ABI void __do_compare_assert(long, _LHS&, _RHS&) {} 54 }; 55 56 // Pass the comparator by lvalue reference. Or in the debug mode, using a debugging wrapper that stores a reference. 57 #if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG 58 template <class _Comp> 59 using __comp_ref_type = __debug_less<_Comp>; 60 #else 61 template <class _Comp> 62 using __comp_ref_type = _Comp&; 63 #endif 64 65 _LIBCPP_END_NAMESPACE_STD 66 67 #endif // _LIBCPP___ALGORITHM_COMP_REF_TYPE_H 68