SeqAn3 3.3.0
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// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2023, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2023, 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 <concepts>
16#include <ranges>
17#include <type_traits>
18
22
23namespace seqan3::detail
24{
25
38enum struct matrix_major_order : uint8_t
39{
40 column,
41 row
42};
43
75template <typename derived_t, matrix_major_order order>
76class two_dimensional_matrix_iterator_base
77{
78private:
80 friend derived_t;
81
83 template <typename other_derived_t, matrix_major_order other_order>
84 friend class two_dimensional_matrix_iterator_base;
85
90 constexpr two_dimensional_matrix_iterator_base() = default;
92 constexpr two_dimensional_matrix_iterator_base(two_dimensional_matrix_iterator_base const &) = default;
94 constexpr two_dimensional_matrix_iterator_base(two_dimensional_matrix_iterator_base &&) = default;
96 constexpr two_dimensional_matrix_iterator_base & operator=(two_dimensional_matrix_iterator_base const &) = default;
98 constexpr two_dimensional_matrix_iterator_base & operator=(two_dimensional_matrix_iterator_base &&) = default;
100 ~two_dimensional_matrix_iterator_base() = default;
102
104 template <typename _derived_t>
105 using difference_type = typename _derived_t::difference_type;
106
108 template <typename _derived_t>
109 using reference = typename _derived_t::reference;
110
112 template <typename _derived_t>
113 using pointer = typename _derived_t::pointer;
114
115public:
120 template <typename dummy_t = derived_t>
121 constexpr reference<dummy_t> operator*() const noexcept
122 {
123 return *as_derived().host_iter;
124 }
125
127 template <typename dummy_t = derived_t>
128 constexpr reference<dummy_t> operator[](std::iter_difference_t<dummy_t> const offset) const noexcept
129 {
130 return *(as_derived() + offset);
131 }
132
134 template <typename dummy_t = derived_t>
135 constexpr reference<dummy_t> operator[](matrix_offset const & offset) const noexcept
136 {
137 return *(as_derived() + offset);
138 }
139
141 template <typename dummy_t = derived_t>
142 constexpr pointer<dummy_t> operator->() const noexcept
143 {
144 return std::addressof(*as_derived().host_iter);
145 }
146
157 SEQAN3_DOXYGEN_ONLY(constexpr seqan3::detail::matrix_coordinate coordinate() const noexcept {})
159
178 SEQAN3_DOXYGEN_ONLY(constexpr derived_t & operator+=(matrix_offset const & offset) noexcept {})
179
181 constexpr derived_t & operator++() noexcept
182 {
183 if constexpr (order == matrix_major_order::column)
184 return as_derived() += matrix_offset{row_index_type{1}, column_index_type{0}};
185 else
186 return as_derived() += matrix_offset{row_index_type{0}, column_index_type{1}};
187 }
188
190 constexpr derived_t operator++(int) noexcept
191 {
192 derived_t previous{as_derived()};
193 ++(*this);
194 return previous;
195 }
196
198 template <typename dummy_t = derived_t>
199 constexpr derived_t & operator+=(std::iter_difference_t<dummy_t> const offset) noexcept
200 {
201 if constexpr (order == matrix_major_order::column)
202 return as_derived() += matrix_offset{row_index_type{offset}, column_index_type{0}};
203 else
204 return as_derived() += matrix_offset{row_index_type{0}, column_index_type{offset}};
205 }
206
208 template <typename dummy_t = derived_t>
209 constexpr derived_t operator+(std::iter_difference_t<dummy_t> const offset) const noexcept
210 {
211 derived_t next{as_derived()};
212 next += offset;
213 return next;
214 }
215
217 template <typename dummy_t = derived_t>
218 constexpr friend derived_t operator+(std::iter_difference_t<dummy_t> const offset, derived_t const iter)
219 {
220 return iter + offset;
221 }
222
224 constexpr derived_t operator+(matrix_offset const & offset) const noexcept
225 {
226 derived_t next{as_derived()};
227 next += offset;
228 return next;
229 }
230
232 constexpr friend derived_t operator+(matrix_offset const & offset, derived_t const iter)
233 {
234 return iter + offset;
235 }
236
238 constexpr derived_t & operator--() noexcept
239 {
240 if constexpr (order == matrix_major_order::column)
241 return as_derived() += matrix_offset{row_index_type{-1}, column_index_type{0}};
242 else
243 return as_derived() += matrix_offset{row_index_type{0}, column_index_type{-1}};
244 }
245
247 constexpr derived_t operator--(int) noexcept
248 {
249 derived_t previous{as_derived()};
250 --(*this);
251 return previous;
252 }
253
255 template <typename dummy_t = derived_t>
256 constexpr derived_t & operator-=(std::iter_difference_t<dummy_t> const offset) noexcept
257 {
258 return *this += -offset;
259 }
260
262 template <typename dummy_t = derived_t>
263 constexpr derived_t operator-(std::iter_difference_t<dummy_t> const offset) const noexcept
264 {
265 derived_t next{as_derived()};
266 next -= offset;
267 return next;
268 }
269
271 constexpr derived_t & operator-=(matrix_offset const & offset) noexcept
272 {
273 return as_derived() += matrix_offset{row_index_type{-offset.row}, column_index_type{-offset.col}};
274 }
275
277 constexpr derived_t operator-(matrix_offset const & offset) const noexcept
278 {
279 derived_t next{as_derived()};
280 next -= offset;
281 return next;
282 }
283
285 template <typename dummy_t = derived_t>
286 friend constexpr std::iter_difference_t<dummy_t> operator-(derived_t const lhs, derived_t const rhs) noexcept
287 {
288 return lhs.as_host_iter() - rhs.as_host_iter();
289 }
291
296 // What if the derived type is different?
297 // How can make sure this is the same type?
298 template <typename other_derived_t>
299 requires std::constructible_from<derived_t, other_derived_t>
300 || std::constructible_from<other_derived_t, derived_t>
301 constexpr bool operator==(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
302 {
303 return as_derived().host_iter == rhs.as_derived().host_iter;
304 }
305
307 template <typename other_derived_t>
308 requires std::constructible_from<derived_t, other_derived_t>
309 || std::constructible_from<other_derived_t, derived_t>
310 constexpr bool operator!=(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
311 {
312 return !(*this == rhs);
313 }
314
316 template <typename other_derived_t>
317 requires std::constructible_from<derived_t, other_derived_t>
318 || std::constructible_from<other_derived_t, derived_t>
319 constexpr bool operator<(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
320 {
321 return as_derived().host_iter < rhs.as_derived().host_iter;
322 }
323
325 template <typename other_derived_t>
326 requires std::constructible_from<derived_t, other_derived_t>
327 || std::constructible_from<other_derived_t, derived_t>
328 constexpr bool operator<=(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
329 {
330 return as_derived().host_iter <= rhs.as_derived().host_iter;
331 }
332
334 template <typename other_derived_t>
335 requires std::constructible_from<derived_t, other_derived_t>
336 || std::constructible_from<other_derived_t, derived_t>
337 constexpr bool operator>(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
338 {
339 return as_derived().host_iter > rhs.as_derived().host_iter;
340 }
341
343 template <typename other_derived_t>
344 requires std::constructible_from<derived_t, other_derived_t>
345 || 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 }
351
352private:
354 constexpr auto const & as_host_iter() const
355 {
356 return as_derived().host_iter;
357 }
358
360 constexpr derived_t & as_derived()
361 {
362 return static_cast<derived_t &>(*this);
363 }
364
366 constexpr derived_t const & as_derived() const
367 {
368 return static_cast<derived_t const &>(*this);
369 }
370
371 // matrix_iterator_t host_iter{}; //!< The wrapped matrix iterator.
372};
373} // 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)