range<I> operator()(I begin, iterator_difference_t<I> dist, V const & val, R pred_ = R{}, P proj_ = P{}) const { RANGES_ASSERT(0 <= dist); auto &&pred = invokable(pred_); auto &&proj = invokable(proj_); while(0 != dist) { auto half = dist / 2; auto middle = next(begin, half); if(pred(proj(*middle), val)) { begin = std::move(++middle); dist -= half + 1; } else if(pred(val, proj(*middle))) { dist = half; } else return {lower_bound_n(std::move(begin), half, val, std::ref(pred)), upper_bound_n(next(middle), dist - half - 1, val, std::ref(pred))}; } return {begin, begin}; }
void insertion_sort_n(I begin, typename std::iterator_traits<I>::difference_type n) { auto m = 0; for(auto it = begin; m != n; ++it, ++m) { auto insertion = upper_bound_n(begin, m, *it); ranges::rotate(insertion, it, std::next(it)); } }