22namespace seqan3::detail
48template <
typename derived_t, std::input_or_output_iterator base_t>
49class 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>)
101 : base_t{std::move(it)}
105 constexpr inherited_iterator_base(base_t it)
noexcept
109 : member{std::move(it)}
114 constexpr base_t
const & base() const & noexcept
120 constexpr base_t & base() &
noexcept
126 constexpr base_t base() &&
noexcept
128 return std::move(as_base());
137 constexpr bool operator==(derived_t
const & rhs)
const
138 noexcept(
noexcept(std::declval<base_t &>() == std::declval<base_t &>()))
140 requires std::equality_comparable<base_t>
143 return base() == rhs.base();
147 constexpr bool operator!=(derived_t
const & rhs)
const
148 noexcept(
noexcept(std::declval<base_t &>() == std::declval<base_t &>()))
150 requires std::equality_comparable<base_t>
153 return !(*
this == rhs);
157 constexpr bool operator<(derived_t
const & rhs)
const
158 noexcept(
noexcept(std::declval<base_t &>() < std::declval<base_t &>()))
160 requires std::totally_ordered<base_t>
163 return base() < rhs.base();
167 constexpr bool operator>(derived_t
const & rhs)
const
168 noexcept(
noexcept(std::declval<base_t &>() > std::declval<base_t &>()))
170 requires std::totally_ordered<base_t>
173 return base() > rhs.base();
177 constexpr bool operator<=(derived_t
const & rhs)
const
178 noexcept(
noexcept(std::declval<base_t &>() > std::declval<base_t &>()))
180 requires std::totally_ordered<base_t>
183 return !(*
this > rhs);
187 constexpr bool operator>=(derived_t
const & rhs)
const
188 noexcept(
noexcept(std::declval<base_t &>() < std::declval<base_t &>()))
190 requires std::totally_ordered<base_t>
193 return !(*
this < rhs);
203 template <
typename base_t_ = base_t>
205 constexpr derived_t & operator++() noexcept(noexcept(++
std::declval<base_t &>()))
207 requires requires (base_t_ i) { ++i; }
211 return *this_derived();
216 template <
typename base_t_ = base_t>
218 constexpr auto operator++(
int)
noexcept(
noexcept(std::declval<base_t &>()++))
220 requires requires (base_t_ i) { i++;
requires !std::same_as<
decltype(i++), base_t_>; }
228 template <
typename base_t_ = base_t>
230 constexpr derived_t operator++(
int)
noexcept(
noexcept(std::declval<base_t &>()++) &&
231 noexcept(derived_t(std::declval<base_t &>())))
234 std::constructible_from<derived_t, base_t_>
237 return derived_t{as_base()++};
242 template <
typename base_t_ = base_t>
244 constexpr derived_t & operator--() noexcept(noexcept(--
std::declval<base_t &>()))
246 requires requires (base_t_ i) { --i; }
250 return *this_derived();
255 template <
typename base_t_ = base_t>
257 constexpr derived_t operator--(
int)
noexcept(
noexcept(std::declval<base_t &>()--) &&
258 noexcept(derived_t{std::declval<base_t &>()}))
260 requires requires (base_t_ i) { i--; } && std::constructible_from<derived_t, base_t_>
263 return derived_t{as_base()--};
268 template <
typename base_t_ = base_t>
270 constexpr derived_t & operator+=(difference_type
const skip)
noexcept(
noexcept(std::declval<base_t &>() += skip))
272 requires requires (base_t_ i, difference_type
const n) { i += n; }
276 return *this_derived();
281 template <
typename base_t_ = base_t>
283 constexpr derived_t operator+(difference_type
const skip)
const
284 noexcept(
noexcept(std::declval<base_t &>() + skip) &&
noexcept(derived_t{std::declval<base_t &>()}))
286 requires requires (base_t_
const i, difference_type
const n) { i + n; } &&
287 std::constructible_from<derived_t, base_t_>
290 return derived_t{as_base() + skip};
294 constexpr friend derived_t operator+(difference_type
const skip, derived_t
const & it)
295 noexcept(
noexcept(skip + std::declval<base_t const &>()))
297 requires requires (base_t
const i, difference_type
const n) { n + i; } &&
298 std::constructible_from<derived_t, base_t>
306 template <
typename base_t_ = base_t>
308 constexpr derived_t & operator-=(difference_type
const skip)
noexcept(
noexcept(std::declval<base_t &>() -= skip))
310 requires requires (base_t_ i, difference_type
const n) { i -= n; }
314 return *this_derived();
319 template <
typename base_t_ = base_t>
321 constexpr derived_t operator-(difference_type
const skip)
const
322 noexcept(
noexcept(std::declval<base_t const &>() - skip) &&
noexcept(derived_t(std::declval<base_t &>())))
324 requires requires (base_t_ i, difference_type
const n) { i - n; } &&
325 std::constructible_from<derived_t, base_t_>
328 return derived_t{as_base() - skip};
332 constexpr difference_type operator-(derived_t
const & rhs)
const
333 noexcept(
noexcept(std::declval<base_t &>() - std::declval<base_t &>()))
335 requires std::sized_sentinel_for<base_t, base_t>
338 return as_base() - rhs.as_base();
346 constexpr reference operator*() noexcept(noexcept(*
std::declval<base_t &>()))
348 requires
std::indirectly_readable<base_t>
355 constexpr decltype(
auto)
operator*()
const noexcept(
noexcept(*std::declval<base_t const &>()))
357 requires std::indirectly_readable<base_t>
364 constexpr pointer operator->() noexcept(noexcept(*
std::declval<base_t &>()))
366 requires
std::input_iterator<base_t>
373 constexpr decltype(
auto) operator->() const noexcept(noexcept(*
std::declval<base_t const &>()))
375 requires
std::input_iterator<base_t>
383 template <
typename base_t_ = base_t>
386 noexcept(
noexcept(std::declval<base_t &>()[0]))
388 requires requires (base_t_ i, difference_type
const n) { i[n]; }
396 template <
typename base_t_ = base_t>
399 noexcept(
noexcept(std::declval<base_t const &>()[0]))
401 requires requires (base_t_
const i, difference_type
const n) { i[n]; }
416 constexpr base_t & as_base() &
noexcept
418 if constexpr (wrap_base)
425 constexpr base_t
const & as_base() const & noexcept
427 if constexpr (wrap_base)
434 constexpr derived_t * this_derived()
436 return static_cast<derived_t*
>(
this);
440 constexpr derived_t
const * this_derived()
const
442 return static_cast<derived_t
const *
>(
this);
Provides seqan3::detail::empty_type.
Provides various transformation traits for use on iterators.
The <iterator> header from C++20's standard library.
SeqAn specific customisations in the standard namespace.