20namespace seqan3::detail
38template <std::ranges::view urng_t>
39 requires pseudo_random_access_range<urng_t>
40class view_enforce_random_access :
public std::ranges::view_interface<view_enforce_random_access<urng_t>>
44 template <
typename underlying_iter_t>
51 constexpr view_enforce_random_access() =
default;
52 constexpr view_enforce_random_access(view_enforce_random_access
const &) =
default;
53 constexpr view_enforce_random_access(view_enforce_random_access &&) =
default;
54 constexpr view_enforce_random_access & operator=(view_enforce_random_access
const &) =
default;
55 constexpr view_enforce_random_access & operator=(view_enforce_random_access &&) =
default;
56 ~view_enforce_random_access() =
default;
59 explicit constexpr view_enforce_random_access(urng_t && range) : urng{std::move(range)}
63 template <
typename viewable_rng_t>
64 requires (!std::same_as<std::remove_cvref_t<viewable_rng_t>, view_enforce_random_access>)
65 && std::ranges::viewable_range<viewable_rng_t>
66 && std::constructible_from<urng_t, std::ranges::ref_view<std::remove_reference_t<viewable_rng_t>>>
67 explicit constexpr view_enforce_random_access(viewable_rng_t && range) :
68 view_enforce_random_access{std::views::all(std::
forward<viewable_rng_t>(range))}
76 constexpr auto begin() noexcept
78 return basic_iterator<
decltype(std::ranges::begin(urng))>{std::ranges::begin(urng)};
82 constexpr auto begin() const noexcept
83 requires const_iterable_range<urng_t>
85 return basic_iterator<
decltype(std::ranges::begin(urng))>{std::ranges::begin(urng)};
96 constexpr auto end() noexcept
98 if constexpr (std::ranges::common_range<urng_t>)
99 return basic_iterator<
decltype(std::ranges::end(urng))>{std::ranges::end(urng)};
105 constexpr auto end() const noexcept
106 requires const_iterable_range<urng_t>
108 if constexpr (std::ranges::common_range<urng_t>)
109 return basic_iterator<
decltype(std::ranges::end(urng))>{std::ranges::end(urng)};
111 return std::ranges::cend(urng);
126template <std::ranges::view urng_t>
127 requires pseudo_random_access_range<urng_t>
128template <
typename underlying_iter_t>
129class view_enforce_random_access<urng_t>::basic_iterator :
130 public inherited_iterator_base<basic_iterator<underlying_iter_t>, underlying_iter_t>
134 using base_t = inherited_iterator_base<basic_iterator<underlying_iter_t>, underlying_iter_t>;
138 using iterator_category = std::random_access_iterator_tag;
140 using iterator_concept = iterator_category;
146 using base_t::base_t;
148 constexpr basic_iterator() =
default;
150 constexpr basic_iterator(basic_iterator
const &) =
default;
152 constexpr basic_iterator(basic_iterator &&) =
default;
154 constexpr basic_iterator & operator=(basic_iterator
const &) =
default;
156 constexpr basic_iterator & operator=(basic_iterator &&) =
default;
158 ~basic_iterator() =
default;
166 using base_t::operator==;
167 using base_t::operator!=;
169 friend constexpr bool operator==(basic_iterator
const & lhs, std::ranges::sentinel_t<urng_t>
const & rhs)
173 return lhs.base() == rhs;
177 friend constexpr bool operator==(std::ranges::sentinel_t<urng_t>
const & lhs, basic_iterator
const & rhs)
185 friend constexpr bool operator!=(basic_iterator
const & lhs, std::ranges::sentinel_t<urng_t>
const & rhs)
189 return !(lhs == rhs);
193 friend constexpr bool operator!=(std::ranges::sentinel_t<urng_t>
const & lhs, basic_iterator
const & rhs)
205 using base_t::operator-;
208 constexpr typename base_t::difference_type operator-(std::ranges::sentinel_t<urng_t>
const & rhs)
const
211 requires std::sized_sentinel_for<std::ranges::sentinel_t<urng_t>, underlying_iter_t>
213 return this->base() - rhs;
217 constexpr friend typename base_t::difference_type operator-(std::ranges::sentinel_t<urng_t>
const & lhs,
218 basic_iterator
const & rhs)
221 requires std::sized_sentinel_for<std::ranges::sentinel_t<urng_t>, underlying_iter_t>
223 return lhs - rhs.base();
233template <std::ranges::viewable_range rng_t>
234view_enforce_random_access(rng_t &&) -> view_enforce_random_access<std::views::all_t<rng_t>>;
242struct pseudo_random_access_fn :
public adaptor_base<pseudo_random_access_fn>
246 using base_t = adaptor_base<pseudo_random_access_fn>;
250 using base_t::base_t;
259 template <std::ranges::viewable_range urng_t>
260 static constexpr auto impl(urng_t && urange)
262 static_assert(std::ranges::random_access_range<urng_t> || pseudo_random_access_range<urng_t>,
263 "The adapted range must either model std::ranges::random_access_range or must be "
264 "a specific SeqAn range type that supports pseudo random access.");
265 static_assert(std::ranges::forward_range<urng_t>,
266 "The underlying range must model std::ranges::forward_range.");
268 if constexpr (std::ranges::random_access_range<urng_t>)
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:351
Provides the seqan3::detail::inherited_iterator_base template.
The SeqAn namespace for views.
Definition char_strictly_to.hpp:19
Additional non-standard concepts for ranges.