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_MINMAX_ELEMENT_H 10 #define _LIBCPP___ALGORITHM_MINMAX_ELEMENT_H 11 12 #include <__config> 13 #include <__iterator/iterator_traits.h> 14 #include <utility> 15 16 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 17 #pragma GCC system_header 18 #endif 19 20 _LIBCPP_PUSH_MACROS 21 #include <__undef_macros> 22 23 _LIBCPP_BEGIN_NAMESPACE_STD 24 25 template <class _ForwardIterator, class _Compare> 26 _LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX11 27 pair<_ForwardIterator, _ForwardIterator> 28 minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) 29 { 30 static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value, 31 "std::minmax_element requires a ForwardIterator"); 32 pair<_ForwardIterator, _ForwardIterator> __result(__first, __first); 33 if (__first != __last) 34 { 35 if (++__first != __last) 36 { 37 if (__comp(*__first, *__result.first)) 38 __result.first = __first; 39 else 40 __result.second = __first; 41 while (++__first != __last) 42 { 43 _ForwardIterator __i = __first; 44 if (++__first == __last) 45 { 46 if (__comp(*__i, *__result.first)) 47 __result.first = __i; 48 else if (!__comp(*__i, *__result.second)) 49 __result.second = __i; 50 break; 51 } 52 else 53 { 54 if (__comp(*__first, *__i)) 55 { 56 if (__comp(*__first, *__result.first)) 57 __result.first = __first; 58 if (!__comp(*__i, *__result.second)) 59 __result.second = __i; 60 } 61 else 62 { 63 if (__comp(*__i, *__result.first)) 64 __result.first = __i; 65 if (!__comp(*__first, *__result.second)) 66 __result.second = __first; 67 } 68 } 69 } 70 } 71 } 72 return __result; 73 } 74 75 template <class _ForwardIterator> 76 _LIBCPP_NODISCARD_EXT inline 77 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 78 pair<_ForwardIterator, _ForwardIterator> 79 minmax_element(_ForwardIterator __first, _ForwardIterator __last) 80 { 81 return _VSTD::minmax_element(__first, __last, 82 __less<typename iterator_traits<_ForwardIterator>::value_type>()); 83 } 84 85 _LIBCPP_END_NAMESPACE_STD 86 87 _LIBCPP_POP_MACROS 88 89 #endif // _LIBCPP___ALGORITHM_MINMAX_ELEMENT_H 90