19namespace seqan3::detail
45template <
typename derived_t, std::input_or_output_iterator base_t>
46class inherited_iterator_base :
47 public std::conditional_t<std::is_pointer_v<base_t> || !std::semiregular<base_t>, empty_type, base_t>,
48 public maybe_inherited_iterator_category<base_t>
52 static constexpr bool wrap_base = std::is_pointer_v<base_t> || !std::semiregular<base_t>;
67 using pointer = detail::iter_pointer_t<base_t>;
68#if SEQAN3_DOXYGEN_ONLY(1) 0
70 using iterator_category = maybe_present;
73 using iterator_concept = detail::iterator_concept_tag_t<base_t>;
80 constexpr inherited_iterator_base()
81 noexcept(
std::is_nothrow_default_constructible_v<base_t>) = default;
82 constexpr inherited_iterator_base(inherited_iterator_base const & rhs)
83 noexcept(
std::is_nothrow_copy_constructible_v<base_t>) = default;
84 constexpr inherited_iterator_base(inherited_iterator_base && rhs)
85 noexcept(
std::is_nothrow_move_constructible_v<base_t>) = default;
86 constexpr inherited_iterator_base & operator=(inherited_iterator_base const & rhs)
87 noexcept(
std::is_nothrow_copy_assignable_v<base_t>) = default;
88 constexpr inherited_iterator_base & operator=(inherited_iterator_base && rhs)
89 noexcept(
std::is_nothrow_move_assignable_v<base_t>) = default;
90 ~inherited_iterator_base() noexcept(
std::is_nothrow_destructible_v<base_t>) = default;
93 constexpr inherited_iterator_base(base_t it) noexcept(
std::is_nothrow_move_constructible_v<base_t>)
95 : base_t{std::move(it)}
99 constexpr inherited_iterator_base(base_t it)
noexcept
101 : member{std::move(it)}
106 constexpr base_t
const & base() const & noexcept
112 constexpr base_t & base() &
noexcept
118 constexpr base_t base() &&
noexcept
120 return std::move(as_base());
129 constexpr bool operator==(derived_t
const & rhs)
const
130 noexcept(
noexcept(std::declval<base_t &>() == std::declval<base_t &>()))
131 requires std::equality_comparable<base_t>
133 return base() == rhs.base();
137 constexpr bool operator!=(derived_t
const & rhs)
const
138 noexcept(
noexcept(std::declval<base_t &>() == std::declval<base_t &>()))
139 requires std::equality_comparable<base_t>
141 return !(*
this == rhs);
145 constexpr bool operator<(derived_t
const & rhs)
const
146 noexcept(
noexcept(std::declval<base_t &>() < std::declval<base_t &>()))
147 requires std::totally_ordered<base_t>
149 return base() < rhs.base();
153 constexpr bool operator>(derived_t
const & rhs)
const
154 noexcept(
noexcept(std::declval<base_t &>() > std::declval<base_t &>()))
155 requires std::totally_ordered<base_t>
157 return base() > rhs.base();
161 constexpr bool operator<=(derived_t
const & rhs)
const
162 noexcept(
noexcept(std::declval<base_t &>() > std::declval<base_t &>()))
163 requires std::totally_ordered<base_t>
165 return !(*
this > rhs);
169 constexpr bool operator>=(derived_t
const & rhs)
const
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>
185 constexpr derived_t & operator++() noexcept(noexcept(++
std::declval<base_t &>()))
186 requires requires (base_t_ i) { ++i; }
189 return *this_derived();
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>
209 constexpr derived_t operator++(
int)
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>
216 derived_t tmp = *this_derived();
223 template <
typename base_t_ = base_t>
225 constexpr derived_t & operator--() noexcept(noexcept(--
std::declval<base_t &>()))
226 requires requires (base_t_ i) { --i; }
229 return *this_derived();
234 template <
typename base_t_ = base_t>
236 constexpr derived_t operator--(
int)
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>
240 derived_t tmp = *this_derived();
247 template <
typename base_t_ = base_t>
249 constexpr derived_t & operator+=(difference_type
const skip)
noexcept(
noexcept(std::declval<base_t &>() += skip))
250 requires requires (base_t_ i, difference_type
const n) { i += n; }
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) && 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>
264 derived_t tmp = *this_derived();
265 tmp.as_base() += skip;
274 template <
typename base_t_ = base_t>
276 constexpr friend derived_t operator+(difference_type
const skip, derived_t
const & it)
277 noexcept(
noexcept(skip + std::declval<base_t const &>()))
278 requires requires (base_t
const i, difference_type
const n) { n + i; }
279 && std::constructible_from<derived_t, base_t>
286 template <
typename base_t_ = base_t>
288 constexpr derived_t & operator-=(difference_type
const skip)
noexcept(
noexcept(std::declval<base_t &>() -= skip))
289 requires requires (base_t_ i, difference_type
const n) { i -= n; }
292 return *this_derived();
297 template <
typename base_t_ = base_t>
299 constexpr derived_t operator-(difference_type
const skip)
const
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>
303 derived_t tmp = *this_derived();
304 tmp.as_base() -= skip;
309 constexpr difference_type operator-(derived_t
const & rhs)
const
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();
321 constexpr reference operator*() noexcept(noexcept(*
std::declval<base_t &>()))
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>
335 constexpr pointer operator->() noexcept(noexcept(*
std::declval<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]))
354 requires requires (base_t_ i, difference_type
const n) { i[n]; }
361 template <
typename base_t_ = base_t>
364 noexcept(
noexcept(std::declval<base_t const &>()[0]))
365 requires requires (base_t_
const i, difference_type
const n) { i[n]; }
379 constexpr base_t & as_base() &
noexcept
381 if constexpr (wrap_base)
388 constexpr base_t
const & as_base() const & noexcept
390 if constexpr (wrap_base)
397 constexpr derived_t * this_derived()
399 return static_cast<derived_t *
>(
this);
403 constexpr derived_t
const * this_derived()
const
405 return static_cast<derived_t
const *
>(
this);
Provides seqan3::detail::empty_type.
Provides various transformation traits for use on iterators.
SeqAn specific customisations in the standard namespace.