SeqAn3  3.0.1
The Modern C++ library for sequence analysis.
alphabet_tuple_base.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2020, 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 <utility>
17 
18 #include <meta/meta.hpp>
19 
32 #include <seqan3/std/concepts>
33 
34 namespace seqan3::detail
35 {
36 
38 template <typename tuple_derived_t, typename rhs_t, typename ... component_types>
39 inline constexpr bool tuple_general_guard =
41  (!std::same_as<rhs_t, alphabet_tuple_base<component_types...>>) &&
42  (!std::is_base_of_v<tuple_derived_t, rhs_t>) &&
44  (!list_traits::contains<tuple_derived_t, recursive_required_types_t<rhs_t>>);
45 
46 
48 template <typename lhs_t, typename tuple_derived_t, typename rhs_t, typename ... component_types>
49 inline constexpr bool tuple_eq_guard =
50  (instantiate_if_v<lazy<weakly_equality_comparable_with_trait, rhs_t, component_types>,
52  tuple_general_guard<tuple_derived_t, rhs_t, component_types...>
53  > || ...);
54 
56 template <typename lhs_t, typename tuple_derived_t, typename rhs_t, typename ... component_types>
57 inline constexpr bool tuple_order_guard =
58  (instantiate_if_v<lazy<weakly_ordered_with_trait, rhs_t, component_types>,
60  tuple_general_guard<lhs_t, tuple_derived_t, rhs_t, component_types...>
61  > || ...);
62 
63 } // namespace seqan3::detail
64 
65 namespace seqan3
66 {
67 
68 // forwards
70 template <typename t>
71 decltype(auto) get();
72 
73 template <size_t i>
74 decltype(auto) get();
76 
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 = meta::list<component_types...>;
133 
135  template <typename type>
136  static constexpr bool is_component =
137  meta::in<component_list, type>::value;
138 
140  template <typename type>
141  static constexpr bool is_unique_component =
142  is_component<type> &&
143  (meta::find_index<component_list, type>::value == meta::reverse_find_index<component_list, type>::value);
144 
149  template <typename alphabet_type, size_t index>
150  class component_proxy : public alphabet_proxy<component_proxy<alphabet_type, index>, alphabet_type>
151  {
152  private:
156  friend base_t;
157 
159  alphabet_tuple_base *parent;
160 
162  constexpr void on_update() noexcept
163  {
164  parent->assign_component_rank<index>(to_rank());
165  }
166 
167  public:
168  //Import from base type:
169  using base_t::operator=;
170 
174  component_proxy() = delete;
176  constexpr component_proxy(component_proxy const &) = default;
177  constexpr component_proxy(component_proxy &&) = default;
178  constexpr component_proxy & operator=(component_proxy const &) = default;
179  constexpr component_proxy & operator=(component_proxy &&) = default;
180  ~component_proxy() = default;
181 
183  constexpr component_proxy(alphabet_type const l, alphabet_tuple_base & p) :
184  base_t{l}, parent{&p}
185  {}
186 
187  // Does not inherit the base's constructor for alphabet_type so as not to cause ambiguity
189 
199  friend constexpr bool operator==(derived_type const lhs, component_proxy const rhs) noexcept
200  {
201  return get<index>(lhs) == static_cast<alphabet_type>(rhs);
202  }
203 
205  friend constexpr bool operator==(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
206  {
207  return rhs == lhs;
208  }
209 
211  friend constexpr bool operator!=(derived_type const lhs, component_proxy const rhs) noexcept
212  {
213  return get<index>(lhs) != static_cast<alphabet_type>(rhs);
214  }
215 
217  friend constexpr bool operator!=(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
218  {
219  return rhs != lhs;
220  }
221 
223  friend constexpr bool operator<(derived_type const lhs, component_proxy const rhs) noexcept
224  {
225  return get<index>(lhs) < static_cast<alphabet_type>(rhs);
226  }
227 
229  friend constexpr bool operator<(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
230  {
231  return rhs > lhs;
232  }
233 
235  friend constexpr bool operator<=(derived_type const lhs, component_proxy const rhs) noexcept
236  {
237  return get<index>(lhs) <= static_cast<alphabet_type>(rhs);
238  }
239 
241  friend constexpr bool operator<=(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
242  {
243  return rhs >= lhs;
244  }
245 
247  friend constexpr bool operator>(derived_type const lhs, component_proxy const rhs) noexcept
248  {
249  return get<index>(lhs) > static_cast<alphabet_type>(rhs);
250  }
251 
253  friend constexpr bool operator>(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
254  {
255  return rhs < lhs;
256  }
257 
259  friend constexpr bool operator>=(derived_type const lhs, component_proxy const rhs) noexcept
260  {
261  return get<index>(lhs) >= static_cast<alphabet_type>(rhs);
262  }
263 
265  friend constexpr bool operator>=(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
266  {
267  return rhs <= lhs;
268  }
269  };
270 
274  constexpr alphabet_tuple_base() noexcept : base_t{} {}
275  constexpr alphabet_tuple_base(alphabet_tuple_base const &) = default;
276  constexpr alphabet_tuple_base(alphabet_tuple_base &&) = default;
277  constexpr alphabet_tuple_base & operator=(alphabet_tuple_base const &) = default;
278  constexpr alphabet_tuple_base & operator=(alphabet_tuple_base &&) = default;
279  ~alphabet_tuple_base() = default;
280 
281  using base_t::base_t;
283 
286  friend derived_type;
287 
288  // Import from base:
289  using typename base_t::rank_type;
290 
291 public:
292  // Import from base:
293  using base_t::alphabet_size;
294  using base_t::to_rank;
295  using base_t::assign_rank;
296 
299  using seqan3_required_types = component_list;
302  using seqan3_recursive_required_types =
303  meta::concat<component_list,
304  detail::transformation_trait_or_t<detail::recursive_required_types<component_types>,
305  meta::list<>>...>;
308  static constexpr bool seqan3_alphabet_tuple_base_specialisation = true;
309 
317  constexpr alphabet_tuple_base(component_types ... components) noexcept
319  {
320  assign_rank(rank_sum_helper(components..., std::make_index_sequence<sizeof...(component_types)>{}));
321  }
322 
331  template <typename component_type>
333  requires (!std::is_base_of_v<alphabet_tuple_base, component_type>) &&
334  is_unique_component<component_type>
336  constexpr explicit alphabet_tuple_base(component_type const alph) noexcept : alphabet_tuple_base{}
337  {
338  get<component_type>(*this) = alph;
339  }
340 
354  template <typename indirect_component_type>
356  requires ((detail::instantiate_if_v<
357  detail::lazy<std::is_convertible, indirect_component_type, component_types>,
358  detail::tuple_general_guard<derived_type, indirect_component_type, component_types...>> || ...))
360  constexpr explicit alphabet_tuple_base(indirect_component_type const alph) noexcept : alphabet_tuple_base{}
361  {
362  using component_type = meta::front<meta::find_if<component_list, detail::implicitly_convertible_from<indirect_component_type>>>;
363  component_type tmp(alph); // delegate construction
364  get<component_type>(*this) = tmp;
365  }
366 
368  template <typename indirect_component_type>
369  requires ((!(detail::instantiate_if_v<
370  detail::lazy<std::is_convertible, indirect_component_type, component_types>,
371  detail::tuple_general_guard<derived_type, indirect_component_type, component_types...>> || ...)) &&
372  (detail::instantiate_if_v<
373  detail::lazy<std::is_constructible, component_types, indirect_component_type>,
374  detail::tuple_general_guard<derived_type, indirect_component_type, component_types...>> || ...))
375  constexpr explicit alphabet_tuple_base(indirect_component_type const alph) noexcept : alphabet_tuple_base{}
376  {
377  using component_type = meta::front<meta::find_if<component_list, detail::constructible_from<indirect_component_type>>>;
378  component_type tmp(alph); // delegate construction
379  get<component_type>(*this) = tmp;
380  }
382 
391  template <typename component_type>
394  is_unique_component<component_type>
396  constexpr derived_type & operator=(component_type const alph) noexcept
397  {
398  get<component_type>(*this) = alph;
399  return static_cast<derived_type &>(*this);
400  }
401 
411  template <typename indirect_component_type>
414  (!is_unique_component<indirect_component_type>) &&
417  constexpr derived_type & operator=(indirect_component_type const alph) noexcept
418  {
419  using component_type = meta::front<meta::find_if<component_list, detail::assignable_from<indirect_component_type>>>;
420  get<component_type>(*this) = alph; // delegate assignment
421  return static_cast<derived_type &>(*this);
422  }
424  // If not assignable but implicit convertible, convert first and assign afterwards
425  template <typename indirect_component_type>
427  (!is_unique_component<indirect_component_type>) &&
430  constexpr derived_type & operator=(indirect_component_type const alph) noexcept
431  {
432  using component_type = meta::front<meta::find_if<component_list, detail::implicitly_convertible_from<indirect_component_type>>>;
433  component_type tmp(alph);
434  get<component_type>(*this) = tmp;
435  return static_cast<derived_type &>(*this);
436  }
437 
438  template <typename indirect_component_type>
440  (!is_unique_component<indirect_component_type>) &&
444  constexpr derived_type & operator=(indirect_component_type const alph) noexcept
445  {
446  using component_type = meta::front<meta::find_if<component_list, detail::constructible_from<indirect_component_type>>>;
447  component_type tmp(alph); // delegate construction
448  get<component_type>(*this) = tmp;
449  return static_cast<derived_type &>(*this);
450  }
453 
462  template <size_t index>
463  friend constexpr auto get(alphabet_tuple_base & l) noexcept
464  {
465  static_assert(index < sizeof...(component_types), "Index out of range.");
466 
467  using t = meta::at_c<component_list, index>;
468  t val{};
469 
470  seqan3::assign_rank_to(l.to_component_rank<index>(), val);
471 
472  return component_proxy<t, index>{val, l};
473  }
474 
479  template <typename type>
480  friend constexpr auto get(alphabet_tuple_base & l) noexcept
482  requires is_unique_component<type>
484  {
485  return get<meta::find_index<component_list, type>::value>(l);
486  }
487 
492  template <size_t index>
493  friend constexpr auto get(alphabet_tuple_base const & l) noexcept
494  {
495  static_assert(index < sizeof...(component_types), "Index out of range.");
496 
497  using t = meta::at_c<component_list, index>;
498 
499  return seqan3::assign_rank_to(l.to_component_rank<index>(), t{});
500  }
501 
506  template <typename type>
507  friend constexpr type get(alphabet_tuple_base const & l) noexcept
509  requires is_unique_component<type>
511  {
512  return get<meta::find_index<component_list, type>::value>(l);
513  }
514 
517  template <typename type>
518  constexpr operator type() const noexcept
520  requires is_unique_component<type>
522  {
523  return get<type>(*this);
524  }
526 
542  template <typename derived_type_t, typename indirect_component_type>
543  friend constexpr auto operator==(derived_type_t const lhs, indirect_component_type const rhs) noexcept
544  -> std::enable_if_t<detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
545  bool>
546  {
547  using component_type = meta::front<meta::find_if<component_list, detail::weakly_equality_comparable_with_<indirect_component_type>>>;
548  return get<component_type>(lhs) == rhs;
549  }
550 
552  template <typename derived_type_t, typename indirect_component_type>
553  friend constexpr auto operator==(indirect_component_type const lhs, derived_type_t const rhs) noexcept
554  -> std::enable_if_t<detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
555  bool>
556  {
557  return rhs == lhs;
558  }
559 
561  template <typename derived_type_t, typename indirect_component_type>
562  friend constexpr auto operator!=(derived_type_t const lhs, indirect_component_type const rhs) noexcept
563  -> std::enable_if_t<detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
564  bool>
565  {
566  using component_type = meta::front<meta::find_if<component_list, detail::weakly_equality_comparable_with_<indirect_component_type>>>;
567  return get<component_type>(lhs) != rhs;
568  }
569 
571  template <typename derived_type_t, typename indirect_component_type>
572  friend constexpr auto operator!=(indirect_component_type const lhs, derived_type_t const rhs) noexcept
573  -> std::enable_if_t<detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
574  bool>
575  {
576  return rhs != lhs;
577  }
578 
580  template <typename derived_type_t, typename indirect_component_type>
581  friend constexpr auto operator<(derived_type_t const lhs, indirect_component_type const rhs) noexcept
582  -> std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
583  bool>
584  {
585  using component_type = meta::front<meta::find_if<component_list, detail::weakly_ordered_with_<indirect_component_type>>>;
586  return get<component_type>(lhs) < rhs;
587  }
588 
590  template <typename derived_type_t, typename indirect_component_type>
591  friend constexpr auto operator<(indirect_component_type const lhs, derived_type_t const rhs) noexcept
592  -> std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
593  bool>
594  {
595  return rhs > lhs;
596  }
597 
599  template <typename derived_type_t, typename indirect_component_type>
600  friend constexpr auto operator<=(derived_type_t const lhs, indirect_component_type const rhs) noexcept
601  -> std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
602  bool>
603  {
604  using component_type = meta::front<meta::find_if<component_list, detail::weakly_ordered_with_<indirect_component_type>>>;
605  return get<component_type>(lhs) <= rhs;
606  }
607 
609  template <typename derived_type_t, typename indirect_component_type>
610  friend constexpr auto operator<=(indirect_component_type const lhs, derived_type_t const rhs) noexcept
611  -> std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
612  bool>
613  {
614  return rhs >= lhs;
615  }
616 
618  template <typename derived_type_t, typename indirect_component_type>
619  friend constexpr auto operator>(derived_type_t const lhs, indirect_component_type const rhs) noexcept
620  -> std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
621  bool>
622  {
623  using component_type = meta::front<meta::find_if<component_list, detail::weakly_ordered_with_<indirect_component_type>>>;
624  return get<component_type>(lhs) > rhs;
625  }
626 
628  template <typename derived_type_t, typename indirect_component_type>
629  friend constexpr auto operator>(indirect_component_type const lhs, derived_type_t const rhs) noexcept
630  -> std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
631  bool>
632  {
633  return rhs < lhs;
634  }
635 
637  template <typename derived_type_t, typename indirect_component_type>
638  friend constexpr auto operator>=(derived_type_t const lhs, indirect_component_type const rhs) noexcept
639  -> std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
640  bool>
641  {
642  using component_type = meta::front<meta::find_if<component_list, detail::weakly_ordered_with_<indirect_component_type>>>;
643  return get<component_type>(lhs) >= rhs;
644  }
645 
647  template <typename derived_type_t, typename indirect_component_type>
648  friend constexpr auto operator>=(indirect_component_type const lhs, derived_type_t const rhs) noexcept
649  -> std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
650  bool>
651  {
652  return rhs <= lhs;
653  }
655 
656 private:
658  template <size_t index>
659  constexpr rank_type to_component_rank() const noexcept
660  {
661  if constexpr (alphabet_size < 1024) // computation is cached for small alphabets
662  {
663  return rank_to_component_rank[index][to_rank()];
664  }
665  else
666  {
667  return (to_rank() / cummulative_alph_sizes[index]) %
668  seqan3::alphabet_size<pack_traits::at<index, component_types...>>;
669  }
670  }
671 
673  template <size_t index>
674  constexpr void assign_component_rank(ptrdiff_t const r) noexcept
675  {
676  assign_rank(static_cast<ptrdiff_t>(to_rank()) +
677  ((r - static_cast<ptrdiff_t>(to_component_rank<index>())) *
678  static_cast<ptrdiff_t>(cummulative_alph_sizes[index])));
679  }
680 
682  static constexpr std::array<rank_type, component_list::size()> cummulative_alph_sizes
683  {
684  [] () constexpr
685  {
686  // create array (1, |sigma1|, |sigma1|*|sigma2|, ... , |sigma1|*...*|sigmaN|)
687  std::array<rank_type, component_list::size() + 1> ret{};
688  ret[0] = 1;
689  size_t count = 1;
690  meta::for_each(meta::reverse<component_list>{}, [&] (auto alph) constexpr
691  {
692  ret[count] = static_cast<rank_type>(seqan3::alphabet_size<decltype(alph)> * ret[count - 1]);
693  ++count;
694  });
695 
696  // reverse and strip one: (|sigma1|*...*|sigmaN-1|, ... |sigma1|*|sigma2|, |sigma1|, 1)
697  // reverse order guarantees that the first alphabet is the most significant rank contributer
698  // resulting in element-wise alphabetical ordering on comparison
699  std::array<rank_type, component_list::size()> ret2{};
700  for (size_t i = 0; i < component_list::size(); ++i)
701  ret2[i] = ret[component_list::size() - i - 1];
702 
703  return ret2;
704  }()
705  };
706 
708  template <std::size_t ...idx>
709  static constexpr rank_type rank_sum_helper(component_types ... components, std::index_sequence<idx...> const &) noexcept
710  {
711  return ((seqan3::to_rank(components) * cummulative_alph_sizes[idx]) + ...);
712  }
713 
716  list_traits::size<component_list>> rank_to_component_rank
717  {
718  [] () constexpr
719  {
721  list_traits::size<component_list>> ret{};
722 
723  if constexpr (alphabet_size < 1024)
724  {
725  std::array<size_t, alphabet_size> alph_sizes{ seqan3::alphabet_size<component_types>... };
726 
727  for (size_t i = 0; i < list_traits::size<component_list>; ++i)
728  for (size_t j = 0; j < static_cast<size_t>(alphabet_size); ++j)
729  ret[i][j] = (j / cummulative_alph_sizes[i]) % alph_sizes[i];
730  }
731 
732  return ret;
733  }()
734  };
735 };
736 
737 } // namespace seqan3
738 
739 namespace std
740 {
741 
747 template <std::size_t i, seqan3::detail::alphabet_tuple_base_specialisation tuple_t>
748 struct tuple_element<i, tuple_t>
749 {
751  using type = meta::at_c<typename tuple_t::seqan3_required_types, i>;
752 };
753 
759 template <seqan3::detail::alphabet_tuple_base_specialisation tuple_t>
760 struct tuple_size<tuple_t> :
761  public std::integral_constant<size_t, seqan3::list_traits::size<typename tuple_t::seqan3_required_types>>
762 {};
763 
764 } // namespace std
765 
seqan3::alphabet_tuple_base::operator=
constexpr derived_type & operator=(component_type const alph) noexcept
Assignment via a value of one of the components.
Definition: alphabet_tuple_base.hpp:396
seqan3::alphabet_tuple_base::get
constexpr friend auto get(alphabet_tuple_base &l) noexcept
Tuple-like access to the contained components.
Definition: alphabet_tuple_base.hpp:463
alphabet_base.hpp
Provides seqan3::alphabet_base.
std::integral_constant
seqan3::assign_rank_to
constexpr auto assign_rank_to
Assign a rank to an alphabet object.
Definition: concept.hpp:238
utility
seqan3::alphabet_tuple_base::get
constexpr friend auto get(alphabet_tuple_base const &l) noexcept
Tuple-like access to the contained components.
Definition: alphabet_tuple_base.hpp:493
tuple.hpp
Provides seqan3::tuple_like.
constructible_from
The std::constructible_from concept specifies that a variable of type T can be initialized with the g...
seqan3::alphabet_tuple_base::operator!=
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:562
std::make_index_sequence
seqan3::alphabet_tuple_base
The CRTP base for a combined alphabet that contains multiple values of different alphabets at the sam...
Definition: alphabet_tuple_base.hpp:120
detail.hpp
Provides implementation detail for seqan3::alphabet_variant and seqan3::alphabet_tuple_base.
seqan3::alphabet_tuple_base::operator>=
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:648
seqan3::alphabet_base
A CRTP-base that makes defining a custom alphabet easier.
Definition: alphabet_base.hpp:51
seqan3::to_rank
constexpr auto to_rank
Return the rank representation of a (semi-)alphabet object.
Definition: concept.hpp:142
debug_stream_type.hpp
Provides seqan3::debug_stream and related types.
seqan3::alphabet_tuple_base::operator<=
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:600
seqan3::alphabet_tuple_base::alphabet_tuple_base
constexpr alphabet_tuple_base(component_type const alph) noexcept
Construction via a value of one of the components.
Definition: alphabet_tuple_base.hpp:336
concepts
The Concepts library.
same_as
The concept std::same_as<T, U> is satisfied if and only if T and U denote the same type.
seqan3::alphabet_tuple_base::operator>=
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:638
seqan3::alphabet_tuple_base::operator<
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:581
seqan3::alphabet_tuple_base::operator<
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:591
concept.hpp
Quality alphabet concept.
tuple_utility.hpp
Provides utility functions for tuple like interfaces.
std::enable_if_t
alphabet_proxy.hpp
Provides seqan3::alphabet_proxy.
core_language.hpp
Provides concepts for core language types and relations that don't have concepts in C++20 (yet).
seqan3::alphabet_tuple_base::get
constexpr friend type get(alphabet_tuple_base const &l) noexcept
Tuple-like access to the contained components.
Definition: alphabet_tuple_base.hpp:507
seqan3::alphabet_tuple_base::operator==
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:553
transformation_trait_or.hpp
Provides seqan3::detail::transformation_trait_or.
std::array
seqan3
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:36
assignable_from
The concept std::assignable_from<LHS, RHS> specifies that an expression of the type and value categor...
seqan3::alphabet_tuple_base::operator>
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:629
seqan3::alphabet_tuple_base::operator!=
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:572
seqan3::alphabet_tuple_base::operator<=
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:610
convertible_to
The concept std::convertible_to<From, To> specifies that an expression of the type and value category...
pack.hpp
Provides unary type traits on a set of types, usually provided as template argument pack.
seqan3::pack_traits::size
constexpr size_t size
The size of a type pack.
Definition: traits.hpp:116
regular
Subsumes std::semiregular and std::equality_comparable.
derived_from
The concept std::derived_from<Derived, Base> is satisfied if and only if Base is a class type that is...
seqan3::alphabet_tuple_base::operator==
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:543
int_types.hpp
Provides metaprogramming utilities for integer types.
seqan3::alphabet_tuple_base::operator>
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:619
std
SeqAn specific customisations in the standard namespace.
cassert
seqan3::list_traits::contains
constexpr bool contains
Whether a type occurs in a type list or not.
Definition: traits.hpp:495
seqan3::list_traits::concat
decltype(detail::concat(lists_t{}...)) concat
Join two seqan3::type_list s into one.
Definition: traits.hpp:592
std::size_t
std::conditional_t
std::tuple_element< i, tuple_t >::type
meta::at_c< typename tuple_t::seqan3_required_types, i > type
Element type.
Definition: alphabet_tuple_base.hpp:751
seqan3::pack_traits::at
typename decltype(detail::at< idx, pack_t... >())::type at
Return the type at given index from the type pack.
Definition: traits.hpp:221
seqan3::alphabet_size
constexpr auto alphabet_size
A type trait that holds the size of a (semi-)alphabet.
Definition: concept.hpp:706
seqan3::get
constexpr const auto & 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:576
concept.hpp
Core alphabet concept and free function/type trait wrappers.
seqan3::pack_traits::count
constexpr ptrdiff_t count
Count the occurrences of a type in a pack.
Definition: traits.hpp:134
seqan3::alphabet_proxy
A CRTP-base that eases the definition of proxy types returned in place of regular alphabets.
Definition: alphabet_proxy.hpp:59