22namespace seqan3::detail
48template <
typename derived_t, std::input_or_output_iterator base_t>
49class inherited_iterator_base :
50 public std::conditional_t<std::is_pointer_v<base_t> || !std::semiregular<base_t>, empty_type, base_t>,
51 public maybe_inherited_iterator_category<base_t>
55 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() noexcept(
std::is_nothrow_default_constructible_v<base_t>) =
85 constexpr inherited_iterator_base(inherited_iterator_base const & rhs) noexcept(
86 std::is_nothrow_copy_constructible_v<base_t>) = default;
87 constexpr inherited_iterator_base(inherited_iterator_base && rhs) noexcept(
88 std::is_nothrow_move_constructible_v<base_t>) = default;
89 constexpr inherited_iterator_base & operator=(inherited_iterator_base const & rhs) noexcept(
90 std::is_nothrow_copy_assignable_v<base_t>) = default;
91 constexpr inherited_iterator_base & operator=(inherited_iterator_base && rhs) noexcept(
92 std::is_nothrow_move_assignable_v<base_t>) = default;
93 ~inherited_iterator_base() noexcept(
std::is_nothrow_destructible_v<base_t>) = default;
96 constexpr inherited_iterator_base(base_t it) noexcept(
std::is_nothrow_move_constructible_v<base_t>)
98 : base_t{std::move(it)}
102 constexpr inherited_iterator_base(base_t it)
noexcept
104 : member{std::move(it)}
109 constexpr base_t
const & base() const & noexcept
115 constexpr base_t & base() &
noexcept
121 constexpr base_t base() &&
noexcept
123 return std::move(as_base());
132 constexpr bool operator==(derived_t
const & rhs)
const
133 noexcept(
noexcept(std::declval<base_t &>() == std::declval<base_t &>()))
134 requires std::equality_comparable<base_t>
136 return base() == rhs.base();
140 constexpr bool operator!=(derived_t
const & rhs)
const
141 noexcept(
noexcept(std::declval<base_t &>() == std::declval<base_t &>()))
142 requires std::equality_comparable<base_t>
144 return !(*
this == rhs);
148 constexpr bool operator<(derived_t
const & rhs)
const
149 noexcept(
noexcept(std::declval<base_t &>() < std::declval<base_t &>()))
150 requires std::totally_ordered<base_t>
152 return base() < rhs.base();
156 constexpr bool operator>(derived_t
const & rhs)
const
157 noexcept(
noexcept(std::declval<base_t &>() > std::declval<base_t &>()))
158 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 &>()))
166 requires std::totally_ordered<base_t>
168 return !(*
this > rhs);
172 constexpr bool operator>=(derived_t
const & rhs)
const
173 noexcept(
noexcept(std::declval<base_t &>() < std::declval<base_t &>()))
174 requires std::totally_ordered<base_t>
176 return !(*
this < rhs);
186 template <
typename base_t_ = base_t>
188 constexpr derived_t & operator++() noexcept(noexcept(++
std::declval<base_t &>()))
189 requires requires (base_t_ i) { ++i; }
192 return *this_derived();
197 template <
typename base_t_ = base_t>
199 constexpr auto operator++(
int)
noexcept(
noexcept(std::declval<base_t &>()++))
200 requires requires (base_t_ i) {
202 requires !std::same_as<
decltype(i++), base_t_>;
210 template <
typename base_t_ = base_t>
213 operator++(
int)
noexcept(
noexcept(std::declval<base_t &>()++) &&
noexcept(derived_t(std::declval<base_t &>())))
214 requires requires (base_t_ i) {
218 } -> std::same_as<base_t_>;
219 } && std::constructible_from<derived_t, base_t_>
221 return derived_t{as_base()++};
226 template <
typename base_t_ = base_t>
228 constexpr derived_t & operator--() noexcept(noexcept(--
std::declval<base_t &>()))
229 requires requires (base_t_ i) { --i; }
232 return *this_derived();
237 template <
typename base_t_ = base_t>
240 operator--(
int)
noexcept(
noexcept(std::declval<base_t &>()--) &&
noexcept(derived_t{std::declval<base_t &>()}))
241 requires requires (base_t_ i) { i--; } && std::constructible_from<derived_t, base_t_>
243 return derived_t{as_base()--};
248 template <
typename base_t_ = base_t>
250 constexpr derived_t & operator+=(difference_type
const skip)
noexcept(
noexcept(std::declval<base_t &>() += skip))
251 requires requires (base_t_ i, difference_type
const n) { i += n; }
254 return *this_derived();
259 template <
typename base_t_ = base_t>
261 constexpr derived_t operator+(difference_type
const skip)
const
262 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; }
264 && std::constructible_from<derived_t, base_t_>
266 return derived_t{as_base() + skip};
274 template <
typename base_t_ = base_t>
276 constexpr friend derived_t operator+(difference_type
const skip,
277 derived_t
const & it)
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) &&
noexcept(derived_t(std::declval<base_t &>())))
301 requires requires (base_t_ i, difference_type
const n) { i - n; } && std::constructible_from<derived_t, base_t_>
303 return derived_t{as_base() - skip};
307 constexpr difference_type operator-(derived_t
const & rhs)
const
308 noexcept(
noexcept(std::declval<base_t &>() - std::declval<base_t &>()))
309 requires std::sized_sentinel_for<base_t, base_t>
311 return as_base() - rhs.as_base();
319 constexpr reference operator*() noexcept(noexcept(*
std::declval<base_t &>()))
320 requires
std::indirectly_readable<base_t>
326 constexpr decltype(
auto)
operator*()
const noexcept(
noexcept(*std::declval<base_t const &>()))
327 requires std::indirectly_readable<base_t>
333 constexpr pointer operator->() noexcept(noexcept(*
std::declval<base_t &>()))
334 requires
std::input_iterator<base_t>
340 constexpr decltype(
auto) operator->() const noexcept(noexcept(*
std::declval<base_t const &>()))
341 requires
std::input_iterator<base_t>
348 template <
typename base_t_ = base_t>
350 constexpr decltype(
auto)
352 requires requires (base_t_ i, difference_type
const n) { i[n]; }
359 template <
typename base_t_ = base_t>
362 noexcept(
noexcept(std::declval<base_t const &>()[0]))
363 requires requires (base_t_
const i, difference_type
const n) { i[n]; }
377 constexpr base_t & as_base() &
noexcept
379 if constexpr (wrap_base)
386 constexpr base_t
const & as_base() const & noexcept
388 if constexpr (wrap_base)
395 constexpr derived_t * this_derived()
397 return static_cast<derived_t *
>(
this);
401 constexpr derived_t
const * this_derived()
const
403 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.