19 #include <meta/meta.hpp>
32 namespace seqan3::detail
36 template <
typename tuple_derived_t,
typename rhs_t,
typename ... component_types>
37 inline constexpr
bool tuple_general_guard =
38 (!std::same_as<rhs_t, tuple_derived_t>) &&
39 (!std::same_as<rhs_t, alphabet_tuple_base<component_types...>>) &&
40 (!std::is_base_of_v<tuple_derived_t, rhs_t>) &&
41 (!(std::same_as<rhs_t, component_types> || ...)) &&
46 template <
typename lhs_t,
typename tuple_derived_t,
typename rhs_t,
typename ... component_types>
47 inline constexpr
bool tuple_eq_guard =
48 (instantiate_if_v<lazy<weakly_equality_comparable_with_trait, rhs_t, component_types>,
49 std::same_as<lhs_t, tuple_derived_t> &&
50 tuple_general_guard<tuple_derived_t, rhs_t, component_types...>
54 template <
typename lhs_t,
typename tuple_derived_t,
typename rhs_t,
typename ... component_types>
55 inline constexpr
bool tuple_order_guard =
56 (instantiate_if_v<lazy<weakly_ordered_with_trait, rhs_t, component_types>,
57 std::same_as<lhs_t, tuple_derived_t> &&
58 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);
146 template <
typename alphabet_type,
size_t index>
147 class component_proxy;
159 using base_t::base_t;
173 using base_t::assign_rank;
177 using seqan3_required_types = component_list;
180 using seqan3_recursive_required_types =
182 detail::transformation_trait_or_t<detail::recursive_required_types<component_types>,
186 static constexpr
bool seqan3_alphabet_tuple_like =
true;
211 template <
typename component_type>
213 requires (!std::is_base_of_v<alphabet_tuple_base, component_type>) &&
214 is_unique_component<component_type>
218 get<component_type>(*
this) = alph;
236 template <
typename indirect_component_type>
238 requires ((detail::instantiate_if_v<
239 detail::lazy<std::is_convertible, indirect_component_type, component_types>,
240 detail::tuple_general_guard<derived_type, indirect_component_type, component_types...>> || ...))
244 using component_type = meta::front<meta::find_if<component_list, detail::implicitly_convertible_from<indirect_component_type>>>;
245 component_type tmp(alph);
246 get<component_type>(*
this) = tmp;
250 template <
typename indirect_component_type>
251 requires ((!(detail::instantiate_if_v<
252 detail::lazy<std::is_convertible, indirect_component_type, component_types>,
253 detail::tuple_general_guard<derived_type, indirect_component_type, component_types...>> || ...)) &&
254 (detail::instantiate_if_v<
255 detail::lazy<std::is_constructible, component_types, indirect_component_type>,
256 detail::tuple_general_guard<derived_type, indirect_component_type, component_types...>> || ...))
257 constexpr explicit alphabet_tuple_base(indirect_component_type const alph) noexcept : alphabet_tuple_base{}
259 using component_type = meta::front<meta::find_if<component_list, detail::constructible_from<indirect_component_type>>>;
260 component_type tmp(alph);
261 get<component_type>(*
this) = tmp;
275 template <
typename component_type>
277 requires (!std::derived_from<component_type, alphabet_tuple_base>) &&
278 is_unique_component<component_type>
280 constexpr derived_type &
operator=(component_type
const alph) noexcept
282 get<component_type>(*
this) = alph;
283 return static_cast<derived_type &
>(*this);
297 template <
typename indirect_component_type>
299 requires ((!std::derived_from<indirect_component_type, alphabet_tuple_base>) &&
300 (!is_unique_component<indirect_component_type>) &&
301 (std::assignable_from<component_types, indirect_component_type> || ...))
303 constexpr derived_type & operator=(indirect_component_type const alph) noexcept
305 using component_type = meta::front<meta::find_if<component_list, detail::assignable_from<indirect_component_type>>>;
306 get<component_type>(*
this) = alph;
307 return static_cast<derived_type &
>(*this);
311 template <
typename indirect_component_type>
312 requires ((!std::derived_from<indirect_component_type, alphabet_tuple_base>) &&
313 (!is_unique_component<indirect_component_type>) &&
314 (!(std::assignable_from<component_types, indirect_component_type> || ...)) &&
315 (std::convertible_to<indirect_component_type, component_types> || ...))
316 constexpr derived_type & operator=(indirect_component_type const alph) noexcept
318 using component_type = meta::front<meta::find_if<component_list, detail::implicitly_convertible_from<indirect_component_type>>>;
319 component_type tmp(alph);
320 get<component_type>(*
this) = tmp;
321 return static_cast<derived_type &
>(*this);
324 template <
typename indirect_component_type>
325 requires ((!std::derived_from<indirect_component_type, alphabet_tuple_base>) &&
326 (!is_unique_component<indirect_component_type>) &&
327 (!(std::assignable_from<component_types, indirect_component_type> || ...)) &&
328 (!(std::convertible_to<indirect_component_type, component_types> || ...)) &&
329 (std::constructible_from<component_types, indirect_component_type> || ...))
330 constexpr derived_type & operator=(indirect_component_type const alph) noexcept
332 using component_type = meta::front<meta::find_if<component_list, detail::constructible_from<indirect_component_type>>>;
333 component_type tmp(alph);
334 get<component_type>(*
this) = tmp;
335 return static_cast<derived_type &
>(*this);
350 template <
size_t index>
353 static_assert(index <
sizeof...(component_types),
"Index out of range.");
355 using t = meta::at_c<component_list, index>;
360 return component_proxy<t, index>{val, l};
369 template <
typename type>
372 requires is_unique_component<type>
375 return get<meta::find_index<component_list, type>::value>(l);
384 template <
size_t index>
387 static_assert(index <
sizeof...(component_types),
"Index out of range.");
389 using t = meta::at_c<component_list, index>;
400 template <
typename type>
403 requires is_unique_component<type>
406 return get<meta::find_index<component_list, type>::value>(l);
413 template <
typename type>
414 constexpr
operator type() const noexcept
416 requires is_unique_component<type>
419 return get<type>(*
this);
440 template <
typename derived_type_t,
typename indirect_component_type>
441 friend constexpr
auto operator==(derived_type_t
const lhs, indirect_component_type
const rhs) noexcept
442 ->
std::enable_if_t<detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
445 using component_type = meta::front<meta::find_if<component_list, detail::weakly_equality_comparable_with_<indirect_component_type>>>;
446 return get<component_type>(lhs) == rhs;
450 template <
typename derived_type_t,
typename indirect_component_type>
451 friend constexpr
auto operator==(indirect_component_type
const lhs, derived_type_t
const rhs) noexcept
452 ->
std::enable_if_t<detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
459 template <
typename derived_type_t,
typename indirect_component_type>
460 friend constexpr
auto operator!=(derived_type_t
const lhs, indirect_component_type
const rhs) noexcept
461 ->
std::enable_if_t<detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
464 using component_type = meta::front<meta::find_if<component_list, detail::weakly_equality_comparable_with_<indirect_component_type>>>;
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
471 ->
std::enable_if_t<detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
478 template <
typename derived_type_t,
typename indirect_component_type>
479 friend constexpr
auto operator<(derived_type_t
const lhs, indirect_component_type
const rhs) noexcept
480 ->
std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
483 using component_type = meta::front<meta::find_if<component_list, detail::weakly_ordered_with_<indirect_component_type>>>;
484 return get<component_type>(lhs) < rhs;
488 template <
typename derived_type_t,
typename indirect_component_type>
489 friend constexpr
auto operator<(indirect_component_type
const lhs, derived_type_t
const rhs) noexcept
490 ->
std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
497 template <
typename derived_type_t,
typename indirect_component_type>
498 friend constexpr
auto operator<=(derived_type_t
const lhs, indirect_component_type
const rhs) noexcept
499 ->
std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
502 using component_type = meta::front<meta::find_if<component_list, detail::weakly_ordered_with_<indirect_component_type>>>;
503 return get<component_type>(lhs) <= rhs;
507 template <
typename derived_type_t,
typename indirect_component_type>
508 friend constexpr
auto operator<=(indirect_component_type
const lhs, derived_type_t
const rhs) noexcept
509 ->
std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
516 template <
typename derived_type_t,
typename indirect_component_type>
517 friend constexpr
auto operator>(derived_type_t
const lhs, indirect_component_type
const rhs) noexcept
518 ->
std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
521 using component_type = meta::front<meta::find_if<component_list, detail::weakly_ordered_with_<indirect_component_type>>>;
522 return get<component_type>(lhs) > rhs;
526 template <
typename derived_type_t,
typename indirect_component_type>
527 friend constexpr
auto operator>(indirect_component_type
const lhs, derived_type_t
const rhs) noexcept
528 ->
std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
535 template <
typename derived_type_t,
typename indirect_component_type>
536 friend constexpr
auto operator>=(derived_type_t
const lhs, indirect_component_type
const rhs) noexcept
537 ->
std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
540 using component_type = meta::front<meta::find_if<component_list, detail::weakly_ordered_with_<indirect_component_type>>>;
541 return get<component_type>(lhs) >= rhs;
545 template <
typename derived_type_t,
typename indirect_component_type>
546 friend constexpr
auto operator>=(indirect_component_type
const lhs, derived_type_t
const rhs) noexcept
547 ->
std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
556 template <
size_t index>
557 constexpr rank_type to_component_rank() const noexcept
561 return rank_to_component_rank[index][
to_rank()];
565 return (
to_rank() / cummulative_alph_sizes[index]) %
571 template <
size_t index>
572 constexpr
void assign_component_rank(ptrdiff_t
const r) noexcept
574 assign_rank(
static_cast<ptrdiff_t
>(
to_rank()) +
575 ((r -
static_cast<ptrdiff_t
>(to_component_rank<index>())) *
576 static_cast<ptrdiff_t
>(cummulative_alph_sizes[index])));
588 meta::for_each(meta::reverse<component_list>{}, [&] (
auto alph) constexpr
609 return ((
seqan3::to_rank(components) * cummulative_alph_sizes[idx]) + ...);
614 list_traits::size<component_list>> rank_to_component_rank
619 list_traits::size<component_list>> ret{};
625 for (
size_t i = 0; i < list_traits::size<component_list>; ++i)
626 for (
size_t j = 0; j < static_cast<size_t>(
alphabet_size); ++j)
627 ret[i][j] = (j / cummulative_alph_sizes[i]) % alph_sizes[i];
641 template <
typename derived_type,
typename ...component_types>
642 template <
typename alphabet_type,
size_t index>
643 class alphabet_tuple_base<derived_type, component_types...>::component_proxy :
public alphabet_proxy<component_proxy<alphabet_type, index>, alphabet_type>
647 using base_t = alphabet_proxy<component_proxy<alphabet_type, index>, alphabet_type>;
652 alphabet_tuple_base *parent;
655 constexpr
void on_update() noexcept
657 parent->assign_component_rank<index>(
to_rank());
662 using base_t::operator=;
668 component_proxy() =
delete;
669 constexpr component_proxy(component_proxy
const &) =
default;
670 constexpr component_proxy(component_proxy &&) =
default;
671 constexpr component_proxy & operator=(component_proxy
const &) =
default;
672 constexpr component_proxy & operator=(component_proxy &&) =
default;
673 ~component_proxy() =
default;
676 constexpr component_proxy(alphabet_type
const l, alphabet_tuple_base & p) :
677 base_t{l}, parent{&p}
692 friend constexpr
bool operator==(derived_type
const lhs, component_proxy
const rhs) noexcept
694 return get<index>(lhs) ==
static_cast<alphabet_type
>(rhs);
698 friend constexpr
bool operator==(component_proxy<alphabet_type, index>
const lhs, derived_type
const rhs) noexcept
704 friend constexpr
bool operator!=(derived_type
const lhs, component_proxy
const rhs) noexcept
706 return get<index>(lhs) !=
static_cast<alphabet_type
>(rhs);
710 friend constexpr
bool operator!=(component_proxy<alphabet_type, index>
const lhs, derived_type
const rhs) noexcept
716 friend constexpr
bool operator<(derived_type
const lhs, component_proxy
const rhs) noexcept
718 return get<index>(lhs) <
static_cast<alphabet_type
>(rhs);
722 friend constexpr
bool operator<(component_proxy<alphabet_type, index>
const lhs, derived_type
const rhs) noexcept
728 friend constexpr
bool operator<=(derived_type
const lhs, component_proxy
const rhs) noexcept
730 return get<index>(lhs) <=
static_cast<alphabet_type
>(rhs);
734 friend constexpr
bool operator<=(component_proxy<alphabet_type, index>
const lhs, derived_type
const rhs) noexcept
740 friend constexpr
bool operator>(derived_type
const lhs, component_proxy
const rhs) noexcept
742 return get<index>(lhs) >
static_cast<alphabet_type
>(rhs);
746 friend constexpr
bool operator>(component_proxy<alphabet_type, index>
const lhs, derived_type
const rhs) noexcept
752 friend constexpr
bool operator>=(derived_type
const lhs, component_proxy
const rhs) noexcept
754 return get<index>(lhs) >=
static_cast<alphabet_type
>(rhs);
758 friend constexpr
bool operator>=(component_proxy<alphabet_type, index>
const lhs, derived_type
const rhs) noexcept
777 template <std::
size_t i, seqan3::detail::alphabet_tuple_like tuple_t>
778 struct tuple_element<i, tuple_t>
781 using type = meta::at_c<typename tuple_t::seqan3_required_types, i>;
791 template <seqan3::detail::alphabet_tuple_like tuple_t>
792 struct 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:81
constexpr rank_type to_rank() const noexcept
Return the letter's numeric value (rank in the alphabet).
Definition: alphabet_base.hpp:185
The CRTP base for a combined alphabet that contains multiple values of different alphabets at the sam...
Definition: alphabet_tuple_base.hpp:124
constexpr friend 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:527
constexpr friend 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:508
constexpr friend 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:451
constexpr friend 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:441
constexpr derived_type & operator=(component_type const alph) noexcept
Assignment via a value of one of the components.
Definition: alphabet_tuple_base.hpp:280
constexpr friend 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:489
constexpr friend type get(alphabet_tuple_base const &l) noexcept
Tuple-like access to the contained components.
Definition: alphabet_tuple_base.hpp:401
constexpr friend 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:546
constexpr friend 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:498
constexpr friend 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:460
constexpr friend 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:536
constexpr friend 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:479
constexpr alphabet_tuple_base(component_types ... components) noexcept
Construction from initialiser-list.
Definition: alphabet_tuple_base.hpp:196
constexpr friend 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:470
constexpr friend auto get(alphabet_tuple_base const &l) noexcept
Tuple-like access to the contained components.
Definition: alphabet_tuple_base.hpp:385
constexpr friend 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:517
constexpr alphabet_tuple_base(component_type const alph) noexcept
Construction via a value of one of the components.
Definition: alphabet_tuple_base.hpp:216
constexpr friend auto get(alphabet_tuple_base &l) noexcept
Tuple-like access to the contained components.
Definition: alphabet_tuple_base.hpp:351
Provides concepts for core language types and relations that don't have concepts in C++20 (yet).
constexpr auto alphabet_size
A type trait that holds the size of a (semi-)alphabet.
Definition: concept.hpp:858
constexpr auto assign_rank_to
Assign a rank to an alphabet object.
Definition: concept.hpp:291
constexpr auto to_rank
Return the rank representation of a (semi-)alphabet object.
Definition: concept.hpp:155
decltype(detail::concat(lists_t{}...)) concat
Join two seqan3::type_list s into one.
Definition: traits.hpp:292
constexpr bool contains
Whether a type occurs in a type list or not.
Definition: traits.hpp:194
constexpr ptrdiff_t count
Count the occurrences of a type in a pack.
Definition: traits.hpp:168
typename decltype(detail::at< idx, pack_t... >())::type at
Return the type at given index from the type pack.
Definition: traits.hpp:255
constexpr size_t size
The size of a type pack.
Definition: traits.hpp:150
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:434
SeqAn specific customisations in the standard namespace.
meta::at_c< typename tuple_t::seqan3_required_types, i > type
Element type.
Definition: alphabet_tuple_base.hpp:781
Provides seqan3::tuple_like.
Provides traits for seqan3::type_list.
Provides various traits for template packs.