SeqAn3 3.4.0-rc.4
The Modern C++ library for sequence analysis.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
enforce_random_access.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2006-2025 Knut Reinert & Freie Universität Berlin
2// SPDX-FileCopyrightText: 2016-2025 Knut Reinert & MPI für molekulare Genetik
3// SPDX-License-Identifier: BSD-3-Clause
4
10#pragma once
11
12#include <iterator>
13#include <ranges>
14#include <type_traits>
15
19
20namespace seqan3::detail
21{
22
23// ============================================================================
24// view_pseudo_random_access
25// ============================================================================
26
38template <std::ranges::view urng_t>
40class view_enforce_random_access : public std::ranges::view_interface<view_enforce_random_access<urng_t>>
41{
42private:
43 // Iterator declaration.
44 template <typename underlying_iter_t>
45 class basic_iterator;
46
47public:
51 constexpr view_enforce_random_access() = default;
57
59 explicit constexpr view_enforce_random_access(urng_t && range) : urng{std::move(range)}
60 {}
61
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))}
69 {}
71
76 constexpr auto begin() noexcept
77 {
79 }
80
82 constexpr auto begin() const noexcept
83 requires const_iterable_range<urng_t>
84 {
86 }
87
96 constexpr auto end() noexcept
97 {
98 if constexpr (std::ranges::common_range<urng_t>)
99 return basic_iterator<decltype(std::ranges::end(urng))>{std::ranges::end(urng)};
100 else
101 return urng.end();
102 }
103
105 constexpr auto end() const noexcept
106 requires const_iterable_range<urng_t>
107 {
108 if constexpr (std::ranges::common_range<urng_t>)
109 return basic_iterator<decltype(std::ranges::end(urng))>{std::ranges::end(urng)};
110 else
111 return std::ranges::cend(urng);
112 }
114
115 urng_t urng;
116};
117
126template <std::ranges::view urng_t>
128template <typename underlying_iter_t>
130 public inherited_iterator_base<basic_iterator<underlying_iter_t>, underlying_iter_t>
131{
132private:
135
136public:
141
145 // Importing base's constructors.
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;
160
165 // Importing base's equality operators
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)
170 noexcept(noexcept(std::declval<underlying_iter_t const &>()
171 == std::declval<std::ranges::sentinel_t<urng_t> const &>()))
172 {
173 return lhs.base() == rhs;
174 }
175
177 friend constexpr bool operator==(std::ranges::sentinel_t<urng_t> const & lhs, basic_iterator const & rhs)
178 noexcept(noexcept(std::declval<underlying_iter_t const &>()
179 == std::declval<std::ranges::sentinel_t<urng_t> const &>()))
180 {
181 return rhs == lhs;
182 }
183
185 friend constexpr bool operator!=(basic_iterator const & lhs, std::ranges::sentinel_t<urng_t> const & rhs)
186 noexcept(noexcept(std::declval<underlying_iter_t const &>()
187 != std::declval<std::ranges::sentinel_t<urng_t> const &>()))
188 {
189 return !(lhs == rhs);
190 }
191
193 friend constexpr bool operator!=(std::ranges::sentinel_t<urng_t> const & lhs, basic_iterator const & rhs)
194 noexcept(noexcept(std::declval<underlying_iter_t const &>()
195 != std::declval<std::ranges::sentinel_t<urng_t> const &>()))
196 {
197 return rhs != lhs;
198 }
200
204 // Import operator from base.
205 using base_t::operator-;
206
208 constexpr typename base_t::difference_type operator-(std::ranges::sentinel_t<urng_t> const & rhs) const
209 noexcept(noexcept(std::declval<underlying_iter_t const &>()
210 - std::declval<std::ranges::sentinel_t<urng_t> const &>()))
211 requires std::sized_sentinel_for<std::ranges::sentinel_t<urng_t>, underlying_iter_t>
212 {
213 return this->base() - rhs;
214 }
215
217 constexpr friend typename base_t::difference_type operator-(std::ranges::sentinel_t<urng_t> const & lhs,
218 basic_iterator const & rhs)
219 noexcept(noexcept(std::declval<std::ranges::sentinel_t<urng_t> const &>()
220 - std::declval<underlying_iter_t const &>()))
221 requires std::sized_sentinel_for<std::ranges::sentinel_t<urng_t>, underlying_iter_t>
222 {
223 return lhs - rhs.base();
224 }
226};
227
233template <std::ranges::viewable_range rng_t>
236
237// ============================================================================
238// pseudo_random_access_fn (adaptor definition)
239// ============================================================================
240
242struct pseudo_random_access_fn : public adaptor_base<pseudo_random_access_fn>
243{
244private:
247
248public:
250 using base_t::base_t;
251
252private:
254 friend base_t;
255
259 template <std::ranges::viewable_range urng_t>
260 static constexpr auto impl(urng_t && urange)
261 {
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.");
267
268 if constexpr (std::ranges::random_access_range<urng_t>)
269 { // Nothing to do, just return as ref_view or original view.
270 return std::views::all(std::forward<urng_t>(urange));
271 }
272 else
273 { // Get a subrange using the random access iterators of the container.
274 return view_enforce_random_access{std::forward<urng_t>(urange)};
275 }
276 }
277};
278
279} // namespace seqan3::detail
280
281namespace seqan3::views
282{
352
353} // namespace seqan3::views
Provides seqan3::detail::adaptor_base and seqan3::detail::combined_adaptor.
T begin(T... args)
CRTP-base to simplify the definition of range adaptor closure objects and similar types.
Definition adaptor_base.hpp:74
A CRTP base template for creating iterators that inherit from other iterators.
Definition inherited_iterator_base.hpp:49
constexpr base_t const & base() const &noexcept
Get a const reference to the base.
Definition inherited_iterator_base.hpp:106
Iterator wrapper for the underlying range iterator enforcing std::random_access_iterator_tag.
Definition enforce_random_access.hpp:131
friend constexpr bool operator!=(basic_iterator const &lhs, std::ranges::sentinel_t< urng_t > const &rhs) noexcept(noexcept(std::declval< underlying_iter_t const & >() !=std::declval< std::ranges::sentinel_t< urng_t > const & >()))
Tests if iterator is not at the end.
Definition enforce_random_access.hpp:185
constexpr basic_iterator & operator=(basic_iterator &&)=default
Defaulted.
constexpr basic_iterator(basic_iterator const &)=default
Defaulted.
constexpr basic_iterator(basic_iterator &&)=default
Defaulted.
constexpr friend base_t::difference_type operator-(std::ranges::sentinel_t< urng_t > const &lhs, basic_iterator const &rhs) noexcept(noexcept(std::declval< std::ranges::sentinel_t< urng_t > const & >() - std::declval< underlying_iter_t const & >()))
Computes the distance betwen this iterator and the sentinel of the underlying range.
Definition enforce_random_access.hpp:217
friend constexpr bool operator==(basic_iterator const &lhs, std::ranges::sentinel_t< urng_t > const &rhs) noexcept(noexcept(std::declval< underlying_iter_t const & >()==std::declval< std::ranges::sentinel_t< urng_t > const & >()))
Tests if iterator is at the end.
Definition enforce_random_access.hpp:169
constexpr basic_iterator & operator=(basic_iterator const &)=default
Defaulted.
friend constexpr bool operator!=(std::ranges::sentinel_t< urng_t > const &lhs, basic_iterator const &rhs) noexcept(noexcept(std::declval< underlying_iter_t const & >() !=std::declval< std::ranges::sentinel_t< urng_t > const & >()))
Tests if iterator is not at the end.
Definition enforce_random_access.hpp:193
friend constexpr bool operator==(std::ranges::sentinel_t< urng_t > const &lhs, basic_iterator const &rhs) noexcept(noexcept(std::declval< underlying_iter_t const & >()==std::declval< std::ranges::sentinel_t< urng_t > const & >()))
Tests if iterator is at the end.
Definition enforce_random_access.hpp:177
constexpr base_t::difference_type operator-(std::ranges::sentinel_t< urng_t > const &rhs) const noexcept(noexcept(std::declval< underlying_iter_t const & >() - std::declval< std::ranges::sentinel_t< urng_t > const & >()))
Computes the distance betwen this iterator and the sentinel of the underlying range.
Definition enforce_random_access.hpp:208
View to force random access range iterator for seqan3::pseudo_random_access_range.
Definition enforce_random_access.hpp:41
constexpr view_enforce_random_access & operator=(view_enforce_random_access const &)=default
Defaulted.
constexpr auto end() noexcept
Returns the sentinel to the end of the range.
Definition enforce_random_access.hpp:96
view_enforce_random_access(rng_t &&) -> view_enforce_random_access< std::views::all_t< rng_t > >
A deduction guide for the view class template.
constexpr view_enforce_random_access(view_enforce_random_access &&)=default
Defaulted.
constexpr auto end() const noexcept
Returns the sentinel to the end of the range.
Definition enforce_random_access.hpp:105
constexpr view_enforce_random_access()=default
Defaulted.
constexpr view_enforce_random_access(viewable_rng_t &&range)
Construction from the underlying viewable range.
Definition enforce_random_access.hpp:67
urng_t urng
The underlying range.
Definition enforce_random_access.hpp:115
constexpr auto begin() const noexcept
Returns the iterator to the begin of the range.
Definition enforce_random_access.hpp:82
constexpr view_enforce_random_access(urng_t &&range)
Construction from the underlying view.
Definition enforce_random_access.hpp:59
constexpr view_enforce_random_access & operator=(view_enforce_random_access &&)=default
Defaulted.
constexpr auto begin() noexcept
Returns the iterator to the begin of the range.
Definition enforce_random_access.hpp:76
constexpr view_enforce_random_access(view_enforce_random_access const &)=default
Defaulted.
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.
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 internal SeqAn3 namespace.
Definition aligned_sequence_concept.hpp:26
The SeqAn namespace for views.
Definition char_strictly_to.hpp:19
SeqAn specific customisations in the standard namespace.
View adaptor definition for seqan3::views::enforce_random_access.
Definition enforce_random_access.hpp:243
static constexpr auto impl(urng_t &&urange)
Call the view's constructor with the underlying view as argument.
Definition enforce_random_access.hpp:260
friend base_t
Befriend the base class so it can call impl().
Definition enforce_random_access.hpp:254
Additional non-standard concepts for ranges.
Hide me