minmax_element.h revision 1.1.1.1
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
26template <class _ForwardIterator, class _Compare>
27_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX11
28pair<_ForwardIterator, _ForwardIterator>
29minmax_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
76template <class _ForwardIterator>
77_LIBCPP_NODISCARD_EXT inline
78_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
79pair<_ForwardIterator, _ForwardIterator>
80minmax_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