Beispiel #1
0
 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
         }
     }
 }
Beispiel #2
0
 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
         }
     }
 }
Beispiel #3
0
 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
         }
     }
 }
Beispiel #4
0
 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);
 }
Beispiel #5
0
 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);
 }
Beispiel #7
0
 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)};
 }
Beispiel #8
0
 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};
 }
Beispiel #9
0
 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};
 }
Beispiel #10
0
 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;
         }
     }
 }
Beispiel #11
0
 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;
 }