SeqAn3 3.3.0-rc.1
The Modern C++ library for sequence analysis.
single_pass_input.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2022, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2022, Knut Reinert & MPI für molekulare Genetik
4// This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
5// shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md
6// -----------------------------------------------------------------------------------------------------
7
13#pragma once
14
15#include <cassert>
16#include <concepts>
17#include <iterator>
18#include <memory>
19#include <ranges>
20#include <type_traits>
21
24
25//-----------------------------------------------------------------------------
26// Implementation of single pass input view.
27//-----------------------------------------------------------------------------
28
29namespace seqan3::detail
30{
31
33template <typename view_t>
35
42template <std::ranges::view urng_t>
43class single_pass_input_view : public std::ranges::view_interface<single_pass_input_view<urng_t>>
44{
46
47private:
49 using urng_iterator_type = std::ranges::iterator_t<urng_t>;
50
52 template <typename view_t>
53 friend class basic_iterator;
54
56 struct state
57 {
59 urng_t urng;
62 };
63
66
73 using sentinel = std::ranges::sentinel_t<urng_t>;
74 //\}
75
76public:
82 constexpr single_pass_input_view() = default;
84 constexpr single_pass_input_view(single_pass_input_view const &) = default;
93
95 explicit constexpr single_pass_input_view(urng_t _urng) : state_ptr{new state{std::move(_urng)}}
96 {}
97
99 template <typename other_urng_t>
100 requires (!std::same_as<std::remove_cvref_t<other_urng_t>, single_pass_input_view>
101 && std::ranges::viewable_range<other_urng_t>
102 && // Must come after self type check to avoid conflicts with the move constructor.
103 std::constructible_from<urng_t, std::ranges::ref_view<std::remove_reference_t<other_urng_t>>>)
104 explicit constexpr single_pass_input_view(other_urng_t && _urng) : single_pass_input_view{std::views::all(_urng)}
105 {}
107
119 {
120 return {*this};
121 }
122
124 iterator begin() const = delete;
125
128 {
129 return {std::ranges::end(state_ptr->urng)};
130 }
131
133 sentinel end() const = delete;
135};
136
143template <std::ranges::viewable_range urng_t>
146} // namespace seqan3::detail
147
148//-----------------------------------------------------------------------------
149// Iterator for single pass input view.
150//-----------------------------------------------------------------------------
151
152namespace seqan3::detail
153{
161template <typename view_type>
163{
168
171
173 template <typename input_view_type>
174 friend class basic_iterator;
175
177 static_assert(std::sentinel_for<sentinel_type, base_iterator_type>);
178
179public:
194
199 basic_iterator() = default;
201 constexpr basic_iterator(basic_iterator const & rhs) = default;
203 constexpr basic_iterator(basic_iterator && rhs) = default;
205 constexpr basic_iterator & operator=(basic_iterator const & rhs) = default;
207 constexpr basic_iterator & operator=(basic_iterator && rhs) = default;
209 ~basic_iterator() = default;
210
212 basic_iterator(single_pass_input_view<view_type> & view) noexcept : view_ptr{&view}
213 {}
215
220 reference operator*() const noexcept
221 {
222 return *cached();
223 }
224
226 pointer operator->() const noexcept
227 requires (!std::is_void_v<pointer>)
228 {
229 return std::addressof(*cached());
230 }
232
238 {
239 ++cached();
240 return *this;
241 }
242
244 void operator++(int) noexcept
245 {
246 // this post-increment can't be an std::output_iterator, because it would require that `*it++ = value` must have
247 // the same semantic as `*i = value; ++i`, but it actually has the following `++i; *i = value` semantic, due to
248 // the centralised storage of the underlying_iterator in the view where each copy of a basic_iterator points to
249 // the same centralised state.
250 ++(*this);
251 }
253
258 constexpr bool operator==(sentinel_type const & s) const noexcept
259 {
260 return cached() == s;
261 }
262
264 friend constexpr bool operator==(sentinel_type const & s, basic_iterator const & rhs) noexcept
265 {
266 return rhs == s;
267 }
268
270 constexpr bool operator!=(sentinel_type const & rhs) const noexcept
271 {
272 return !(*this == rhs);
273 }
274
276 friend constexpr bool operator!=(sentinel_type const & s, basic_iterator const & rhs) noexcept
277 {
278 return rhs != s;
279 }
281
282protected:
285 base_iterator_type & cached() const noexcept
286 {
287 assert(view_ptr != nullptr);
288 assert(view_ptr->state_ptr != nullptr);
289 return view_ptr->state_ptr->cached_urng_iter;
290 }
291};
292} // namespace seqan3::detail
293
294//-----------------------------------------------------------------------------
295// View shortcut for functor.
296//-----------------------------------------------------------------------------
297
299namespace seqan3::views
300{
349
350} // namespace seqan3::views
Provides seqan3::detail::adaptor_for_view_without_args.
T addressof(T... args)
T begin(T... args)
Template for range adaptor closure objects that store no arguments and always delegate to the view co...
Definition: adaptor_for_view_without_args.hpp:49
friend constexpr bool operator!=(sentinel_type const &s, basic_iterator const &rhs) noexcept
Compares for inequality with sentinel.
Definition: single_pass_input.hpp:276
typename single_pass_input_view< view_type >::sentinel sentinel_type
The sentinel type to compare to.
Definition: single_pass_input.hpp:167
constexpr basic_iterator & operator=(basic_iterator const &rhs)=default
Copy assignment.
void operator++(int) noexcept
Post-increment.
Definition: single_pass_input.hpp:244
constexpr basic_iterator & operator=(basic_iterator &&rhs)=default
Move assignment.
friend constexpr bool operator==(sentinel_type const &s, basic_iterator const &rhs) noexcept
Compares for equality with sentinel.
Definition: single_pass_input.hpp:264
basic_iterator(single_pass_input_view< view_type > &view) noexcept
Constructing from the underlying seqan3::single_pass_input_view.
Definition: single_pass_input.hpp:212
pointer operator->() const noexcept
Returns pointer to the pointed-to object.
Definition: single_pass_input.hpp:226
constexpr bool operator==(sentinel_type const &s) const noexcept
Compares for equality with sentinel.
Definition: single_pass_input.hpp:258
constexpr bool operator!=(sentinel_type const &rhs) const noexcept
Compares for inequality with sentinel.
Definition: single_pass_input.hpp:270
basic_iterator & operator++() noexcept
Pre-increment.
Definition: single_pass_input.hpp:237
constexpr basic_iterator(basic_iterator &&rhs)=default
Move construction.
constexpr basic_iterator(basic_iterator const &rhs)=default
Copy construction.
typename single_pass_input_view< view_type >::urng_iterator_type base_iterator_type
The pointer to the associated view.
Definition: single_pass_input.hpp:165
reference operator*() const noexcept
Dereferences the cached iterator.
Definition: single_pass_input.hpp:220
detail::iter_pointer_t< base_iterator_type > pointer
Pointer type.
Definition: single_pass_input.hpp:188
base_iterator_type & cached() const noexcept
Gives access to the cached iterator.
Definition: single_pass_input.hpp:285
Forward declaration.
Definition: single_pass_input.hpp:34
Adds single_pass_input behavior to the underlying range.
Definition: single_pass_input.hpp:44
sentinel end() const =delete
Const version of end is deleted, since the underlying view_state must be mutable.
single_pass_input_view(urng_t &&) -> single_pass_input_view< std::views::all_t< urng_t > >
Deduces the single_pass_input_view from the underlying range if it is a std::ranges::viewable_range.
constexpr single_pass_input_view(single_pass_input_view &&)=default
Default move-constructor.
std::ranges::iterator_t< urng_t > urng_iterator_type
[view_def]
Definition: single_pass_input.hpp:49
iterator begin()
Returns an iterator to the current begin of the underlying range.
Definition: single_pass_input.hpp:118
constexpr single_pass_input_view & operator=(single_pass_input_view const &)=default
Default copy-assignment.
std::shared_ptr< state > state_ptr
Manages the internal state.
Definition: single_pass_input.hpp:65
~single_pass_input_view()=default
Default destructor.
constexpr single_pass_input_view & operator=(single_pass_input_view &&)=default
Default move-assignment.
constexpr single_pass_input_view(other_urng_t &&_urng)
Construction from std::ranges::viewable_range.
Definition: single_pass_input.hpp:104
constexpr single_pass_input_view(single_pass_input_view const &)=default
Default copy-constructor.
constexpr single_pass_input_view(urng_t _urng)
Construction from the underlying view.
Definition: single_pass_input.hpp:95
sentinel end()
Returns a sentinel.
Definition: single_pass_input.hpp:127
iterator begin() const =delete
Const version of begin is deleted, since the underlying view_state must be mutable.
std::ranges::sentinel_t< urng_t > sentinel
The sentinel type.
Definition: single_pass_input.hpp:73
constexpr single_pass_input_view()=default
Default default-constructor.
typename iter_pointer< it_t >::type iter_pointer_t
Return the pointer type of the input type (transformation_trait shortcut).
Definition: iterator_traits.hpp:166
constexpr auto all
Returns a view that includes all elements of the range argument.
Definition: all_view.hpp:204
constexpr auto single_pass_input
A view adapter that decays most of the range properties and adds single pass behavior.
Definition: single_pass_input.hpp:348
Provides various transformation traits for use on iterators.
The internal SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
The SeqAn namespace for views.
Definition: char_strictly_to.hpp:22
SeqAn specific customisations in the standard namespace.
An internal state to capture the underlying range and a cached iterator.
Definition: single_pass_input.hpp:57
urng_iterator_type cached_urng_iter
The cached iterator of the underlying range.
Definition: single_pass_input.hpp:61
urng_t urng
The underlying range.
Definition: single_pass_input.hpp:59