SeqAn3 3.1.0
The Modern C++ library for sequence analysis.
alphabet_tuple_base.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2021, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2021, 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 <seqan3/std/concepts>
17#include <utility>
18
31
32namespace seqan3::detail
33{
34
36template <typename tuple_derived_t, typename rhs_t, typename ... component_types>
37inline 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> || ...)) &&
42 (!list_traits::contains<tuple_derived_t, recursive_required_types_t<rhs_t>>);
43
44
46template <typename lhs_t, typename tuple_derived_t, typename rhs_t, typename ... component_types>
47inline 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...>
51 > || ...);
52
54template <typename lhs_t, typename tuple_derived_t, typename rhs_t, typename ... component_types>
55inline 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...>
59 > || ...);
60
61} // namespace seqan3::detail
62
63namespace seqan3
64{
65
66// forwards
68template <typename t>
69decltype(auto) get();
70
71template <size_t i>
72decltype(auto) get();
74
114template <typename derived_type,
115 typename ...component_types>
117 requires (detail::writable_constexpr_semialphabet<component_types> && ...) &&
118 (std::regular<component_types> && ...)
121 public alphabet_base<derived_type,
122 (1 * ... * alphabet_size<component_types>),
123 void> // no char type, because this is only semi_alphabet
124{
125private:
127 using base_t = alphabet_base<derived_type,
128 (1 * ... * alphabet_size<component_types>),
129 void>; // no char type, because this is only semi_alphabet
130
132 using component_list = seqan3::type_list<component_types...>;
133
135 template <typename type>
136 static constexpr bool is_component = seqan3::list_traits::contains<type, component_list>;
137
139 template <typename type>
140 static constexpr bool is_unique_component = (seqan3::list_traits::count<type, component_list> == 1);
141
142 // forward declaration: see implementation below
143 template <typename alphabet_type, size_t index>
144 class component_proxy;
145
149 constexpr alphabet_tuple_base() noexcept : base_t{} {}
150 constexpr alphabet_tuple_base(alphabet_tuple_base const &) = default;
151 constexpr alphabet_tuple_base(alphabet_tuple_base &&) = default;
152 constexpr alphabet_tuple_base & operator=(alphabet_tuple_base const &) = default;
153 constexpr alphabet_tuple_base & operator=(alphabet_tuple_base &&) = default;
154 ~alphabet_tuple_base() = default;
155
156 using base_t::base_t;
158
161 friend derived_type;
162
163 // Import from base:
164 using typename base_t::rank_type;
165
166public:
167 // Import from base:
169 using base_t::to_rank;
171
177 using seqan3_recursive_required_types =
179 detail::transformation_trait_or_t<detail::recursive_required_types<component_types>,
183 static constexpr bool seqan3_alphabet_tuple_like = true;
184
193 constexpr alphabet_tuple_base(component_types ... components) noexcept
194 {
195 assign_rank(rank_sum_helper(components..., std::make_index_sequence<sizeof...(component_types)>{}));
196 }
197
208 template <typename component_type>
210 requires (!std::is_base_of_v<alphabet_tuple_base, component_type>) &&
211 is_unique_component<component_type>
213 constexpr explicit alphabet_tuple_base(component_type const alph) noexcept : alphabet_tuple_base{}
214 {
215 get<component_type>(*this) = alph;
216 }
217
233 template <typename indirect_component_type>
235 requires ((detail::instantiate_if_v<
236 detail::lazy<std::is_convertible, indirect_component_type, component_types>,
237 detail::tuple_general_guard<derived_type, indirect_component_type, component_types...>> || ...))
239 constexpr explicit alphabet_tuple_base(indirect_component_type const alph) noexcept : alphabet_tuple_base{}
240 {
241 using component_predicate = detail::implicitly_convertible_from<indirect_component_type>;
242 constexpr auto component_position = seqan3::list_traits::find_if<component_predicate::template invoke,
243 component_list>;
245 component_type tmp(alph); // delegate construction
246 get<component_type>(*this) = tmp;
247 }
248
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{}
258 {
259 using component_predicate = detail::constructible_from<indirect_component_type>;
260 constexpr auto component_position = seqan3::list_traits::find_if<component_predicate::template invoke,
261 component_list>;
263 component_type tmp(alph); // delegate construction
264 get<component_type>(*this) = tmp;
265 }
267
278 template <typename component_type>
280 requires (!std::derived_from<component_type, alphabet_tuple_base>) &&
281 is_unique_component<component_type>
283 constexpr derived_type & operator=(component_type const alph) noexcept
284 {
285 get<component_type>(*this) = alph;
286 return static_cast<derived_type &>(*this);
287 }
288
300 template <typename indirect_component_type>
302 requires ((!std::derived_from<indirect_component_type, alphabet_tuple_base>) &&
303 (!is_unique_component<indirect_component_type>) &&
304 (std::assignable_from<component_types, indirect_component_type> || ...))
306 constexpr derived_type & operator=(indirect_component_type const alph) noexcept
307 {
308 using component_predicate = detail::assignable_from<indirect_component_type>;
309 constexpr auto component_position = seqan3::list_traits::find_if<component_predicate::template invoke,
312 get<component_type>(*this) = alph; // delegate assignment
313 return static_cast<derived_type &>(*this);
314 }
316 // If not assignable but implicit convertible, convert first and assign afterwards
317 template <typename indirect_component_type>
318 requires ((!std::derived_from<indirect_component_type, alphabet_tuple_base>) &&
319 (!is_unique_component<indirect_component_type>) &&
320 (!(std::assignable_from<component_types, indirect_component_type> || ...)) &&
321 (std::convertible_to<indirect_component_type, component_types> || ...))
322 constexpr derived_type & operator=(indirect_component_type const alph) noexcept
323 {
324 using component_predicate = detail::implicitly_convertible_from<indirect_component_type>;
325 constexpr auto component_position = seqan3::list_traits::find_if<component_predicate::template invoke,
326 component_list>;
328 component_type tmp(alph);
329 get<component_type>(*this) = tmp;
330 return static_cast<derived_type &>(*this);
331 }
332
333 template <typename indirect_component_type>
334 requires ((!std::derived_from<indirect_component_type, alphabet_tuple_base>) &&
335 (!is_unique_component<indirect_component_type>) &&
336 (!(std::assignable_from<component_types, indirect_component_type> || ...)) &&
337 (!(std::convertible_to<indirect_component_type, component_types> || ...)) &&
338 (std::constructible_from<component_types, indirect_component_type> || ...))
339 constexpr derived_type & operator=(indirect_component_type const alph) noexcept
340 {
341 using component_predicate = detail::constructible_from<indirect_component_type>;
342 constexpr auto component_position = seqan3::list_traits::find_if<component_predicate::template invoke,
343 component_list>;
345 component_type tmp(alph); // delegate construction
346 get<component_type>(*this) = tmp;
347 return static_cast<derived_type &>(*this);
348 }
351
362 template <size_t index>
363 friend constexpr auto get(alphabet_tuple_base & l) noexcept
364 {
365 static_assert(index < sizeof...(component_types), "Index out of range.");
366
368 t val{};
369
370 seqan3::assign_rank_to(l.to_component_rank<index>(), val);
371
372 return component_proxy<t, index>{val, l};
373 }
374
381 template <typename type>
382 friend constexpr auto get(alphabet_tuple_base & l) noexcept
384 requires is_unique_component<type>
386 {
387 return get<seqan3::list_traits::find<type, component_list>>(l);
388 }
389
396 template <size_t index>
397 friend constexpr auto get(alphabet_tuple_base const & l) noexcept
398 {
399 static_assert(index < sizeof...(component_types), "Index out of range.");
400
402
403 return seqan3::assign_rank_to(l.to_component_rank<index>(), t{});
404 }
405
412 template <typename type>
413 friend constexpr type get(alphabet_tuple_base const & l) noexcept
415 requires is_unique_component<type>
417 {
418 return get<seqan3::list_traits::find<type, component_list>>(l);
419 }
420
425 template <typename type>
426 constexpr operator type() const noexcept
428 requires is_unique_component<type>
430 {
431 return get<type>(*this);
432 }
434
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
454 -> std::enable_if_t<detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
455 bool>
456 {
457 using component_predicate = detail::weakly_equality_comparable_with_<indirect_component_type>;
458 constexpr auto component_position = seqan3::list_traits::find_if<component_predicate::template invoke,
461 return get<component_type>(lhs) == rhs;
462 }
463
465 template <typename derived_type_t, typename indirect_component_type>
466 friend constexpr auto operator==(indirect_component_type const lhs, derived_type_t const rhs) noexcept
467 -> std::enable_if_t<detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
468 bool>
469 {
470 return rhs == lhs;
471 }
472
474 template <typename derived_type_t, typename indirect_component_type>
475 friend constexpr auto operator!=(derived_type_t const lhs, indirect_component_type const rhs) noexcept
476 -> std::enable_if_t<detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
477 bool>
478 {
479 using component_predicate = detail::weakly_equality_comparable_with_<indirect_component_type>;
480 constexpr auto component_position = seqan3::list_traits::find_if<component_predicate::template invoke,
483 return get<component_type>(lhs) != rhs;
484 }
485
487 template <typename derived_type_t, typename indirect_component_type>
488 friend constexpr auto operator!=(indirect_component_type const lhs, derived_type_t const rhs) noexcept
489 -> std::enable_if_t<detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
490 bool>
491 {
492 return rhs != lhs;
493 }
494
496 template <typename derived_type_t, typename indirect_component_type>
497 friend constexpr auto operator<(derived_type_t const lhs, indirect_component_type const rhs) noexcept
498 -> std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
499 bool>
500 {
501 using component_predicate = detail::weakly_ordered_with_<indirect_component_type>;
502 constexpr auto component_position = seqan3::list_traits::find_if<component_predicate::template invoke,
505 return get<component_type>(lhs) < rhs;
506 }
507
509 template <typename derived_type_t, typename indirect_component_type>
510 friend constexpr auto operator<(indirect_component_type const lhs, derived_type_t const rhs) noexcept
511 -> std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
512 bool>
513 {
514 return rhs > lhs;
515 }
516
518 template <typename derived_type_t, typename indirect_component_type>
519 friend constexpr auto operator<=(derived_type_t const lhs, indirect_component_type const rhs) noexcept
520 -> std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
521 bool>
522 {
523 using component_predicate = detail::weakly_ordered_with_<indirect_component_type>;
524 constexpr auto component_position = seqan3::list_traits::find_if<component_predicate::template invoke,
527 return get<component_type>(lhs) <= rhs;
528 }
529
531 template <typename derived_type_t, typename indirect_component_type>
532 friend constexpr auto operator<=(indirect_component_type const lhs, derived_type_t const rhs) noexcept
533 -> std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
534 bool>
535 {
536 return rhs >= lhs;
537 }
538
540 template <typename derived_type_t, typename indirect_component_type>
541 friend constexpr auto operator>(derived_type_t const lhs, indirect_component_type const rhs) noexcept
542 -> std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
543 bool>
544 {
545 using component_predicate = detail::weakly_ordered_with_<indirect_component_type>;
546 constexpr auto component_position = seqan3::list_traits::find_if<component_predicate::template invoke,
549 return get<component_type>(lhs) > rhs;
550 }
551
553 template <typename derived_type_t, typename indirect_component_type>
554 friend constexpr auto operator>(indirect_component_type const lhs, derived_type_t const rhs) noexcept
555 -> std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
556 bool>
557 {
558 return rhs < lhs;
559 }
560
562 template <typename derived_type_t, typename indirect_component_type>
563 friend constexpr auto operator>=(derived_type_t const lhs, indirect_component_type const rhs) noexcept
564 -> std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
565 bool>
566 {
567 using component_predicate = detail::weakly_ordered_with_<indirect_component_type>;
568 constexpr auto component_position = seqan3::list_traits::find_if<component_predicate::template invoke,
571 return get<component_type>(lhs) >= rhs;
572 }
573
575 template <typename derived_type_t, typename indirect_component_type>
576 friend constexpr auto operator>=(indirect_component_type const lhs, derived_type_t const rhs) noexcept
577 -> std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
578 bool>
579 {
580 return rhs <= lhs;
581 }
583
584private:
586 template <size_t index>
587 constexpr rank_type to_component_rank() const noexcept
588 {
589 if constexpr (alphabet_size < 1024) // computation is cached for small alphabets
590 {
591 return rank_to_component_rank[index][to_rank()];
592 }
593 else
594 {
595 return (to_rank() / cummulative_alph_sizes[index]) %
596 seqan3::alphabet_size<pack_traits::at<index, component_types...>>;
597 }
598 }
599
601 template <size_t index>
602 constexpr void assign_component_rank(ptrdiff_t const r) noexcept
603 {
604 assign_rank(static_cast<ptrdiff_t>(to_rank()) +
605 ((r - static_cast<ptrdiff_t>(to_component_rank<index>())) *
606 static_cast<ptrdiff_t>(cummulative_alph_sizes[index])));
607 }
608
610 static constexpr std::array<rank_type, component_list::size()> cummulative_alph_sizes
611 {
612 [] () constexpr
613 {
614 // create array (1, |sigma1|, |sigma1|*|sigma2|, ... , |sigma1|*...*|sigmaN|)
616 ret[0] = 1;
617 size_t count = 1;
618 using reverse_list_t = decltype(seqan3::list_traits::detail::reverse(component_list{}));
619 seqan3::detail::for_each<reverse_list_t>([&] (auto alphabet_type_identity) constexpr
620 {
621 using alphabet_t = typename decltype(alphabet_type_identity)::type;
622 ret[count] = static_cast<rank_type>(seqan3::alphabet_size<alphabet_t> * ret[count - 1]);
623 ++count;
624 });
625
626 // reverse and strip one: (|sigma1|*...*|sigmaN-1|, ... |sigma1|*|sigma2|, |sigma1|, 1)
627 // reverse order guarantees that the first alphabet is the most significant rank contributer
628 // resulting in element-wise alphabetical ordering on comparison
630 for (size_t i = 0; i < component_list::size(); ++i)
631 ret2[i] = ret[component_list::size() - i - 1];
632
633 return ret2;
634 }()
635 };
636
638 template <std::size_t ...idx>
639 static constexpr rank_type rank_sum_helper(component_types ... components, std::index_sequence<idx...> const &) noexcept
640 {
641 return ((seqan3::to_rank(components) * cummulative_alph_sizes[idx]) + ...);
642 }
643
646 list_traits::size<component_list>> rank_to_component_rank
647 {
648 [] () constexpr
649 {
651 list_traits::size<component_list>> ret{};
652
653 if constexpr (alphabet_size < 1024)
654 {
655 std::array<size_t, alphabet_size> alph_sizes{ seqan3::alphabet_size<component_types>... };
656
657 for (size_t i = 0; i < list_traits::size<component_list>; ++i)
658 for (size_t j = 0; j < static_cast<size_t>(alphabet_size); ++j)
659 ret[i][j] = (j / cummulative_alph_sizes[i]) % alph_sizes[i];
660 }
661
662 return ret;
663 }()
664 };
665};
666
673template <typename derived_type, typename ...component_types>
674template <typename alphabet_type, size_t index>
675class alphabet_tuple_base<derived_type, component_types...>::component_proxy : public alphabet_proxy<component_proxy<alphabet_type, index>, alphabet_type>
676{
677private:
679 using base_t = alphabet_proxy<component_proxy<alphabet_type, index>, alphabet_type>;
681 friend base_t;
682
684 alphabet_tuple_base *parent;
685
687 constexpr void on_update() noexcept
688 {
689 parent->assign_component_rank<index>(to_rank());
690 }
691
692public:
693 //Import from base type:
694 using base_t::operator=;
695
700 component_proxy() = delete;
701 constexpr component_proxy(component_proxy const &) = default;
702 constexpr component_proxy(component_proxy &&) = default;
703 constexpr component_proxy & operator=(component_proxy const &) = default;
704 constexpr component_proxy & operator=(component_proxy &&) = default;
705 ~component_proxy() = default;
706
708 constexpr component_proxy(alphabet_type const l, alphabet_tuple_base & p) :
709 base_t{l}, parent{&p}
710 {}
711
712 // Does not inherit the base's constructor for alphabet_type so as not to cause ambiguity
714
724 friend constexpr bool operator==(derived_type const lhs, component_proxy const rhs) noexcept
725 {
726 return get<index>(lhs) == static_cast<alphabet_type>(rhs);
727 }
728
730 friend constexpr bool operator==(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
731 {
732 return rhs == lhs;
733 }
734
736 friend constexpr bool operator!=(derived_type const lhs, component_proxy const rhs) noexcept
737 {
738 return get<index>(lhs) != static_cast<alphabet_type>(rhs);
739 }
740
742 friend constexpr bool operator!=(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
743 {
744 return rhs != lhs;
745 }
746
748 friend constexpr bool operator<(derived_type const lhs, component_proxy const rhs) noexcept
749 {
750 return get<index>(lhs) < static_cast<alphabet_type>(rhs);
751 }
752
754 friend constexpr bool operator<(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
755 {
756 return rhs > lhs;
757 }
758
760 friend constexpr bool operator<=(derived_type const lhs, component_proxy const rhs) noexcept
761 {
762 return get<index>(lhs) <= static_cast<alphabet_type>(rhs);
763 }
764
766 friend constexpr bool operator<=(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
767 {
768 return rhs >= lhs;
769 }
770
772 friend constexpr bool operator>(derived_type const lhs, component_proxy const rhs) noexcept
773 {
774 return get<index>(lhs) > static_cast<alphabet_type>(rhs);
775 }
776
778 friend constexpr bool operator>(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
779 {
780 return rhs < lhs;
781 }
782
784 friend constexpr bool operator>=(derived_type const lhs, component_proxy const rhs) noexcept
785 {
786 return get<index>(lhs) >= static_cast<alphabet_type>(rhs);
787 }
788
790 friend constexpr bool operator>=(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
791 {
792 return rhs <= lhs;
793 }
795};
796
797} // namespace seqan3
798
799namespace std
800{
801
809template <std::size_t i, seqan3::detail::alphabet_tuple_like tuple_t>
810struct tuple_element<i, tuple_t>
811{
814};
815
823template <seqan3::detail::alphabet_tuple_like tuple_t>
824struct tuple_size<tuple_t> :
825 public std::integral_constant<size_t, seqan3::list_traits::size<typename tuple_t::seqan3_required_types>>
826{};
827
828} // 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:139
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:203
constexpr derived_type & assign_rank(rank_type const c) noexcept
Assign from a numeric value.
Definition: alphabet_base.hpp:191
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:554
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:532
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:466
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:453
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:510
constexpr friend type get(alphabet_tuple_base const &l) noexcept
Tuple-like access to the contained components.
Definition: alphabet_tuple_base.hpp:413
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:239
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:576
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:519
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:475
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:563
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:497
constexpr alphabet_tuple_base(component_types ... components) noexcept
Construction from initialiser-list.
Definition: alphabet_tuple_base.hpp:193
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:488
constexpr friend auto get(alphabet_tuple_base const &l) noexcept
Tuple-like access to the contained components.
Definition: alphabet_tuple_base.hpp:397
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:541
constexpr alphabet_tuple_base(component_type const alph) noexcept
Construction via a value of one of the components.
Definition: alphabet_tuple_base.hpp:213
constexpr friend auto get(alphabet_tuple_base &l) noexcept
Tuple-like access to the contained components.
Definition: alphabet_tuple_base.hpp:363
The <concepts> header from C++20's standard library.
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:861
constexpr auto assign_rank_to
Assign a rank to an alphabet object.
Definition: concept.hpp:294
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:329
constexpr bool contains
Whether a type occurs in a type list or not.
Definition: traits.hpp:231
typename decltype(detail::at< idx >(list_t{}))::type at
Return the type at given index from the type list.
Definition: traits.hpp:260
constexpr ptrdiff_t count
Count the occurrences of a type in a pack.
Definition: traits.hpp:169
typename decltype(detail::at< idx, pack_t... >())::type at
Return the type at given index from the type pack.
Definition: traits.hpp:256
constexpr ptrdiff_t find_if
Get the index of the first type in a pack that satisfies the given predicate.
Definition: traits.hpp:210
Provides metaprogramming utilities for integer types.
T invoke(T... args)
The main SeqAn3 namespace.
Definition: cigar_operation_table.hpp:2
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:429
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:813
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.