22 #include <meta/meta.hpp> 53 template <
typename variant_t,
54 template <
typename>
typename fun_t,
56 inline bool constexpr one_alternative_is =
false;
61 template <
typename ... alternatives,
62 template <
typename>
typename fun_t,
64 inline bool constexpr one_alternative_is<alphabet_variant<alternatives...>,
67 = !
meta::empty<meta::find_if<meta::list<alternatives...>, fun_t<target_t>>>::value;
70 template <
typename ... alternatives,
71 template <
typename>
typename fun_t>
72 inline bool constexpr one_alternative_is<alphabet_variant<alternatives...>,
74 alphabet_variant<alternatives...>> =
false;
77 template <
typename ... alternatives,
78 template <
typename>
typename fun_t,
80 requires ConvertibleToByMember<target_t, alphabet_variant<alternatives...>>
81 inline bool constexpr one_alternative_is<alphabet_variant<alternatives...>,
86 template <
typename ... alternatives,
87 template <
typename>
typename fun_t,
89 requires AlphabetTupleBase<target_t> &&
90 meta::in<detail::transformation_trait_or_t<recursive_tuple_components<target_t>, meta::list<>>,
91 alphabet_variant<alternatives...>>::value
92 inline bool constexpr one_alternative_is<alphabet_variant<alternatives...>,
97 template <
typename ... alternatives,
98 template <
typename>
typename fun_t,
100 requires type_in_pack_v<target_t, alternatives...>
101 inline bool constexpr one_alternative_is<alphabet_variant<alternatives...>,
106 template <
typename ... alternatives,
107 template <
typename>
typename fun_t,
109 requires type_in_pack_v<target_t, alternatives...>
110 inline bool constexpr one_alternative_is<target_t,
112 alphabet_variant<alternatives...>> =
false;
115 template <
typename ... alternatives,
116 template <
typename>
typename fun_t,
119 requires requires {
std::Same<
typename target_t::value_type, alphabet_variant<alternatives...>>; }
120 inline bool constexpr one_alternative_is<alphabet_variant<alternatives...>,
126 template <
typename ... alternatives,
127 template <
typename>
typename fun_t,
129 requires TupleSize<target_t> && !AlphabetTupleBase<target_t>
130 inline bool constexpr one_alternative_is<alphabet_variant<alternatives...>,
198 template <
typename ...alternative_types>
200 requires (detail::WritableConstexprAlphabet<alternative_types> && ...) &&
201 (!std::is_reference_v<alternative_types> && ...) &&
202 (
sizeof...(alternative_types) >= 2)
206 (static_cast<size_t>(alphabet_size<alternative_types>) + ...),
213 (
static_cast<size_t>(alphabet_size<alternative_types>) + ...),
219 using alternatives = meta::list<alternative_types...>;
221 static_assert(
std::Same<alternatives, meta::unique<alternatives>>,
222 "All types in a alphabet_variant must be distinct.");
237 template <
typename alternative_t>
240 return detail::type_in_pack_v<alternative_t, alternative_types...>;
259 template <typename alternative_t>
276 template <
typename indirect_alternative_t>
279 detail::implicitly_convertible_from,
280 indirect_alternative_t> &&
282 detail::constructible_from,
283 indirect_alternative_t>
287 assign_rank(rank_by_type_(meta::front<meta::find_if<alternatives,
288 detail::constructible_from<indirect_alternative_t>>>(rhs)));
292 template <
typename indirect_alternative_t>
294 detail::implicitly_convertible_from,
295 indirect_alternative_t>
300 meta::front<meta::find_if<alternatives,
301 detail::implicitly_convertible_from<indirect_alternative_t>>>(rhs)));
311 template <
typename indirect_alternative_t>
314 detail::implicitly_convertible_from,
315 indirect_alternative_t> &&
317 detail::constructible_from,
318 indirect_alternative_t> &&
320 detail::assignable_from,
321 indirect_alternative_t>
325 using alternative_t = meta::front<meta::find_if<alternatives, detail::assignable_from<indirect_alternative_t>>>;
326 alternative_t alternative{};
336 template <
size_t index>
341 static_assert(index <
alphabet_size,
"The alphabet_variant contains less alternatives than you are checking.");
342 return (
to_rank() >= partial_sum_sizes[index]) && (
to_rank() < partial_sum_sizes[index + 1]);
349 template <
size_t index>
352 return convert_impl<index, true>();
358 template <
size_t index>
361 return convert_impl<index, false>();
371 template <
typename alternative_t>
375 constexpr
size_t index = meta::find_index<alternatives, alternative_t>::value;
376 return is_alternative<index>();
383 template <
typename alternative_t>
387 constexpr
size_t index = meta::find_index<alternatives, alternative_t>::value;
388 return convert_impl<index, true>();
394 template <
typename alternative_t>
398 constexpr
size_t index = meta::find_index<alternatives, alternative_t>::value;
399 return convert_impl<index, false>();
409 template <
typename alternative_t>
410 constexpr
bool operator==(alternative_t
const rhs)
const noexcept
411 requires holds_alternative<alternative_t>()
413 return is_alternative<alternative_t>() && (convert_unsafely_to<alternative_t>() == rhs);
416 template <
typename alternative_t>
417 constexpr
bool operator!=(alternative_t
const rhs)
const noexcept
418 requires holds_alternative<alternative_t>()
420 return !operator==(rhs);
431 template <
typename indirect_alternative_type>
432 constexpr
bool operator==(indirect_alternative_type
const rhs)
const noexcept
435 detail::weakly_equality_comparable_with,
436 indirect_alternative_type>
439 using alternative_t =
440 meta::front<meta::find_if<alternatives,
441 detail::weakly_equality_comparable_with<indirect_alternative_type>>>;
442 return is_alternative<alternative_t>() && (convert_unsafely_to<alternative_t>() == rhs);
445 template <
typename indirect_alternative_type>
446 constexpr
bool operator!=(indirect_alternative_type
const rhs)
const noexcept
449 detail::weakly_equality_comparable_with,
450 indirect_alternative_type>
453 return !operator==(rhs);
464 template <
size_t index,
bool throws>
465 constexpr
auto convert_impl() const noexcept(!throws) -> meta::at_c<alternatives, index>
467 static_assert(index <
alphabet_size,
"The alphabet_variant contains less alternatives than you are checking.");
468 using alternative_t = meta::at_c<alternatives, index>;
470 if constexpr (
throws)
472 if (!is_alternative<index>())
489 static constexpr
std::array partial_sum_sizes = []() constexpr
491 constexpr
size_t N =
sizeof...(alternative_types) + 1;
494 for (
size_t i = 1u; i < N; ++i)
495 partial_sum[i] += partial_sum[i-1];
512 auto assign_rank_to_char = [](
auto alternative,
size_t rank) constexpr
517 auto assign_value_to_char = [assign_rank_to_char] (
auto alternative,
auto & value_to_char,
auto & value) constexpr
520 for (
size_t i = 0u; i < seqan3::alphabet_size<alternative_t>; ++i, ++value)
521 value_to_char[value] = assign_rank_to_char(alternative, i);
531 ((assign_value_to_char(alternative_types{}, value_to_char, value)),...);
533 return value_to_char;
540 template <
size_t index,
typename alternative_t>
542 requires holds_alternative<alternative_t>()
544 static constexpr
rank_type rank_by_index_(alternative_t
const & alternative) noexcept
553 template <
typename alternative_t>
555 requires holds_alternative<alternative_t>()
557 static constexpr
rank_type rank_by_type_(alternative_t
const & alternative) noexcept
559 constexpr
size_t index = meta::find_index<alternatives, alternative_t>::value;
560 return rank_by_index_<index>(alternative);
570 static constexpr
std::array char_to_rank = []() constexpr
572 constexpr
size_t table_size = 1 << (
sizeof(
char_type) * 8);
576 for (
size_t i = 0u; i < table_size; ++i)
579 bool there_was_no_valid_representation{
true};
581 meta::for_each(alternatives{}, [&] (
auto && alt)
583 using alt_type = remove_cvref_t<decltype(alt)>;
585 if (there_was_no_valid_representation && char_is_valid_for<alt_type>(chr))
587 there_was_no_valid_representation =
false;
592 if (there_was_no_valid_representation)
593 char_to_rank[i] = rank_by_type_(
assign_char_to(chr, meta::front<alternatives>{}));
600 static constexpr
bool char_is_valid(
char_type const chr) noexcept
602 bool is_valid{
false};
604 meta::for_each(alternatives{}, [&] (
auto && alt)
619 template <
typename lhs_t,
typename ...alternative_types>
620 constexpr
bool operator==(lhs_t
const lhs, alphabet_variant<alternative_types...>
const rhs) noexcept
622 requires detail::WeaklyEqualityComparableByMembersWith<alphabet_variant<alternative_types...>, lhs_t> &&
623 !detail::WeaklyEqualityComparableByMembersWith<lhs_t, alphabet_variant<alternative_types...>>
629 template <
typename lhs_t,
typename ...alternative_types>
630 constexpr
bool operator!=(lhs_t
const lhs, alphabet_variant<alternative_types...>
const rhs) noexcept
632 requires detail::WeaklyEqualityComparableByMembersWith<alphabet_variant<alternative_types...>, lhs_t> &&
633 !detail::WeaklyEqualityComparableByMembersWith<lhs_t, alphabet_variant<alternative_types...>>
A combined alphabet that can hold values of either of its alternatives.
Definition: alphabet_variant.hpp:205
detail::min_viable_uint_t< size - 1 > rank_type
The type of the alphabet when represented as a number (e.g. via to_rank()).
Definition: alphabet_base.hpp:63
Provides concepts for core language types and relations that don't have concepts in C++20 (yet)...
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: concept.hpp:501
constexpr auto assign_rank_to
Assign a rank to an alphabet object.
Definition: concept.hpp:207
Provides metaprogramming utilities for integer types.
constexpr auto to_char
Return the char representation of an alphabet object.
Definition: concept.hpp:285
Provides unary type traits on a set of types, usually provided as template argument pack...
constexpr auto to_rank
Return the rank representation of a (semi-)alphabet object.
Definition: concept.hpp:103
std::remove_cv_t< std::remove_reference_t< t > > remove_cvref_t
Return the input type with const, volatile and references removed (type trait).
Definition: basic.hpp:35
The main SeqAn3 namespace.
constexpr alphabet_variant() noexcept=default
Defaulted.
Provides implementation detail for seqan3::alphabet_variant and seqan3::alphabet_tuple_base.
constexpr alphabet_variant< alternative_types... > & assign_rank(rank_type const c) noexcept
Assign from a numeric value.
Definition: alphabet_base.hpp:166
constexpr bool is_alternative() const noexcept requires holds_alternative< alternative_t >()
Whether the variant alphabet currently holds a value of the given alternative.
Definition: alphabet_variant.hpp:372
Provides utility functions for tuple like interfaces.
constexpr auto convert_to() const
Convert to the specified alphabet (throws if is_alternative() would be false).
Definition: alphabet_variant.hpp:350
constexpr bool is_alternative() const noexcept
Whether the variant alphabet currently holds a value of the given alternative.
Definition: alphabet_variant.hpp:339
constexpr alphabet_variant(indirect_alternative_t const &rhs) noexcept
Construction via the value of a type that an alternative type is constructible from.
Definition: alphabet_variant.hpp:285
constexpr auto convert_unsafely_to() const noexcept
Convert to the specified alphabet (undefined behaviour if is_alternative() would be false)...
Definition: alphabet_variant.hpp:359
Provides seqan3::alphabet_base.
constexpr char_type to_char() const noexcept
Return the letter as a character of char_type.
Definition: alphabet_base.hpp:95
static detail::min_viable_uint_t< size > constexpr alphabet_size
The size of the alphabet, i.e. the number of different values it can take.
Definition: alphabet_base.hpp:175
Definition: aligned_sequence_concept.hpp:35
constexpr alphabet_variant & operator=(indirect_alternative_t const &rhs) noexcept
Assignment via a value that one of the alternative types is assignable from.
Definition: alphabet_variant.hpp:323
Provides C++20 additions to the type_traits header.
constexpr rank_type to_rank() const noexcept
Return the letter's numeric value (rank in the alphabet).
Definition: alphabet_base.hpp:117
constexpr alternative_t convert_to() const requires holds_alternative< alternative_t >()
Convert to the specified alphabet (throws if is_alternative() would be false).
Definition: alphabet_variant.hpp:384
::ranges::empty empty
Alias for ranges::empty. Checks whether a range is empty.
Definition: ranges:194
Core alphabet concept and free function/type trait wrappers.
A CRTP-base that makes defining a custom alphabet easier.
Definition: alphabet_base.hpp:52
static constexpr bool holds_alternative() noexcept
Returns true if alternative_t is one of the given alternative types.
Definition: alphabet_variant.hpp:238
Provides various transformation traits used by the range module.
constexpr auto assign_char_to
Assign a character to an alphabet object.
Definition: concept.hpp:395
The concept std::Same<T, U> is satisfied if and only if T and U denote the same type.
std::conditional_t< std::Same< char, void >, char, char > char_type
The char representation; conditional needed to make semi alphabet definitions legal.
Definition: alphabet_base.hpp:61
constexpr alternative_t convert_unsafely_to() const noexcept requires holds_alternative< alternative_t >()
Convert to the specified alphabet (undefined behaviour if is_alternative() would be false)...
Definition: alphabet_variant.hpp:395