requires models::Permutable<I> I bidirectional_buffer(I first, I last, difference_type_t<I> n, buf_t<I>& buf, Pred& pred, Proj& proj) { // Precondition: !pred(proj(*first)) // Precondition: pred(proj(*last)) // Precondition: n == distance(first, last) STL2_ASSUME(n >= 2); STL2_ASSUME(n <= buf.size()); // Move the false values into the temporary buffer // and the true values to the front of the sequence. auto&& vec = detail::make_temporary_vector(buf); vec.push_back(__stl2::iter_move(first)); auto middle = __stl2::next(first); middle = __stl2::partition_move(__stl2::move(middle), last, __stl2::move(first), __stl2::back_inserter(vec), __stl2::ref(pred), __stl2::ref(proj)).out1(); *middle = __stl2::iter_move(last); ++middle; __stl2::move(vec, middle); return middle; }
requires models::Permutable<I> I bidirectional(I first, I last, difference_type_t<I> n, buf_t<I>& buf, Pred& pred, Proj& proj) { // Precondition: !pred(proj(*first)) // Precondition: pred(proj(*last)) // Precondition: n == distance(first, last) STL2_ASSUME(n >= difference_type_t<I>(1)); if (n == difference_type_t<I>(1)) { __stl2::iter_swap(first, last); return last; } // n >= 2 if (n <= buf.size()) { return stable_part::bidirectional_buffer( __stl2::move(first), __stl2::move(last), n, buf, pred, proj); } const auto half_n = n / 2; auto middle = __stl2::next(first, half_n); auto pp1 = stable_part::bidirectional_reduce_back( __stl2::move(first), middle, half_n, buf, pred, proj); auto pp2 = stable_part::bidirectional_reduce_front( middle, __stl2::move(last), n - half_n, buf, pred, proj); return __stl2::rotate(__stl2::move(pp1), __stl2::move(middle), __stl2::move(pp2)).begin(); }
requires models::Permutable<I> ext::range<I> forward(I first, difference_type_t<I> n, buf_t<I>& buf, Pred& pred, Proj& proj) { // Precondition: !pred(proj(*first))) STL2_ASSUME(n > 0); auto middle = __stl2::next(first); if (n == difference_type_t<I>(1)) { return {__stl2::move(first), __stl2::move(middle)}; } // n >= 2 if (n <= buf.size()) { return stable_part::forward_buffer( __stl2::move(first), __stl2::move(middle), n, buf, pred, proj); } const auto half_n = n / 2; auto res1 = stable_part::forward(__stl2::move(first), half_n, buf, pred, proj); auto res2 = stable_part::forward_reduce(res1.end(), n - half_n, buf, pred, proj); auto pp = __stl2::rotate(__stl2::move(res1.begin()), __stl2::move(res1.end()), __stl2::move(res2.begin())).begin(); return {__stl2::move(pp), __stl2::move(res2.end())}; }
requires RandomAccessIterator<I>() { STL2_ASSUME(n <= count_); current() += n; count_ -= n; return *this; }
tagged_pair<tag::in(I), tag::out(O)> copy_n(I first_, DifferenceType<I> n, O result) { STL2_ASSUME(n >= 0); auto norig = n; auto first = __stl2::ext::uncounted(first_); for(; n > 0; ++first, ++result, --n) { *result = *first; } return {__stl2::ext::recounted(first_, first, norig), result}; }
void skip_false(I& last, difference_type_t<I>& n, Pred& pred, Proj& proj) { // Move last backward past values that do not satisfy pred. // Precondition: pred(proj(*(last - n))) STL2_ASSUME(n > 0); // Ensures: n == 0 || pred(proj(*last)) do { --last; } while (--n != 0 && !pred(proj(*last))); }
requires models::Permutable<I> ext::range<I> forward_buffer(I first, I next, difference_type_t<I> n, buf_t<I>& buf, Pred& pred, Proj& proj) { // Precondition: !pred(proj(*first))) // Precondition: __stl2::next(first) == next STL2_ASSUME(n >= 2); STL2_ASSUME(n <= buf.size()); auto&& vec = detail::make_temporary_vector(buf); vec.push_back(__stl2::iter_move(first)); auto counted = __stl2::make_counted_iterator( ext::uncounted(next), n - 1); auto pp = __stl2::partition_move( __stl2::move(counted), default_sentinel{}, __stl2::move(first), __stl2::back_inserter(vec), __stl2::ref(pred), __stl2::ref(proj)).out1(); auto last = __stl2::move(vec, pp).out(); return {__stl2::move(pp), __stl2::move(last)}; }
requires models::Sortable<I, Comp, Proj> I choose_pivot(I first, I last, Comp& comp, Proj& proj) { STL2_ASSUME(first != last); I mid = first + difference_type_t<I>(last - first) / 2; --last; // Find the median: return [&](auto&& a, auto&& b, auto&& c) { return comp(a, b) ? (comp(b, c) ? mid : (comp(a, c) ? last : first)) : (comp(a, c) ? first : (comp(b, c) ? last : mid )); }(proj(*first), proj(*mid), proj(*last)); }
inline I merge_n_with_buffer(I f0, DifferenceType<I> n0, I f1, DifferenceType<I> n1, buf_t<I>& buf, Comp& comp, Proj& proj) { STL2_ASSUME(n0 <= buf.size()); auto&& vec = make_temporary_vector(buf); __stl2::move(__stl2::make_counted_iterator(f0, n0), __stl2::default_sentinel{}, __stl2::back_inserter(vec)); return __stl2::merge_move( vec.begin(), vec.end(), __stl2::make_counted_iterator(__stl2::move(f1), n1), __stl2::default_sentinel{}, __stl2::move(f0), __stl2::ref(comp), __stl2::ref(proj), __stl2::ref(proj)).out(); }
requires models::Permutable<I> I bidirectional_reduce_back(I first, I last, difference_type_t<I> n, buf_t<I>& buf, Pred& pred, Proj& proj) { // Precondition: !pred(proj(*first)) // Precondition: n == __stl2::distance(first, last) STL2_ASSUME(n >= difference_type_t<I>(1)); stable_part::skip_false(last, n, pred, proj); if (n == difference_type_t<I>(0)) { return first; } return stable_part::bidirectional(first, last, n, buf, pred, proj); }
requires models::Permutable<I> I bidirectional_reduce_front(I first, I last, difference_type_t<I> n, buf_t<I>& buf, Pred& pred, Proj& proj) { // Precondition: pred(proj(*last)) // Precondition: n == distance(first, last) STL2_ASSUME(n >= difference_type_t<I>(0)); stable_part::skip_true(first, n, pred, proj); if (n == difference_type_t<I>(0)) { return __stl2::move(++last); } return stable_part::bidirectional(first, last, n, buf, pred, proj); }
requires models::IndirectlyCopyable<I, O> tagged_pair<tag::in(I), tag::out(O)> copy_n(I first_, difference_type_t<I> n, O result) { STL2_ASSUME(n >= 0); auto norig = n; auto first = __stl2::ext::uncounted(first_); for(; n > 0; ++first, ++result, --n) { *result = *first; } return { __stl2::ext::recounted(first_, first, norig), __stl2::move(result) }; }
I is_heap_until_n(I first, const DifferenceType<I> n, Comp comp_ = Comp{}, Proj proj_ = Proj{}) { STL2_ASSUME(0 <= n); auto&& comp = __stl2::as_function(comp_); auto&& proj = __stl2::as_function(proj_); DifferenceType<I> p = 0, c = 1; I pp = first; while (c < n) { I cp = first + c; if (comp(proj(*pp), proj(*cp))) { return cp; } ++c; ++cp; if (c == n || comp(proj(*pp), proj(*cp))) { return cp; } ++p; ++pp; c = 2 * p + 1; } return first + n; }
STL2_CONSTEXPR_EXT counted_iterator operator+(difference_type_t<I> n) const requires RandomAccessIterator<I>() { STL2_ASSUME(n <= count_); return {current() + n, count_ - n}; }
constexpr T* operator->() const noexcept { STL2_ASSUME(ptr_); return ptr_; }
requires RandomAccessIterator<I>() { STL2_ASSUME(n < count_); return current()[n]; }
constexpr T& operator*() const noexcept { STL2_ASSUME(ptr_); return *ptr_; }