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