16 #include <type_traits> 48 template <
typename derived_t, std::input_or_output_iterator base_t>
49 class inherited_iterator_base :
public std::conditional_t<std::is_pointer_v<base_t> || !std::semiregular<base_t>,
71 using iterator_category = iterator_tag_t<base_t>;
78 constexpr inherited_iterator_base()
79 noexcept(
std::is_nothrow_default_constructible_v<base_t>) = default;
80 constexpr inherited_iterator_base(inherited_iterator_base const & rhs)
81 noexcept(
std::is_nothrow_copy_constructible_v<base_t>) = default;
82 constexpr inherited_iterator_base(inherited_iterator_base && rhs)
83 noexcept(
std::is_nothrow_move_constructible_v<base_t>) = default;
84 constexpr inherited_iterator_base & operator=(inherited_iterator_base const & rhs)
85 noexcept(
std::is_nothrow_copy_assignable_v<base_t>) = default;
86 constexpr inherited_iterator_base & operator=(inherited_iterator_base && rhs)
87 noexcept(
std::is_nothrow_move_assignable_v<base_t>) = default;
88 ~inherited_iterator_base()
89 noexcept(
std::is_nothrow_destructible_v<base_t>) = default;
92 constexpr inherited_iterator_base(base_t it) noexcept(
std::is_nothrow_move_constructible_v<base_t>)
100 constexpr inherited_iterator_base(base_t it) noexcept
113 constexpr
bool operator==(derived_t
const & rhs)
const 115 noexcept(noexcept(std::declval<base_t &>() == std::declval<base_t &>()))
117 requires
std::equality_comparable<base_t>
120 return *this_to_base() == *rhs.this_to_base();
124 constexpr
bool operator!=(derived_t
const & rhs)
const 125 noexcept(noexcept(std::declval<base_t &>() == std::declval<base_t &>()))
127 requires
std::equality_comparable<base_t>
130 return !(*
this == rhs);
134 constexpr
bool operator<(derived_t
const & rhs)
const 135 noexcept(noexcept(std::declval<base_t &>() < std::declval<base_t &>()))
137 requires
std::totally_ordered<base_t>
140 return *this_to_base() < *rhs.this_to_base();
144 constexpr
bool operator>(derived_t
const & rhs)
const 145 noexcept(noexcept(std::declval<base_t &>() > std::declval<base_t &>()))
147 requires
std::totally_ordered<base_t>
150 return *this_to_base() > *rhs.this_to_base();
154 constexpr
bool operator<=(derived_t
const & rhs)
const 155 noexcept(noexcept(std::declval<base_t &>() > std::declval<base_t &>()))
157 requires
std::totally_ordered<base_t>
160 return !(*
this > rhs);
164 constexpr
bool operator>=(derived_t
const & rhs)
const 165 noexcept(noexcept(std::declval<base_t &>() < std::declval<base_t &>()))
167 requires
std::totally_ordered<base_t>
170 return !(*
this < rhs);
178 template <
typename base_t_ = base_t>
182 constexpr derived_t & operator++() noexcept(noexcept(++
std::declval<base_t &>()))
184 requires requires (base_t_ i) { ++i; }
188 return *this_derived();
193 template <
typename base_t_ = base_t>
195 constexpr
auto operator++(
int) noexcept(noexcept(std::declval<base_t &>()++))
200 return (*this_to_base())++;
205 template <
typename base_t_ = base_t>
207 constexpr derived_t operator++(
int) noexcept(noexcept(std::declval<base_t &>()++) &&
208 noexcept(derived_t(std::declval<base_t &>())))
214 return derived_t{(*this_to_base())++};
219 template <
typename base_t_ = base_t>
221 constexpr derived_t & operator--() noexcept(noexcept(--
std::declval<base_t &>()))
223 requires requires (base_t_ i) { --i; }
227 return *this_derived();
232 template <
typename base_t_ = base_t>
234 constexpr derived_t operator--(
int) noexcept(noexcept(std::declval<base_t &>()--) &&
235 noexcept(derived_t{std::declval<base_t &>()}))
240 return derived_t{(*this_to_base())--};
245 template <
typename base_t_ = base_t>
247 constexpr derived_t & operator+=(difference_type
const skip) noexcept(noexcept(std::declval<base_t &>() += skip))
249 requires requires (base_t_ i, difference_type
const n) { i += n; }
252 *this_to_base() += skip;
253 return *this_derived();
258 template <
typename base_t_ = base_t>
260 constexpr derived_t operator+(difference_type
const skip)
const 261 noexcept(noexcept(std::declval<base_t &>() + skip) && noexcept(derived_t{std::declval<base_t &>()}))
263 requires requires (base_t_
const i, difference_type
const n) { i + n; } &&
267 return derived_t{*this_to_base() + skip};
271 constexpr
friend derived_t operator+(difference_type
const skip, derived_t
const & it)
272 noexcept(noexcept(skip + std::declval<base_t const &>()))
274 requires requires (base_t const i, difference_type const n) { n + i; } &&
278 return derived_t{skip +
static_cast<base_t
const &
>(it)};
283 template <
typename base_t_ = base_t>
285 constexpr derived_t & operator-=(difference_type
const skip) noexcept(noexcept(std::declval<base_t &>() -= skip))
287 requires requires (base_t_ i, difference_type
const n) { i -= n; }
290 *this_to_base() -= skip;
291 return *this_derived();
296 template <
typename base_t_ = base_t>
298 constexpr derived_t operator-(difference_type
const skip)
const 299 noexcept(noexcept(std::declval<base_t const &>() - skip) && noexcept(derived_t(std::declval<base_t &>())))
301 requires requires (base_t_ i, difference_type const n) { i - n; } &&
305 return derived_t{*this_to_base() - skip};
309 constexpr difference_type operator-(derived_t
const rhs)
const 310 noexcept(noexcept(std::declval<base_t &>() - std::declval<base_t &>()))
312 requires
std::sized_sentinel_for<base_t, base_t>
315 return static_cast<difference_type
>(*this_to_base() - *rhs.this_to_base());
322 constexpr reference operator*() noexcept(noexcept(*
std::declval<base_t &>()))
325 requires
std::readable<base_t>
328 return **this_to_base();
332 constexpr decltype(
auto) operator*() const noexcept(noexcept(*
std::declval<base_t const &>()))
334 requires
std::readable<base_t>
337 return **this_to_base();
341 constexpr pointer operator->() noexcept(noexcept(*
std::declval<base_t &>()))
343 requires
std::input_iterator<base_t>
346 return &*this_to_base();
350 constexpr decltype(
auto) operator->() const noexcept(noexcept(*
std::declval<base_t const &>()))
352 requires
std::input_iterator<base_t>
355 return &*this_to_base();
360 template <
typename base_t_ = base_t>
362 constexpr decltype(
auto) operator[](
std::make_signed_t<difference_type> const n)
363 noexcept(noexcept(
std::declval<base_t &>()[0]))
365 requires requires (base_t_ i, difference_type const n) { i[n]; }
368 return (*this_to_base())[n];
373 template <
typename base_t_ = base_t>
375 constexpr decltype(
auto) operator[](
std::make_signed_t<difference_type> const n) const
376 noexcept(noexcept(
std::declval<base_t const &>()[0]))
378 requires requires (base_t_ const i, difference_type const n) { i[n]; }
381 return (*this_to_base())[n];
393 constexpr derived_t * this_derived()
395 return static_cast<derived_t*
>(
this);
399 constexpr derived_t
const * this_derived()
const 401 return static_cast<derived_t
const *
>(
this);
405 constexpr base_t * this_to_base()
407 if constexpr (wrap_base)
410 return static_cast<base_t*
>(
this);
414 constexpr base_t
const * this_to_base()
const 416 if constexpr (wrap_base)
419 return static_cast<base_t
const *
>(
this);
Provides C++20 additions to the <iterator> header.
SeqAn specific customisations in the standard namespace.
Subsumes std::copyable and std::default_constructible.
Provides various transformation traits for use on iterators.
Definition: aligned_sequence_concept.hpp:36
The std::constructible_from concept specifies that a variable of type T can be initialized with the g...
auto const move
A view that turns lvalue-references into rvalue-references.
Definition: move.hpp:68
Provides seqan3::detail::empty_type.
The concept std::same_as<T, U> is satisfied if and only if T and U denote the same type...