/// \file // Range v3 library // // Copyright Hui Xie 2021 // // Use, modification and distribution is subject to the // Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Project home: https://github.com/ericniebler/range-v3 // #ifndef RANGES_V3_VIEW_CHUNK_BY_HPP #define RANGES_V3_VIEW_CHUNK_BY_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace ranges { /// \addtogroup group-views /// @{ template struct chunk_by_view : view_facade, is_finite::value ? finite : range_cardinality::value> { private: friend range_access; Rng rng_; // cached version of the end of the first subrange / start of the second subrange detail::non_propagating_cache> second_; semiregular_box_t fun_; struct cursor { private: friend range_access; friend chunk_by_view; iterator_t cur_; iterator_t next_cur_; sentinel_t last_; semiregular_box_ref_or_val_t fun_; #ifdef _MSC_VER template> subrange read() const { return {cur_, next_cur_}; } #else subrange> read() const { return {cur_, next_cur_}; } #endif void next() { cur_ = next_cur_; auto partition_cur = adjacent_find(cur_, last_, not_fn(fun_)); next_cur_ = partition_cur != last_ ? ranges::next(partition_cur) : partition_cur; } bool equal(default_sentinel_t) const { return cur_ == last_; } bool equal(cursor const & that) const { return cur_ == that.cur_; } cursor(semiregular_box_ref_or_val_t fun, iterator_t first, iterator_t next_cur, sentinel_t last) : cur_(first) , next_cur_(next_cur) , last_(last) , fun_(fun) {} public: cursor() = default; }; cursor begin_cursor() { auto first = ranges::begin(rng_); auto last = ranges::end(rng_); if(!second_) { auto partition_cur = adjacent_find(first, last, not_fn(fun_)); second_ = partition_cur != last ? ranges::next(partition_cur) : partition_cur; } return {fun_, first, *second_, last}; } public: chunk_by_view() = default; constexpr chunk_by_view(Rng rng, Fun fun) : rng_(std::move(rng)) , fun_(std::move(fun)) {} }; #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17 template(typename Rng, typename Fun)( requires copy_constructible) chunk_by_view(Rng &&, Fun) ->chunk_by_view, Fun>; #endif namespace views { struct chunk_by_base_fn { template(typename Rng, typename Fun)( requires viewable_range AND forward_range AND // indirect_relation>) // constexpr chunk_by_view, Fun> operator()(Rng && rng, Fun fun) const { return {all(static_cast(rng)), std::move(fun)}; } }; struct chunk_by_fn : chunk_by_base_fn { using chunk_by_base_fn::operator(); template constexpr auto operator()(Fun fun) const { return make_view_closure(bind_back(chunk_by_base_fn{}, std::move(fun))); } }; /// \relates chunk_by_fn /// \ingroup group-views RANGES_INLINE_VARIABLE(chunk_by_fn, chunk_by) } // namespace views /// @} } // namespace ranges #include #include RANGES_SATISFY_BOOST_RANGE(::ranges::chunk_by_view) #endif