23namespace bio::ranges::detail
49template <
typename derived_t, std::input_or_output_iterator base_t>
50class inherited_iterator_base :
51 public std::conditional_t<std::is_pointer_v<base_t> || !std::semiregular<base_t>, meta::detail::empty_type, 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>;
72 using iterator_category = detail::iterator_category_tag_t<base_t>;
74 using iterator_concept = detail::iterator_concept_tag_t<base_t>;
81 constexpr inherited_iterator_base() noexcept(
82 std::is_nothrow_default_constructible_v<base_t>) = default;
83 constexpr inherited_iterator_base(inherited_iterator_base const & rhs) noexcept(
84 std::is_nothrow_copy_constructible_v<base_t>) = default;
85 constexpr inherited_iterator_base(inherited_iterator_base && rhs) noexcept(
86 std::is_nothrow_move_constructible_v<base_t>) = default;
87 constexpr inherited_iterator_base & operator=(inherited_iterator_base const & rhs) noexcept(
88 std::is_nothrow_copy_assignable_v<base_t>) = default;
89 constexpr inherited_iterator_base & operator=(inherited_iterator_base && rhs) noexcept(
90 std::is_nothrow_move_assignable_v<base_t>) = default;
91 ~inherited_iterator_base() noexcept(
std::is_nothrow_destructible_v<base_t>) = default;
94 constexpr inherited_iterator_base(base_t && it) noexcept(
std::is_nothrow_move_constructible_v<base_t>)
96 : base_t{std::move(it)}
100 constexpr inherited_iterator_base(base_t
const & it)
noexcept(std::is_copy_constructible_v<base_t>)
106 constexpr inherited_iterator_base(base_t it)
noexcept
108 : member{std::move(it)}
118 constexpr friend bool operator==(derived_t
const & lhs, derived_t
const & rhs)
noexcept(
119 noexcept(std::declval<base_t &>() == std::declval<base_t &>()))
120 requires std::equality_comparable<base_t>
122 return *lhs.this_to_base() == *rhs.this_to_base();
126 constexpr bool operator<(derived_t
const & rhs)
const
127 noexcept(
noexcept(std::declval<base_t &>() < std::declval<base_t &>()))
128 requires std::totally_ordered<base_t>
130 return *this_to_base() < *rhs.this_to_base();
134 constexpr bool operator>(derived_t
const & rhs)
const
135 noexcept(
noexcept(std::declval<base_t &>() > std::declval<base_t &>()))
136 requires std::totally_ordered<base_t>
138 return *this_to_base() > *rhs.this_to_base();
142 constexpr bool operator<=(derived_t
const & rhs)
const
143 noexcept(
noexcept(std::declval<base_t &>() > std::declval<base_t &>()))
144 requires std::totally_ordered<base_t>
146 return !(*
this > rhs);
150 constexpr bool operator>=(derived_t
const & rhs)
const
151 noexcept(
noexcept(std::declval<base_t &>() < std::declval<base_t &>()))
152 requires std::totally_ordered<base_t>
154 return !(*
this < rhs);
164 template <
typename base_t_ = base_t>
166 constexpr derived_t & operator++() noexcept(noexcept(++
std::declval<base_t &>()))
167 requires(requires(base_t_ i) { ++i; })
170 return *this_derived();
175 template <
typename base_t_ = base_t>
177 constexpr auto operator++(
int)
noexcept(
noexcept(std::declval<base_t &>()++))
178 requires(
requires(base_t_ i) {
180 requires !std::same_as<
decltype(i++), base_t_>;
183 return (*this_to_base())++;
188 template <
typename base_t_ = base_t>
190 constexpr derived_t operator++(
int)
noexcept(
191 noexcept(std::declval<base_t &>()++) &&
noexcept(derived_t(std::declval<base_t &>())))
193 requires(
requires(base_t_ i) {
197 } -> std::same_as<base_t_>;
198 } && std::constructible_from<derived_t, base_t_>)
201 return derived_t{(*this_to_base())++};
206 template <
typename base_t_ = base_t>
208 constexpr derived_t & operator--() noexcept(noexcept(--
std::declval<base_t &>()))
209 requires(requires(base_t_ i) { --i; })
212 return *this_derived();
217 template <
typename base_t_ = base_t>
219 constexpr derived_t operator--(
int)
noexcept(
220 noexcept(std::declval<base_t &>()--) &&
noexcept(derived_t{std::declval<base_t &>()}))
221 requires(
requires(base_t_ i) { i--; } && std::constructible_from<derived_t, base_t_>)
223 return derived_t{(*this_to_base())--};
228 template <
typename base_t_ = base_t>
230 constexpr derived_t & operator+=(difference_type
const skip)
noexcept(
noexcept(std::declval<base_t &>() += skip))
231 requires(
requires(base_t_ i, difference_type
const n) { i += n; })
233 *this_to_base() += skip;
234 return *this_derived();
239 template <
typename base_t_ = base_t>
241 constexpr derived_t operator+(difference_type
const skip)
const
242 noexcept(
noexcept(std::declval<base_t &>() + skip) &&
noexcept(derived_t{std::declval<base_t &>()}))
243 requires(
requires(base_t_
const i, difference_type
const n) { i + n; } &&
244 std::constructible_from<derived_t, base_t_>)
246 return derived_t{*this_to_base() + skip};
250 constexpr friend derived_t operator+(difference_type
const skip,
251 derived_t
const & it)
noexcept(
noexcept(skip + std::declval<base_t const &>()))
252 requires(
requires(base_t
const i, difference_type
const n) { n + i; } &&
253 std::constructible_from<derived_t, base_t>)
255 return derived_t{skip +
static_cast<base_t
const &
>(it)};
260 template <
typename base_t_ = base_t>
262 constexpr derived_t & operator-=(difference_type
const skip)
noexcept(
noexcept(std::declval<base_t &>() -= skip))
263 requires(
requires(base_t_ i, difference_type
const n) { i -= n; })
265 *this_to_base() -= skip;
266 return *this_derived();
271 template <
typename base_t_ = base_t>
273 constexpr derived_t operator-(difference_type
const skip)
const
274 noexcept(
noexcept(std::declval<base_t const &>() - skip) &&
noexcept(derived_t(std::declval<base_t &>())))
275 requires(
requires(base_t_ i, difference_type
const n) { i - n; } && std::constructible_from<derived_t, base_t_>)
277 return derived_t{*this_to_base() - skip};
281 constexpr difference_type operator-(derived_t
const rhs)
const
282 noexcept(
noexcept(std::declval<base_t &>() - std::declval<base_t &>()))
283 requires std::sized_sentinel_for<base_t, base_t>
285 return static_cast<difference_type
>(*this_to_base() - *rhs.this_to_base());
293 constexpr reference operator*() noexcept(noexcept(*
std::declval<base_t &>()))
294 requires
std::indirectly_readable<base_t>
296 return **this_to_base();
300 constexpr decltype(
auto)
operator*()
const noexcept(
noexcept(*std::declval<base_t const &>()))
301 requires std::indirectly_readable<base_t>
303 return **this_to_base();
307 constexpr pointer operator->() noexcept(noexcept(*
std::declval<base_t &>()))
308 requires
std::input_iterator<base_t>
310 return &*this_to_base();
314 constexpr decltype(
auto) operator->() const noexcept(noexcept(*
std::declval<base_t const &>()))
315 requires
std::input_iterator<base_t>
317 return &*this_to_base();
322 template <
typename base_t_ = base_t>
325 noexcept(std::declval<base_t &>()[0]))
326 requires(
requires(base_t_ i, difference_type
const n) { i[n]; })
328 return (*this_to_base())[n];
333 template <
typename base_t_ = base_t>
336 noexcept(
noexcept(std::declval<base_t const &>()[0]))
337 requires(
requires(base_t_
const i, difference_type
const n) { i[n]; })
339 return (*this_to_base())[n];
351 constexpr derived_t * this_derived() {
return static_cast<derived_t *
>(
this); }
354 constexpr derived_t
const * this_derived()
const {
return static_cast<derived_t
const *
>(
this); }
357 constexpr base_t * this_to_base()
359 if constexpr (wrap_base)
362 return static_cast<base_t *
>(
this);
366 constexpr base_t
const * this_to_base()
const
368 if constexpr (wrap_base)
371 return static_cast<base_t
const *
>(
this);
Provides bio::meta::detail::empty_type.
Provides various transformation traits used by the range module.