SeqAn3  3.2.0
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-2022, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2022, 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 <cassert>
16 #include <iterator>
17 #include <ranges>
18 #include <span>
19 
22 
23 namespace seqan3::detail
24 {
25 
61 template <typename derived_t>
62 class alignment_matrix_column_major_range_base
63 {
64 private:
66  friend derived_t;
67 
77  class alignment_column_type : public std::ranges::view_interface<alignment_column_type>
78  {
79  private:
81  using view_type = typename deferred_type<typename derived_t::column_data_view_type>::type;
82 
83  static_assert(std::ranges::random_access_range<view_type>, "Column view must support random access.");
84  static_assert(std::ranges::sized_range<view_type>, "Column view must be a sized range.");
85  static_assert(std::ranges::view<view_type>, "Column view must be a view.");
86 
88  using sentinel = std::ranges::sentinel_t<view_type>;
89 
99  class iterator_type
100  {
101  public:
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) : ref{std::move(ref)}, me_ptr{&me}
242  {}
244 
250  constexpr iterator_type begin() noexcept
251  {
252  assert(me_ptr != nullptr);
253  return iterator_type{*this};
254  }
255 
257  constexpr auto begin() const noexcept = delete; // Not needed by the alignment algorithm
258 
260  constexpr sentinel end() noexcept
261  {
262  return ref.end();
263  }
264 
266  constexpr sentinel end() const noexcept = delete; // Not needed by the alignment algorithm
268 
270  constexpr size_t size() const noexcept
271  {
272  return std::ranges::size(ref);
273  }
274 
275  private:
277  view_type ref{};
279  derived_t * me_ptr{};
280  }; // class alignment_column_type
281 
294  class iterator_type
295  {
296  public:
301  using value_type = alignment_column_type;
303  using reference = value_type;
305  using pointer = void;
307  using difference_type = std::ranges::range_difference_t<alignment_column_type>;
309  using iterator_category = std::input_iterator_tag;
311 
315  constexpr iterator_type() = default;
316  constexpr iterator_type(iterator_type const &) = default;
317  constexpr iterator_type(iterator_type &&) = default;
318  constexpr iterator_type & operator=(iterator_type const &) = default;
319  constexpr iterator_type & operator=(iterator_type &&) = default;
320  ~iterator_type() = default;
321 
325  explicit constexpr iterator_type(derived_t & me) : me_ptr{&me}, column_index{0}
326  {}
328 
333  constexpr reference operator*() const noexcept
334  {
335  static_assert(std::convertible_to<decltype(me_ptr->initialise_column(column_index)), reference>,
336  "The returned type of initialise_column must be convertible to the reference type.");
337  return me_ptr->initialise_column(column_index);
338  }
340 
345  constexpr iterator_type & operator++() noexcept
346  {
347  ++column_index;
348  return *this;
349  }
350 
352  constexpr void operator++(int) noexcept
353  {
354  ++(*this);
355  }
357 
362  constexpr bool operator==(std::default_sentinel_t const &) const noexcept
363  {
364  return column_index == me_ptr->num_cols;
365  }
366 
368  friend constexpr bool operator==(std::default_sentinel_t const & lhs, iterator_type const & rhs) noexcept
369  {
370  return rhs == lhs;
371  }
372 
374  constexpr bool operator!=(std::default_sentinel_t const & rhs) const noexcept
375  {
376  return !(*this == rhs);
377  }
378 
380  friend constexpr bool operator!=(std::default_sentinel_t const & lhs, iterator_type const & rhs) noexcept
381  {
382  return rhs != lhs;
383  }
385 
386  private:
388  derived_t * me_ptr;
390  size_t column_index{};
391  }; // class iterator_type
392 
397  constexpr alignment_matrix_column_major_range_base() = default;
399  constexpr alignment_matrix_column_major_range_base(alignment_matrix_column_major_range_base const &) = default;
401  constexpr alignment_matrix_column_major_range_base(alignment_matrix_column_major_range_base &&) = default;
403  constexpr alignment_matrix_column_major_range_base &
404  operator=(alignment_matrix_column_major_range_base const &) = default;
406  constexpr alignment_matrix_column_major_range_base &
407  operator=(alignment_matrix_column_major_range_base &&) = default;
409  ~alignment_matrix_column_major_range_base() = default;
411 
419  SEQAN3_DOXYGEN_ONLY(typedef /*IMPLEMENTATION_DEFINED*/ value_type;)
420 
424  SEQAN3_DOXYGEN_ONLY(typedef /*IMPLEMENTATION_DEFINED*/ column_data_view_type;)
426 
436  SEQAN3_DOXYGEN_ONLY(value_type make_proxy(iter_t host_iter) noexcept {})
437 
450  SEQAN3_DOXYGEN_ONLY(alignment_column_type initialise_column(size_t column_index){})
451 
456  template <typename iter_t>
457  constexpr void on_column_iterator_creation(iter_t SEQAN3_DOXYGEN_ONLY(host_iter)) noexcept
458  {}
459 
464  template <typename iter_t>
465  constexpr void before_column_iterator_increment(iter_t SEQAN3_DOXYGEN_ONLY(host_iter)) noexcept
466  {}
467 
472  template <typename iter_t>
473  constexpr void after_column_iterator_increment(iter_t SEQAN3_DOXYGEN_ONLY(host_iter)) noexcept
474  {}
476 
478  using iterator = iterator_type;
480  using sentinel = std::default_sentinel_t;
481 
482 public:
488  constexpr iterator begin() noexcept
489  {
490  return iterator{static_cast<derived_t &>(*this)};
491  }
492 
494  constexpr iterator begin() const noexcept = delete; // not needed for the alignment algorithm
495 
497  constexpr sentinel end() noexcept
498  {
499  return std::default_sentinel;
500  }
501 
503  constexpr sentinel end() const noexcept = delete; // not needed for the alignment algorithm
505 };
506 } // namespace seqan3::detail
Provides various type traits on generic types.
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: type_pack/traits.hpp:146
SeqAn specific customisations in the standard namespace.
T operator!=(T... args)
The <ranges> header from C++20's standard library.
T ref(T... args)
Provides std::span from the C++20 standard library.