Loading...
Searching...
No Matches
alignment_trace_matrix_full.hpp
Go to the documentation of this file.
// SPDX-FileCopyrightText: 2006-2025 Knut Reinert & Freie Universität Berlin
// SPDX-FileCopyrightText: 2016-2025 Knut Reinert & MPI für molekulare Genetik
// SPDX-License-Identifier: BSD-3-Clause
#pragma once
#include <iterator>
#include <ranges>
#include <seqan3/alignment/matrix/detail/alignment_matrix_column_major_range_base.hpp>
#include <seqan3/alignment/matrix/detail/alignment_trace_matrix_base.hpp>
#include <seqan3/alignment/matrix/detail/alignment_trace_matrix_proxy.hpp>
#include <seqan3/alignment/matrix/detail/trace_iterator.hpp>
#include <seqan3/utility/views/zip.hpp>
namespace seqan3::detail
{
template <typename trace_t, bool coordinate_only = false>
class alignment_trace_matrix_full :
protected alignment_trace_matrix_base<trace_t>,
public alignment_matrix_column_major_range_base<alignment_trace_matrix_full<trace_t, coordinate_only>>
{
private:
static_assert(std::same_as<trace_t, trace_directions> || simd_concept<trace_t>,
"Value type must either be a trace_directions object or a simd vector.");
using matrix_base_t = alignment_trace_matrix_base<trace_t>;
using range_base_t =
alignment_matrix_column_major_range_base<alignment_trace_matrix_full<trace_t, coordinate_only>>;
friend range_base_t;
protected:
using typename matrix_base_t::coordinate_type;
using typename matrix_base_t::element_type;
using typename range_base_t::alignment_column_type;
using column_data_view_type =
std::conditional_t<coordinate_only,
decltype(std::views::iota(coordinate_type{}, coordinate_type{})),
decltype(views::zip(std::declval<std::span<element_type>>(),
std::declval<std::span<element_type>>(),
std::views::iota(coordinate_type{}, coordinate_type{})))>;
public:
using value_type =
alignment_trace_matrix_proxy<coordinate_type,
std::conditional_t<coordinate_only, detail::ignore_t const, trace_t>>;
using reference = value_type;
using iterator = typename range_base_t::iterator;
using sentinel = typename range_base_t::sentinel;
using typename matrix_base_t::size_type;
constexpr alignment_trace_matrix_full() = default;
constexpr alignment_trace_matrix_full(alignment_trace_matrix_full const &) = default;
constexpr alignment_trace_matrix_full(alignment_trace_matrix_full &&) = default;
constexpr alignment_trace_matrix_full & operator=(alignment_trace_matrix_full const &) = default;
constexpr alignment_trace_matrix_full & operator=(alignment_trace_matrix_full &&) = default;
~alignment_trace_matrix_full() = default;
template <std::ranges::forward_range first_sequence_t, std::ranges::forward_range second_sequence_t>
constexpr alignment_trace_matrix_full(first_sequence_t && first,
second_sequence_t && second,
[[maybe_unused]] trace_t const initial_value = trace_t{})
{
matrix_base_t::num_cols = static_cast<size_type>(std::ranges::distance(first) + 1);
matrix_base_t::num_rows = static_cast<size_type>(std::ranges::distance(second) + 1);
if constexpr (!coordinate_only)
{
// Allocate the matrix here.
matrix_base_t::data = typename matrix_base_t::pool_type{number_rows{matrix_base_t::num_rows},
number_cols{matrix_base_t::num_cols}};
matrix_base_t::cache_left.resize(matrix_base_t::num_rows, initial_value);
}
}
auto trace_path(matrix_coordinate const & trace_begin)
{
static_assert(!coordinate_only, "Requested trace but storing the trace was disabled!");
using matrix_iter_t = std::ranges::iterator_t<typename matrix_base_t::pool_type>;
using trace_iterator_t = trace_iterator<matrix_iter_t>;
using path_t = std::ranges::subrange<trace_iterator_t, std::default_sentinel_t>;
if (trace_begin.row >= matrix_base_t::num_rows || trace_begin.col >= matrix_base_t::num_cols)
throw std::invalid_argument{"The given coordinate exceeds the matrix in vertical or horizontal direction."};
return path_t{trace_iterator_t{matrix_base_t::data.begin() + matrix_offset{trace_begin}},
std::default_sentinel};
}
private:
constexpr alignment_column_type initialise_column(size_type const column_index) noexcept
{
coordinate_type row_begin{column_index_type{column_index}, row_index_type{0u}};
coordinate_type row_end{column_index_type{column_index}, row_index_type{matrix_base_t::num_rows}};
if constexpr (coordinate_only)
{
return alignment_column_type{
*this,
column_data_view_type{std::views::iota(std::move(row_begin), std::move(row_end))}};
}
else
{
matrix_coordinate current_position{row_index_type{0u}, column_index_type{column_index}};
auto col = views::zip(
std::span<element_type>{std::addressof(matrix_base_t::data[current_position]), matrix_base_t::num_rows},
std::span<element_type>{matrix_base_t::cache_left},
std::views::iota(std::move(row_begin), std::move(row_end)));
return alignment_column_type{*this, column_data_view_type{col}};
}
}
template <std::random_access_iterator iter_t>
constexpr value_type make_proxy(iter_t host_iter) noexcept
{
if constexpr (coordinate_only)
{
return {*host_iter, std::ignore, std::ignore, std::ignore, std::ignore};
}
else
{
return {
std::get<2>(*host_iter), // the coordinate.
std::get<0>(*host_iter), // the current entry.
std::get<1>(*host_iter), // the last left cell to read from.
std::get<1>(*host_iter), // the next left cell to write to.
matrix_base_t::cache_up, // the last up cell to read/write from/to.
};
}
}
};
} // namespace seqan3::detail
std::addressof
T addressof(T... args)
alignment_matrix_column_major_range_base.hpp
Provides seqan3::detail::alignment_matrix_column_major_range_base.
alignment_trace_matrix_base.hpp
Provides seqan3::detail::alignment_trace_matrix_base.
alignment_trace_matrix_proxy.hpp
Provides seqan3::detail::alignment_trace_matrix_proxy.
std::declval
T declval(T... args)
seqan3::views::zip
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
iterator
trace_iterator.hpp
Provides seqan3::detail::trace_iterator.
zip.hpp
Provides seqan3::views::zip.
Hide me