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