xref: /freebsd/contrib/llvm-project/libcxx/include/__algorithm/lower_bound.h (revision 82d4dc0621c92e3c05a86013eec35afbdec057a5)
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_LOWER_BOUND_H
10  #define _LIBCPP___ALGORITHM_LOWER_BOUND_H
11  
12  #include <__config>
13  #include <__algorithm/comp.h>
14  #include <__algorithm/half_positive.h>
15  #include <iterator>
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 _Compare, class _ForwardIterator, class _Tp>
27  _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
28  __lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
29  {
30      typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
31      difference_type __len = _VSTD::distance(__first, __last);
32      while (__len != 0)
33      {
34          difference_type __l2 = _VSTD::__half_positive(__len);
35          _ForwardIterator __m = __first;
36          _VSTD::advance(__m, __l2);
37          if (__comp(*__m, __value_))
38          {
39              __first = ++__m;
40              __len -= __l2 + 1;
41          }
42          else
43              __len = __l2;
44      }
45      return __first;
46  }
47  
48  template <class _ForwardIterator, class _Tp, class _Compare>
49  _LIBCPP_NODISCARD_EXT inline
50  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
51  _ForwardIterator
52  lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
53  {
54      typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
55      return _VSTD::__lower_bound<_Comp_ref>(__first, __last, __value_, __comp);
56  }
57  
58  template <class _ForwardIterator, class _Tp>
59  _LIBCPP_NODISCARD_EXT inline
60  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
61  _ForwardIterator
62  lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
63  {
64      return _VSTD::lower_bound(__first, __last, __value_,
65                               __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
66  }
67  
68  _LIBCPP_END_NAMESPACE_STD
69  
70  _LIBCPP_POP_MACROS
71  
72  #endif // _LIBCPP___ALGORITHM_LOWER_BOUND_H
73