Loading...
Searching...
No Matches
alphabet_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 <seqan3/alphabet/alphabet_base.hpp>
#include <seqan3/alphabet/detail/concept.hpp>
#include <seqan3/alphabet/nucleotide/concept.hpp>
#include <seqan3/alphabet/quality/concept.hpp>
#include <seqan3/core/detail/template_inspection.hpp>
#include <seqan3/utility/concept.hpp>
#include <seqan3/utility/type_traits/basic.hpp>
namespace seqan3
{
template <typename derived_type, writable_semialphabet alphabet_type>
requires std::regular<alphabet_type>
class alphabet_proxy :
public std::conditional_t<std::is_class_v<alphabet_type>,
alphabet_type,
alphabet_base<derived_type,
alphabet_size<alphabet_type>,
detail::valid_template_spec_or_t<void, alphabet_char_t, alphabet_type>>>
{
private:
using base_t =
std::conditional_t<std::is_class_v<alphabet_type>,
alphabet_type, // inherit from emulated type if possible
alphabet_base<derived_type, // else: alphabet_base
alphabet_size<alphabet_type>,
detail::valid_template_spec_or_t<void, alphabet_char_t, alphabet_type>>>;
friend base_t;
using char_type = detail::valid_template_spec_or_t<char, alphabet_char_t, alphabet_type>;
using phred_type = detail::valid_template_spec_or_t<int8_t, alphabet_phred_t, alphabet_type>;
private:
constexpr alphabet_proxy() noexcept = default;
constexpr alphabet_proxy(alphabet_proxy const &) = default;
constexpr alphabet_proxy(alphabet_proxy &&) = default;
constexpr alphabet_proxy & operator=(alphabet_proxy const &) = default;
constexpr alphabet_proxy & operator=(alphabet_proxy &&) = default;
~alphabet_proxy() = default;
constexpr alphabet_proxy(alphabet_type const a) noexcept
requires std::is_class_v<alphabet_type>
: base_t{a}
{}
constexpr alphabet_proxy(alphabet_type const a) noexcept
requires (!std::is_class_v<alphabet_type>)
: base_t{}
{
base_t::assign_rank(seqan3::to_rank(a));
}
constexpr derived_type & operator=(alphabet_type const & c) noexcept
{
if constexpr (std::is_class_v<alphabet_type>)
seqan3::assign_rank_to(seqan3::to_rank(c), static_cast<alphabet_type &>(*this));
else
base_t::assign_rank(seqan3::to_rank(c));
static_cast<derived_type &>(*this).on_update(); // <- this invokes the actual proxy behaviour!
return static_cast<derived_type &>(*this);
}
template <typename indirect_assignable_type>
constexpr derived_type & operator=(indirect_assignable_type const & c) noexcept
requires weakly_assignable_from<alphabet_type, indirect_assignable_type>
{
alphabet_type a{};
a = c;
return operator=(a);
}
friend derived_type;
public:
static constexpr auto alphabet_size = seqan3::alphabet_size<alphabet_type>;
constexpr derived_type & assign_rank(alphabet_rank_t<alphabet_type> const r) noexcept
{
alphabet_type tmp{};
assign_rank_to(r, tmp);
return operator=(tmp);
}
constexpr derived_type & assign_char(char_type const c) noexcept
requires writable_alphabet<alphabet_type>
{
alphabet_type tmp{};
assign_char_to(c, tmp);
return operator=(tmp);
}
constexpr derived_type & assign_phred(phred_type const c) noexcept
requires writable_quality_alphabet<alphabet_type>
{
alphabet_type tmp{};
assign_phred_to(c, tmp);
return operator=(tmp);
}
constexpr operator alphabet_type() const noexcept
{
if constexpr (std::is_class_v<alphabet_type>)
return *this;
else
return assign_rank_to(base_t::to_rank(), alphabet_type{});
/* Instead of static_cast'ing to the alphabet_type which also considers the constructors of the alphabet_type,
* we explicitly invoke this operator in various places.
* This prevents errors associated with using alphabet_type's constructors.
*
* This is one of error cases:
* The tuple composite seqan3::qualified returns a component_proxy which inherits from alphabet_proxy_base.
* The qualified alphabet itself inherits from phred_base.
* Now when accessing get<1>(seq_qual_alph) we want to call to_phred at some point because we want the quality,
* therefore the to_phred function from alphabet_proxy is called, but this function did a static_cast to the
* derived type which is calling the constructor from phred_base. Unfortunately now, the generic phred_base
* constructor uses `assign_phred_to(to_phred(other), static_cast<derived_type &>(*this))`; (here) which again
* tries to call to_phred of the alphabet_proxy => infinite loop :boom:
*/
}
template <typename other_t>
requires (!std::is_class_v<alphabet_type>) && std::convertible_to<alphabet_type, other_t>
constexpr operator other_t() const noexcept
{
return operator alphabet_type();
}
constexpr auto to_rank() const noexcept
{
return seqan3::to_rank(operator alphabet_type());
}
constexpr auto to_char() const noexcept
requires alphabet<alphabet_type>
{
return seqan3::to_char(operator alphabet_type());
}
constexpr auto to_phred() const noexcept
requires quality_alphabet<alphabet_type>
{
return seqan3::to_phred(operator alphabet_type());
}
constexpr alphabet_type complement() const noexcept
requires nucleotide_alphabet<alphabet_type>
{
return seqan3::complement(operator alphabet_type());
}
static constexpr bool char_is_valid(char_type const c) noexcept
requires writable_alphabet<alphabet_type>
{
return char_is_valid_for<alphabet_type>(c);
}
private:
template <typename t>
static constexpr bool is_alphabet_comparable_with =
!std::is_same_v<derived_type, t> && detail::weakly_equality_comparable_with<alphabet_type, t>;
public:
template <typename t>
friend constexpr auto operator==(derived_type const lhs,
t const rhs) noexcept -> std::enable_if_t<is_alphabet_comparable_with<t>, bool>
{
return (lhs.operator alphabet_type() == rhs);
}
template <typename t>
friend constexpr auto
operator==(t const lhs, derived_type const rhs) noexcept -> std::enable_if_t<is_alphabet_comparable_with<t>, bool>
{
return (rhs == lhs);
}
template <typename t>
friend constexpr auto operator!=(derived_type const lhs,
t const rhs) noexcept -> std::enable_if_t<is_alphabet_comparable_with<t>, bool>
{
return !(lhs == rhs);
}
template <typename t>
friend constexpr auto
operator!=(t const lhs, derived_type const rhs) noexcept -> std::enable_if_t<is_alphabet_comparable_with<t>, bool>
{
return (rhs != lhs);
}
};
} // namespace seqan3
concept.hpp
Provides alphabet helper concepts.
concept.hpp
Provides seqan3::nucleotide_alphabet.
concept.hpp
Quality alphabet concept.
alphabet_base.hpp
Provides seqan3::alphabet_base.
basic.hpp
Provides various type traits on generic types.
seqan3::alphabet_base
A CRTP-base that makes defining a custom alphabet easier.
Definition alphabet_base.hpp:54
seqan3::alphabet_proxy::operator!=
friend constexpr auto operator!=(derived_type const lhs, t const rhs) noexcept -> std::enable_if_t< is_alphabet_comparable_with< t >, bool >
Allow (in-)equality comparison with types that the emulated type is comparable with.
Definition alphabet_proxy.hpp:269
seqan3::alphabet_proxy::assign_char
constexpr derived_type & assign_char(char_type const c) noexcept
Assigns a character.
Definition alphabet_proxy.hpp:150
seqan3::alphabet_proxy::assign_rank
constexpr derived_type & assign_rank(alphabet_rank_t< alphabet_type > const r) noexcept
Assigns a rank.
Definition alphabet_proxy.hpp:142
seqan3::alphabet_proxy::alphabet_size
static constexpr auto alphabet_size
The alphabet size.
Definition alphabet_proxy.hpp:134
seqan3::alphabet_proxy::assign_phred
constexpr derived_type & assign_phred(phred_type const c) noexcept
Assigns a Phred score.
Definition alphabet_proxy.hpp:159
seqan3::alphabet_proxy::operator!=
friend constexpr auto operator!=(t const lhs, derived_type const rhs) noexcept -> std::enable_if_t< is_alphabet_comparable_with< t >, bool >
Allow (in-)equality comparison with types that the emulated type is comparable with.
Definition alphabet_proxy.hpp:278
seqan3::alphabet_proxy::operator==
friend constexpr auto operator==(t const lhs, derived_type const rhs) noexcept -> std::enable_if_t< is_alphabet_comparable_with< t >, bool >
Allow (in-)equality comparison with types that the emulated type is comparable with.
Definition alphabet_proxy.hpp:262
seqan3::alphabet_proxy::operator==
friend constexpr auto operator==(derived_type const lhs, t const rhs) noexcept -> std::enable_if_t< is_alphabet_comparable_with< t >, bool >
Allow (in-)equality comparison with types that the emulated type is comparable with.
Definition alphabet_proxy.hpp:253
seqan3::alphabet_proxy::complement
constexpr alphabet_type complement() const noexcept
Returns the complement.
Definition alphabet_proxy.hpp:224
seqan3::alphabet_proxy::to_char
constexpr auto to_char() const noexcept
Returns the character.
Definition alphabet_proxy.hpp:210
seqan3::alphabet_proxy::to_phred
constexpr auto to_phred() const noexcept
Returns the Phred score.
Definition alphabet_proxy.hpp:217
seqan3::alphabet_proxy::to_rank
constexpr auto to_rank() const noexcept
Returns the rank.
Definition alphabet_proxy.hpp:204
seqan3::alphabet_proxy::char_is_valid
static constexpr bool char_is_valid(char_type const c) noexcept
Delegate to the emulated type's validator.
Definition alphabet_proxy.hpp:231
std::conditional_t
std::enable_if_t
seqan3::complement
constexpr auto complement
Return the complement of a nucleotide object.
Definition alphabet/nucleotide/concept.hpp:102
seqan3::assign_char_to
constexpr auto assign_char_to
Assign a character to an alphabet object.
Definition alphabet/concept.hpp:517
seqan3::to_char
constexpr auto to_char
Return the char representation of an alphabet object.
Definition alphabet/concept.hpp:381
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::alphabet_rank_t
decltype(seqan3::to_rank(std::declval< semi_alphabet_type >())) alphabet_rank_t
The rank_type of the semi-alphabet; defined as the return type of seqan3::to_rank....
Definition alphabet/concept.hpp:164
seqan3::char_is_valid_for
constexpr auto char_is_valid_for
Returns whether a character is in the valid set of a seqan3::alphabet (usually implies a bijective ma...
Definition alphabet/concept.hpp:661
seqan3::to_rank
constexpr auto to_rank
Return the rank representation of a (semi-)alphabet object.
Definition alphabet/concept.hpp:152
alphabet
The generic alphabet concept that covers most data types used in ranges.
nucleotide_alphabet
A concept that indicates whether an alphabet represents nucleotides.
quality_alphabet
A concept that indicates whether an alphabet represents quality scores.
weakly_assignable_from
Resolves to std::is_assignable_v<t>.
writable_alphabet
Refines seqan3::alphabet and adds assignability.
writable_quality_alphabet
A concept that indicates whether a writable alphabet represents quality scores.
std::is_class_v
T is_class_v
std::is_same_v
T is_same_v
seqan3
The main SeqAn3 namespace.
Definition aligned_sequence_concept.hpp:26
seqan3::to_phred
constexpr auto to_phred
The public getter function for the Phred representation of a quality score.
Definition alphabet/quality/concept.hpp:97
seqan3::assign_phred_to
constexpr auto assign_phred_to
Assign a Phred score to a quality alphabet object.
Definition alphabet/quality/concept.hpp:225
template_inspection.hpp
Provides type traits for working with templates.
concept.hpp
Provides concepts that do not have equivalents in C++20.
Hide me