VCCC  2024.05
VisualCamp Common C++ library
basic_const_iterator.hpp
Go to the documentation of this file.
1 //
2 // Created by yonggyulee on 1/15/24.
3 //
4 
5 #ifndef VCCC_ITERATOR_BASIC_CONST_ITERATOR_HPP
6 #define VCCC_ITERATOR_BASIC_CONST_ITERATOR_HPP
7 
8 #include <memory>
9 #include <type_traits>
10 #include <utility>
11 
40 
41 namespace vccc {
42 namespace detail {
43 
45 struct basic_const_iterator_category {
46  using iterator_category = typename cxx20_iterator_traits<Iter>::iterator_category;
47 };
48 
49 template<typename Iter>
50 struct basic_const_iterator_category<Iter, false> {
51 #if __cplusplus < 202002L
52  using iterator_category = iterator_ignore;
53 #endif
54 };
55 
56 template<typename Iter>
57 struct basic_const_iterator_concept {
58  using iterator_concept =
59  std::conditional_t<
60  contiguous_iterator<Iter>::value, contiguous_iterator_tag,
61  std::conditional_t<
63  std::conditional_t<
65  std::conditional_t<
68  >>>>;
69 };
70 
72 struct constant_iterator : std::false_type {};
73 template<typename I>
74 struct constant_iterator<I, true>
75  : same_as<iter_const_reference_t<I>, iter_reference_t<I>> {};
76 
77 template<
78  template<typename> class Class,
79  typename Other,
80  typename Iter,
81  bool = negation< is_specialization<Other, Class> >::value /* false */
82 >
83 struct const_iterator_implicit_conversion_check : std::false_type {};
84 template<template<typename> class Class, typename Other, typename Iter>
85 struct const_iterator_implicit_conversion_check<Class, Other, Iter, true>
86  : conjunction<
87  constant_iterator<Other>,
88  convertible_to<Iter, Other>
89  > {};
90 
91 
92 }
93 
96 
97 template<typename Iter>
98 class basic_const_iterator : public detail::basic_const_iterator_category<Iter> {
100  public:
101  static_assert(input_iterator<Iter>::value, "Constraints not satisfied");
102 
103  using iterator_concept = typename detail::basic_const_iterator_concept<Iter>::iterator_concept;
107 
108  basic_const_iterator() = default;
109 
110  constexpr basic_const_iterator(Iter x) : current_(std::move(x)) {}
111 
114  : current_(std::move(other.current_)) {}
115 
116  template<typename T, std::enable_if_t<conjunction<
119  >::value, int> = 0>
120  constexpr basic_const_iterator(T&& x)
121  : current_(std::forward<T>(x)) {}
122 
123  // TODO: Implement operator= or not
124 
125  constexpr const Iter& base() const& noexcept {
126  return current_;
127  }
128 
129  constexpr Iter base() && {
130  return std::move(current_);
131  }
132 
133  constexpr reference operator*() const {
134  return static_cast<reference>(*base());
135  }
136 
137  template<typename I = Iter, std::enable_if_t<conjunction<
138  std::is_lvalue_reference<iter_reference_t<I>>,
140  >::value, int> = 0>
141  constexpr const auto* operator->() const {
142  return arrow(contiguous_iterator<Iter>{});
143  }
144 
147  return static_cast<iter_const_reference_t<Iter>>(base()[n]);
148  }
149 
151  ++current_;
152  return *this;
153  }
154 
156  constexpr void operator++(int) {
157  ++current_;
158  }
159 
162  auto tmp = *this;
163  ++*this;
164  return tmp;
165  }
166 
169  --current_;
170  return *this;
171  }
172 
175  auto tmp = *this;
176  --*this;
177  return tmp;
178  }
179 
182  current_ += n;
183  return *this;
184  }
185 
188  current_ -= n;
189  return *this;
190  }
191 
192  template<typename Other, std::enable_if_t<
194  constexpr operator Other() const& noexcept(is_nothrow_convertible<const Iter&, Other>::value) {
195  return current_;
196  }
197 
198  template<typename Other, std::enable_if_t<
200  constexpr operator Other() && noexcept(is_nothrow_convertible<Iter, Other>::value) {
201  return std::move(current_);
202  }
203 
204  // TODO: Reduce comparison operators
205 
207  constexpr bool operator==(const basic_const_iterator& other) const {
208  return current_ == other.current_;
209  }
210 
212  constexpr bool operator!=(const basic_const_iterator& other) const {
213  return !(current_ == other.current_);
214  }
215 
216  template<typename S, std::enable_if_t<conjunction<
217 #if __cplusplus < 202002L
219 #endif
221  >::value, int> = 0>
222  constexpr bool operator==(const S& s) const {
223  using namespace vccc::rel_ops;
224  return base() == s;
225  }
226 
227 #if __cplusplus < 202002L
228  template<typename S, std::enable_if_t<conjunction<
231  >::value, int> = 0>
232  friend constexpr bool operator==(const S& s, const basic_const_iterator& i) {
233  return i == s;
234  }
235 #endif
236 
237  template<typename S, std::enable_if_t<conjunction<
240  >::value, int> = 0>
241  constexpr bool operator!=(const S& s) const {
242  return !(*this == s);
243  }
244 
245  template<typename S, std::enable_if_t<conjunction<
248  >::value, int> = 0>
249  friend constexpr bool operator!=(const S& s, const basic_const_iterator& i) {
250  return i != s;
251  }
252 
254  constexpr bool operator<(const basic_const_iterator& y) const {
255  return base() < y;
256  }
257 
259  constexpr bool operator>(const basic_const_iterator& y) const {
260  using namespace vccc::rel_ops;
261  return base() > y;
262  }
263 
265  constexpr bool operator<=(const basic_const_iterator& y) const {
266  using namespace vccc::rel_ops;
267  return base() <= y;
268  }
269 
271  constexpr bool operator>=(const basic_const_iterator& y) const {
272  using namespace vccc::rel_ops;
273  return base() >= y;
274  }
275 
276  template<typename I, std::enable_if_t<conjunction<
280  >::value, int> = 0>
281  constexpr bool operator<(const I& y) const {
282  using namespace vccc::rel_ops;
283  return base() < y;
284  }
285 
286  template<typename I, std::enable_if_t<conjunction<
290  >::value, int> = 0>
291  constexpr bool operator>(const I& y) const {
292  using namespace vccc::rel_ops;
293  return base() > y;
294  }
295 
296  template<typename I, std::enable_if_t<conjunction<
300  >::value, int> = 0>
301  constexpr bool operator<=(const I& y) const {
302  using namespace vccc::rel_ops;
303  return base() <= y;
304  }
305 
306  template<typename I, std::enable_if_t<conjunction<
310  >::value, int> = 0>
311  constexpr bool operator>=(const I& y) const {
312  using namespace vccc::rel_ops;
313  return base() >= y;
314  }
315 
318  return basic_const_iterator(i.base() + n);
319  }
320 
323  return basic_const_iterator(i.base() + n);
324  }
325 
328  return basic_const_iterator(i.base() - n);
329  }
330 
332  constexpr difference_type operator-(const basic_const_iterator& i) const {
333  return current_ - i.current_;
334  }
335 
336  template<typename S, std::enable_if_t<conjunction<
339  >::value, int> = 0>
340  constexpr difference_type operator-(const S& s) const {
341  return current_ - s;
342  }
343 
344  template<typename S, std::enable_if_t<conjunction<
347  >::value, int> = 0>
348  friend constexpr difference_type operator-(const S& s, const basic_const_iterator& i) {
349  return s - i.base();
350  }
351 
352  friend constexpr rvalue_reference
354  noexcept(noexcept(static_cast<rvalue_reference>(ranges::iter_move(i.base()))))
355  {
356  return static_cast<rvalue_reference>(vccc::ranges::iter_move(i));
357  }
358 
359  private:
360  constexpr const auto* arrow(std::true_type /* contiguous_iterator */) const {
361  return vccc::to_address(base());
362  }
363  constexpr const auto* arrow(std::false_type /* contiguous_iterator */) const {
364  return vccc::addressof(*base());
365  }
366 
367  Iter current_;
368 };
369 
370 template<typename I>
372  std::conditional_t<
374  I,
376  >
377 >;
378 
379 template<typename S>
381  std::conditional_t<
384  S
385  >
386 >;
387 
389 constexpr const_iterator<I> make_const_iterator(I it) { return it; }
390 
392 constexpr const_sentinel<S> make_const_sentinel(S s) { return s; }
393 
394 namespace detail {
395 
396 template<typename T, typename U, bool = conjunction<common_with<U, T>>::value>
397 struct basic_const_iterator_common_type
398  : std::conditional_t<
399  input_iterator<common_type_t<T, U>>::value,
400  type_identity< basic_const_iterator<common_type_t<T, U>> >,
401  no_common_type
402  > {};
403 template<typename T, typename U>
404 struct basic_const_iterator_common_type<T, U, false> {};
405 
406 } // namespace detail
407 
408 template<typename T, typename U>
410  : detail::basic_const_iterator_common_type<T, U> {};
411 
412 template<typename T, typename U>
414  : detail::basic_const_iterator_common_type<T, U> {};
415 
416 template<typename T, typename U>
418  : detail::basic_const_iterator_common_type<T, U> {};
419 
421 
422 } // namespace vccc
423 
424 #endif // VCCC_ITERATOR_BASIC_CONST_ITERATOR_HPP
Definition: basic_const_iterator.hpp:98
constexpr basic_const_iterator & operator+=(difference_type n)
Definition: basic_const_iterator.hpp:181
iter_const_reference_t< Iter > reference
Definition: basic_const_iterator.hpp:106
constexpr bool operator<(const I &y) const
Definition: basic_const_iterator.hpp:281
constexpr basic_const_iterator & operator-=(difference_type n)
Definition: basic_const_iterator.hpp:187
constexpr bool operator!=(const S &s) const
Definition: basic_const_iterator.hpp:241
typename detail::basic_const_iterator_concept< Iter >::iterator_concept iterator_concept
Definition: basic_const_iterator.hpp:103
constexpr const Iter & base() const &noexcept
Definition: basic_const_iterator.hpp:125
iter_value_t< Iter > value_type
Definition: basic_const_iterator.hpp:104
constexpr void operator++(int)
Definition: basic_const_iterator.hpp:156
constexpr basic_const_iterator & operator--()
Definition: basic_const_iterator.hpp:168
constexpr difference_type operator-(const S &s) const
Definition: basic_const_iterator.hpp:340
constexpr basic_const_iterator(T &&x)
Definition: basic_const_iterator.hpp:120
constexpr bool operator<=(const basic_const_iterator &y) const
Definition: basic_const_iterator.hpp:265
constexpr friend basic_const_iterator operator-(const basic_const_iterator &i, difference_type n)
Definition: basic_const_iterator.hpp:327
iter_difference_t< Iter > difference_type
Definition: basic_const_iterator.hpp:105
constexpr basic_const_iterator & operator++()
Definition: basic_const_iterator.hpp:150
constexpr bool operator>=(const I &y) const
Definition: basic_const_iterator.hpp:311
constexpr basic_const_iterator operator++(int)
Definition: basic_const_iterator.hpp:161
constexpr bool operator<(const basic_const_iterator &y) const
Definition: basic_const_iterator.hpp:254
constexpr Iter base() &&
Definition: basic_const_iterator.hpp:129
constexpr iter_const_reference_t< I > operator[](difference_type n) const
Definition: basic_const_iterator.hpp:146
constexpr bool operator>(const basic_const_iterator &y) const
Definition: basic_const_iterator.hpp:259
constexpr bool operator==(const basic_const_iterator &other) const
Definition: basic_const_iterator.hpp:207
constexpr const auto * operator->() const
Definition: basic_const_iterator.hpp:141
constexpr basic_const_iterator(Iter x)
Definition: basic_const_iterator.hpp:110
constexpr friend basic_const_iterator operator+(const basic_const_iterator &i, difference_type n)
Definition: basic_const_iterator.hpp:317
constexpr friend bool operator==(const S &s, const basic_const_iterator &i)
Definition: basic_const_iterator.hpp:232
constexpr bool operator==(const S &s) const
Definition: basic_const_iterator.hpp:222
constexpr reference operator*() const
Definition: basic_const_iterator.hpp:133
constexpr difference_type operator-(const basic_const_iterator &i) const
Definition: basic_const_iterator.hpp:332
constexpr bool operator<=(const I &y) const
Definition: basic_const_iterator.hpp:301
constexpr bool operator>=(const basic_const_iterator &y) const
Definition: basic_const_iterator.hpp:271
constexpr friend basic_const_iterator operator+(difference_type n, const basic_const_iterator &i)
Definition: basic_const_iterator.hpp:322
constexpr bool operator!=(const basic_const_iterator &other) const
Definition: basic_const_iterator.hpp:212
constexpr friend bool operator!=(const S &s, const basic_const_iterator &i)
Definition: basic_const_iterator.hpp:249
constexpr basic_const_iterator operator--(int)
Definition: basic_const_iterator.hpp:174
constexpr bool operator>(const I &y) const
Definition: basic_const_iterator.hpp:291
constexpr basic_const_iterator(basic_const_iterator< U > other)
Definition: basic_const_iterator.hpp:113
constexpr friend rvalue_reference iter_move(const basic_const_iterator &i) noexcept(noexcept(static_cast< rvalue_reference >(ranges::iter_move(i.base()))))
Definition: basic_const_iterator.hpp:353
constexpr friend difference_type operator-(const S &s, const basic_const_iterator &i)
Definition: basic_const_iterator.hpp:348
constexpr VCCC_INLINE_OR_STATIC detail_iter_move::iter_move_niebloid iter_move
Definition: iter_move.hpp:92
std::enable_if_t< semiregular< S >::value, std::conditional_t< input_iterator< S >::value, const_iterator< S >, S > > const_sentinel
Definition: basic_const_iterator.hpp:386
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
constexpr const_iterator< I > make_const_iterator(I it)
Definition: basic_const_iterator.hpp:389
constexpr T * to_address(T *p) noexcept
Definition: to_address.hpp:37
typename iter_rvalue_reference< T >::type iter_rvalue_reference_t
Definition: iter_rvalue_reference_t.hpp:33
typename iter_value< T >::type iter_value_t
Definition: iter_value_t.hpp:42
typename iter_difference< T >::type iter_difference_t
Computes the difference type of T
Definition: iter_difference_t.hpp:49
std::enable_if_t< input_iterator< I >::value, std::conditional_t< detail::constant_iterator< I >::value, I, basic_const_iterator< I > > > const_iterator
Definition: basic_const_iterator.hpp:377
std::input_iterator_tag input_iterator_tag
Definition: iterator_tag.hpp:15
constexpr const_sentinel< S > make_const_sentinel(S s)
Definition: basic_const_iterator.hpp:392
std::bidirectional_iterator_tag bidirectional_iterator_tag
Definition: iterator_tag.hpp:18
typename iter_const_reference< T >::type iter_const_reference_t
Definition: iter_const_reference_t.hpp:47
std::enable_if_t< std::is_object< T >::value, T * > addressof(T &t) noexcept
Definition: addressof.hpp:33
typename common_reference< T... >::type common_reference_t
Definition: common_reference.hpp:54
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: common_type.hpp:117
Definition: conjunction.hpp:22
specifies that a random_access_iterator is a contiguous iterator, referring to elements that are cont...
Definition: contiguous_iterator.hpp:88
Models std::convertible_to
Definition: convertible_to.hpp:38
Definition: different_from.hpp:18
specifies that a type is an input iterator, that is, its referenced values can be read and it can be ...
Definition: input_iterator.hpp:55
Definition: is_nothrow_convertible.hpp:32
Definition: negation.hpp:23
specifies that a bidirectional_iterator is a random-access iterator, supporting advancement in consta...
Definition: random_access_iterator.hpp:120
Models std::same_as
Definition: same_as.hpp:33
Definition: sentinel_for.hpp:24
specifies that the - operator can be applied to an iterator and a sentinel to calculate their differe...
Definition: sized_sentinel_for.hpp:75
specifies that the comparison operators on the type yield a total order
Definition: totally_ordered.hpp:74