31 namespace seqan3::detail
35 template <
typename tuple_derived_t,
typename rhs_t,
typename... component_types>
36 inline constexpr
bool tuple_general_guard =
37 (!std::same_as<rhs_t, tuple_derived_t>)&&(!std::same_as<rhs_t, alphabet_tuple_base<component_types...>>)&&(
38 !std::is_base_of_v<tuple_derived_t, rhs_t>)&&(!(std::same_as<rhs_t, component_types> || ...))
42 template <
typename lhs_t,
typename tuple_derived_t,
typename rhs_t,
typename... component_types>
43 inline constexpr
bool tuple_eq_guard =
44 (instantiate_if_v<lazy<weakly_equality_comparable_with_trait, rhs_t, component_types>,
45 std::same_as<lhs_t, tuple_derived_t>
46 && tuple_general_guard<tuple_derived_t, rhs_t, component_types...>>
50 template <
typename lhs_t,
typename tuple_derived_t,
typename rhs_t,
typename... component_types>
51 inline constexpr
bool tuple_order_guard =
52 (instantiate_if_v<lazy<weakly_ordered_with_trait, rhs_t, component_types>,
53 std::same_as<lhs_t, tuple_derived_t>
54 && tuple_general_guard<lhs_t, tuple_derived_t, rhs_t, component_types...>>
110 template <typename derived_type, typename... component_types>
111 requires (detail::writable_constexpr_semialphabet<component_types> && ...) && (
std::regular<component_types> && ...)
112 class alphabet_tuple_base :
113 public alphabet_base<derived_type,
114 (1 * ... * alphabet_size<component_types>),
119 using base_t = alphabet_base<derived_type,
120 (1 * ... * alphabet_size<component_types>),
127 template <
typename type>
128 static constexpr
bool is_component = seqan3::list_traits::contains<type, component_list>;
131 template <
typename type>
132 static constexpr
bool is_unique_component = (seqan3::list_traits::count<type, component_list> == 1);
135 template <
typename alphabet_type,
size_t index>
136 class component_proxy;
141 constexpr alphabet_tuple_base() noexcept : base_t{}
143 constexpr alphabet_tuple_base(alphabet_tuple_base
const &) =
default;
144 constexpr alphabet_tuple_base(alphabet_tuple_base &&) =
default;
145 constexpr alphabet_tuple_base & operator=(alphabet_tuple_base
const &) =
default;
146 constexpr alphabet_tuple_base & operator=(alphabet_tuple_base &&) =
default;
147 ~alphabet_tuple_base() =
default;
149 using base_t::base_t;
157 using typename base_t::rank_type;
161 using base_t::alphabet_size;
162 using base_t::assign_rank;
167 using seqan3_required_types = component_list;
170 using seqan3_recursive_required_types = list_traits::concat<
172 detail::transformation_trait_or_t<detail::recursive_required_types<component_types>,
seqan3::type_list<>>...>;
175 static constexpr
bool seqan3_alphabet_tuple_like =
true;
185 constexpr alphabet_tuple_base(component_types... components) noexcept
200 template <
typename component_type>
201 requires (!std::is_base_of_v<alphabet_tuple_base, component_type>) && is_unique_component<component_type>
202 constexpr
explicit alphabet_tuple_base(component_type
const alph) noexcept : alphabet_tuple_base{}
204 get<component_type>(*
this) = alph;
222 template <
typename indirect_component_type>
223 requires ((detail::instantiate_if_v<
224 detail::lazy<std::is_convertible, indirect_component_type, component_types>,
225 detail::tuple_general_guard<derived_type, indirect_component_type, component_types...>>
227 constexpr explicit alphabet_tuple_base(indirect_component_type const alph) noexcept : alphabet_tuple_base{}
229 using component_predicate = detail::implicitly_convertible_from<indirect_component_type>;
230 constexpr
auto component_position =
231 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
232 using component_type = seqan3::list_traits::at<component_position, component_list>;
233 component_type tmp(alph);
234 get<component_type>(*
this) = tmp;
238 template <
typename indirect_component_type>
239 requires ((!(detail::instantiate_if_v<
240 detail::lazy<std::is_convertible, indirect_component_type, component_types>,
241 detail::tuple_general_guard<derived_type, indirect_component_type, component_types...>>
243 && (detail::instantiate_if_v<
244 detail::lazy<std::is_constructible, component_types, indirect_component_type>,
245 detail::tuple_general_guard<derived_type, indirect_component_type, component_types...>>
247 constexpr explicit alphabet_tuple_base(indirect_component_type const alph) noexcept : alphabet_tuple_base{}
249 using component_predicate = detail::constructible_from<indirect_component_type>;
250 constexpr
auto component_position =
251 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
252 using component_type = seqan3::list_traits::at<component_position, component_list>;
253 component_type tmp(alph);
254 get<component_type>(*
this) = tmp;
268 template <
typename component_type>
269 requires (!std::derived_from<component_type, alphabet_tuple_base>) && is_unique_component<component_type>
270 constexpr derived_type & operator=(component_type
const alph) noexcept
272 get<component_type>(*
this) = alph;
273 return static_cast<derived_type &
>(*this);
287 template <
typename indirect_component_type>
288 requires ((!std::derived_from<indirect_component_type, alphabet_tuple_base>)
289 && (!is_unique_component<indirect_component_type>)
290 && (std::assignable_from<component_types, indirect_component_type> || ...))
291 constexpr derived_type & operator=(indirect_component_type const alph) noexcept
293 using component_predicate = detail::assignable_from<indirect_component_type>;
294 constexpr
auto component_position =
295 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
296 using component_type = seqan3::list_traits::at<component_position, component_list>;
297 get<component_type>(*
this) = alph;
298 return static_cast<derived_type &
>(*this);
302 template <
typename indirect_component_type>
303 requires ((!std::derived_from<indirect_component_type, alphabet_tuple_base>)
304 && (!is_unique_component<indirect_component_type>)
305 && (!(std::assignable_from<component_types, indirect_component_type> || ...))
306 && (std::convertible_to<indirect_component_type, component_types> || ...))
307 constexpr derived_type & operator=(indirect_component_type const alph) noexcept
309 using component_predicate = detail::implicitly_convertible_from<indirect_component_type>;
310 constexpr
auto component_position =
311 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
312 using component_type = seqan3::list_traits::at<component_position, component_list>;
313 component_type tmp(alph);
314 get<component_type>(*
this) = tmp;
315 return static_cast<derived_type &
>(*this);
318 template <
typename indirect_component_type>
319 requires ((!std::derived_from<indirect_component_type, alphabet_tuple_base>)
320 && (!is_unique_component<indirect_component_type>)
321 && (!(std::assignable_from<component_types, indirect_component_type> || ...))
322 && (!(std::convertible_to<indirect_component_type, component_types> || ...))
323 && (std::constructible_from<component_types, indirect_component_type> || ...))
324 constexpr derived_type & operator=(indirect_component_type const alph) noexcept
326 using component_predicate = detail::constructible_from<indirect_component_type>;
327 constexpr
auto component_position =
328 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
329 using component_type = seqan3::list_traits::at<component_position, component_list>;
330 component_type tmp(alph);
331 get<component_type>(*
this) = tmp;
332 return static_cast<derived_type &
>(*this);
347 template <
size_t index>
348 friend constexpr
auto get(alphabet_tuple_base & l) noexcept
350 static_assert(index <
sizeof...(component_types),
"Index out of range.");
352 using t = seqan3::list_traits::at<index, component_list>;
357 return component_proxy<t, index>{val, l};
366 template <
typename type>
367 friend constexpr
auto get(alphabet_tuple_base & l) noexcept
370 return get<seqan3::list_traits::find<type, component_list>>(l);
379 template <
size_t index>
380 friend constexpr
auto get(alphabet_tuple_base
const & l) noexcept
382 static_assert(index <
sizeof...(component_types),
"Index out of range.");
384 using t = seqan3::list_traits::at<index, component_list>;
395 template <
typename type>
396 friend constexpr type
get(alphabet_tuple_base
const & l) noexcept
399 return get<seqan3::list_traits::find<type, component_list>>(l);
406 template <
typename type>
407 constexpr
operator type() const noexcept
410 return get<type>(*
this);
431 template <
typename derived_type_t,
typename indirect_component_type>
432 friend constexpr
auto operator==(derived_type_t
const lhs, indirect_component_type
const rhs) noexcept
434 detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
437 using component_predicate = detail::weakly_equality_comparable_with_<indirect_component_type>;
438 constexpr
auto component_position =
439 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
440 using component_type = seqan3::list_traits::at<component_position, component_list>;
441 return get<component_type>(lhs) == rhs;
445 template <
typename derived_type_t,
typename indirect_component_type>
446 friend constexpr
auto operator==(indirect_component_type
const lhs, derived_type_t
const rhs) noexcept
448 detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
455 template <
typename derived_type_t,
typename indirect_component_type>
456 friend constexpr
auto operator!=(derived_type_t
const lhs, indirect_component_type
const rhs) noexcept
458 detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
461 using component_predicate = detail::weakly_equality_comparable_with_<indirect_component_type>;
462 constexpr
auto component_position =
463 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
464 using component_type = seqan3::list_traits::at<component_position, component_list>;
465 return get<component_type>(lhs) != rhs;
469 template <
typename derived_type_t,
typename indirect_component_type>
470 friend constexpr
auto operator!=(indirect_component_type
const lhs, derived_type_t
const rhs) noexcept
472 detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
479 template <
typename derived_type_t,
typename indirect_component_type>
480 friend constexpr
auto operator<(derived_type_t
const lhs, indirect_component_type
const rhs) noexcept
482 detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
485 using component_predicate = detail::weakly_ordered_with_<indirect_component_type>;
486 constexpr
auto component_position =
487 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
488 using component_type = seqan3::list_traits::at<component_position, component_list>;
489 return get<component_type>(lhs) < rhs;
493 template <
typename derived_type_t,
typename indirect_component_type>
494 friend constexpr
auto operator<(indirect_component_type
const lhs, derived_type_t
const rhs) noexcept
496 detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
503 template <
typename derived_type_t,
typename indirect_component_type>
504 friend constexpr
auto operator<=(derived_type_t
const lhs, indirect_component_type
const rhs) noexcept
506 detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
509 using component_predicate = detail::weakly_ordered_with_<indirect_component_type>;
510 constexpr
auto component_position =
511 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
512 using component_type = seqan3::list_traits::at<component_position, component_list>;
513 return get<component_type>(lhs) <= rhs;
517 template <
typename derived_type_t,
typename indirect_component_type>
518 friend constexpr
auto operator<=(indirect_component_type
const lhs, derived_type_t
const rhs) noexcept
520 detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
527 template <
typename derived_type_t,
typename indirect_component_type>
528 friend constexpr
auto operator>(derived_type_t
const lhs, indirect_component_type
const rhs) noexcept
530 detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
533 using component_predicate = detail::weakly_ordered_with_<indirect_component_type>;
534 constexpr
auto component_position =
535 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
536 using component_type = seqan3::list_traits::at<component_position, component_list>;
537 return get<component_type>(lhs) > rhs;
541 template <
typename derived_type_t,
typename indirect_component_type>
542 friend constexpr
auto operator>(indirect_component_type
const lhs, derived_type_t
const rhs) noexcept
544 detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
551 template <
typename derived_type_t,
typename indirect_component_type>
552 friend constexpr
auto operator>=(derived_type_t
const lhs, indirect_component_type
const rhs) noexcept
554 detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
557 using component_predicate = detail::weakly_ordered_with_<indirect_component_type>;
558 constexpr
auto component_position =
559 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
560 using component_type = seqan3::list_traits::at<component_position, component_list>;
561 return get<component_type>(lhs) >= rhs;
565 template <
typename derived_type_t,
typename indirect_component_type>
566 friend constexpr
auto operator>=(indirect_component_type
const lhs, derived_type_t
const rhs) noexcept
568 detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
577 template <
size_t index>
578 constexpr rank_type to_component_rank() const noexcept
580 if constexpr (alphabet_size < 1024)
582 return rank_to_component_rank[index][
to_rank()];
586 return (
to_rank() / cummulative_alph_sizes[index])
587 % seqan3::alphabet_size<pack_traits::at<index, component_types...>>;
592 template <
size_t index>
593 constexpr
void assign_component_rank(ptrdiff_t
const r) noexcept
595 assign_rank(
static_cast<ptrdiff_t
>(
to_rank())
596 + ((r -
static_cast<ptrdiff_t
>(to_component_rank<index>()))
597 *
static_cast<ptrdiff_t
>(cummulative_alph_sizes[index])));
606 using reverse_list_t = decltype(seqan3::list_traits::detail::reverse(component_list{}));
607 seqan3::detail::for_each<reverse_list_t>([&](
auto alphabet_type_identity) constexpr {
608 using alphabet_t =
typename decltype(alphabet_type_identity)::type;
609 ret[
count] =
static_cast<rank_type
>(seqan3::alphabet_size<alphabet_t> * ret[
count - 1]);
628 return ((
seqan3::to_rank(components) * cummulative_alph_sizes[idx]) + ...);
633 alphabet_size<1024 ? alphabet_size : 0>,
634 list_traits::size<component_list>>
635 rank_to_component_rank{
637 alphabet_size<1024 ? alphabet_size : 0>,
638 list_traits::size<component_list>> ret{};
640 if constexpr (alphabet_size < 1024)
644 for (
size_t i = 0; i < list_traits::size<component_list>; ++i)
645 for (
size_t j = 0; j < static_cast<size_t>(alphabet_size); ++j)
646 ret[i][j] = (j / cummulative_alph_sizes[i]) % alph_sizes[i];
663 template <
typename derived_type,
typename... component_types>
664 requires (detail::writable_constexpr_semialphabet<component_types> && ...) && (std::regular<component_types> && ...)
665 template <
typename alphabet_type,
size_t index>
666 class alphabet_tuple_base<derived_type, component_types...>::component_proxy :
667 public alphabet_proxy<component_proxy<alphabet_type, index>, alphabet_type>
671 using base_t = alphabet_proxy<component_proxy<alphabet_type, index>, alphabet_type>;
676 alphabet_tuple_base * parent;
679 constexpr
void on_update() noexcept
681 parent->assign_component_rank<index>(this->
to_rank());
686 using base_t::operator=;
692 component_proxy() =
delete;
693 constexpr component_proxy(component_proxy
const &) =
default;
694 constexpr component_proxy(component_proxy &&) =
default;
695 constexpr component_proxy & operator=(component_proxy
const &) =
default;
696 constexpr component_proxy & operator=(component_proxy &&) =
default;
697 ~component_proxy() =
default;
700 constexpr component_proxy(alphabet_type
const l, alphabet_tuple_base & p) : base_t{l}, parent{&p}
715 friend constexpr
bool operator==(derived_type
const lhs, component_proxy
const rhs) noexcept
717 return get<index>(lhs) ==
static_cast<alphabet_type
>(rhs);
721 friend constexpr
bool operator==(component_proxy<alphabet_type, index>
const lhs, derived_type
const rhs) noexcept
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
800 template <std::
size_t i, seqan3::detail::alphabet_tuple_like tuple_t>
801 struct tuple_element<i, tuple_t>
804 using type = seqan3::list_traits::at<i, typename tuple_t::seqan3_required_types>;
814 template <seqan3::detail::alphabet_tuple_like tuple_t>
815 struct tuple_size<tuple_t> :
Core alphabet concept and free function/type trait wrappers.
Provides seqan3::alphabet_base.
Provides seqan3::alphabet_proxy.
The <concepts> header from C++20's standard library.
constexpr auto assign_rank_to
Assign a rank to an alphabet object.
Definition: alphabet/concept.hpp:293
requires requires
The rank_type of the semi-alphabet; defined as the return type of seqan3::to_rank....
Definition: alphabet/concept.hpp:164
constexpr auto to_rank
Return the rank representation of a (semi-)alphabet object.
Definition: alphabet/concept.hpp:155
requires constexpr seqan3::detail::template_specialisation_of< list_t, seqan3::type_list > bool contains
Whether a type occurs in a type list or not.
Definition: type_list/traits.hpp:252
constexpr ptrdiff_t count
Count the occurrences of a type in a pack.
Definition: type_pack/traits.hpp:164
constexpr size_t size
The size of a type pack.
Definition: type_pack/traits.hpp:146
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:415
SeqAn specific customisations in the standard namespace.
Type that contains multiple types.
Definition: type_list.hpp:29
seqan3::list_traits::at< i, typename tuple_t::seqan3_required_types > type
Element type.
Definition: alphabet_tuple_base.hpp:804
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.