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