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