SeqAn3 3.2.0
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-2022, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2022, 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 requires (order == other_order)
85 friend class two_dimensional_matrix_iterator_base;
86
91 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;
103
105 template <typename _derived_t>
106 using difference_type = typename _derived_t::difference_type;
107
109 template <typename _derived_t>
110 using reference = typename _derived_t::reference;
111
113 template <typename _derived_t>
114 using pointer = typename _derived_t::pointer;
115
116public:
121 template <typename dummy_t = derived_t>
122 constexpr reference<dummy_t> operator*() const noexcept
123 {
124 return *as_derived().host_iter;
125 }
126
128 template <typename dummy_t = derived_t>
129 constexpr reference<dummy_t> operator[](std::iter_difference_t<dummy_t> const offset) const noexcept
130 {
131 return *(as_derived() + offset);
132 }
133
135 template <typename dummy_t = derived_t>
136 constexpr reference<dummy_t> operator[](matrix_offset const & offset) const noexcept
137 {
138 return *(as_derived() + offset);
139 }
140
142 template <typename dummy_t = derived_t>
143 constexpr pointer<dummy_t> operator->() const noexcept
144 {
145 return std::addressof(*as_derived().host_iter);
146 }
147
158 SEQAN3_DOXYGEN_ONLY(constexpr seqan3::detail::matrix_coordinate coordinate() const noexcept {})
160
179 SEQAN3_DOXYGEN_ONLY(constexpr derived_t & operator+=(matrix_offset const & offset) noexcept {})
180
182 constexpr derived_t & operator++() noexcept
183 {
184 if constexpr (order == matrix_major_order::column)
185 return as_derived() += matrix_offset{row_index_type{1}, column_index_type{0}};
186 else
187 return as_derived() += matrix_offset{row_index_type{0}, column_index_type{1}};
188 }
189
191 constexpr derived_t operator++(int) noexcept
192 {
193 derived_t previous{as_derived()};
194 ++(*this);
195 return previous;
196 }
197
199 template <typename dummy_t = derived_t>
200 constexpr derived_t & operator+=(std::iter_difference_t<dummy_t> const offset) noexcept
201 {
202 if constexpr (order == matrix_major_order::column)
203 return as_derived() += matrix_offset{row_index_type{offset}, column_index_type{0}};
204 else
205 return as_derived() += matrix_offset{row_index_type{0}, column_index_type{offset}};
206 }
207
209 template <typename dummy_t = derived_t>
210 constexpr derived_t operator+(std::iter_difference_t<dummy_t> const offset) const noexcept
211 {
212 derived_t next{as_derived()};
213 next += offset;
214 return next;
215 }
216
218 template <typename dummy_t = derived_t>
219 constexpr friend derived_t operator+(std::iter_difference_t<dummy_t> const offset, derived_t const iter)
220 {
221 return iter + offset;
222 }
223
225 constexpr derived_t operator+(matrix_offset const & offset) const noexcept
226 {
227 derived_t next{as_derived()};
228 next += offset;
229 return next;
230 }
231
233 constexpr friend derived_t operator+(matrix_offset const & offset, derived_t const iter)
234 {
235 return iter + offset;
236 }
237
239 constexpr derived_t & operator--() noexcept
240 {
241 if constexpr (order == matrix_major_order::column)
242 return as_derived() += matrix_offset{row_index_type{-1}, column_index_type{0}};
243 else
244 return as_derived() += matrix_offset{row_index_type{0}, column_index_type{-1}};
245 }
246
248 constexpr derived_t operator--(int) noexcept
249 {
250 derived_t previous{as_derived()};
251 --(*this);
252 return previous;
253 }
254
256 template <typename dummy_t = derived_t>
257 constexpr derived_t & operator-=(std::iter_difference_t<dummy_t> const offset) noexcept
258 {
259 return *this += -offset;
260 }
261
263 template <typename dummy_t = derived_t>
264 constexpr derived_t operator-(std::iter_difference_t<dummy_t> const offset) const noexcept
265 {
266 derived_t next{as_derived()};
267 next -= offset;
268 return next;
269 }
270
272 constexpr derived_t & operator-=(matrix_offset const & offset) noexcept
273 {
274 return as_derived() += matrix_offset{row_index_type{-offset.row}, column_index_type{-offset.col}};
275 }
276
278 constexpr derived_t operator-(matrix_offset const & offset) const noexcept
279 {
280 derived_t next{as_derived()};
281 next -= offset;
282 return next;
283 }
284
286 template <typename dummy_t = derived_t>
287 friend constexpr std::iter_difference_t<dummy_t> operator-(derived_t const lhs, derived_t const rhs) noexcept
288 {
289 return lhs.as_host_iter() - rhs.as_host_iter();
290 }
292
297 // What if the derived type is different?
298 // How can make sure this is the same type?
299 template <typename other_derived_t>
300 requires std::constructible_from<derived_t, other_derived_t>
301 || std::constructible_from<other_derived_t, derived_t>
302 constexpr bool operator==(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
303 {
304 return as_derived().host_iter == rhs.as_derived().host_iter;
305 }
306
308 template <typename other_derived_t>
309 requires std::constructible_from<derived_t, other_derived_t>
310 || std::constructible_from<other_derived_t, derived_t>
311 constexpr bool operator!=(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
312 {
313 return !(*this == rhs);
314 }
315
317 template <typename other_derived_t>
318 requires std::constructible_from<derived_t, other_derived_t>
319 || std::constructible_from<other_derived_t, derived_t>
320 constexpr bool operator<(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
321 {
322 return as_derived().host_iter < rhs.as_derived().host_iter;
323 }
324
326 template <typename other_derived_t>
327 requires std::constructible_from<derived_t, other_derived_t>
328 || std::constructible_from<other_derived_t, derived_t>
329 constexpr bool operator<=(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
330 {
331 return as_derived().host_iter <= rhs.as_derived().host_iter;
332 }
333
335 template <typename other_derived_t>
336 requires std::constructible_from<derived_t, other_derived_t>
337 || std::constructible_from<other_derived_t, derived_t>
338 constexpr bool operator>(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
339 {
340 return as_derived().host_iter > rhs.as_derived().host_iter;
341 }
342
344 template <typename other_derived_t>
345 requires std::constructible_from<derived_t, other_derived_t>
346 || std::constructible_from<other_derived_t, derived_t>
347 constexpr bool operator>=(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
348 {
349 return as_derived().host_iter >= rhs.as_derived().host_iter;
350 }
352
353private:
355 constexpr auto const & as_host_iter() const
356 {
357 return as_derived().host_iter;
358 }
359
361 constexpr derived_t & as_derived()
362 {
363 return static_cast<derived_t &>(*this);
364 }
365
367 constexpr derived_t const & as_derived() const
368 {
369 return static_cast<derived_t const &>(*this);
370 }
371
372 // matrix_iterator_t host_iter{}; //!< The wrapped matrix iterator.
373};
374} // 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)