VCCC  2024.05
VisualCamp Common C++ library
enumerate_view.hpp
Go to the documentation of this file.
1 //
2 // Created by yonggyulee on 1/22/24.
3 //
4 
5 #ifndef VCCC_RANGES_VIEWS_ENUMERATE_VIEW_HPP
6 #define VCCC_RANGES_VIEWS_ENUMERATE_VIEW_HPP
7 
8 #include <tuple>
9 #include <utility>
10 
17 #include "vccc/__ranges/begin.hpp"
23 #include "vccc/__ranges/end.hpp"
33 #include "vccc/__ranges/size.hpp"
35 #include "vccc/__ranges/view.hpp"
37 #if __cplusplus >= 201703L
39 #endif
44 
45 namespace vccc {
46 namespace ranges {
47 namespace detail {
48 
50 struct range_with_movable_reference : std::false_type {};
51 template<typename R>
52 struct range_with_movable_reference<R, true>
53  : conjunction<
54  move_constructible<range_reference_t<R>>,
55  move_constructible<range_rvalue_reference_t<R>>
56  > {};
57 
58 } // namespace detail
59 
62 
63 template<typename V, template<typename...> class Tuple = std::tuple>
64 class enumerate_view : public view_interface<enumerate_view<V>> {
65  public:
66  static_assert(view<V>::value, "Constraints not satisfied");
67  static_assert(detail::range_with_movable_reference<V>::value, "Constraints not satisfied");
68 
69  template<bool Const> class iterator;
70  template<bool Const> class sentinel;
71 
72  template<bool Const>
73  class iterator {
74  friend class enumerate_view;
75  template<bool b>
76  friend class sentinel;
77 
78  using Base = maybe_const<Const, V>;
79 
80  public:
83  std::conditional_t<
85  std::conditional_t<
87  std::conditional_t<
90  >>>;
92  using value_type = Tuple<difference_type, range_value_t<Base>>;
93  using pointer = void;
94  using reference = Tuple<difference_type, range_reference_t<Base>>;
95 
96  iterator() = default;
97 
98  template<bool AntiConst, std::enable_if_t<conjunction<
99  bool_constant<((Const != AntiConst) && Const)>,
101  >::value, int> = 0>
103  : current_(std::move(i.current_)), pos_(i.pos_) {}
104 
105  private:
106  constexpr explicit iterator(iterator_t<Base> current, difference_type pos)
107  : current_(std::move(current)), pos_(pos) {}
108 
109  public:
110  constexpr const iterator_t<Base>& base() const& noexcept {
111  return current_;
112  }
113  constexpr iterator_t<Base> base() && {
114  return std::move(current_);
115  }
116 
117  constexpr difference_type index() const noexcept {
118  return pos_;
119  }
120 
121  constexpr auto operator*() const {
122  return reference(pos_, *current_);
123  }
124 
126  constexpr auto operator[](difference_type n) const {
127  return reference(pos_ + n, current_[n]);
128  }
129 
130  constexpr iterator& operator++() {
131  ++current_;
132  ++pos_;
133  return *this;
134  }
135 
137  constexpr void operator++(int) {
138  ++current_;
139  }
140 
142  constexpr iterator operator++(int) {
143  auto tmp = *this;
144  ++*this;
145  return tmp;
146  }
147 
149  constexpr iterator& operator--() {
150  --current_;
151  --pos_;
152  return *this;
153  }
154 
156  constexpr iterator operator--(int) {
157  auto tmp = *this;
158  --*this;
159  return tmp;
160  }
161 
164  current_ += n;
165  pos_ += n;
166  return *this;
167  }
168 
171  current_ -= n;
172  pos_ -= n;
173  return *this;
174  }
175 
176  friend constexpr bool operator==(const iterator& x, const iterator& y) noexcept {
177  return x.pos_ == y.pos_;
178  }
179 
180  friend constexpr bool operator!=(const iterator& x, const iterator& y) noexcept {
181  return !(x == y);
182  }
183 
184  friend constexpr bool operator<(const iterator& x, const iterator& y) noexcept {
185  return x.pos_ < y.pos_;
186  }
187 
188  friend constexpr bool operator<=(const iterator& x, const iterator& y) noexcept {
189  return !(y < x);
190  }
191 
192  friend constexpr bool operator>(const iterator& x, const iterator& y) noexcept {
193  return y < x;
194  }
195 
196  friend constexpr bool operator>=(const iterator& x, const iterator& y) noexcept {
197  return !(x < y);
198  }
199 
201  friend constexpr iterator operator+(const iterator& i, difference_type n) {
202  auto temp = i;
203  temp += n;
204  return temp;
205  }
206 
208  friend constexpr iterator operator+(difference_type n, const iterator& i) {
209  return i + n;
210  }
211 
213  friend constexpr iterator operator-(const iterator& i, difference_type n) {
214  auto temp = i;
215  temp -= n;
216  return temp;
217  }
218 
219  friend constexpr iterator operator-(const iterator& i, const iterator& j) noexcept {
220  return i.pos_ - j.pos_;
221  }
222 
223  friend constexpr auto iter_move(const iterator& i)
224  noexcept(
225  noexcept(ranges::iter_move(i.current_)) &&
226  std::is_nothrow_move_constructible<
228  )
229  {
230  return std::tuple<difference_type, range_rvalue_reference_t<Base>>(i.pos_, ranges::iter_move(i.current_));
231  }
232 
233  private:
234  iterator_t<Base> current_;
235  difference_type pos_;
236  };
237 
238  template<bool Const>
239  class sentinel {
240  using Base = maybe_const<Const, V>;
241  friend class enumerate_view;
242 
243  public:
244  sentinel() = default;
245 
246  template<bool AntiConst, std::enable_if_t<conjunction<
247  bool_constant<((Const != AntiConst) && Const)>,
249  >::value, int> = 0>
250  constexpr sentinel(sentinel<AntiConst> other)
251  : end_(std::move(other.end_)) {}
252 
253  private:
254  constexpr explicit sentinel(sentinel_t<Base> end)
255  : end_(std::move(end)) {}
256 
257  public:
258  constexpr sentinel_t<Base> base() const {
259  return end_;
260  }
261 
262  friend constexpr bool operator==(const iterator<Const>& x, const sentinel& y) {
263  using namespace vccc::rel_ops;
264  return x.current_ == y.end_;
265  }
266 
267  friend constexpr bool operator!=(const iterator<Const>& x, const sentinel& y) {
268  return !(x == y);
269  }
270 
271  friend constexpr bool operator==(const sentinel& y, const iterator<Const>& x) {
272  return x == y;
273  }
274 
275  friend constexpr bool operator!=(const sentinel& y, const iterator<Const>& x) {
276  return !(x == y);
277  }
278 
279  template<bool OtherConst, std::enable_if_t<conjunction<
283  >
284  >::value, int> = 0>
287  return x.base() - y.base();
288  }
289 
290  template<bool OtherConst, std::enable_if_t<conjunction<
294  >
295  >::value, int> = 0>
298  return y.base() - x.base();
299  }
300 
301 
302  private:
303  sentinel_t<Base> end_;
304  };
305 
306  enumerate_view() = default;
307 
308  constexpr explicit enumerate_view(V base)
309  : base_(std::move(base)) {}
310 
312  constexpr V base() const& {
313  return base_;
314  }
315 
316  constexpr V base() && {
317  return std::move(base_);
318  }
319 
320  template<typename V2 = V, std::enable_if_t<simple_view<V2>::valule == false, int> = 0>
321  constexpr iterator<false> begin() {
322  return iterator<false>(ranges::begin(base_), 0);
323  }
324 
325  template<typename V2 = V, std::enable_if_t<
327  constexpr iterator<true> begin() const {
328  return iterator<true>(ranges::begin(base_), 0);
329  }
330 
332  constexpr auto end() {
333  return end_nonconst(conjunction<common_range<V2>, sized_range<V2>>{});
334  }
335 
336  template<typename V2 = V, std::enable_if_t<
338  constexpr auto end() const {
340  }
341 
343  constexpr auto size() {
344  return ranges::size(base_);
345  }
346 
348  constexpr auto size() const {
349  return ranges::size(base_);
350  }
351 
352  private:
353  template<typename V2 = V>
354  constexpr iterator<false> end_nonconst(std::true_type) {
355  return iterator<false>(ranges::end(base_), ranges::distance(base_));
356  }
357  template<typename V2 = V>
358  constexpr sentinel<false> end_nonconst(std::false_type) {
359  return sentinel<false>(ranges::end(base_));
360  }
361 
362  template<typename V2 = V>
363  constexpr iterator<true> end_const(std::true_type) const {
364  return iterator<true>(ranges::end(base_), ranges::distance(base_));
365  }
366  template<typename V2 = V>
367  constexpr sentinel<true> end_const(std::false_type) const {
368  return sentinel<true>(ranges::end(base_));
369  }
370 
371  V base_;
372 };
373 
374 #if __cplusplus >= 201703L
375 
376 template<typename R>
377 enumerate_view(R&&) -> enumerate_view<views::all_t<R>>;
378 
379 #endif
380 
381 template<typename View>
383 
385 
386 } // namespace ranges
387 } // namespace vccc
388 
389 #endif // VCCC_RANGES_VIEWS_ENUMERATE_VIEW_HPP
Definition: enumerate_view.hpp:73
constexpr friend bool operator<=(const iterator &x, const iterator &y) noexcept
Definition: enumerate_view.hpp:188
constexpr iterator & operator--()
Definition: enumerate_view.hpp:149
constexpr friend iterator operator+(const iterator &i, difference_type n)
Definition: enumerate_view.hpp:201
constexpr auto operator[](difference_type n) const
Definition: enumerate_view.hpp:126
constexpr friend bool operator>(const iterator &x, const iterator &y) noexcept
Definition: enumerate_view.hpp:192
constexpr friend iterator operator-(const iterator &i, difference_type n)
Definition: enumerate_view.hpp:213
void pointer
Definition: enumerate_view.hpp:93
constexpr void operator++(int)
Definition: enumerate_view.hpp:137
constexpr friend bool operator!=(const iterator &x, const iterator &y) noexcept
Definition: enumerate_view.hpp:180
constexpr difference_type index() const noexcept
Definition: enumerate_view.hpp:117
constexpr iterator(iterator< AntiConst > i)
Definition: enumerate_view.hpp:102
constexpr auto operator*() const
Definition: enumerate_view.hpp:121
constexpr iterator & operator-=(difference_type n)
Definition: enumerate_view.hpp:170
constexpr friend bool operator==(const iterator &x, const iterator &y) noexcept
Definition: enumerate_view.hpp:176
constexpr iterator & operator+=(difference_type n)
Definition: enumerate_view.hpp:163
input_iterator_tag iterator_category
Definition: enumerate_view.hpp:81
constexpr iterator operator--(int)
Definition: enumerate_view.hpp:156
constexpr iterator_t< Base > base() &&
Definition: enumerate_view.hpp:113
constexpr friend iterator operator+(difference_type n, const iterator &i)
Definition: enumerate_view.hpp:208
Tuple< difference_type, range_reference_t< Base > > reference
Definition: enumerate_view.hpp:94
constexpr friend bool operator<(const iterator &x, const iterator &y) noexcept
Definition: enumerate_view.hpp:184
std::conditional_t< random_access_range< Base >::value, random_access_iterator_tag, std::conditional_t< bidirectional_range< Base >::value, bidirectional_iterator_tag, std::conditional_t< forward_range< Base >::value, forward_iterator_tag, input_iterator_tag > >> iterator_concept
Definition: enumerate_view.hpp:90
Tuple< difference_type, range_value_t< Base > > value_type
Definition: enumerate_view.hpp:92
constexpr iterator operator++(int)
Definition: enumerate_view.hpp:142
constexpr friend auto iter_move(const iterator &i) noexcept(noexcept(ranges::iter_move(i.current_)) &&std::is_nothrow_move_constructible< range_rvalue_reference_t< Base >>::value)
Definition: enumerate_view.hpp:223
constexpr friend iterator operator-(const iterator &i, const iterator &j) noexcept
Definition: enumerate_view.hpp:219
constexpr iterator & operator++()
Definition: enumerate_view.hpp:130
constexpr const iterator_t< Base > & base() const &noexcept
Definition: enumerate_view.hpp:110
constexpr friend bool operator>=(const iterator &x, const iterator &y) noexcept
Definition: enumerate_view.hpp:196
range_difference_t< Base > difference_type
Definition: enumerate_view.hpp:91
Definition: enumerate_view.hpp:239
constexpr sentinel_t< Base > base() const
Definition: enumerate_view.hpp:258
constexpr friend range_difference_t< maybe_const< OtherConst, V > > operator-(const iterator< OtherConst > &x, const sentinel &y)
Definition: enumerate_view.hpp:286
constexpr friend bool operator==(const sentinel &y, const iterator< Const > &x)
Definition: enumerate_view.hpp:271
constexpr friend bool operator==(const iterator< Const > &x, const sentinel &y)
Definition: enumerate_view.hpp:262
constexpr sentinel(sentinel< AntiConst > other)
Definition: enumerate_view.hpp:250
constexpr friend bool operator!=(const iterator< Const > &x, const sentinel &y)
Definition: enumerate_view.hpp:267
constexpr friend range_difference_t< maybe_const< OtherConst, V > > operator-(const sentinel &y, const iterator< OtherConst > &x)
Definition: enumerate_view.hpp:297
constexpr friend bool operator!=(const sentinel &y, const iterator< Const > &x)
Definition: enumerate_view.hpp:275
Definition: enumerate_view.hpp:64
constexpr V base() const &
Definition: enumerate_view.hpp:312
constexpr auto size() const
Definition: enumerate_view.hpp:348
constexpr auto size()
Definition: enumerate_view.hpp:343
constexpr V base() &&
Definition: enumerate_view.hpp:316
constexpr auto end()
Definition: enumerate_view.hpp:332
constexpr auto end() const
Definition: enumerate_view.hpp:338
constexpr iterator< true > begin() const
Definition: enumerate_view.hpp:327
constexpr enumerate_view(V base)
Definition: enumerate_view.hpp:308
constexpr iterator< false > begin()
Definition: enumerate_view.hpp:321
helper class template for defining a view, using the curiously recurring template pattern
Definition: view_interface.hpp:78
constexpr VCCC_INLINE_OR_STATIC detail_iter_move::iter_move_niebloid iter_move
Definition: iter_move.hpp:92
std::forward_iterator_tag forward_iterator_tag
Definition: iterator_tag.hpp:17
std::random_access_iterator_tag random_access_iterator_tag
Definition: iterator_tag.hpp:19
std::input_iterator_tag input_iterator_tag
Definition: iterator_tag.hpp:15
std::bidirectional_iterator_tag bidirectional_iterator_tag
Definition: iterator_tag.hpp:18
typename sentinel< R >::type sentinel_t
Definition: sentinel_t.hpp:29
typename ranges::iterator< T >::type iterator_t
Definition: iterator_t.hpp:32
constexpr VCCC_INLINE_OR_STATIC detail::begin_niebloid begin
returns an iterator to the beginning of a range
Definition: begin.hpp:116
typename range_rvalue_reference< R >::type range_rvalue_reference_t
Used to obtain the rvalue reference type of the iterator type of range type R.
Definition: range_rvalue_reference_t.hpp:38
constexpr VCCC_INLINE_OR_STATIC detail::distance_niebloid distance
Definition: distance.hpp:72
constexpr VCCC_INLINE_OR_STATIC detail::size_niebloid size
returns the size of a container or array
Definition: size.hpp:145
constexpr VCCC_INLINE_OR_STATIC detail::end_niebloid end
returns a sentinel indicating the end of a range
Definition: end.hpp:120
typename range_difference< R >::type range_difference_t
Used to obtain the difference type of the iterator type of range type R.
Definition: range_difference_t.hpp:41
std::integral_constant< bool, v > bool_constant
Definition: bool_constant.hpp:19
std::conditional_t< Const, const V, V > maybe_const
Definition: maybe_const.hpp:16
Definition: matrix.hpp:495
Definition: cxx20_rel_ops.hpp:17
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35
Definition: conjunction.hpp:22
Models std::convertible_to
Definition: convertible_to.hpp:38
specifies a range whose iterator type satisfies bidirectional_iterator
Definition: bidirectional_range.hpp:49
Definition: common_range.hpp:41
Definition: enable_borrowed_range.hpp:17
specifies a range whose iterator type satisfies forward_iterator
Definition: forward_range.hpp:47
specifies a range whose iterator type satisfies random_access_iterator
Definition: random_access_range.hpp:48
specifies that a range knows its size in constant time
Definition: sized_range.hpp:38
specifies that a range is a view, that is, it has constant time copy/move/assignment
Definition: view.hpp:31
specifies that the - operator can be applied to an iterator and a sentinel to calculate their differe...
Definition: sized_sentinel_for.hpp:75