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>
85 requires (order == other_order)
87 friend class two_dimensional_matrix_iterator_base;
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;
107 template <
typename _derived_t>
108 using difference_type =
typename _derived_t::difference_type;
111 template <
typename _derived_t>
112 using reference =
typename _derived_t::reference;
115 template <
typename _derived_t>
116 using pointer =
typename _derived_t::pointer;
123 template <
typename dummy_t = derived_t>
125 constexpr reference<dummy_t> operator*() const noexcept
127 return *as_derived().host_iter;
131 template <
typename dummy_t = derived_t>
134 return *(as_derived() + offset);
138 template <
typename dummy_t = derived_t>
139 constexpr reference<dummy_t> operator[](matrix_offset
const & offset)
const noexcept
141 return *(as_derived() + offset);
145 template <
typename dummy_t = derived_t>
146 constexpr pointer<dummy_t> operator->() const noexcept
161 SEQAN3_DOXYGEN_ONLY(constexpr seqan3::detail::matrix_coordinate coordinate()
const noexcept {})
182 SEQAN3_DOXYGEN_ONLY(constexpr derived_t &
operator+=(matrix_offset
const & offset) noexcept {})
185 constexpr derived_t &
operator++() noexcept
187 if constexpr (order == matrix_major_order::column)
188 return as_derived() += matrix_offset{row_index_type{1}, column_index_type{0}};
190 return as_derived() += matrix_offset{row_index_type{0}, column_index_type{1}};
194 constexpr derived_t operator++(
int) noexcept
196 derived_t previous{as_derived()};
202 template <
typename dummy_t = derived_t>
205 if constexpr (order == matrix_major_order::column)
206 return as_derived() += matrix_offset{row_index_type{offset}, column_index_type{0}};
208 return as_derived() += matrix_offset{row_index_type{0}, column_index_type{offset}};
212 template <
typename dummy_t = derived_t>
215 derived_t
next{as_derived()};
221 template <
typename dummy_t = derived_t>
224 return iter + offset;
228 constexpr derived_t operator+(matrix_offset
const & offset)
const noexcept
230 derived_t
next{as_derived()};
236 constexpr
friend derived_t operator+(matrix_offset
const & offset, derived_t
const iter)
238 return iter + offset;
242 constexpr derived_t & operator--() noexcept
244 if constexpr (order == matrix_major_order::column)
245 return as_derived() += matrix_offset{row_index_type{-1}, column_index_type{0}};
247 return as_derived() += matrix_offset{row_index_type{0}, column_index_type{-1}};
251 constexpr derived_t operator--(
int) noexcept
253 derived_t previous{as_derived()};
259 template <
typename dummy_t = derived_t>
262 return *
this += -offset;
266 template <
typename dummy_t = derived_t>
269 derived_t
next{as_derived()};
275 constexpr derived_t & operator-=(matrix_offset
const & offset) noexcept
277 return as_derived() += matrix_offset{row_index_type{-offset.row}, column_index_type{-offset.col}};
281 constexpr derived_t operator-(matrix_offset
const & offset)
const noexcept
283 derived_t
next{as_derived()};
289 template <
typename dummy_t = derived_t>
292 return lhs.as_host_iter() - rhs.as_host_iter();
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
308 return as_derived().host_iter == rhs.as_derived().host_iter;
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
318 return !(*
this == rhs);
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
328 return as_derived().host_iter < rhs.as_derived().host_iter;
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
338 return as_derived().host_iter <= rhs.as_derived().host_iter;
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
348 return as_derived().host_iter > rhs.as_derived().host_iter;
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
358 return as_derived().host_iter >= rhs.as_derived().host_iter;
364 constexpr
auto const & as_host_iter()
const
366 return as_derived().host_iter;
370 constexpr derived_t & as_derived()
372 return static_cast<derived_t &
>(*this);
376 constexpr derived_t
const & as_derived()
const
378 return static_cast<derived_t
const &
>(*this);