File indexing completed on 2025-01-18 10:09:54
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef RANGES_V3_VIEW_CHUNK_BY_HPP
0015 #define RANGES_V3_VIEW_CHUNK_BY_HPP
0016
0017 #include <type_traits>
0018 #include <utility>
0019
0020 #include <meta/meta.hpp>
0021
0022 #include <range/v3/range_fwd.hpp>
0023
0024 #include <range/v3/algorithm/adjacent_find.hpp>
0025 #include <range/v3/functional/bind_back.hpp>
0026 #include <range/v3/functional/not_fn.hpp>
0027 #include <range/v3/iterator/default_sentinel.hpp>
0028 #include <range/v3/range/access.hpp>
0029 #include <range/v3/range/concepts.hpp>
0030 #include <range/v3/range/traits.hpp>
0031 #include <range/v3/utility/optional.hpp>
0032 #include <range/v3/utility/semiregular_box.hpp>
0033 #include <range/v3/utility/static_const.hpp>
0034 #include <range/v3/view/all.hpp>
0035 #include <range/v3/view/facade.hpp>
0036 #include <range/v3/view/subrange.hpp>
0037 #include <range/v3/view/view.hpp>
0038
0039 #include <range/v3/detail/prologue.hpp>
0040
0041 namespace ranges
0042 {
0043
0044
0045
0046 template<typename Rng, typename Fun>
0047 struct chunk_by_view
0048 : view_facade<chunk_by_view<Rng, Fun>,
0049 is_finite<Rng>::value ? finite : range_cardinality<Rng>::value>
0050 {
0051 private:
0052 friend range_access;
0053 Rng rng_;
0054
0055 detail::non_propagating_cache<iterator_t<Rng>> second_;
0056 semiregular_box_t<Fun> fun_;
0057
0058 struct cursor
0059 {
0060 private:
0061 friend range_access;
0062 friend chunk_by_view;
0063 iterator_t<Rng> cur_;
0064 iterator_t<Rng> next_cur_;
0065 sentinel_t<Rng> last_;
0066 semiregular_box_ref_or_val_t<Fun, false> fun_;
0067
0068 #ifdef _MSC_VER
0069 template<typename I = iterator_t<Rng>>
0070 subrange<I> read() const
0071 {
0072 return {cur_, next_cur_};
0073 }
0074 #else
0075 subrange<iterator_t<Rng>> read() const
0076 {
0077 return {cur_, next_cur_};
0078 }
0079 #endif
0080 void next()
0081 {
0082 cur_ = next_cur_;
0083 auto partition_cur = adjacent_find(cur_, last_, not_fn(fun_));
0084 next_cur_ =
0085 partition_cur != last_ ? ranges::next(partition_cur) : partition_cur;
0086 }
0087
0088 bool equal(default_sentinel_t) const
0089 {
0090 return cur_ == last_;
0091 }
0092 bool equal(cursor const & that) const
0093 {
0094 return cur_ == that.cur_;
0095 }
0096 cursor(semiregular_box_ref_or_val_t<Fun, false> fun, iterator_t<Rng> first,
0097 iterator_t<Rng> next_cur, sentinel_t<Rng> last)
0098 : cur_(first)
0099 , next_cur_(next_cur)
0100 , last_(last)
0101 , fun_(fun)
0102 {}
0103
0104 public:
0105 cursor() = default;
0106 };
0107 cursor begin_cursor()
0108 {
0109 auto first = ranges::begin(rng_);
0110 auto last = ranges::end(rng_);
0111 if(!second_)
0112 {
0113 auto partition_cur = adjacent_find(first, last, not_fn(fun_));
0114 second_ =
0115 partition_cur != last ? ranges::next(partition_cur) : partition_cur;
0116 }
0117 return {fun_, first, *second_, last};
0118 }
0119
0120 public:
0121 chunk_by_view() = default;
0122 constexpr chunk_by_view(Rng rng, Fun fun)
0123 : rng_(std::move(rng))
0124 , fun_(std::move(fun))
0125 {}
0126 };
0127
0128 #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
0129 template(typename Rng, typename Fun)(
0130 requires copy_constructible<Fun>) chunk_by_view(Rng &&, Fun)
0131 ->chunk_by_view<views::all_t<Rng>, Fun>;
0132 #endif
0133
0134 namespace views
0135 {
0136 struct chunk_by_base_fn
0137 {
0138 template(typename Rng, typename Fun)(
0139 requires viewable_range<Rng> AND forward_range<Rng> AND
0140 indirect_relation<Fun, iterator_t<Rng>>)
0141 constexpr chunk_by_view<all_t<Rng>, Fun>
0142 operator()(Rng && rng, Fun fun) const
0143 {
0144 return {all(static_cast<Rng &&>(rng)), std::move(fun)};
0145 }
0146 };
0147
0148 struct chunk_by_fn : chunk_by_base_fn
0149 {
0150 using chunk_by_base_fn::operator();
0151
0152 template<typename Fun>
0153 constexpr auto operator()(Fun fun) const
0154 {
0155 return make_view_closure(bind_back(chunk_by_base_fn{}, std::move(fun)));
0156 }
0157 };
0158
0159
0160
0161 RANGES_INLINE_VARIABLE(chunk_by_fn, chunk_by)
0162 }
0163
0164 }
0165
0166 #include <range/v3/detail/epilogue.hpp>
0167 #include <range/v3/detail/satisfy_boost_range.hpp>
0168 RANGES_SATISFY_BOOST_RANGE(::ranges::chunk_by_view)
0169
0170 #endif