45template <
typename derived_t, std::input_or_output_iterator base_t>
47 public std::conditional_t<std::is_pointer_v<base_t> || !std::semiregular<base_t>, empty_type, base_t>,
52 static constexpr bool wrap_base = std::is_pointer_v<base_t> || !std::semiregular<base_t>;
68#if SEQAN3_DOXYGEN_ONLY(1) 0
73 using iterator_concept = detail::iterator_concept_tag_t<base_t>;
81 noexcept(
std::is_nothrow_default_constructible_v<base_t>) = default;
83 noexcept(
std::is_nothrow_copy_constructible_v<base_t>) = default;
85 noexcept(
std::is_nothrow_move_constructible_v<base_t>) = default;
87 noexcept(
std::is_nothrow_copy_assignable_v<base_t>) = default;
89 noexcept(
std::is_nothrow_move_assignable_v<base_t>) = default;
95 : base_t{std::move(it)}
106 constexpr base_t
const &
base() const & noexcept
112 constexpr base_t &
base() &
noexcept
118 constexpr base_t
base() &&
noexcept
130 noexcept(
noexcept(std::declval<base_t &>() == std::declval<base_t &>()))
131 requires std::equality_comparable<base_t>
133 return base() == rhs.base();
138 noexcept(
noexcept(std::declval<base_t &>() == std::declval<base_t &>()))
139 requires std::equality_comparable<base_t>
141 return !(*
this == rhs);
146 noexcept(
noexcept(std::declval<base_t &>() < std::declval<base_t &>()))
147 requires std::totally_ordered<base_t>
149 return base() < rhs.base();
154 noexcept(
noexcept(std::declval<base_t &>() > std::declval<base_t &>()))
155 requires std::totally_ordered<base_t>
157 return base() > rhs.base();
162 noexcept(
noexcept(std::declval<base_t &>() > std::declval<base_t &>()))
163 requires std::totally_ordered<base_t>
165 return !(*
this > rhs);
170 noexcept(
noexcept(std::declval<base_t &>() < std::declval<base_t &>()))
171 requires std::totally_ordered<base_t>
173 return !(*
this < rhs);
183 template <
typename base_t_ = base_t>
186 requires requires (base_t_ i) { ++i; }
194 template <
typename base_t_ = base_t>
196 constexpr auto operator++(
int)
noexcept(
noexcept(std::declval<base_t &>()++))
197 requires requires (base_t_ i) {
199 requires !std::same_as<
decltype(i++), base_t_>;
207 template <
typename base_t_ = base_t>
210 noexcept(
noexcept(std::declval<base_t &>()++) && std::is_nothrow_copy_constructible_v<derived_t>)
211 requires requires (base_t_ i) {
213 { i++ } -> std::same_as<base_t_>;
214 } && std::copy_constructible<derived_t>
223 template <
typename base_t_ = base_t>
226 requires requires (base_t_ i) { --i; }
234 template <
typename base_t_ = base_t>
237 noexcept(
noexcept(std::declval<base_t &>()--) && std::is_nothrow_copy_constructible_v<derived_t>)
238 requires requires (base_t_ i) { i--; } && std::copy_constructible<derived_t>
247 template <
typename base_t_ = base_t>
258 template <
typename base_t_ = base_t>
261 noexcept(
noexcept(std::declval<base_t &>() + skip) && std::is_nothrow_copy_constructible_v<derived_t>)
262 requires requires (base_t_
const i,
difference_type const n) { i + n; } && std::copy_constructible<derived_t>
265 tmp.as_base() += skip;
274 template <
typename base_t_ = base_t>
277 noexcept(
noexcept(skip + std::declval<base_t const &>()))
279 && std::constructible_from<derived_t, base_t>
286 template <
typename base_t_ = base_t>
297 template <
typename base_t_ = base_t>
300 noexcept(
noexcept(std::declval<base_t const &>() - skip) && std::is_nothrow_copy_constructible_v<derived_t>)
301 requires requires (base_t_ i,
difference_type const n) { i - n; } && std::copy_constructible<derived_t>
304 tmp.as_base() -= skip;
310 noexcept(
noexcept(std::declval<base_t &>() - std::declval<base_t &>()))
311 requires std::sized_sentinel_for<base_t, base_t>
313 return as_base() - rhs.as_base();
322 requires
std::indirectly_readable<base_t>
328 constexpr decltype(
auto)
operator*()
const noexcept(
noexcept(*std::declval<base_t const &>()))
329 requires std::indirectly_readable<base_t>
336 requires
std::input_iterator<base_t>
342 constexpr decltype(
auto) operator->() const noexcept(noexcept(*
std::declval<base_t const &>()))
343 requires
std::input_iterator<base_t>
350 template <
typename base_t_ = base_t>
353 noexcept(
noexcept(std::declval<base_t &>()[0]))
361 template <
typename base_t_ = base_t>
364 noexcept(
noexcept(std::declval<base_t const &>()[0]))
388 constexpr base_t
const &
as_base() const & noexcept
405 return static_cast<derived_t const *
>(
this);
A CRTP base template for creating iterators that inherit from other iterators.
Definition inherited_iterator_base.hpp:49
constexpr base_t base() &&noexcept
Returns an rvalue of the base.
Definition inherited_iterator_base.hpp:118
constexpr pointer operator->() noexcept(noexcept(*std::declval< base_t & >()))
Return pointer to this iterator.
Definition inherited_iterator_base.hpp:335
constexpr reference operator*() noexcept(noexcept(*std::declval< base_t & >()))
Dereference operator returns element currently pointed at.
Definition inherited_iterator_base.hpp:321
constexpr bool operator==(derived_t const &rhs) const noexcept(noexcept(std::declval< base_t & >()==std::declval< base_t & >()))
Checks whether *this is equal to rhs.
Definition inherited_iterator_base.hpp:129
constexpr derived_t operator--(int) noexcept(noexcept(std::declval< base_t & >() --) &&std::is_nothrow_copy_constructible_v< derived_t >)
Post-decrement, return previous iterator state.
Definition inherited_iterator_base.hpp:236
constexpr bool operator<(derived_t const &rhs) const noexcept(noexcept(std::declval< base_t & >()< std::declval< base_t & >()))
Checks whether *this is less than rhs.
Definition inherited_iterator_base.hpp:145
maybe_present iterator_category
The iterator category tag.
Definition inherited_iterator_base.hpp:70
static constexpr bool wrap_base
Whether this iterator inherits or wraps.
Definition inherited_iterator_base.hpp:52
constexpr derived_t & operator+=(difference_type const skip) noexcept(noexcept(std::declval< base_t & >()+=skip))
Move iterator to the right.
Definition inherited_iterator_base.hpp:249
constexpr auto operator++(int) noexcept(noexcept(std::declval< base_t & >()++))
Post-increment of input iterators that do not return a copy of themselves but void or a proxy type.
Definition inherited_iterator_base.hpp:196
constexpr derived_t operator-(difference_type const skip) const noexcept(noexcept(std::declval< base_t const & >() - skip) &&std::is_nothrow_copy_constructible_v< derived_t >)
Return decremented copy of this iterator.
Definition inherited_iterator_base.hpp:299
std::conditional_t< wrap_base, base_t, empty_type > member
If the base is a pointer, we wrap it instead of inheriting.
Definition inherited_iterator_base.hpp:373
constexpr inherited_iterator_base(base_t it) noexcept
Initialise member if deriving from pointer.
Definition inherited_iterator_base.hpp:99
detail::iter_pointer_t< base_t > pointer
The pointer type.
Definition inherited_iterator_base.hpp:67
constexpr difference_type operator-(derived_t const &rhs) const noexcept(noexcept(std::declval< base_t & >() - std::declval< base_t & >()))
Return offset between this and remote iterator's position.
Definition inherited_iterator_base.hpp:309
constexpr derived_t & operator-=(difference_type const skip) noexcept(noexcept(std::declval< base_t & >() -=skip))
Decrement iterator by skip.
Definition inherited_iterator_base.hpp:288
constexpr derived_t const * this_derived() const
Cast this to derived type.
Definition inherited_iterator_base.hpp:403
constexpr derived_t & operator--() noexcept(noexcept(--std::declval< base_t & >()))
Pre-decrement, return updated iterator.
Definition inherited_iterator_base.hpp:225
constexpr derived_t * this_derived()
Cast this to derived type.
Definition inherited_iterator_base.hpp:397
constexpr base_t & base() &noexcept
Get a reference to the base.
Definition inherited_iterator_base.hpp:112
constexpr bool operator>(derived_t const &rhs) const noexcept(noexcept(std::declval< base_t & >() > std::declval< base_t & >()))
Checks whether *this is greater than rhs.
Definition inherited_iterator_base.hpp:153
constexpr bool operator!=(derived_t const &rhs) const noexcept(noexcept(std::declval< base_t & >()==std::declval< base_t & >()))
Checks whether *this is not equal to rhs.
Definition inherited_iterator_base.hpp:137
constexpr base_t & as_base() &noexcept
Cast this to base type.
Definition inherited_iterator_base.hpp:379
constexpr bool operator<=(derived_t const &rhs) const noexcept(noexcept(std::declval< base_t & >() > std::declval< base_t & >()))
Checks whether *this is less than or equal to rhs.
Definition inherited_iterator_base.hpp:161
constexpr derived_t & operator++() noexcept(noexcept(++std::declval< base_t & >()))
Pre-increment, return updated iterator.
Definition inherited_iterator_base.hpp:185
constexpr base_t const & base() const &noexcept
Get a const reference to the base.
Definition inherited_iterator_base.hpp:106
constexpr derived_t operator++(int) noexcept(noexcept(std::declval< base_t & >()++) &&std::is_nothrow_copy_constructible_v< derived_t >)
Post-increment, return previous iterator state.
Definition inherited_iterator_base.hpp:209
constexpr derived_t operator+(difference_type const skip) const noexcept(noexcept(std::declval< base_t & >()+skip) &&std::is_nothrow_copy_constructible_v< derived_t >)
Returns an iterator which is advanced by skip positions.
Definition inherited_iterator_base.hpp:260
friend derived_t
Befriend the derived type so it can access the private members.
Definition inherited_iterator_base.hpp:376
constexpr inherited_iterator_base() noexcept(std::is_nothrow_default_constructible_v< base_t >)=default
Defaulted.
constexpr base_t const & as_base() const &noexcept
Cast this to base type.
Definition inherited_iterator_base.hpp:388
constexpr friend derived_t operator+(difference_type const skip, derived_t const &it) noexcept(noexcept(skip+std::declval< base_t const & >()))
Non-member operator+ delegates to non-friend operator+.
Definition inherited_iterator_base.hpp:276
constexpr bool operator>=(derived_t const &rhs) const noexcept(noexcept(std::declval< base_t & >()< std::declval< base_t & >()))
Checks whether *this is greater than or equal to rhs.
Definition inherited_iterator_base.hpp:169
Provides seqan3::detail::empty_type.
typename iter_pointer< it_t >::type iter_pointer_t
Return the pointer type of the input type (transformation_trait shortcut).
Definition iterator_traits.hpp:151
Provides various transformation traits for use on iterators.
The internal SeqAn3 namespace.
Definition aligned_sequence_concept.hpp:26
SeqAn specific customisations in the standard namespace.
This handles more cases than maybe_iterator_category if you inherit the underling_iterator_t.
Definition iterator_traits.hpp:77