5 #ifndef VCCC_RANGES_VIEWS_IOTA_HPP_
6 #define VCCC_RANGES_VIEWS_IOTA_HPP_
43 negation<std::is_integral<I>>,
46 bool_constant<( sizeof(iter_difference_t<I>) > sizeof(I) )>
49 type_identity<iter_difference_t<I>>,
50 type_identity<std::intmax_t>
54 using iota_diff_t =
typename iota_diff<I>::type;
57 struct iv_decrementable : std::false_type {};
60 struct iv_decrementable<
63 void_t<decltype( std::declval<I&>()-- )>
65 same_as<decltype( --std::declval<I&>() ), I&>,
66 same_as<decltype( std::declval<I&>()-- ), I>
69 template<
typename I,
typename D,
typename =
void,
typename =
void,
typename =
void,
typename =
void>
70 struct iv_advanceable_explicit : std::false_type {};
72 template<
typename I,
typename D>
73 struct iv_advanceable_explicit<
75 void_t<decltype(
std::declval<I>() + std::declval<D>() )>,
76 void_t<decltype( std::declval<D>() + std::declval<I>() )>,
77 void_t<decltype( std::declval<I>() - std::declval<D>() )>,
78 void_t<decltype( std::declval<I>() - std::declval<I>() )>
80 std::is_constructible<remove_cvref_t<I>, decltype( std::declval<I>() + std::declval<D>() )>,
81 std::is_constructible<remove_cvref_t<I>, decltype( std::declval<D>() + std::declval<I>() )>,
82 std::is_constructible<remove_cvref_t<I>, decltype( std::declval<I>() - std::declval<D>() )>,
83 convertible_to<decltype( std::declval<I>() - std::declval<I>() ), remove_cvref_t<D>>
86 template<
typename I,
bool = conjunction<iv_decrementable<I>, totally_ordered<I>>::value>
87 struct iv_advanceable : std::false_type {};
91 struct iv_advanceable<I, true>
93 implicit_expression_check<vccc::detail::detail_random_access_iterator::explicit_op_assign_check, I&, const iota_diff_t<I>&>,
94 implicit_expression_check<iv_advanceable_explicit, const I&, const iota_diff_t<I>&>
98 struct iota_view_iterator_category {
102 struct iota_view_iterator_category<I, false> {};
105 struct iota_view_iterator_concept
106 : std::conditional_t<
107 iv_advanceable<I>::value, type_identity<random_access_iterator_tag>,
109 iv_decrementable<I>::value, type_identity<bidirectional_iterator_tag>,
111 incrementable<I>::value, type_identity<forward_iterator_tag>,
112 type_identity<input_iterator_tag>
115 template<
typename W,
typename Bound,
typename IV>
116 struct iv_ctor_iterator_last {
117 using type =
typename IV::sentinel;
120 template<
typename W,
typename IV>
121 struct iv_ctor_iterator_last<W, unreachable_sentinel_t, IV> {
122 using type = unreachable_sentinel_t;
125 template<
typename W,
typename IV>
126 struct iv_ctor_iterator_last<W, W, IV> {
127 using type =
typename IV::iterator;
196 typename Bound = unreachable_sentinel_t>
207 class iterator :
public detail::iota_view_iterator_category<W> {
213 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
214 default_initializable<W>
229 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
230 negation<incrementable<W>>
235 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
245 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
246 detail::iv_decrementable<W>
252 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
253 detail::iv_decrementable<W>
261 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
262 detail::iv_advanceable<W>,
263 is_
unsigned_
integer_like<W>
266 n < 0 ? (void)(value_ += static_cast<W>(n)) : (
void)(value_ -=
static_cast<W
>(-n));
269 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
270 detail::iv_advanceable<W>,
271 negation<is_
unsigned_
integer_like<W>>
274 value_ +=
static_cast<W
>(n);
278 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
279 detail::iv_advanceable<W>,
280 is_
unsigned_
integer_like<W>
283 n < 0 ? (void)(value_ -=
static_cast<W
>(n)) : (
void)(value_ +=
static_cast<W
>(-n));
286 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
287 detail::iv_advanceable<W>,
288 negation<is_
unsigned_
integer_like<W>>
295 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
296 detail::iv_advanceable<W>
299 return W(value_ + n);
304 return x.value_ == y.value_;
312 return x.value_ < y.value_;
345 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
346 detail::iv_advanceable<W>,
347 is_
signed_
integer_like<W>
353 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
354 detail::iv_advanceable<W>,
355 negation<is_
signed_
integer_like<W>>,
356 is_
unsigned_
integer_like<W>
360 return y.value_ > x.value_ ? D(-D(y.value_ - x.value_)) : D(x.value_ - y.value_);
363 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
364 detail::iv_advanceable<W>,
365 negation<is_
signed_
integer_like<W>>,
366 negation<is_
unsigned_
integer_like<W>>
369 return x.value_ - y.value_;
383 constexpr
explicit sentinel(Bound bound) : bound_(bound) {}
387 return *x == y.bound_;
399 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
400 sized_sentinel_for<Bound, W>
403 return *x - y.bound_;
406 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
407 sized_sentinel_for<Bound, W>
410 return -(*y - x.bound_);
420 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
421 default_initializable<W>
431 : value_(*
first), bound_(get_value(last)) {}
438 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
439 negation<same_as<W, Bound>>
444 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
453 return value_ == bound_;
456 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
458 conjunction<same_as<W, Bound>, detail::iv_advanceable<W>>,
459 conjunction<is_
integer_like<W>, is_
integer_like<Bound>>,
460 sized_sentinel_for<Bound, W>
469 static constexpr
auto to_unsigned_like(T x) {
470 using R = std::make_unsigned_t<T>;
471 return static_cast<R
>(x);
474 constexpr
auto size_impl(std::true_type)
const {
477 ? to_unsigned_like(-value_) - to_unsigned_like(-bound_)
478 : to_unsigned_like(bound_) + to_unsigned_like(-value_)
480 : to_unsigned_like(bound_) - to_unsigned_like(value_);
482 constexpr
auto size_impl(std::false_type)
const {
483 return static_cast<std::size_t
>(bound_ - value_);
486 static constexpr W get_value(
const iterator& i) {
489 static constexpr Bound get_value(
const sentinel& s) {
492 static constexpr unreachable_sentinel_t get_value(
const unreachable_sentinel_t&) {
493 return unreachable_sentinel_t{};
497 Bound bound_ = Bound();
502 template<
typename W,
typename Bound>
516 template<
typename W,
typename Bound, std::enable_if_t<
conjunction<
Definition: iota_view.hpp:207
constexpr iterator & operator--()
Definition: iota_view.hpp:248
constexpr W operator*() const noexcept(std::is_nothrow_copy_constructible< W >::value)
Definition: iota_view.hpp:220
constexpr friend std::enable_if_t< totally_ordered< W >::value, bool > operator>=(const iterator &x, const iterator &y)
Definition: iota_view.hpp:323
constexpr iterator(W value)
Definition: iota_view.hpp:218
constexpr friend std::enable_if_t< equality_comparable< W >::value, bool > operator==(const iterator &x, const iterator &y)
Definition: iota_view.hpp:303
constexpr void operator++(int)
Definition: iota_view.hpp:232
constexpr friend std::enable_if_t< totally_ordered< W >::value, bool > operator<(const iterator &x, const iterator &y)
Definition: iota_view.hpp:311
W value_type
Definition: iota_view.hpp:209
constexpr W operator[](difference_type n) const
Definition: iota_view.hpp:298
constexpr friend std::enable_if_t< totally_ordered< W >::value, bool > operator>(const iterator &x, const iterator &y)
Definition: iota_view.hpp:315
constexpr friend std::enable_if_t< detail::iv_advanceable< W >::value, iterator > operator+(iterator i, difference_type n)
Definition: iota_view.hpp:328
constexpr iterator & operator-=(difference_type n)
Definition: iota_view.hpp:282
constexpr friend std::enable_if_t< detail::iv_advanceable< W >::value, iterator > operator-(iterator i, difference_type n)
Definition: iota_view.hpp:339
constexpr iterator & operator+=(difference_type n)
Definition: iota_view.hpp:265
constexpr iterator operator--(int)
Definition: iota_view.hpp:255
constexpr iterator()
Definition: iota_view.hpp:216
constexpr friend std::enable_if_t< totally_ordered< W >::value, bool > operator<=(const iterator &x, const iterator &y)
Definition: iota_view.hpp:319
constexpr friend std::enable_if_t< detail::iv_advanceable< W >::value, iterator > operator+(difference_type n, iterator i)
Definition: iota_view.hpp:333
constexpr iterator operator++(int)
Definition: iota_view.hpp:238
constexpr friend std::enable_if_t< equality_comparable< W >::value, bool > operator!=(const iterator &x, const iterator &y)
Definition: iota_view.hpp:307
detail::iota_diff_t< W > difference_type
Definition: iota_view.hpp:210
typename detail::iota_view_iterator_concept< W >::type iterator_concept
Definition: iota_view.hpp:211
constexpr iterator & operator++()
Definition: iota_view.hpp:224
constexpr friend difference_type operator-(iterator x, iterator y)
Definition: iota_view.hpp:349
Definition: iota_view.hpp:379
constexpr sentinel()
Definition: iota_view.hpp:381
constexpr friend bool operator!=(const iterator &x, const sentinel &y)
Definition: iota_view.hpp:389
constexpr friend bool operator==(const iterator &x, const sentinel &y)
Definition: iota_view.hpp:385
constexpr friend iter_difference_t< W > operator-(const iterator &x, const sentinel &y)
Definition: iota_view.hpp:402
constexpr friend bool operator==(const sentinel &y, const iterator &x)
Definition: iota_view.hpp:392
constexpr friend iter_difference_t< W > operator-(const sentinel &x, const iterator &y)
Definition: iota_view.hpp:409
constexpr sentinel(Bound bound)
Definition: iota_view.hpp:383
constexpr friend bool operator!=(const sentinel &y, const iterator &x)
Definition: iota_view.hpp:395
Definition: iota_view.hpp:197
constexpr iota_view(type_identity_t< W > value, type_identity_t< Bound > bound)
Definition: iota_view.hpp:427
constexpr iota_view(iterator first, typename detail::iv_ctor_iterator_last< W, Bound, iota_view >::type last)
Definition: iota_view.hpp:430
constexpr auto size() const
Definition: iota_view.hpp:463
constexpr iota_view()
Definition: iota_view.hpp:423
constexpr iterator end() const
Definition: iota_view.hpp:447
constexpr iota_view(W value)
Definition: iota_view.hpp:425
constexpr iterator begin() const
Definition: iota_view.hpp:433
constexpr sentinel end() const
Definition: iota_view.hpp:441
constexpr bool empty() const
Definition: iota_view.hpp:451
helper class template for defining a view, using the curiously recurring template pattern
Definition: view_interface.hpp:78
typename iter_difference< T >::type iter_difference_t
Computes the difference type of T
Definition: iter_difference_t.hpp:49
std::input_iterator_tag input_iterator_tag
Definition: iterator_tag.hpp:15
constexpr VCCC_INLINE_OR_STATIC detail::iota_niebloid iota
Definition: iota_view.hpp:539
std::integral_constant< bool, v > bool_constant
Definition: bool_constant.hpp:19
#define VCCC_INLINE_OR_STATIC
Definition: inline_or_static.hpp:9
Definition: matrix.hpp:495
Definition: cxx20_rel_ops.hpp:17
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 0 > first
Definition: key_value.hpp:34
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35
Definition: conjunction.hpp:22
specifies that an object of a type can be copied, moved, and swapped
Definition: copyable.hpp:59
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
Definition: enable_borrowed_range.hpp:17
Definition: iota_view.hpp:510
constexpr iota_view< std::remove_reference_t< W > > operator()(W &&value) const
Definition: iota_view.hpp:512
constexpr ranges::iota_view< std::remove_reference_t< W >, std::remove_reference_t< Bound > > operator()(W &&value, Bound &&bound) const
Definition: iota_view.hpp:524
specifies that an object of a type can be copied, moved, swapped, and default constructed
Definition: semiregular.hpp:31
specifies that two different objects can be compared for equality with each other (in either order) u...
Definition: weakly_equality_comparable_with.hpp:51
Definition: weakly_incrementable.hpp:52