[libcxx-commits] [PATCH] D121964: [libc++][ranges] Implement ranges::binary_search and ranges::{lower, upper}_bound

Louis Dionne via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Tue May 17 11:13:41 PDT 2022


ldionne added a comment.

Sorry for being MIA, but I do have a few comments. Some of them may apply to algorithms that we've shipped previously as well.



================
Comment at: libcxx/include/__algorithm/ranges_lower_bound.h:38
+_LIBCPP_HIDE_FROM_ABI constexpr
+_Ip __lower_bound_impl(_Ip __first, _Sp __last, const _Tp& __value, _Comp& __comp, _Proj& __proj) {
+  using __diff_t = typename iterator_traits<_Ip>::difference_type;
----------------
Mordante wrote:
> philnik wrote:
> > var-const wrote:
> > > Have you considered sharing the implementation of the algorithm between the ranges and non-ranges versions? This algorithm, while not very complicated, isn't trivial and is quite prone to off-by-one errors. Personally, I'm on the fence.
> > > 
> > > (cc'ing @ldionne as well)
> > Yes, but I think it's simple enough to not warrant sharing the implementation, but I'm on the fence too.
> I don't have a strong opinion whether to combine these two versions or keep them separate. `std::invoke` requires C++17, but our implementation of `std::invoke` uses `std::__invoke` requires C++11. So it seems to be an issue to use invoke on C++03.
I would really like to share this with the implementation in `<__algorithm/__lower_bound.h>`. I suspect it's not too difficult to do that, and we'll avoid duplicating code.


================
Comment at: libcxx/include/__algorithm/ranges_lower_bound.h:40
+  using __diff_t = typename iterator_traits<_Iter>::difference_type;
+  __diff_t __len = std::distance(__first, __last);
+
----------------
Shouldn't this be `ranges::distance`?


================
Comment at: libcxx/include/__algorithm/ranges_upper_bound.h:49
+                                         _Proj __proj = {}) const {
+    auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return !std::invoke(__comp, __rhs, __lhs); };
+    return __lower_bound_impl(ranges::begin(__r), ranges::end(__r), __value, __comp_lhs_rhs_swapped, __proj);
----------------
Should we be forwarding `__lhs` and `__rhs`? I think we're not losing anything if we do it, and I suspect we might be required to (if so, then we're also missing a test case).


================
Comment at: libcxx/include/__algorithm/ranges_upper_bound.h:50
+    auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return !std::invoke(__comp, __rhs, __lhs); };
+    return __lower_bound_impl(ranges::begin(__r), ranges::end(__r), __value, __comp_lhs_rhs_swapped, __proj);
+  }
----------------
This is not ADL-proof. Same above. I think we should have ADL proofing tests for ranges algorithms.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D121964/new/

https://reviews.llvm.org/D121964



More information about the libcxx-commits mailing list