コード例 #1
0
ファイル: rotate.hpp プロジェクト: CornedBee/range-v3
 static range<I> rotate_gcd(I begin, I middle, I end)
 {
     auto const m1 = middle - begin;
     auto const m2 = end - middle;
     if(m1 == m2)
     {
         swap_ranges(begin, middle, middle);
         return {middle, end};
     }
     auto const g = rotate_fn::gcd(m1, m2);
     for (I p = begin + g; p != begin;)
     {
         iterator_value_t<I> t = iter_move(--p);
         I p1 = p;
         I p2 = p1 + m1;
         do
         {
             *p1 = iter_move(p2);
             p1 = p2;
             auto const d = end - p2;
             if(m1 < d)
                 p2 += m1;
             else
                 p2 = begin + (m1 - d);
         } while(p2 != p);
         *p1 = std::move(t);
     }
     return {begin + m2, end};
 }
コード例 #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
ファイル: stable_partition.hpp プロジェクト: Hincoin/range-v3
 static I impl(I begin, I end, C pred, P proj, D len, Pair p, concepts::ForwardIterator *fi)
 {
     // *begin is known to be false
     // len >= 1
     if (len == 1)
         return begin;
     if(len == 2)
     {
         I tmp = begin;
         if(pred(proj(*++tmp)))
         {
             ranges::iter_swap(begin, tmp);
             return tmp;
         }
         return begin;
     }
     if(len <= p.second)
     {   // The buffer is big enough to use
         using value_type = iterator_value_t<I>;
         std::unique_ptr<value_type, detail::destroy_n<value_type>> h{p.first, {}};
         // Move the falses into the temporary buffer, and the trues to the front of the line
         // Update begin to always point to the end of the trues
         auto buf = ranges::make_counted_raw_storage_iterator(p.first, h.get_deleter());
         *buf = iter_move(begin);
         ++buf;
         auto res = partition_move(next(begin), end, begin, buf, std::ref(pred), std::ref(proj));
         // All trues now at start of range, all falses in buffer
         // Move falses back into range, but don't mess up begin which points to first false
         ranges::move(p.first, std::get<2>(res).base().base(), std::get<1>(res));
         // h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer
         return std::get<1>(res);
     }
     // Else not enough buffer, do in place
     // len >= 3
     D half = len / 2;  // half >= 2
     I middle = next(begin, half);
     // recurse on [begin, middle), *begin know to be false
     // F?????????????????
     // f       m         l
     I begin_false = stable_partition_fn::impl(begin, middle, pred, proj, half, p, fi);
     // TTTFFFFF??????????
     // f  ff   m         l
     // recurse on [middle, end], except increase middle until *(middle) is false, *end know to be true
     I m1 = middle;
     D len_half = len - half;
     while(pred(proj(*m1)))
     {
         if(++m1 == end)
             return ranges::rotate(begin_false, middle, end).begin();
         --len_half;
     }
     // TTTFFFFFTTTF??????
     // f  ff   m  m1     l
     I end_false = stable_partition_fn::impl(m1, end, pred, proj, len_half, p, fi);
     // TTTFFFFFTTTTTFFFFF
     // f  ff   m    sf   l
     return ranges::rotate(begin_false, middle, end_false).begin();
     // TTTTTTTTFFFFFFFFFF
     //         |
 }
コード例 #4
0
ファイル: rotate.hpp プロジェクト: CornedBee/range-v3
 static range<I> rotate_left(I begin, I end)
 {
     iterator_value_t<I> tmp = iter_move(begin);
     I lm1 = move(next(begin), end, begin).second;
     *lm1 = std::move(tmp);
     return {lm1, end};
 }
コード例 #5
0
 static I impl(I begin, I end, C pred, P proj, D len, Pair const p, concepts::ForwardIterator *fi)
 {
     // *begin is known to be false
     // len >= 1
     if(len == 1)
         return begin;
     if(len == 2)
     {
         I tmp = begin;
         if(invoke(pred, invoke(proj, *++tmp)))
         {
             ranges::iter_swap(begin, tmp);
             return tmp;
         }
         return begin;
     }
     if(len <= p.second)
     {   // The buffer is big enough to use
         // Move the falses into the temporary buffer, and the trues to the front of the line
         // Update begin to always point to the end of the trues
         auto tmpbuf = make_raw_buffer(p.first);
         auto buf = tmpbuf.begin();
         *buf = iter_move(begin);
         ++buf;
         auto res = partition_copy(make_move_iterator(next(begin)),
             make_move_sentinel(end), begin, buf, std::ref(pred), std::ref(proj));
         // All trues now at start of range, all falses in buffer
         // Move falses back into range, but don't mess up begin which points to first false
         ranges::move(p.first, res.out2().base().base(), res.out1());
         // h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer
         return res.out1();
     }
     // Else not enough buffer, do in place
     // len >= 3
     D half = len / 2;  // half >= 2
     I middle = next(begin, half);
     // recurse on [begin, middle), *begin know to be false
     // F?????????????????
     // f       m         l
     I begin_false = stable_partition_fn::impl(begin, middle, pred, proj, half, p, fi);
     // TTTFFFFF??????????
     // f  ff   m         l
     // recurse on [middle, end], except increase middle until *(middle) is false, *end know to be true
     I m1 = middle;
     D len_half = len - half;
     while(invoke(pred, invoke(proj, *m1)))
     {
         if(++m1 == end)
             return ranges::rotate(begin_false, middle, end).begin();
         --len_half;
     }
     // TTTFFFFFTTTF??????
     // f  ff   m  m1     l
     I end_false = stable_partition_fn::impl(m1, end, pred, proj, len_half, p, fi);
     // TTTFFFFFTTTTTFFFFF
     // f  ff   m    sf   l
     return ranges::rotate(begin_false, middle, end_false).begin();
     // TTTTTTTTFFFFFFFFFF
     //         |
 }
コード例 #6
0
ファイル: rotate.hpp プロジェクト: CornedBee/range-v3
 static range<I> rotate_right(I begin, I end)
 {
     I lm1 = prev(end);
     iterator_value_t<I> tmp = iter_move(lm1);
     I fp1 = move_backward(begin, lm1, end).second;
     *begin = std::move(tmp);
     return {fp1, end};
 }
コード例 #7
0
ファイル: replace.hpp プロジェクト: gnzlbg/range-v3
 common_reference_t<unwrap_reference_t<Val2 const &>, rvalue_reference_t<I>>
 operator()(move_tag, I const &i) const
 {
     auto &&x = iter_move(i);
     if(x == unwrap_reference(old_value_))
         return unwrap_reference(new_value_);
     return ((decltype(x) &&) x);
 }
コード例 #8
0
ファイル: sort.hpp プロジェクト: OhGameKillers/range-v3
 inline void linear_insert(I begin, I end, C &pred, P &proj)
 {
     iterator_value_t<I> val = iter_move(end);
     if(pred(proj(val), proj(*begin)))
     {
         move_backward(begin, end, end + 1);
         *begin = std::move(val);
     }
     else
         detail::unguarded_linear_insert(end, std::move(val), pred, proj);
 }
コード例 #9
0
ファイル: sort.hpp プロジェクト: OhGameKillers/range-v3
 inline void unguarded_linear_insert(I end, iterator_value_t<I> val, C &pred, P &proj)
 {
     I next = prev(end);
     while(pred(proj(val), proj(*next)))
     {
         *end = iter_move(next);
         end = next;
         --next;
     }
     *end = std::move(val);
 }
コード例 #10
0
ファイル: move_backward.hpp プロジェクト: CornedBee/range-v3
 std::pair<I, O> operator()(I begin, S end_, O out, P proj_ = P{}) const
 {
     auto &&proj = invokable(proj_);
     I i = next_to(begin, end_), end = i;
     while(begin != i)
     {
         // BUGBUG should the projection be applied *before* the move?
         auto &&x = iter_move(--i);
         *--out = proj((decltype(x) &&) x);
     }
     return {end, out};
 }
コード例 #11
0
            I operator()(I begin, S end, C pred = C{}, P proj = P{}) const
            {
                begin = adjacent_find(std::move(begin), end, std::ref(pred), std::ref(proj));

                if(begin != end)
                {
                    for(I i = next(begin); ++i != end;)
                        if(!invoke(pred, invoke(proj, *begin), invoke(proj, *i)))
                            *++begin = iter_move(i);
                    ++begin;
                }
                return begin;
            }
コード例 #12
0
ファイル: merge_move.hpp プロジェクト: meetmorpheus/range-v3
 std::tuple<I0, I1, O>
 operator()(I0 begin0, S0 end0, I1 begin1, S1 end1, O out, C pred_ = C{},
     P0 proj0_ = P0{}, P1 proj1_ = P1{}) const
 {
     auto &&pred = as_function(pred_);
     auto &&proj0 = as_function(proj0_);
     auto &&proj1 = as_function(proj1_);
     for(; begin0 != end0 && begin1 != end1; ++out)
     {
         if(pred(proj1(*begin1), proj0(*begin0)))
         {
             *out = iter_move(begin1);
             ++begin1;
         }
         else
         {
             *out = iter_move(begin0);
             ++begin0;
         }
     }
     auto t0 = move(begin0, end0, out);
     auto t1 = move(begin1, end1, t0.second);
     return std::tuple<I0, I1, O>{t0.first, t1.first, t1.second};
 }
コード例 #13
0
ファイル: unique.hpp プロジェクト: Hincoin/range-v3
            I operator()(I begin, S end, C pred_ = C{}, P proj_ = P{}) const
            {
                auto &&pred = as_function(pred_);
                auto &&proj = as_function(proj_);

                begin = adjacent_find(std::move(begin), end, std::ref(pred), std::ref(proj));

                if(begin != end)
                {
                    for(I i = next(begin); ++i != end;)
                        if(!pred(proj(*begin), proj(*i)))
                            *++begin = iter_move(i);
                    ++begin;
                }
                return begin;
            }
コード例 #14
0
            I operator()(I first, S last, C pred, P proj = {}) const
            {
                while(true)
                {
                    first = find_if(std::move(first), last, pred, proj);
                    last  = find_if_not(
                            make_reverse_iterator(std::move(last)),
                            make_reverse_iterator(first),
                            pred, proj).base();
                    if (first == last) return first;
                    *first = iter_move(--last);

                    // discussion here: https://github.com/ericniebler/range-v3/issues/988
                    ++first;
                }
            }
コード例 #15
0
 I operator()(I begin, S end, T const &val, P proj_ = P{}) const
 {
     auto &&proj = as_function(proj_);
     begin = find(std::move(begin), end, val, std::ref(proj));
     if(begin != end)
     {
         for(I i = next(begin); i != end; ++i)
         {
             if(!(proj(*i) == val))
             {
                 *begin = iter_move(i);
                 ++begin;
             }
         }
     }
     return begin;
 }
コード例 #16
0
ファイル: remove_if.hpp プロジェクト: michel-steuwer/range-v3
 I operator()(I begin, S end, C pred_, P proj_ = P{}) const
 {
     auto &&pred = as_function(pred_);
     auto &&proj = as_function(proj_);
     begin = find_if(std::move(begin), end, std::ref(pred), std::ref(proj));
     if(begin != end)
     {
         for(I i = next(begin); i != end; ++i)
         {
             if(!(pred(proj(*i))))
             {
                 *begin = iter_move(i);
                 ++begin;
             }
         }
     }
     return begin;
 }
コード例 #17
0
ファイル: zip.hpp プロジェクト: anders-sjogren/range-v3
                auto operator()(Its const &...its) const
                    noexcept(meta::and_c<noexcept(iterator_reference_t<Its>(*its))...>::value)
                RANGES_DECLTYPE_AUTO_RETURN
                (
                    common_tuple<iterator_reference_t<Its>...>{*its...}
                )

                // tuple rvalue reference
                template<typename ...Its,
                    CONCEPT_REQUIRES_(meta::and_<Readable<Its>...>() && sizeof...(Its) != 2)>
                auto operator()(move_tag, Its const &...its) const
                    noexcept(meta::and_c<
                        noexcept(iterator_rvalue_reference_t<Its>(iter_move(its)))...>::value)
                RANGES_DECLTYPE_AUTO_RETURN
                (
                    common_tuple<iterator_rvalue_reference_t<Its>...>{iter_move(its)...}
                )

                // pair value
                template<typename It1, typename It2,
                    CONCEPT_REQUIRES_(Readable<It1>() && Readable<It2>())>
                auto operator()(copy_tag, It1, It2) const ->
                    std::pair<iterator_value_t<It1>, iterator_value_t<It2>>;

                // pair reference
                template<typename It1, typename It2,
                    CONCEPT_REQUIRES_(Readable<It1>() && Readable<It2>())>
                auto operator()(It1 const &it1, It2 const &it2) const
                    noexcept(noexcept(iterator_reference_t<It1>(*it1)) &&
                             noexcept(iterator_reference_t<It2>(*it2)))
                RANGES_DECLTYPE_AUTO_RETURN
コード例 #18
0
ファイル: sdb_util.c プロジェクト: xinoir/gocha
bool iter_next(struct iter *iter) {
    assert(iter); assert(iter->buffer);
    return !*(iter->buffer) ? false : !iter->item ? (iter->item = iter->buffer) : *(iter_move(iter));
}
コード例 #19
0
 static I impl(I begin, I end, C pred, P proj, D len, Pair p,
               detail::bidirectional_iterator_tag_ bi)
 {
     // *begin is known to be false
     // *end is known to be true
     // len >= 2
     if(len == 2)
     {
         ranges::iter_swap(begin, end);
         return end;
     }
     if(len == 3)
     {
         I tmp = begin;
         if(invoke(pred, invoke(proj, *++tmp)))
         {
             ranges::iter_swap(begin, tmp);
             ranges::iter_swap(tmp, end);
             return end;
         }
         ranges::iter_swap(tmp, end);
         ranges::iter_swap(begin, tmp);
         return tmp;
     }
     if(len <= p.second)
     { // The buffer is big enough to use
         // Move the falses into the temporary buffer, and the trues to the front
         // of the line Update begin to always point to the end of the trues
         auto tmpbuf = ranges::make_raw_buffer(p.first);
         auto buf = tmpbuf.begin();
         *buf = iter_move(begin);
         ++buf;
         auto res = partition_copy(make_move_iterator(next(begin)),
                                   make_move_sentinel(end),
                                   begin,
                                   buf,
                                   std::ref(pred),
                                   std::ref(proj));
         begin = res.out1;
         // move *end, known to be true
         *begin = iter_move(res.in);
         ++begin;
         // All trues now at start of range, all falses in buffer
         // Move falses back into range, but don't mess up begin which points to
         // first false
         ranges::move(p.first, res.out2.base().base(), begin);
         // h destructs moved-from values out of the temp buffer, but doesn't
         // deallocate buffer
         return begin;
     }
     // Else not enough buffer, do in place
     // len >= 4
     I middle = begin;
     D half = len / 2; // half >= 2
     advance(middle, half);
     // recurse on [begin, middle-1], except reduce middle-1 until *(middle-1) is
     // true, *begin know to be false F????????????????T f       m        l
     I m1 = middle;
     I begin_false = begin;
     D len_half = half;
     while(!invoke(pred, invoke(proj, *--m1)))
     {
         if(m1 == begin)
             goto first_half_done;
         --len_half;
     }
     // F???TFFF?????????T
     // f   m1  m        l
     begin_false =
         stable_partition_fn::impl(begin, m1, pred, proj, len_half, p, bi);
 first_half_done:
     // TTTFFFFF?????????T
     // f  ff   m        l
     // recurse on [middle, end], except increase middle until *(middle) is false,
     // *end know to be true
     m1 = middle;
     len_half = len - half;
     while(invoke(pred, invoke(proj, *m1)))
     {
         if(++m1 == end)
             return ranges::rotate(begin_false, middle, ++end).begin();
         --len_half;
     }
     // TTTFFFFFTTTF?????T
     // f  ff   m  m1    l
     I end_false = stable_partition_fn::impl(m1, end, pred, proj, len_half, p, bi);
     // TTTFFFFFTTTTTFFFFF
     // f  ff   m    sf  l
     return ranges::rotate(begin_false, middle, end_false).begin();
     // TTTTTTTTFFFFFFFFFF
     //         |
 }
コード例 #20
0
ファイル: sort.hpp プロジェクト: OhGameKillers/range-v3
 inline void unguarded_insertion_sort(I begin, I end, C &pred, P &proj)
 {
     for(I i = begin; i != end; ++i)
         detail::unguarded_linear_insert(i, iter_move(i), pred, proj);
 }