xref: /llvm-project/libcxx/include/__algorithm/minmax_element.h (revision 7ed7d4ccb8991e2b5b95334b508f8cec2faee737)
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