23namespace seqan3::detail
41template <std::ranges::view urng_t>
43class view_enforce_random_access :
public std::ranges::view_interface<view_enforce_random_access<urng_t>>
47 template <
typename underlying_iter_t>
54 constexpr view_enforce_random_access() =
default;
55 constexpr view_enforce_random_access(view_enforce_random_access
const &) =
default;
56 constexpr view_enforce_random_access(view_enforce_random_access &&) =
default;
57 constexpr view_enforce_random_access & operator=(view_enforce_random_access
const &) =
default;
58 constexpr view_enforce_random_access & operator=(view_enforce_random_access &&) =
default;
59 ~view_enforce_random_access() =
default;
62 explicit constexpr view_enforce_random_access(urng_t && range) : urng{
std::
move(range)}
66 template <
typename viewable_rng_t>
67 requires (!std::same_as<std::remove_cvref_t<viewable_rng_t>, view_enforce_random_access>)
68 && std::ranges::viewable_range<viewable_rng_t>
70 explicit constexpr view_enforce_random_access(viewable_rng_t && range) :
71 view_enforce_random_access{std::views::all(std::forward<viewable_rng_t>(range))}
79 constexpr auto begin() noexcept
85 constexpr auto begin() const noexcept
99 constexpr auto end() noexcept
101 if constexpr (std::ranges::common_range<urng_t>)
102 return basic_iterator<
decltype(std::ranges::end(urng))>{std::ranges::end(urng)};
108 constexpr auto end() const noexcept
111 if constexpr (std::ranges::common_range<urng_t>)
112 return basic_iterator<
decltype(std::ranges::end(urng))>{std::ranges::end(urng)};
114 return std::ranges::cend(urng);
129template <std::ranges::view urng_t>
131template <
typename underlying_iter_t>
132class view_enforce_random_access<urng_t>::basic_iterator :
133 public inherited_iterator_base<basic_iterator<underlying_iter_t>, underlying_iter_t>
137 using base_t = inherited_iterator_base<basic_iterator<underlying_iter_t>, underlying_iter_t>;
143 using iterator_concept = iterator_category;
149 using base_t::base_t;
151 constexpr basic_iterator() =
default;
153 constexpr basic_iterator(basic_iterator
const &) =
default;
155 constexpr basic_iterator(basic_iterator &&) =
default;
157 constexpr basic_iterator & operator=(basic_iterator
const &) =
default;
159 constexpr basic_iterator & operator=(basic_iterator &&) =
default;
161 ~basic_iterator() =
default;
169 using base_t::operator==;
170 using base_t::operator!=;
172 friend constexpr bool operator==(basic_iterator
const & lhs, std::ranges::sentinel_t<urng_t>
const & rhs)
noexcept(
173 noexcept(std::declval<underlying_iter_t const &>() == std::declval<std::ranges::sentinel_t<urng_t>
const &>()))
175 return lhs.base() == rhs;
179 friend constexpr bool operator==(std::ranges::sentinel_t<urng_t>
const & lhs, basic_iterator
const & rhs)
noexcept(
180 noexcept(std::declval<underlying_iter_t const &>() == std::declval<std::ranges::sentinel_t<urng_t>
const &>()))
186 friend constexpr bool operator!=(basic_iterator
const & lhs, std::ranges::sentinel_t<urng_t>
const & rhs)
noexcept(
187 noexcept(std::declval<underlying_iter_t const &>() != std::declval<std::ranges::sentinel_t<urng_t>
const &>()))
189 return !(lhs == rhs);
193 friend constexpr bool operator!=(std::ranges::sentinel_t<urng_t>
const & lhs, basic_iterator
const & rhs)
noexcept(
194 noexcept(std::declval<underlying_iter_t const &>() != std::declval<std::ranges::sentinel_t<urng_t>
const &>()))
204 using base_t::operator-;
207 constexpr typename base_t::difference_type operator-(std::ranges::sentinel_t<urng_t>
const & rhs)
const
208 noexcept(
noexcept(std::declval<underlying_iter_t const &>()
209 - std::declval<std::ranges::sentinel_t<urng_t>
const &>()))
210 requires std::sized_sentinel_for<std::ranges::sentinel_t<urng_t>, underlying_iter_t>
212 return this->base() - rhs;
216 constexpr friend typename base_t::difference_type
217 operator-(std::ranges::sentinel_t<urng_t>
const & lhs,
218 basic_iterator
const & rhs)
noexcept(
noexcept(std::declval<std::ranges::sentinel_t<urng_t>
const &>()
219 - std::declval<underlying_iter_t const &>()))
220 requires std::sized_sentinel_for<std::ranges::sentinel_t<urng_t>, underlying_iter_t>
222 return lhs - rhs.base();
232template <std::ranges::viewable_range rng_t>
233view_enforce_random_access(rng_t &&) -> view_enforce_random_access<std::views::all_t<rng_t>>;
241struct pseudo_random_access_fn :
public adaptor_base<pseudo_random_access_fn>
245 using base_t = adaptor_base<pseudo_random_access_fn>;
249 using base_t::base_t;
258 template <std::ranges::viewable_range urng_t>
259 static constexpr auto impl(urng_t && urange)
262 "The adapted range must either model std::ranges::random_access_range or must be "
263 "a specific SeqAn range type that supports pseudo random access.");
264 static_assert(std::ranges::forward_range<urng_t>,
265 "The underlying range must model std::ranges::forward_range.");
267 if constexpr (std::ranges::random_access_range<urng_t>)
269 return std::views::all(std::forward<urng_t>(urange));
273 return view_enforce_random_access{std::forward<urng_t>(urange)};
Provides seqan3::detail::adaptor_base and seqan3::detail::combined_adaptor.
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:350
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.
The SeqAn namespace for views.
Definition: char_strictly_to.hpp:22
SeqAn specific customisations in the standard namespace.
Additional non-standard concepts for ranges.