SeqAn3  3.1.0-rc.1
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:
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;
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 
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  {
242  constexpr auto component_position = seqan3::list_traits::find_if<component_predicate::template invoke,
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,
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  {
325  constexpr auto component_position = seqan3::list_traits::find_if<component_predicate::template invoke,
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,
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  {
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  {
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 
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 
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:
681  friend base_t;
682 
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
Provides implementation detail for seqan3::alphabet_variant and seqan3::alphabet_tuple_base.
Core alphabet concept and free function/type trait wrappers.
Provides seqan3::alphabet_base.
Provides seqan3::alphabet_proxy.
A CRTP-base that makes defining a custom alphabet easier.
Definition: alphabet_base.hpp: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
A CRTP-base that eases the definition of proxy types returned in place of regular alphabets.
Definition: alphabet_proxy.hpp:66
Specialisation of seqan3::alphabet_proxy that updates the rank of the alphabet_tuple_base.
Definition: alphabet_tuple_base.hpp:676
constexpr void on_update() noexcept
The implementation updates the rank in the parent object.
Definition: alphabet_tuple_base.hpp:687
constexpr component_proxy(component_proxy const &)=default
Defaulted.
constexpr friend bool operator>=(derived_type const lhs, component_proxy const rhs) noexcept
Comparison against the alphabet tuple by casting self and tuple to the emulated type.
Definition: alphabet_tuple_base.hpp:784
constexpr friend bool operator<(derived_type const lhs, component_proxy const rhs) noexcept
Comparison against the alphabet tuple by casting self and tuple to the emulated type.
Definition: alphabet_tuple_base.hpp:748
constexpr friend bool operator>(derived_type const lhs, component_proxy const rhs) noexcept
Comparison against the alphabet tuple by casting self and tuple to the emulated type.
Definition: alphabet_tuple_base.hpp:772
constexpr component_proxy & operator=(component_proxy &&)=default
Defaulted.
constexpr friend bool operator==(derived_type const lhs, component_proxy const rhs) noexcept
Comparison against the alphabet tuple by casting self and tuple to the emulated type.
Definition: alphabet_tuple_base.hpp:724
alphabet_tuple_base * parent
Store a pointer to the parent object so we can update it.
Definition: alphabet_tuple_base.hpp:684
constexpr friend bool operator>=(component_proxy< alphabet_type, index > const lhs, derived_type const rhs) noexcept
Comparison against the alphabet tuple by casting self and tuple to the emulated type.
Definition: alphabet_tuple_base.hpp:790
constexpr friend bool operator<=(derived_type const lhs, component_proxy const rhs) noexcept
Comparison against the alphabet tuple by casting self and tuple to the emulated type.
Definition: alphabet_tuple_base.hpp:760
constexpr friend bool operator>(component_proxy< alphabet_type, index > const lhs, derived_type const rhs) noexcept
Comparison against the alphabet tuple by casting self and tuple to the emulated type.
Definition: alphabet_tuple_base.hpp:778
constexpr friend bool operator!=(derived_type const lhs, component_proxy const rhs) noexcept
Comparison against the alphabet tuple by casting self and tuple to the emulated type.
Definition: alphabet_tuple_base.hpp:736
constexpr component_proxy & operator=(component_proxy const &)=default
Defaulted.
constexpr friend bool operator<(component_proxy< alphabet_type, index > const lhs, derived_type const rhs) noexcept
Comparison against the alphabet tuple by casting self and tuple to the emulated type.
Definition: alphabet_tuple_base.hpp:754
constexpr friend bool operator!=(component_proxy< alphabet_type, index > const lhs, derived_type const rhs) noexcept
Comparison against the alphabet tuple by casting self and tuple to the emulated type.
Definition: alphabet_tuple_base.hpp:742
constexpr component_proxy(alphabet_type const l, alphabet_tuple_base &p)
Construct from an alphabet letter and reference to the parent object.
Definition: alphabet_tuple_base.hpp:708
friend base_t
Befriend the base type so it can call our seqan3::alphabet_tuple_base::component_proxy::on_update().
Definition: alphabet_tuple_base.hpp:681
constexpr friend bool operator==(component_proxy< alphabet_type, index > const lhs, derived_type const rhs) noexcept
Comparison against the alphabet tuple by casting self and tuple to the emulated type.
Definition: alphabet_tuple_base.hpp:730
constexpr friend bool operator<=(component_proxy< alphabet_type, index > const lhs, derived_type const rhs) noexcept
Comparison against the alphabet tuple by casting self and tuple to the emulated type.
Definition: alphabet_tuple_base.hpp:766
constexpr component_proxy(component_proxy &&)=default
Defaulted.
component_proxy()=delete
Deleted, because using this proxy without parent would be undefined behaviour.
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
~alphabet_tuple_base()=default
Defaulted.
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 rank_type to_component_rank() const noexcept
Return the rank of the i-th component.
Definition: alphabet_tuple_base.hpp:587
constexpr derived_type & operator=(component_type const alph) noexcept
Assignment via a value of one of the components.
Definition: alphabet_tuple_base.hpp:283
static constexpr rank_type rank_sum_helper(component_types ... components, std::index_sequence< idx... > const &) noexcept
For the given components, compute the combined rank.
Definition: alphabet_tuple_base.hpp:639
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 alphabet_tuple_base & operator=(alphabet_tuple_base const &)=default
Defaulted.
constexpr friend type get(alphabet_tuple_base const &l) noexcept
Tuple-like access to the contained components.
Definition: alphabet_tuple_base.hpp:413
static constexpr bool seqan3_alphabet_tuple_like
Make specialisations of this template identifiable in metapgrogramming contexts.
Definition: alphabet_tuple_base.hpp:183
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 alphabet_tuple_base(alphabet_tuple_base const &)=default
Defaulted.
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 alphabet_tuple_base(alphabet_tuple_base &&)=default
Defaulted.
static constexpr bool is_unique_component
Is set to true if the type is uniquely contained in the type list.
Definition: alphabet_tuple_base.hpp:140
constexpr alphabet_tuple_base() noexcept
Defaulted.
Definition: alphabet_tuple_base.hpp:149
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 alphabet_tuple_base & operator=(alphabet_tuple_base &&)=default
Defaulted.
seqan3::type_list< component_types... > component_list
A seqan3::type_list The types of each component in the composite.
Definition: alphabet_tuple_base.hpp:132
list_traits::concat< component_list, detail::transformation_trait_or_t< detail::recursive_required_types< component_types >, seqan3::type_list<> >... > seqan3_recursive_required_types
Export this type's components and possibly the components' components in a visible manner.
Definition: alphabet_tuple_base.hpp:180
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
static constexpr std::array< rank_type, component_list::size()> cummulative_alph_sizes
The cumulative alphabet size products are cached.
Definition: alphabet_tuple_base.hpp:611
constexpr friend auto get(alphabet_tuple_base const &l) noexcept
Tuple-like access to the contained components.
Definition: alphabet_tuple_base.hpp:397
static constexpr bool is_component
Is set to true if the type is contained in the type list.
Definition: alphabet_tuple_base.hpp:136
constexpr void assign_component_rank(ptrdiff_t const r) noexcept
Assign via the rank of i-th component (does not update other components' state).
Definition: alphabet_tuple_base.hpp:602
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
friend derived_type
Befriend the derived type so that it can instantiate.
Definition: alphabet_tuple_base.hpp:161
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 ptrdiff_t find_if
Get the index of the first type in a pack that satisfies the given predicate.
Definition: traits.hpp:210
typename transformation_trait_or< type_t, default_t >::type transformation_trait_or_t
Helper type of seqan3::detail::transformation_trait_or (transformation_trait shortcut).
Definition: transformation_trait_or.hpp:51
Provides metaprogramming utilities for integer types.
Subconcept definition for seqan3::tuple_like to test for std::tuple_size-interface.
T invoke(T... args)
The internal SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
constexpr bool tuple_general_guard
Prevents wrong instantiations of seqan3::alphabet_tuple_base's equality comparison operators.
Definition: alphabet_tuple_base.hpp:37
constexpr bool tuple_eq_guard
Prevents wrong instantiations of seqan3::alphabet_tuple_base's equality comparison operators.
Definition: alphabet_tuple_base.hpp:47
constexpr bool tuple_order_guard
Prevents wrong instantiations of seqan3::alphabet_tuple_base's ordered comparison operators.
Definition: alphabet_tuple_base.hpp:55
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.
'Callable' helper class that is invokable by meta::invoke. Returns an std::true_type if the type is a...
Definition: detail.hpp:160
'Callable' helper class that is invokable by meta::invoke. Returns an std::true_type if the T is impl...
Definition: detail.hpp:149
'Callable' helper class that is invokable by meta::invoke. Returns an std::true_type if the type is w...
Definition: detail.hpp:171
'Callable' helper class that is invokable by meta::invoke. Returns an std::true_type if the type is c...
Definition: detail.hpp:182
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 various traits for template packs.
Provides seqan3::tuple_like.