Loading...
Searching...
No Matches
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 <ranges>
#include <span>
#include <vector>
#include <seqan3/alignment/matrix/detail/matrix_coordinate.hpp>
#include <seqan3/alignment/matrix/detail/trace_directions.hpp>
#include <seqan3/alignment/matrix/detail/trace_iterator.hpp>
#include <seqan3/alignment/matrix/detail/two_dimensional_matrix.hpp>
#include <seqan3/core/detail/template_inspection.hpp>
#include <seqan3/utility/concept.hpp>
#include <seqan3/utility/container/aligned_allocator.hpp>
#include <seqan3/utility/views/repeat_n.hpp>
#include <seqan3/utility/views/zip.hpp>
namespace seqan3::detail
{
template <typename trace_t>
requires std::same_as<trace_t, trace_directions>
class trace_matrix_full
{
private:
using matrix_t =
two_dimensional_matrix<trace_t, aligned_allocator<trace_t, sizeof(trace_t)>, matrix_major_order::column>;
using physical_column_t = std::vector<trace_t>;
using virtual_column_t = decltype(views::repeat_n(trace_t{}, 1));
class iterator;
matrix_t complete_matrix{};
physical_column_t horizontal_column{};
virtual_column_t vertical_column{};
size_t column_count{};
size_t row_count{};
public:
trace_matrix_full() = default;
trace_matrix_full(trace_matrix_full const &) = default;
trace_matrix_full(trace_matrix_full &&) = default;
trace_matrix_full & operator=(trace_matrix_full const &) = default;
trace_matrix_full & operator=(trace_matrix_full &&) = default;
~trace_matrix_full() = default;
template <std::integral column_index_t, std::integral row_index_t>
void resize(column_index_type<column_index_t> const column_count, row_index_type<row_index_t> const row_count)
{
this->column_count = column_count.get();
this->row_count = row_count.get();
complete_matrix.resize(number_rows{this->row_count}, number_cols{this->column_count});
horizontal_column.resize(this->row_count);
vertical_column = views::repeat_n(trace_t{}, this->row_count);
}
auto trace_path(matrix_coordinate const & trace_begin) const
{
using matrix_iter_t = std::ranges::iterator_t<matrix_t const>;
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 >= row_count || trace_begin.col >= column_count)
throw std::invalid_argument{"The given coordinate exceeds the matrix in vertical or horizontal direction."};
return path_t{trace_iterator_t{complete_matrix.begin() + matrix_offset{trace_begin}}, std::default_sentinel};
}
iterator begin()
{
return iterator{*this, 0u};
}
iterator begin() const = delete;
iterator end()
{
return iterator{*this, column_count};
}
iterator end() const = delete;
};
template <typename trace_t>
requires std::same_as<trace_t, trace_directions>
class trace_matrix_full<trace_t>::iterator
{
private:
using single_trace_column_type = std::span<trace_t>;
using matrix_column_type = decltype(views::zip(std::declval<single_trace_column_type>(),
std::declval<physical_column_t &>(),
std::declval<virtual_column_t &>()));
using matrix_column_value_t = std::vector<std::ranges::range_value_t<matrix_column_type>>;
// Defines a proxy that can be converted to the value type.
class column_proxy;
trace_matrix_full * host_ptr{nullptr};
size_t current_column_id{};
public:
using value_type = matrix_column_value_t;
using reference = column_proxy;
using pointer = void;
using difference_type = std::ptrdiff_t;
using iterator_category = std::input_iterator_tag;
iterator() noexcept = default;
iterator(iterator const &) noexcept = default;
iterator(iterator &&) noexcept = default;
iterator & operator=(iterator const &) noexcept = default;
iterator & operator=(iterator &&) noexcept = default;
~iterator() = default;
explicit iterator(trace_matrix_full & host_matrix, size_t const initial_column_id) noexcept :
host_ptr{std::addressof(host_matrix)},
current_column_id{initial_column_id}
{}
reference operator*() const
{
auto column_begin = host_ptr->complete_matrix.data() + current_column_id * host_ptr->row_count;
single_trace_column_type single_trace_column{column_begin, column_begin + host_ptr->row_count};
return column_proxy{
views::zip(std::move(single_trace_column), host_ptr->horizontal_column, host_ptr->vertical_column)};
}
iterator & operator++()
{
++current_column_id;
return *this;
}
void operator++(int)
{
++(*this);
}
friend bool operator==(iterator const & lhs, iterator const & rhs) noexcept
{
return lhs.current_column_id == rhs.current_column_id;
}
friend bool operator!=(iterator const & lhs, iterator const & rhs) noexcept
{
return !(lhs == rhs);
}
};
template <typename trace_t>
requires std::same_as<trace_t, trace_directions>
class trace_matrix_full<trace_t>::iterator::column_proxy : public std::ranges::view_interface<column_proxy>
{
private:
matrix_column_type column;
public:
column_proxy() = default;
column_proxy(column_proxy const &) = default;
column_proxy(column_proxy &&) = default;
column_proxy & operator=(column_proxy const &) = default;
column_proxy & operator=(column_proxy &&) = default;
~column_proxy() = default;
explicit column_proxy(matrix_column_type && column) noexcept : column{std::move(column)}
{}
std::ranges::iterator_t<matrix_column_type> begin()
{
return column.begin();
}
std::ranges::iterator_t<matrix_column_type> begin() const = delete;
std::ranges::sentinel_t<matrix_column_type> end()
{
return column.end();
}
std::ranges::sentinel_t<matrix_column_type> end() const = delete;
constexpr operator matrix_column_value_t() const
{
matrix_column_value_t target{};
std::ranges::copy(column, std::back_inserter(target));
return target;
}
};
} // namespace seqan3::detail
std::addressof
T addressof(T... args)
aligned_allocator.hpp
Provides seqan3::aligned_allocator.
std::back_inserter
T back_inserter(T... args)
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
seqan3::views::repeat_n
constexpr auto repeat_n
A view factory that repeats a given value n times.
Definition repeat_n.hpp:88
matrix_coordinate.hpp
Provides seqan3::detail::matrix_index, seqan3::detail::matrix_coordinate and associated strong types.
std::rel_ops::operator!=
T operator!=(T... args)
repeat_n.hpp
Provides seqan3::views::repeat_n.
template_inspection.hpp
Provides type traits for working with templates.
trace_directions.hpp
Provides the declaration of seqan3::detail::trace_directions.
trace_iterator.hpp
Provides seqan3::detail::trace_iterator.
two_dimensional_matrix.hpp
Provides seqan3::detail::two_dimensional_matrix.
concept.hpp
Provides concepts that do not have equivalents in C++20.
vector
zip.hpp
Provides seqan3::views::zip.
Hide me