17 #include <type_traits>
22 namespace seqan3::detail
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>,
52 public maybe_inherited_iterator_category<base_t>
56 static constexpr
bool wrap_base = std::is_pointer_v<base_t> || !std::semiregular<base_t>;
70 using pointer = detail::iter_pointer_t<base_t>;
71 #if SEQAN3_DOXYGEN_ONLY(1)0
73 using iterator_category = maybe_present;
76 using iterator_concept = detail::iterator_concept_tag_t<base_t>;
83 constexpr inherited_iterator_base()
84 noexcept(
std::is_nothrow_default_constructible_v<base_t>) = default;
85 constexpr inherited_iterator_base(inherited_iterator_base const & rhs)
86 noexcept(
std::is_nothrow_copy_constructible_v<base_t>) = default;
87 constexpr inherited_iterator_base(inherited_iterator_base && rhs)
88 noexcept(
std::is_nothrow_move_constructible_v<base_t>) = default;
89 constexpr inherited_iterator_base & operator=(inherited_iterator_base const & rhs)
90 noexcept(
std::is_nothrow_copy_assignable_v<base_t>) = default;
91 constexpr inherited_iterator_base & operator=(inherited_iterator_base && rhs)
92 noexcept(
std::is_nothrow_move_assignable_v<base_t>) = default;
93 ~inherited_iterator_base()
94 noexcept(
std::is_nothrow_destructible_v<base_t>) = default;
97 constexpr inherited_iterator_base(base_t it) noexcept(
std::is_nothrow_move_constructible_v<base_t>)
105 constexpr inherited_iterator_base(base_t it) noexcept
114 constexpr base_t base() const &
116 requires
std::copyable<base_t>
123 constexpr base_t base() &&
134 constexpr
bool operator==(derived_t
const & rhs)
const
135 noexcept(noexcept(std::declval<base_t &>() == std::declval<base_t &>()))
137 requires
std::equality_comparable<base_t>
140 return base() == rhs.base();
144 constexpr
bool operator!=(derived_t
const & rhs)
const
145 noexcept(noexcept(std::declval<base_t &>() == std::declval<base_t &>()))
147 requires
std::equality_comparable<base_t>
150 return !(*
this == rhs);
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 base() < rhs.base();
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 base() > rhs.base();
174 constexpr
bool operator<=(derived_t
const & rhs)
const
175 noexcept(noexcept(std::declval<base_t &>() > std::declval<base_t &>()))
177 requires
std::totally_ordered<base_t>
180 return !(*
this > rhs);
184 constexpr
bool operator>=(derived_t
const & rhs)
const
185 noexcept(noexcept(std::declval<base_t &>() < std::declval<base_t &>()))
187 requires
std::totally_ordered<base_t>
190 return !(*
this < rhs);
200 template <
typename base_t_ = base_t>
202 constexpr derived_t & operator++() noexcept(noexcept(++
std::declval<base_t &>()))
204 requires requires (base_t_ i) { ++i; }
208 return *this_derived();
213 template <
typename base_t_ = base_t>
215 constexpr
auto operator++(
int) noexcept(noexcept(std::declval<base_t &>()++))
217 requires requires (base_t_ i) { i++; requires !std::same_as<decltype(i++), base_t_>; }
225 template <
typename base_t_ = base_t>
227 constexpr derived_t operator++(
int) noexcept(noexcept(std::declval<base_t &>()++) &&
228 noexcept(derived_t(std::declval<base_t &>())))
231 std::constructible_from<derived_t, base_t_>
234 return derived_t{as_base()++};
239 template <
typename base_t_ = base_t>
241 constexpr derived_t & operator--() noexcept(noexcept(--
std::declval<base_t &>()))
243 requires requires (base_t_ i) { --i; }
247 return *this_derived();
252 template <
typename base_t_ = base_t>
254 constexpr derived_t operator--(
int) noexcept(noexcept(std::declval<base_t &>()--) &&
255 noexcept(derived_t{std::declval<base_t &>()}))
257 requires requires (base_t_ i) { i--; } && std::constructible_from<derived_t, base_t_>
260 return derived_t{as_base()--};
265 template <
typename base_t_ = base_t>
267 constexpr derived_t & operator+=(difference_type
const skip) noexcept(noexcept(std::declval<base_t &>() += skip))
269 requires requires (base_t_ i, difference_type
const n) { i += n; }
273 return *this_derived();
278 template <
typename base_t_ = base_t>
280 constexpr derived_t operator+(difference_type
const skip)
const
281 noexcept(noexcept(std::declval<base_t &>() + skip) && noexcept(derived_t{std::declval<base_t &>()}))
283 requires requires (base_t_ const i, difference_type const n) { i + n; } &&
284 std::constructible_from<derived_t, base_t_>
287 return derived_t{as_base() + skip};
291 constexpr
friend derived_t operator+(difference_type
const skip, derived_t
const & it)
292 noexcept(noexcept(skip + std::declval<base_t const &>()))
294 requires requires (base_t const i, difference_type const n) { n + i; } &&
295 std::constructible_from<derived_t, base_t>
303 template <
typename base_t_ = base_t>
305 constexpr derived_t & operator-=(difference_type
const skip) noexcept(noexcept(std::declval<base_t &>() -= skip))
307 requires requires (base_t_ i, difference_type
const n) { i -= n; }
311 return *this_derived();
316 template <
typename base_t_ = base_t>
318 constexpr derived_t operator-(difference_type
const skip)
const
319 noexcept(noexcept(std::declval<base_t const &>() - skip) && noexcept(derived_t(std::declval<base_t &>())))
321 requires requires (base_t_ i, difference_type const n) { i - n; } &&
322 std::constructible_from<derived_t, base_t_>
325 return derived_t{as_base() - skip};
329 constexpr difference_type operator-(derived_t
const & rhs)
const
330 noexcept(noexcept(std::declval<base_t &>() - std::declval<base_t &>()))
332 requires
std::sized_sentinel_for<base_t, base_t>
335 return as_base() - rhs.as_base();
343 constexpr reference operator*() noexcept(noexcept(*
std::declval<base_t &>()))
345 requires
std::indirectly_readable<base_t>
352 constexpr decltype(
auto) operator*() const noexcept(noexcept(*
std::declval<base_t const &>()))
354 requires
std::indirectly_readable<base_t>
361 constexpr pointer operator->() noexcept(noexcept(*
std::declval<base_t &>()))
363 requires
std::input_iterator<base_t>
370 constexpr decltype(
auto) operator->() const noexcept(noexcept(*
std::declval<base_t const &>()))
372 requires
std::input_iterator<base_t>
380 template <
typename base_t_ = base_t>
382 constexpr decltype(
auto) operator[](
std::make_signed_t<difference_type> const n)
383 noexcept(noexcept(
std::declval<base_t &>()[0]))
385 requires requires (base_t_ i, difference_type const n) { i[n]; }
393 template <
typename base_t_ = base_t>
395 constexpr decltype(
auto) operator[](
std::make_signed_t<difference_type> const n) const
396 noexcept(noexcept(
std::declval<base_t const &>()[0]))
398 requires requires (base_t_ const i, difference_type const n) { i[n]; }
413 constexpr base_t & as_base() & noexcept
415 if constexpr (wrap_base)
422 constexpr base_t
const & as_base() const & noexcept
424 if constexpr (wrap_base)
431 constexpr derived_t * this_derived()
433 return static_cast<derived_t*
>(
this);
437 constexpr derived_t
const * this_derived()
const
439 return static_cast<derived_t
const *
>(
this);
Provides seqan3::detail::empty_type.
auto const move
A view that turns lvalue-references into rvalue-references.
Definition: move.hpp:74
Provides various transformation traits for use on iterators.
Provides C++20 additions to the <iterator> header.
SeqAn specific customisations in the standard namespace.