SeqAn3  3.0.0
The Modern C++ library for sequence analysis.
single_pass_input.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2019, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2019, 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 
18 #include <seqan3/std/concepts>
19 #include <seqan3/std/iterator>
20 #include <seqan3/std/ranges>
21 
22 //-----------------------------------------------------------------------------
23 // Implementation of single pass input view.
24 //-----------------------------------------------------------------------------
25 
26 namespace seqan3::detail
27 {
28 
30 template <typename view_t>
31 class single_pass_input_iterator;
32 
38 template <std::ranges::View urng_t>
40 class single_pass_input_view : public std::ranges::view_interface<single_pass_input_view<urng_t>>
41 {
43 private:
44 
46  using urng_iterator_type = std::ranges::iterator_t<urng_t>;
47 
49  template <typename view_t>
50  friend class single_pass_input_iterator;
51 
53  struct state
54  {
56  urng_t urng;
58  urng_iterator_type cached_urng_iter = std::ranges::begin(urng);
59  };
60 
62  std::shared_ptr<state> state_ptr{};
63 
64 public:
68  using iterator = single_pass_input_iterator<single_pass_input_view>;
71  using const_iterator = void;
73  using sentinel = std::ranges::sentinel_t<urng_t>;
75  using value_type = typename iterator::value_type;
77  using reference = typename iterator::reference;
79  using const_reference = void;
80  //\}
81 
86  constexpr single_pass_input_view() = default;
89  constexpr single_pass_input_view(single_pass_input_view const &) = default;
91  constexpr single_pass_input_view(single_pass_input_view &&) = default;
93  constexpr single_pass_input_view & operator=(single_pass_input_view const &) = default;
95  constexpr single_pass_input_view & operator=(single_pass_input_view &&) = default;
97  ~single_pass_input_view() = default;
98 
100  explicit single_pass_input_view(urng_t _urng) :
101  state_ptr{new state{std::move(_urng)}}
102  {}
103 
105  template <typename other_urng_t>
107  requires !std::Same<remove_cvref_t<other_urng_t>, single_pass_input_view> &&
108  std::ranges::ViewableRange<other_urng_t> && // Must come after self type check to avoid conflicts with the move constructor.
111  explicit single_pass_input_view(other_urng_t && _urng) :
112  single_pass_input_view{std::view::all(_urng)}
113  {}
115 
126  iterator begin()
127  {
128  return iterator{*this};
129  }
130 
132  const_iterator begin() const = delete;
133 
135  const_iterator cbegin() const = delete;
136 
138  sentinel end()
139  {
140  return {seqan3::end(state_ptr->urng)};
141  }
142 
144  sentinel end() const = delete;
145 
147  sentinel cend() const = delete;
149 };
150 
156 template <std::ranges::ViewableRange urng_t>
158 single_pass_input_view(urng_t &&) ->
159  single_pass_input_view<std::ranges::all_view<urng_t>>;
161 } // seqan3::detail
162 
163 //-----------------------------------------------------------------------------
164 // Iterator for single pass input view.
165 //-----------------------------------------------------------------------------
166 
167 namespace seqan3::detail
168 {
176 template <typename view_type>
177 class single_pass_input_iterator<single_pass_input_view<view_type>>
178 {
180  using base_iterator_type = typename single_pass_input_view<view_type>::urng_iterator_type;
182  using sentinel_type = typename single_pass_input_view<view_type>::sentinel;
183 
185  single_pass_input_view<view_type> * view_ptr{};
186 
188  template <typename input_view_type>
189  friend class single_pass_input_iterator;
190 
193 
194 public:
195 
199  using difference_type = difference_type_t<base_iterator_type>;
202  using value_type = value_type_t<base_iterator_type>;
204  using pointer = typename std::iterator_traits<base_iterator_type>::pointer;
206  using reference = reference_t<base_iterator_type>;
208  using iterator_category = std::input_iterator_tag;
210 
214  single_pass_input_iterator() = default;
217  constexpr single_pass_input_iterator(single_pass_input_iterator const & rhs) = default;
219  constexpr single_pass_input_iterator(single_pass_input_iterator && rhs) = default;
221  constexpr single_pass_input_iterator & operator=(single_pass_input_iterator const & rhs) = default;
223  constexpr single_pass_input_iterator & operator=(single_pass_input_iterator && rhs) = default;
225  ~single_pass_input_iterator() = default;
226 
228  single_pass_input_iterator(single_pass_input_view<view_type> & view) noexcept : view_ptr{&view}
229  {}
231 
235  reference operator*() const noexcept
237  {
238  return *cached();
239  }
240 
242  pointer operator->() const noexcept
244  requires !std::is_void_v<pointer>
246  {
247  return std::addressof(*cached());
248  }
250 
254  single_pass_input_iterator & operator++() noexcept
256  {
257  ++cached();
258  return *this;
259  }
260 
262  auto operator++(int) noexcept
263  {
266  {
267  single_pass_input_iterator tmp{*this};
268  ++(*this);
269  return tmp;
270  }
271  else
272  {
273  ++(*this);
274  }
275  }
277 
281  constexpr bool operator==(sentinel_type const & s) const noexcept
283  {
284  return cached() == s;
285  }
286 
288  friend constexpr bool
289  operator==(sentinel_type const & s,
290  single_pass_input_iterator<single_pass_input_view<view_type>> const & rhs) noexcept
291  {
292  return rhs == s;
293  }
294 
296  constexpr bool operator!=(sentinel_type const & rhs) const noexcept
297  {
298  return !(*this == rhs);
299  }
300 
302  friend constexpr bool
303  operator!=(sentinel_type const & s,
304  single_pass_input_iterator<single_pass_input_view<view_type>> const & rhs) noexcept
305  {
306  return rhs != s;
307  }
309 
310 protected:
313  base_iterator_type & cached() const noexcept
314  {
315  return view_ptr->state_ptr->cached_urng_iter;
316  }
317 };
318 } // seqan3::detail
319 
320 //-----------------------------------------------------------------------------
321 // View shortcut for functor.
322 //-----------------------------------------------------------------------------
323 
325 namespace seqan3::view
326 {
381 inline constexpr auto single_pass_input = detail::adaptor_for_view_without_args<detail::single_pass_input_view>{};
382 
384 } // namespace seqan3::view
::ranges::cbegin cbegin
Alias for ranges::cbegin. Returns an iterator to the beginning of a range.
Definition: ranges:209
Specifies the requirements of a Range type that is either a std::ranges::View or an lvalue-reference...
T operator!=(T... args)
Provides C++20 additions to the <iterator> header.
Provides various shortcuts for common std::ranges functions.
SeqAn specific customisations in the standard namespace.
constexpr auto all
A view adaptor that behaves like std::view:all, but type erases contiguous ranges.
Definition: view_all.hpp:160
The concept std::CopyConstructible is satisfied if T is an lvalue reference type, or if it is a MoveC...
::ranges::view_interface< urng_t > view_interface
Alias for ranges::view_interface.
Definition: ranges:220
Provides various type traits.
The Sentinel concept specifies the relationship between an std::Iterator type and a std::Semiregular ...
The Concepts library.
Auxiliary header for the view submodule .
::ranges::iterator_t iterator_t
Alias for ranges::iterator_t. Obtains the iterator type of a range.
Definition: ranges:204
Adaptations of concepts from the Ranges TS.
::ranges::sentinel_t sentinel_t
Alias for ranges::sentinel_t. Obtains the sentinel type of a range.
Definition: ranges:199
::ranges::begin begin
Alias for ranges::begin. Returns an iterator to the beginning of a range.
Definition: ranges:174
The SeqAn3 namespace for views.
T addressof(T... args)
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:381
Definition: aligned_sequence_concept.hpp:35
The std::Constructible concept specifies that a variable of type T can be initialized with the given ...
The OutputIterator concept is a refinement of std::Iterator, adding the requirement that it can be us...
::ranges::cend cend
Alias for ranges::cend. Returns an iterator to the end of a range.
Definition: ranges:214
The concept std::Same<T, U> is satisfied if and only if T and U denote the same type.
Definition: ranges:347
::ranges::end end
Alias for ranges::end. Returns an iterator to the end of a range.
Definition: ranges:179