45 #include <meta/meta.hpp> 79 template <
typename cartesian_t,
typename cartesian_derived_t,
template <
typename>
typename fun_t,
typename other_t>
80 inline bool constexpr one_component_is =
false;
85 template <
typename ... cartesian_comps,
86 typename cartesian_derived_t,
87 template <
typename>
typename fun_t,
89 inline bool constexpr one_component_is<cartesian_composition<cartesian_derived_t, cartesian_comps...>,
93 !
meta::empty<meta::find_if<meta::list<cartesian_comps...>, fun_t<other_t>>>::value;
97 template <
typename ... cartesian_comps,
98 typename cartesian_derived_t,
99 template <
typename>
typename fun_t>
100 inline bool constexpr one_component_is<cartesian_composition<cartesian_derived_t, cartesian_comps...>,
103 cartesian_composition<cartesian_derived_t, cartesian_comps...>> =
false;
106 template <
typename ... cartesian_comps,
107 typename cartesian_derived_t,
108 template <
typename>
typename fun_t>
109 inline bool constexpr one_component_is<cartesian_composition<cartesian_derived_t, cartesian_comps...>,
112 cartesian_derived_t> =
false;
115 template <
typename ... cartesian_comps,
116 typename cartesian_derived_t,
117 template <
typename>
typename fun_t,
119 requires convertible_to_by_member_concept<other_t, cartesian_derived_t>
120 inline bool constexpr one_component_is<cartesian_composition<cartesian_derived_t, cartesian_comps...>,
126 template <
typename ... cartesian_comps,
127 typename cartesian_derived_t,
128 template <
typename>
typename fun_t,
130 requires type_in_pack_v<other_t, cartesian_comps...>
133 inline bool constexpr one_component_is<cartesian_composition<cartesian_derived_t, cartesian_comps...>,
140 template <
typename ... cartesian_comps,
141 typename cartesian_derived_t,
143 requires implicitly_convertible_to_concept<other_t, cartesian_derived_t>
144 inline bool constexpr one_component_is<cartesian_composition<cartesian_derived_t, cartesian_comps...>,
146 weakly_equality_comparable_with,
148 template <
typename ... cartesian_comps,
149 typename cartesian_derived_t,
151 requires implicitly_convertible_to_concept<other_t, cartesian_derived_t>
152 inline bool constexpr one_component_is<cartesian_composition<cartesian_derived_t, cartesian_comps...>,
165 template <
typename t>
166 decltype(
auto)
get();
169 decltype(auto)
get();
204 template <typename derived_type,
205 typename ...component_types>
207 requires (detail::constexpr_semi_alphabet_concept<component_types> && ...)
211 (1 * ... * alphabet_size_v<component_types>),
217 (1 * ... * alphabet_size_v<component_types>),
221 using component_list = meta::list<component_types...>;
224 template <
typename type>
225 static constexpr
bool is_component =
226 meta::in<component_list, type>::value;
229 template <
typename type>
230 static constexpr
bool is_unique_component =
231 is_component<type> &&
232 (meta::find_index<component_list, type>::value == meta::reverse_find_index<component_list, type>::value);
238 template <
typename alphabet_type,
size_t index>
239 class component_proxy :
public alphabet_proxy<component_proxy<alphabet_type, index>, alphabet_type>
251 constexpr
void on_update() noexcept
255 - parent->template to_component_rank<index>() * cartesian_composition::cummulative_alph_sizes[index]
256 +
to_rank() * cartesian_composition::cummulative_alph_sizes[index]);
262 using base_t::value_size;
263 using base_t::operator=;
270 using typename base_t::phred_type;
276 constexpr component_proxy() :
base_t{}, parent{} {}
277 constexpr component_proxy(component_proxy
const &) =
default;
278 constexpr component_proxy(component_proxy &&) =
default;
279 constexpr component_proxy & operator=(component_proxy
const &) =
default;
280 constexpr component_proxy & operator=(component_proxy &&) =
default;
281 ~component_proxy() =
default;
295 constexpr cartesian_composition(cartesian_composition
const &) =
default;
296 constexpr cartesian_composition(cartesian_composition &&) =
default;
297 constexpr cartesian_composition & operator=(cartesian_composition
const &) =
default;
298 constexpr cartesian_composition & operator=(cartesian_composition &&) =
default;
299 ~cartesian_composition() =
default;
301 using base_t::base_t;
310 using base_t::value_size;
317 using seqan3_cartesian_components = component_list;
320 using seqan3_recursive_cartesian_components =
321 meta::concat<component_list,
322 detail::transformation_trait_or_t<detail::recursive_cartesian_components<component_types>,
332 constexpr cartesian_composition(component_types ... components)
335 assign_rank(rank_sum_helper(components..., std::make_index_sequence<
sizeof...(component_types)>{}));
347 template <
typename component_type>
349 requires is_unique_component<component_type>
353 get<component_type>(*this) = alph;
369 template <
typename indirect_component_type>
371 requires detail::one_component_is<cartesian_composition, derived_type, detail::implicitly_convertible_from, indirect_component_type>
375 using component_type = meta::front<meta::find_if<component_list, detail::implicitly_convertible_from<indirect_component_type>>>;
376 component_type tmp(alph);
377 get<component_type>(*this) = tmp;
381 template <
typename indirect_component_type>
382 requires !detail::one_component_is<cartesian_composition, derived_type, detail::implicitly_convertible_from, indirect_component_type> &&
383 detail::one_component_is<cartesian_composition, derived_type, detail::constructible_from, indirect_component_type>
384 constexpr
explicit cartesian_composition(indirect_component_type
const alph) : cartesian_composition{}
386 using component_type = meta::front<meta::find_if<component_list, detail::constructible_from<indirect_component_type>>>;
387 component_type tmp(alph);
388 get<component_type>(*this) = tmp;
401 template <
typename component_type>
403 requires is_unique_component<component_type>
405 constexpr derived_type &
operator=(component_type
const alph)
407 get<component_type>(*this) = alph;
408 return static_cast<derived_type &
>(*this);
420 template <
typename indirect_component_type>
422 requires detail::one_component_is<cartesian_composition, derived_type, detail::assignable_from, indirect_component_type>
424 constexpr derived_type &
operator=(indirect_component_type
const alph)
426 using component_type = meta::front<meta::find_if<component_list, detail::assignable_from<indirect_component_type>>>;
427 get<component_type>(*this) = alph;
428 return static_cast<derived_type &
>(*this);
432 template <
typename indirect_component_type>
434 requires !detail::one_component_is<cartesian_composition, derived_type, detail::assignable_from, indirect_component_type> &&
435 detail::one_component_is<cartesian_composition, derived_type, detail::implicitly_convertible_from, indirect_component_type>
437 constexpr derived_type & operator=(indirect_component_type
const alph)
439 using component_type = meta::front<meta::find_if<component_list, detail::implicitly_convertible_from<indirect_component_type>>>;
440 component_type tmp(alph);
441 get<component_type>(*this) = tmp;
442 return static_cast<derived_type &
>(*this);
455 template <
size_t index>
456 friend constexpr
auto get(cartesian_composition & l)
458 static_assert(index <
sizeof...(component_types),
"Index out of range.");
460 using t = meta::at_c<component_list, index>;
466 return component_proxy<t, index>{val, l};
473 template <
typename type>
474 friend constexpr
auto get(cartesian_composition & l)
476 requires is_unique_component<type>
479 return get<meta::find_index<component_list, type>::value>(l);
486 template <
size_t index>
487 friend constexpr
auto get(cartesian_composition
const & l)
489 static_assert(index <
sizeof...(component_types),
"Index out of range.");
491 using t = meta::at_c<component_list, index>;
504 template <
typename type>
505 friend constexpr type
get(cartesian_composition
const & l)
507 requires is_unique_component<type>
510 return get<meta::find_index<component_list, type>::value>(l);
515 template <
typename type>
516 constexpr
operator type() const
518 requires is_unique_component<type>
521 return get<type>(*this);
530 template <
typename indirect_component_type>
531 constexpr
bool operator==(indirect_component_type
const & rhs)
const noexcept
533 requires detail::one_component_is<cartesian_composition, derived_type, detail::weakly_equality_comparable_with, indirect_component_type>
536 using component_type = meta::front<meta::find_if<component_list, detail::weakly_equality_comparable_with<indirect_component_type>>>;
537 return get<component_type>(*this) == rhs;
540 template <
typename indirect_component_type>
541 constexpr
bool operator!=(indirect_component_type
const & rhs)
const noexcept
543 requires detail::one_component_is<cartesian_composition, derived_type, detail::weakly_equality_comparable_with, indirect_component_type>
546 using component_type = meta::front<meta::find_if<component_list, detail::weakly_equality_comparable_with<indirect_component_type>>>;
547 return get<component_type>(*this) != rhs;
550 template <
typename indirect_component_type>
551 constexpr
bool operator<(indirect_component_type
const & rhs)
const noexcept
553 requires detail::one_component_is<cartesian_composition, derived_type, detail::weakly_ordered_with, indirect_component_type>
556 using component_type = meta::front<meta::find_if<component_list, detail::weakly_ordered_with<indirect_component_type>>>;
557 return get<component_type>(*this) < rhs;
560 template <
typename indirect_component_type>
561 constexpr
bool operator>(indirect_component_type
const & rhs)
const noexcept
563 requires detail::one_component_is<cartesian_composition, derived_type, detail::weakly_ordered_with, indirect_component_type>
566 using component_type = meta::front<meta::find_if<component_list, detail::weakly_ordered_with<indirect_component_type>>>;
567 return get<component_type>(*this) > rhs;
570 template <
typename indirect_component_type>
571 constexpr
bool operator<=(indirect_component_type
const & rhs)
const noexcept
573 requires detail::one_component_is<cartesian_composition, derived_type, detail::weakly_ordered_with, indirect_component_type>
576 using component_type = meta::front<meta::find_if<component_list, detail::weakly_ordered_with<indirect_component_type>>>;
577 return get<component_type>(*this) <= rhs;
580 template <
typename indirect_component_type>
581 constexpr
bool operator>=(indirect_component_type
const & rhs)
const noexcept
583 requires detail::one_component_is<cartesian_composition, derived_type, detail::weakly_ordered_with, indirect_component_type>
586 using component_type = meta::front<meta::find_if<component_list, detail::weakly_ordered_with<indirect_component_type>>>;
587 return get<component_type>(*this) >= rhs;
593 template <
size_t index>
594 constexpr
rank_type to_component_rank()
const 596 return (
to_rank() / cummulative_alph_sizes[index]) % alphabet_size_v<meta::at_c<component_list, index>>;
600 static constexpr std::array<rank_type, component_list::size()> cummulative_alph_sizes
605 std::array<rank_type, component_list::size() + 1> ret{};
608 meta::for_each(meta::reverse<component_list>{}, [&] (
auto && alph) constexpr
610 ret[count] =
static_cast<rank_type>(alphabet_size_v<std::decay_t<decltype(alph)>> * ret[count - 1]);
617 std::array<rank_type, component_list::size()> ret2{};
619 ret2[i] = ret[component_list::size() - i - 1];
626 template <std::size_t ...idx>
627 static constexpr
rank_type rank_sum_helper(component_types ... components, std::index_sequence<idx...>
const &)
630 return ((
to_rank(components) * cummulative_alph_sizes[idx]) + ...);
639 template <
typename indirect_component_type,
typename derived_type,
typename ...component_types>
641 requires detail::weakly_equality_comparable_by_members_with_concept<derived_type, indirect_component_type> &&
642 !detail::weakly_equality_comparable_by_members_with_concept<indirect_component_type, derived_type>
644 constexpr
bool operator==(indirect_component_type
const & lhs,
650 template <
typename indirect_component_type,
typename derived_type,
typename ...indirect_component_types>
652 requires detail::weakly_equality_comparable_by_members_with_concept<derived_type, indirect_component_type> &&
653 !detail::weakly_equality_comparable_by_members_with_concept<indirect_component_type, derived_type>
655 constexpr
bool operator!=(indirect_component_type
const & lhs,
661 template <
typename indirect_component_type,
typename derived_type,
typename ...indirect_component_types>
663 requires detail::weakly_ordered_by_members_with_concept<derived_type, indirect_component_type> &&
664 !detail::weakly_ordered_by_members_with_concept<indirect_component_type, derived_type>
666 constexpr
bool operator<(indirect_component_type
const & lhs,
672 template <
typename indirect_component_type,
typename derived_type,
typename ...indirect_component_types>
674 requires detail::weakly_ordered_by_members_with_concept<derived_type, indirect_component_type> &&
675 !detail::weakly_ordered_by_members_with_concept<indirect_component_type, derived_type>
677 constexpr
bool operator>(indirect_component_type
const & lhs,
683 template <
typename indirect_component_type,
typename derived_type,
typename ...indirect_component_types>
685 requires detail::weakly_ordered_by_members_with_concept<derived_type, indirect_component_type> &&
686 !detail::weakly_ordered_by_members_with_concept<indirect_component_type, derived_type>
688 constexpr
bool operator<=(indirect_component_type
const & lhs,
694 template <
typename indirect_component_type,
typename derived_type,
typename ...indirect_component_types>
696 requires detail::weakly_ordered_by_members_with_concept<derived_type, indirect_component_type> &&
697 !detail::weakly_ordered_by_members_with_concept<indirect_component_type, derived_type>
699 constexpr
bool operator>=(indirect_component_type
const & lhs,
713 template <std::
size_t i, seqan3::detail::cartesian_composition_concept tuple_t>
714 struct tuple_element<i, tuple_t>
717 using type = meta::at_c<typename tuple_t::seqan3_cartesian_components, i>;
722 template <seqan3::detail::cartesian_composition_concept tuple_t>
723 struct tuple_size<tuple_t> :
724 public std::integral_constant<size_t, tuple_t::seqan3_cartesian_components::size()>
constexpr cartesian_composition(component_type const alph)
Construction via a value of one of the components.
Definition: cartesian_composition.hpp:351
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:89
Provides concepts for core language types and relations that don't have concepts in C++20 (yet)...
void char_type
The type of the alphabet when converted to char (e.g. via to_char()).
Definition: alphabet_base.hpp:87
The CRTP base for a combined alphabet that contains multiple values of different alphabets at the sam...
Definition: cartesian_composition.hpp:209
A CRTP-base that eases the definition of proxy types returned in place of regular alphabets...
Definition: alphabet_proxy.hpp:152
Contains metaprogramming utilities for integer types.
Provides various metafunctions on a set of types, usually provided as template argument pack...
meta::at_c< typename tuple_t::seqan3_cartesian_components, i > type
Element type.
Definition: cartesian_composition.hpp:717
SeqAn specific customisations in the standard namespace.
Definition: align_result.hpp:221
constexpr derived_type & operator=(component_type const alph)
Assignment via a value of one of the components.
Definition: cartesian_composition.hpp:405
::ranges::size size
Alias for ranges::size. Obtains the size of a range whose size can be calculated in constant time...
Definition: ranges:195
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:58
Provides implementation detail for seqan3::union_composition and seqan3::cartesian_composition.
constexpr auto const & get(detail::configuration< cfg_elements_t... > const &cfg) noexcept
Definition: utility.hpp:364
Provides seqan3::tuple_like_concept.
constexpr alphabet_type & assign_rank(alphabet_type &alph, underlying_rank_t< alphabet_type > const rank) requires requires(alphabet_type alph)
Implementation of seqan3::semi_alphabet_concept::assign_rank() that delegates to a member function...
Definition: member_exposure.hpp:110
Free function/metafunction wrappers for alphabets with member functions/types.
Provides utility functions for tuple like interfaces.
Provides seqan3::alphabet_base.
Definition: aligned_sequence_concept.hpp:288
semi_alphabet_concept && assign_rank(semi_alphabet_concept &&alph, rank_type const rank)
Returns the alphabet letter's value in rank representation.
rank_type to_rank(semi_alphabet_concept const alph)
Returns the alphabet letter's value in rank representation.
::ranges::empty empty
Alias for ranges::empty. Checks whether a range is empty.
Definition: ranges:205
Core alphabet concept and free function/metafunction wrappers.
constexpr derived_type & operator=(indirect_component_type const alph)
Assignment via a value of a subtype that is assignable to one of the components.
Definition: cartesian_composition.hpp:424
A CRTP-base that makes defining a custom alphabet easier.
Definition: alphabet_base.hpp:77
Quality alphabet concept.
constexpr cartesian_composition(indirect_component_type const alph)
Construction via a value of a subtype that is assignable to one of the components.
Definition: cartesian_composition.hpp:373
constexpr underlying_rank_t< alphabet_type > to_rank(alphabet_type const alph) requires requires(alphabet_type alph)
Implementation of seqan3::semi_alphabet_concept::to_rank() that delegates to a member function...
Definition: member_exposure.hpp:97
auto const to_rank
A view that calls seqan3::to_rank() on each element in the input range.
Definition: to_rank.hpp:90