18 #include <meta/meta.hpp> 38 template <
typename tuple_derived_t,
typename rhs_t,
typename ... component_types>
39 inline constexpr
bool tuple_general_guard =
41 (!
std::same_as<rhs_t, alphabet_tuple_base<component_types...>>) &&
42 (!std::is_base_of_v<tuple_derived_t, rhs_t>) &&
48 template <
typename lhs_t,
typename tuple_derived_t,
typename rhs_t,
typename ... component_types>
49 inline constexpr
bool tuple_eq_guard =
50 (instantiate_if_v<lazy<weakly_equality_comparable_with_trait, rhs_t, component_types>,
52 tuple_general_guard<tuple_derived_t, rhs_t, component_types...>
56 template <
typename lhs_t,
typename tuple_derived_t,
typename rhs_t,
typename ... component_types>
57 inline constexpr
bool tuple_order_guard =
58 (instantiate_if_v<lazy<weakly_ordered_with_trait, rhs_t, component_types>,
60 tuple_general_guard<lhs_t, tuple_derived_t, rhs_t, component_types...>
114 template <typename derived_type,
115 typename ...component_types>
117 requires (detail::writable_constexpr_semialphabet<component_types> && ...) &&
118 (
std::regular<component_types> && ...)
128 (1 * ... * alphabet_size<component_types>),
132 using component_list = meta::list<component_types...>;
135 template <
typename type>
136 static constexpr
bool is_component =
137 meta::in<component_list, type>::value;
140 template <
typename type>
141 static constexpr
bool is_unique_component =
142 is_component<type> &&
143 (meta::find_index<component_list, type>::value == meta::reverse_find_index<component_list, type>::value);
149 template <
typename alphabet_type,
size_t index>
150 class component_proxy :
public alphabet_proxy<component_proxy<alphabet_type, index>, alphabet_type>
162 constexpr
void on_update() noexcept
164 parent->assign_component_rank<index>(
to_rank());
169 using base_t::operator=;
174 component_proxy() =
delete;
176 constexpr component_proxy(component_proxy
const &) =
default;
177 constexpr component_proxy(component_proxy &&) =
default;
178 constexpr component_proxy & operator=(component_proxy
const &) =
default;
179 constexpr component_proxy & operator=(component_proxy &&) =
default;
180 ~component_proxy() =
default;
199 friend constexpr
bool operator==(derived_type
const lhs, component_proxy
const rhs) noexcept
201 return get<index>(lhs) == static_cast<alphabet_type>(rhs);
205 friend constexpr
bool operator==(component_proxy<alphabet_type, index>
const lhs, derived_type
const rhs) noexcept
211 friend constexpr
bool operator!=(derived_type
const lhs, component_proxy
const rhs) noexcept
213 return get<index>(lhs) != static_cast<alphabet_type>(rhs);
217 friend constexpr
bool operator!=(component_proxy<alphabet_type, index>
const lhs, derived_type
const rhs) noexcept
223 friend constexpr
bool operator<(derived_type
const lhs, component_proxy
const rhs) noexcept
225 return get<index>(lhs) < static_cast<alphabet_type>(rhs);
229 friend constexpr
bool operator<(component_proxy<alphabet_type, index>
const lhs, derived_type
const rhs) noexcept
235 friend constexpr
bool operator<=(derived_type
const lhs, component_proxy
const rhs) noexcept
237 return get<index>(lhs) <= static_cast<alphabet_type>(rhs);
241 friend constexpr
bool operator<=(component_proxy<alphabet_type, index>
const lhs, derived_type
const rhs) noexcept
247 friend constexpr
bool operator>(derived_type
const lhs, component_proxy
const rhs) noexcept
249 return get<index>(lhs) > static_cast<alphabet_type>(rhs);
253 friend constexpr
bool operator>(component_proxy<alphabet_type, index>
const lhs, derived_type
const rhs) noexcept
259 friend constexpr
bool operator>=(derived_type
const lhs, component_proxy
const rhs) noexcept
261 return get<index>(lhs) >= static_cast<alphabet_type>(rhs);
265 friend constexpr
bool operator>=(component_proxy<alphabet_type, index>
const lhs, derived_type
const rhs) noexcept
281 using base_t::base_t;
295 using base_t::assign_rank;
299 using seqan3_required_types = component_list;
302 using seqan3_recursive_required_types =
304 detail::transformation_trait_or_t<detail::recursive_required_types<component_types>,
308 static constexpr
bool seqan3_alphabet_tuple_base_specialisation =
true;
331 template <
typename component_type>
333 requires (!std::is_base_of_v<alphabet_tuple_base, component_type>) &&
334 is_unique_component<component_type>
338 get<component_type>(*this) = alph;
354 template <
typename indirect_component_type>
356 requires ((detail::instantiate_if_v<
357 detail::lazy<std::is_convertible, indirect_component_type, component_types>,
358 detail::tuple_general_guard<derived_type, indirect_component_type, component_types...>> || ...))
362 using component_type = meta::front<meta::find_if<component_list, detail::implicitly_convertible_from<indirect_component_type>>>;
363 component_type tmp(alph);
364 get<component_type>(*this) = tmp;
368 template <
typename indirect_component_type>
369 requires ((!(detail::instantiate_if_v<
370 detail::lazy<std::is_convertible, indirect_component_type, component_types>,
371 detail::tuple_general_guard<derived_type, indirect_component_type, component_types...>> || ...)) &&
372 (detail::instantiate_if_v<
373 detail::lazy<std::is_constructible, component_types, indirect_component_type>,
374 detail::tuple_general_guard<derived_type, indirect_component_type, component_types...>> || ...))
377 using component_type = meta::front<meta::find_if<component_list, detail::constructible_from<indirect_component_type>>>;
378 component_type tmp(alph);
379 get<component_type>(*this) = tmp;
391 template <
typename component_type>
394 is_unique_component<component_type>
396 constexpr derived_type &
operator=(component_type
const alph) noexcept
398 get<component_type>(*this) = alph;
399 return static_cast<derived_type &
>(*this);
411 template <
typename indirect_component_type>
414 (!is_unique_component<indirect_component_type>) &&
417 constexpr derived_type & operator=(indirect_component_type const alph) noexcept
419 using component_type = meta::front<meta::find_if<component_list, detail::assignable_from<indirect_component_type>>>;
420 get<component_type>(*this) = alph;
421 return static_cast<derived_type &
>(*this);
425 template <
typename indirect_component_type>
427 (!is_unique_component<indirect_component_type>) &&
430 constexpr derived_type & operator=(indirect_component_type
const alph) noexcept
432 using component_type = meta::front<meta::find_if<component_list, detail::implicitly_convertible_from<indirect_component_type>>>;
433 component_type tmp(alph);
434 get<component_type>(*this) = tmp;
435 return static_cast<derived_type &
>(*this);
438 template <
typename indirect_component_type>
440 (!is_unique_component<indirect_component_type>) &&
444 constexpr derived_type & operator=(indirect_component_type
const alph) noexcept
446 using component_type = meta::front<meta::find_if<component_list, detail::constructible_from<indirect_component_type>>>;
447 component_type tmp(alph);
448 get<component_type>(*this) = tmp;
449 return static_cast<derived_type &
>(*this);
462 template <
size_t index>
465 static_assert(index <
sizeof...(component_types),
"Index out of range.");
467 using t = meta::at_c<component_list, index>;
472 return component_proxy<t, index>{val, l};
479 template <
typename type>
482 requires is_unique_component<type>
485 return get<meta::find_index<component_list, type>::value>(l);
492 template <
size_t index>
495 static_assert(index <
sizeof...(component_types),
"Index out of range.");
497 using t = meta::at_c<component_list, index>;
506 template <
typename type>
509 requires is_unique_component<type>
512 return get<meta::find_index<component_list, type>::value>(l);
517 template <
typename type>
518 constexpr
operator type() const noexcept
520 requires is_unique_component<type>
523 return get<type>(*this);
542 template <
typename derived_type_t,
typename indirect_component_type>
543 friend constexpr
auto operator==(derived_type_t
const lhs, indirect_component_type
const rhs) noexcept
544 ->
std::enable_if_t<detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
547 using component_type = meta::front<meta::find_if<component_list, detail::weakly_equality_comparable_with_<indirect_component_type>>>;
548 return get<component_type>(lhs) == rhs;
552 template <
typename derived_type_t,
typename indirect_component_type>
553 friend constexpr
auto operator==(indirect_component_type
const lhs, derived_type_t
const rhs) noexcept
554 ->
std::enable_if_t<detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
561 template <
typename derived_type_t,
typename indirect_component_type>
562 friend constexpr
auto operator!=(derived_type_t
const lhs, indirect_component_type
const rhs) noexcept
563 ->
std::enable_if_t<detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
566 using component_type = meta::front<meta::find_if<component_list, detail::weakly_equality_comparable_with_<indirect_component_type>>>;
567 return get<component_type>(lhs) != rhs;
571 template <
typename derived_type_t,
typename indirect_component_type>
572 friend constexpr
auto operator!=(indirect_component_type
const lhs, derived_type_t
const rhs) noexcept
573 ->
std::enable_if_t<detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
580 template <
typename derived_type_t,
typename indirect_component_type>
581 friend constexpr
auto operator<(derived_type_t
const lhs, indirect_component_type
const rhs) noexcept
582 ->
std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
585 using component_type = meta::front<meta::find_if<component_list, detail::weakly_ordered_with_<indirect_component_type>>>;
586 return get<component_type>(lhs) < rhs;
590 template <
typename derived_type_t,
typename indirect_component_type>
591 friend constexpr
auto operator<(indirect_component_type
const lhs, derived_type_t
const rhs) noexcept
592 ->
std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
599 template <
typename derived_type_t,
typename indirect_component_type>
600 friend constexpr
auto operator<=(derived_type_t
const lhs, indirect_component_type
const rhs) noexcept
601 ->
std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
604 using component_type = meta::front<meta::find_if<component_list, detail::weakly_ordered_with_<indirect_component_type>>>;
605 return get<component_type>(lhs) <= rhs;
609 template <
typename derived_type_t,
typename indirect_component_type>
610 friend constexpr
auto operator<=(indirect_component_type
const lhs, derived_type_t
const rhs) noexcept
611 ->
std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
618 template <
typename derived_type_t,
typename indirect_component_type>
619 friend constexpr
auto operator>(derived_type_t
const lhs, indirect_component_type
const rhs) noexcept
620 ->
std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
623 using component_type = meta::front<meta::find_if<component_list, detail::weakly_ordered_with_<indirect_component_type>>>;
624 return get<component_type>(lhs) > rhs;
628 template <
typename derived_type_t,
typename indirect_component_type>
629 friend constexpr
auto operator>(indirect_component_type
const lhs, derived_type_t
const rhs) noexcept
630 ->
std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
637 template <
typename derived_type_t,
typename indirect_component_type>
638 friend constexpr
auto operator>=(derived_type_t
const lhs, indirect_component_type
const rhs) noexcept
639 ->
std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
642 using component_type = meta::front<meta::find_if<component_list, detail::weakly_ordered_with_<indirect_component_type>>>;
643 return get<component_type>(lhs) >= rhs;
647 template <
typename derived_type_t,
typename indirect_component_type>
648 friend constexpr
auto operator>=(indirect_component_type
const lhs, derived_type_t
const rhs) noexcept
649 ->
std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
658 template <
size_t index>
659 constexpr
rank_type to_component_rank()
const noexcept
663 return rank_to_component_rank[index][
to_rank()];
667 return (
to_rank() / cummulative_alph_sizes[index]) %
673 template <
size_t index>
674 constexpr
void assign_component_rank(ptrdiff_t
const r) noexcept
676 assign_rank(static_cast<ptrdiff_t>(
to_rank()) +
677 ((r - static_cast<ptrdiff_t>(to_component_rank<index>())) *
678 static_cast<ptrdiff_t>(cummulative_alph_sizes[index])));
690 meta::for_each(meta::reverse<component_list>{}, [&] (
auto alph) constexpr
692 ret[
count] =
static_cast<rank_type>(seqan3::alphabet_size<decltype(alph)> * ret[count - 1]);
701 ret2[i] = ret[component_list::size() - i - 1];
711 return ((
seqan3::to_rank(components) * cummulative_alph_sizes[idx]) + ...);
716 list_traits::size<component_list>> rank_to_component_rank
720 std::array<std::array<rank_type, alphabet_size < 1024 ? alphabet_size : 0>,
721 list_traits::size<component_list>> ret{};
727 for (
size_t i = 0; i < list_traits::size<component_list>; ++i)
728 for (
size_t j = 0; j < static_cast<size_t>(
alphabet_size); ++j)
729 ret[i][j] = (j / cummulative_alph_sizes[i]) % alph_sizes[i];
747 template <std::
size_t i, seqan3::detail::alphabet_tuple_base_specialisation tuple_t>
748 struct tuple_element<i, tuple_t>
751 using type = meta::at_c<typename tuple_t::seqan3_required_types, i>;
759 template <seqan3::detail::alphabet_tuple_base_specialisation tuple_t>
760 struct tuple_size<tuple_t> :
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 >
Comparison against types comparable with components.
Definition: alphabet_tuple_base.hpp:553
Provides concepts for core language types and relations that don't have concepts in C++20 (yet)...
typename decltype(detail::at< idx, pack_t... >())::type at
Return the type at given index from the type pack.
Definition: traits.hpp:221
constexpr auto assign_rank_to
Assign a rank to an alphabet object.
Definition: concept.hpp:238
A CRTP-base that eases the definition of proxy types returned in place of regular alphabets...
Definition: alphabet_proxy.hpp:59
constexpr derived_type & operator=(component_type const alph) noexcept
Assignment via a value of one of the components.
Definition: alphabet_tuple_base.hpp:396
Provides metaprogramming utilities for integer types.
constexpr alphabet_tuple_base(component_type const alph) noexcept
Construction via a value of one of the components.
Definition: alphabet_tuple_base.hpp:336
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 >
Comparison against types comparable with components.
Definition: alphabet_tuple_base.hpp:600
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:142
Provides seqan3::debug_stream and related types.
SeqAn specific customisations in the standard namespace.
constexpr auto const & get(configuration< configs_t... > const &config) noexcept
Definition: configuration.hpp:576
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 >
Comparison against types comparable with components.
Definition: alphabet_tuple_base.hpp:591
The main SeqAn3 namespace.
Provides implementation detail for seqan3::alphabet_variant and seqan3::alphabet_tuple_base.
constexpr bool contains
Whether a type occurs in a type list or not.
Definition: traits.hpp:495
Provides seqan3::tuple_like.
The concept std::assignable_from<LHS, RHS> specifies that an expression of the type and value categor...
The CRTP base for a combined alphabet that contains multiple values of different alphabets at the sam...
Definition: alphabet_tuple_base.hpp:120
Provides seqan3::alphabet_proxy.
Provides utility functions for tuple like interfaces.
decltype(detail::concat(lists_t{}...)) concat
Join two seqan3::type_list s into one.
Definition: traits.hpp:592
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 >
Comparison against types comparable with components.
Definition: alphabet_tuple_base.hpp:610
Provides seqan3::alphabet_base.
constexpr size_t size
The size of a type pack.
Definition: traits.hpp:116
Definition: aligned_sequence_concept.hpp:36
The std::constructible_from concept specifies that a variable of type T can be initialized with the g...
The concept std::derived_from<Derived, Base> is satisfied if and only if Base is a class type that is...
The concept std::convertible_to<From, To> specifies that an expression of the type and value category...
Core alphabet concept and free function/type trait wrappers.
A CRTP-base that makes defining a custom alphabet easier.
Definition: alphabet_base.hpp:51
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 >
Comparison against types comparable with components.
Definition: alphabet_tuple_base.hpp:581
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 >
Comparison against types comparable with components.
Definition: alphabet_tuple_base.hpp:572
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 >
Comparison against types comparable with components.
Definition: alphabet_tuple_base.hpp:629
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 >
Comparison against types comparable with components.
Definition: alphabet_tuple_base.hpp:619
Quality alphabet concept.
constexpr auto alphabet_size
A type trait that holds the size of a (semi-)alphabet.
Definition: concept.hpp:706
meta::at_c< typename tuple_t::seqan3_required_types, i > type
Element type.
Definition: alphabet_tuple_base.hpp:751
The concept std::same_as<T, U> is satisfied if and only if T and U denote the same type...
constexpr ptrdiff_t count
Count the occurrences of a type in a pack.
Definition: traits.hpp:134
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 >
Comparison against types comparable with components.
Definition: alphabet_tuple_base.hpp:648
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 >
Comparison against types comparable with components.
Definition: alphabet_tuple_base.hpp:638
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:543
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:562