SeqAn3 3.4.0-rc.1
The Modern C++ library for sequence analysis.
Loading...
Searching...
No Matches
alphabet_tuple_base.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2006-2024 Knut Reinert & Freie Universität Berlin
2// SPDX-FileCopyrightText: 2016-2024 Knut Reinert & MPI für molekulare Genetik
3// SPDX-License-Identifier: BSD-3-Clause
4
10#pragma once
11
12#include <cassert>
13#include <concepts>
14#include <utility>
15
27
28namespace seqan3::detail
29{
30
32template <typename tuple_derived_t, typename rhs_t, typename... component_types>
33inline constexpr bool tuple_general_guard =
34 (!std::same_as<rhs_t, tuple_derived_t>) && (!std::same_as<rhs_t, alphabet_tuple_base<component_types...>>)
35 && (!std::is_base_of_v<tuple_derived_t, rhs_t>) && (!(std::same_as<rhs_t, component_types> || ...))
36 && (!list_traits::contains<tuple_derived_t, recursive_required_types_t<rhs_t>>);
37
39template <typename lhs_t, typename tuple_derived_t, typename rhs_t, typename... component_types>
40inline constexpr bool tuple_eq_guard =
41 (instantiate_if_v<lazy<weakly_equality_comparable_with_trait, rhs_t, component_types>,
42 std::same_as<lhs_t, tuple_derived_t>
43 && tuple_general_guard<tuple_derived_t, rhs_t, component_types...>>
44 || ...);
45
47template <typename lhs_t, typename tuple_derived_t, typename rhs_t, typename... component_types>
48inline constexpr bool tuple_order_guard =
49 (instantiate_if_v<lazy<weakly_ordered_with_trait, rhs_t, component_types>,
50 std::same_as<lhs_t, tuple_derived_t>
51 && tuple_general_guard<lhs_t, tuple_derived_t, rhs_t, component_types...>>
52 || ...);
53
54} // namespace seqan3::detail
55
56namespace seqan3
57{
58
59// forwards
61template <typename t>
62decltype(auto) get();
63
64template <size_t i>
65decltype(auto) get();
67
107template <typename derived_type, typename... component_types>
108 requires (detail::writable_constexpr_semialphabet<component_types> && ...) && (std::regular<component_types> && ...)
110 public alphabet_base<derived_type,
111 (1 * ... * alphabet_size<component_types>),
112 void> // no char type, because this is only semi_alphabet
113{
114private:
116 using base_t = alphabet_base<derived_type,
117 (1 * ... * alphabet_size<component_types>),
118 void>; // no char type, because this is only semi_alphabet
119
121 using component_list = seqan3::type_list<component_types...>;
122
124 template <typename type>
125 static constexpr bool is_component = seqan3::list_traits::contains<type, component_list>;
126
128 template <typename type>
129 static constexpr bool is_unique_component = (seqan3::list_traits::count<type, component_list> == 1);
130
131 // forward declaration: see implementation below
132 template <typename alphabet_type, size_t index>
133 class component_proxy;
134
138 constexpr alphabet_tuple_base() noexcept : base_t{}
139 {}
140 constexpr alphabet_tuple_base(alphabet_tuple_base const &) = default;
141 constexpr alphabet_tuple_base(alphabet_tuple_base &&) = default;
142 constexpr alphabet_tuple_base & operator=(alphabet_tuple_base const &) = default;
143 constexpr alphabet_tuple_base & operator=(alphabet_tuple_base &&) = default;
144 ~alphabet_tuple_base() = default;
145
146 using base_t::base_t;
148
151 friend derived_type;
152
153 // Import from base:
154 using typename base_t::rank_type;
155
156public:
157 // Import from base:
160 using base_t::to_rank;
161
167 using seqan3_recursive_required_types = list_traits::concat<
169 detail::transformation_trait_or_t<detail::recursive_required_types<component_types>, seqan3::type_list<>>...>;
172 static constexpr bool seqan3_alphabet_tuple_like = true;
173
182 constexpr alphabet_tuple_base(component_types... components) noexcept
183 {
184 assign_rank(rank_sum_helper(components..., std::make_index_sequence<sizeof...(component_types)>{}));
185 }
186
197 template <typename component_type>
198 requires (!std::is_base_of_v<alphabet_tuple_base, component_type>) && is_unique_component<component_type>
199 constexpr explicit alphabet_tuple_base(component_type const alph) noexcept : alphabet_tuple_base{}
200 {
201 get<component_type>(*this) = alph;
202 }
203
219 template <typename indirect_component_type>
220 requires ((detail::instantiate_if_v<
221 detail::lazy<std::is_convertible, indirect_component_type, component_types>,
222 detail::tuple_general_guard<derived_type, indirect_component_type, component_types...>>
223 || ...))
224 constexpr explicit alphabet_tuple_base(indirect_component_type const alph) noexcept : alphabet_tuple_base{}
225 {
226 using component_predicate = detail::implicitly_convertible_from<indirect_component_type>;
227 constexpr auto component_position =
228 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
230 component_type tmp(alph); // delegate construction
231 get<component_type>(*this) = tmp;
232 }
233
235 template <typename indirect_component_type>
236 requires ((!(detail::instantiate_if_v<
237 detail::lazy<std::is_convertible, indirect_component_type, component_types>,
238 detail::tuple_general_guard<derived_type, indirect_component_type, component_types...>>
239 || ...))
240 && (detail::instantiate_if_v<
241 detail::lazy<std::is_constructible, component_types, indirect_component_type>,
242 detail::tuple_general_guard<derived_type, indirect_component_type, component_types...>>
243 || ...))
244 constexpr explicit alphabet_tuple_base(indirect_component_type const alph) noexcept : alphabet_tuple_base{}
245 {
246 using component_predicate = detail::constructible_from<indirect_component_type>;
247 constexpr auto component_position =
248 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
250 component_type tmp(alph); // delegate construction
251 get<component_type>(*this) = tmp;
252 }
254
265 template <typename component_type>
266 requires (!std::derived_from<component_type, alphabet_tuple_base>) && is_unique_component<component_type>
267 constexpr derived_type & operator=(component_type const alph) noexcept
268 {
269 get<component_type>(*this) = alph;
270 return static_cast<derived_type &>(*this);
271 }
272
284 template <typename indirect_component_type>
285 requires ((!std::derived_from<indirect_component_type, alphabet_tuple_base>)
286 && (!is_unique_component<indirect_component_type>)
287 && (std::assignable_from<component_types, indirect_component_type> || ...))
288 constexpr derived_type & operator=(indirect_component_type const alph) noexcept
289 {
290 using component_predicate = detail::assignable_from<indirect_component_type>;
291 constexpr auto component_position =
292 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
294 get<component_type>(*this) = alph; // delegate assignment
295 return static_cast<derived_type &>(*this);
296 }
298 // If not assignable but implicit convertible, convert first and assign afterwards
299 template <typename indirect_component_type>
300 requires ((!std::derived_from<indirect_component_type, alphabet_tuple_base>)
301 && (!is_unique_component<indirect_component_type>)
302 && (!(std::assignable_from<component_types, indirect_component_type> || ...))
303 && (std::convertible_to<indirect_component_type, component_types> || ...))
304 constexpr derived_type & operator=(indirect_component_type const alph) noexcept
305 {
306 using component_predicate = detail::implicitly_convertible_from<indirect_component_type>;
307 constexpr auto component_position =
308 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
310 component_type tmp(alph);
311 get<component_type>(*this) = tmp;
312 return static_cast<derived_type &>(*this);
313 }
314
315 template <typename indirect_component_type>
316 requires ((!std::derived_from<indirect_component_type, alphabet_tuple_base>)
317 && (!is_unique_component<indirect_component_type>)
318 && (!(std::assignable_from<component_types, indirect_component_type> || ...))
319 && (!(std::convertible_to<indirect_component_type, component_types> || ...))
320 && (std::constructible_from<component_types, indirect_component_type> || ...))
321 constexpr derived_type & operator=(indirect_component_type const alph) noexcept
322 {
323 using component_predicate = detail::constructible_from<indirect_component_type>;
324 constexpr auto component_position =
325 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
327 component_type tmp(alph); // delegate construction
328 get<component_type>(*this) = tmp;
329 return static_cast<derived_type &>(*this);
330 }
333
344 template <size_t index>
345 friend constexpr auto get(alphabet_tuple_base & l) noexcept
346 {
347 static_assert(index < sizeof...(component_types), "Index out of range.");
348
350 t val{};
351
352 seqan3::assign_rank_to(l.to_component_rank<index>(), val);
353
354 return component_proxy<t, index>{val, l};
355 }
356
363 template <typename type>
364 friend constexpr auto get(alphabet_tuple_base & l) noexcept
365 requires is_unique_component<type>
366 {
367 return get<seqan3::list_traits::find<type, component_list>>(l);
368 }
369
376 template <size_t index>
377 friend constexpr auto get(alphabet_tuple_base const & l) noexcept
378 {
379 static_assert(index < sizeof...(component_types), "Index out of range.");
380
382
383 return seqan3::assign_rank_to(l.to_component_rank<index>(), t{});
384 }
385
392 template <typename type>
393 friend constexpr type get(alphabet_tuple_base const & l) noexcept
394 requires is_unique_component<type>
395 {
396 return get<seqan3::list_traits::find<type, component_list>>(l);
397 }
398
403 template <typename type>
404 constexpr operator type() const noexcept
405 requires is_unique_component<type>
406 {
407 return get<type>(*this);
408 }
410
428 template <typename derived_type_t, typename indirect_component_type>
429 friend constexpr auto operator==(derived_type_t const lhs, indirect_component_type const rhs) noexcept
431 detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
432 bool>
433 {
434 using component_predicate = detail::weakly_equality_comparable_with_<indirect_component_type>;
435 constexpr auto component_position =
436 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
438 return get<component_type>(lhs) == rhs;
439 }
440
442 template <typename derived_type_t, typename indirect_component_type>
443 friend constexpr auto operator==(indirect_component_type const lhs, derived_type_t const rhs) noexcept
445 detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
446 bool>
447 {
448 return rhs == lhs;
449 }
450
452 template <typename derived_type_t, typename indirect_component_type>
453 friend constexpr auto operator!=(derived_type_t const lhs, indirect_component_type const rhs) noexcept
455 detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
456 bool>
457 {
458 using component_predicate = detail::weakly_equality_comparable_with_<indirect_component_type>;
459 constexpr auto component_position =
460 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
462 return get<component_type>(lhs) != rhs;
463 }
464
466 template <typename derived_type_t, typename indirect_component_type>
467 friend constexpr auto operator!=(indirect_component_type const lhs, derived_type_t const rhs) noexcept
469 detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
470 bool>
471 {
472 return rhs != lhs;
473 }
474
476 template <typename derived_type_t, typename indirect_component_type>
477 friend constexpr auto operator<(derived_type_t const lhs, indirect_component_type const rhs) noexcept
479 detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
480 bool>
481 {
482 using component_predicate = detail::weakly_ordered_with_<indirect_component_type>;
483 constexpr auto component_position =
484 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
486 return get<component_type>(lhs) < rhs;
487 }
488
490 template <typename derived_type_t, typename indirect_component_type>
491 friend constexpr auto operator<(indirect_component_type const lhs, derived_type_t const rhs) noexcept
493 detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
494 bool>
495 {
496 return rhs > lhs;
497 }
498
500 template <typename derived_type_t, typename indirect_component_type>
501 friend constexpr auto operator<=(derived_type_t const lhs, indirect_component_type const rhs) noexcept
503 detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
504 bool>
505 {
506 using component_predicate = detail::weakly_ordered_with_<indirect_component_type>;
507 constexpr auto component_position =
508 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
510 return get<component_type>(lhs) <= rhs;
511 }
512
514 template <typename derived_type_t, typename indirect_component_type>
515 friend constexpr auto operator<=(indirect_component_type const lhs, derived_type_t const rhs) noexcept
517 detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
518 bool>
519 {
520 return rhs >= lhs;
521 }
522
524 template <typename derived_type_t, typename indirect_component_type>
525 friend constexpr auto operator>(derived_type_t const lhs, indirect_component_type const rhs) noexcept
527 detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
528 bool>
529 {
530 using component_predicate = detail::weakly_ordered_with_<indirect_component_type>;
531 constexpr auto component_position =
532 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
534 return get<component_type>(lhs) > rhs;
535 }
536
538 template <typename derived_type_t, typename indirect_component_type>
539 friend constexpr auto operator>(indirect_component_type const lhs, derived_type_t const rhs) noexcept
541 detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
542 bool>
543 {
544 return rhs < lhs;
545 }
546
548 template <typename derived_type_t, typename indirect_component_type>
549 friend constexpr auto operator>=(derived_type_t const lhs, indirect_component_type const rhs) noexcept
551 detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
552 bool>
553 {
554 using component_predicate = detail::weakly_ordered_with_<indirect_component_type>;
555 constexpr auto component_position =
556 seqan3::list_traits::find_if<component_predicate::template invoke, component_list>;
558 return get<component_type>(lhs) >= rhs;
559 }
560
562 template <typename derived_type_t, typename indirect_component_type>
563 friend constexpr auto operator>=(indirect_component_type const lhs, derived_type_t const rhs) noexcept
565 detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
566 bool>
567 {
568 return rhs <= lhs;
569 }
571
572private:
574 template <size_t index>
575 constexpr rank_type to_component_rank() const noexcept
576 {
577 if constexpr (alphabet_size < 1024) // computation is cached for small alphabets
578 {
579 return rank_to_component_rank[index][to_rank()];
580 }
581 else
582 {
583 return (to_rank() / cummulative_alph_sizes[index])
584 % seqan3::alphabet_size<pack_traits::at<index, component_types...>>;
585 }
586 }
587
589 template <size_t index>
590 constexpr void assign_component_rank(ptrdiff_t const r) noexcept
591 {
592 assign_rank(static_cast<ptrdiff_t>(to_rank())
593 + ((r - static_cast<ptrdiff_t>(to_component_rank<index>()))
594 * static_cast<ptrdiff_t>(cummulative_alph_sizes[index])));
595 }
596
598 template <std::size_t... idx>
599 static constexpr rank_type rank_sum_helper(component_types... components,
600 std::index_sequence<idx...> const &) noexcept
601 {
602 return ((seqan3::to_rank(components) * cummulative_alph_sizes[idx]) + ...);
603 }
604
606 static constexpr std::array<rank_type, component_list::size()> cummulative_alph_sizes{
607 []() constexpr
608 {
609 // create array (1, |sigma1|, |sigma1|*|sigma2|, ... , |sigma1|*...*|sigmaN|)
611 ret[0] = 1;
612
613 size_t count = 1;
614 using reverse_list_t = decltype(seqan3::list_traits::detail::reverse(component_list{}));
615
616 seqan3::detail::for_each<reverse_list_t>(
617 [&](auto alphabet_type_identity) constexpr
618 {
619 using alphabet_t = typename decltype(alphabet_type_identity)::type;
620 ret[count] = static_cast<rank_type>(seqan3::alphabet_size<alphabet_t> * ret[count - 1]);
621 ++count;
622 });
623
624 // reverse and strip one: (|sigma1|*...*|sigmaN-1|, ... |sigma1|*|sigma2|, |sigma1|, 1)
625 // reverse order guarantees that the first alphabet is the most significant rank contributer
626 // resulting in element-wise alphabetical ordering on comparison
628
629 for (size_t i = 0; i < component_list::size(); ++i)
630 ret2[i] = ret[component_list::size() - i - 1];
631
632 return ret2;
633 }()};
634
636 static constexpr std::array < std::array<rank_type,
637 alphabet_size<1024u ? alphabet_size : 0u>, // not for big alphs
638 list_traits::size<component_list>>
639 rank_to_component_rank{
640 []() constexpr
641 {
643 alphabet_size<1024u ? alphabet_size : 0u>, // not for big alphs
644 list_traits::size<component_list>>
645 ret{};
646
647 if constexpr (alphabet_size < 1024u)
648 {
649 std::array<size_t, alphabet_size> alph_sizes{seqan3::alphabet_size<component_types>...};
650
651 for (size_t i = 0; i < list_traits::size<component_list>; ++i)
652 for (size_t j = 0; j < static_cast<size_t>(alphabet_size); ++j)
653 ret[i][j] = (j / cummulative_alph_sizes[i]) % alph_sizes[i];
654 }
655
656 return ret;
657 }()};
658};
659
666template <typename derived_type, typename... component_types>
667 requires (detail::writable_constexpr_semialphabet<component_types> && ...) && (std::regular<component_types> && ...)
668template <typename alphabet_type, size_t index>
669class alphabet_tuple_base<derived_type, component_types...>::component_proxy :
670 public alphabet_proxy<component_proxy<alphabet_type, index>, alphabet_type>
671{
672private:
674 using base_t = alphabet_proxy<component_proxy<alphabet_type, index>, alphabet_type>;
676 friend base_t;
677
679 alphabet_tuple_base * parent;
680
682 constexpr void on_update() noexcept
683 {
684 parent->assign_component_rank<index>(this->to_rank());
685 }
686
687public:
688 //Import from base type:
689 using base_t::operator=;
690
695 component_proxy() = delete;
696 constexpr component_proxy(component_proxy const &) = default;
697 constexpr component_proxy(component_proxy &&) = default;
698 constexpr component_proxy & operator=(component_proxy const &) = default;
699 constexpr component_proxy & operator=(component_proxy &&) = default;
700 ~component_proxy() = default;
701
703 constexpr component_proxy(alphabet_type const l, alphabet_tuple_base & p) : base_t{l}, parent{&p}
704 {}
705
706 // Does not inherit the base's constructor for alphabet_type so as not to cause ambiguity
708
718 friend constexpr bool operator==(derived_type const lhs, component_proxy const rhs) noexcept
719 {
720 return get<index>(lhs) == static_cast<alphabet_type>(rhs);
721 }
722
724 friend constexpr bool operator==(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
725 {
726 return rhs == lhs;
727 }
728
730 friend constexpr bool operator!=(derived_type const lhs, component_proxy const rhs) noexcept
731 {
732 return get<index>(lhs) != static_cast<alphabet_type>(rhs);
733 }
734
736 friend constexpr bool operator!=(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
737 {
738 return rhs != lhs;
739 }
740
742 friend constexpr bool operator<(derived_type const lhs, component_proxy const rhs) noexcept
743 {
744 return get<index>(lhs) < static_cast<alphabet_type>(rhs);
745 }
746
748 friend constexpr bool operator<(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
749 {
750 return rhs > lhs;
751 }
752
754 friend constexpr bool operator<=(derived_type const lhs, component_proxy const rhs) noexcept
755 {
756 return get<index>(lhs) <= static_cast<alphabet_type>(rhs);
757 }
758
760 friend constexpr bool operator<=(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
761 {
762 return rhs >= lhs;
763 }
764
766 friend constexpr bool operator>(derived_type const lhs, component_proxy const rhs) noexcept
767 {
768 return get<index>(lhs) > static_cast<alphabet_type>(rhs);
769 }
770
772 friend constexpr bool operator>(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
773 {
774 return rhs < lhs;
775 }
776
778 friend constexpr bool operator>=(derived_type const lhs, component_proxy const rhs) noexcept
779 {
780 return get<index>(lhs) >= static_cast<alphabet_type>(rhs);
781 }
782
784 friend constexpr bool operator>=(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
785 {
786 return rhs <= lhs;
787 }
789};
790
791} // namespace seqan3
792
793namespace std
794{
795
803template <std::size_t i, seqan3::detail::alphabet_tuple_like tuple_t>
804struct tuple_element<i, tuple_t>
805{
808};
809
817template <seqan3::detail::alphabet_tuple_like tuple_t>
818struct tuple_size<tuple_t> :
819 public std::integral_constant<size_t, seqan3::list_traits::size<typename tuple_t::seqan3_required_types>>
820{};
821
822} // namespace std
Provides implementation detail for seqan3::alphabet_variant and seqan3::alphabet_tuple_base.
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:54
constexpr rank_type to_rank() const noexcept
Return the letter's numeric value (rank in the alphabet).
Definition alphabet_base.hpp:134
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:77
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:196
constexpr derived_type & assign_rank(rank_type const c) noexcept
Assign from a numeric value.
Definition alphabet_base.hpp:184
The CRTP base for a combined alphabet that contains multiple values of different alphabets at the sam...
Definition alphabet_tuple_base.hpp:113
friend constexpr auto get(alphabet_tuple_base &l) noexcept
Tuple-like access to the contained components.
Definition alphabet_tuple_base.hpp:345
friend constexpr type get(alphabet_tuple_base const &l) noexcept
Tuple-like access to the contained components.
Definition alphabet_tuple_base.hpp:393
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:443
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:549
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:515
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:477
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:539
friend constexpr auto get(alphabet_tuple_base &l) noexcept
Tuple-like access to the contained components.
Definition alphabet_tuple_base.hpp:364
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:224
constexpr alphabet_tuple_base(component_type const alph) noexcept
Construction via a value of one of the components.
Definition alphabet_tuple_base.hpp:199
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:525
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:491
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:563
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:453
constexpr alphabet_tuple_base(component_types... components) noexcept
Construction from initialiser-list.
Definition alphabet_tuple_base.hpp:182
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:467
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:429
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:501
friend constexpr auto get(alphabet_tuple_base const &l) noexcept
Tuple-like access to the contained components.
Definition alphabet_tuple_base.hpp:377
constexpr auto alphabet_size
A type trait that holds the size of a (semi-)alphabet.
Definition alphabet/concept.hpp:834
constexpr auto assign_rank_to
Assign a rank to an alphabet object.
Definition alphabet/concept.hpp:288
constexpr auto to_rank
Return the rank representation of a (semi-)alphabet object.
Definition alphabet/concept.hpp:152
decltype(detail::concat(lists_t{}...)) concat
Join two seqan3::type_list s into one.
Definition type_list/traits.hpp:339
constexpr bool contains
Whether a type occurs in a type list or not.
Definition type_list/traits.hpp:249
typename decltype(detail::at< idx >(list_t{}))::type at
Return the type at given index from the type list.
Definition type_list/traits.hpp:276
constexpr ptrdiff_t count
Count the occurrences of a type in a pack.
Definition type_pack/traits.hpp:161
typename decltype(detail::at< idx, pack_t... >())::type at
Return the type at given index from the type pack.
Definition type_pack/traits.hpp:245
Provides metaprogramming utilities for integer types.
The main SeqAn3 namespace.
Definition aligned_sequence_concept.hpp:26
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:412
SeqAn specific customisations in the standard namespace.
Type that contains multiple types.
Definition type_list.hpp:26
static constexpr size_t size() noexcept
The number of types contained in the type list.
Definition type_list.hpp:31
seqan3::list_traits::at< i, typename tuple_t::seqan3_required_types > type
Element type.
Definition alphabet_tuple_base.hpp:807
Provides seqan3::detail::transformation_trait_or.
Provides traits for seqan3::type_list.
constexpr type_list reverse(type_list<>)
A replacement for meta::reverse [recursion anchor].
Definition type_list/traits.hpp:123
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.
Hide me