Loading...
Searching...
No Matches
alphabet_tuple_base.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 <cassert>
#include <concepts>
#include <utility>
#include <seqan3/alphabet/alphabet_base.hpp>
#include <seqan3/alphabet/composite/detail.hpp>
#include <seqan3/alphabet/concept.hpp>
#include <seqan3/alphabet/detail/alphabet_proxy.hpp>
#include <seqan3/utility/detail/integer_traits.hpp>
#include <seqan3/utility/tuple/concept.hpp>
#include <seqan3/utility/type_list/detail/type_list_algorithm.hpp>
#include <seqan3/utility/type_list/traits.hpp>
#include <seqan3/utility/type_list/type_list.hpp>
#include <seqan3/utility/type_pack/traits.hpp>
#include <seqan3/utility/type_traits/detail/transformation_trait_or.hpp>
namespace seqan3::detail
{
template <typename tuple_derived_t, typename rhs_t, typename... component_types>
inline constexpr bool tuple_general_guard =
(!std::same_as<rhs_t, tuple_derived_t>) && (!std::same_as<rhs_t, alphabet_tuple_base<component_types...>>)
&& (!std::is_base_of_v<tuple_derived_t, rhs_t>) && (!(std::same_as<rhs_t, component_types> || ...))
&& (!list_traits::contains<tuple_derived_t, recursive_required_types_t<rhs_t>>);
template <typename lhs_t, typename tuple_derived_t, typename rhs_t, typename... component_types>
inline constexpr bool tuple_eq_guard =
(instantiate_if_v<lazy<weakly_equality_comparable_with_trait, rhs_t, component_types>,
std::same_as<lhs_t, tuple_derived_t>
&& tuple_general_guard<tuple_derived_t, rhs_t, component_types...>>
|| ...);
template <typename lhs_t, typename tuple_derived_t, typename rhs_t, typename... component_types>
inline constexpr bool tuple_order_guard =
(instantiate_if_v<lazy<weakly_ordered_with_trait, rhs_t, component_types>,
std::same_as<lhs_t, tuple_derived_t>
&& tuple_general_guard<lhs_t, tuple_derived_t, rhs_t, component_types...>>
|| ...);
} // namespace seqan3::detail
namespace seqan3
{
// forwards
template <typename t>
decltype(auto) get();
template <size_t i>
decltype(auto) get();
template <typename derived_type, typename... component_types>
requires (detail::writable_constexpr_semialphabet<component_types> && ...) && (std::regular<component_types> && ...)
class alphabet_tuple_base :
public alphabet_base<derived_type,
(1 * ... * alphabet_size<component_types>),
void> // no char type, because this is only semi_alphabet
{
private:
using base_t = alphabet_base<derived_type,
(1 * ... * alphabet_size<component_types>),
void>; // no char type, because this is only semi_alphabet
using component_list = seqan3::type_list<component_types...>;
template <typename type>
static constexpr bool is_component = seqan3::list_traits::contains<type, component_list>;
template <typename type>
static constexpr bool is_unique_component = (seqan3::list_traits::count<type, component_list> == 1);
// forward declaration: see implementation below
template <typename alphabet_type, size_t index>
class component_proxy;
constexpr alphabet_tuple_base() noexcept : base_t{}
{}
constexpr alphabet_tuple_base(alphabet_tuple_base const &) = default;
constexpr alphabet_tuple_base(alphabet_tuple_base &&) = default;
constexpr alphabet_tuple_base & operator=(alphabet_tuple_base const &) = default;
constexpr alphabet_tuple_base & operator=(alphabet_tuple_base &&) = default;
~alphabet_tuple_base() = default;
using base_t::base_t;
friend derived_type;
// Import from base:
using typename base_t::rank_type;
public:
// Import from base:
using base_t::alphabet_size;
using base_t::assign_rank;
using base_t::to_rank;
using seqan3_required_types = component_list;
using seqan3_recursive_required_types = list_traits::concat<
component_list,
detail::transformation_trait_or_t<detail::recursive_required_types<component_types>, seqan3::type_list<>>...>;
static constexpr bool seqan3_alphabet_tuple_like = true;
constexpr alphabet_tuple_base(component_types... components) noexcept
{
assign_rank(rank_sum_helper(components..., std::make_index_sequence<sizeof...(component_types)>{}));
}
template <typename component_type>
requires (!std::is_base_of_v<alphabet_tuple_base, component_type>) && is_unique_component<component_type>
constexpr explicit alphabet_tuple_base(component_type const alph) noexcept : alphabet_tuple_base{}
{
get<component_type>(*this) = alph;
}
template <typename indirect_component_type>
requires ((detail::instantiate_if_v<
detail::lazy<std::is_convertible, indirect_component_type, component_types>,
detail::tuple_general_guard<derived_type, indirect_component_type, component_types...>>
|| ...))
constexpr explicit alphabet_tuple_base(indirect_component_type const alph) noexcept : alphabet_tuple_base{}
{
using component_predicate = detail::implicitly_convertible_from<indirect_component_type>;
constexpr auto component_position =
seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
using component_type = seqan3::list_traits::at<component_position, component_list>;
component_type tmp(alph); // delegate construction
get<component_type>(*this) = tmp;
}
template <typename indirect_component_type>
requires ((!(detail::instantiate_if_v<
detail::lazy<std::is_convertible, indirect_component_type, component_types>,
detail::tuple_general_guard<derived_type, indirect_component_type, component_types...>>
|| ...))
&& (detail::instantiate_if_v<
detail::lazy<std::is_constructible, component_types, indirect_component_type>,
detail::tuple_general_guard<derived_type, indirect_component_type, component_types...>>
|| ...))
constexpr explicit alphabet_tuple_base(indirect_component_type const alph) noexcept : alphabet_tuple_base{}
{
using component_predicate = detail::constructible_from<indirect_component_type>;
constexpr auto component_position =
seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
using component_type = seqan3::list_traits::at<component_position, component_list>;
component_type tmp(alph); // delegate construction
get<component_type>(*this) = tmp;
}
template <typename component_type>
requires (!std::derived_from<component_type, alphabet_tuple_base>) && is_unique_component<component_type>
constexpr derived_type & operator=(component_type const alph) noexcept
{
get<component_type>(*this) = alph;
return static_cast<derived_type &>(*this);
}
template <typename indirect_component_type>
requires ((!std::derived_from<indirect_component_type, alphabet_tuple_base>)
&& (!is_unique_component<indirect_component_type>)
&& (std::assignable_from<component_types, indirect_component_type> || ...))
constexpr derived_type & operator=(indirect_component_type const alph) noexcept
{
using component_predicate = detail::assignable_from<indirect_component_type>;
constexpr auto component_position =
seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
using component_type = seqan3::list_traits::at<component_position, component_list>;
get<component_type>(*this) = alph; // delegate assignment
return static_cast<derived_type &>(*this);
}
// If not assignable but implicit convertible, convert first and assign afterwards
template <typename indirect_component_type>
requires ((!std::derived_from<indirect_component_type, alphabet_tuple_base>)
&& (!is_unique_component<indirect_component_type>)
&& (!(std::assignable_from<component_types, indirect_component_type> || ...))
&& (std::convertible_to<indirect_component_type, component_types> || ...))
constexpr derived_type & operator=(indirect_component_type const alph) noexcept
{
using component_predicate = detail::implicitly_convertible_from<indirect_component_type>;
constexpr auto component_position =
seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
using component_type = seqan3::list_traits::at<component_position, component_list>;
component_type tmp(alph);
get<component_type>(*this) = tmp;
return static_cast<derived_type &>(*this);
}
template <typename indirect_component_type>
requires ((!std::derived_from<indirect_component_type, alphabet_tuple_base>)
&& (!is_unique_component<indirect_component_type>)
&& (!(std::assignable_from<component_types, indirect_component_type> || ...))
&& (!(std::convertible_to<indirect_component_type, component_types> || ...))
&& (std::constructible_from<component_types, indirect_component_type> || ...))
constexpr derived_type & operator=(indirect_component_type const alph) noexcept
{
using component_predicate = detail::constructible_from<indirect_component_type>;
constexpr auto component_position =
seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
using component_type = seqan3::list_traits::at<component_position, component_list>;
component_type tmp(alph); // delegate construction
get<component_type>(*this) = tmp;
return static_cast<derived_type &>(*this);
}
template <size_t index>
friend constexpr auto get(alphabet_tuple_base & l) noexcept
{
static_assert(index < sizeof...(component_types), "Index out of range.");
using t = seqan3::list_traits::at<index, component_list>;
t val{};
seqan3::assign_rank_to(l.to_component_rank<index>(), val);
return component_proxy<t, index>{val, l};
}
template <typename type>
friend constexpr auto get(alphabet_tuple_base & l) noexcept
requires is_unique_component<type>
{
return get<seqan3::list_traits::find<type, component_list>>(l);
}
template <size_t index>
friend constexpr auto get(alphabet_tuple_base const & l) noexcept
{
static_assert(index < sizeof...(component_types), "Index out of range.");
using t = seqan3::list_traits::at<index, component_list>;
return seqan3::assign_rank_to(l.to_component_rank<index>(), t{});
}
template <typename type>
friend constexpr type get(alphabet_tuple_base const & l) noexcept
requires is_unique_component<type>
{
return get<seqan3::list_traits::find<type, component_list>>(l);
}
template <typename type>
constexpr operator type() const noexcept
requires is_unique_component<type>
{
return get<type>(*this);
}
template <typename derived_type_t, typename indirect_component_type>
friend constexpr auto operator==(derived_type_t const lhs, indirect_component_type const rhs) noexcept
-> std::enable_if_t<
detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
bool>
{
using component_predicate = detail::weakly_equality_comparable_with_<indirect_component_type>;
constexpr auto component_position =
seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
using component_type = seqan3::list_traits::at<component_position, component_list>;
return get<component_type>(lhs) == rhs;
}
template <typename derived_type_t, typename indirect_component_type>
friend constexpr auto operator==(indirect_component_type const lhs, derived_type_t const rhs) noexcept
-> std::enable_if_t<
detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
bool>
{
return rhs == lhs;
}
template <typename derived_type_t, typename indirect_component_type>
friend constexpr auto operator!=(derived_type_t const lhs, indirect_component_type const rhs) noexcept
-> std::enable_if_t<
detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
bool>
{
using component_predicate = detail::weakly_equality_comparable_with_<indirect_component_type>;
constexpr auto component_position =
seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
using component_type = seqan3::list_traits::at<component_position, component_list>;
return get<component_type>(lhs) != rhs;
}
template <typename derived_type_t, typename indirect_component_type>
friend constexpr auto operator!=(indirect_component_type const lhs, derived_type_t const rhs) noexcept
-> std::enable_if_t<
detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
bool>
{
return rhs != lhs;
}
template <typename derived_type_t, typename indirect_component_type>
friend constexpr auto operator<(derived_type_t const lhs, indirect_component_type const rhs) noexcept
-> std::enable_if_t<
detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
bool>
{
using component_predicate = detail::weakly_ordered_with_<indirect_component_type>;
constexpr auto component_position =
seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
using component_type = seqan3::list_traits::at<component_position, component_list>;
return get<component_type>(lhs) < rhs;
}
template <typename derived_type_t, typename indirect_component_type>
friend constexpr auto operator<(indirect_component_type const lhs, derived_type_t const rhs) noexcept
-> std::enable_if_t<
detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
bool>
{
return rhs > lhs;
}
template <typename derived_type_t, typename indirect_component_type>
friend constexpr auto operator<=(derived_type_t const lhs, indirect_component_type const rhs) noexcept
-> std::enable_if_t<
detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
bool>
{
using component_predicate = detail::weakly_ordered_with_<indirect_component_type>;
constexpr auto component_position =
seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
using component_type = seqan3::list_traits::at<component_position, component_list>;
return get<component_type>(lhs) <= rhs;
}
template <typename derived_type_t, typename indirect_component_type>
friend constexpr auto operator<=(indirect_component_type const lhs, derived_type_t const rhs) noexcept
-> std::enable_if_t<
detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
bool>
{
return rhs >= lhs;
}
template <typename derived_type_t, typename indirect_component_type>
friend constexpr auto operator>(derived_type_t const lhs, indirect_component_type const rhs) noexcept
-> std::enable_if_t<
detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
bool>
{
using component_predicate = detail::weakly_ordered_with_<indirect_component_type>;
constexpr auto component_position =
seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
using component_type = seqan3::list_traits::at<component_position, component_list>;
return get<component_type>(lhs) > rhs;
}
template <typename derived_type_t, typename indirect_component_type>
friend constexpr auto operator>(indirect_component_type const lhs, derived_type_t const rhs) noexcept
-> std::enable_if_t<
detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
bool>
{
return rhs < lhs;
}
template <typename derived_type_t, typename indirect_component_type>
friend constexpr auto operator>=(derived_type_t const lhs, indirect_component_type const rhs) noexcept
-> std::enable_if_t<
detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
bool>
{
using component_predicate = detail::weakly_ordered_with_<indirect_component_type>;
constexpr auto component_position =
seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
using component_type = seqan3::list_traits::at<component_position, component_list>;
return get<component_type>(lhs) >= rhs;
}
template <typename derived_type_t, typename indirect_component_type>
friend constexpr auto operator>=(indirect_component_type const lhs, derived_type_t const rhs) noexcept
-> std::enable_if_t<
detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
bool>
{
return rhs <= lhs;
}
private:
template <size_t index>
constexpr rank_type to_component_rank() const noexcept
{
if constexpr (alphabet_size < 1024) // computation is cached for small alphabets
{
return rank_to_component_rank[index][to_rank()];
}
else
{
return (to_rank() / cummulative_alph_sizes[index])
% seqan3::alphabet_size<pack_traits::at<index, component_types...>>;
}
}
template <size_t index>
constexpr void assign_component_rank(ptrdiff_t const r) noexcept
{
assign_rank(static_cast<ptrdiff_t>(to_rank())
+ ((r - static_cast<ptrdiff_t>(to_component_rank<index>()))
* static_cast<ptrdiff_t>(cummulative_alph_sizes[index])));
}
template <std::size_t... idx>
static constexpr rank_type rank_sum_helper(component_types... components,
std::index_sequence<idx...> const &) noexcept
{
return ((seqan3::to_rank(components) * cummulative_alph_sizes[idx]) + ...);
}
static constexpr std::array<rank_type, component_list::size()> cummulative_alph_sizes{
[]() constexpr
{
// create array (1, |sigma1|, |sigma1|*|sigma2|, ... , |sigma1|*...*|sigmaN|)
std::array<rank_type, component_list::size() + 1> ret{};
ret[0] = 1;
size_t count = 1;
using reverse_list_t = decltype(seqan3::list_traits::detail::reverse(component_list{}));
seqan3::detail::for_each<reverse_list_t>(
[&](auto alphabet_type_identity) constexpr
{
using alphabet_t = typename decltype(alphabet_type_identity)::type;
ret[count] = static_cast<rank_type>(seqan3::alphabet_size<alphabet_t> * ret[count - 1]);
++count;
});
// reverse and strip one: (|sigma1|*...*|sigmaN-1|, ... |sigma1|*|sigma2|, |sigma1|, 1)
// reverse order guarantees that the first alphabet is the most significant rank contributer
// resulting in element-wise alphabetical ordering on comparison
std::array<rank_type, component_list::size()> ret2{};
for (size_t i = 0; i < component_list::size(); ++i)
ret2[i] = ret[component_list::size() - i - 1];
return ret2;
}()};
static constexpr std::array < std::array<rank_type,
alphabet_size<1024u ? alphabet_size : 0u>, // not for big alphs
list_traits::size<component_list>>
rank_to_component_rank{
[]() constexpr
{
std::array < std::array<rank_type,
alphabet_size<1024u ? alphabet_size : 0u>, // not for big alphs
list_traits::size<component_list>>
ret{};
if constexpr (alphabet_size < 1024u)
{
std::array<size_t, alphabet_size> alph_sizes{seqan3::alphabet_size<component_types>...};
for (size_t i = 0; i < list_traits::size<component_list>; ++i)
for (size_t j = 0; j < static_cast<size_t>(alphabet_size); ++j)
ret[i][j] = (j / cummulative_alph_sizes[i]) % alph_sizes[i];
}
return ret;
}()};
};
template <typename derived_type, typename... component_types>
requires (detail::writable_constexpr_semialphabet<component_types> && ...) && (std::regular<component_types> && ...)
template <typename alphabet_type, size_t index>
class alphabet_tuple_base<derived_type, component_types...>::component_proxy :
public alphabet_proxy<component_proxy<alphabet_type, index>, alphabet_type>
{
private:
using base_t = alphabet_proxy<component_proxy<alphabet_type, index>, alphabet_type>;
friend base_t;
alphabet_tuple_base * parent;
constexpr void on_update() noexcept
{
parent->assign_component_rank<index>(this->to_rank());
}
public:
//Import from base type:
using base_t::operator=;
component_proxy() = delete;
constexpr component_proxy(component_proxy const &) = default;
constexpr component_proxy(component_proxy &&) = default;
constexpr component_proxy & operator=(component_proxy const &) = default;
constexpr component_proxy & operator=(component_proxy &&) = default;
~component_proxy() = default;
constexpr component_proxy(alphabet_type const l, alphabet_tuple_base & p) : base_t{l}, parent{&p}
{}
// Does not inherit the base's constructor for alphabet_type so as not to cause ambiguity
friend constexpr bool operator==(derived_type const lhs, component_proxy const rhs) noexcept
{
return get<index>(lhs) == static_cast<alphabet_type>(rhs);
}
friend constexpr bool operator==(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
{
return rhs == lhs;
}
friend constexpr bool operator!=(derived_type const lhs, component_proxy const rhs) noexcept
{
return get<index>(lhs) != static_cast<alphabet_type>(rhs);
}
friend constexpr bool operator!=(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
{
return rhs != lhs;
}
friend constexpr bool operator<(derived_type const lhs, component_proxy const rhs) noexcept
{
return get<index>(lhs) < static_cast<alphabet_type>(rhs);
}
friend constexpr bool operator<(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
{
return rhs > lhs;
}
friend constexpr bool operator<=(derived_type const lhs, component_proxy const rhs) noexcept
{
return get<index>(lhs) <= static_cast<alphabet_type>(rhs);
}
friend constexpr bool operator<=(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
{
return rhs >= lhs;
}
friend constexpr bool operator>(derived_type const lhs, component_proxy const rhs) noexcept
{
return get<index>(lhs) > static_cast<alphabet_type>(rhs);
}
friend constexpr bool operator>(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
{
return rhs < lhs;
}
friend constexpr bool operator>=(derived_type const lhs, component_proxy const rhs) noexcept
{
return get<index>(lhs) >= static_cast<alphabet_type>(rhs);
}
friend constexpr bool operator>=(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
{
return rhs <= lhs;
}
};
} // namespace seqan3
namespace std
{
template <std::size_t i, seqan3::detail::alphabet_tuple_like tuple_t>
struct tuple_element<i, tuple_t>
{
using type = seqan3::list_traits::at<i, typename tuple_t::seqan3_required_types>;
};
template <seqan3::detail::alphabet_tuple_like tuple_t>
struct tuple_size<tuple_t> :
public std::integral_constant<size_t, seqan3::list_traits::size<typename tuple_t::seqan3_required_types>>
{};
} // namespace std
detail.hpp
Provides implementation detail for seqan3::alphabet_variant and seqan3::alphabet_tuple_base.
concept.hpp
Core alphabet concept and free function/type trait wrappers.
alphabet_base.hpp
Provides seqan3::alphabet_base.
alphabet_proxy.hpp
Provides seqan3::alphabet_proxy.
cassert
seqan3::alphabet_base< derived_type,(1 *... *alphabet_size< component_types >), void >::alphabet_base
constexpr alphabet_base() noexcept=default
seqan3::alphabet_base< derived_type,(1 *... *alphabet_size< component_types >), void >::to_rank
constexpr rank_type to_rank() const noexcept
Definition alphabet_base.hpp:134
seqan3::alphabet_base< derived_type,(1 *... *alphabet_size< component_types >), void >::rank_type
detail::min_viable_uint_t< size - 1 > rank_type
Definition alphabet_base.hpp:77
seqan3::alphabet_base< derived_type,(1 *... *alphabet_size< component_types >), void >::alphabet_size
static constexpr detail::min_viable_uint_t< size > alphabet_size
Definition alphabet_base.hpp:196
seqan3::alphabet_base< derived_type,(1 *... *alphabet_size< component_types >), void >::assign_rank
constexpr derived_type & assign_rank(rank_type const c) noexcept
Definition alphabet_base.hpp:184
seqan3::alphabet_proxy
A CRTP-base that eases the definition of proxy types returned in place of regular alphabets.
Definition alphabet_proxy.hpp:62
seqan3::alphabet_tuple_base
The CRTP base for a combined alphabet that contains multiple values of different alphabets at the sam...
Definition alphabet_tuple_base.hpp:113
seqan3::alphabet_tuple_base::get
friend constexpr auto get(alphabet_tuple_base &l) noexcept
Tuple-like access to the contained components.
Definition alphabet_tuple_base.hpp:345
seqan3::alphabet_tuple_base::get
friend constexpr type get(alphabet_tuple_base const &l) noexcept
Tuple-like access to the contained components.
Definition alphabet_tuple_base.hpp:393
seqan3::alphabet_tuple_base::assign_rank
constexpr derived_type & assign_rank(rank_type const c) noexcept
Assign from a numeric value.
Definition alphabet_base.hpp:184
seqan3::alphabet_tuple_base::operator=
constexpr derived_type & operator=(indirect_component_type const alph) noexcept
Assignment via a value of a subtype that is assignable to one of the components.
Definition alphabet_tuple_base.hpp:288
seqan3::alphabet_tuple_base::operator==
friend constexpr auto operator==(indirect_component_type const lhs, derived_type_t const rhs) noexcept -> std::enable_if_t< detail::tuple_eq_guard< derived_type_t, derived_type, indirect_component_type, component_types... >, bool >
Definition alphabet_tuple_base.hpp:443
seqan3::alphabet_tuple_base::operator>=
friend constexpr auto operator>=(derived_type_t const lhs, indirect_component_type const rhs) noexcept -> std::enable_if_t< detail::tuple_order_guard< derived_type_t, derived_type, indirect_component_type, component_types... >, bool >
Definition alphabet_tuple_base.hpp:549
seqan3::alphabet_tuple_base::alphabet_size
static constexpr detail::min_viable_uint_t< size > alphabet_size
The size of the alphabet, i.e. the number of different values it can take.
Definition alphabet_base.hpp:196
seqan3::alphabet_tuple_base::operator<=
friend constexpr auto operator<=(indirect_component_type const lhs, derived_type_t const rhs) noexcept -> std::enable_if_t< detail::tuple_order_guard< derived_type_t, derived_type, indirect_component_type, component_types... >, bool >
Definition alphabet_tuple_base.hpp:515
seqan3::alphabet_tuple_base::operator<
friend constexpr auto operator<(derived_type_t const lhs, indirect_component_type const rhs) noexcept -> std::enable_if_t< detail::tuple_order_guard< derived_type_t, derived_type, indirect_component_type, component_types... >, bool >
Definition alphabet_tuple_base.hpp:477
seqan3::alphabet_tuple_base::operator>
friend constexpr auto operator>(indirect_component_type const lhs, derived_type_t const rhs) noexcept -> std::enable_if_t< detail::tuple_order_guard< derived_type_t, derived_type, indirect_component_type, component_types... >, bool >
Definition alphabet_tuple_base.hpp:539
seqan3::alphabet_tuple_base::get
friend constexpr auto get(alphabet_tuple_base &l) noexcept
Tuple-like access to the contained components.
Definition alphabet_tuple_base.hpp:364
seqan3::alphabet_tuple_base::alphabet_tuple_base
constexpr alphabet_tuple_base(indirect_component_type const alph) noexcept
Construction via a value of a subtype that is assignable to one of the components.
Definition alphabet_tuple_base.hpp:224
seqan3::alphabet_tuple_base::alphabet_tuple_base
constexpr alphabet_tuple_base(component_type const alph) noexcept
Construction via a value of one of the components.
Definition alphabet_tuple_base.hpp:199
seqan3::alphabet_tuple_base::operator>
friend constexpr auto operator>(derived_type_t const lhs, indirect_component_type const rhs) noexcept -> std::enable_if_t< detail::tuple_order_guard< derived_type_t, derived_type, indirect_component_type, component_types... >, bool >
Definition alphabet_tuple_base.hpp:525
seqan3::alphabet_tuple_base::operator<
friend constexpr auto operator<(indirect_component_type const lhs, derived_type_t const rhs) noexcept -> std::enable_if_t< detail::tuple_order_guard< derived_type_t, derived_type, indirect_component_type, component_types... >, bool >
Definition alphabet_tuple_base.hpp:491
seqan3::alphabet_tuple_base::operator>=
friend constexpr auto operator>=(indirect_component_type const lhs, derived_type_t const rhs) noexcept -> std::enable_if_t< detail::tuple_order_guard< derived_type_t, derived_type, indirect_component_type, component_types... >, bool >
Definition alphabet_tuple_base.hpp:563
seqan3::alphabet_tuple_base::operator!=
friend constexpr auto operator!=(derived_type_t const lhs, indirect_component_type const rhs) noexcept -> std::enable_if_t< detail::tuple_eq_guard< derived_type_t, derived_type, indirect_component_type, component_types... >, bool >
Definition alphabet_tuple_base.hpp:453
seqan3::alphabet_tuple_base::alphabet_tuple_base
constexpr alphabet_tuple_base(component_types... components) noexcept
Construction from initialiser-list.
Definition alphabet_tuple_base.hpp:182
seqan3::alphabet_tuple_base::operator!=
friend constexpr auto operator!=(indirect_component_type const lhs, derived_type_t const rhs) noexcept -> std::enable_if_t< detail::tuple_eq_guard< derived_type_t, derived_type, indirect_component_type, component_types... >, bool >
Definition alphabet_tuple_base.hpp:467
seqan3::alphabet_tuple_base::operator==
friend constexpr auto operator==(derived_type_t const lhs, indirect_component_type const rhs) noexcept -> std::enable_if_t< detail::tuple_eq_guard< derived_type_t, derived_type, indirect_component_type, component_types... >, bool >
Comparison against types comparable with components.
Definition alphabet_tuple_base.hpp:429
seqan3::alphabet_tuple_base::to_rank
constexpr rank_type to_rank() const noexcept
Return the letter's numeric value (rank in the alphabet).
Definition alphabet_base.hpp:134
seqan3::alphabet_tuple_base::operator<=
friend constexpr auto operator<=(derived_type_t const lhs, indirect_component_type const rhs) noexcept -> std::enable_if_t< detail::tuple_order_guard< derived_type_t, derived_type, indirect_component_type, component_types... >, bool >
Definition alphabet_tuple_base.hpp:501
seqan3::alphabet_tuple_base::get
friend constexpr auto get(alphabet_tuple_base const &l) noexcept
Tuple-like access to the contained components.
Definition alphabet_tuple_base.hpp:377
std::enable_if_t
seqan3::alphabet_size
constexpr auto alphabet_size
A type trait that holds the size of a (semi-)alphabet.
Definition alphabet/concept.hpp:834
seqan3::assign_rank_to
constexpr auto assign_rank_to
Assign a rank to an alphabet object.
Definition alphabet/concept.hpp:288
seqan3::to_rank
constexpr auto to_rank
Return the rank representation of a (semi-)alphabet object.
Definition alphabet/concept.hpp:152
seqan3::list_traits::contains
constexpr bool contains
Whether a type occurs in a type list or not.
Definition type_list/traits.hpp:249
seqan3::list_traits::at
typename decltype(detail::at< idx >(list_t{}))::type at
Return the type at given index from the type list.
Definition type_list/traits.hpp:276
seqan3::list_traits::concat
decltype(detail::concat(lists_t{}...)) concat
Join two seqan3::type_list s into one.
Definition type_list/traits.hpp:339
seqan3::pack_traits::at
typename decltype(detail::at< idx, pack_t... >())::type at
Return the type at given index from the type pack.
Definition type_pack/traits.hpp:245
seqan3::pack_traits::count
constexpr ptrdiff_t count
Count the occurrences of a type in a pack.
Definition type_pack/traits.hpp:161
integer_traits.hpp
Provides metaprogramming utilities for integer types.
std::make_index_sequence
std::integral_constant
std::is_base_of_v
T is_base_of_v
seqan3
The main SeqAn3 namespace.
Definition aligned_sequence_concept.hpp:26
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.
seqan3::type_list
Type that contains multiple types.
Definition type_list.hpp:26
seqan3::type_list< component_types... >::size
static constexpr size_t size() noexcept
Definition type_list.hpp:31
std::tuple_element< i, tuple_t >::type
seqan3::list_traits::at< i, typename tuple_t::seqan3_required_types > type
Element type.
Definition alphabet_tuple_base.hpp:807
transformation_trait_or.hpp
Provides seqan3::detail::transformation_trait_or.
traits.hpp
Provides traits for seqan3::type_list.
seqan3::list_traits::detail::reverse
constexpr type_list reverse(type_list<>)
A replacement for meta::reverse [recursion anchor].
Definition type_list/traits.hpp:123
type_list.hpp
Provides seqan3::type_list.
type_list_algorithm.hpp
Provides algorithms for meta programming, parameter packs and seqan3::type_list.
traits.hpp
Provides various traits for template packs.
concept.hpp
Provides seqan3::tuple_like.
utility
Hide me