SeqAn3 3.4.0-rc.4
The Modern C++ library for sequence analysis.
Loading...
Searching...
No Matches
alphabet/concept.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2006-2025 Knut Reinert & Freie Universität Berlin
2// SPDX-FileCopyrightText: 2016-2025 Knut Reinert & MPI für molekulare Genetik
3// SPDX-License-Identifier: BSD-3-Clause
4
10#pragma once
11
12#include <type_traits>
13
20
21// ============================================================================
22// forwards
23// ============================================================================
24
25namespace seqan3::custom
26{
27
44template <typename t>
46{};
47
49template <typename t>
50struct alphabet<t const> : alphabet<t>
51{};
52
53template <typename t>
54struct alphabet<t &> : alphabet<t>
55{};
56
57template <typename t>
58struct alphabet<t const &> : alphabet<t>
59{};
61
62} // namespace seqan3::custom
63
64// ============================================================================
65// to_rank()
66// ============================================================================
67
68namespace seqan3::detail::adl_only
69{
70
72template <typename... args_t>
73void to_rank(args_t...) = delete;
74
77struct to_rank_cpo : public detail::customisation_point_object<to_rank_cpo, 2>
78{
82 using base_t::base_t;
83
88 template <typename alphabet_t>
89 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<2>, alphabet_t && alphabet)(
90 /*return*/ seqan3::custom::alphabet<alphabet_t>::to_rank(std::forward<alphabet_t>(alphabet)) /*;*/
91 );
92
97 template <typename alphabet_t>
98 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<1>, alphabet_t && alphabet)(
99 /*return*/ to_rank(std::forward<alphabet_t>(alphabet)) /*;*/
100 );
101
106 template <typename alphabet_t>
107 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<0>, alphabet_t && alphabet)(
108 /*return*/ std::forward<alphabet_t>(alphabet).to_rank() /*;*/
109 );
110};
111
112} // namespace seqan3::detail::adl_only
113
114namespace seqan3
115{
116
158inline constexpr auto to_rank = detail::adl_only::to_rank_cpo{};
160
166template <typename semi_alphabet_type>
167 requires requires {
168 { seqan3::to_rank(std::declval<semi_alphabet_type>()) };
169 }
170using alphabet_rank_t = decltype(seqan3::to_rank(std::declval<semi_alphabet_type>()));
171
172} // namespace seqan3
173
174// ============================================================================
175// assign_rank_to()
176// ============================================================================
178namespace seqan3::detail::adl_only
179{
180
182template <typename... args_t>
183void assign_rank_to(args_t...) = delete;
187struct assign_rank_to_cpo : public detail::customisation_point_object<assign_rank_to_cpo, 2>
188{
192 using base_t::base_t;
193
207 template <typename alphabet_t>
208 static constexpr auto
210 /*return*/ static_cast<alphabet_t>(seqan3::custom::alphabet<alphabet_t>::assign_rank_to(rank, alphabet)) /*;*/
211 );
212
226 template <typename alphabet_t>
227 static constexpr auto
229 /*return*/ static_cast<alphabet_t>(assign_rank_to(rank, alphabet)) /*;*/
230 );
231
242 template <typename alphabet_t> // least priority
243 static constexpr auto
245 /*return*/ static_cast<alphabet_t>(std::forward<alphabet_t>(alphabet).assign_rank(rank)) /*;*/
246 );
247};
248
249} // namespace seqan3::detail::adl_only
250
251namespace seqan3
252{
253
302} // namespace seqan3
303
304// ============================================================================
305// to_char()
306// ============================================================================
307
308namespace seqan3::detail::adl_only
309{
310
312template <typename... args_t>
313void to_char(args_t...) = delete;
314
317struct to_char_cpo : public detail::customisation_point_object<to_char_cpo, 2>
318{
322 using base_t::base_t;
323
328 template <typename alphabet_t>
329 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<2>, alphabet_t && alphabet)(
330 /*return*/ seqan3::custom::alphabet<alphabet_t>::to_char(std::forward<alphabet_t>(alphabet)) /*;*/
331 );
332
337 template <typename alphabet_t>
338 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<1>, alphabet_t && alphabet)(
339 /*return*/ to_char(std::forward<alphabet_t>(alphabet)) /*;*/
340 );
341
346 template <typename alphabet_t>
347 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<0>, alphabet_t && alphabet)(
348 /*return*/ std::forward<alphabet_t>(alphabet).to_char() /*;*/
349 );
350};
351
352} // namespace seqan3::detail::adl_only
353
354namespace seqan3
355{
356
399inline constexpr auto to_char = detail::adl_only::to_char_cpo{};
401
407template <typename alphabet_type>
408 requires requires (alphabet_type const a) {
409 { seqan3::to_char(a) };
411using alphabet_char_t = decltype(seqan3::to_char(std::declval<alphabet_type const>()));
412
413} // namespace seqan3
414
415// ============================================================================
416// assign_char_to()
417// ============================================================================
418
419namespace seqan3::detail::adl_only
420{
421
423template <typename... args_t>
424void assign_char_to(args_t...) = delete;
425
428struct assign_char_to_cpo : public detail::customisation_point_object<assign_char_to_cpo, 2>
429{
433 using base_t::base_t;
434
448 template <typename alphabet_t>
449 static constexpr auto
451 /*return*/ static_cast<alphabet_t>(seqan3::custom::alphabet<alphabet_t>::assign_char_to(chr, alphabet)) /*;*/
452 );
453
467 template <typename alphabet_t>
468 static constexpr auto
470 /*return*/ static_cast<alphabet_t>(assign_char_to(chr, alphabet)) /*;*/
471 );
472
483 template <typename alphabet_t> // least priority
484 static constexpr auto
486 /*return*/ static_cast<alphabet_t>(alphabet.assign_char(chr)) /*;*/
487 );
488};
489
490} // namespace seqan3::detail::adl_only
491
492namespace seqan3
493{
494
543} // namespace seqan3
544
545// ============================================================================
546// char_is_valid_for()
547// ============================================================================
549namespace seqan3::detail::adl_only
550{
551
553template <typename... args_t>
554void char_is_valid_for(args_t...) = delete;
555
560template <typename alphabet_t>
561struct char_is_valid_for_cpo : public detail::customisation_point_object<char_is_valid_for_cpo<alphabet_t>, 3>
562{
566 using base_t::base_t;
567
571 template <typename alphabet_type>
576
581 template <typename alphabet_type = alphabet_t>
584 );
585
596 template <typename alphabet_type = alphabet_t>
598 /*return*/ char_is_valid_for(chr, alphabet_or_type_identity<alphabet_type>{}) == true /*;*/
599 );
600
605 template <typename alphabet_type = alphabet_t>
607 /*return*/ std::remove_cvref_t<alphabet_type>::char_is_valid(chr) == true /*;*/
608 );
609
630 template <typename alphabet_type = alphabet_t>
632 /*return*/ seqan3::to_char(seqan3::assign_char_to(chr, alphabet_or_type_identity<alphabet_type>{})) == chr /*;*/
633 );
634};
635
636} // namespace seqan3::detail::adl_only
637
638namespace seqan3
639{
640
689template <typename alph_t>
690 requires requires {
691 { to_char(std::declval<alph_t>()) };
692 } // to_char() is required by some defs
693inline constexpr auto char_is_valid_for = detail::adl_only::char_is_valid_for_cpo<alph_t>{};
695} // namespace seqan3
696
697// ============================================================================
698// assign_char_strictly_to()
699// ============================================================================
700
701namespace seqan3::detail::adl_only
702{
703
706struct assign_char_strictly_to_fn
707{
709 template <typename alphabet_t>
710 constexpr decltype(auto) operator()(seqan3::alphabet_char_t<alphabet_t> const chr, alphabet_t && alphabet) const
711 requires requires () {
712 { seqan3::assign_char_to(chr, std::forward<alphabet_t>(alphabet)) } -> std::convertible_to<alphabet_t>;
713 { seqan3::char_is_valid_for<alphabet_t>(chr) } -> std::same_as<bool>;
714 }
715 {
716 if (!seqan3::char_is_valid_for<alphabet_t>(chr))
717 throw seqan3::invalid_char_assignment{detail::type_name_as_string<alphabet_t>, chr};
718
719 return seqan3::assign_char_to(chr, std::forward<alphabet_t>(alphabet));
720 }
722
723} // namespace seqan3::detail::adl_only
724
725namespace seqan3
726{
727
753inline constexpr auto assign_char_strictly_to = detail::adl_only::assign_char_strictly_to_fn{};
755} // namespace seqan3
756
757// ============================================================================
758// alphabet_size
759// ============================================================================
760
761namespace seqan3::detail::adl_only
763
765template <typename... args_t>
766void alphabet_size(args_t...) = delete;
767
772template <typename alphabet_t>
773struct alphabet_size_cpo : public detail::customisation_point_object<alphabet_size_cpo<alphabet_t>, 2>
774{
778 using base_t::base_t;
783 template <typename alphabet_type>
786 && seqan3::is_constexpr_default_constructible_v<std::remove_cvref_t<alphabet_type>>,
789
793 template <typename alphabet_type = alphabet_t>
794 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<2>)(
796 );
797
806 template <typename alphabet_type = alphabet_t>
807 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<1>)(
809 );
810
814 template <typename alphabet_type = alphabet_t>
815 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<0>)(
817 );
818};
819
820} // namespace seqan3::detail::adl_only
821
822namespace seqan3
823{
824
868template <typename alph_t>
869 requires requires {
871 }
872inline constexpr auto alphabet_size = detail::adl_only::alphabet_size_cpo<alph_t>{}();
873
874// ============================================================================
875// semialphabet
876// ============================================================================
877
920template <typename t>
921concept semialphabet =
922 std::totally_ordered<t> && std::copy_constructible<t> && std::is_nothrow_copy_constructible_v<t> && requires (t v) {
923 { seqan3::alphabet_size<t> };
924 { seqan3::to_rank(v) };
925 };
927
928// ============================================================================
929// writable_semialphabet
930// ============================================================================
931
967template <typename t>
968concept writable_semialphabet = semialphabet<t> && requires (t v, alphabet_rank_t<t> r) {
969 { seqan3::assign_rank_to(r, v) };
970};
972
973// ============================================================================
974// alphabet
975// ============================================================================
976
1005template <typename t>
1006concept alphabet = semialphabet<t> && requires (t v) {
1007 { seqan3::to_char(v) };
1008};
1010
1011// ============================================================================
1012// writable_alphabet
1013// ============================================================================
1014
1052template <typename t>
1053concept writable_alphabet = alphabet<t> && writable_semialphabet<t> && requires (t v, alphabet_char_t<t> c) {
1054 { seqan3::assign_char_to(c, v) };
1055};
1057
1058// ============================================================================
1059// serialisation
1060// ============================================================================
1061
1082template <cereal_output_archive archive_t, semialphabet alphabet_t>
1083alphabet_rank_t<alphabet_t> CEREAL_SAVE_MINIMAL_FUNCTION_NAME(archive_t const &, alphabet_t const & l)
1084{
1085 return to_rank(l);
1086}
1087
1101template <cereal_input_archive archive_t, typename wrapped_alphabet_t>
1102void CEREAL_LOAD_MINIMAL_FUNCTION_NAME(archive_t const &,
1103 wrapped_alphabet_t && l,
1104 alphabet_rank_t<detail::strip_cereal_wrapper_t<wrapped_alphabet_t>> const & r)
1106{
1107 assign_rank_to(r, static_cast<detail::strip_cereal_wrapper_t<wrapped_alphabet_t> &>(l));
1108}
1113} // namespace seqan3
1114
1115namespace seqan3::detail
1116{
1117// ============================================================================
1118// constexpr_semialphabet
1119// ============================================================================
1120
1130template <typename t>
1131concept constexpr_semialphabet = semialphabet<t> && requires {
1132 // currently only tests rvalue interfaces, because we have no constexpr values in this scope to get references to
1134};
1136
1137// ============================================================================
1138// writable_constexpr_semialphabet
1139// ============================================================================
1140
1151template <typename t>
1153 // currently only tests rvalue interfaces, because we have no constexpr values in this scope to get references to
1155};
1157
1158// ============================================================================
1159// constexpr_alphabet
1160// ============================================================================
1161
1172template <typename t>
1174 // currently only tests rvalue interfaces, because we have no constexpr values in this scope to get references to
1176};
1178
1179// ============================================================================
1180// writable_constexpr_alphabet
1181// ============================================================================
1182
1194template <typename t>
1197 // currently only tests rvalue interfaces, because we have no constexpr values in this scope to get references to
1199 };
1201
1202} // namespace seqan3::detail
Exceptions thrown by entities in the alphabet module.
Provides various type traits on generic types.
Adaptions of concepts from the Cereal library.
Helper utilities for defining customisation point objects (CPOs).
constexpr auto assign_char_to
Assign a character to an alphabet object.
Definition alphabet/concept.hpp:517
constexpr auto to_char
Return the char representation of an alphabet object.
Definition alphabet/concept.hpp:381
decltype(seqan3::to_rank(std::declval< semi_alphabet_type >())) alphabet_rank_t
The rank_type of the semi-alphabet; defined as the return type of seqan3::to_rank....
Definition alphabet/concept.hpp:164
constexpr auto alphabet_size
A type trait that holds the size of a (semi-)alphabet.
Definition alphabet/concept.hpp:834
constexpr auto assign_rank_to
Assign a rank to an alphabet object.
Definition alphabet/concept.hpp:288
decltype(seqan3::to_char(std::declval< alphabet_type const >())) alphabet_char_t
The char_type of the alphabet; defined as the return type of seqan3::to_char.
Definition alphabet/concept.hpp:393
constexpr auto char_is_valid_for
Returns whether a character is in the valid set of a seqan3::alphabet (usually implies a bijective ma...
Definition alphabet/concept.hpp:661
constexpr auto assign_char_strictly_to
Assign a character to an alphabet object, throw if the character is not valid.
Definition alphabet/concept.hpp:721
constexpr auto to_rank
Return the rank representation of a (semi-)alphabet object.
Definition alphabet/concept.hpp:152
#define SEQAN3_CPO_OVERLOAD(...)
A macro that helps to define a seqan3::detail::customisation_point_object.
Definition customisation_point.hpp:106
#define SEQAN3_IS_CONSTEXPR(...)
Returns true if the expression passed to this macro can be evaluated at compile time,...
Definition basic.hpp:29
The generic alphabet concept that covers most data types used in ranges.
A seqan3::alphabet that has constexpr accessors.
A seqan3::semialphabet that has constexpr accessors.
A seqan3::writable_alphabet that has constexpr accessors.
A seqan3::writable_semialphabet that has a constexpr assignment.
The basis for seqan3::alphabet, but requires only rank interface (not char).
Refines seqan3::alphabet and adds assignability.
A refinement of seqan3::semialphabet that adds assignability.
A namespace for third party and standard library specialisations of SeqAn customisation points.
Definition char.hpp:40
The internal SeqAn3 namespace.
Definition aligned_sequence_concept.hpp:26
The main SeqAn3 namespace.
Definition aligned_sequence_concept.hpp:26
#define CEREAL_LOAD_MINIMAL_FUNCTION_NAME
Macro for Cereal's load_minimal function.
Definition platform.hpp:157
#define CEREAL_SAVE_MINIMAL_FUNCTION_NAME
Definition platform.hpp:158
A type that can be specialised to provide customisation point implementations so that third party typ...
Definition alphabet/concept.hpp:46
seqan3::detail::customisation_point_object (CPO) definition for seqan3::alphabet_size.
Definition alphabet/concept.hpp:742
seqan3::detail::customisation_point_object (CPO) definition for seqan3::assign_char_to.
Definition alphabet/concept.hpp:411
detail::customisation_point_object< assign_char_to_cpo, 2 > base_t
CRTP base class seqan3::detail::customisation_point_object.
Definition alphabet/concept.hpp:413
seqan3::detail::customisation_point_object (CPO) definition for seqan3::assign_rank_to.
Definition alphabet/concept.hpp:182
seqan3::detail::customisation_point_object (CPO) definition for seqan3::char_is_valid_for.
Definition alphabet/concept.hpp:538
seqan3::detail::customisation_point_object (CPO) definition for seqan3::to_char.
Definition alphabet/concept.hpp:306
seqan3::detail::customisation_point_object (CPO) definition for seqan3::to_rank.
Definition alphabet/concept.hpp:78
A CRTP base-class that defines a customisation_point_object (CPO).
Definition customisation_point.hpp:140
A tag that allows controlled overload resolution via implicit base conversion rules.
Definition customisation_point.hpp:31
An exception typically thrown by seqan3::alphabet::assign_char_strict.
Definition alphabet/exception.hpp:27
Provides traits to inspect some information of a type, for example its name.
Provides concepts that do not have equivalents in C++20.
Hide me