Skip to content

Commit 7aa3927

Browse files
committed
Review feedback: don't use one-sided lower bound in lower_bound() itself since that violates the complexity guarantees from the standard.
1 parent 08af548 commit 7aa3927

File tree

3 files changed

+13
-28
lines changed

3 files changed

+13
-28
lines changed

libcxx/include/__algorithm/lower_bound.h

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -78,38 +78,24 @@ __lower_bound_onesided(_Iter __first, _Sent __last, const _Type& __value, _Comp&
7878
return __first;
7979
}
8080

81-
template <class _AlgPolicy, class _InputIter, class _Sent, class _Type, class _Proj, class _Comp>
82-
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIter __lower_bound(
83-
_InputIter __first, _Sent __last, const _Type& __value, _Comp& __comp, _Proj& __proj, std::input_iterator_tag) {
84-
return std::__lower_bound_onesided<_AlgPolicy>(__first, __last, __value, __comp, __proj);
85-
}
86-
8781
template <class _AlgPolicy, class _RandIter, class _Sent, class _Type, class _Proj, class _Comp>
8882
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandIter __lower_bound(
8983
_RandIter __first,
9084
_Sent __last,
9185
const _Type& __value,
9286
_Comp& __comp,
93-
_Proj& __proj,
94-
std::random_access_iterator_tag) {
87+
_Proj& __proj) {
9588
const auto __dist = _IterOps<_AlgPolicy>::distance(__first, __last);
9689
return std::__lower_bound_bisecting<_AlgPolicy>(__first, __value, __dist, __comp, __proj);
9790
}
9891

99-
template <class _AlgPolicy, class _Iter, class _Sent, class _Type, class _Proj, class _Comp>
100-
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter
101-
__lower_bound(_Iter __first, _Sent __last, const _Type& __value, _Comp&& __comp, _Proj&& __proj) {
102-
return std::__lower_bound<_AlgPolicy>(
103-
__first, __last, __value, __comp, __proj, typename _IterOps<_AlgPolicy>::template __iterator_category<_Iter>());
104-
}
105-
10692
template <class _ForwardIterator, class _Tp, class _Compare>
10793
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
10894
_ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) {
10995
static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value,
11096
"The comparator has to be callable");
11197
auto __proj = std::__identity();
112-
return std::__lower_bound<_ClassicAlgPolicy>(__first, __last, __value, std::move(__comp), std::move(__proj));
98+
return std::__lower_bound<_ClassicAlgPolicy>(__first, __last, __value, __comp, __proj);
11399
}
114100

115101
template <class _ForwardIterator, class _Tp>

libcxx/test/std/algorithms/alg.sorting/alg.binary.search/lower.bound/lower_bound.pass.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,14 @@ test(Iter first, Iter last, const T& value)
4545
stride_counting_iterator l(last, &strides, &displacement);
4646

4747
auto i = std::lower_bound(f, l, value);
48-
for (auto j = f; j != i; ++j)
48+
for (auto j = base(f); j != base(i); ++j)
4949
assert(*j < value);
50-
for (auto j = i; j != l; ++j)
50+
for (auto j = base(i); j != base(l); ++j)
5151
assert(!(*j < value));
5252

53-
auto len = std::distance(first, last);
54-
assert(strides <= 2.5 * len + 1);
55-
assert(displacement <= 2.5 * len + 1);
53+
auto len = static_cast<std::size_t>(std::distance(first, last));
54+
assert(strides <= 2 * len);
55+
assert(displacement <= 2 * len);
5656
}
5757

5858
template <class Iter>

libcxx/test/std/algorithms/alg.sorting/alg.binary.search/lower.bound/lower_bound_comp.pass.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,15 @@ test(Iter first, Iter last, const T& value)
5151
};
5252

5353
auto i = std::lower_bound(f, l, value, cmp);
54-
55-
for (auto j = f; j != i; ++j)
54+
for (auto j = base(f); j != base(i); ++j)
5655
assert(std::greater<int>()(*j, value));
57-
for (auto j = i; j != l; ++j)
56+
for (auto j = base(i); j != base(l); ++j)
5857
assert(!std::greater<int>()(*j, value));
5958

60-
auto len = std::distance(first, last);
61-
assert(strides <= 2.5 * len + 1);
62-
assert(displacement <= 2.5 * len + 1);
63-
assert(comparisons <= 2 * ceil(log(len + 1) + 2));
59+
auto len = static_cast<std::size_t>(std::distance(first, last));
60+
assert(strides <= 2 * len);
61+
assert(displacement <= 2 * len);
62+
assert(comparisons <= std::ceil(std::log2(len + 1)));
6463
}
6564

6665
template <class Iter>

0 commit comments

Comments
 (0)