SeqAn3  3.0.1
The Modern C++ library for sequence analysis.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
two_dimensional_matrix_iterator_base.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 
15 #include <type_traits>
16 
20 #include <seqan3/std/concepts>
21 #include <seqan3/std/ranges>
22 
23 namespace seqan3::detail
24 {
25 
38 enum struct matrix_major_order : uint8_t
39 {
40  column,
41  row
42 };
43 
75 template <typename derived_t, matrix_major_order order>
76 class two_dimensional_matrix_iterator_base
77 {
78 private:
80  friend derived_t;
81 
83  template <typename other_derived_t, matrix_major_order other_order>
84  requires order == other_order
85  friend class two_dimensional_matrix_iterator_base;
86 
90  constexpr two_dimensional_matrix_iterator_base() = default;
93  constexpr two_dimensional_matrix_iterator_base(two_dimensional_matrix_iterator_base const &) = default;
95  constexpr two_dimensional_matrix_iterator_base(two_dimensional_matrix_iterator_base &&) = default;
97  constexpr two_dimensional_matrix_iterator_base & operator=(two_dimensional_matrix_iterator_base const &) = default;
99  constexpr two_dimensional_matrix_iterator_base & operator=(two_dimensional_matrix_iterator_base &&) = default;
101  ~two_dimensional_matrix_iterator_base() = default;
103 
105  template <typename _derived_t>
106  using difference_type = typename _derived_t::difference_type;
107 
109  template <typename _derived_t>
110  using reference = typename _derived_t::reference;
111 
113  template <typename _derived_t>
114  using pointer = typename _derived_t::pointer;
115 
116 public:
117 
121  template <typename dummy_t = derived_t>
123  constexpr reference<dummy_t> operator*() const noexcept
124  {
125  return *as_derived().host_iter;
126  }
127 
129  template <typename dummy_t = derived_t>
130  constexpr reference<dummy_t> operator[](difference_type<dummy_t> const offset) const noexcept
131  {
132  return *(as_derived() + offset);
133  }
134 
136  template <typename dummy_t = derived_t>
137  constexpr reference<dummy_t> operator[](matrix_offset const & offset) const noexcept
138  {
139  return *(as_derived() + offset);
140  }
141 
143  template <typename dummy_t = derived_t>
144  constexpr pointer<dummy_t> operator->() const noexcept
145  {
146  return std::addressof(*as_derived().host_iter);
147  }
148 
159  SEQAN3_DOXYGEN_ONLY(constexpr seqan3::detail::matrix_coordinate coordinate() const noexcept {})
161 
180  SEQAN3_DOXYGEN_ONLY(constexpr derived_t & operator+=(matrix_offset const & offset) noexcept {})
181 
183  constexpr derived_t & operator++() noexcept
184  {
185  if constexpr (order == matrix_major_order::column)
186  return as_derived() += matrix_offset{row_index_type{1}, column_index_type{0}};
187  else
188  return as_derived() += matrix_offset{row_index_type{0}, column_index_type{1}};
189  }
190 
192  constexpr derived_t operator++(int) noexcept
193  {
194  derived_t previous{as_derived()};
195  ++(*this);
196  return previous;
197  }
198 
200  template <typename dummy_t = derived_t>
201  constexpr derived_t & operator+=(difference_type<dummy_t> const offset) noexcept
202  {
203  if constexpr (order == matrix_major_order::column)
204  return as_derived() += matrix_offset{row_index_type{offset}, column_index_type{0}};
205  else
206  return as_derived() += matrix_offset{row_index_type{0}, column_index_type{offset}};
207  }
208 
210  template <typename dummy_t = derived_t>
211  constexpr derived_t operator+(difference_type<dummy_t> const offset) const noexcept
212  {
213  derived_t next{as_derived()};
214  next += offset;
215  return next;
216  }
217 
219  template <typename dummy_t = derived_t>
220  constexpr friend derived_t operator+(difference_type<dummy_t> const offset, derived_t const iter)
221  {
222  return iter + offset;
223  }
224 
226  constexpr derived_t operator+(matrix_offset const & offset) const noexcept
227  {
228  derived_t next{as_derived()};
229  next += offset;
230  return next;
231  }
232 
234  constexpr friend derived_t operator+(matrix_offset const & offset, derived_t const iter)
235  {
236  return iter + offset;
237  }
238 
240  constexpr derived_t & operator--() noexcept
241  {
242  if constexpr (order == matrix_major_order::column)
243  return as_derived() += matrix_offset{row_index_type{-1}, column_index_type{0}};
244  else
245  return as_derived() += matrix_offset{row_index_type{0}, column_index_type{-1}};
246  }
247 
249  constexpr derived_t operator--(int) noexcept
250  {
251  derived_t previous{as_derived()};
252  --(*this);
253  return previous;
254  }
255 
257  template <typename dummy_t = derived_t>
258  constexpr derived_t & operator-=(difference_type<dummy_t> const offset) noexcept
259  {
260  return *this += -offset;
261  }
262 
264  template <typename dummy_t = derived_t>
265  constexpr derived_t operator-(difference_type<dummy_t> const offset) const noexcept
266  {
267  derived_t next{as_derived()};
268  next -= offset;
269  return next;
270  }
271 
273  constexpr derived_t & operator-=(matrix_offset const & offset) noexcept
274  {
275  return as_derived() += matrix_offset{row_index_type{-offset.row}, column_index_type{-offset.col}};
276  }
277 
279  constexpr derived_t operator-(matrix_offset const & offset) const noexcept
280  {
281  derived_t next{as_derived()};
282  next -= offset;
283  return next;
284  }
285 
287  template <typename dummy_t = derived_t>
288  constexpr difference_type<dummy_t> operator-(derived_t const rhs) const noexcept
289  {
290  return as_derived().host_iter - rhs.host_iter;
291  }
293 
297  // What if the derived type is different?
299  // How can make sure this is the same type?
300  template <typename other_derived_t>
304  constexpr bool operator==(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
305  {
306  return as_derived().host_iter == rhs.as_derived().host_iter;
307  }
308 
310  template <typename other_derived_t>
314  constexpr bool operator!=(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
315  {
316  return !(*this == rhs);
317  }
318 
320  template <typename other_derived_t>
324  constexpr bool operator<(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
325  {
326  return as_derived().host_iter < rhs.as_derived().host_iter;
327  }
328 
330  template <typename other_derived_t>
334  constexpr bool operator<=(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
335  {
336  return as_derived().host_iter <= rhs.as_derived().host_iter;
337  }
338 
340  template <typename other_derived_t>
344  constexpr bool operator>(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
345  {
346  return as_derived().host_iter > rhs.as_derived().host_iter;
347  }
348 
350  template <typename other_derived_t>
354  constexpr bool operator>=(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
355  {
356  return as_derived().host_iter >= rhs.as_derived().host_iter;
357  }
359 private:
360 
362  constexpr derived_t & as_derived()
363  {
364  return static_cast<derived_t &>(*this);
365  }
366 
368  constexpr derived_t const & as_derived() const
369  {
370  return static_cast<derived_t const &>(*this);
371  }
372 
373  // matrix_iterator_t host_iter{}; //!< The wrapped matrix iterator.
374 };
375 } // namespace seqan3::detail
matrix_coordinate.hpp
Provides seqan3::detail::alignment_coordinate and associated strong types.
seqan3::field::offset
Sequence (SEQ) relative start position (0-based), unsigned value.
constructible_from
The std::constructible_from concept specifies that a variable of type T can be initialized with the g...
std::rel_ops::operator!=
T operator!=(T... args)
basic.hpp
Provides various type traits on generic types.
concepts
The Concepts library.
std::addressof
T addressof(T... args)
iterator.hpp
Provides various transformation traits for use on iterators.
ranges
Adaptations of concepts from the Ranges TS.
std::next
T next(T... args)