SeqAn3 3.2.0
The Modern C++ library for sequence analysis.
coordinate_matrix.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
26
27namespace seqan3::detail
28{
29
30//------------------------------------------------------------------------------
31// coordinate_matrix
32//------------------------------------------------------------------------------
33
62template <typename index_t>
63 requires (std::integral<index_t> || simd_index<index_t>)
64class coordinate_matrix
65{
66private:
74 struct convert_to_matrix_coordinate
75 {
77 index_t column_index{};
78
85 auto operator()(index_t const row_index) noexcept
86 {
87 return matrix_index<index_t>{row_index_type{row_index}, column_index_type{column_index}};
88 }
89 };
90
92 template <typename simd_index_t>
93 using lazy_scalar_type_t = typename simd_traits<simd_index_t>::scalar_type;
94
96 using size_type = lazy_conditional_t<simd_concept<index_t>, lazy<lazy_scalar_type_t, index_t>, index_t>;
97
98 // The coordinate matrix iterator.
99 class iterator;
100
102 size_type column_count{};
104 size_type row_count{};
105
106public:
110 coordinate_matrix() = default;
111 coordinate_matrix(coordinate_matrix const &) = default;
112 coordinate_matrix(coordinate_matrix &&) = default;
113 coordinate_matrix & operator=(coordinate_matrix const &) = default;
114 coordinate_matrix & operator=(coordinate_matrix &&) = default;
115 ~coordinate_matrix() = default;
116
135 template <std::integral column_index_t, std::integral row_index_t>
136 void resize(column_index_type<column_index_t> const column_count,
137 row_index_type<row_index_t> const row_count) noexcept
138 {
139 this->column_count = column_count.get();
140 this->row_count = row_count.get();
141 }
143
148 iterator begin() const noexcept
149 {
150 return iterator{size_type{}, row_count};
151 }
152
154 iterator end() const noexcept
155 {
156 return iterator{column_count, row_count};
157 }
159};
160
161//------------------------------------------------------------------------------
162// iterator
163//------------------------------------------------------------------------------
164
174template <typename index_t>
175 requires (std::integral<index_t> || simd_index<index_t>)
176class coordinate_matrix<index_t>::iterator
177{
178private:
180 using iota_view_t = lazy_conditional_t<simd_index<index_t>,
181 lazy<iota_simd_view, index_t>,
182 decltype(std::views::iota(size_type{}, size_type{}))>;
184 index_t column_id{0};
186 size_type row_count{0};
187
188public:
193 using value_type = decltype(std::declval<iota_view_t>()
194 | std::views::transform(convert_to_matrix_coordinate{index_t{} /*column_id*/}));
196 using reference = value_type;
198 using pointer = void;
200 using difference_type = std::ptrdiff_t;
202 using iterator_category = std::forward_iterator_tag;
204
208 iterator() = default;
209 iterator(iterator const &) = default;
210 iterator(iterator &&) = default;
211 iterator & operator=(iterator const &) = default;
212 iterator & operator=(iterator &&) = default;
213 ~iterator() = default;
214
221 explicit iterator(size_type column_id, size_type row_count) noexcept : row_count{std::move(row_count)}
222 {
223 if constexpr (simd_index<index_t>)
224 this->column_id = simd::fill<index_t>(std::move(column_id));
225 else
226 this->column_id = std::move(column_id);
227 }
229
235 auto operator*() const
236 {
237 if constexpr (simd_index<index_t>)
238 {
239 return views::iota_simd<index_t>(size_type{}, row_count)
240 | std::views::transform(convert_to_matrix_coordinate{column_id});
241 }
242 else
243 {
244 return std::views::iota(size_type{}, row_count)
245 | std::views::transform(convert_to_matrix_coordinate{column_id});
246 }
247 }
249
255 iterator & operator++()
256 {
257 // clang: pre-increment of a SIMD vector does not work
258 if constexpr (simd_index<index_t>)
259 column_id = column_id + simd::fill<index_t>(1);
260 else
261 ++column_id;
262
263 return *this;
264 }
265
267 iterator operator++(int)
268 {
269 iterator tmp{*this};
270 ++(*this);
271 return tmp;
272 }
274
280 friend bool operator==(iterator const & lhs, iterator const & rhs)
281 {
282 if constexpr (simd_index<index_t>)
283 return lhs.column_id[0] == rhs.column_id[0];
284 else
285 return lhs.column_id == rhs.column_id;
286 }
287
289 friend bool operator!=(iterator const & lhs, iterator const & rhs)
290 {
291 return !(lhs == rhs);
292 }
294};
295} // namespace seqan3::detail
Provides algorithms to modify seqan3::simd::simd_type.
Provides seqan3::aligned_allocator.
T begin(T... args)
T end(T... args)
decltype(detail::transform< trait_t >(list_t{})) transform
Apply a transformation trait to every type in the list and return a seqan3::type_list of the results.
Definition: traits.hpp:470
Provides seqan3::detail::counted_simd_iterator and seqan3::views::iota_simd.
Provides lazy template instantiation traits.
Provides seqan3::detail::matrix_index, seqan3::detail::matrix_coordinate and associated strong types.
T operator!=(T... args)
Provides seqan3::simd::simd_traits.
Provides type traits for working with templates.
Provides seqan3::simd::simd_concept.