SeqAn3  3.0.1
The Modern C++ library for sequence analysis.
single_pass_input.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2020, 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_as<remove_cvref_t<other_urng_t>, single_pass_input_view> &&
108  std::ranges::viewable_range<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::views::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::viewable_range 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 
192  static_assert(std::sentinel_for<sentinel_type, base_iterator_type>);
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  {
264  if constexpr (std::output_iterator<base_iterator_type, reference> &&
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::views
326 {
378 inline constexpr auto single_pass_input = detail::adaptor_for_view_without_args<detail::single_pass_input_view>{};
379 
381 } // namespace seqan3::views
shortcuts.hpp
Provides various shortcuts for common std::ranges functions.
seqan3::views
The SeqAn namespace for views.
Definition: view_to_simd.hpp:672
std::shared_ptr
constructible_from
The std::constructible_from concept specifies that a variable of type T can be initialized with the g...
all.hpp
Provides various type traits.
std::rel_ops::operator!=
T operator!=(T... args)
iterator
Provides C++20 additions to the <iterator> header.
std::input_iterator_tag
seqan3::views::move
const auto move
A view that turns lvalue-references into rvalue-references.
Definition: move.hpp:68
concepts
The Concepts library.
same_as
The concept std::same_as<T, U> is satisfied if and only if T and U denote the same type.
std::addressof
T addressof(T... args)
std::iterator_traits
seqan3::search_cfg::all
constexpr detail::search_mode_all all
Configuration element to receive all hits within the error bounds.
Definition: mode.hpp:43
ranges
Adaptations of concepts from the Ranges TS.
copy_constructible
The concept std::copy_constructible is satisfied if T is an lvalue reference type,...
std::ranges::begin
T begin(T... args)
std
SeqAn specific customisations in the standard namespace.
std::end
T end(T... args)
detail.hpp
Auxiliary header for the views submodule .
seqan3::views::single_pass_input
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:378