SeqAn3  3.0.3
The Modern C++ library for sequence analysis.
alignment_matrix_column_major_range_base.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2021, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2021, 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 <seqan3/std/iterator>
16 #include <seqan3/std/ranges>
17 #include <seqan3/std/span>
18 
21 
22 namespace seqan3::detail
23 {
24 
60 template <typename derived_t>
61 class alignment_matrix_column_major_range_base
62 {
63 private:
65  friend derived_t;
66 
76  class alignment_column_type : public std::ranges::view_interface<alignment_column_type>
77  {
78  private:
80  using view_type = typename deferred_type<typename derived_t::column_data_view_type>::type;
81 
82  static_assert(std::ranges::random_access_range<view_type>, "Column view must support random access.");
83  static_assert(std::ranges::sized_range<view_type>, "Column view must be a sized range.");
84  static_assert(std::ranges::view<view_type>, "Column view must be a view.");
85 
87  using sentinel = std::ranges::sentinel_t<view_type>;
88 
98  class iterator_type
99  {
100  public:
101 
106  using value_type = typename deferred_type<typename derived_t::value_type>::type;
108  using reference = typename deferred_type<typename derived_t::reference>::type;
110  using pointer = void;
112  using difference_type = std::ranges::range_difference_t<view_type>;
114  using iterator_category = std::forward_iterator_tag;
116 
120  constexpr iterator_type() = default;
121  constexpr iterator_type(iterator_type const &) = default;
122  constexpr iterator_type(iterator_type &&) = default;
123  constexpr iterator_type & operator=(iterator_type const &) = default;
124  constexpr iterator_type & operator=(iterator_type &&) = default;
125  ~iterator_type() = default;
126 
130  explicit constexpr iterator_type(alignment_column_type & host) :
131  host_ptr{&host},
132  host_iter{host.ref.begin()}
133  {
134  host_ptr->me_ptr->on_column_iterator_creation(host_iter);
135  }
137 
142  constexpr reference operator*() const noexcept
143  {
144  static_assert(std::convertible_to<decltype(host_ptr->me_ptr->make_proxy(host_iter)), reference>,
145  "The returned type of make_proxy must be convertible to the reference type.");
146  assert(host_ptr != nullptr);
147  return host_ptr->me_ptr->make_proxy(host_iter);
148  }
150 
155  constexpr iterator_type & operator++() noexcept
156  {
157  assert(host_ptr != nullptr);
158  assert(host_ptr->me_ptr != nullptr);
159 
160  host_ptr->me_ptr->before_column_iterator_increment(host_iter);
161  ++host_iter;
162  host_ptr->me_ptr->after_column_iterator_increment(host_iter);
163  return *this;
164  }
165 
167  constexpr iterator_type operator++(int) noexcept
168  {
169  iterator_type tmp{*this};
170  ++(*this);
171  return tmp;
172  }
174 
179  constexpr bool operator==(sentinel const & rhs) const noexcept
180  {
181  return host_iter == rhs;
182  }
183 
185  friend constexpr bool operator==(sentinel const & lhs, iterator_type const & rhs) noexcept
186  {
187  return rhs == lhs;
188  }
189 
191  constexpr bool operator==(iterator_type const & rhs) const noexcept
192  {
193  return (host_ptr == rhs.host_ptr) && (host_iter == rhs.host_iter);
194  }
195 
197  constexpr bool operator!=(sentinel const & rhs) const noexcept
198  {
199  return !(*this == rhs);
200  }
201 
203  friend constexpr bool operator!=(sentinel const & lhs, iterator_type const & rhs) noexcept
204  {
205  return rhs != lhs;
206  }
207 
209  constexpr bool operator!=(iterator_type const & rhs) const noexcept
210  {
211  return !(*this == rhs);
212  }
214 
215  private:
217  alignment_column_type * host_ptr{nullptr};
219  std::ranges::iterator_t<view_type> host_iter{};
220  }; // class iterator_type
221 
222  public:
226  constexpr alignment_column_type() = default;
227  constexpr alignment_column_type(alignment_column_type const &) = default;
228  constexpr alignment_column_type(alignment_column_type &&) = default;
229  constexpr alignment_column_type & operator=(alignment_column_type const &) = default;
230  constexpr alignment_column_type & operator=(alignment_column_type &&) = default;
231  ~alignment_column_type() = default;
232 
241  constexpr alignment_column_type(derived_t & me, view_type ref) :
242  ref{std::move(ref)},
243  me_ptr{&me}
244  {}
246 
252  constexpr iterator_type begin() noexcept
253  {
254  assert(me_ptr != nullptr);
255  return iterator_type{*this};
256  }
257 
259  constexpr auto begin() const noexcept = delete; // Not needed by the alignment algorithm
260 
262  constexpr sentinel end() noexcept
263  {
264  return ref.end();
265  }
266 
268  constexpr sentinel end() const noexcept = delete; // Not needed by the alignment algorithm
270 
272  constexpr size_t size() const noexcept
273  {
274  return std::ranges::size(ref);
275  }
276 
277  private:
279  view_type ref{};
281  derived_t * me_ptr{};
282  }; // class alignment_column_type
283 
296  class iterator_type
297  {
298  public:
303  using value_type = alignment_column_type;
305  using reference = value_type;
307  using pointer = void;
309  using difference_type = std::ranges::range_difference_t<alignment_column_type>;
311  using iterator_category = std::input_iterator_tag;
313 
317  constexpr iterator_type() = default;
318  constexpr iterator_type(iterator_type const &) = default;
319  constexpr iterator_type(iterator_type &&) = default;
320  constexpr iterator_type & operator=(iterator_type const &) = default;
321  constexpr iterator_type & operator=(iterator_type &&) = default;
322  ~iterator_type() = default;
323 
327  explicit constexpr iterator_type(derived_t & me) :
328  me_ptr{&me},
329  column_index{0}
330  {}
332 
337  constexpr reference operator*() const noexcept
338  {
339  static_assert(std::convertible_to<decltype(me_ptr->initialise_column(column_index)), reference>,
340  "The returned type of initialise_column must be convertible to the reference type.");
341  return me_ptr->initialise_column(column_index);
342  }
344 
349  constexpr iterator_type & operator++() noexcept
350  {
351  ++column_index;
352  return *this;
353  }
354 
356  constexpr void operator++(int) noexcept
357  {
358  ++(*this);
359  }
361 
366  constexpr bool operator==(std::default_sentinel_t const &) const noexcept
367  {
368  return column_index == me_ptr->num_cols;
369  }
370 
372  friend constexpr bool operator==(std::default_sentinel_t const & lhs, iterator_type const & rhs) noexcept
373  {
374  return rhs == lhs;
375  }
376 
378  constexpr bool operator!=(std::default_sentinel_t const & rhs) const noexcept
379  {
380  return !(*this == rhs);
381  }
382 
384  friend constexpr bool operator!=(std::default_sentinel_t const & lhs, iterator_type const & rhs) noexcept
385  {
386  return rhs != lhs;
387  }
389 
390  private:
392  derived_t * me_ptr;
394  size_t column_index{};
395  }; // class iterator_type
396 
401  constexpr alignment_matrix_column_major_range_base() = default;
403  constexpr alignment_matrix_column_major_range_base(alignment_matrix_column_major_range_base const &) = default;
405  constexpr alignment_matrix_column_major_range_base(alignment_matrix_column_major_range_base &&) = default;
407  constexpr alignment_matrix_column_major_range_base &
408  operator=(alignment_matrix_column_major_range_base const &) = default;
410  constexpr alignment_matrix_column_major_range_base &
411  operator=(alignment_matrix_column_major_range_base &&) = default;
413  ~alignment_matrix_column_major_range_base() = default;
415 
423  SEQAN3_DOXYGEN_ONLY(typedef /*IMPLEMENTATION_DEFINED*/ value_type;)
424 
428  SEQAN3_DOXYGEN_ONLY(typedef /*IMPLEMENTATION_DEFINED*/ column_data_view_type;)
430 
440  SEQAN3_DOXYGEN_ONLY(value_type make_proxy(iter_t host_iter) noexcept {})
441 
454  SEQAN3_DOXYGEN_ONLY(alignment_column_type initialise_column(size_t column_index) {})
455 
460  template <typename iter_t>
461  constexpr void on_column_iterator_creation(iter_t SEQAN3_DOXYGEN_ONLY(host_iter)) noexcept
462  {}
463 
468  template <typename iter_t>
469  constexpr void before_column_iterator_increment(iter_t SEQAN3_DOXYGEN_ONLY(host_iter)) noexcept
470  {}
471 
476  template <typename iter_t>
477  constexpr void after_column_iterator_increment(iter_t SEQAN3_DOXYGEN_ONLY(host_iter)) noexcept
478  {}
480 
482  using iterator = iterator_type;
484  using sentinel = std::default_sentinel_t;
485 
486 public:
492  constexpr iterator begin() noexcept
493  {
494  return iterator{static_cast<derived_t &>(*this)};
495  }
496 
498  constexpr iterator begin() const noexcept = delete; // not needed for the alignment algorithm
499 
501  constexpr sentinel end() noexcept
502  {
503  return std::default_sentinel;
504  }
505 
507  constexpr sentinel end() const noexcept = delete; // not needed for the alignment algorithm
509 };
510 } // namespace seqan3::detail
T begin(T... args)
Provides various transformation traits used by the range module.
T end(T... args)
constexpr size_t size
The size of a type pack.
Definition: traits.hpp:151
auto const move
A view that turns lvalue-references into rvalue-references.
Definition: move.hpp:74
Provides C++20 additions to the <iterator> header.
SeqAn specific customisations in the standard namespace.
T operator!=(T... args)
Adaptations of concepts from the Ranges TS.
T ref(T... args)
Provides std::span from the C++20 standard library.
Provides various type traits on generic types.