SeqAn3
alignment_range.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 
42 #include <range/v3/utility/iterator.hpp>
43 
44 #include <seqan3/std/concepts>
45 #include <seqan3/std/ranges>
46 
47 namespace seqan3
48 {
49 
59 template <typename range_buffer_t>
61 {
62  static_assert(!std::is_const_v<range_buffer_t>,
63  "Cannot create an alignment stream over a const buffer.");
64 
66  class iterator_type
67  {
68  public:
72  using value_type = typename alignment_range::value_type;
74  using reference = typename alignment_range::reference;
76  using const_reference = std::add_const_t<reference>;
78  using pointer = std::add_pointer_t<value_type>;
80  using iterator_category = std::input_iterator_tag;
81 
85  iterator_type() = default;
86  iterator_type(iterator_type const &) = default;
87  iterator_type(iterator_type &&) = default;
88  iterator_type & operator=(iterator_type const &) = default;
89  iterator_type & operator=(iterator_type &&) = default;
90  ~iterator_type() = default;
91 
93  iterator_type(alignment_range & _stream) : stream_ptr(&_stream)
94  {}
96 
100  reference operator*()
101  {
102  return stream_ptr->cached();
103  }
104 
105  const_reference operator*() const
106  {
107  return stream_ptr->cached();
108  }
110 
114  iterator_type & operator++(/*pre*/)
115  {
116  stream_ptr->next();
117  return *this;
118  }
119 
120  iterator_type operator++(int /*post*/)
121  {
122  auto tmp{*this};
123  stream_ptr->next();
124  return tmp;
125  }
127 
132  constexpr bool operator==(std::ranges::default_sentinel const &) const
133  {
134  return stream_ptr->eof();
135  }
136 
137  friend constexpr bool operator==(std::ranges::default_sentinel const & lhs,
138  iterator_type const & rhs)
139  {
140  return rhs == lhs;
141  }
142 
143  constexpr bool operator!=(std::ranges::default_sentinel const & rhs) const
144  {
145  return !(*this == rhs);
146  }
147 
148  friend constexpr bool operator!=(std::ranges::default_sentinel const & lhs,
149  iterator_type const & rhs)
150  {
151  return rhs != lhs;
152  }
154  private:
156  alignment_range * stream_ptr{};
157  };
158 
159  // Befriend the iterator with this class.
160  friend class iterator_type;
161 
162 public:
163 
165  using difference_type = typename range_buffer_t::difference_type;
167  using value_type = typename range_buffer_t::value_type;
169  using reference = typename range_buffer_t::reference;
171  using iterator = iterator_type;
174 
178  alignment_range() = delete;
179  alignment_range(alignment_range const &) = default;
180  alignment_range(alignment_range &&) = default;
181  alignment_range & operator=(alignment_range const &) = default;
182  alignment_range & operator=(alignment_range &&) = default;
183  ~alignment_range() = default;
184 
185  explicit alignment_range(range_buffer_t & _range_buffer) :
186  range_buffer{&_range_buffer, [](auto) { /*no-op*/ }}
187  {}
188 
189  // Construct from resource.
190  template <typename resource_t,
191  typename selector_t>
193  requires std::is_constructible_v<range_buffer_t, resource_t, selector_t>
195  explicit alignment_range(resource_t _range_buffer_resource,
196  selector_t _selector) :
197  range_buffer{std::make_shared<range_buffer_t>(std::forward<resource_t>(_range_buffer_resource), _selector)}
198  {}
200 
204  iterator begin()
205  {
206  next();
207  return iterator{*this};
208  }
209 
210  sentinel end() noexcept
211  {
212  return {};
213  }
215 
216 protected:
217 
219  void next()
220  {
221  assert(!eof());
222  if (auto opt = range_buffer->bump(); opt.has_value())
223  cache = &(*opt).get();
224  else
225  eof_flag = true;
226  }
227 
229  // TODO make iterable in case of multiple results per alignment.
230  auto & cached() noexcept
231  {
232  assert(cache);
233  return *cache;
234  }
235 
237  auto const & cached() const noexcept
238  {
239  assert(cache);
240  return *cache;
241  }
242 
244  constexpr bool eof() const noexcept
245  {
246  return eof_flag;
247  }
248 
249 private:
251  std::shared_ptr<range_buffer_t> range_buffer;
253  value_type * cache{};
255  bool eof_flag{false};
256 };
257 
258 } // namespace seqan3
typename range_buffer_t::value_type value_type
The alignment result type.
Definition: alignment_range.hpp:167
auto & cached() noexcept
Returns the cached result.
Definition: alignment_range.hpp:230
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:58
The Concepts library.
Adaptations of concepts from the Ranges TS.
auto const & cached() const noexcept
Returns the cached result.
Definition: alignment_range.hpp:237
::ranges::begin begin
Alias for ranges::begin. Returns an iterator to the beginning of a range.
Definition: ranges:185
void next()
Receives the next alignment result from the executor buffer.
Definition: alignment_range.hpp:219
constexpr bool eof() const noexcept
Returns whether the executor buffer reached is end.
Definition: alignment_range.hpp:244
Type metafunction that returns the const_reference of another type [metafunction declaration].
Definition: pre.hpp:146
typename range_buffer_t::difference_type difference_type
The offset type.
Definition: alignment_range.hpp:165
std::ranges::default_sentinel sentinel
The sentinel type.
Definition: alignment_range.hpp:173
::ranges::end end
Alias for ranges::end. Returns an iterator to the end of a range.
Definition: ranges:190
iterator_type iterator
The iterator type.
Definition: alignment_range.hpp:171
::ranges::default_sentinel default_sentinel
Alias for ranges::default_sentinel. Empty sentinel type for use with iterator types that know the bou...
Definition: ranges:215
The alignment.
Definition: alignment_range.hpp:60
typename range_buffer_t::reference reference
The reference type.
Definition: alignment_range.hpp:169