SeqAn3 3.1.0
The Modern C++ library for sequence analysis.
two_dimensional_matrix_iterator_base.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2021, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2021, 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 <seqan3/std/concepts>
16#include <seqan3/std/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>
85 requires (order == other_order)
87 friend class two_dimensional_matrix_iterator_base;
88
93 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;
105
107 template <typename _derived_t>
108 using difference_type = typename _derived_t::difference_type;
109
111 template <typename _derived_t>
112 using reference = typename _derived_t::reference;
113
115 template <typename _derived_t>
116 using pointer = typename _derived_t::pointer;
117
118public:
119
124 template <typename dummy_t = derived_t>
125 constexpr reference<dummy_t> operator*() const noexcept
126 {
127 return *as_derived().host_iter;
128 }
129
131 template <typename dummy_t = derived_t>
132 constexpr reference<dummy_t> operator[](std::iter_difference_t<dummy_t> const offset) const noexcept
133 {
134 return *(as_derived() + offset);
135 }
136
138 template <typename dummy_t = derived_t>
139 constexpr reference<dummy_t> operator[](matrix_offset const & offset) const noexcept
140 {
141 return *(as_derived() + offset);
142 }
143
145 template <typename dummy_t = derived_t>
146 constexpr pointer<dummy_t> operator->() const noexcept
147 {
148 return std::addressof(*as_derived().host_iter);
149 }
150
161 SEQAN3_DOXYGEN_ONLY(constexpr seqan3::detail::matrix_coordinate coordinate() const noexcept {})
163
182 SEQAN3_DOXYGEN_ONLY(constexpr derived_t & operator+=(matrix_offset const & offset) noexcept {})
183
185 constexpr derived_t & operator++() noexcept
186 {
187 if constexpr (order == matrix_major_order::column)
188 return as_derived() += matrix_offset{row_index_type{1}, column_index_type{0}};
189 else
190 return as_derived() += matrix_offset{row_index_type{0}, column_index_type{1}};
191 }
192
194 constexpr derived_t operator++(int) noexcept
195 {
196 derived_t previous{as_derived()};
197 ++(*this);
198 return previous;
199 }
200
202 template <typename dummy_t = derived_t>
203 constexpr derived_t & operator+=(std::iter_difference_t<dummy_t> const offset) noexcept
204 {
205 if constexpr (order == matrix_major_order::column)
206 return as_derived() += matrix_offset{row_index_type{offset}, column_index_type{0}};
207 else
208 return as_derived() += matrix_offset{row_index_type{0}, column_index_type{offset}};
209 }
210
212 template <typename dummy_t = derived_t>
213 constexpr derived_t operator+(std::iter_difference_t<dummy_t> const offset) const noexcept
214 {
215 derived_t next{as_derived()};
216 next += offset;
217 return next;
218 }
219
221 template <typename dummy_t = derived_t>
222 constexpr friend derived_t operator+(std::iter_difference_t<dummy_t> const offset, derived_t const iter)
223 {
224 return iter + offset;
225 }
226
228 constexpr derived_t operator+(matrix_offset const & offset) const noexcept
229 {
230 derived_t next{as_derived()};
231 next += offset;
232 return next;
233 }
234
236 constexpr friend derived_t operator+(matrix_offset const & offset, derived_t const iter)
237 {
238 return iter + offset;
239 }
240
242 constexpr derived_t & operator--() noexcept
243 {
244 if constexpr (order == matrix_major_order::column)
245 return as_derived() += matrix_offset{row_index_type{-1}, column_index_type{0}};
246 else
247 return as_derived() += matrix_offset{row_index_type{0}, column_index_type{-1}};
248 }
249
251 constexpr derived_t operator--(int) noexcept
252 {
253 derived_t previous{as_derived()};
254 --(*this);
255 return previous;
256 }
257
259 template <typename dummy_t = derived_t>
260 constexpr derived_t & operator-=(std::iter_difference_t<dummy_t> const offset) noexcept
261 {
262 return *this += -offset;
263 }
264
266 template <typename dummy_t = derived_t>
267 constexpr derived_t operator-(std::iter_difference_t<dummy_t> const offset) const noexcept
268 {
269 derived_t next{as_derived()};
270 next -= offset;
271 return next;
272 }
273
275 constexpr derived_t & operator-=(matrix_offset const & offset) noexcept
276 {
277 return as_derived() += matrix_offset{row_index_type{-offset.row}, column_index_type{-offset.col}};
278 }
279
281 constexpr derived_t operator-(matrix_offset const & offset) const noexcept
282 {
283 derived_t next{as_derived()};
284 next -= offset;
285 return next;
286 }
287
289 template <typename dummy_t = derived_t>
290 friend constexpr std::iter_difference_t<dummy_t> operator-(derived_t const lhs, derived_t const rhs) noexcept
291 {
292 return lhs.as_host_iter() - rhs.as_host_iter();
293 }
295
300 // What if the derived type is different?
301 // How can make sure this is the same type?
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
307 {
308 return as_derived().host_iter == rhs.as_derived().host_iter;
309 }
310
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
317 {
318 return !(*this == rhs);
319 }
320
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
327 {
328 return as_derived().host_iter < rhs.as_derived().host_iter;
329 }
330
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
337 {
338 return as_derived().host_iter <= rhs.as_derived().host_iter;
339 }
340
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
347 {
348 return as_derived().host_iter > rhs.as_derived().host_iter;
349 }
350
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
357 {
358 return as_derived().host_iter >= rhs.as_derived().host_iter;
359 }
361private:
362
364 constexpr auto const & as_host_iter() const
365 {
366 return as_derived().host_iter;
367 }
368
370 constexpr derived_t & as_derived()
371 {
372 return static_cast<derived_t &>(*this);
373 }
374
376 constexpr derived_t const & as_derived() const
377 {
378 return static_cast<derived_t const &>(*this);
379 }
380
381 // matrix_iterator_t host_iter{}; //!< The wrapped matrix iterator.
382};
383} // namespace seqan3::detail
T addressof(T... args)
Provides various type traits on generic types.
The <concepts> header from C++20's standard library.
@ 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)
The <ranges> header from C++20's standard library.