예제 #1
0
 iterator_range<I>
 operator()(Rng & rng, iterator_difference_t<I> dist, V const & val, R pred = R{}, P proj = P{}) const
 {
     static_assert(!is_infinite<Rng>::value, "Trying to binary search an infinite range");
     RANGES_ASSERT(0 <= dist);
     RANGES_ASSERT(dist <= distance(rng));
     return (*this)(begin(rng), dist, std::move(pred), std::move(proj));
 }
예제 #2
0
 friend iterator_rvalue_reference_t<I> indirect_move(common_iterator<I, S> const &it)
     noexcept(noexcept(iter_move(std::declval<I const &>())))
 {
     common_cursor const &cur = get_cursor(it);
     RANGES_ASSERT(!cur.is_sentinel());
     return iter_move(cur.it());
 }
예제 #3
0
 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};
 }
예제 #4
0
 Rng operator()(Rng && rng, range_difference_t<Rng> from,
     range_difference_t<Rng> to) const
 {
     RANGES_ASSERT(from <= to);
     ranges::action::erase(rng, next(begin(rng), to), end(rng));
     ranges::action::erase(rng, begin(rng), next(begin(rng), from));
     return std::forward<Rng>(rng);
 }
예제 #5
0
파일: slice.hpp 프로젝트: QiTai/range-v3
 range_iterator_t<Rng> pos_at_(Rng && rng, Int i, concepts::InputRange *,
     std::false_type)
 {
     RANGES_ASSERT(i >= 0 || SizedRange<Rng>() || ForwardRange<Rng>());
     if(0 > i)
         return next(ranges::begin(rng), distance(rng) + i);
     return next(ranges::begin(rng), i);
 }
예제 #6
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};
 }
예제 #7
0
파일: fill_n.hpp 프로젝트: Hincoin/range-v3
 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);
 }
예제 #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};
 }
예제 #9
0
 void selection_sort(I begin, I end, C &pred, P &proj)
 {
     RANGES_ASSERT(begin != end);
     for(I lm1 = ranges::prev(end); begin != lm1; ++begin)
     {
         I i = ranges::min_element(begin, end, std::ref(pred), std::ref(proj));
         if(i != begin)
             ranges::iter_swap(begin, i);
     }
 }
예제 #10
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};
 }
예제 #11
0
 void next()
 {
     RANGES_ASSERT(cur_ != last_);
     // If the last match consumed zero elements, bump the position.
     advance_bounded(cur_, (int)zero_, last_);
     zero_ = false;
     for(; cur_ != last_; ++cur_)
     {
         std::pair<bool, range_difference_t<Rng>> p = fun_(cur_, last_);
         if(p.first)
         {
             advance(cur_, p.second);
             zero_ = (0 == p.second);
             return;
         }
     }
 }
예제 #12
0
 void operator()(Rng & rng, range_difference_t<Rng> const step) const
 {
     RANGES_ASSERT(0 < step);
     if(1 < step)
     {
         I begin = ranges::begin(rng);
         S const end = ranges::end(rng);
         if(begin != end)
         {
             for(I i = next_bounded(++begin, step-1, end); i != end;
                 advance_bounded(i, step, end), ++begin)
             {
                 *begin = std::move(*i);
             }
         }
         ranges::action::erase(rng, begin, end);
     }
 }
예제 #13
0
 I operator()(I const begin_, iterator_difference_t<I> const n_, C pred_ = C{}, P proj_ = P{}) const
 {
     RANGES_ASSERT(0 <= n_);
     auto &&pred = as_function(pred_);
     auto &&proj = as_function(proj_);
     iterator_difference_t<I> p = 0, c = 1;
     I pp = begin_;
     while(c < n_)
     {
         I cp = begin_ + c;
         if(pred(proj(*pp), proj(*cp)))
             return cp;
         ++c;
         ++cp;
         if(c == n_ || pred(proj(*pp), proj(*cp)))
             return cp;
         ++p;
         ++pp;
         c = 2 * p + 1;
     }
     return begin_ + n_;
 }
예제 #14
0
 cursor<true> begin_cursor() const
 {
     RANGES_ASSERT(!!gen_);
     return {*gen_};
 }
예제 #15
0
 cursor<false> begin_cursor()
 {
     RANGES_ASSERT(!!gen_);
     return {*gen_};
 }
예제 #16
0
 T const & get() const
 {
     RANGES_ASSERT(!!t_);
     return *t_;
 }
예제 #17
0
 T & get()
 {
     RANGES_ASSERT(!!t_);
     return *t_;
 }
예제 #18
0
 friend counted_iterator<I, D>
 recounted(counted_iterator<I, D> const &j, I i, iterator_difference_t<I> n)
 {
     RANGES_ASSERT(!ForwardIterator<I>() || ranges::next(j.base(), n) == i);
     return {i, j.count() - n};
 }
예제 #19
0
 void next()
 {
     RANGES_ASSERT(0 != n_);
     --n_;
 }
예제 #20
0
 T & get() const noexcept
 {
     RANGES_ASSERT(nullptr != t_);
     return *t_;
 }
예제 #21
0
파일: slice.hpp 프로젝트: QiTai/range-v3
 slice_view_(Rng rng, difference_type_ from, difference_type_ count)
   : rng_(std::move(rng)), from_(from), count_(count)
 {
     RANGES_ASSERT(0 <= count_);
 }
예제 #22
0
 I const & it() const
 {
     RANGES_ASSERT(!is_sentinel());
     return ranges::get<0>(data_);
 }
예제 #23
0
파일: take.hpp 프로젝트: Hincoin/range-v3
 Rng operator()(Rng && rng, range_difference_t<Rng> n) const
 {
     RANGES_ASSERT(n >= 0);
     ranges::action::erase(rng, ranges::next(begin(rng), n, end(rng)), end(rng));
     return std::forward<Rng>(rng);
 }
예제 #24
0
 S const & se() const
 {
     RANGES_ASSERT(is_sentinel());
     return ranges::get<1>(data_);
 }
예제 #25
0
 chunk_view(Rng rng, range_difference_t<Rng> n)
   : view_adaptor_t<chunk_view>(std::move(rng)), n_(n)
 {
     RANGES_ASSERT(0 < n_);
 }
예제 #26
0
 constexpr repeat_n_view(Val value, std::ptrdiff_t n)
   : value_(detail::move(value)), n_((RANGES_ASSERT(0 <= n), n))
 {}
예제 #27
0
파일: slice.hpp 프로젝트: QiTai/range-v3
 range_iterator_t<Rng> pos_at_(Rng && rng, Int i, concepts::InputRange *,
     std::true_type)
 {
     RANGES_ASSERT(0 <= i);
     return next(ranges::begin(rng), i);
 }
예제 #28
0
 T const & operator*() const
 {
     RANGES_ASSERT(!!*this);
     return ranges::get<0>(data_);
 }
예제 #29
0
파일: stride.hpp 프로젝트: QiTai/range-v3
 stride_view(Rng rng, difference_type_ stride)
   : view_adaptor_t<stride_view>{std::move(rng)}
   , stride_(stride)
 {
     RANGES_ASSERT(0 < stride_);
 }
예제 #30
0
 inline Target polymorphic_downcast(Source* x)
 {
     RANGES_ASSERT(dynamic_cast<Target>(x) == x);
     return static_cast<Target>(x);
 }