SeqAn3  3.0.2
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 
28 #include <seqan3/std/concepts>
29 
30 namespace seqan3::detail
31 {
32 
34 template <typename tuple_derived_t, typename rhs_t, typename ... component_types>
35 inline constexpr bool tuple_general_guard =
36  (!std::same_as<rhs_t, tuple_derived_t>) &&
37  (!std::same_as<rhs_t, alphabet_tuple_base<component_types...>>) &&
38  (!std::is_base_of_v<tuple_derived_t, rhs_t>) &&
39  (!(std::same_as<rhs_t, component_types> || ...)) &&
40  (!list_traits::contains<tuple_derived_t, recursive_required_types_t<rhs_t>>);
41 
42 
44 template <typename lhs_t, typename tuple_derived_t, typename rhs_t, typename ... component_types>
45 inline constexpr bool tuple_eq_guard =
46  (instantiate_if_v<lazy<weakly_equality_comparable_with_trait, rhs_t, component_types>,
47  std::same_as<lhs_t, tuple_derived_t> &&
48  tuple_general_guard<tuple_derived_t, rhs_t, component_types...>
49  > || ...);
50 
52 template <typename lhs_t, typename tuple_derived_t, typename rhs_t, typename ... component_types>
53 inline constexpr bool tuple_order_guard =
54  (instantiate_if_v<lazy<weakly_ordered_with_trait, rhs_t, component_types>,
55  std::same_as<lhs_t, tuple_derived_t> &&
56  tuple_general_guard<lhs_t, tuple_derived_t, rhs_t, component_types...>
57  > || ...);
58 
59 } // namespace seqan3::detail
60 
61 namespace seqan3
62 {
63 
64 // forwards
66 template <typename t>
67 decltype(auto) get();
68 
69 template <size_t i>
70 decltype(auto) get();
72 
110 template <typename derived_type,
111  typename ...component_types>
113  requires (detail::writable_constexpr_semialphabet<component_types> && ...) &&
114  (std::regular<component_types> && ...)
117  public alphabet_base<derived_type,
118  (1 * ... * alphabet_size<component_types>),
119  void> // no char type, because this is only semi_alphabet
120 {
121 private:
123  using base_t = alphabet_base<derived_type,
124  (1 * ... * alphabet_size<component_types>),
125  void>; // no char type, because this is only semi_alphabet
126 
128  using component_list = meta::list<component_types...>;
129 
131  template <typename type>
132  static constexpr bool is_component =
133  meta::in<component_list, type>::value;
134 
136  template <typename type>
137  static constexpr bool is_unique_component =
138  is_component<type> &&
139  (meta::find_index<component_list, type>::value == meta::reverse_find_index<component_list, type>::value);
140 
145  template <typename alphabet_type, size_t index>
146  class component_proxy : public alphabet_proxy<component_proxy<alphabet_type, index>, alphabet_type>
147  {
148  private:
152  friend base_t;
153 
155  alphabet_tuple_base *parent;
156 
158  constexpr void on_update() noexcept
159  {
160  parent->assign_component_rank<index>(to_rank());
161  }
162 
163  public:
164  //Import from base type:
165  using base_t::operator=;
166 
170  component_proxy() = delete;
172  constexpr component_proxy(component_proxy const &) = default;
173  constexpr component_proxy(component_proxy &&) = default;
174  constexpr component_proxy & operator=(component_proxy const &) = default;
175  constexpr component_proxy & operator=(component_proxy &&) = default;
176  ~component_proxy() = default;
177 
179  constexpr component_proxy(alphabet_type const l, alphabet_tuple_base & p) :
180  base_t{l}, parent{&p}
181  {}
182 
183  // Does not inherit the base's constructor for alphabet_type so as not to cause ambiguity
185 
195  friend constexpr bool operator==(derived_type const lhs, component_proxy const rhs) noexcept
196  {
197  return get<index>(lhs) == static_cast<alphabet_type>(rhs);
198  }
199 
201  friend constexpr bool operator==(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
202  {
203  return rhs == lhs;
204  }
205 
207  friend constexpr bool operator!=(derived_type const lhs, component_proxy const rhs) noexcept
208  {
209  return get<index>(lhs) != static_cast<alphabet_type>(rhs);
210  }
211 
213  friend constexpr bool operator!=(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
214  {
215  return rhs != lhs;
216  }
217 
219  friend constexpr bool operator<(derived_type const lhs, component_proxy const rhs) noexcept
220  {
221  return get<index>(lhs) < static_cast<alphabet_type>(rhs);
222  }
223 
225  friend constexpr bool operator<(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
226  {
227  return rhs > lhs;
228  }
229 
231  friend constexpr bool operator<=(derived_type const lhs, component_proxy const rhs) noexcept
232  {
233  return get<index>(lhs) <= static_cast<alphabet_type>(rhs);
234  }
235 
237  friend constexpr bool operator<=(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
238  {
239  return rhs >= lhs;
240  }
241 
243  friend constexpr bool operator>(derived_type const lhs, component_proxy const rhs) noexcept
244  {
245  return get<index>(lhs) > static_cast<alphabet_type>(rhs);
246  }
247 
249  friend constexpr bool operator>(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
250  {
251  return rhs < lhs;
252  }
253 
255  friend constexpr bool operator>=(derived_type const lhs, component_proxy const rhs) noexcept
256  {
257  return get<index>(lhs) >= static_cast<alphabet_type>(rhs);
258  }
259 
261  friend constexpr bool operator>=(component_proxy<alphabet_type, index> const lhs, derived_type const rhs) noexcept
262  {
263  return rhs <= lhs;
264  }
265  };
266 
270  constexpr alphabet_tuple_base() noexcept : base_t{} {}
271  constexpr alphabet_tuple_base(alphabet_tuple_base const &) = default;
272  constexpr alphabet_tuple_base(alphabet_tuple_base &&) = default;
273  constexpr alphabet_tuple_base & operator=(alphabet_tuple_base const &) = default;
274  constexpr alphabet_tuple_base & operator=(alphabet_tuple_base &&) = default;
275  ~alphabet_tuple_base() = default;
276 
277  using base_t::base_t;
279 
282  friend derived_type;
283 
284  // Import from base:
285  using typename base_t::rank_type;
286 
287 public:
288  // Import from base:
289  using base_t::alphabet_size;
290  using base_t::to_rank;
291  using base_t::assign_rank;
292 
295  using seqan3_required_types = component_list;
298  using seqan3_recursive_required_types =
299  meta::concat<component_list,
300  detail::transformation_trait_or_t<detail::recursive_required_types<component_types>,
301  meta::list<>>...>;
304  static constexpr bool seqan3_alphabet_tuple_base_specialisation = true;
305 
313  constexpr alphabet_tuple_base(component_types ... components) noexcept
315  {
316  assign_rank(rank_sum_helper(components..., std::make_index_sequence<sizeof...(component_types)>{}));
317  }
318 
327  template <typename component_type>
329  requires (!std::is_base_of_v<alphabet_tuple_base, component_type>) &&
330  is_unique_component<component_type>
332  constexpr explicit alphabet_tuple_base(component_type const alph) noexcept : alphabet_tuple_base{}
333  {
334  get<component_type>(*this) = alph;
335  }
336 
350  template <typename indirect_component_type>
352  requires ((detail::instantiate_if_v<
353  detail::lazy<std::is_convertible, indirect_component_type, component_types>,
354  detail::tuple_general_guard<derived_type, indirect_component_type, component_types...>> || ...))
356  constexpr explicit alphabet_tuple_base(indirect_component_type const alph) noexcept : alphabet_tuple_base{}
357  {
358  using component_type = meta::front<meta::find_if<component_list, detail::implicitly_convertible_from<indirect_component_type>>>;
359  component_type tmp(alph); // delegate construction
360  get<component_type>(*this) = tmp;
361  }
362 
364  template <typename indirect_component_type>
365  requires ((!(detail::instantiate_if_v<
366  detail::lazy<std::is_convertible, indirect_component_type, component_types>,
367  detail::tuple_general_guard<derived_type, indirect_component_type, component_types...>> || ...)) &&
368  (detail::instantiate_if_v<
369  detail::lazy<std::is_constructible, component_types, indirect_component_type>,
370  detail::tuple_general_guard<derived_type, indirect_component_type, component_types...>> || ...))
371  constexpr explicit alphabet_tuple_base(indirect_component_type const alph) noexcept : alphabet_tuple_base{}
372  {
373  using component_type = meta::front<meta::find_if<component_list, detail::constructible_from<indirect_component_type>>>;
374  component_type tmp(alph); // delegate construction
375  get<component_type>(*this) = tmp;
376  }
378 
387  template <typename component_type>
389  requires (!std::derived_from<component_type, alphabet_tuple_base>) &&
390  is_unique_component<component_type>
392  constexpr derived_type & operator=(component_type const alph) noexcept
393  {
394  get<component_type>(*this) = alph;
395  return static_cast<derived_type &>(*this);
396  }
397 
407  template <typename indirect_component_type>
409  requires ((!std::derived_from<indirect_component_type, alphabet_tuple_base>) &&
410  (!is_unique_component<indirect_component_type>) &&
411  (std::assignable_from<component_types, indirect_component_type> || ...))
413  constexpr derived_type & operator=(indirect_component_type const alph) noexcept
414  {
415  using component_type = meta::front<meta::find_if<component_list, detail::assignable_from<indirect_component_type>>>;
416  get<component_type>(*this) = alph; // delegate assignment
417  return static_cast<derived_type &>(*this);
418  }
420  // If not assignable but implicit convertible, convert first and assign afterwards
421  template <typename indirect_component_type>
422  requires ((!std::derived_from<indirect_component_type, alphabet_tuple_base>) &&
423  (!is_unique_component<indirect_component_type>) &&
424  (!(std::assignable_from<component_types, indirect_component_type> || ...)) &&
425  (std::convertible_to<indirect_component_type, component_types> || ...))
426  constexpr derived_type & operator=(indirect_component_type const alph) noexcept
427  {
428  using component_type = meta::front<meta::find_if<component_list, detail::implicitly_convertible_from<indirect_component_type>>>;
429  component_type tmp(alph);
430  get<component_type>(*this) = tmp;
431  return static_cast<derived_type &>(*this);
432  }
433 
434  template <typename indirect_component_type>
435  requires ((!std::derived_from<indirect_component_type, alphabet_tuple_base>) &&
436  (!is_unique_component<indirect_component_type>) &&
437  (!(std::assignable_from<component_types, indirect_component_type> || ...)) &&
438  (!(std::convertible_to<indirect_component_type, component_types> || ...)) &&
439  (std::constructible_from<component_types, indirect_component_type> || ...))
440  constexpr derived_type & operator=(indirect_component_type const alph) noexcept
441  {
442  using component_type = meta::front<meta::find_if<component_list, detail::constructible_from<indirect_component_type>>>;
443  component_type tmp(alph); // delegate construction
444  get<component_type>(*this) = tmp;
445  return static_cast<derived_type &>(*this);
446  }
449 
458  template <size_t index>
459  friend constexpr auto get(alphabet_tuple_base & l) noexcept
460  {
461  static_assert(index < sizeof...(component_types), "Index out of range.");
462 
463  using t = meta::at_c<component_list, index>;
464  t val{};
465 
466  seqan3::assign_rank_to(l.to_component_rank<index>(), val);
467 
468  return component_proxy<t, index>{val, l};
469  }
470 
475  template <typename type>
476  friend constexpr auto get(alphabet_tuple_base & l) noexcept
478  requires is_unique_component<type>
480  {
481  return get<meta::find_index<component_list, type>::value>(l);
482  }
483 
488  template <size_t index>
489  friend constexpr auto get(alphabet_tuple_base const & l) noexcept
490  {
491  static_assert(index < sizeof...(component_types), "Index out of range.");
492 
493  using t = meta::at_c<component_list, index>;
494 
495  return seqan3::assign_rank_to(l.to_component_rank<index>(), t{});
496  }
497 
502  template <typename type>
503  friend constexpr type get(alphabet_tuple_base const & l) noexcept
505  requires is_unique_component<type>
507  {
508  return get<meta::find_index<component_list, type>::value>(l);
509  }
510 
513  template <typename type>
514  constexpr operator type() const noexcept
516  requires is_unique_component<type>
518  {
519  return get<type>(*this);
520  }
522 
538  template <typename derived_type_t, typename indirect_component_type>
539  friend constexpr auto operator==(derived_type_t const lhs, indirect_component_type const rhs) noexcept
540  -> std::enable_if_t<detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
541  bool>
542  {
543  using component_type = meta::front<meta::find_if<component_list, detail::weakly_equality_comparable_with_<indirect_component_type>>>;
544  return get<component_type>(lhs) == rhs;
545  }
546 
548  template <typename derived_type_t, typename indirect_component_type>
549  friend constexpr auto operator==(indirect_component_type const lhs, derived_type_t const rhs) noexcept
550  -> std::enable_if_t<detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
551  bool>
552  {
553  return rhs == lhs;
554  }
555 
557  template <typename derived_type_t, typename indirect_component_type>
558  friend constexpr auto operator!=(derived_type_t const lhs, indirect_component_type const rhs) noexcept
559  -> std::enable_if_t<detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
560  bool>
561  {
562  using component_type = meta::front<meta::find_if<component_list, detail::weakly_equality_comparable_with_<indirect_component_type>>>;
563  return get<component_type>(lhs) != rhs;
564  }
565 
567  template <typename derived_type_t, typename indirect_component_type>
568  friend constexpr auto operator!=(indirect_component_type const lhs, derived_type_t const rhs) noexcept
569  -> std::enable_if_t<detail::tuple_eq_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
570  bool>
571  {
572  return rhs != lhs;
573  }
574 
576  template <typename derived_type_t, typename indirect_component_type>
577  friend constexpr auto operator<(derived_type_t const lhs, indirect_component_type const rhs) noexcept
578  -> std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
579  bool>
580  {
581  using component_type = meta::front<meta::find_if<component_list, detail::weakly_ordered_with_<indirect_component_type>>>;
582  return get<component_type>(lhs) < rhs;
583  }
584 
586  template <typename derived_type_t, typename indirect_component_type>
587  friend constexpr auto operator<(indirect_component_type const lhs, derived_type_t const rhs) noexcept
588  -> std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
589  bool>
590  {
591  return rhs > lhs;
592  }
593 
595  template <typename derived_type_t, typename indirect_component_type>
596  friend constexpr auto operator<=(derived_type_t const lhs, indirect_component_type const rhs) noexcept
597  -> std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
598  bool>
599  {
600  using component_type = meta::front<meta::find_if<component_list, detail::weakly_ordered_with_<indirect_component_type>>>;
601  return get<component_type>(lhs) <= rhs;
602  }
603 
605  template <typename derived_type_t, typename indirect_component_type>
606  friend constexpr auto operator<=(indirect_component_type const lhs, derived_type_t const rhs) noexcept
607  -> std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
608  bool>
609  {
610  return rhs >= lhs;
611  }
612 
614  template <typename derived_type_t, typename indirect_component_type>
615  friend constexpr auto operator>(derived_type_t const lhs, indirect_component_type const rhs) noexcept
616  -> std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
617  bool>
618  {
619  using component_type = meta::front<meta::find_if<component_list, detail::weakly_ordered_with_<indirect_component_type>>>;
620  return get<component_type>(lhs) > rhs;
621  }
622 
624  template <typename derived_type_t, typename indirect_component_type>
625  friend constexpr auto operator>(indirect_component_type const lhs, derived_type_t const rhs) noexcept
626  -> std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
627  bool>
628  {
629  return rhs < lhs;
630  }
631 
633  template <typename derived_type_t, typename indirect_component_type>
634  friend constexpr auto operator>=(derived_type_t const lhs, indirect_component_type const rhs) noexcept
635  -> std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
636  bool>
637  {
638  using component_type = meta::front<meta::find_if<component_list, detail::weakly_ordered_with_<indirect_component_type>>>;
639  return get<component_type>(lhs) >= rhs;
640  }
641 
643  template <typename derived_type_t, typename indirect_component_type>
644  friend constexpr auto operator>=(indirect_component_type const lhs, derived_type_t const rhs) noexcept
645  -> std::enable_if_t<detail::tuple_order_guard<derived_type_t, derived_type, indirect_component_type, component_types...>,
646  bool>
647  {
648  return rhs <= lhs;
649  }
651 
652 private:
654  template <size_t index>
655  constexpr rank_type to_component_rank() const noexcept
656  {
657  if constexpr (alphabet_size < 1024) // computation is cached for small alphabets
658  {
659  return rank_to_component_rank[index][to_rank()];
660  }
661  else
662  {
663  return (to_rank() / cummulative_alph_sizes[index]) %
664  seqan3::alphabet_size<pack_traits::at<index, component_types...>>;
665  }
666  }
667 
669  template <size_t index>
670  constexpr void assign_component_rank(ptrdiff_t const r) noexcept
671  {
672  assign_rank(static_cast<ptrdiff_t>(to_rank()) +
673  ((r - static_cast<ptrdiff_t>(to_component_rank<index>())) *
674  static_cast<ptrdiff_t>(cummulative_alph_sizes[index])));
675  }
676 
678  static constexpr std::array<rank_type, component_list::size()> cummulative_alph_sizes
679  {
680  [] () constexpr
681  {
682  // create array (1, |sigma1|, |sigma1|*|sigma2|, ... , |sigma1|*...*|sigmaN|)
683  std::array<rank_type, component_list::size() + 1> ret{};
684  ret[0] = 1;
685  size_t count = 1;
686  meta::for_each(meta::reverse<component_list>{}, [&] (auto alph) constexpr
687  {
688  ret[count] = static_cast<rank_type>(seqan3::alphabet_size<decltype(alph)> * ret[count - 1]);
689  ++count;
690  });
691 
692  // reverse and strip one: (|sigma1|*...*|sigmaN-1|, ... |sigma1|*|sigma2|, |sigma1|, 1)
693  // reverse order guarantees that the first alphabet is the most significant rank contributer
694  // resulting in element-wise alphabetical ordering on comparison
695  std::array<rank_type, component_list::size()> ret2{};
696  for (size_t i = 0; i < component_list::size(); ++i)
697  ret2[i] = ret[component_list::size() - i - 1];
698 
699  return ret2;
700  }()
701  };
702 
704  template <std::size_t ...idx>
705  static constexpr rank_type rank_sum_helper(component_types ... components, std::index_sequence<idx...> const &) noexcept
706  {
707  return ((seqan3::to_rank(components) * cummulative_alph_sizes[idx]) + ...);
708  }
709 
712  list_traits::size<component_list>> rank_to_component_rank
713  {
714  [] () constexpr
715  {
717  list_traits::size<component_list>> ret{};
718 
719  if constexpr (alphabet_size < 1024)
720  {
721  std::array<size_t, alphabet_size> alph_sizes{ seqan3::alphabet_size<component_types>... };
722 
723  for (size_t i = 0; i < list_traits::size<component_list>; ++i)
724  for (size_t j = 0; j < static_cast<size_t>(alphabet_size); ++j)
725  ret[i][j] = (j / cummulative_alph_sizes[i]) % alph_sizes[i];
726  }
727 
728  return ret;
729  }()
730  };
731 };
732 
733 } // namespace seqan3
734 
735 namespace std
736 {
737 
743 template <std::size_t i, seqan3::detail::alphabet_tuple_base_specialisation tuple_t>
744 struct tuple_element<i, tuple_t>
745 {
747  using type = meta::at_c<typename tuple_t::seqan3_required_types, i>;
748 };
749 
755 template <seqan3::detail::alphabet_tuple_base_specialisation tuple_t>
756 struct tuple_size<tuple_t> :
757  public std::integral_constant<size_t, seqan3::list_traits::size<typename tuple_t::seqan3_required_types>>
758 {};
759 
760 } // namespace std
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:392
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:459
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:239
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:489
tuple.hpp
Provides seqan3::tuple_like.
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:558
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
seqan3::get
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:627
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:644
seqan3::alphabet_base
A CRTP-base that makes defining a custom alphabet easier.
Definition: alphabet_base.hpp:54
seqan3::to_rank
constexpr auto to_rank
Return the rank representation of a (semi-)alphabet object.
Definition: concept.hpp:143
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:596
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:332
concepts
The Concepts library.
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:634
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:577
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:587
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:503
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:549
transformation_trait_or.hpp
Provides seqan3::detail::transformation_trait_or.
std::array
seqan3
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
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:625
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:568
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:606
seqan3::pack_traits::size
constexpr size_t size
The size of a type pack.
Definition: traits.hpp:116
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:539
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:615
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:747
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:707
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:65