5 #ifndef VCCC_ITERATOR_COMMON_ITERATOR_HPP_
6 #define VCCC_ITERATOR_COMMON_ITERATOR_HPP_
47 template<
typename I,
typename S>
87 template<
typename I2,
typename S2, std::enable_if_t<
conjunction<
93 std::is_nothrow_constructible<I, const I2&>,
94 std::is_nothrow_constructible<S, const S2&>>::
value)
95 : var_{detail::variant_valueless_ctor{}}
97 switch (x.var_.index()) {
99 var_.
emplace<0>(detail::variant_raw_get(x.var_._base().storage(), in_place_index<0>));
102 var_.
emplace<1>(detail::variant_raw_get(x.var_._base().storage(), in_place_index<1>));
109 template<
typename I2,
typename S2>
112 std::is_nothrow_constructible<I, const I2&>, std::is_nothrow_assignable<I, const I2&>,
113 std::is_nothrow_constructible<S, const S2&>, std::is_nothrow_assignable<S, const S2&> >::
value)
115 if (var_.
index() == x.var_.index()) {
116 switch (x.var_.index()) {
118 this->iterator() = detail::variant_raw_get(x.var_._base().storage(), in_place_index<0>);
121 this->sentinel() = detail::variant_raw_get(x.var_._base().storage(), in_place_index<1>);
128 switch (x.var_.index()) {
130 var_.
emplace<0>(detail::variant_raw_get(x._base().storage(), in_place_index<0>));
133 var_.
emplace<1>(detail::variant_raw_get(x._base().storage(), in_place_index<1>));
142 constexpr decltype(
auto) operator*() {
143 return *this->iterator();
147 constexpr decltype(
auto) operator*()
const {
148 return *this->iterator();
151 template<
typename I2 = I, std::enable_if_t<
conjunction<
156 std::is_reference<iter_reference_t<I2>>,
162 detail::conditional_tag<
164 std::is_reference<iter_reference_t<I>>
166 return operator_arrow(tag{});
174 constexpr decltype(
auto) operator++(
int) {
176 detail::conditional_tag<
180 detail::is_post_incrementable<I>,
188 return post_increment(tag{});
191 template<
typename I2,
typename S2, std::enable_if_t<
conjunction<
201 switch (x.var_.
index()) {
203 switch(y.var_.
index()) {
205 case 1:
return x.iterator() == y.sentinel();
206 default:
return false;
209 switch(y.var_.
index()) {
210 case 0:
return x.sentinel() == y.iterator();
212 default:
return false;
219 template<
typename I2,
typename S2, std::enable_if_t<
conjunction<
228 template<
typename I2,
typename S2, std::enable_if_t<
conjunction<
235 switch (x.var_.
index()) {
237 switch(y.var_.
index()) {
238 case 0:
return x.iterator() == y.iterator();
239 case 1:
return x.iterator() == y.sentinel();
240 default:
return false;
243 switch(y.var_.
index()) {
244 case 0:
return x.sentinel() == y.iterator();
246 default:
return false;
253 template<
typename I2,
typename S2, std::enable_if_t<
conjunction<
263 template<
typename I2,
typename S2, std::enable_if_t<
conjunction<
269 switch (x.var_.
index()) {
271 switch(y.var_.
index()) {
272 case 0:
return x.iterator() - y.iterator();
273 case 1:
return x.iterator() - y.sentinel();
277 switch(y.var_.
index()) {
278 case 0:
return x.sentinel() - y.iterator();
287 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
291 noexcept(noexcept(ranges::
iter_move(
std::declval<const I&>())))
296 template<
typename I2,
typename S2, std::enable_if_t<
300 noexcept(noexcept(
ranges::iter_swap(std::declval<const I&>(), std::declval<const I2&>())))
306 decltype(
auto) iterator() {
307 return detail::variant_raw_get(var_._base().storage(), in_place_index<0>);
309 decltype(
auto) iterator()
const {
310 return detail::variant_raw_get(var_._base().storage(), in_place_index<0>);
312 decltype(
auto) sentinel() {
313 return detail::variant_raw_get(var_._base().storage(), in_place_index<1>);
315 decltype(
auto) sentinel()
const {
316 return detail::variant_raw_get(var_._base().storage(), in_place_index<1>);
319 constexpr
auto operator_arrow(detail::tag_1)
const {
320 return this->iterator();
322 constexpr
auto operator_arrow(detail::tag_2)
const {
326 constexpr
auto operator_arrow(detail::tag_else)
const {
327 return proxy(**
this);
330 constexpr decltype(
auto) post_increment(detail::tag_1) {
335 constexpr decltype(
auto) post_increment(detail::tag_2) {
336 return this->iterator()++;
338 constexpr postfix_proxy post_increment(detail::tag_else) {
339 postfix_proxy p(**
this);
344 variant<I, S> var_{};
347 template<
typename I,
typename S>
354 template<
typename I,
bool = std::is_
integral<iter_difference_t<I>>::value >
355 struct common_iterator_category {
356 #if __cplusplus < 202002L
361 template<
typename I,
bool v = has_
typename_iterator_category<cxx20_iterator_traits<I>>::value >
362 struct common_iterator_category_check_forward : std::false_type {};
364 struct common_iterator_category_check_forward<I, true>
365 : derived_from<typename cxx20_iterator_traits<I>::iterator_category, forward_iterator_tag> {};
368 struct common_iterator_category<I, true> {
369 using iterator_category =
377 template<
typename I,
typename S,
bool = has_operator_arrow<const common_iterator<I, S>&>::value >
378 struct common_iterator_pointer {
381 template<
typename I,
typename S>
382 struct common_iterator_pointer<I, S, true> {
383 using type = decltype(std::declval<
const common_iterator<I, S>&>().operator->());
388 template<
typename I,
typename S>
393 using pointer =
typename detail::common_iterator_pointer<I, S>::type;
397 template<
typename I,
typename S>
404 template<
typename I,
typename S>
Definition: common_iterator.hpp:48
constexpr friend void iter_swap(const common_iterator &x, const common_iterator< I2, S2 > &y) noexcept(noexcept(ranges::iter_swap(std::declval< const I & >(), std::declval< const I2 & >())))
Definition: common_iterator.hpp:299
constexpr decltype(auto) friend iter_move(const common_iterator &i) noexcept(noexcept(ranges::iter_move(std::declval< const I & >())))
Definition: common_iterator.hpp:290
constexpr decltype(auto) operator*()
Definition: common_iterator.hpp:142
constexpr common_iterator(S s)
Definition: common_iterator.hpp:85
constexpr friend iter_difference_t< I2 > operator-(const common_iterator &x, const common_iterator< I2, S2 > &y)
Definition: common_iterator.hpp:268
constexpr friend bool operator!=(const common_iterator &x, const common_iterator< I2, S2 > &y)
Definition: common_iterator.hpp:224
constexpr common_iterator(const common_iterator< I2, S2 > &x) noexcept(conjunction< std::is_nothrow_constructible< I, const I2 & >, std::is_nothrow_constructible< S, const S2 & >>::value)
Definition: common_iterator.hpp:91
constexpr friend bool operator==(const common_iterator &x, const common_iterator< I2, S2 > &y)
Definition: common_iterator.hpp:196
common_iterator()=default
constexpr auto operator->() const
Definition: common_iterator.hpp:160
constexpr common_iterator(I i)
Definition: common_iterator.hpp:84
constexpr common_iterator & operator++()
Definition: common_iterator.hpp:169
constexpr common_iterator & operator=(const common_iterator< I2, S2 > &x) noexcept(conjunction< std::is_nothrow_constructible< I, const I2 & >, std::is_nothrow_assignable< I, const I2 & >, std::is_nothrow_constructible< S, const S2 & >, std::is_nothrow_assignable< S, const S2 & > >::value)
Definition: common_iterator.hpp:110
constexpr std::size_t index() const noexcept
Definition: variant.hpp:662
VCCC_CONSTEXPR_AFTER_CXX20 T & emplace(Args &&... args)
Definition: variant.hpp:674
constexpr VCCC_INLINE_OR_STATIC detail_iter_move::iter_move_niebloid iter_move
Definition: iter_move.hpp:92
constexpr VCCC_INLINE_OR_STATIC detail_iter_swap::iter_swap_niebloid iter_swap
Definition: iter_swap.hpp:90
std::forward_iterator_tag forward_iterator_tag
Definition: iterator_tag.hpp:17
typename iter_reference< T >::type iter_reference_t
Definition: iter_reference_t.hpp:30
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::input_iterator_tag input_iterator_tag
Definition: iterator_tag.hpp:15
std::enable_if_t< std::is_object< T >::value, T * > addressof(T &t) noexcept
Definition: addressof.hpp:33
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
specifies that a variable of the type can be constructed from or bound to a set of argument types
Definition: constructible_from.hpp:31
Models std::convertible_to
Definition: convertible_to.hpp:38
specifies that an object of a type can be copied, moved, and swapped
Definition: copyable.hpp:59
std::conditional_t< forward_iterator< I >::value, forward_iterator_tag, input_iterator_tag > iterator_concept
Definition: common_iterator.hpp:390
typename detail::common_iterator_pointer< I, S >::type pointer
Definition: common_iterator.hpp:393
iter_value_t< I > value_type
Definition: common_iterator.hpp:391
iter_reference_t< I > reference
Definition: common_iterator.hpp:394
iter_difference_t< I > difference_type
Definition: common_iterator.hpp:392
Definition: cxx20_iterator_traits.hpp:188
specifies that an object of a type can be dereferenced
Definition: dereferenceable.hpp:45
Definition: disjunction.hpp:22
specifies that operator == is an equivalence relation
Definition: equality_comparable.hpp:79
specifies that an input_iterator is a forward iterator, supporting equality comparison and multi-pass
Definition: forward_iterator.hpp:53
Definition: has_operator_arrow.hpp:18
iter_difference_t< I > difference_type
Definition: common_iterator.hpp:349
computes the difference type of a weakly_incrementable type
Definition: incrementable_traits.hpp:123
Definition: indirectly_readable.hpp:59
Definition: indirectly_swappable.hpp:46
Definition: iterator_tag.hpp:28
Definition: negation.hpp:23
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