VCCC  2024.05
VisualCamp Common C++ library
take_view.hpp
Go to the documentation of this file.
1 //
2 // Created by yonggyulee on 2024/01/02.
3 //
4 
5 #ifndef VCCC_RANGES_VIEWS_TAKE_VIEW_HPP
6 #define VCCC_RANGES_VIEWS_TAKE_VIEW_HPP
7 
8 #include <algorithm>
9 #include <type_traits>
10 #include <utility>
11 
17 #include "vccc/__ranges/begin.hpp"
21 #include "vccc/__ranges/range.hpp"
24 #include "vccc/__ranges/size.hpp"
27 #include "vccc/__ranges/view.hpp"
35 
36 namespace vccc {
37 namespace ranges {
38 
41 
42 template<typename V>
43 class take_view : public view_interface<take_view<V>> {
44  public:
45  static_assert(view<V>::value, "Constraints not satisfied");
46 
47  template<bool Const>
48  class sentinel {
49  using Base = maybe_const<Const, V>;
50  public:
51  sentinel() = default;
52 
53  constexpr explicit sentinel(sentinel_t<Base> end)
54  : end_(std::move(end)) {}
55 
56  template<bool NoConst, std::enable_if_t<conjunction<
60  >::value, int> = 0>
62  : end_(std::move(s.end_)) {}
63 
64  constexpr sentinel_t<Base> base() const {
65  return end_;
66  }
67 
68  friend constexpr bool
70  using namespace vccc::rel_ops;
71  return y.count() == 0 || y.base() == x.end_;
72  }
73 
74  friend constexpr bool
76  return y == x;
77  }
78 
79  friend constexpr bool
81  return !(y == x);
82  }
83 
84  friend constexpr bool
86  return !(y == x);
87  }
88 
89  template<bool AntiConst, std::enable_if_t<conjunction<
93  >::value, int> = 0>
94  friend constexpr bool
96  using namespace vccc::rel_ops;
97  return y.count() == 0 || y.base() == x.end_;
98  }
99 
100  template<bool AntiConst, std::enable_if_t<conjunction<
104  >::value, int> = 0>
105  friend constexpr bool
107  return y == x;
108  }
109 
110  template<bool AntiConst, std::enable_if_t<conjunction<
114  >::value, int> = 0>
115  friend constexpr bool
117  return !(y == x);
118  }
119 
120  template<bool AntiConst, std::enable_if_t<conjunction<
124  >::value, int> = 0>
125  friend constexpr bool
127  return !(y == x);
128  }
129 
130  private:
131  sentinel_t<Base> end_;
132  };
133 
134  take_view() = default;
135 
136  constexpr explicit take_view(V base, range_difference_t<V> count)
137  : base_(std::move(base)), count_(count) {}
138 
139 
141  constexpr V base() const& {
142  return base_;
143  }
144 
145  constexpr V base() && {
146  return std::move(base_);
147  }
148 
149 
150  template<typename T = V, std::enable_if_t<conjunction<
154  >::value, int> = 0>
155  constexpr auto begin() {
156  return ranges::begin(base_);
157  }
158 
159  template<typename T = V, std::enable_if_t<conjunction<
163  >::value, int> = 0>
164  constexpr auto begin() {
165  using I = remove_cvref_t<iterator_t<T>>;
167  }
168 
169  template<typename T = V, std::enable_if_t<conjunction<
172  >::value, int> = 0>
173  constexpr auto begin() {
174  using I = remove_cvref_t<iterator_t<T>>;
175  return counted_iterator<I>(ranges::begin(base_), count_);
176  }
177 
178  template<typename T = const V, std::enable_if_t<conjunction<
179  range<T>,
182  >::value, int> = 0>
183  constexpr auto begin() const {
184  return ranges::begin(base_);
185  }
186 
187  template<typename T = const V, std::enable_if_t<conjunction<
188  range<T>,
191  >::value, int> = 0>
192  constexpr auto begin() const {
193  using I = remove_cvref_t<iterator_t<T>>;
195  }
196 
197  template<typename T = const V, std::enable_if_t<conjunction<
198  range<T>,
200  >::value, int> = 0>
201  constexpr auto begin() const {
202  using I = remove_cvref_t<iterator_t<T>>;
203  return counted_iterator<I>(ranges::begin(base_), count_);
204  }
205 
206 
207  template<typename T = V, std::enable_if_t<conjunction<
211  >::value, int> = 0>
212  constexpr auto end() {
213  return ranges::begin(base_) + ranges::range_difference_t<T>(this->size());
214  }
215 
216  template<typename T = V, std::enable_if_t<conjunction<
220  >::value, int> = 0>
221  constexpr default_sentinel_t end() {
222  return default_sentinel;
223  }
224 
225  template<typename T = V, std::enable_if_t<conjunction<
228  >::value, int> = 0>
229  constexpr sentinel<false> end() {
230  return sentinel<false>(ranges::end(base_));
231  }
232 
233  template<typename T = const V, std::enable_if_t<conjunction<
234  range<T>,
237  >::value, int> = 0>
238  constexpr auto end() const {
239  return ranges::begin(base_) + ranges::range_difference_t<T>(this->size());
240  }
241 
242  template<typename T = V, std::enable_if_t<conjunction<
243  range<T>,
246  >::value, int> = 0>
247  constexpr default_sentinel_t end() const {
248  return default_sentinel;
249  }
250 
251  template<typename T = V, std::enable_if_t<conjunction<
252  range<T>,
254  >::value, int> = 0>
255  constexpr sentinel<true> end() const {
256  return sentinel<true>(ranges::end(base_));
257  }
258 
260  constexpr auto size() {
261  auto n = ranges::size(base_);
262  return (std::min)(n, static_cast<decltype(n)>(count_));
263  }
264 
266  constexpr auto size() const {
267  auto n = ranges::size(base_);
268  return (std::min)(n, static_cast<decltype(n)>(count_));
269  }
270 
271  private:
272  V base_;
273  range_difference_t<V> count_ = 0;
274 };
275 
276 template<typename R>
278  return take_view<views::all_t<R>>(std::forward<R>(r), count);
279 }
280 
281 #if __cplusplus >= 201703L
282 
283 template<typename R>
284 take_view(R&&, ranges::range_difference_t<R>) -> take_view<views::all_t<R>>;
285 
286 #endif
287 
288 template<typename T>
290 
292 
293 } // namespace ranges
294 } // namespace vccc
295 
296 #endif // VCCC_RANGES_VIEWS_TAKE_VIEW_HPP
Definition: counted_iterator.hpp:71
Definition: take_view.hpp:48
constexpr sentinel_t< Base > base() const
Definition: take_view.hpp:64
constexpr sentinel(sentinel< NoConst > s)
Definition: take_view.hpp:61
constexpr friend bool operator!=(const sentinel &x, const counted_iterator< iterator_t< Base >> &y)
Definition: take_view.hpp:85
constexpr friend bool operator==(const sentinel &x, const counted_iterator< iterator_t< maybe_const< AntiConst, V >>> &y)
Definition: take_view.hpp:106
constexpr friend bool operator==(const counted_iterator< iterator_t< Base >> &y, const sentinel &x)
Definition: take_view.hpp:69
constexpr friend bool operator!=(const counted_iterator< iterator_t< maybe_const< AntiConst, V >>> &y, const sentinel &x)
Definition: take_view.hpp:116
constexpr friend bool operator==(const counted_iterator< iterator_t< maybe_const< AntiConst, V >>> &y, const sentinel &x)
Definition: take_view.hpp:95
constexpr friend bool operator!=(const counted_iterator< iterator_t< Base >> &y, const sentinel &x)
Definition: take_view.hpp:80
constexpr friend bool operator!=(const sentinel &x, const counted_iterator< iterator_t< maybe_const< AntiConst, V >>> &y)
Definition: take_view.hpp:126
constexpr friend bool operator==(const sentinel &x, const counted_iterator< iterator_t< Base >> &y)
Definition: take_view.hpp:75
constexpr sentinel(sentinel_t< Base > end)
Definition: take_view.hpp:53
Definition: take_view.hpp:43
constexpr V base() const &
Definition: take_view.hpp:141
constexpr default_sentinel_t end() const
Definition: take_view.hpp:247
constexpr auto size() const
Definition: take_view.hpp:266
constexpr auto size()
Definition: take_view.hpp:260
constexpr sentinel< false > end()
Definition: take_view.hpp:229
constexpr default_sentinel_t end()
Definition: take_view.hpp:221
constexpr V base() &&
Definition: take_view.hpp:145
constexpr auto end()
Definition: take_view.hpp:212
constexpr sentinel< true > end() const
Definition: take_view.hpp:255
constexpr auto end() const
Definition: take_view.hpp:238
constexpr auto begin() const
Definition: take_view.hpp:183
constexpr take_view(V base, range_difference_t< V > count)
Definition: take_view.hpp:136
constexpr auto begin()
Definition: take_view.hpp:155
helper class template for defining a view, using the curiously recurring template pattern
Definition: view_interface.hpp:78
constexpr VCCC_INLINE_OR_STATIC detail::min_niebloid min
Definition: min.hpp:90
constexpr VCCC_INLINE_OR_STATIC detail::count_niebloid count
Definition: count.hpp:58
constexpr VCCC_INLINE_OR_STATIC default_sentinel_t default_sentinel
Definition: default_sentinel_t.hpp:25
constexpr take_view< views::all_t< R > > make_take_view(R &&r, range_difference_t< R > count)
Definition: take_view.hpp:277
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
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
typename remove_cvref< T >::type remove_cvref_t
Definition: remove_cvref.hpp:24
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
Definition: default_sentinel_t.hpp:23
Definition: negation.hpp:23
Definition: enable_borrowed_range.hpp:17
specifies a range whose iterator type satisfies random_access_iterator
Definition: random_access_range.hpp:48
specifies that a type is a range, that is, it provides a begin iterator and an end sentinel
Definition: range.hpp:53
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
Definition: sentinel_for.hpp:24