BioC++ core-0.7.0
The Modern C++ libraries for Bioinformatics.
 
Loading...
Searching...
No Matches
bio::alphabet::variant< alternative_types > Class Template Reference

A combined alphabet that can hold values of either of its alternatives.. More...

#include <bio/alphabet/composite/variant.hpp>

+ Inheritance diagram for bio::alphabet::variant< alternative_types >:

Public Member Functions

Constructors, destructor and assignment
constexpr variant () noexcept=default
 Defaulted.
 
constexpr variant (variant const &) noexcept=default
 Defaulted.
 
constexpr variant (variant &&) noexcept=default
 Defaulted.
 
constexpr variantoperator= (variant const &) noexcept=default
 Defaulted.
 
constexpr variantoperator= (variant &&) noexcept=default
 Defaulted.
 
 ~variant () noexcept=default
 Defaulted.
 
template<typename alternative_t >
requires (is_alternative<alternative_t>())
constexpr variant (alternative_t const alternative) noexcept
 Construction via the value of an alternative.
 
template<typename indirect_alternative_t >
requires (detail::variant_general_guard<indirect_alternative_t, alternative_types...> && (std::is_convertible_v<indirect_alternative_t, alternative_types> || ...))
constexpr variant (indirect_alternative_t const rhs) noexcept
 Constructor for arguments implicitly convertible to an alternative.
 
template<typename indirect_alternative_t >
requires (detail::variant_general_guard<indirect_alternative_t, alternative_types...> && !(std::is_convertible_v<indirect_alternative_t, alternative_types> || ...) && (std::is_constructible_v<alternative_types, indirect_alternative_t> || ...))
constexpr variant (indirect_alternative_t const rhs) noexcept
 Constructor for arguments explicitly (but not implicitly) convertible to an alternative.
 
template<typename indirect_alternative_t >
requires (detail::variant_general_guard<indirect_alternative_t, alternative_types...> && (meta::weakly_assignable_from<alternative_types, indirect_alternative_t> || ...))
constexpr variantoperator= (indirect_alternative_t const &rhs) noexcept
 Assignment for arguments assignable to an alternative.
 
Conversion (by index)
template<size_t index>
constexpr bool holds_alternative () const noexcept
 Whether the variant alphabet currently holds a value of the given alternative.
 
template<size_t index>
constexpr auto convert_to () const
 Convert to the specified alphabet (throws if holds_alternative() would be false).
 
template<size_t index>
constexpr auto convert_unsafely_to () const noexcept
 Convert to the specified alphabet (undefined behaviour if holds_alternative() would be false).
 
Conversion (by type)
template<typename alternative_t >
requires (is_alternative<alternative_t>())
constexpr bool holds_alternative () const noexcept
 Whether the variant alphabet currently holds a value of the given alternative.
 
template<typename alternative_t >
requires (is_alternative<alternative_t>())
constexpr alternative_t convert_to () const
 Convert to the specified alphabet (throws if holds_alternative() would be false).
 
template<typename alternative_t >
requires (is_alternative<alternative_t>())
constexpr alternative_t convert_unsafely_to () const noexcept
 Convert to the specified alphabet (undefined behaviour if holds_alternative() would be false).
 
Read functions
constexpr char_type to_char () const noexcept
 Return the letter as a character of char_type.
 
constexpr rank_type to_rank () const noexcept
 Return the letter's numeric value (rank in the alphabet).
 
Write functions
constexpr variant< alternative_types... > & assign_char (char_type const c) noexcept
 Assign from a character, implicitly converts invalid characters.
 
constexpr variant< alternative_types... > & assign_rank (rank_type const c) noexcept
 Assign from a numeric value.
 

Static Public Member Functions

static constexpr bool char_is_valid (char_type const chr) noexcept
 Validate whether a character is valid in the combined alphabet.
 
template<typename alternative_t >
static constexpr bool is_alternative () noexcept
 Returns true if alternative_t is one of the given alternative types.
 

Static Public Attributes

static constexpr size_t alphabet_size
 The size of the alphabet, i.e. the number of different values it can take.
 

Protected Types

Member types
using char_type = std::conditional_t< std::same_as< char, void >, char, char >
 The char representation; conditional needed to make semi alphabet definitions legal.
 
using rank_type = meta::detail::min_viable_uint_t< size - 1 >
 The type of the alphabet when represented as a number (e.g. via to_rank()).
 

Friends

Comparison operators (against indirect alternatives)

Defines comparison against types that are not subject to implicit construction/conversion but are comparable against alternatives, e.g. variant<bio::alphabet::rna4, bio::alphabet::gap> vs variant<bio::alphabet::dna4, bio::alphabet::gap>. Only (in-)equality comparison is defined as reasoning about order of variants is inherently difficult.

template<std::same_as< variant > variant_t, typename indirect_alternative_type >
requires ((detail::variant_general_guard<indirect_alternative_type, alternative_types...>) && (meta::weakly_equality_comparable_with<indirect_alternative_type, alternative_types> || ...))
constexpr bool operator== (variant_t const lhs, indirect_alternative_type const rhs) noexcept
 (In-)Equality comparison against types comparable with alternatives but not convertible to the variant.
 

Detailed Description

template<typename... alternative_types>
requires ((detail::writable_constexpr_alphabet<alternative_types> && ...) && (std::regular<alternative_types> && ...) && (sizeof...(alternative_types) >= 2))
class bio::alphabet::variant< alternative_types >

A combined alphabet that can hold values of either of its alternatives.

.

Template Parameters
...alternative_typesTypes of possible values (at least 2); all must model bio::alphabet::writable_alphabet, std::regular and must be unique; all required functions for bio::alphabet::writable_alphabet need to be callable in a constexpr-context.

The variant represents the union of two or more alternative alphabets (e.g. the four letter DNA alternative + the gap alternative). It behaves similar to a variant or std::variant, but it preserves the bio::alphabet::alphabet.

Short description:

  • combines multiple different alphabets in an "either-or"-fashion;
  • is itself a bio::alphabet::alphabet;
  • its alphabet size is the sum of the individual sizes;
  • default initialises to the the first alternative's default (no empty state like std::variant);
  • constructible, assignable and (in-)equality-comparable with each alternative type and also all types that these are constructible/assignable/equality-comparable with;
  • only convertible to its alternatives through the member function convert_to() (which can throw!)

Example

int main()
{
using namespace bio::alphabet::literals;
using namespace bio::alphabet::literals;
bio::alphabet::variant<bio::alphabet::dna5, bio::alphabet::gap> letter2{'C'_dna5}; // constructed from alternative (== 'C'_dna5)
bio::alphabet::variant<bio::alphabet::dna5, bio::alphabet::gap> letter3{'U'_rna5}; // constructed from type that alternative is constructible from (== 'T'_dna5)
letter2.assign_char('T'); // == 'T'_dna5
letter2.assign_char('-'); // == gap{}
letter2.assign_char('K'); // unknown characters map to the default/unknown
// character of the first alternative type (== 'N'_dna5)
letter2 = bio::alphabet::gap{}; // assigned from alternative (== gap{})
letter2 = 'U'_rna5; // assigned from type that alternative is assignable from (== 'T'_dna5)
bio::alphabet::dna5 letter4 = letter2.convert_to<bio::alphabet::dna5>();
}
Meta-header for the nucleotide submodule; includes all headers from alphabet/nucleotide/.
constexpr derived_type & assign_char(char_type const c) noexcept
Assign from a character, implicitly converts invalid characters.
Definition: base.hpp:145
The five letter DNA alphabet of A,C,G,T and the unknown character N..
Definition: dna5.hpp:50
The alphabet of a gap character '-'.
Definition: gap.hpp:38
A combined alphabet that can hold values of either of its alternatives..
Definition: variant.hpp:104
Provides bio::alphabet::gap.
An inline namespace for alphabet literals. It exists to safely allow using namespace.
Definition: aa10li.hpp:183
Provides bio::alphabet::variant.

The char representation of an variant

Part of the bio::alphabet::alphabet concept requires that the variant provides a char representation in addition to the rank representation. For an object of bio::alphabet::variant, the to_char() member function will always return the same character as if invoked on the respective alternative. In contrast, the assign_char() member function might be ambiguous between the alternative alphabets in a variant.

For example, assigning a '!' to bio::alphabet::dna15 resolves to an object of rank 8 with char representation 'N' while assigning '!' to bio::alphabet::gap always resolves to rank 0, the gap symbol itself ('-'_gap). We tackle this ambiguousness by defaulting unknown characters to the representation of the first alternative (e.g. ‘variant<dna15, gap>{}.assign_char(’!')resolves to rank 8, representingN`_dna15).

On the other hand, two alternative alphabets might have the same char representation (e.g if you combine dna4 with dna5, 'A', 'C', 'G' and 'T' are ambiguous). We tackle this ambiguousness by always choosing the first valid char representation (e.g. ‘variant<dna4, dna5>{}.assign_char('A’)resolves to rank 0, representing anA`_dna4).

To explicitly assign via the character representation of a specific alphabet, assign to that type first and then assign to the variant, e.g.

int main()
{
using namespace bio::alphabet::literals;
var.assign_char('A'); // will be in the "dna4-state"
var = 'A'_dna5; // will be in the "dna5-state"
}

Constructor & Destructor Documentation

◆ variant() [1/3]

template<typename... alternative_types>
template<typename alternative_t >
requires (is_alternative<alternative_t>())
constexpr bio::alphabet::variant< alternative_types >::variant ( alternative_t const  alternative)
inlineconstexprnoexcept

Construction via the value of an alternative.

Template Parameters
alternative_tOne of the alternative types.
Parameters
alternativeThe value of a alternative that should be assigned.

◆ variant() [2/3]

template<typename... alternative_types>
template<typename indirect_alternative_t >
requires (detail::variant_general_guard<indirect_alternative_t, alternative_types...> && (std::is_convertible_v<indirect_alternative_t, alternative_types> || ...))
constexpr bio::alphabet::variant< alternative_types >::variant ( indirect_alternative_t const  rhs)
inlineconstexprnoexcept

Constructor for arguments implicitly convertible to an alternative.

Template Parameters
indirect_alternative_tA type that is implicitly convertible to an alternative type.
Parameters
rhsThe value that should be assigned.

This constructor is preferred over the explicit version.

Example

  • bio::alphabet::dna4 and bio::alphabet::rna4 are implicitly convertible to each other so the variant accepts either.
  • Construction via {} considers implicit and explicit conversions.
  • Construction via = considers only implicit conversions (but that is sufficient here).

◆ variant() [3/3]

template<typename... alternative_types>
template<typename indirect_alternative_t >
requires (detail::variant_general_guard<indirect_alternative_t, alternative_types...> && !(std::is_convertible_v<indirect_alternative_t, alternative_types> || ...) && (std::is_constructible_v<alternative_types, indirect_alternative_t> || ...))
constexpr bio::alphabet::variant< alternative_types >::variant ( indirect_alternative_t const  rhs)
inlineexplicitconstexprnoexcept

Constructor for arguments explicitly (but not implicitly) convertible to an alternative.

Template Parameters
indirect_alternative_tA type that is explicitly (but not implicitly) convertible to an alternative type.
Parameters
rhsThe value that should be assigned.

Example

int main()
{
using namespace bio::alphabet::literals;
// possible:
// not possible:
// bio::alphabet::variant<bio::alphabet::dna4, bio::alphabet::gap> letter2 = 'C'_dna5;
}
  • bio::alphabet::dna4 and bio::alphabet::dna5 are not implicitly convertible to each other, only explicitly.
  • Construction via {} considers implicit and explicit conversions so this works.
  • Construction via = considers only implicit conversions so it does not work.

Member Function Documentation

◆ assign_char()

constexpr variant< alternative_types... > & bio::alphabet::base< variant< alternative_types... > , size, char >::assign_char ( char_type const  c)
inlineconstexprnoexceptinherited

Assign from a character, implicitly converts invalid characters.

Parameters
cThe character to be assigned.

Provides an implementation for bio::alphabet::assign_char_to, required to model bio::alphabet::alphabet.

Complexity

Constant.

Exceptions

Guaranteed not to throw.

◆ assign_rank()

constexpr variant< alternative_types... > & bio::alphabet::base< variant< alternative_types... > , size, char >::assign_rank ( rank_type const  c)
inlineconstexprnoexceptinherited

Assign from a numeric value.

Parameters
cThe rank to be assigned.

Provides an implementation for bio::alphabet::assign_rank_to, required to model bio::alphabet::semialphabet.

Complexity

Constant.

Exceptions

Guaranteed not to throw.

◆ char_is_valid()

template<typename... alternative_types>
static constexpr bool bio::alphabet::variant< alternative_types >::char_is_valid ( char_type const  chr)
inlinestaticconstexprnoexcept

Validate whether a character is valid in the combined alphabet.

◆ convert_to() [1/2]

template<typename... alternative_types>
template<size_t index>
constexpr auto bio::alphabet::variant< alternative_types >::convert_to ( ) const
inlineconstexpr

Convert to the specified alphabet (throws if holds_alternative() would be false).

Template Parameters
indexIndex of the alternative to check for.
Exceptions
std::bad_variant_accessIf the variant_alphabet currently holds the value of a different alternative.

◆ convert_to() [2/2]

template<typename... alternative_types>
template<typename alternative_t >
requires (is_alternative<alternative_t>())
constexpr alternative_t bio::alphabet::variant< alternative_types >::convert_to ( ) const
inlineconstexpr

Convert to the specified alphabet (throws if holds_alternative() would be false).

Template Parameters
alternative_tThe type of the alternative that you wish to check for.
Exceptions
std::bad_variant_accessIf the variant_alphabet currently holds the value of a different alternative.

◆ convert_unsafely_to() [1/2]

template<typename... alternative_types>
template<size_t index>
constexpr auto bio::alphabet::variant< alternative_types >::convert_unsafely_to ( ) const
inlineconstexprnoexcept

Convert to the specified alphabet (undefined behaviour if holds_alternative() would be false).

Template Parameters
indexIndex of the alternative to check for.

◆ convert_unsafely_to() [2/2]

template<typename... alternative_types>
template<typename alternative_t >
requires (is_alternative<alternative_t>())
constexpr alternative_t bio::alphabet::variant< alternative_types >::convert_unsafely_to ( ) const
inlineconstexprnoexcept

Convert to the specified alphabet (undefined behaviour if holds_alternative() would be false).

Template Parameters
alternative_tThe type of the alternative that you wish to check for.

◆ holds_alternative() [1/2]

template<typename... alternative_types>
template<size_t index>
constexpr bool bio::alphabet::variant< alternative_types >::holds_alternative ( ) const
inlineconstexprnoexcept

Whether the variant alphabet currently holds a value of the given alternative.

Template Parameters
indexIndex of the alternative to check for.
See also
std::variant::holds_alternative

◆ holds_alternative() [2/2]

template<typename... alternative_types>
template<typename alternative_t >
requires (is_alternative<alternative_t>())
constexpr bool bio::alphabet::variant< alternative_types >::holds_alternative ( ) const
inlineconstexprnoexcept

Whether the variant alphabet currently holds a value of the given alternative.

Template Parameters
alternative_tThe type of the alternative that you wish to check for.

◆ is_alternative()

template<typename... alternative_types>
template<typename alternative_t >
static constexpr bool bio::alphabet::variant< alternative_types >::is_alternative ( )
inlinestaticconstexprnoexcept

Returns true if alternative_t is one of the given alternative types.

Template Parameters
alternative_tThe type to check.
#include <gtest/gtest.h>
int main()
{
static_assert(variant_t::is_alternative<bio::alphabet::dna5>(), "dna5 is an alternative of variant_t");
static_assert(!variant_t::is_alternative<bio::alphabet::dna4>(), "dna4 is not an alternative of variant_t");
static_assert(variant_t::is_alternative<bio::alphabet::gap>(), "gap is an alternative of variant_t");
}

◆ operator=()

template<typename... alternative_types>
template<typename indirect_alternative_t >
requires (detail::variant_general_guard<indirect_alternative_t, alternative_types...> && (meta::weakly_assignable_from<alternative_types, indirect_alternative_t> || ...))
constexpr variant & bio::alphabet::variant< alternative_types >::operator= ( indirect_alternative_t const &  rhs)
inlineconstexprnoexcept

Assignment for arguments assignable to an alternative.

Template Parameters
indirect_alternative_tA type that one of the alternatives is assignable from.
Parameters
rhsThe value of an alternative.

Most assignments happen through implicit conversion and the default assignment operator. This assignment operator is for the rest.

◆ to_char()

constexpr char_type bio::alphabet::base< variant< alternative_types... > , size, char >::to_char ( ) const
inlineconstexprnoexceptinherited

Return the letter as a character of char_type.

Provides an implementation for bio::alphabet::to_char, required to model bio::alphabet::alphabet.

Complexity

Constant.

Exceptions

Guaranteed not to throw.

◆ to_rank()

constexpr rank_type bio::alphabet::base< variant< alternative_types... > , size, char >::to_rank ( ) const
inlineconstexprnoexceptinherited

Return the letter's numeric value (rank in the alphabet).

Provides an implementation for bio::alphabet::to_rank, required to model bio::alphabet::semialphabet.

Complexity

Constant.

Exceptions

Guaranteed not to throw.

Friends And Related Function Documentation

◆ operator==

template<typename... alternative_types>
template<std::same_as< variant > variant_t, typename indirect_alternative_type >
requires ((detail::variant_general_guard<indirect_alternative_type, alternative_types...>) && (meta::weakly_equality_comparable_with<indirect_alternative_type, alternative_types> || ...))
constexpr bool operator== ( variant_t const  lhs,
indirect_alternative_type const  rhs 
)
friend

(In-)Equality comparison against types comparable with alternatives but not convertible to the variant.

Template Parameters
variant_tThe type of the variant; given as template parameter to prevent conversion.
indirect_alternative_typeMust be comparable with an alternative's type.
Parameters
lhsLeft-hand-side of comparison.
rhsRight-hand-side of comparison.
Returns
true or false.

To determine (in-)equality, it is first deduced which alternative the argument is comparable with. It is then checked if the variant currently is in that alternative's state and if yes whether the values compare to true; else false is returned.


The documentation for this class was generated from the following files: