SeqAn3 3.4.0-rc.1
The Modern C++ library for sequence analysis.
Loading...
Searching...
No Matches
trace_matrix_full.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 <ranges>
13#include <span>
14#include <vector>
15
25
26namespace seqan3::detail
27{
28
47template <typename trace_t>
48 requires std::same_as<trace_t, trace_directions>
49class trace_matrix_full
50{
51private:
53 using matrix_t =
54 two_dimensional_matrix<trace_t, aligned_allocator<trace_t, sizeof(trace_t)>, matrix_major_order::column>;
56 using physical_column_t = std::vector<trace_t>;
58 using virtual_column_t = decltype(views::repeat_n(trace_t{}, 1));
59
60 class iterator;
61
63 matrix_t complete_matrix{};
65 physical_column_t horizontal_column{};
67 virtual_column_t vertical_column{};
69 size_t column_count{};
71 size_t row_count{};
72
73public:
77 trace_matrix_full() = default;
78 trace_matrix_full(trace_matrix_full const &) = default;
79 trace_matrix_full(trace_matrix_full &&) = default;
80 trace_matrix_full & operator=(trace_matrix_full const &) = default;
81 trace_matrix_full & operator=(trace_matrix_full &&) = default;
82 ~trace_matrix_full() = default;
83
85
108 template <std::integral column_index_t, std::integral row_index_t>
109 void resize(column_index_type<column_index_t> const column_count, row_index_type<row_index_t> const row_count)
110 {
111 this->column_count = column_count.get();
112 this->row_count = row_count.get();
113 complete_matrix.resize(number_rows{this->row_count}, number_cols{this->column_count});
114 horizontal_column.resize(this->row_count);
115 vertical_column = views::repeat_n(trace_t{}, this->row_count);
116 }
117
124 auto trace_path(matrix_coordinate const & trace_begin) const
125 {
126 using matrix_iter_t = std::ranges::iterator_t<matrix_t const>;
127 using trace_iterator_t = trace_iterator<matrix_iter_t>;
128 using path_t = std::ranges::subrange<trace_iterator_t, std::default_sentinel_t>;
129
130 if (trace_begin.row >= row_count || trace_begin.col >= column_count)
131 throw std::invalid_argument{"The given coordinate exceeds the matrix in vertical or horizontal direction."};
132
133 return path_t{trace_iterator_t{complete_matrix.begin() + matrix_offset{trace_begin}}, std::default_sentinel};
134 }
135
140 iterator begin()
141 {
142 return iterator{*this, 0u};
143 }
144
146 iterator begin() const = delete;
147
149 iterator end()
150 {
151 return iterator{*this, column_count};
152 }
153
155 iterator end() const = delete;
157};
158
168template <typename trace_t>
169 requires std::same_as<trace_t, trace_directions>
170class trace_matrix_full<trace_t>::iterator
171{
172private:
174 using single_trace_column_type = std::span<trace_t>;
176 using matrix_column_type = decltype(views::zip(std::declval<single_trace_column_type>(),
177 std::declval<physical_column_t &>(),
178 std::declval<virtual_column_t &>()));
181
182 // Defines a proxy that can be converted to the value type.
183 class column_proxy;
184
186 trace_matrix_full * host_ptr{nullptr};
188 size_t current_column_id{};
189
190public:
195 using value_type = matrix_column_value_t;
197 using reference = column_proxy;
199 using pointer = void;
201 using difference_type = std::ptrdiff_t;
203 using iterator_category = std::input_iterator_tag;
205
209 iterator() noexcept = default;
210 iterator(iterator const &) noexcept = default;
211 iterator(iterator &&) noexcept = default;
212 iterator & operator=(iterator const &) noexcept = default;
213 iterator & operator=(iterator &&) noexcept = default;
214 ~iterator() = default;
215
221 explicit iterator(trace_matrix_full & host_matrix, size_t const initial_column_id) noexcept :
222 host_ptr{std::addressof(host_matrix)},
223 current_column_id{initial_column_id}
224 {}
226
231 reference operator*() const
232 {
233 auto column_begin = host_ptr->complete_matrix.data() + current_column_id * host_ptr->row_count;
234 single_trace_column_type single_trace_column{column_begin, column_begin + host_ptr->row_count};
235
236 return column_proxy{
237 views::zip(std::move(single_trace_column), host_ptr->horizontal_column, host_ptr->vertical_column)};
238 }
240
245 iterator & operator++()
246 {
247 ++current_column_id;
248 return *this;
249 }
250
252 void operator++(int)
253 {
254 ++(*this);
255 }
257
262 friend bool operator==(iterator const & lhs, iterator const & rhs) noexcept
263 {
264 return lhs.current_column_id == rhs.current_column_id;
265 }
266
268 friend bool operator!=(iterator const & lhs, iterator const & rhs) noexcept
269 {
270 return !(lhs == rhs);
271 }
273};
274
283template <typename trace_t>
284 requires std::same_as<trace_t, trace_directions>
285class trace_matrix_full<trace_t>::iterator::column_proxy : public std::ranges::view_interface<column_proxy>
286{
287private:
289 matrix_column_type column;
290
291public:
295 column_proxy() = default;
296 column_proxy(column_proxy const &) = default;
297 column_proxy(column_proxy &&) = default;
298 column_proxy & operator=(column_proxy const &) = default;
299 column_proxy & operator=(column_proxy &&) = default;
300 ~column_proxy() = default;
301
306 explicit column_proxy(matrix_column_type && column) noexcept : column{std::move(column)}
307 {}
309
314 std::ranges::iterator_t<matrix_column_type> begin()
315 {
316 return column.begin();
317 }
319 std::ranges::iterator_t<matrix_column_type> begin() const = delete;
320
322 std::ranges::sentinel_t<matrix_column_type> end()
323 {
324 return column.end();
325 }
326
328 std::ranges::sentinel_t<matrix_column_type> end() const = delete;
330
332 constexpr operator matrix_column_value_t() const
333 {
334 matrix_column_value_t target{};
335 std::ranges::copy(column, std::back_inserter(target));
336 return target;
337 }
338};
339
340} // namespace seqan3::detail
T addressof(T... args)
Provides seqan3::aligned_allocator.
T back_inserter(T... args)
T begin(T... args)
T copy(T... args)
T end(T... args)
seqan::stl::views::zip zip
A view adaptor that takes several views and returns tuple-like values from every i-th element of each...
Definition zip.hpp:24
constexpr auto repeat_n
A view factory that repeats a given value n times.
Definition repeat_n.hpp:88
Provides seqan3::detail::matrix_index, seqan3::detail::matrix_coordinate and associated strong types.
T operator!=(T... args)
Provides seqan3::views::repeat_n.
T resize(T... args)
Provides type traits for working with templates.
Provides the declaration of seqan3::detail::trace_directions.
Provides seqan3::detail::trace_iterator.
Provides seqan3::detail::two_dimensional_matrix.
Provides concepts that do not have equivalents in C++20.
Provides seqan3::views::zip.
Hide me