SeqAn3 3.1.0
The Modern C++ library for sequence analysis.
trace_matrix_full.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/ranges>
16#include <seqan3/std/span>
17#include <vector>
18
28
29namespace seqan3::detail
30{
31
50template <typename trace_t>
52 requires std::same_as<trace_t, trace_directions>
54class trace_matrix_full
55{
56private:
58 using matrix_t = two_dimensional_matrix<trace_t,
59 aligned_allocator<trace_t, sizeof(trace_t)>,
60 matrix_major_order::column>;
62 using physical_column_t = std::vector<trace_t>;
64 using virtual_column_t = decltype(views::repeat_n(trace_t{}, 1));
65
66 class iterator;
67
69 matrix_t complete_matrix{};
71 physical_column_t horizontal_column{};
73 virtual_column_t vertical_column{};
75 size_t column_count{};
77 size_t row_count{};
78
79public:
83 trace_matrix_full() = default;
84 trace_matrix_full(trace_matrix_full const &) = default;
85 trace_matrix_full(trace_matrix_full &&) = default;
86 trace_matrix_full & operator=(trace_matrix_full const &) = default;
87 trace_matrix_full & operator=(trace_matrix_full &&) = default;
88 ~trace_matrix_full() = default;
89
91
114 template <std::integral column_index_t, std::integral row_index_t>
115 void resize(column_index_type<column_index_t> const column_count,
116 row_index_type<row_index_t> const row_count)
117 {
118 this->column_count = column_count.get();
119 this->row_count = row_count.get();
120 complete_matrix.resize(number_rows{this->row_count}, number_cols{this->column_count});
121 horizontal_column.resize(this->row_count);
122 vertical_column = views::repeat_n(trace_t{}, this->row_count);
123 }
124
131 auto trace_path(matrix_coordinate const & trace_begin) const
132 {
133 using matrix_iter_t = std::ranges::iterator_t<matrix_t const>;
134 using trace_iterator_t = trace_iterator<matrix_iter_t>;
135 using path_t = std::ranges::subrange<trace_iterator_t, std::default_sentinel_t>;
136
137 if (trace_begin.row >= row_count || trace_begin.col >= column_count)
138 throw std::invalid_argument{"The given coordinate exceeds the matrix in vertical or horizontal direction."};
139
140 return path_t{trace_iterator_t{complete_matrix.begin() + matrix_offset{trace_begin}}, std::default_sentinel};
141 }
142
147 iterator begin()
148 {
149 return iterator{*this, 0u};
150 }
151
153 iterator begin() const = delete;
154
156 iterator end()
157 {
158 return iterator{*this, column_count};
159 }
160
162 iterator end() const = delete;
164};
165
175template <typename trace_t>
177 requires std::same_as<trace_t, trace_directions>
179class trace_matrix_full<trace_t>::iterator
180{
181private:
183 using single_trace_column_type = std::span<trace_t>;
185 using matrix_column_type = decltype(views::zip(std::declval<single_trace_column_type>(),
186 std::declval<physical_column_t &>(),
187 std::declval<virtual_column_t &>()));
190
191 // Defines a proxy that can be converted to the value type.
192 class column_proxy;
193
195 trace_matrix_full * host_ptr{nullptr};
197 size_t current_column_id{};
198
199public:
204 using value_type = matrix_column_value_t;
206 using reference = column_proxy;
208 using pointer = void;
210 using difference_type = std::ptrdiff_t;
212 using iterator_category = std::input_iterator_tag;
214
218 iterator() noexcept = default;
219 iterator(iterator const &) noexcept = default;
220 iterator(iterator &&) noexcept = default;
221 iterator & operator=(iterator const &) noexcept = default;
222 iterator & operator=(iterator &&) noexcept = default;
223 ~iterator() = default;
224
230 explicit iterator(trace_matrix_full & host_matrix, size_t const initial_column_id) noexcept :
231 host_ptr{std::addressof(host_matrix)},
232 current_column_id{initial_column_id}
233 {}
235
240 reference operator*() const
241 {
242 auto column_begin = host_ptr->complete_matrix.data() + current_column_id * host_ptr->row_count;
243 single_trace_column_type single_trace_column{column_begin, column_begin + host_ptr->row_count};
244
245 return column_proxy{views::zip(std::move(single_trace_column),
246 host_ptr->horizontal_column,
247 host_ptr->vertical_column)};
248 }
250
255 iterator & operator++()
256 {
257 ++current_column_id;
258 return *this;
259 }
260
262 void operator++(int)
263 {
264 ++(*this);
265 }
267
272 friend bool operator==(iterator const & lhs, iterator const & rhs) noexcept
273 {
274 return lhs.current_column_id == rhs.current_column_id;
275 }
276
278 friend bool operator!=(iterator const & lhs, iterator const & rhs) noexcept
279 {
280 return !(lhs == rhs);
281 }
283};
284
293template <typename trace_t>
295 requires std::same_as<trace_t, trace_directions>
297class trace_matrix_full<trace_t>::iterator::column_proxy : public std::ranges::view_interface<column_proxy>
298{
299private:
301 matrix_column_type column{};
302
303public:
307 column_proxy() = default;
308 column_proxy(column_proxy const &) = default;
309 column_proxy(column_proxy &&) = default;
310 column_proxy & operator=(column_proxy const &) = default;
311 column_proxy & operator=(column_proxy &&) = default;
312 ~column_proxy() = default;
313
318 explicit column_proxy(matrix_column_type && column) noexcept : column{std::move(column)}
319 {}
321
326 std::ranges::iterator_t<matrix_column_type> begin()
327 {
328 return column.begin();
329 }
331 std::ranges::iterator_t<matrix_column_type> begin() const = delete;
332
334 std::ranges::sentinel_t<matrix_column_type> end()
335 {
336 return column.end();
337 }
338
340 std::ranges::sentinel_t<matrix_column_type> end() const = delete;
342
344 constexpr operator matrix_column_value_t() const
345 {
346 matrix_column_value_t target{};
347 std::ranges::copy(column, std::cpp20::back_inserter(target));
348 return target;
349 }
350};
351
352} // namespace seqan3::detail
T addressof(T... args)
Provides seqan3::aligned_allocator.
T begin(T... args)
Provides concepts for core language types and relations that don't have concepts in C++20 (yet).
T end(T... args)
constexpr auto zip
A zip view.
Definition: zip.hpp:29
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)
The <ranges> header from C++20's standard library.
Provides seqan3::views::repeat_n.
T resize(T... args)
Provides std::span from the C++20 standard library.
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 seqan3::views::zip.