SeqAn3 3.4.0-rc.4
The Modern C++ library for sequence analysis.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
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{
80 using base_t = detail::customisation_point_object<to_rank_cpo, 2>;
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// ============================================================================
177
178namespace seqan3::detail::adl_only
179{
180
182template <typename... args_t>
183void assign_rank_to(args_t...) = delete;
184
187struct assign_rank_to_cpo : public detail::customisation_point_object<assign_rank_to_cpo, 2>
188{
190 using base_t = detail::customisation_point_object<assign_rank_to_cpo, 2>;
192 using base_t::base_t;
193
207 template <typename alphabet_t>
208 static constexpr auto
209 SEQAN3_CPO_OVERLOAD(priority_tag<2>, seqan3::alphabet_rank_t<alphabet_t> const rank, alphabet_t && alphabet)(
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
228 SEQAN3_CPO_OVERLOAD(priority_tag<1>, seqan3::alphabet_rank_t<alphabet_t> const rank, alphabet_t && alphabet)(
229 /*return*/ static_cast<alphabet_t>(assign_rank_to(rank, alphabet)) /*;*/
230 );
231
242 template <typename alphabet_t> // least priority
243 static constexpr auto
244 SEQAN3_CPO_OVERLOAD(priority_tag<0>, seqan3::alphabet_rank_t<alphabet_t> const rank, alphabet_t && alphabet)(
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
300inline constexpr auto assign_rank_to = detail::adl_only::assign_rank_to_cpo{};
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{
320 using base_t = detail::customisation_point_object<to_char_cpo, 2>;
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) };
410 }
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{
431 using base_t = detail::customisation_point_object<assign_char_to_cpo, 2>;
433 using base_t::base_t;
434
448 template <typename alphabet_t>
449 static constexpr auto
450 SEQAN3_CPO_OVERLOAD(priority_tag<2>, seqan3::alphabet_char_t<alphabet_t> const chr, alphabet_t && alphabet)(
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
469 SEQAN3_CPO_OVERLOAD(priority_tag<1>, seqan3::alphabet_char_t<alphabet_t> const chr, alphabet_t && alphabet)(
470 /*return*/ static_cast<alphabet_t>(assign_char_to(chr, alphabet)) /*;*/
471 );
472
483 template <typename alphabet_t> // least priority
484 static constexpr auto
485 SEQAN3_CPO_OVERLOAD(priority_tag<0>, seqan3::alphabet_char_t<alphabet_t> const chr, alphabet_t && alphabet)(
486 /*return*/ static_cast<alphabet_t>(alphabet.assign_char(chr)) /*;*/
487 );
488};
489
490} // namespace seqan3::detail::adl_only
491
492namespace seqan3
493{
494
541inline constexpr auto assign_char_to = detail::adl_only::assign_char_to_cpo{};
543} // namespace seqan3
544
545// ============================================================================
546// char_is_valid_for()
547// ============================================================================
548
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{
564 using base_t = detail::customisation_point_object<char_is_valid_for_cpo<alphabet_t>, 3>;
566 using base_t::base_t;
567
571 template <typename alphabet_type>
572 using alphabet_or_type_identity =
576
581 template <typename alphabet_type = alphabet_t>
582 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<3>, alphabet_char_t<alphabet_type> const chr)(
584 );
585
596 template <typename alphabet_type = alphabet_t>
597 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<2>, alphabet_char_t<alphabet_type> const chr)(
598 /*return*/ char_is_valid_for(chr, alphabet_or_type_identity<alphabet_type>{}) == true /*;*/
599 );
600
605 template <typename alphabet_type = alphabet_t>
606 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<1>, alphabet_char_t<alphabet_type> const chr)(
607 /*return*/ std::remove_cvref_t<alphabet_type>::char_is_valid(chr) == true /*;*/
608 );
609
630 template <typename alphabet_type = alphabet_t>
631 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<0>, alphabet_char_t<alphabet_type> const chr)(
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 {
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
762{
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{
776 using base_t = detail::customisation_point_object<alphabet_size_cpo<alphabet_t>, 2>;
778 using base_t::base_t;
779
783 template <typename alphabet_type>
784 using alphabet_or_type_identity =
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>)(
808 /*return*/ alphabet_size(alphabet_or_type_identity<alphabet_type>{}) /*;*/
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 {
870 { detail::adl_only::alphabet_size_cpo<alph_t>{}() };
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) {
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
1133 requires SEQAN3_IS_CONSTEXPR(to_rank(std::remove_reference_t<t>{}));
1134};
1136
1137// ============================================================================
1138// writable_constexpr_semialphabet
1139// ============================================================================
1140
1151template <typename t>
1152concept writable_constexpr_semialphabet = constexpr_semialphabet<t> && writable_semialphabet<t> && requires {
1153 // currently only tests rvalue interfaces, because we have no constexpr values in this scope to get references to
1154 requires SEQAN3_IS_CONSTEXPR(seqan3::assign_rank_to(alphabet_rank_t<t>{}, std::remove_reference_t<t>{}));
1155};
1157
1158// ============================================================================
1159// constexpr_alphabet
1160// ============================================================================
1161
1172template <typename t>
1173concept constexpr_alphabet = constexpr_semialphabet<t> && alphabet<t> && requires {
1174 // currently only tests rvalue interfaces, because we have no constexpr values in this scope to get references to
1175 requires SEQAN3_IS_CONSTEXPR(to_char(std::remove_reference_t<t>{}));
1176};
1178
1179// ============================================================================
1180// writable_constexpr_alphabet
1181// ============================================================================
1182
1194template <typename t>
1195concept writable_constexpr_alphabet =
1196 constexpr_alphabet<t> && writable_constexpr_semialphabet<t> && writable_alphabet<t> && requires {
1197 // currently only tests rvalue interfaces, because we have no constexpr values in this scope to get references to
1198 requires SEQAN3_IS_CONSTEXPR(seqan3::assign_char_to(alphabet_char_t<t>{}, std::remove_reference_t<t>{}));
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.
A "pretty printer" for most SeqAn data structures and related types.
Definition debug_stream_type.hpp:79
Helper utilities for defining customisation point objects (CPOs).
#define SEQAN3_CPO_OVERLOAD(...)
A macro that helps to define a seqan3::detail::customisation_point_object.
Definition customisation_point.hpp:106
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
The generic alphabet concept that covers most data types used in ranges.
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 main SeqAn3 namespace.
Definition aligned_sequence_concept.hpp:26
A type that can be specialised to provide customisation point implementations so that third party typ...
Definition alphabet/concept.hpp:46
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