SeqAn3 3.4.0-rc.1
The Modern C++ library for sequence analysis.
Loading...
Searching...
No Matches
two_dimensional_matrix_iterator_base.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2006-2024 Knut Reinert & Freie Universität Berlin
2// SPDX-FileCopyrightText: 2016-2024 Knut Reinert & MPI für molekulare Genetik
3// SPDX-License-Identifier: BSD-3-Clause
4
10#pragma once
11
12#include <concepts>
13#include <ranges>
14#include <type_traits>
15
19
20namespace seqan3::detail
21{
22
35enum struct matrix_major_order : uint8_t
36{
37 column,
38 row
39};
40
72template <typename derived_t, matrix_major_order order>
73class two_dimensional_matrix_iterator_base
74{
75private:
77 friend derived_t;
78
80 template <typename other_derived_t, matrix_major_order other_order>
81 friend class two_dimensional_matrix_iterator_base;
82
87 constexpr two_dimensional_matrix_iterator_base() = default;
89 constexpr two_dimensional_matrix_iterator_base(two_dimensional_matrix_iterator_base const &) = default;
91 constexpr two_dimensional_matrix_iterator_base(two_dimensional_matrix_iterator_base &&) = default;
93 constexpr two_dimensional_matrix_iterator_base & operator=(two_dimensional_matrix_iterator_base const &) = default;
95 constexpr two_dimensional_matrix_iterator_base & operator=(two_dimensional_matrix_iterator_base &&) = default;
97 ~two_dimensional_matrix_iterator_base() = default;
99
101 template <typename _derived_t>
102 using difference_type = typename _derived_t::difference_type;
103
105 template <typename _derived_t>
106 using reference = typename _derived_t::reference;
107
109 template <typename _derived_t>
110 using pointer = typename _derived_t::pointer;
111
112public:
117 template <typename dummy_t = derived_t>
118 constexpr reference<dummy_t> operator*() const noexcept
119 {
120 return *as_derived().host_iter;
121 }
122
124 template <typename dummy_t = derived_t>
125 constexpr reference<dummy_t> operator[](std::iter_difference_t<dummy_t> const offset) const noexcept
126 {
127 return *(as_derived() + offset);
128 }
129
131 template <typename dummy_t = derived_t>
132 constexpr reference<dummy_t> operator[](matrix_offset const & offset) const noexcept
133 {
134 return *(as_derived() + offset);
135 }
136
138 template <typename dummy_t = derived_t>
139 constexpr pointer<dummy_t> operator->() const noexcept
140 {
141 return std::addressof(*as_derived().host_iter);
142 }
143
154 SEQAN3_DOXYGEN_ONLY(constexpr seqan3::detail::matrix_coordinate coordinate() const noexcept {})
156
175 SEQAN3_DOXYGEN_ONLY(constexpr derived_t & operator+=(matrix_offset const & offset) noexcept {})
176
178 constexpr derived_t & operator++() noexcept
179 {
180 if constexpr (order == matrix_major_order::column)
181 return as_derived() += matrix_offset{row_index_type{1}, column_index_type{0}};
182 else
183 return as_derived() += matrix_offset{row_index_type{0}, column_index_type{1}};
184 }
185
187 constexpr derived_t operator++(int) noexcept
188 {
189 derived_t previous{as_derived()};
190 ++(*this);
191 return previous;
192 }
193
195 template <typename dummy_t = derived_t>
196 constexpr derived_t & operator+=(std::iter_difference_t<dummy_t> const offset) noexcept
197 {
198 if constexpr (order == matrix_major_order::column)
199 return as_derived() += matrix_offset{row_index_type{offset}, column_index_type{0}};
200 else
201 return as_derived() += matrix_offset{row_index_type{0}, column_index_type{offset}};
202 }
203
205 template <typename dummy_t = derived_t>
206 constexpr derived_t operator+(std::iter_difference_t<dummy_t> const offset) const noexcept
207 {
208 derived_t next{as_derived()};
209 next += offset;
210 return next;
211 }
212
214 template <typename dummy_t = derived_t>
215 constexpr friend derived_t operator+(std::iter_difference_t<dummy_t> const offset, derived_t const iter)
216 {
217 return iter + offset;
218 }
219
221 constexpr derived_t operator+(matrix_offset const & offset) const noexcept
222 {
223 derived_t next{as_derived()};
224 next += offset;
225 return next;
226 }
227
229 constexpr friend derived_t operator+(matrix_offset const & offset, derived_t const iter)
230 {
231 return iter + offset;
232 }
233
235 constexpr derived_t & operator--() noexcept
236 {
237 if constexpr (order == matrix_major_order::column)
238 return as_derived() += matrix_offset{row_index_type{-1}, column_index_type{0}};
239 else
240 return as_derived() += matrix_offset{row_index_type{0}, column_index_type{-1}};
241 }
242
244 constexpr derived_t operator--(int) noexcept
245 {
246 derived_t previous{as_derived()};
247 --(*this);
248 return previous;
249 }
250
252 template <typename dummy_t = derived_t>
253 constexpr derived_t & operator-=(std::iter_difference_t<dummy_t> const offset) noexcept
254 {
255 return *this += -offset;
256 }
257
259 template <typename dummy_t = derived_t>
260 constexpr derived_t operator-(std::iter_difference_t<dummy_t> const offset) const noexcept
261 {
262 derived_t next{as_derived()};
263 next -= offset;
264 return next;
265 }
266
268 constexpr derived_t & operator-=(matrix_offset const & offset) noexcept
269 {
270 return as_derived() += matrix_offset{row_index_type{-offset.row}, column_index_type{-offset.col}};
271 }
272
274 constexpr derived_t operator-(matrix_offset const & offset) const noexcept
275 {
276 derived_t next{as_derived()};
277 next -= offset;
278 return next;
279 }
280
282 template <typename dummy_t = derived_t>
283 friend constexpr std::iter_difference_t<dummy_t> operator-(derived_t const lhs, derived_t const rhs) noexcept
284 {
285 return lhs.as_host_iter() - rhs.as_host_iter();
286 }
288
293 // What if the derived type is different?
294 // How can make sure this is the same type?
295 template <typename other_derived_t>
296 requires std::constructible_from<derived_t, other_derived_t>
297 || std::constructible_from<other_derived_t, derived_t>
298 constexpr bool operator==(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
299 {
300 return as_derived().host_iter == rhs.as_derived().host_iter;
301 }
302
304 template <typename other_derived_t>
305 requires std::constructible_from<derived_t, other_derived_t>
306 || std::constructible_from<other_derived_t, derived_t>
307 constexpr bool operator!=(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
308 {
309 return !(*this == rhs);
310 }
311
313 template <typename other_derived_t>
314 requires std::constructible_from<derived_t, other_derived_t>
315 || 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 as_derived().host_iter < rhs.as_derived().host_iter;
319 }
320
322 template <typename other_derived_t>
323 requires std::constructible_from<derived_t, other_derived_t>
324 || std::constructible_from<other_derived_t, derived_t>
325 constexpr bool operator<=(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
326 {
327 return as_derived().host_iter <= rhs.as_derived().host_iter;
328 }
329
331 template <typename other_derived_t>
332 requires std::constructible_from<derived_t, other_derived_t>
333 || std::constructible_from<other_derived_t, 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>
341 requires std::constructible_from<derived_t, other_derived_t>
342 || std::constructible_from<other_derived_t, derived_t>
343 constexpr bool operator>=(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
344 {
345 return as_derived().host_iter >= rhs.as_derived().host_iter;
346 }
348
349private:
351 constexpr auto const & as_host_iter() const
352 {
353 return as_derived().host_iter;
354 }
355
357 constexpr derived_t & as_derived()
358 {
359 return static_cast<derived_t &>(*this);
360 }
361
363 constexpr derived_t const & as_derived() const
364 {
365 return static_cast<derived_t const &>(*this);
366 }
367
368 // matrix_iterator_t host_iter{}; //!< The wrapped matrix iterator.
369};
370} // namespace seqan3::detail
T addressof(T... args)
Provides various type traits on generic types.
@ offset
Sequence (seqan3::field::seq) relative start position (0-based), unsigned value.
Provides various transformation traits for use on iterators.
Provides seqan3::detail::matrix_index, seqan3::detail::matrix_coordinate and associated strong types.
T next(T... args)
T operator!=(T... args)
Hide me