SeqAn3 3.2.0
The Modern C++ library for sequence analysis.
trace_matrix_full.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 <ranges>
16#include <span>
17#include <vector>
18
28
29namespace seqan3::detail
30{
31
50template <typename trace_t>
51 requires std::same_as<trace_t, trace_directions>
52class trace_matrix_full
53{
54private:
56 using matrix_t =
57 two_dimensional_matrix<trace_t, aligned_allocator<trace_t, sizeof(trace_t)>, matrix_major_order::column>;
59 using physical_column_t = std::vector<trace_t>;
61 using virtual_column_t = decltype(views::repeat_n(trace_t{}, 1));
62
63 class iterator;
64
66 matrix_t complete_matrix{};
68 physical_column_t horizontal_column{};
70 virtual_column_t vertical_column{};
72 size_t column_count{};
74 size_t row_count{};
75
76public:
80 trace_matrix_full() = default;
81 trace_matrix_full(trace_matrix_full const &) = default;
82 trace_matrix_full(trace_matrix_full &&) = default;
83 trace_matrix_full & operator=(trace_matrix_full const &) = default;
84 trace_matrix_full & operator=(trace_matrix_full &&) = default;
85 ~trace_matrix_full() = default;
86
88
111 template <std::integral column_index_t, std::integral row_index_t>
112 void resize(column_index_type<column_index_t> const column_count, row_index_type<row_index_t> const row_count)
113 {
114 this->column_count = column_count.get();
115 this->row_count = row_count.get();
116 complete_matrix.resize(number_rows{this->row_count}, number_cols{this->column_count});
117 horizontal_column.resize(this->row_count);
118 vertical_column = views::repeat_n(trace_t{}, this->row_count);
119 }
120
127 auto trace_path(matrix_coordinate const & trace_begin) const
128 {
129 using matrix_iter_t = std::ranges::iterator_t<matrix_t const>;
130 using trace_iterator_t = trace_iterator<matrix_iter_t>;
131 using path_t = std::ranges::subrange<trace_iterator_t, std::default_sentinel_t>;
132
133 if (trace_begin.row >= row_count || trace_begin.col >= column_count)
134 throw std::invalid_argument{"The given coordinate exceeds the matrix in vertical or horizontal direction."};
135
136 return path_t{trace_iterator_t{complete_matrix.begin() + matrix_offset{trace_begin}}, std::default_sentinel};
137 }
138
143 iterator begin()
144 {
145 return iterator{*this, 0u};
146 }
147
149 iterator begin() const = delete;
150
152 iterator end()
153 {
154 return iterator{*this, column_count};
155 }
156
158 iterator end() const = delete;
160};
161
171template <typename trace_t>
172 requires std::same_as<trace_t, trace_directions>
173class trace_matrix_full<trace_t>::iterator
174{
175private:
177 using single_trace_column_type = std::span<trace_t>;
179 using matrix_column_type = decltype(views::zip(std::declval<single_trace_column_type>(),
180 std::declval<physical_column_t &>(),
181 std::declval<virtual_column_t &>()));
184
185 // Defines a proxy that can be converted to the value type.
186 class column_proxy;
187
189 trace_matrix_full * host_ptr{nullptr};
191 size_t current_column_id{};
192
193public:
198 using value_type = matrix_column_value_t;
200 using reference = column_proxy;
202 using pointer = void;
204 using difference_type = std::ptrdiff_t;
206 using iterator_category = std::input_iterator_tag;
208
212 iterator() noexcept = default;
213 iterator(iterator const &) noexcept = default;
214 iterator(iterator &&) noexcept = default;
215 iterator & operator=(iterator const &) noexcept = default;
216 iterator & operator=(iterator &&) noexcept = default;
217 ~iterator() = default;
218
224 explicit iterator(trace_matrix_full & host_matrix, size_t const initial_column_id) noexcept :
225 host_ptr{std::addressof(host_matrix)},
226 current_column_id{initial_column_id}
227 {}
229
234 reference operator*() const
235 {
236 auto column_begin = host_ptr->complete_matrix.data() + current_column_id * host_ptr->row_count;
237 single_trace_column_type single_trace_column{column_begin, column_begin + host_ptr->row_count};
238
239 return column_proxy{
240 views::zip(std::move(single_trace_column), host_ptr->horizontal_column, host_ptr->vertical_column)};
241 }
243
248 iterator & operator++()
249 {
250 ++current_column_id;
251 return *this;
252 }
253
255 void operator++(int)
256 {
257 ++(*this);
258 }
260
265 friend bool operator==(iterator const & lhs, iterator const & rhs) noexcept
266 {
267 return lhs.current_column_id == rhs.current_column_id;
268 }
269
271 friend bool operator!=(iterator const & lhs, iterator const & rhs) noexcept
272 {
273 return !(lhs == rhs);
274 }
276};
277
286template <typename trace_t>
287 requires std::same_as<trace_t, trace_directions>
288class trace_matrix_full<trace_t>::iterator::column_proxy : public std::ranges::view_interface<column_proxy>
289{
290private:
292 matrix_column_type column{};
293
294public:
298 column_proxy() = default;
299 column_proxy(column_proxy const &) = default;
300 column_proxy(column_proxy &&) = default;
301 column_proxy & operator=(column_proxy const &) = default;
302 column_proxy & operator=(column_proxy &&) = default;
303 ~column_proxy() = default;
304
309 explicit column_proxy(matrix_column_type && column) noexcept : column{std::move(column)}
310 {}
312
317 std::ranges::iterator_t<matrix_column_type> begin()
318 {
319 return column.begin();
320 }
322 std::ranges::iterator_t<matrix_column_type> begin() const = delete;
323
325 std::ranges::sentinel_t<matrix_column_type> end()
326 {
327 return column.end();
328 }
329
331 std::ranges::sentinel_t<matrix_column_type> end() const = delete;
333
335 constexpr operator matrix_column_value_t() const
336 {
337 matrix_column_value_t target{};
338 std::ranges::copy(column, std::back_inserter(target));
339 return target;
340 }
341};
342
343} // 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)
constexpr auto zip
A view adaptor that takes several views and returns tuple-like values from every i-th element of each...
Definition: zip.hpp:573
constexpr auto repeat_n
A view factory that repeats a given value n times.
Definition: repeat_n.hpp:91
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.