28namespace seqan3::detail
32template <
typename tuple_derived_t,
typename rhs_t,
typename... component_types>
33inline constexpr bool tuple_general_guard =
34 (!std::same_as<rhs_t, tuple_derived_t>) && (!std::same_as<rhs_t, alphabet_tuple_base<component_types...>>)
35 && (!std::is_base_of_v<tuple_derived_t, rhs_t>) && (!(std::same_as<rhs_t, component_types> || ...))
39template <
typename lhs_t,
typename tuple_derived_t,
typename rhs_t,
typename... component_types>
40inline constexpr bool tuple_eq_guard =
41 (instantiate_if_v<lazy<weakly_equality_comparable_with_trait, rhs_t, component_types>,
42 std::same_as<lhs_t, tuple_derived_t>
43 && tuple_general_guard<tuple_derived_t, rhs_t, component_types...>>
47template <
typename lhs_t,
typename tuple_derived_t,
typename rhs_t,
typename... component_types>
48inline constexpr bool tuple_order_guard =
49 (instantiate_if_v<lazy<weakly_ordered_with_trait, rhs_t, component_types>,
50 std::same_as<lhs_t, tuple_derived_t>
51 && tuple_general_guard<lhs_t, tuple_derived_t, rhs_t, component_types...>>
107template <
typename derived_type,
typename... component_types>
108 requires (detail::writable_constexpr_semialphabet<component_types> && ...) && (std::regular<component_types> && ...)
111 (1 * ... * alphabet_size<component_types>),
117 (1 * ... * alphabet_size<component_types>),
124 template <
typename type>
125 static constexpr bool is_component = seqan3::list_traits::contains<type, component_list>;
128 template <
typename type>
129 static constexpr bool is_unique_component = (seqan3::list_traits::count<type, component_list> == 1);
132 template <
typename alphabet_type,
size_t index>
133 class component_proxy;
146 using base_t::base_t;
169 detail::transformation_trait_or_t<detail::recursive_required_types<component_types>,
seqan3::type_list<>>...>;
172 static constexpr bool seqan3_alphabet_tuple_like =
true;
197 template <
typename component_type>
198 requires (!std::is_base_of_v<alphabet_tuple_base, component_type>) && is_unique_component<component_type>
201 get<component_type>(*
this) = alph;
219 template <
typename indirect_component_type>
220 requires ((detail::instantiate_if_v<
221 detail::lazy<std::is_convertible, indirect_component_type, component_types>,
222 detail::tuple_general_guard<derived_type, indirect_component_type, component_types...>>
226 using component_predicate = detail::implicitly_convertible_from<indirect_component_type>;
227 constexpr auto component_position =
228 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
230 component_type tmp(alph);
231 get<component_type>(*
this) = tmp;
235 template <
typename indirect_component_type>
236 requires ((!(detail::instantiate_if_v<
237 detail::lazy<std::is_convertible, indirect_component_type, component_types>,
238 detail::tuple_general_guard<derived_type, indirect_component_type, component_types...>>
240 && (detail::instantiate_if_v<
241 detail::lazy<std::is_constructible, component_types, indirect_component_type>,
242 detail::tuple_general_guard<derived_type, indirect_component_type, component_types...>>
244 constexpr explicit alphabet_tuple_base(indirect_component_type
const alph) noexcept : alphabet_tuple_base{}
246 using component_predicate = detail::constructible_from<indirect_component_type>;
247 constexpr auto component_position =
248 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
250 component_type tmp(alph);
251 get<component_type>(*
this) = tmp;
265 template <
typename component_type>
266 requires (!std::derived_from<component_type, alphabet_tuple_base>) && is_unique_component<component_type>
267 constexpr derived_type &
operator=(component_type
const alph)
noexcept
269 get<component_type>(*
this) = alph;
270 return static_cast<derived_type &
>(*this);
284 template <
typename indirect_component_type>
285 requires ((!std::derived_from<indirect_component_type, alphabet_tuple_base>)
286 && (!is_unique_component<indirect_component_type>)
287 && (std::assignable_from<component_types, indirect_component_type> || ...))
288 constexpr derived_type &
operator=(indirect_component_type
const alph)
noexcept
290 using component_predicate = detail::assignable_from<indirect_component_type>;
291 constexpr auto component_position =
292 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
294 get<component_type>(*
this) = alph;
295 return static_cast<derived_type &
>(*this);
299 template <
typename indirect_component_type>
300 requires ((!std::derived_from<indirect_component_type, alphabet_tuple_base>)
301 && (!is_unique_component<indirect_component_type>)
302 && (!(std::assignable_from<component_types, indirect_component_type> || ...))
303 && (std::convertible_to<indirect_component_type, component_types> || ...))
304 constexpr derived_type &
operator=(indirect_component_type
const alph)
noexcept
306 using component_predicate = detail::implicitly_convertible_from<indirect_component_type>;
307 constexpr auto component_position =
308 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
310 component_type tmp(alph);
311 get<component_type>(*
this) = tmp;
312 return static_cast<derived_type &
>(*this);
315 template <
typename indirect_component_type>
316 requires ((!std::derived_from<indirect_component_type, alphabet_tuple_base>)
317 && (!is_unique_component<indirect_component_type>)
318 && (!(std::assignable_from<component_types, indirect_component_type> || ...))
319 && (!(std::convertible_to<indirect_component_type, component_types> || ...))
320 && (std::constructible_from<component_types, indirect_component_type> || ...))
321 constexpr derived_type &
operator=(indirect_component_type
const alph)
noexcept
323 using component_predicate = detail::constructible_from<indirect_component_type>;
324 constexpr auto component_position =
325 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
327 component_type tmp(alph);
328 get<component_type>(*
this) = tmp;
329 return static_cast<derived_type &
>(*this);
344 template <
size_t index>
347 static_assert(index <
sizeof...(component_types),
"Index out of range.");
354 return component_proxy<t, index>{val, l};
363 template <
typename type>
365 requires is_unique_component<type>
367 return get<seqan3::list_traits::find<type, component_list>>(l);
376 template <
size_t index>
379 static_assert(index <
sizeof...(component_types),
"Index out of range.");
392 template <
typename type>
394 requires is_unique_component<type>
396 return get<seqan3::list_traits::find<type, component_list>>(l);
403 template <
typename type>
404 constexpr operator type() const noexcept
405 requires is_unique_component<type>
407 return get<type>(*
this);
428 template <
typename derived_type_t,
typename indirect_component_type>
429 friend constexpr auto operator==(derived_type_t
const lhs, indirect_component_type
const rhs)
noexcept
431 detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
434 using component_predicate = detail::weakly_equality_comparable_with_<indirect_component_type>;
435 constexpr auto component_position =
436 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
438 return get<component_type>(lhs) == rhs;
442 template <
typename derived_type_t,
typename indirect_component_type>
443 friend constexpr auto operator==(indirect_component_type
const lhs, derived_type_t
const rhs)
noexcept
445 detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
452 template <
typename derived_type_t,
typename indirect_component_type>
453 friend constexpr auto operator!=(derived_type_t
const lhs, indirect_component_type
const rhs)
noexcept
455 detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
458 using component_predicate = detail::weakly_equality_comparable_with_<indirect_component_type>;
459 constexpr auto component_position =
460 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
462 return get<component_type>(lhs) != rhs;
466 template <
typename derived_type_t,
typename indirect_component_type>
467 friend constexpr auto operator!=(indirect_component_type
const lhs, derived_type_t
const rhs)
noexcept
469 detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
476 template <
typename derived_type_t,
typename indirect_component_type>
477 friend constexpr auto operator<(derived_type_t
const lhs, indirect_component_type
const rhs)
noexcept
479 detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
482 using component_predicate = detail::weakly_ordered_with_<indirect_component_type>;
483 constexpr auto component_position =
484 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
486 return get<component_type>(lhs) < rhs;
490 template <
typename derived_type_t,
typename indirect_component_type>
491 friend constexpr auto operator<(indirect_component_type
const lhs, derived_type_t
const rhs)
noexcept
493 detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
500 template <
typename derived_type_t,
typename indirect_component_type>
501 friend constexpr auto operator<=(derived_type_t
const lhs, indirect_component_type
const rhs)
noexcept
503 detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
506 using component_predicate = detail::weakly_ordered_with_<indirect_component_type>;
507 constexpr auto component_position =
508 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
510 return get<component_type>(lhs) <= rhs;
514 template <
typename derived_type_t,
typename indirect_component_type>
515 friend constexpr auto operator<=(indirect_component_type
const lhs, derived_type_t
const rhs)
noexcept
517 detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
524 template <
typename derived_type_t,
typename indirect_component_type>
525 friend constexpr auto operator>(derived_type_t
const lhs, indirect_component_type
const rhs)
noexcept
527 detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
530 using component_predicate = detail::weakly_ordered_with_<indirect_component_type>;
531 constexpr auto component_position =
532 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
534 return get<component_type>(lhs) > rhs;
538 template <
typename derived_type_t,
typename indirect_component_type>
539 friend constexpr auto operator>(indirect_component_type
const lhs, derived_type_t
const rhs)
noexcept
541 detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
548 template <
typename derived_type_t,
typename indirect_component_type>
549 friend constexpr auto operator>=(derived_type_t
const lhs, indirect_component_type
const rhs)
noexcept
551 detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
554 using component_predicate = detail::weakly_ordered_with_<indirect_component_type>;
555 constexpr auto component_position =
556 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
558 return get<component_type>(lhs) >= rhs;
562 template <
typename derived_type_t,
typename indirect_component_type>
563 friend constexpr auto operator>=(indirect_component_type
const lhs, derived_type_t
const rhs)
noexcept
565 detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
574 template <
size_t index>
575 constexpr rank_type to_component_rank() const noexcept
579 return rank_to_component_rank[index][
to_rank()];
583 return (
to_rank() / cummulative_alph_sizes[index])
589 template <
size_t index>
590 constexpr void assign_component_rank(ptrdiff_t
const r)
noexcept
593 + ((r -
static_cast<ptrdiff_t
>(to_component_rank<index>()))
594 *
static_cast<ptrdiff_t
>(cummulative_alph_sizes[index])));
599 static constexpr rank_type rank_sum_helper(component_types... components,
602 return ((
seqan3::to_rank(components) * cummulative_alph_sizes[idx]) + ...);
616 seqan3::detail::for_each<reverse_list_t>(
617 [&](
auto alphabet_type_identity)
constexpr
619 using alphabet_t =
typename decltype(alphabet_type_identity)::type;
637 alphabet_size<1024u ? alphabet_size : 0u>,
638 list_traits::size<component_list>>
639 rank_to_component_rank{
643 alphabet_size<1024u ? alphabet_size : 0u>,
644 list_traits::size<component_list>>
651 for (
size_t i = 0; i < list_traits::size<component_list>; ++i)
652 for (
size_t j = 0; j < static_cast<size_t>(
alphabet_size); ++j)
653 ret[i][j] = (j / cummulative_alph_sizes[i]) % alph_sizes[i];
666template <
typename derived_type,
typename... component_types>
667 requires (detail::writable_constexpr_semialphabet<component_types> && ...) && (std::regular<component_types> && ...)
668template <
typename alphabet_type,
size_t index>
669class alphabet_tuple_base<derived_type, component_types...>::component_proxy :
670 public alphabet_proxy<component_proxy<alphabet_type, index>, alphabet_type>
674 using base_t = alphabet_proxy<component_proxy<alphabet_type, index>, alphabet_type>;
679 alphabet_tuple_base * parent;
682 constexpr void on_update() noexcept
684 parent->assign_component_rank<index>(this->
to_rank());
689 using base_t::operator=;
695 component_proxy() =
delete;
696 constexpr component_proxy(component_proxy
const &) =
default;
697 constexpr component_proxy(component_proxy &&) =
default;
698 constexpr component_proxy & operator=(component_proxy
const &) =
default;
699 constexpr component_proxy & operator=(component_proxy &&) =
default;
700 ~component_proxy() =
default;
703 constexpr component_proxy(alphabet_type
const l, alphabet_tuple_base & p) : base_t{l}, parent{&p}
718 friend constexpr bool operator==(derived_type
const lhs, component_proxy
const rhs)
noexcept
720 return get<index>(lhs) ==
static_cast<alphabet_type
>(rhs);
724 friend constexpr bool operator==(component_proxy<alphabet_type, index>
const lhs, derived_type
const rhs)
noexcept
730 friend constexpr bool operator!=(derived_type
const lhs, component_proxy
const rhs)
noexcept
732 return get<index>(lhs) !=
static_cast<alphabet_type
>(rhs);
736 friend constexpr bool operator!=(component_proxy<alphabet_type, index>
const lhs, derived_type
const rhs)
noexcept
742 friend constexpr bool operator<(derived_type
const lhs, component_proxy
const rhs)
noexcept
744 return get<index>(lhs) <
static_cast<alphabet_type
>(rhs);
748 friend constexpr bool operator<(component_proxy<alphabet_type, index>
const lhs, derived_type
const rhs)
noexcept
754 friend constexpr bool operator<=(derived_type
const lhs, component_proxy
const rhs)
noexcept
756 return get<index>(lhs) <=
static_cast<alphabet_type
>(rhs);
760 friend constexpr bool operator<=(component_proxy<alphabet_type, index>
const lhs, derived_type
const rhs)
noexcept
766 friend constexpr bool operator>(derived_type
const lhs, component_proxy
const rhs)
noexcept
768 return get<index>(lhs) >
static_cast<alphabet_type
>(rhs);
772 friend constexpr bool operator>(component_proxy<alphabet_type, index>
const lhs, derived_type
const rhs)
noexcept
778 friend constexpr bool operator>=(derived_type
const lhs, component_proxy
const rhs)
noexcept
780 return get<index>(lhs) >=
static_cast<alphabet_type
>(rhs);
784 friend constexpr bool operator>=(component_proxy<alphabet_type, index>
const lhs, derived_type
const rhs)
noexcept
803template <std::
size_t i, seqan3::detail::alphabet_tuple_like tuple_t>
804struct tuple_element<i, tuple_t>
817template <seqan3::detail::alphabet_tuple_like tuple_t>
818struct tuple_size<tuple_t> :
Provides implementation detail for seqan3::alphabet_variant and seqan3::alphabet_tuple_base.
Core alphabet concept and free function/type trait wrappers.
Provides seqan3::alphabet_base.
Provides seqan3::alphabet_proxy.
A CRTP-base that makes defining a custom alphabet easier.
Definition alphabet_base.hpp:54
constexpr rank_type to_rank() const noexcept
Return the letter's numeric value (rank in the alphabet).
Definition alphabet_base.hpp:134
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:77
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
constexpr derived_type & assign_rank(rank_type const c) noexcept
Assign from a numeric value.
Definition alphabet_base.hpp:184
The CRTP base for a combined alphabet that contains multiple values of different alphabets at the sam...
Definition alphabet_tuple_base.hpp:113
friend constexpr auto get(alphabet_tuple_base &l) noexcept
Tuple-like access to the contained components.
Definition alphabet_tuple_base.hpp:345
friend constexpr type get(alphabet_tuple_base const &l) noexcept
Tuple-like access to the contained components.
Definition alphabet_tuple_base.hpp:393
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:443
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:549
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:515
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:477
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:539
friend constexpr auto get(alphabet_tuple_base &l) noexcept
Tuple-like access to the contained components.
Definition alphabet_tuple_base.hpp:364
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
constexpr alphabet_tuple_base(component_type const alph) noexcept
Construction via a value of one of the components.
Definition alphabet_tuple_base.hpp:199
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:525
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:491
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:563
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:453
constexpr alphabet_tuple_base(component_types... components) noexcept
Construction from initialiser-list.
Definition alphabet_tuple_base.hpp:182
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:467
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
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:501
friend constexpr auto get(alphabet_tuple_base const &l) noexcept
Tuple-like access to the contained components.
Definition alphabet_tuple_base.hpp:377
constexpr auto alphabet_size
A type trait that holds the size of a (semi-)alphabet.
Definition alphabet/concept.hpp:834
constexpr auto assign_rank_to
Assign a rank to an alphabet object.
Definition alphabet/concept.hpp:288
constexpr auto to_rank
Return the rank representation of a (semi-)alphabet object.
Definition alphabet/concept.hpp:152
decltype(detail::concat(lists_t{}...)) concat
Join two seqan3::type_list s into one.
Definition type_list/traits.hpp:339
constexpr bool contains
Whether a type occurs in a type list or not.
Definition type_list/traits.hpp:249
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
constexpr ptrdiff_t count
Count the occurrences of a type in a pack.
Definition type_pack/traits.hpp:161
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
Provides metaprogramming utilities for integer types.
The main SeqAn3 namespace.
Definition aligned_sequence_concept.hpp:26
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
SeqAn specific customisations in the standard namespace.
Type that contains multiple types.
Definition type_list.hpp:26
static constexpr size_t size() noexcept
The number of types contained in the type list.
Definition type_list.hpp:31
seqan3::list_traits::at< i, typename tuple_t::seqan3_required_types > type
Element type.
Definition alphabet_tuple_base.hpp:807
Provides traits for seqan3::type_list.
constexpr type_list reverse(type_list<>)
A replacement for meta::reverse [recursion anchor].
Definition type_list/traits.hpp:123
Provides seqan3::type_list.
Provides algorithms for meta programming, parameter packs and seqan3::type_list.
Provides various traits for template packs.
Provides seqan3::tuple_like.