22 namespace seqan3::detail
40 template <std::ranges::view urng_t>
44 class view_enforce_random_access :
public std::ranges::view_interface<view_enforce_random_access<urng_t>>
49 template <
typename underlying_iter_t>
57 constexpr view_enforce_random_access() =
default;
58 constexpr view_enforce_random_access(view_enforce_random_access
const &) =
default;
59 constexpr view_enforce_random_access(view_enforce_random_access &&) =
default;
60 constexpr view_enforce_random_access & operator=(view_enforce_random_access
const &) =
default;
61 constexpr view_enforce_random_access & operator=(view_enforce_random_access &&) =
default;
62 ~view_enforce_random_access() =
default;
65 explicit constexpr view_enforce_random_access(urng_t range) : urng{
std::
move(range)}
69 template <
typename viewable_rng_t>
72 std::ranges::viewable_range<viewable_rng_t> &&
73 std::constructible_from<urng_t, std::ranges::ref_view<std::remove_reference_t<viewable_rng_t>>>
75 explicit constexpr view_enforce_random_access(viewable_rng_t range) :
76 view_enforce_random_access{
std::views::all(range)}
84 constexpr
auto begin() noexcept
90 constexpr
auto begin() const noexcept
106 constexpr
auto end() noexcept
108 if constexpr (std::ranges::common_range<urng_t>)
109 return basic_iterator<decltype(std::ranges::end(urng))>{std::ranges::end(urng)};
115 constexpr
auto end() const noexcept
120 if constexpr (std::ranges::common_range<urng_t>)
121 return basic_iterator<decltype(std::ranges::cend(urng))>{std::ranges::cend(urng)};
123 return std::ranges::cend(urng);
138 template <std::ranges::view urng_t>
142 template <
typename underlying_iter_t>
143 class view_enforce_random_access<urng_t>::basic_iterator :
144 public inherited_iterator_base<basic_iterator<underlying_iter_t>, underlying_iter_t>
148 using base_t = inherited_iterator_base<basic_iterator<underlying_iter_t>, underlying_iter_t>;
155 using iterator_concept = iterator_category;
161 using base_t::base_t;
163 constexpr basic_iterator() =
default;
165 constexpr basic_iterator(basic_iterator
const &) =
default;
167 constexpr basic_iterator(basic_iterator &&) =
default;
169 constexpr basic_iterator & operator=(basic_iterator
const &) =
default;
171 constexpr basic_iterator & operator=(basic_iterator &&) =
default;
173 ~basic_iterator() =
default;
181 using base_t::operator==;
182 using base_t::operator!=;
184 friend constexpr
bool operator==(basic_iterator
const & lhs, std::ranges::sentinel_t<urng_t>
const & rhs)
185 noexcept(noexcept(std::declval<underlying_iter_t const &>() ==
186 std::declval<std::ranges::sentinel_t<urng_t>
const &>()))
188 return lhs.base() == rhs;
192 friend constexpr
bool operator==(std::ranges::sentinel_t<urng_t>
const & lhs, basic_iterator
const & rhs)
193 noexcept(noexcept(std::declval<underlying_iter_t const &>() ==
194 std::declval<std::ranges::sentinel_t<urng_t>
const &>()))
200 friend constexpr
bool operator!=(basic_iterator
const & lhs, std::ranges::sentinel_t<urng_t>
const & rhs)
201 noexcept(noexcept(std::declval<underlying_iter_t const &>() !=
202 std::declval<std::ranges::sentinel_t<urng_t>
const &>()))
204 return !(lhs == rhs);
208 friend constexpr
bool operator!=(std::ranges::sentinel_t<urng_t>
const & lhs, basic_iterator
const & rhs)
209 noexcept(noexcept(std::declval<underlying_iter_t const &>() !=
210 std::declval<std::ranges::sentinel_t<urng_t>
const &>()))
220 using base_t::operator-;
223 constexpr
typename base_t::difference_type operator-(std::ranges::sentinel_t<urng_t>
const & rhs)
const
224 noexcept(noexcept(std::declval<underlying_iter_t const &>() -
225 std::declval<std::ranges::sentinel_t<urng_t>
const &>()))
226 requires
std::sized_sentinel_for<
std::ranges::sentinel_t<urng_t>, underlying_iter_t>
228 return this->base() - rhs;
232 constexpr
friend typename base_t::difference_type operator-(std::ranges::sentinel_t<urng_t>
const & lhs,
233 basic_iterator
const & rhs)
234 noexcept(noexcept(
std::declval<std::ranges::sentinel_t<urng_t>
const &>() -
235 std::declval<underlying_iter_t const &>()))
236 requires
std::sized_sentinel_for<
std::ranges::sentinel_t<urng_t>, underlying_iter_t>
238 return lhs - rhs.base();
248 template <std::ranges::viewable_range rng_t>
249 view_enforce_random_access(rng_t &&) -> view_enforce_random_access<std::views::all_t<rng_t>>;
257 struct pseudo_random_access_fn :
public adaptor_base<pseudo_random_access_fn>
261 using base_t = adaptor_base<pseudo_random_access_fn>;
265 using base_t::base_t;
274 template <std::ranges::viewable_range urng_t>
275 static constexpr
auto impl(urng_t && urange)
278 "The adapted range must either model std::ranges::random_access_range or must be "
279 "a specific SeqAn range type that supports pseudo random access.");
280 static_assert(std::ranges::forward_range<urng_t>,
281 "The underlying range must model std::ranges::forward_range.");
283 if constexpr (std::ranges::random_access_range<urng_t>)
285 return std::views::all(std::forward<urng_t>(urange));
289 return view_enforce_random_access{std::forward<urng_t>(urange)};
auto const move
A view that turns lvalue-references into rvalue-references.
Definition: move.hpp:70
constexpr auto enforce_random_access
A view adaptor that converts a pseudo random access range to a std::ranges::random_access_range.
Definition: enforce_random_access.hpp:371
Provides the seqan3::detail::inherited_iterator_base template.
Specifies requirements of an input range type for which the const version of that type satisfies the ...
This concept checks if a type models a pseudo random access range.
Provides C++20 additions to the <iterator> header.
The SeqAn namespace for views.
Definition: char_to.hpp:22
SeqAn specific customisations in the standard namespace.
Additional non-standard concepts for ranges.
Adaptations of concepts from the Ranges TS.