SeqAn3  3.0.3
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 
32 namespace seqan3::detail
33 {
34 
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> || ...)) &&
42  (!list_traits::contains<tuple_derived_t, recursive_required_types_t<rhs_t>>);
43 
44 
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...>
51  > || ...);
52 
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...>
59  > || ...);
60 
61 } // namespace seqan3::detail
62 
63 namespace seqan3
64 {
65 
66 // forwards
68 template <typename t>
69 decltype(auto) get();
70 
71 template <size_t i>
72 decltype(auto) get();
74 
114 template <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 {
125 private:
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 
166 public:
167  // Import from base:
168  using base_t::alphabet_size;
169  using base_t::to_rank;
170  using base_t::assign_rank;
171 
177  using seqan3_recursive_required_types =
179  detail::transformation_trait_or_t<detail::recursive_required_types<component_types>,
180  seqan3::type_list<>>...>;
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 
584 private:
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|)
615  std::array<rank_type, component_list::size() + 1> ret{};
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
629  std::array<rank_type, component_list::size()> ret2{};
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 
673 template <typename derived_type, typename ...component_types>
674 template <typename alphabet_type, size_t index>
675 class alphabet_tuple_base<derived_type, component_types...>::component_proxy : public alphabet_proxy<component_proxy<alphabet_type, index>, alphabet_type>
676 {
677 private:
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 
692 public:
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 
799 namespace std
800 {
801 
809 template <std::size_t i, seqan3::detail::alphabet_tuple_like tuple_t>
810 struct tuple_element<i, tuple_t>
811 {
814 };
815 
823 template <seqan3::detail::alphabet_tuple_like tuple_t>
824 struct 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: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: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 derived_type & operator=(component_type const alph) noexcept
Assignment via a value of one of the components.
Definition: alphabet_tuple_base.hpp:283
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 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 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: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: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 size_t size
The size of a type pack.
Definition: traits.hpp:151
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: 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:429
SeqAn specific customisations in the standard namespace.
Provides algorithms for meta programming, parameter packs and seqan3::type_list.
Type that contains multiple types.
Definition: type_list.hpp:29
seqan3::list_traits::at< i, typename tuple_t::seqan3_required_types > type
Element type.
Definition: alphabet_tuple_base.hpp:813
Provides seqan3::tuple_like.
Provides traits for seqan3::type_list.
Provides seqan3::type_list.
Provides various traits for template packs.
Provides seqan3::detail::transformation_trait_or.