VCCC  2024.05
VisualCamp Common C++ library
repeat_view.hpp
Go to the documentation of this file.
1 //
2 // Created by yonggyulee on 2024/01/28.
3 //
4 
5 #ifndef VCCC_RANGES_VIEWS_REPEAT_VIEW_HPP
6 #define VCCC_RANGES_VIEWS_REPEAT_VIEW_HPP
7 
8 #include <cassert>
9 #include <cstdint>
10 #include <type_traits>
11 #include <utility>
12 
26 
27 namespace vccc {
28 namespace ranges {
29 
32 
33 template<typename W, typename Bound = unreachable_sentinel_t>
34 class repeat_view : public view_interface<repeat_view<W, Bound>> {
35  public:
36  static_assert(move_constructible<W>::value, "Constraints not satisfied");
37  static_assert(semiregular<Bound>::value, "Constraints not satisfied");
38  static_assert(std::is_object<W>::value, "Constraints not satisfied");
39  static_assert(same_as<W, std::remove_cv_t<W>>::value, "Constraints not satisfied");
40  static_assert(disjunction<is_integer_like<Bound>,
41  same_as<Bound, unreachable_sentinel_t>>::value, "Constraints not satisfied");
42 
43  class iterator {
44  friend class repeat_view;
45  using index_type = std::conditional_t<same_as<Bound, unreachable_sentinel_t>::value, std::ptrdiff_t, Bound>;
46 
47  public:
50  using value_type = W;
51  using difference_type = std::conditional_t<
52  is_signed_integer_like<index_type>::value, index_type, detail::iota_diff_t<index_type>>;
53 #if __cplusplus < 202002L
54  using pointer = void;
55  using reference = const W&;
56 #endif
57 
58  constexpr iterator() : value_(nullptr), current_() {}
59 
60  constexpr const W& operator*() const noexcept {
61  return *value_;
62  }
63 
64  constexpr const W& operator[](difference_type n) const noexcept {
65  return *(*this + n);
66  }
67 
68  constexpr iterator& operator++() {
69  ++current_;
70  return *this;
71  }
72 
73  constexpr iterator operator++(int) {
74  auto tmp = *this;
75  ++*this;
76  return tmp;
77  }
78 
79  constexpr iterator& operator--() {
80  --current_;
81  return *this;
82  }
83 
84  constexpr iterator operator--(int) {
85  auto tmp = *this;
86  --*this;
87  return tmp;
88  }
89 
91  current_ += n;
92  return *this;
93  }
94 
96  current_ -= n;
97  return *this;
98  }
99 
100  friend constexpr bool operator==(const iterator& x, const iterator& y) {
101  return x.current_ == y.current_;
102  }
103 
104  friend constexpr bool operator!=(const iterator& x, const iterator& y) {
105  return !(x == y);
106  }
107 
108  friend constexpr bool operator<(const iterator& x, const iterator& y) {
109  return x.current_ < y.current_;
110  }
111 
112  friend constexpr bool operator<=(const iterator& x, const iterator& y) {
113  return (x == y) || (x < y);
114  }
115 
116  friend constexpr bool operator>(const iterator& x, const iterator& y) {
117  return y < x;
118  }
119 
120  friend constexpr bool operator>=(const iterator& x, const iterator& y) {
121  return !(x < y);
122  }
123 
124  friend constexpr iterator operator+(iterator i, difference_type n) {
125  i += n;
126  return i;
127  }
128 
129  friend constexpr iterator operator+(difference_type n, iterator i) {
130  i += n;
131  return i;
132  }
133 
134  friend constexpr iterator operator-(iterator i, difference_type n) {
135  i -= n;
136  return i;
137  }
138 
139  friend constexpr difference_type operator-(const iterator& x, const iterator& y) {
140  return static_cast<difference_type>(x.current_) - static_cast<difference_type>(y.current_);
141  }
142 
143  private:
144  constexpr explicit iterator(const W* value, index_type b = index_type())
145  : value_(value), current_(b)
146  {
147  assert(((void)"B must be non negative", std::is_same<Bound, unreachable_sentinel_t>::value || (b >= 0)));
148  }
149 
150  const W* value_;
151  index_type current_;
152  };
153 
155  : value_(W()), bound_(Bound()) {}
156 
157  constexpr explicit repeat_view(const W& value, Bound bound = Bound())
158  : value_(value), bound_(bound){}
159 
160  constexpr explicit repeat_view(W&& value, Bound bound = Bound())
161  : value_(std::move(value)), bound_(bound){}
162 
163  template<typename... WArgs, typename... BoundArgs, std::enable_if_t<conjunction<
164  constructible_from<W, WArgs...>,
165  constructible_from<Bound, BoundArgs...>
166  >::value, int> = 0>
167  constexpr repeat_view(std::piecewise_construct_t, std::tuple<WArgs...> value_args, std::tuple<BoundArgs...> bound_args = std::tuple<>())
168  : repeat_view(std::piecewise_construct, std::move(value_args), std::move(bound_args),
169  std::index_sequence_for<WArgs...>{}, std::index_sequence_for<BoundArgs...>{}) {}
170 
172  return iterator(vccc::addressof(*value_));
173  }
174 
175  template<typename B = Bound, std::enable_if_t<
177  ::value, int> = 0>
179  return iterator(vccc::addressof(*value_), bound_);
180  }
181 
182  template<typename B = Bound, std::enable_if_t<
184  ::value, int> = 0>
185  constexpr unreachable_sentinel_t end() const {
186  return unreachable_sentinel;
187  }
188 
189  template<typename B = Bound, std::enable_if_t<
191  ::value, int> = 0>
192  constexpr auto size() const {
193  using R = std::make_unsigned_t<Bound>;
194  return static_cast<R>(bound_);
195  }
196 
197  private:
198  template<typename WTuple, typename BoundTuple, std::size_t... I, std::size_t... J>
199  constexpr repeat_view(
200  std::piecewise_construct_t, WTuple&& value_args, BoundTuple&& bound_args,
201  std::index_sequence<I...>, std::index_sequence<J...>)
202  : value_(std::get<I>(std::forward<WTuple>(value_args))...), bound_(std::get<J>(std::forward<BoundTuple>(bound_args))...) {}
203 
204  movable_box<W> value_;
205  Bound bound_;
206 };
207 
208 #if __cplusplus >= 201703L
209 
210 template<typename W, typename Bound>
211 repeat_view(W, Bound) -> repeat_view<W, Bound>;
212 
213 #endif
214 
216 
217 } // namespace ranges
218 } // namespace vccc
219 
220 #endif // VCCC_RANGES_VIEWS_REPEAT_VIEW_HPP
#define VCCC_ADDRESSOF_CONSTEXPR
Definition: addressof.hpp:14
Definition: repeat_view.hpp:43
constexpr friend bool operator<(const iterator &x, const iterator &y)
Definition: repeat_view.hpp:108
void pointer
Definition: repeat_view.hpp:54
constexpr friend difference_type operator-(const iterator &x, const iterator &y)
Definition: repeat_view.hpp:139
constexpr friend bool operator!=(const iterator &x, const iterator &y)
Definition: repeat_view.hpp:104
constexpr const W & operator*() const noexcept
Definition: repeat_view.hpp:60
constexpr const W & operator[](difference_type n) const noexcept
Definition: repeat_view.hpp:64
constexpr friend iterator operator+(iterator i, difference_type n)
Definition: repeat_view.hpp:124
constexpr friend bool operator==(const iterator &x, const iterator &y)
Definition: repeat_view.hpp:100
constexpr friend iterator operator-(iterator i, difference_type n)
Definition: repeat_view.hpp:134
constexpr iterator & operator+=(difference_type n)
Definition: repeat_view.hpp:90
random_access_iterator_tag iterator_category
Definition: repeat_view.hpp:49
W value_type
Definition: repeat_view.hpp:50
constexpr iterator & operator--()
Definition: repeat_view.hpp:79
constexpr friend bool operator>(const iterator &x, const iterator &y)
Definition: repeat_view.hpp:116
std::conditional_t< is_signed_integer_like< index_type >::value, index_type, detail::iota_diff_t< index_type > > difference_type
Definition: repeat_view.hpp:52
constexpr friend bool operator>=(const iterator &x, const iterator &y)
Definition: repeat_view.hpp:120
constexpr iterator & operator-=(difference_type n)
Definition: repeat_view.hpp:95
constexpr friend bool operator<=(const iterator &x, const iterator &y)
Definition: repeat_view.hpp:112
constexpr iterator operator--(int)
Definition: repeat_view.hpp:84
constexpr iterator operator++(int)
Definition: repeat_view.hpp:73
constexpr iterator & operator++()
Definition: repeat_view.hpp:68
random_access_iterator_tag iterator_concept
Definition: repeat_view.hpp:48
const W & reference
Definition: repeat_view.hpp:55
constexpr iterator()
Definition: repeat_view.hpp:58
constexpr friend iterator operator+(difference_type n, iterator i)
Definition: repeat_view.hpp:129
Definition: repeat_view.hpp:34
constexpr repeat_view(const W &value, Bound bound=Bound())
Definition: repeat_view.hpp:157
constexpr auto size() const
Definition: repeat_view.hpp:192
VCCC_ADDRESSOF_CONSTEXPR iterator end() const
Definition: repeat_view.hpp:178
repeat_view()
Definition: repeat_view.hpp:154
constexpr repeat_view(W &&value, Bound bound=Bound())
Definition: repeat_view.hpp:160
constexpr repeat_view(std::piecewise_construct_t, std::tuple< WArgs... > value_args, std::tuple< BoundArgs... > bound_args=std::tuple<>())
Definition: repeat_view.hpp:167
VCCC_ADDRESSOF_CONSTEXPR iterator begin() const
Definition: repeat_view.hpp:171
constexpr unreachable_sentinel_t end() const
Definition: repeat_view.hpp:185
helper class template for defining a view, using the curiously recurring template pattern
Definition: view_interface.hpp:78
constexpr VCCC_INLINE_OR_STATIC unreachable_sentinel_t unreachable_sentinel
Definition: unreachable_sentinel.hpp:25
std::random_access_iterator_tag random_access_iterator_tag
Definition: iterator_tag.hpp:19
std::enable_if_t< std::is_object< T >::value, T * > addressof(T &t) noexcept
Definition: addressof.hpp:33
constexpr auto get(const subrange< I, S, K > &r)
Definition: subrange.hpp:371
Definition: matrix.hpp:495
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35
Definition: conjunction.hpp:22
specifies that a variable of the type can be constructed from or bound to a set of argument types
Definition: constructible_from.hpp:31
Definition: disjunction.hpp:22
Check if type models integer-like type (C++ 20 requirement)
Definition: is_integer_like.hpp:34
Definition: is_integer_like.hpp:48
Definition: negation.hpp:23
Models std::same_as
Definition: same_as.hpp:33
specifies that an object of a type can be copied, moved, swapped, and default constructed
Definition: semiregular.hpp:31
sentinel that always compares unequal to any weakly_incrementable type
Definition: unreachable_sentinel.hpp:17