Loading...
Searching...
No Matches
affine_cell_proxy.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 <concepts>
#include <tuple>
#include <type_traits>
#include <seqan3/alignment/matrix/detail/trace_directions.hpp>
#include <seqan3/core/detail/empty_type.hpp>
#include <seqan3/utility/concept.hpp>
#include <seqan3/utility/simd/concept.hpp>
#include <seqan3/utility/tuple/concept.hpp>
namespace seqan3::detail
{
template <typename t>
concept arithmetic_or_simd = arithmetic<t> || simd_concept<t>;
template <typename t>
concept tracedirections_or_simd = std::same_as<std::remove_cvref_t<t>, trace_directions> || simd_concept<t>;
template <typename t>
concept affine_score_cell = tuple_like<t> && std::tuple_size_v<t> == 3
&& arithmetic_or_simd<std::remove_reference_t<std::tuple_element_t<0, t>>>
&& arithmetic_or_simd<std::remove_reference_t<std::tuple_element_t<1, t>>>
&& arithmetic_or_simd<std::remove_reference_t<std::tuple_element_t<2, t>>>;
template <typename t>
concept affine_trace_cell = tuple_like<t> && std::tuple_size_v<t> == 3
&& tracedirections_or_simd<std::remove_reference_t<std::tuple_element_t<0, t>>>
&& tracedirections_or_simd<std::remove_reference_t<std::tuple_element_t<1, t>>>
&& tracedirections_or_simd<std::remove_reference_t<std::tuple_element_t<2, t>>>;
template <typename t>
concept affine_score_and_trace_cell =
tuple_like<t> && std::tuple_size_v<t> == 2
&& affine_score_cell<std::tuple_element_t<0, t>> && affine_trace_cell<std::tuple_element_t<1, t>>;
template <typename tuple_t>
requires (affine_score_cell<tuple_t> || affine_score_and_trace_cell<tuple_t>)
class affine_cell_proxy : public tuple_t
{
private:
using score_cell_type = std::conditional_t<affine_score_cell<tuple_t>, tuple_t, std::tuple_element_t<0, tuple_t>>;
using trace_cell_type =
std::conditional_t<affine_score_and_trace_cell<tuple_t>, std::tuple_element_t<1, tuple_t>, empty_type>;
public:
affine_cell_proxy() = default;
affine_cell_proxy(affine_cell_proxy const &) = default;
affine_cell_proxy(affine_cell_proxy &&) = default;
affine_cell_proxy & operator=(affine_cell_proxy const &) = default;
affine_cell_proxy & operator=(affine_cell_proxy &&) = default;
~affine_cell_proxy() = default;
// Inherit the base class's constructor to enable element-wise initialisation (direct and converting constructor).
using tuple_t::tuple_t;
template <typename other_tuple_t>
requires std::constructible_from<tuple_t, other_tuple_t &&>
explicit affine_cell_proxy(other_tuple_t && other) : tuple_t{std::forward<other_tuple_t>(other)}
{}
template <typename other_tuple_t>
requires std::constructible_from<tuple_t, other_tuple_t const &>
explicit affine_cell_proxy(affine_cell_proxy<other_tuple_t> const & other) :
tuple_t{static_cast<other_tuple_t const &>(other)}
{}
template <typename other_tuple_t>
requires std::constructible_from<tuple_t, other_tuple_t>
explicit affine_cell_proxy(affine_cell_proxy<other_tuple_t> && other) :
tuple_t{static_cast<other_tuple_t &&>(std::move(other))}
{}
template <typename other_tuple_t>
requires std::assignable_from<tuple_t &, other_tuple_t &&>
affine_cell_proxy & operator=(other_tuple_t && other)
{
as_base() = std::forward<other_tuple_t>(other);
return *this;
}
template <typename other_tuple_t>
requires std::assignable_from<tuple_t &, other_tuple_t const &>
affine_cell_proxy & operator=(affine_cell_proxy<other_tuple_t> const & other)
{
as_base() = static_cast<other_tuple_t const &>(other);
return *this;
}
template <typename other_tuple_t>
requires std::assignable_from<tuple_t &, other_tuple_t>
affine_cell_proxy & operator=(affine_cell_proxy<other_tuple_t> && other)
{
as_base() = static_cast<other_tuple_t &&>(std::move(other));
return *this;
}
decltype(auto) best_score() & noexcept
{
return get_score_impl<0>(*this);
}
decltype(auto) best_score() const & noexcept
{
return get_score_impl<0>(*this);
}
decltype(auto) best_score() && noexcept
{
return get_score_impl<0>(std::move(*this));
}
decltype(auto) best_score() const && noexcept
{
return get_score_impl<0>(std::move(*this));
}
decltype(auto) horizontal_score() & noexcept
{
return get_score_impl<1>(*this);
}
decltype(auto) horizontal_score() const & noexcept
{
return get_score_impl<1>(*this);
}
decltype(auto) horizontal_score() && noexcept
{
return get_score_impl<1>(std::move(*this));
}
decltype(auto) horizontal_score() const && noexcept
{
return get_score_impl<1>(std::move(*this));
}
decltype(auto) vertical_score() & noexcept
{
return get_score_impl<2>(*this);
}
decltype(auto) vertical_score() const & noexcept
{
return get_score_impl<2>(*this);
}
decltype(auto) vertical_score() && noexcept
{
return get_score_impl<2>(std::move(*this));
}
decltype(auto) vertical_score() const && noexcept
{
return get_score_impl<2>(std::move(*this));
}
decltype(auto) best_trace() & noexcept
requires affine_score_and_trace_cell<tuple_t>
{
return get_trace_impl<0>(*this);
}
decltype(auto) best_trace() const & noexcept
requires affine_score_and_trace_cell<tuple_t>
{
return get_trace_impl<0>(*this);
}
decltype(auto) best_trace() && noexcept
requires affine_score_and_trace_cell<tuple_t>
{
return get_trace_impl<0>(std::move(*this));
}
decltype(auto) best_trace() const && noexcept
requires affine_score_and_trace_cell<tuple_t>
{
return get_trace_impl<0>(std::move(*this));
}
decltype(auto) horizontal_trace() & noexcept
requires affine_score_and_trace_cell<tuple_t>
{
return get_trace_impl<1>(*this);
}
decltype(auto) horizontal_trace() const & noexcept
requires affine_score_and_trace_cell<tuple_t>
{
return get_trace_impl<1>(*this);
}
decltype(auto) horizontal_trace() && noexcept
requires affine_score_and_trace_cell<tuple_t>
{
return get_trace_impl<1>(std::move(*this));
}
decltype(auto) horizontal_trace() const && noexcept
requires affine_score_and_trace_cell<tuple_t>
{
return get_trace_impl<1>(std::move(*this));
}
decltype(auto) vertical_trace() & noexcept
requires affine_score_and_trace_cell<tuple_t>
{
return get_trace_impl<2>(*this);
}
decltype(auto) vertical_trace() const & noexcept
requires affine_score_and_trace_cell<tuple_t>
{
return get_trace_impl<2>(*this);
}
decltype(auto) vertical_trace() && noexcept
requires affine_score_and_trace_cell<tuple_t>
{
return get_trace_impl<2>(std::move(*this));
}
decltype(auto) vertical_trace() const && noexcept
requires affine_score_and_trace_cell<tuple_t>
{
return get_trace_impl<2>(std::move(*this));
}
private:
template <size_t index, typename this_t>
requires (index < 3)
static constexpr decltype(auto) get_score_impl(this_t && me) noexcept
{
using std::get;
if constexpr (affine_score_cell<tuple_t>)
return get<index>(std::forward<this_t>(me));
else
return get<index>(get<0>(std::forward<this_t>(me)));
}
template <size_t index, typename this_t>
requires (index < 3 && affine_score_and_trace_cell<tuple_t>)
static constexpr decltype(auto) get_trace_impl(this_t && me) noexcept
{
using std::get;
return get<index>(get<1>(std::forward<this_t>(me)));
}
tuple_t & as_base() & noexcept
{
return static_cast<tuple_t &>(*this);
}
};
} // namespace seqan3::detail
namespace std
{
template <typename tuple_t>
requires (seqan3::detail::affine_score_cell<tuple_t> || seqan3::detail::affine_score_and_trace_cell<tuple_t>)
struct tuple_size<seqan3::detail::affine_cell_proxy<tuple_t>> : public tuple_size<tuple_t>
{};
template <size_t index, typename tuple_t>
requires (seqan3::detail::affine_score_cell<tuple_t> || seqan3::detail::affine_score_and_trace_cell<tuple_t>)
struct tuple_element<index, seqan3::detail::affine_cell_proxy<tuple_t>> : public tuple_element<index, tuple_t>
{};
} // namespace std
empty_type.hpp
Provides seqan3::detail::empty_type.
std::forward
T forward(T... args)
seqan3::get
constexpr auto const & get(configuration< configs_t... > const &config) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition configuration.hpp:412
std
SeqAn specific customisations in the standard namespace.
trace_directions.hpp
Provides the declaration of seqan3::detail::trace_directions.
tuple
std::tuple_size_v
T tuple_size_v
type_traits
concept.hpp
Provides concepts that do not have equivalents in C++20.
concept.hpp
Provides seqan3::tuple_like.
Hide me