15 #include <type_traits>
23 namespace seqan3::detail
38 enum struct matrix_major_order : uint8_t
75 template <
typename derived_t, matrix_major_order order>
76 class two_dimensional_matrix_iterator_base
83 template <
typename other_derived_t, matrix_major_order other_order>
84 requires order == other_order
85 friend class two_dimensional_matrix_iterator_base;
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;
105 template <
typename _derived_t>
106 using difference_type =
typename _derived_t::difference_type;
109 template <
typename _derived_t>
110 using reference =
typename _derived_t::reference;
113 template <
typename _derived_t>
114 using pointer =
typename _derived_t::pointer;
121 template <
typename dummy_t = derived_t>
123 constexpr reference<dummy_t> operator*() const noexcept
125 return *as_derived().host_iter;
129 template <
typename dummy_t = derived_t>
130 constexpr reference<dummy_t> operator[](difference_type<dummy_t>
const offset)
const noexcept
132 return *(as_derived() +
offset);
136 template <
typename dummy_t = derived_t>
137 constexpr reference<dummy_t> operator[](matrix_offset
const &
offset)
const noexcept
139 return *(as_derived() +
offset);
143 template <
typename dummy_t = derived_t>
144 constexpr pointer<dummy_t> operator->() const noexcept
159 SEQAN3_DOXYGEN_ONLY(constexpr seqan3::detail::matrix_coordinate coordinate()
const noexcept {})
180 SEQAN3_DOXYGEN_ONLY(constexpr derived_t &
operator+=(matrix_offset
const &
offset) noexcept {})
183 constexpr derived_t &
operator++() noexcept
185 if constexpr (order == matrix_major_order::column)
186 return as_derived() += matrix_offset{row_index_type{1}, column_index_type{0}};
188 return as_derived() += matrix_offset{row_index_type{0}, column_index_type{1}};
192 constexpr derived_t operator++(
int) noexcept
194 derived_t previous{as_derived()};
200 template <
typename dummy_t = derived_t>
201 constexpr derived_t & operator+=(difference_type<dummy_t>
const offset) noexcept
203 if constexpr (order == matrix_major_order::column)
204 return as_derived() += matrix_offset{row_index_type{
offset}, column_index_type{0}};
206 return as_derived() += matrix_offset{row_index_type{0}, column_index_type{
offset}};
210 template <
typename dummy_t = derived_t>
211 constexpr derived_t operator+(difference_type<dummy_t>
const offset)
const noexcept
213 derived_t
next{as_derived()};
219 template <
typename dummy_t = derived_t>
220 constexpr
friend derived_t operator+(difference_type<dummy_t>
const offset, derived_t
const iter)
226 constexpr derived_t operator+(matrix_offset
const &
offset)
const noexcept
228 derived_t
next{as_derived()};
234 constexpr
friend derived_t operator+(matrix_offset
const &
offset, derived_t
const iter)
240 constexpr derived_t & operator--() noexcept
242 if constexpr (order == matrix_major_order::column)
243 return as_derived() += matrix_offset{row_index_type{-1}, column_index_type{0}};
245 return as_derived() += matrix_offset{row_index_type{0}, column_index_type{-1}};
249 constexpr derived_t operator--(
int) noexcept
251 derived_t previous{as_derived()};
257 template <
typename dummy_t = derived_t>
258 constexpr derived_t & operator-=(difference_type<dummy_t>
const offset) noexcept
264 template <
typename dummy_t = derived_t>
265 constexpr derived_t operator-(difference_type<dummy_t>
const offset)
const noexcept
267 derived_t
next{as_derived()};
273 constexpr derived_t & operator-=(matrix_offset
const &
offset) noexcept
275 return as_derived() += matrix_offset{row_index_type{-
offset.row}, column_index_type{-
offset.col}};
279 constexpr derived_t operator-(matrix_offset
const &
offset)
const noexcept
281 derived_t
next{as_derived()};
287 template <
typename dummy_t = derived_t>
288 constexpr difference_type<dummy_t> operator-(derived_t
const rhs)
const noexcept
290 return as_derived().host_iter - rhs.host_iter;
300 template <
typename other_derived_t>
304 constexpr
bool operator==(two_dimensional_matrix_iterator_base<other_derived_t, order>
const & rhs)
const noexcept
306 return as_derived().host_iter == rhs.as_derived().host_iter;
310 template <
typename other_derived_t>
314 constexpr
bool operator!=(two_dimensional_matrix_iterator_base<other_derived_t, order>
const & rhs)
const noexcept
316 return !(*
this == rhs);
320 template <
typename other_derived_t>
324 constexpr
bool operator<(two_dimensional_matrix_iterator_base<other_derived_t, order>
const & rhs)
const noexcept
326 return as_derived().host_iter < rhs.as_derived().host_iter;
330 template <
typename other_derived_t>
334 constexpr
bool operator<=(two_dimensional_matrix_iterator_base<other_derived_t, order>
const & rhs)
const noexcept
336 return as_derived().host_iter <= rhs.as_derived().host_iter;
340 template <
typename other_derived_t>
344 constexpr
bool operator>(two_dimensional_matrix_iterator_base<other_derived_t, order>
const & rhs)
const noexcept
346 return as_derived().host_iter > rhs.as_derived().host_iter;
350 template <
typename other_derived_t>
354 constexpr
bool operator>=(two_dimensional_matrix_iterator_base<other_derived_t, order>
const & rhs)
const noexcept
356 return as_derived().host_iter >= rhs.as_derived().host_iter;
362 constexpr derived_t & as_derived()
364 return static_cast<derived_t &>(*
this);
368 constexpr derived_t
const & as_derived()
const
370 return static_cast<derived_t const &>(*
this);