Horizon
chunk_by.hpp
Go to the documentation of this file.
1 // Range v3 library
3 //
4 // Copyright Hui Xie 2021
5 //
6 // Use, modification and distribution is subject to the
7 // Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10 //
11 // Project home: https://github.com/ericniebler/range-v3
12 //
13 
14 #ifndef RANGES_V3_VIEW_CHUNK_BY_HPP
15 #define RANGES_V3_VIEW_CHUNK_BY_HPP
16 
17 #include <type_traits>
18 #include <utility>
19 
20 #include <meta/meta.hpp>
21 
22 #include <range/v3/range_fwd.hpp>
23 
33 #include <range/v3/utility/static_const.hpp>
34 #include <range/v3/view/all.hpp>
35 #include <range/v3/view/facade.hpp>
37 #include <range/v3/view/view.hpp>
38 
39 #include <range/v3/detail/prologue.hpp>
40 
41 namespace ranges
42 {
43 
46  template<typename Rng, typename Fun>
48  : view_facade<chunk_by_view<Rng, Fun>,
49  is_finite<Rng>::value ? finite : range_cardinality<Rng>::value>
50  {
51  private:
52  friend range_access;
53  Rng rng_;
54  // cached version of the end of the first subrange / start of the second subrange
55  detail::non_propagating_cache<iterator_t<Rng>> second_;
56  semiregular_box_t<Fun> fun_;
57 
58  struct cursor
59  {
60  private:
61  friend range_access;
62  friend chunk_by_view;
63  iterator_t<Rng> cur_;
64  iterator_t<Rng> next_cur_;
65  sentinel_t<Rng> last_;
66  semiregular_box_ref_or_val_t<Fun, false> fun_;
67 
68 #ifdef _MSC_VER
69  template<typename I = iterator_t<Rng>>
70  subrange<I> read() const
71  {
72  return {cur_, next_cur_};
73  }
74 #else
75  subrange<iterator_t<Rng>> read() const
76  {
77  return {cur_, next_cur_};
78  }
79 #endif
80  void next()
81  {
82  cur_ = next_cur_;
83  auto partition_cur = adjacent_find(cur_, last_, not_fn(fun_));
84  next_cur_ =
85  partition_cur != last_ ? ranges::next(partition_cur) : partition_cur;
86  }
87 
88  bool equal(default_sentinel_t) const
89  {
90  return cur_ == last_;
91  }
92  bool equal(cursor const & that) const
93  {
94  return cur_ == that.cur_;
95  }
96  cursor(semiregular_box_ref_or_val_t<Fun, false> fun, iterator_t<Rng> first,
97  iterator_t<Rng> next_cur, sentinel_t<Rng> last)
98  : cur_(first)
99  , next_cur_(next_cur)
100  , last_(last)
101  , fun_(fun)
102  {}
103 
104  public:
105  cursor() = default;
106  };
107  cursor begin_cursor()
108  {
109  auto first = ranges::begin(rng_);
110  auto last = ranges::end(rng_);
111  if(!second_)
112  {
113  auto partition_cur = adjacent_find(first, last, not_fn(fun_));
114  second_ =
115  partition_cur != last ? ranges::next(partition_cur) : partition_cur;
116  }
117  return {fun_, first, *second_, last};
118  }
119 
120  public:
121  chunk_by_view() = default;
122  constexpr chunk_by_view(Rng rng, Fun fun)
123  : rng_(std::move(rng))
124  , fun_(std::move(fun))
125  {}
126  };
127 
128 #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
129  template(typename Rng, typename Fun)(
130  requires copy_constructible<Fun>) chunk_by_view(Rng &&, Fun)
131  ->chunk_by_view<views::all_t<Rng>, Fun>;
132 #endif
133 
134  namespace views
135  {
137  {
138  template(typename Rng, typename Fun)(
139  requires viewable_range<Rng> AND forward_range<Rng> AND //
141  constexpr chunk_by_view<all_t<Rng>, Fun>
142  operator()(Rng && rng, Fun fun) const
143  {
144  return {all(static_cast<Rng &&>(rng)), std::move(fun)};
145  }
146  };
147 
149  {
150  using chunk_by_base_fn::operator();
151 
152  template<typename Fun>
153  constexpr auto operator()(Fun fun) const
154  {
155  return make_view_closure(bind_back(chunk_by_base_fn{}, std::move(fun)));
156  }
157  };
158 
162  } // namespace views
164 } // namespace ranges
165 
166 #include <range/v3/detail/epilogue.hpp>
167 #include <range/v3/detail/satisfy_boost_range.hpp>
168 RANGES_SATISFY_BOOST_RANGE(::ranges::chunk_by_view)
169 
170 #endif
CPP_concept indirect_relation
\concept indirect_relation
Definition: concepts.hpp:670
decltype(begin(declval(Rng &))) iterator_t
Definition: access.hpp:698
RANGES_INLINE_VARIABLE(detail::to_container_fn< detail::from_range< std::vector >>, to_vector) template< template< typename... > class ContT > auto to(RANGES_HIDDEN_DETAIL(detail
For initializing a container of the specified type with the elements of an Range.
Definition: conversion.hpp:399
defer< bind_back, Fn, Ts... > bind_back
Definition: meta.hpp:994
front< Pair > first
Retrieve the first element of the pair Pair.
Definition: meta.hpp:2251
compose< quote< not_ >, Fn > not_fn
Logically negate the result of invocable Fn.
Definition: meta.hpp:3009
Tiny meta-programming library.
Definition: chunk_by.hpp:50
Definition: default_sentinel.hpp:26
Definition: subrange.hpp:196
A utility for constructing a view from a (derived) type that implements begin and end cursors.
Definition: facade.hpp:66
Definition: chunk_by.hpp:137
Definition: chunk_by.hpp:149