static I sized_impl(I const begin_, S end, D const d_, D count, V const &val, C &pred, P &proj) { D d = d_; // always the distance from begin to end auto begin = uncounted(begin_); while(true) { // Find begin element in sequence 1 that matches val, with a mininum of loop checks while(true) { if(d < count) // return the end if we've run out of room return ranges::next(recounted(begin_, std::move(begin), d_ - d), std::move(end)); if(pred(proj(*begin), val)) break; ++begin; --d; } // *begin matches val, now match elements after here auto m = begin; D c = 0; while(true) { if(++c == count) // If pattern exhausted, begin is the answer (works for 1 element pattern) return recounted(begin_, std::move(begin), d_ - d); ++m; // No need to check, we know we have room to match successfully if(!pred(proj(*m), val)) // if there is a mismatch, restart with a new begin { begin = next(std::move(m)); d -= (c+1); break; } // else there is a match, check next elements } } }
static I1 sized_impl(I1 const begin1_, S1 end1, D1 const d1_, I2 begin2, S2 end2, D2 d2, C &pred, P1 &proj1, P2 &proj2) { D1 d1 = d1_; auto begin1 = uncounted(begin1_); while(true) { // Find begin element in sequence 1 that matches *begin2, with a mininum of loop checks while(true) { if(d1 < d2) // return the end if we've run out of room return ranges::next(recounted(begin1_, std::move(begin1), d1_ - d1), std::move(end1)); if(pred(proj1(*begin1), proj2(*begin2))) break; ++begin1; --d1; } // *begin1 matches *begin2, now match elements after here auto m1 = begin1; I2 m2 = begin2; while(true) { if(++m2 == end2) // If pattern exhausted, begin1 is the answer (works for 1 element pattern) return recounted(begin1_, std::move(begin1), d1_ - d1); ++m1; // No need to check, we know we have room to match successfully if(!pred(proj1(*m1), proj2(*m2))) // if there is a mismatch, restart with a new begin1 { ++begin1; --d1; break; } // else there is a match, check next elements } } }
static I sized_impl(I const begin_, I end, D d, D count, V const &val, C &pred, P &proj) { if(d < count) return end; auto begin = uncounted(begin_); auto const s = uncounted(end - (count - 1)); // Start of pattern match can't go beyond here while(true) { // Find first element in sequence that matches val, with a mininum of loop checks while(true) { if(begin >= s) // return the end if we've run out of room return end; if(pred(proj(*begin), val)) break; ++begin; } // *begin matches val, now match elements after here auto m = begin; D c = 0; while(true) { if(++c == count) // If pattern exhausted, begin is the answer (works for 1 element pattern) return recounted(begin_, std::move(begin)); ++m; // No need to check, we know we have room to match successfully if(!pred(proj(*m), val)) // if there is a mismatch, restart with a new begin { begin = next(std::move(m)); break; } // else there is a match, check next elements } } }
O operator()(O begin, iterator_difference_t<O> n, V const & val) const { RANGES_ASSERT(n >= 0); auto norig = n; auto b = uncounted(begin); for(; n != 0; ++b, --n) *b = val; return recounted(begin, b, norig); }
std::pair<O, F> operator()(O begin, iterator_difference_t<O> n, F fun) const { RANGES_ASSERT(n >= 0); auto norig = n; auto b = uncounted(begin); for(; 0 != n; ++b, --n) *b = fun(); return {recounted(begin, b, norig), fun}; }
I operator()(I begin, difference_type_t<I> n, F fun, P proj = P{}) const { RANGES_EXPECT(0 <= n); auto norig = n; auto b = uncounted(begin); for(; 0 < n; ++b, --n) invoke(fun, invoke(proj, *b)); return recounted(begin, b, norig); }
tagged_pair<tag::out(O), tag::fun(F)> operator()(O begin, difference_type_t<O> n, F fun) const { RANGES_EXPECT(n >= 0); auto norig = n; auto b = uncounted(begin); for(; 0 != n; ++b, --n) *b = invoke(fun); return {recounted(begin, b, norig), detail::move(fun)}; }
std::pair<I, O> operator()(I begin, iterator_difference_t<I> n, O out) const { RANGES_ASSERT(0 <= n); auto norig = n; auto b = uncounted(begin); for(; n != 0; ++b, ++out, --n) *out = *b; return {recounted(begin, b, norig), out}; }
std::pair<I, O> operator()(I begin, iterator_difference_t<I> n, O out, P proj_ = P{}) const { RANGES_ASSERT(0 <= n); auto &&proj = invokable(proj_); auto norig = n; auto b = uncounted(begin); for(; n != 0; ++b, ++out, --n) *out = proj(*b); return {recounted(begin, b, norig), out}; }
std::tuple<I0, I1, O> operator()(I0 begin0, iterator_difference_t<I0> n0, I1 begin1, iterator_difference_t<I1> n1, O out, C r = C{}, P0 p0 = P0{}, P1 p1 = P1{}) const { using T = std::tuple<I0, I1, O>; auto &&ir = invokable(r); auto &&ip0 = invokable(p0); auto &&ip1 = invokable(p1); auto n0orig = n0; auto n1orig = n1; auto b0 = uncounted(begin0); auto b1 = uncounted(begin1); while(true) { if(0 == n0) { auto res = copy_n(b1, n1, out); begin0 = recounted(begin0, b0, n0orig); begin1 = recounted(begin1, res.first, n1orig); return T{begin0, begin1, res.second}; } if(0 == n1) { auto res = copy_n(b0, n0, out); begin0 = recounted(begin0, res.first, n0orig); begin1 = recounted(begin1, b1, n1orig); return T{begin0, begin1, res.second}; } if(ir(ip1(*b1), ip0(*b0))) { *out = *b1; ++b1; ++out; --n1; } else { *out = *b0; ++b0; ++out; --n0; } } }
I operator()(I begin, S end, C pred_, P proj_ = P{}) const { auto && pred = invokable(pred_); auto && proj = invokable(proj_); auto len = distance(begin, end); while(len != 0) { auto const half = len / 2; auto middle = next(uncounted(begin), half); if(pred(proj(*middle))) { begin = recounted(begin, std::move(++middle), half + 1); len -= half + 1; } else len = half; } return begin; }