SeqAn3 3.2.0
The Modern C++ library for sequence analysis.
alphabet_tuple_base.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2022, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2022, Knut Reinert & MPI für molekulare Genetik
4// This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
5// shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md
6// -----------------------------------------------------------------------------------------------------
7
13#pragma once
14
15#include <cassert>
16#include <concepts>
17#include <utility>
18
30
31namespace seqan3::detail
32{
33
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>)&&(!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> || ...))
39 && (!list_traits::contains<tuple_derived_t, recursive_required_types_t<rhs_t>>);
40
42template <typename lhs_t, typename tuple_derived_t, typename rhs_t, typename... component_types>
43inline 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...>>
47 || ...);
48
50template <typename lhs_t, typename tuple_derived_t, typename rhs_t, typename... component_types>
51inline 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...>>
55 || ...);
56
57} // namespace seqan3::detail
58
59namespace seqan3
60{
61
62// forwards
64template <typename t>
65decltype(auto) get();
66
67template <size_t i>
68decltype(auto) get();
70
110template <typename derived_type, typename... component_types>
111 requires (detail::writable_constexpr_semialphabet<component_types> && ...) && (std::regular<component_types> && ...)
113 public alphabet_base<derived_type,
114 (1 * ... * alphabet_size<component_types>),
115 void> // no char type, because this is only semi_alphabet
116{
117private:
119 using base_t = alphabet_base<derived_type,
120 (1 * ... * alphabet_size<component_types>),
121 void>; // no char type, because this is only semi_alphabet
122
124 using component_list = seqan3::type_list<component_types...>;
125
127 template <typename type>
128 static constexpr bool is_component = seqan3::list_traits::contains<type, component_list>;
129
131 template <typename type>
132 static constexpr bool is_unique_component = (seqan3::list_traits::count<type, component_list> == 1);
133
134 // forward declaration: see implementation below
135 template <typename alphabet_type, size_t index>
136 class component_proxy;
137
141 constexpr alphabet_tuple_base() noexcept : base_t{}
142 {}
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;
148
149 using base_t::base_t;
151
154 friend derived_type;
155
156 // Import from base:
157 using typename base_t::rank_type;
158
159public:
160 // Import from base:
163 using base_t::to_rank;
164
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;
176
185 constexpr alphabet_tuple_base(component_types... components) noexcept
186 {
187 assign_rank(rank_sum_helper(components..., std::make_index_sequence<sizeof...(component_types)>{}));
188 }
189
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{}
203 {
204 get<component_type>(*this) = alph;
205 }
206
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...>>
226 || ...))
227 constexpr explicit alphabet_tuple_base(indirect_component_type const alph) noexcept : alphabet_tuple_base{}
228 {
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>;
233 component_type tmp(alph); // delegate construction
234 get<component_type>(*this) = tmp;
235 }
236
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...>>
242 || ...))
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...>>
246 || ...))
247 constexpr explicit alphabet_tuple_base(indirect_component_type const alph) noexcept : alphabet_tuple_base{}
248 {
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>;
253 component_type tmp(alph); // delegate construction
254 get<component_type>(*this) = tmp;
255 }
257
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
271 {
272 get<component_type>(*this) = alph;
273 return static_cast<derived_type &>(*this);
274 }
275
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
292 {
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>;
297 get<component_type>(*this) = alph; // delegate assignment
298 return static_cast<derived_type &>(*this);
299 }
301 // If not assignable but implicit convertible, convert first and assign afterwards
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
308 {
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>;
313 component_type tmp(alph);
314 get<component_type>(*this) = tmp;
315 return static_cast<derived_type &>(*this);
316 }
317
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
325 {
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>;
330 component_type tmp(alph); // delegate construction
331 get<component_type>(*this) = tmp;
332 return static_cast<derived_type &>(*this);
333 }
336
347 template <size_t index>
348 friend constexpr auto get(alphabet_tuple_base & l) noexcept
349 {
350 static_assert(index < sizeof...(component_types), "Index out of range.");
351
353 t val{};
354
355 seqan3::assign_rank_to(l.to_component_rank<index>(), val);
356
357 return component_proxy<t, index>{val, l};
358 }
359
366 template <typename type>
367 friend constexpr auto get(alphabet_tuple_base & l) noexcept
368 requires is_unique_component<type>
369 {
370 return get<seqan3::list_traits::find<type, component_list>>(l);
371 }
372
379 template <size_t index>
380 friend constexpr auto get(alphabet_tuple_base const & l) noexcept
381 {
382 static_assert(index < sizeof...(component_types), "Index out of range.");
383
385
386 return seqan3::assign_rank_to(l.to_component_rank<index>(), t{});
387 }
388
395 template <typename type>
396 friend constexpr type get(alphabet_tuple_base const & l) noexcept
397 requires is_unique_component<type>
398 {
399 return get<seqan3::list_traits::find<type, component_list>>(l);
400 }
401
406 template <typename type>
407 constexpr operator type() const noexcept
408 requires is_unique_component<type>
409 {
410 return get<type>(*this);
411 }
413
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...>,
435 bool>
436 {
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>;
441 return get<component_type>(lhs) == rhs;
442 }
443
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...>,
449 bool>
450 {
451 return rhs == lhs;
452 }
453
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...>,
459 bool>
460 {
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>;
465 return get<component_type>(lhs) != rhs;
466 }
467
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...>,
473 bool>
474 {
475 return rhs != lhs;
476 }
477
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...>,
483 bool>
484 {
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>;
489 return get<component_type>(lhs) < rhs;
490 }
491
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...>,
497 bool>
498 {
499 return rhs > lhs;
500 }
501
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...>,
507 bool>
508 {
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>;
513 return get<component_type>(lhs) <= rhs;
514 }
515
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...>,
521 bool>
522 {
523 return rhs >= lhs;
524 }
525
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...>,
531 bool>
532 {
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>;
537 return get<component_type>(lhs) > rhs;
538 }
539
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...>,
545 bool>
546 {
547 return rhs < lhs;
548 }
549
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...>,
555 bool>
556 {
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>;
561 return get<component_type>(lhs) >= rhs;
562 }
563
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...>,
569 bool>
570 {
571 return rhs <= lhs;
572 }
574
575private:
577 template <size_t index>
578 constexpr rank_type to_component_rank() const noexcept
579 {
580 if constexpr (alphabet_size < 1024) // computation is cached for small alphabets
581 {
582 return rank_to_component_rank[index][to_rank()];
583 }
584 else
585 {
586 return (to_rank() / cummulative_alph_sizes[index])
587 % seqan3::alphabet_size<pack_traits::at<index, component_types...>>;
588 }
589 }
590
592 template <size_t index>
593 constexpr void assign_component_rank(ptrdiff_t const r) noexcept
594 {
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])));
598 }
599
601 static constexpr std::array<rank_type, component_list::size()> cummulative_alph_sizes{
602 []() constexpr {// create array (1, |sigma1|, |sigma1|*|sigma2|, ... , |sigma1|*...*|sigmaN|)
604 ret[0] = 1;
605 size_t count = 1;
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]);
610 ++count;
611 });
612
613 // reverse and strip one: (|sigma1|*...*|sigmaN-1|, ... |sigma1|*|sigma2|, |sigma1|, 1)
614 // reverse order guarantees that the first alphabet is the most significant rank contributer
615 // resulting in element-wise alphabetical ordering on comparison
617 for (size_t i = 0; i < component_list::size(); ++i)
618 ret2[i] = ret[component_list::size() - i - 1];
619
620 return ret2;
621}()
622}; // namespace seqan3
623
625template <std::size_t... idx>
626static constexpr rank_type rank_sum_helper(component_types... components, std::index_sequence<idx...> const &) noexcept
627{
628 return ((seqan3::to_rank(components) * cummulative_alph_sizes[idx]) + ...);
629}
630
632static constexpr std::array < std::array<rank_type,
633 alphabet_size<1024 ? alphabet_size : 0>, // not for big alphs
634 list_traits::size<component_list>>
635 rank_to_component_rank{
636 []() constexpr {std::array < std::array<rank_type,
637 alphabet_size<1024 ? alphabet_size : 0>, // not for big alphs
638 list_traits::size<component_list>> ret{};
639
640if constexpr (alphabet_size < 1024)
641{
642 std::array<size_t, alphabet_size> alph_sizes{seqan3::alphabet_size<component_types>...};
643
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];
647}
648
649return ret;
650}
651()
652}
653;
654}
655;
656
663template <typename derived_type, typename... component_types>
664 requires (detail::writable_constexpr_semialphabet<component_types> && ...) && (std::regular<component_types> && ...)
665template <typename alphabet_type, size_t index>
666class alphabet_tuple_base<derived_type, component_types...>::component_proxy :
667 public alphabet_proxy<component_proxy<alphabet_type, index>, alphabet_type>
668{
669private:
671 using base_t = alphabet_proxy<component_proxy<alphabet_type, index>, alphabet_type>;
673 friend base_t;
674
676 alphabet_tuple_base * parent;
677
679 constexpr void on_update() noexcept
680 {
681 parent->assign_component_rank<index>(this->to_rank());
682 }
683
684public:
685 //Import from base type:
686 using base_t::operator=;
687
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;
698
700 constexpr component_proxy(alphabet_type const l, alphabet_tuple_base & p) : base_t{l}, parent{&p}
701 {}
702
703 // Does not inherit the base's constructor for alphabet_type so as not to cause ambiguity
705
715 friend constexpr bool operator==(derived_type const lhs, component_proxy const rhs) noexcept
716 {
717 return get<index>(lhs) == static_cast<alphabet_type>(rhs);
718 }
719
721 friend constexpr bool operator==(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
722 {
723 return rhs == lhs;
724 }
725
727 friend constexpr bool operator!=(derived_type const lhs, component_proxy const rhs) noexcept
728 {
729 return get<index>(lhs) != static_cast<alphabet_type>(rhs);
730 }
731
733 friend constexpr bool operator!=(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
734 {
735 return rhs != lhs;
736 }
737
739 friend constexpr bool operator<(derived_type const lhs, component_proxy const rhs) noexcept
740 {
741 return get<index>(lhs) < static_cast<alphabet_type>(rhs);
742 }
743
745 friend constexpr bool operator<(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
746 {
747 return rhs > lhs;
748 }
749
751 friend constexpr bool operator<=(derived_type const lhs, component_proxy const rhs) noexcept
752 {
753 return get<index>(lhs) <= static_cast<alphabet_type>(rhs);
754 }
755
757 friend constexpr bool operator<=(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
758 {
759 return rhs >= lhs;
760 }
761
763 friend constexpr bool operator>(derived_type const lhs, component_proxy const rhs) noexcept
764 {
765 return get<index>(lhs) > static_cast<alphabet_type>(rhs);
766 }
767
769 friend constexpr bool operator>(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
770 {
771 return rhs < lhs;
772 }
773
775 friend constexpr bool operator>=(derived_type const lhs, component_proxy const rhs) noexcept
776 {
777 return get<index>(lhs) >= static_cast<alphabet_type>(rhs);
778 }
779
781 friend constexpr bool operator>=(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
782 {
783 return rhs <= lhs;
784 }
786};
787
788} // namespace seqan3
789
790namespace std
791{
792
800template <std::size_t i, seqan3::detail::alphabet_tuple_like tuple_t>
801struct tuple_element<i, tuple_t>
802{
805};
806
814template <seqan3::detail::alphabet_tuple_like tuple_t>
815struct tuple_size<tuple_t> :
816 public std::integral_constant<size_t, seqan3::list_traits::size<typename tuple_t::seqan3_required_types>>
817{};
818
819} // namespace std
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
constexpr rank_type to_rank() const noexcept
Return the letter's numeric value (rank in the alphabet).
Definition: alphabet_base.hpp:137
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
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:199
constexpr derived_type & assign_rank(rank_type const c) noexcept
Assign from a numeric value.
Definition: alphabet_base.hpp:187
The CRTP base for a combined alphabet that contains multiple values of different alphabets at the sam...
Definition: alphabet_tuple_base.hpp:116
friend constexpr auto get(alphabet_tuple_base &l) noexcept
Tuple-like access to the contained components.
Definition: alphabet_tuple_base.hpp:348
friend constexpr type get(alphabet_tuple_base const &l) noexcept
Tuple-like access to the contained components.
Definition: alphabet_tuple_base.hpp:396
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:446
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:552
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:518
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:480
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:542
friend constexpr auto get(alphabet_tuple_base &l) noexcept
Tuple-like access to the contained components.
Definition: alphabet_tuple_base.hpp:367
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:227
constexpr alphabet_tuple_base(component_type const alph) noexcept
Construction via a value of one of the components.
Definition: alphabet_tuple_base.hpp:202
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:528
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:494
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:566
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:456
constexpr alphabet_tuple_base(component_types... components) noexcept
Construction from initialiser-list.
Definition: alphabet_tuple_base.hpp:185
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:470
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:432
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:504
friend constexpr auto get(alphabet_tuple_base const &l) noexcept
Tuple-like access to the contained components.
Definition: alphabet_tuple_base.hpp:380
constexpr auto alphabet_size
A type trait that holds the size of a (semi-)alphabet.
Definition: concept.hpp:849
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:155
decltype(detail::concat(lists_t{}...)) concat
Join two seqan3::type_list s into one.
Definition: traits.hpp:342
constexpr bool contains
Whether a type occurs in a type list or not.
Definition: traits.hpp:252
typename decltype(detail::at< idx >(list_t{}))::type at
Return the type at given index from the type list.
Definition: traits.hpp:279
constexpr ptrdiff_t count
Count the occurrences of a type in a pack.
Definition: traits.hpp:164
typename decltype(detail::at< idx, pack_t... >())::type at
Return the type at given index from the type pack.
Definition: traits.hpp:248
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
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:804
Provides seqan3::detail::transformation_trait_or.
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.