SeqAn3  3.0.2
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>
85  requires (order == other_order)
87  friend class two_dimensional_matrix_iterator_base;
88 
92  constexpr two_dimensional_matrix_iterator_base() = default;
95  constexpr two_dimensional_matrix_iterator_base(two_dimensional_matrix_iterator_base const &) = default;
97  constexpr two_dimensional_matrix_iterator_base(two_dimensional_matrix_iterator_base &&) = default;
99  constexpr two_dimensional_matrix_iterator_base & operator=(two_dimensional_matrix_iterator_base const &) = default;
101  constexpr two_dimensional_matrix_iterator_base & operator=(two_dimensional_matrix_iterator_base &&) = default;
103  ~two_dimensional_matrix_iterator_base() = default;
105 
107  template <typename _derived_t>
108  using difference_type = typename _derived_t::difference_type;
109 
111  template <typename _derived_t>
112  using reference = typename _derived_t::reference;
113 
115  template <typename _derived_t>
116  using pointer = typename _derived_t::pointer;
117 
118 public:
119 
123  template <typename dummy_t = derived_t>
125  constexpr reference<dummy_t> operator*() const noexcept
126  {
127  return *as_derived().host_iter;
128  }
129 
131  template <typename dummy_t = derived_t>
132  constexpr reference<dummy_t> operator[](std::iter_difference_t<dummy_t> const offset) const noexcept
133  {
134  return *(as_derived() + offset);
135  }
136 
138  template <typename dummy_t = derived_t>
139  constexpr reference<dummy_t> operator[](matrix_offset const & offset) const noexcept
140  {
141  return *(as_derived() + offset);
142  }
143 
145  template <typename dummy_t = derived_t>
146  constexpr pointer<dummy_t> operator->() const noexcept
147  {
148  return std::addressof(*as_derived().host_iter);
149  }
150 
161  SEQAN3_DOXYGEN_ONLY(constexpr seqan3::detail::matrix_coordinate coordinate() const noexcept {})
163 
182  SEQAN3_DOXYGEN_ONLY(constexpr derived_t & operator+=(matrix_offset const & offset) noexcept {})
183 
185  constexpr derived_t & operator++() noexcept
186  {
187  if constexpr (order == matrix_major_order::column)
188  return as_derived() += matrix_offset{row_index_type{1}, column_index_type{0}};
189  else
190  return as_derived() += matrix_offset{row_index_type{0}, column_index_type{1}};
191  }
192 
194  constexpr derived_t operator++(int) noexcept
195  {
196  derived_t previous{as_derived()};
197  ++(*this);
198  return previous;
199  }
200 
202  template <typename dummy_t = derived_t>
203  constexpr derived_t & operator+=(std::iter_difference_t<dummy_t> const offset) noexcept
204  {
205  if constexpr (order == matrix_major_order::column)
206  return as_derived() += matrix_offset{row_index_type{offset}, column_index_type{0}};
207  else
208  return as_derived() += matrix_offset{row_index_type{0}, column_index_type{offset}};
209  }
210 
212  template <typename dummy_t = derived_t>
213  constexpr derived_t operator+(std::iter_difference_t<dummy_t> const offset) const noexcept
214  {
215  derived_t next{as_derived()};
216  next += offset;
217  return next;
218  }
219 
221  template <typename dummy_t = derived_t>
222  constexpr friend derived_t operator+(std::iter_difference_t<dummy_t> const offset, derived_t const iter)
223  {
224  return iter + offset;
225  }
226 
228  constexpr derived_t operator+(matrix_offset const & offset) const noexcept
229  {
230  derived_t next{as_derived()};
231  next += offset;
232  return next;
233  }
234 
236  constexpr friend derived_t operator+(matrix_offset const & offset, derived_t const iter)
237  {
238  return iter + offset;
239  }
240 
242  constexpr derived_t & operator--() noexcept
243  {
244  if constexpr (order == matrix_major_order::column)
245  return as_derived() += matrix_offset{row_index_type{-1}, column_index_type{0}};
246  else
247  return as_derived() += matrix_offset{row_index_type{0}, column_index_type{-1}};
248  }
249 
251  constexpr derived_t operator--(int) noexcept
252  {
253  derived_t previous{as_derived()};
254  --(*this);
255  return previous;
256  }
257 
259  template <typename dummy_t = derived_t>
260  constexpr derived_t & operator-=(std::iter_difference_t<dummy_t> const offset) noexcept
261  {
262  return *this += -offset;
263  }
264 
266  template <typename dummy_t = derived_t>
267  constexpr derived_t operator-(std::iter_difference_t<dummy_t> const offset) const noexcept
268  {
269  derived_t next{as_derived()};
270  next -= offset;
271  return next;
272  }
273 
275  constexpr derived_t & operator-=(matrix_offset const & offset) noexcept
276  {
277  return as_derived() += matrix_offset{row_index_type{-offset.row}, column_index_type{-offset.col}};
278  }
279 
281  constexpr derived_t operator-(matrix_offset const & offset) const noexcept
282  {
283  derived_t next{as_derived()};
284  next -= offset;
285  return next;
286  }
287 
289  template <typename dummy_t = derived_t>
290  friend constexpr std::iter_difference_t<dummy_t> operator-(derived_t const lhs, derived_t const rhs) noexcept
291  {
292  return lhs.as_host_iter() - rhs.as_host_iter();
293  }
295 
299  // What if the derived type is different?
301  // How can make sure this is the same type?
302  template <typename other_derived_t>
304  requires std::constructible_from<derived_t, other_derived_t> || std::constructible_from<other_derived_t, derived_t>
306  constexpr bool operator==(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
307  {
308  return as_derived().host_iter == rhs.as_derived().host_iter;
309  }
310 
312  template <typename other_derived_t>
314  requires std::constructible_from<derived_t, other_derived_t> || std::constructible_from<other_derived_t, derived_t>
316  constexpr bool operator!=(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
317  {
318  return !(*this == rhs);
319  }
320 
322  template <typename other_derived_t>
324  requires std::constructible_from<derived_t, other_derived_t> || std::constructible_from<other_derived_t, derived_t>
326  constexpr bool operator<(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
327  {
328  return as_derived().host_iter < rhs.as_derived().host_iter;
329  }
330 
332  template <typename other_derived_t>
334  requires std::constructible_from<derived_t, other_derived_t> || std::constructible_from<other_derived_t, derived_t>
336  constexpr bool operator<=(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
337  {
338  return as_derived().host_iter <= rhs.as_derived().host_iter;
339  }
340 
342  template <typename other_derived_t>
344  requires std::constructible_from<derived_t, other_derived_t> || std::constructible_from<other_derived_t, derived_t>
346  constexpr bool operator>(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
347  {
348  return as_derived().host_iter > rhs.as_derived().host_iter;
349  }
350 
352  template <typename other_derived_t>
354  requires std::constructible_from<derived_t, other_derived_t> || std::constructible_from<other_derived_t, derived_t>
356  constexpr bool operator>=(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
357  {
358  return as_derived().host_iter >= rhs.as_derived().host_iter;
359  }
361 private:
362 
364  constexpr auto const & as_host_iter() const
365  {
366  return as_derived().host_iter;
367  }
368 
370  constexpr derived_t & as_derived()
371  {
372  return static_cast<derived_t &>(*this);
373  }
374 
376  constexpr derived_t const & as_derived() const
377  {
378  return static_cast<derived_t const &>(*this);
379  }
380 
381  // matrix_iterator_t host_iter{}; //!< The wrapped matrix iterator.
382 };
383 } // namespace seqan3::detail
matrix_coordinate.hpp
Provides seqan3::detail::alignment_coordinate and associated strong types.
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)
std::iter_difference_t
iterator.hpp
Provides various transformation traits for use on iterators.
ranges
Adaptations of concepts from the Ranges TS.
std::next
T next(T... args)