SeqAn3
single_pass_input.hpp
Go to the documentation of this file.
1 // ============================================================================
2 // SeqAn - The Library for Sequence Analysis
3 // ============================================================================
4 //
5 // Copyright (c) 2006-2018, Knut Reinert & Freie Universitaet Berlin
6 // Copyright (c) 2016-2018, Knut Reinert & MPI Molekulare Genetik
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // * Redistributions of source code must retain the above copyright
13 // notice, this list of conditions and the following disclaimer.
14 // * Redistributions in binary form must reproduce the above copyright
15 // notice, this list of conditions and the following disclaimer in the
16 // documentation and/or other materials provided with the distribution.
17 // * Neither the name of Knut Reinert or the FU Berlin nor the names of
18 // its contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 // ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
25 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31 // DAMAGE.
32 //
33 // ============================================================================
34 
40 #pragma once
41 
45 #include <seqan3/std/concepts>
46 #include <seqan3/std/iterator>
47 #include <seqan3/std/ranges>
48 
49 //-----------------------------------------------------------------------------
50 // Implementation of single pass input view.
51 //-----------------------------------------------------------------------------
52 
53 namespace seqan3::detail
54 {
55 
57 template <typename view_t>
58 class single_pass_input_iterator;
59 
65 template <std::ranges::InputRange urng_t>
66 class single_pass_input_view : public detail::view_base
67 {
68 private:
69 
71  using pure_range_type = std::remove_reference_t<urng_t>;
73  using urng_iterator_type = std::ranges::iterator_t<pure_range_type>;
74 
76  template <typename view_t>
77  friend class single_pass_input_iterator;
78 
80  struct view_state
81  {
83  urng_t urng;
85  urng_iterator_type cached_urng_iter{};
86  };
87 
89  std::shared_ptr<view_state> view_state_ptr{};
90 
91 public:
95  using iterator = single_pass_input_iterator<single_pass_input_view>;
98  using const_iterator = void;
102  using value_type = typename iterator::value_type;
104  using reference = typename iterator::reference;
106  using const_reference = void;
107  //\}
108 
113  constexpr single_pass_input_view() = default;
114  constexpr single_pass_input_view(single_pass_input_view const &) = default;
115  constexpr single_pass_input_view(single_pass_input_view &&) = default;
116  constexpr single_pass_input_view & operator=(single_pass_input_view const &) = default;
117  constexpr single_pass_input_view & operator=(single_pass_input_view &&) = default;
118  ~single_pass_input_view() = default;
119 
121  single_pass_input_view(urng_t && urng) :
122  view_state_ptr{new view_state{std::forward<urng_t>(urng), seqan3::begin(urng)}}
123  {}
125 
136  iterator begin()
137  {
138  return iterator{*this};
139  }
140 
142  const_iterator begin() const = delete;
143 
145  const_iterator cbegin() const = delete;
146 
148  sentinel end()
149  {
150  return {seqan3::end(view_state_ptr->urng)};
151  }
152 
154  sentinel end() const = delete;
155 
157  sentinel cend() const = delete;
159 };
160 
165 template <std::ranges::InputRange urng_t>
167 single_pass_input_view(urng_t &&) -> single_pass_input_view<urng_t>;
169 } // seqan3::detail
170 
171 //-----------------------------------------------------------------------------
172 // Iterator for single pass input view.
173 //-----------------------------------------------------------------------------
174 
175 namespace seqan3::detail
176 {
184 template <typename view_type>
185 class single_pass_input_iterator<single_pass_input_view<view_type>>
186 {
188  using base_iterator_type = typename single_pass_input_view<view_type>::urng_iterator_type;
190  using sentinel_type = typename single_pass_input_view<view_type>::sentinel;
191 
193  single_pass_input_view<view_type> * view_ptr{};
194 
196  template <typename input_view_type>
197  friend class single_pass_input_iterator;
198 
201 
202 public:
203 
207  using difference_type = difference_type_t<base_iterator_type>;
210  using value_type = value_type_t<base_iterator_type>;
212  using pointer = typename std::iterator_traits<base_iterator_type>::pointer;
214  using reference = reference_t<base_iterator_type>;
216  using iterator_category = std::input_iterator_tag;
218 
222  single_pass_input_iterator() = default;
225  constexpr single_pass_input_iterator(single_pass_input_iterator const & rhs) = default;
227  constexpr single_pass_input_iterator(single_pass_input_iterator && rhs) = default;
229  constexpr single_pass_input_iterator & operator=(single_pass_input_iterator const & rhs) = default;
231  constexpr single_pass_input_iterator & operator=(single_pass_input_iterator && rhs) = default;
233  ~single_pass_input_iterator() = default;
234 
236  single_pass_input_iterator(single_pass_input_view<view_type> & view) noexcept : view_ptr{&view}
237  {}
239 
243  reference operator*() const noexcept
245  {
246  return *cached();
247  }
249 
253  single_pass_input_iterator & operator++() noexcept
255  {
256  ++cached();
257  return *this;
258  }
259 
261  void operator++(int) noexcept
262  {
263  ++(*this);
264  }
266 
270  constexpr bool operator==(sentinel_type const & s) const noexcept
272  {
273  return cached() == s;
274  }
275 
277  constexpr bool operator!=(sentinel_type const & rhs) const noexcept
278  {
279  return !(*this == rhs);
280  }
281 
283  friend constexpr bool
284  operator==(sentinel_type const & s,
285  single_pass_input_iterator<single_pass_input_view<view_type>> const & rhs) noexcept
286  {
287  return rhs == s;
288  }
289 
291  friend constexpr bool
292  operator!=(sentinel_type const & s,
293  single_pass_input_iterator<single_pass_input_view<view_type>> const & rhs) noexcept
294  {
295  return rhs != s;
296  }
298 
299 protected:
302  base_iterator_type & cached() const noexcept
303  {
304  return view_ptr->view_state_ptr->cached_urng_iter;
305  }
306 };
307 } // seqan3::detail
308 
309 //-----------------------------------------------------------------------------
310 // View shortcut for functor.
311 //-----------------------------------------------------------------------------
312 
313 namespace seqan3::view
314 {
364 inline constexpr auto single_pass_input = detail::generic_pipable_view_adaptor<detail::single_pass_input_view>{};
365 
367 } // namespace seqan3::view
::ranges::cbegin cbegin
Alias for ranges::cbegin. Returns an iterator to the beginning of a range.
Definition: ranges:245
Provides C++20 additions to the <iterator> header.
Contains various shortcuts for common std::ranges functions.
The Sentinel concept specifies the relationship between an std::Iterator type and a std::Semiregular ...
Provides various metafunctions.
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:225
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:220
::ranges::begin begin
Alias for ranges::begin. Returns an iterator to the beginning of a range.
Definition: ranges:185
The SeqAn3 namespace for views.
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:364
Definition: aligned_sequence_concept.hpp:288
::ranges::cend cend
Alias for ranges::cend. Returns an iterator to the end of a range.
Definition: ranges:250
::ranges::end end
Alias for ranges::end. Returns an iterator to the end of a range.
Definition: ranges:190