29namespace bio::alphabet::detail
33template <
typename tuple_derived_t,
typename rhs_t,
typename... component_types>
34concept tuple_concept_guard = !meta::one_of<rhs_t, tuple_derived_t, component_types...> &&
35 !meta::list_traits::contains<tuple_derived_t, recursive_required_types_t<rhs_t>>;
89template <
typename derived_type,
typename... component_types>
90 requires((detail::writable_constexpr_semialphabet<component_types> && ...) &&
91 (std::regular<component_types> && ...))
93 public base<derived_type,
94 (1 * ... * size<component_types>),
100 (1 * ... * size<component_types>),
107 template <
typename type>
108 static constexpr bool is_component = meta::list_traits::contains<type, component_list>;
111 template <
typename type>
112 static constexpr bool is_unique_component = (meta::list_traits::count<type, component_list> == 1);
115 template <
typename alphabet_type,
size_t index>
116 class component_proxy;
128 using base_t::base_t;
140 using base_t::alphabet_size;
141 using base_t::assign_rank;
142 using base_t::to_rank;
154 static constexpr bool biocpp_alphabet_tuple_like =
true;
179 template <
typename component_type>
180 requires((!std::is_base_of_v<tuple_base, component_type>) && is_unique_component<component_type>)
183 get<component_type>(*
this) = alph;
202 template <
typename indirect_component_type>
203 requires(detail::tuple_concept_guard<derived_type, indirect_component_type, component_types...> &&
204 (std::is_convertible_v<indirect_component_type, component_types> || ...))
207 using component_predicate = detail::implicitly_convertible_from<indirect_component_type>;
208 constexpr auto component_position =
209 meta::list_traits::find_if<component_predicate::template invoke, component_list>;
211 component_type tmp(alph);
212 get<component_type>(*
this) = tmp;
216 template <
typename indirect_component_type>
217 requires(detail::tuple_concept_guard<derived_type, indirect_component_type, component_types...> &&
218 (!(std::is_convertible_v<indirect_component_type, component_types> || ...)) &&
219 (std::is_constructible_v<component_types, indirect_component_type> || ...))
220 constexpr explicit tuple_base(indirect_component_type
const alph) noexcept : tuple_base{}
222 using component_predicate = detail::constructible_from<indirect_component_type>;
223 constexpr auto component_position =
224 meta::list_traits::find_if<component_predicate::template invoke, component_list>;
225 using component_type = meta::list_traits::at<component_position, component_list>;
226 component_type tmp(alph);
227 get<component_type>(*
this) = tmp;
242 template <
typename component_type>
243 requires((!std::derived_from<component_type, tuple_base>) && is_unique_component<component_type>)
244 constexpr derived_type &
operator=(component_type
const alph)
noexcept
246 get<component_type>(*
this) = alph;
247 return static_cast<derived_type &
>(*this);
262 template <
typename indirect_component_type>
263 requires((!std::derived_from<indirect_component_type, tuple_base>) &&
264 (!is_unique_component<indirect_component_type>) &&
265 (std::assignable_from<component_types, indirect_component_type> || ...))
266 constexpr derived_type &
operator=(indirect_component_type
const alph)
noexcept
268 using component_predicate = detail::assignable_from<indirect_component_type>;
269 constexpr auto component_position =
270 meta::list_traits::find_if<component_predicate::template invoke, component_list>;
272 get<component_type>(*
this) = alph;
273 return static_cast<derived_type &
>(*this);
277 template <
typename indirect_component_type>
278 requires((!std::derived_from<indirect_component_type, tuple_base>) &&
279 (!is_unique_component<indirect_component_type>) &&
280 (!(std::assignable_from<component_types, indirect_component_type> || ...)) &&
281 (std::convertible_to<indirect_component_type, component_types> || ...))
282 constexpr derived_type &
operator=(indirect_component_type
const alph)
noexcept
284 using component_predicate = detail::implicitly_convertible_from<indirect_component_type>;
285 constexpr auto component_position =
286 meta::list_traits::find_if<component_predicate::template invoke, component_list>;
288 component_type tmp(alph);
289 get<component_type>(*
this) = tmp;
290 return static_cast<derived_type &
>(*this);
293 template <
typename indirect_component_type>
294 requires((!std::derived_from<indirect_component_type, tuple_base>) &&
295 (!is_unique_component<indirect_component_type>) &&
296 (!(std::assignable_from<component_types, indirect_component_type> || ...)) &&
297 (!(std::convertible_to<indirect_component_type, component_types> || ...)) &&
298 (std::constructible_from<component_types, indirect_component_type> || ...))
299 constexpr derived_type &
operator=(indirect_component_type
const alph)
noexcept
301 using component_predicate = detail::constructible_from<indirect_component_type>;
302 constexpr auto component_position =
303 meta::list_traits::find_if<component_predicate::template invoke, component_list>;
305 component_type tmp(alph);
306 get<component_type>(*
this) = tmp;
307 return static_cast<derived_type &
>(*this);
321 template <
size_t index>
324 static_assert(index <
sizeof...(component_types),
"Index out of range.");
331 return component_proxy<t, index>{l};
339 template <
typename type>
341 requires is_unique_component<type>
343 return get<meta::list_traits::find<type, component_list>>(l);
351 template <
size_t index>
354 static_assert(index <
sizeof...(component_types),
"Index out of range.");
366 template <
typename type>
368 requires is_unique_component<type>
370 return get<meta::list_traits::find<type, component_list>>(l);
376 template <
typename type>
377 constexpr operator type() const noexcept
378 requires is_unique_component<type>
380 return get<type>(*
this);
400 template <std::same_as<derived_type> derived_type_t,
typename indirect_component_type>
401 requires(detail::tuple_concept_guard<derived_type, indirect_component_type, component_types...> &&
403 friend constexpr bool operator==(derived_type_t
const lhs, indirect_component_type
const rhs)
noexcept
405 using component_predicate = detail::weakly_equality_comparable_with_<indirect_component_type>;
406 constexpr auto component_position =
407 meta::list_traits::find_if<component_predicate::template invoke, component_list>;
409 return get<component_type>(lhs) == rhs;
413 template <std::same_as<derived_type> derived_type_t,
typename indirect_component_type>
414 requires(detail::tuple_concept_guard<derived_type, indirect_component_type, component_types...> &&
416 friend constexpr auto operator<=>(derived_type_t
const lhs, indirect_component_type
const rhs)
noexcept
418 using component_predicate = detail::weakly_ordered_with_<indirect_component_type>;
419 constexpr auto component_position =
420 meta::list_traits::find_if<component_predicate::template invoke, component_list>;
422 return get<component_type>(lhs) <=> rhs;
428 template <
size_t index>
429 constexpr rank_type to_component_rank() const noexcept
431 if constexpr (alphabet_size < 1024)
433 return rank_to_component_rank[index][
to_rank()];
437 return (
to_rank() / cummulative_alph_sizes[index]) %
443 template <
size_t index>
444 constexpr void assign_component_rank(ptrdiff_t
const r)
noexcept
446 assign_rank(
static_cast<ptrdiff_t
>(
to_rank()) + ((r -
static_cast<ptrdiff_t
>(to_component_rank<index>())) *
447 static_cast<ptrdiff_t
>(cummulative_alph_sizes[index])));
451 static constexpr std::array<rank_type, component_list::size()> cummulative_alph_sizes = []()
constexpr
454 std::array<rank_type, component_list::size() + 1> ret{};
457 using reverse_list_t =
decltype(meta::list_traits::detail::reverse(component_list{}));
458 bio::meta::detail::for_each<reverse_list_t>(
459 [&](
auto alphabet_type_identity)
constexpr
461 using alphabet_t =
typename decltype(alphabet_type_identity)::type;
462 ret[count] =
static_cast<rank_type
>(bio::alphabet::size<alphabet_t> * ret[count - 1]);
469 std::array<rank_type, component_list::size()> ret2{};
470 for (
size_t i = 0; i < component_list::size(); ++i)
471 ret2[i] = ret[component_list::size() - i - 1];
478 static constexpr rank_type rank_sum_helper(component_types... components,
486 alphabet_size<1024 ? alphabet_size : 0>,
487 meta::list_traits::size<component_list>>
488 rank_to_component_rank = []()
constexpr
491 alphabet_size<1024 ? alphabet_size : 0>,
492 meta::list_traits::size<component_list>>
495 if constexpr (alphabet_size < 1024)
499 for (
size_t i = 0; i < meta::list_traits::size<component_list>; ++i)
500 for (
size_t j = 0; j < static_cast<size_t>(alphabet_size); ++j)
501 ret[i][j] = (j / cummulative_alph_sizes[i]) % alph_sizes[i];
513template <
typename derived_type,
typename... component_types>
514 requires((detail::writable_constexpr_semialphabet<component_types> && ...) &&
515 (std::regular<component_types> && ...))
516template <typename alphabet_type, size_t index>
517class tuple_base<derived_type, component_types...>::component_proxy :
518 public proxy_base<component_proxy<alphabet_type, index>, alphabet_type>
522 using base_t = proxy_base<component_proxy<alphabet_type, index>, alphabet_type>;
531 using base_t::operator=;
537 component_proxy() =
delete;
538 constexpr component_proxy(component_proxy
const &)
noexcept =
default;
539 constexpr component_proxy(component_proxy &&) noexcept = default;
540 ~component_proxy() noexcept = default;
543 constexpr component_proxy(tuple_base & p) : parent{&p} {}
546 constexpr component_proxy & operator=(component_proxy
const & rhs)
548 return assign_rank(rhs.to_rank());
553 constexpr component_proxy
const & operator=(component_proxy
const & rhs)
const
555 return assign_rank(rhs.to_rank());
560 constexpr alphabet::rank_t<alphabet_type>
to_rank() const noexcept {
return parent->to_component_rank<index>(); }
563 constexpr component_proxy & assign_rank(alphabet::rank_t<alphabet_type>
const r)
noexcept
565 parent->assign_component_rank<index>(r);
570 constexpr component_proxy
const & assign_rank(alphabet::rank_t<alphabet_type>
const r)
const noexcept
572 parent->assign_component_rank<index>(r);
585 friend constexpr bool operator==(derived_type
const lhs, component_proxy
const rhs)
noexcept
587 return get<index>(lhs) ==
static_cast<alphabet_type
>(rhs);
591 friend constexpr auto operator<=>(derived_type
const lhs, component_proxy
const rhs)
noexcept
593 return get<index>(lhs) <=>
static_cast<alphabet_type
>(rhs);
609template <std::
size_t i, bio::alphabet::detail::alphabet_tuple_like tuple_t>
610struct tuple_element<i, tuple_t>
622template <bio::alphabet::detail::alphabet_tuple_like tuple_t>
623struct tuple_size<tuple_t> :
624 public std::integral_constant<size_t, bio::meta::list_traits::size<typename tuple_t::biocpp_required_types>>
Provides implementation detail for bio::alphabet::variant and bio::alphabet::tuple_base.
Core alphabet concept and free function/type trait wrappers.
Provides bio::alphabet::base.
A CRTP-base that makes defining a custom alphabet easier.
Definition: base.hpp:55
The CRTP base for a combined alphabet that contains multiple values of different alphabets at the sam...
Definition: tuple_base.hpp:96
constexpr tuple_base(indirect_component_type const alph) noexcept
Construction via a value of a subtype that is assignable to one of the components.
Definition: tuple_base.hpp:205
friend constexpr auto get(tuple_base &l) noexcept
Tuple-like access to the contained components.
Definition: tuple_base.hpp:322
constexpr tuple_base(component_type const alph) noexcept
Construction via a value of one of the components.
Definition: tuple_base.hpp:181
friend constexpr auto get(tuple_base const &l) noexcept
Tuple-like access to the contained components.
Definition: tuple_base.hpp:352
constexpr tuple_base(component_types... components) noexcept
Construction from initialiser-list.
Definition: tuple_base.hpp:163
friend constexpr type get(tuple_base const &l) noexcept
Tuple-like access to the contained components.
Definition: tuple_base.hpp:367
friend constexpr auto get(tuple_base &l) noexcept
Tuple-like access to the contained components.
Definition: tuple_base.hpp:340
constexpr derived_type & operator=(component_type const alph) noexcept
Assignment via a value of one of the components.
Definition: tuple_base.hpp:244
Provides algorithms for meta programming, parameter packs and bio::meta::type_list.
constexpr auto size
A type trait that holds the size of a (semi-)alphabet.
Definition: concept.hpp:517
constexpr auto to_rank
Return the rank representation of a (semi-)alphabet object.
Definition: concept.hpp:70
constexpr auto assign_rank_to
Assign a rank to an alphabet object.
Definition: concept.hpp:138
typename transformation_trait_or< type_t, default_t >::type transformation_trait_or_t
Helper type of bio::meta::transformation_trait_or (transformation_trait shortcut).
Definition: transformation_trait_or.hpp:53
The alphabet module's namespace.
Definition: aa10li.hpp:23
Provides bio::alphabet::proxy_base.
bio::meta::list_traits::at< i, typename tuple_t::biocpp_required_types > type
Element type.
Definition: tuple_base.hpp:613
Provides various traits to inspect templates.
Provides traits for meta::type_list.
Provides bio::meta::type_list.