SeqAn3  3.0.2
The Modern C++ library for sequence analysis.
alignment_trace_matrix_full.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2020, 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 
20 #include <seqan3/std/iterator>
21 #include <seqan3/std/ranges>
22 
23 namespace seqan3::detail
24 {
25 
47 template <typename trace_t, bool coordinate_only = false>
48 class alignment_trace_matrix_full :
49  protected alignment_trace_matrix_base<trace_t>,
50  public alignment_matrix_column_major_range_base<alignment_trace_matrix_full<trace_t, coordinate_only>>
51 {
52 private:
53  static_assert(std::same_as<trace_t, trace_directions> || simd_concept<trace_t>,
54  "Value type must either be a trace_directions object or a simd vector.");
55 
57  using matrix_base_t = alignment_trace_matrix_base<trace_t>;
59  using range_base_t = alignment_matrix_column_major_range_base<alignment_trace_matrix_full<trace_t, coordinate_only>>;
60 
62  friend range_base_t;
63 
64 protected:
65  using typename matrix_base_t::element_type;
66  using typename matrix_base_t::coordinate_type;
67  using typename range_base_t::alignment_column_type;
69  using column_data_view_type = std::conditional_t<coordinate_only,
70  decltype(std::views::iota(coordinate_type{}, coordinate_type{})),
71  decltype(views::zip(std::declval<std::span<element_type>>(),
73  std::views::iota(coordinate_type{}, coordinate_type{})))>;
74 
75 public:
79  using value_type = alignment_trace_matrix_proxy<coordinate_type,
81  std::conditional_t<coordinate_only,
82  detail::ignore_t const,
83  trace_t>>;
85  using reference = value_type;
87  using iterator = typename range_base_t::iterator;
89  using sentinel = typename range_base_t::sentinel;
90  using typename matrix_base_t::size_type;
92 
96  constexpr alignment_trace_matrix_full() = default;
97  constexpr alignment_trace_matrix_full(alignment_trace_matrix_full const &) = default;
98  constexpr alignment_trace_matrix_full(alignment_trace_matrix_full &&) = default;
99  constexpr alignment_trace_matrix_full & operator=(alignment_trace_matrix_full const &) = default;
100  constexpr alignment_trace_matrix_full & operator=(alignment_trace_matrix_full &&) = default;
101  ~alignment_trace_matrix_full() = default;
102 
116  template <std::ranges::forward_range first_sequence_t, std::ranges::forward_range second_sequence_t>
117  constexpr alignment_trace_matrix_full(first_sequence_t && first,
118  second_sequence_t && second,
119  [[maybe_unused]] trace_t const initial_value = trace_t{})
120  {
121  matrix_base_t::num_cols = static_cast<size_type>(std::ranges::distance(first) + 1);
122  matrix_base_t::num_rows = static_cast<size_type>(std::ranges::distance(second) + 1);
123 
124  if constexpr (!coordinate_only)
125  {
126  // Allocate the matrix here.
127  matrix_base_t::data = typename matrix_base_t::pool_type{number_rows{matrix_base_t::num_rows},
128  number_cols{matrix_base_t::num_cols}};
129  matrix_base_t::cache_left.resize(matrix_base_t::num_rows, initial_value);
130  }
131  }
133 
140  auto trace_path(matrix_coordinate const & trace_begin)
141  {
142  static_assert(!coordinate_only, "Requested trace but storing the trace was disabled!");
143 
144  using matrix_iter_t = std::ranges::iterator_t<typename matrix_base_t::pool_type>;
145  using trace_iterator_t = trace_iterator<matrix_iter_t>;
146  using path_t = std::ranges::subrange<trace_iterator_t, std::default_sentinel_t>;
147 
148  if (trace_begin.row >= matrix_base_t::num_rows || trace_begin.col >= matrix_base_t::num_cols)
149  throw std::invalid_argument{"The given coordinate exceeds the matrix in vertical or horizontal direction."};
150 
151  return path_t{trace_iterator_t{matrix_base_t::data.begin() + matrix_offset{trace_begin}},
152  std::default_sentinel};
153  }
154 
155 private:
157  constexpr alignment_column_type initialise_column(size_type const column_index) noexcept
158  {
159  coordinate_type row_begin{column_index_type{column_index}, row_index_type{0u}};
160  coordinate_type row_end{column_index_type{column_index}, row_index_type{matrix_base_t::num_rows}};
161  if constexpr (coordinate_only)
162  {
163  return alignment_column_type{*this,
164  column_data_view_type{std::views::iota(std::move(row_begin),
165  std::move(row_end))}};
166  }
167  else
168  {
169  matrix_coordinate current_position{row_index_type{0u}, column_index_type{column_index}};
170  auto col = views::zip(std::span<element_type>{std::addressof(matrix_base_t::data[current_position]),
171  matrix_base_t::num_rows},
172  std::span<element_type>{matrix_base_t::cache_left},
173  std::views::iota(std::move(row_begin), std::move(row_end)));
174  return alignment_column_type{*this, column_data_view_type{col}};
175  }
176  }
177 
179  template <std::random_access_iterator iter_t>
180  constexpr value_type make_proxy(iter_t host_iter) noexcept
181  {
182  if constexpr (coordinate_only)
183  {
184  return {*host_iter, std::ignore, std::ignore, std::ignore, std::ignore};
185  }
186  else
187  {
188  return {std::get<2>(*host_iter), // the coordinate.
189  std::get<0>(*host_iter), // the current entry.
190  std::get<1>(*host_iter), // the last left cell to read from.
191  std::get<1>(*host_iter), // the next left cell to write to.
192  matrix_base_t::cache_up, // the last up cell to read/write from/to.
193  };
194  }
195  }
196 };
197 
198 } // namespace seqan3::detail
zip.hpp
Provides seqan3::views::zip.
std::span
iterator
Provides C++20 additions to the <iterator> header.
alignment_trace_matrix_proxy.hpp
Provides seqan3::detail::alignment_trace_matrix_proxy.
std::addressof
T addressof(T... args)
seqan3::views::move
auto const move
A view that turns lvalue-references into rvalue-references.
Definition: move.hpp:68
std::invalid_argument
alignment_trace_matrix_base.hpp
Provides seqan3::detail::alignment_trace_matrix_base.
ranges
Adaptations of concepts from the Ranges TS.
std::conditional_t
alignment_matrix_column_major_range_base.hpp
Provides seqan3::detail::alignment_matrix_column_major_range_base.
std::declval
T declval(T... args)
trace_iterator.hpp
Provides seqan3::detail::trace_iterator.