31namespace seqan3::detail
35template <
typename tuple_derived_t,
typename rhs_t,
typename ... component_types>
36inline constexpr bool tuple_general_guard =
37 (!std::same_as<rhs_t, tuple_derived_t>) &&
38 (!std::same_as<rhs_t, alphabet_tuple_base<component_types...>>) &&
39 (!std::is_base_of_v<tuple_derived_t, rhs_t>) &&
40 (!(std::same_as<rhs_t, component_types> || ...)) &&
45template <
typename lhs_t,
typename tuple_derived_t,
typename rhs_t,
typename ... component_types>
46inline constexpr bool tuple_eq_guard =
47 (instantiate_if_v<lazy<weakly_equality_comparable_with_trait, rhs_t, component_types>,
48 std::same_as<lhs_t, tuple_derived_t> &&
49 tuple_general_guard<tuple_derived_t, rhs_t, component_types...>
53template <
typename lhs_t,
typename tuple_derived_t,
typename rhs_t,
typename ... component_types>
54inline constexpr bool tuple_order_guard =
55 (instantiate_if_v<lazy<weakly_ordered_with_trait, rhs_t, component_types>,
56 std::same_as<lhs_t, tuple_derived_t> &&
57 tuple_general_guard<lhs_t, tuple_derived_t, rhs_t, component_types...>
113template <
typename derived_type,
114 typename ...component_types>
116 requires (detail::writable_constexpr_semialphabet<component_types> && ...) &&
117 (std::regular<component_types> && ...)
121 (1 * ... * alphabet_size<component_types>),
127 (1 * ... * alphabet_size<component_types>),
134 template <
typename type>
135 static constexpr bool is_component = seqan3::list_traits::contains<type, component_list>;
138 template <
typename type>
139 static constexpr bool is_unique_component = (seqan3::list_traits::count<type, component_list> == 1);
142 template <
typename alphabet_type,
size_t index>
143 class component_proxy;
155 using base_t::base_t;
176 using seqan3_recursive_required_types =
178 detail::transformation_trait_or_t<detail::recursive_required_types<component_types>,
182 static constexpr bool seqan3_alphabet_tuple_like =
true;
207 template <
typename component_type>
209 requires (!std::is_base_of_v<alphabet_tuple_base, component_type>) &&
210 is_unique_component<component_type>
214 get<component_type>(*
this) = alph;
232 template <
typename indirect_component_type>
234 requires ((detail::instantiate_if_v<
235 detail::lazy<std::is_convertible, indirect_component_type, component_types>,
236 detail::tuple_general_guard<derived_type, indirect_component_type, component_types...>> || ...))
240 using component_predicate = detail::implicitly_convertible_from<indirect_component_type>;
244 component_type tmp(alph);
245 get<component_type>(*
this) = tmp;
249 template <
typename indirect_component_type>
250 requires ((!(detail::instantiate_if_v<
251 detail::lazy<std::is_convertible, indirect_component_type, component_types>,
252 detail::tuple_general_guard<derived_type, indirect_component_type, component_types...>> || ...)) &&
253 (detail::instantiate_if_v<
254 detail::lazy<std::is_constructible, component_types, indirect_component_type>,
255 detail::tuple_general_guard<derived_type, indirect_component_type, component_types...>> || ...))
256 constexpr explicit alphabet_tuple_base(indirect_component_type
const alph) noexcept : alphabet_tuple_base{}
258 using component_predicate = detail::constructible_from<indirect_component_type>;
262 component_type tmp(alph);
263 get<component_type>(*
this) = tmp;
277 template <
typename component_type>
279 requires (!std::derived_from<component_type, alphabet_tuple_base>) &&
280 is_unique_component<component_type>
282 constexpr derived_type &
operator=(component_type
const alph)
noexcept
284 get<component_type>(*
this) = alph;
285 return static_cast<derived_type &
>(*this);
299 template <
typename indirect_component_type>
301 requires ((!std::derived_from<indirect_component_type, alphabet_tuple_base>) &&
302 (!is_unique_component<indirect_component_type>) &&
303 (std::assignable_from<component_types, indirect_component_type> || ...))
305 constexpr derived_type &
operator=(indirect_component_type
const alph)
noexcept
307 using component_predicate = detail::assignable_from<indirect_component_type>;
311 get<component_type>(*
this) = alph;
312 return static_cast<derived_type &
>(*this);
316 template <
typename indirect_component_type>
317 requires ((!std::derived_from<indirect_component_type, alphabet_tuple_base>) &&
318 (!is_unique_component<indirect_component_type>) &&
319 (!(std::assignable_from<component_types, indirect_component_type> || ...)) &&
320 (std::convertible_to<indirect_component_type, component_types> || ...))
321 constexpr derived_type &
operator=(indirect_component_type
const alph)
noexcept
323 using component_predicate = detail::implicitly_convertible_from<indirect_component_type>;
327 component_type tmp(alph);
328 get<component_type>(*
this) = tmp;
329 return static_cast<derived_type &
>(*this);
332 template <
typename indirect_component_type>
333 requires ((!std::derived_from<indirect_component_type, alphabet_tuple_base>) &&
334 (!is_unique_component<indirect_component_type>) &&
335 (!(std::assignable_from<component_types, indirect_component_type> || ...)) &&
336 (!(std::convertible_to<indirect_component_type, component_types> || ...)) &&
337 (std::constructible_from<component_types, indirect_component_type> || ...))
338 constexpr derived_type &
operator=(indirect_component_type
const alph)
noexcept
340 using component_predicate = detail::constructible_from<indirect_component_type>;
344 component_type tmp(alph);
345 get<component_type>(*
this) = tmp;
346 return static_cast<derived_type &
>(*this);
361 template <
size_t index>
364 static_assert(index <
sizeof...(component_types),
"Index out of range.");
371 return component_proxy<t, index>{val, l};
380 template <
typename type>
383 requires is_unique_component<type>
386 return get<seqan3::list_traits::find<type, component_list>>(l);
395 template <
size_t index>
398 static_assert(index <
sizeof...(component_types),
"Index out of range.");
411 template <
typename type>
414 requires is_unique_component<type>
417 return get<seqan3::list_traits::find<type, component_list>>(l);
424 template <
typename type>
425 constexpr operator type() const noexcept
427 requires is_unique_component<type>
430 return get<type>(*
this);
451 template <
typename derived_type_t,
typename indirect_component_type>
452 friend constexpr auto operator==(derived_type_t
const lhs, indirect_component_type
const rhs)
noexcept
453 ->
std::enable_if_t<detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
456 using component_predicate = detail::weakly_equality_comparable_with_<indirect_component_type>;
460 return get<component_type>(lhs) == rhs;
464 template <
typename derived_type_t,
typename indirect_component_type>
465 friend constexpr auto operator==(indirect_component_type
const lhs, derived_type_t
const rhs)
noexcept
466 ->
std::enable_if_t<detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
473 template <
typename derived_type_t,
typename indirect_component_type>
474 friend constexpr auto operator!=(derived_type_t
const lhs, indirect_component_type
const rhs)
noexcept
475 ->
std::enable_if_t<detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
478 using component_predicate = detail::weakly_equality_comparable_with_<indirect_component_type>;
482 return get<component_type>(lhs) != rhs;
486 template <
typename derived_type_t,
typename indirect_component_type>
487 friend constexpr auto operator!=(indirect_component_type
const lhs, derived_type_t
const rhs)
noexcept
488 ->
std::enable_if_t<detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
495 template <
typename derived_type_t,
typename indirect_component_type>
496 friend constexpr auto operator<(derived_type_t
const lhs, indirect_component_type
const rhs)
noexcept
497 ->
std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
500 using component_predicate = detail::weakly_ordered_with_<indirect_component_type>;
504 return get<component_type>(lhs) < rhs;
508 template <
typename derived_type_t,
typename indirect_component_type>
509 friend constexpr auto operator<(indirect_component_type
const lhs, derived_type_t
const rhs)
noexcept
510 ->
std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
517 template <
typename derived_type_t,
typename indirect_component_type>
518 friend constexpr auto operator<=(derived_type_t
const lhs, indirect_component_type
const rhs)
noexcept
519 ->
std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
522 using component_predicate = detail::weakly_ordered_with_<indirect_component_type>;
526 return get<component_type>(lhs) <= rhs;
530 template <
typename derived_type_t,
typename indirect_component_type>
531 friend constexpr auto operator<=(indirect_component_type
const lhs, derived_type_t
const rhs)
noexcept
532 ->
std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
539 template <
typename derived_type_t,
typename indirect_component_type>
540 friend constexpr auto operator>(derived_type_t
const lhs, indirect_component_type
const rhs)
noexcept
541 ->
std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
544 using component_predicate = detail::weakly_ordered_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_order_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_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
566 using component_predicate = detail::weakly_ordered_with_<indirect_component_type>;
570 return get<component_type>(lhs) >= rhs;
574 template <
typename derived_type_t,
typename indirect_component_type>
575 friend constexpr auto operator>=(indirect_component_type
const lhs, derived_type_t
const rhs)
noexcept
576 ->
std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
585 template <
size_t index>
586 constexpr rank_type to_component_rank() const noexcept
590 return rank_to_component_rank[index][
to_rank()];
594 return (
to_rank() / cummulative_alph_sizes[index]) %
600 template <
size_t index>
601 constexpr void assign_component_rank(ptrdiff_t
const r)
noexcept
604 ((r -
static_cast<ptrdiff_t
>(to_component_rank<index>())) *
605 static_cast<ptrdiff_t
>(cummulative_alph_sizes[index])));
617 using reverse_list_t =
decltype(seqan3::list_traits::detail::reverse(component_list{}));
618 seqan3::detail::for_each<reverse_list_t>([&] (
auto alphabet_type_identity)
constexpr
620 using alphabet_t =
typename decltype(alphabet_type_identity)::type;
640 return ((
seqan3::to_rank(components) * cummulative_alph_sizes[idx]) + ...);
645 list_traits::size<component_list>> rank_to_component_rank
650 list_traits::size<component_list>> ret{};
656 for (
size_t i = 0; i < list_traits::size<component_list>; ++i)
657 for (
size_t j = 0; j < static_cast<size_t>(
alphabet_size); ++j)
658 ret[i][j] = (j / cummulative_alph_sizes[i]) % alph_sizes[i];
672template <
typename derived_type,
typename ...component_types>
674 requires (detail::writable_constexpr_semialphabet<component_types> && ...) &&
675 (std::regular<component_types> && ...)
677template <
typename alphabet_type,
size_t index>
678class alphabet_tuple_base<derived_type, component_types...>::component_proxy :
public alphabet_proxy<component_proxy<alphabet_type, index>, alphabet_type>
682 using base_t = alphabet_proxy<component_proxy<alphabet_type, index>, alphabet_type>;
687 alphabet_tuple_base *parent;
690 constexpr void on_update() noexcept
692 parent->assign_component_rank<index>(this->
to_rank());
697 using base_t::operator=;
703 component_proxy() =
delete;
704 constexpr component_proxy(component_proxy
const &) =
default;
705 constexpr component_proxy(component_proxy &&) =
default;
706 constexpr component_proxy & operator=(component_proxy
const &) =
default;
707 constexpr component_proxy & operator=(component_proxy &&) =
default;
708 ~component_proxy() =
default;
711 constexpr component_proxy(alphabet_type
const l, alphabet_tuple_base & p) :
712 base_t{l}, parent{&p}
727 friend constexpr bool operator==(derived_type
const lhs, component_proxy
const rhs)
noexcept
729 return get<index>(lhs) ==
static_cast<alphabet_type
>(rhs);
733 friend constexpr bool operator==(component_proxy<alphabet_type, index>
const lhs, derived_type
const rhs)
noexcept
739 friend constexpr bool operator!=(derived_type
const lhs, component_proxy
const rhs)
noexcept
741 return get<index>(lhs) !=
static_cast<alphabet_type
>(rhs);
745 friend constexpr bool operator!=(component_proxy<alphabet_type, index>
const lhs, derived_type
const rhs)
noexcept
751 friend constexpr bool operator<(derived_type
const lhs, component_proxy
const rhs)
noexcept
753 return get<index>(lhs) <
static_cast<alphabet_type
>(rhs);
757 friend constexpr bool operator<(component_proxy<alphabet_type, index>
const lhs, derived_type
const rhs)
noexcept
763 friend constexpr bool operator<=(derived_type
const lhs, component_proxy
const rhs)
noexcept
765 return get<index>(lhs) <=
static_cast<alphabet_type
>(rhs);
769 friend constexpr bool operator<=(component_proxy<alphabet_type, index>
const lhs, derived_type
const rhs)
noexcept
775 friend constexpr bool operator>(derived_type
const lhs, component_proxy
const rhs)
noexcept
777 return get<index>(lhs) >
static_cast<alphabet_type
>(rhs);
781 friend constexpr bool operator>(component_proxy<alphabet_type, index>
const lhs, derived_type
const rhs)
noexcept
787 friend constexpr bool operator>=(derived_type
const lhs, component_proxy
const rhs)
noexcept
789 return get<index>(lhs) >=
static_cast<alphabet_type
>(rhs);
793 friend constexpr bool operator>=(component_proxy<alphabet_type, index>
const lhs, derived_type
const rhs)
noexcept
812template <std::
size_t i, seqan3::detail::alphabet_tuple_like tuple_t>
813struct tuple_element<i, tuple_t>
826template <seqan3::detail::alphabet_tuple_like tuple_t>
827struct tuple_size<tuple_t> :
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:57
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:203
constexpr rank_type to_rank() const noexcept
Return the letter's numeric value (rank in the alphabet).
Definition: alphabet_base.hpp:139
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:80
constexpr derived_type & assign_rank(rank_type const c) noexcept
Assign from a numeric value.
Definition: alphabet_base.hpp:191
The CRTP base for a combined alphabet that contains multiple values of different alphabets at the sam...
Definition: alphabet_tuple_base.hpp:123
friend constexpr auto get(alphabet_tuple_base &l) noexcept
Tuple-like access to the contained components.
Definition: alphabet_tuple_base.hpp:362
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:465
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:562
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:531
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:496
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:553
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:238
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:540
constexpr alphabet_tuple_base(component_types ... components) noexcept
Construction from initialiser-list.
Definition: alphabet_tuple_base.hpp:192
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:509
friend constexpr type get(alphabet_tuple_base const &l) noexcept
Tuple-like access to the contained components.
Definition: alphabet_tuple_base.hpp:412
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:575
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:474
constexpr alphabet_tuple_base(component_type const alph) noexcept
Construction via a value of one of the components.
Definition: alphabet_tuple_base.hpp:212
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:487
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:452
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:518
friend constexpr auto get(alphabet_tuple_base const &l) noexcept
Tuple-like access to the contained components.
Definition: alphabet_tuple_base.hpp:396
constexpr auto alphabet_size
A type trait that holds the size of a (semi-)alphabet.
Definition: concept.hpp:845
constexpr auto assign_rank_to
Assign a rank to an alphabet object.
Definition: concept.hpp:293
constexpr auto to_rank
Return the rank representation of a (semi-)alphabet object.
Definition: concept.hpp:154
decltype(detail::concat(lists_t{}...)) concat
Join two seqan3::type_list s into one.
Definition: traits.hpp:353
constexpr bool contains
Whether a type occurs in a type list or not.
Definition: traits.hpp:255
typename decltype(detail::at< idx >(list_t{}))::type at
Return the type at given index from the type list.
Definition: traits.hpp:284
constexpr ptrdiff_t count
Count the occurrences of a type in a pack.
Definition: traits.hpp:169
typename decltype(detail::at< idx, pack_t... >())::type at
Return the type at given index from the type pack.
Definition: traits.hpp:256
constexpr ptrdiff_t find_if
Get the index of the first type in a pack that satisfies the given predicate.
Definition: traits.hpp:210
Provides metaprogramming utilities for integer types.
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
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:429
SeqAn specific customisations in the standard namespace.
Type that contains multiple types.
Definition: type_list.hpp:29
static constexpr size_t size() noexcept
The number of types contained in the type list.
Definition: type_list.hpp:34
seqan3::list_traits::at< i, typename tuple_t::seqan3_required_types > type
Element type.
Definition: alphabet_tuple_base.hpp:816
Provides traits for seqan3::type_list.
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.