SeqAn3 3.4.0-rc.1
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-2024 Knut Reinert & Freie Universität Berlin
2// SPDX-FileCopyrightText: 2016-2024 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 {
169 seqan3::to_rank(std::declval<semi_alphabet_type>())
170 };
171 }
172using alphabet_rank_t = decltype(seqan3::to_rank(std::declval<semi_alphabet_type>()));
173
174} // namespace seqan3
175
176// ============================================================================
177// assign_rank_to()
178// ============================================================================
179
180namespace seqan3::detail::adl_only
181{
182
184template <typename... args_t>
185void assign_rank_to(args_t...) = delete;
186
189struct assign_rank_to_cpo : public detail::customisation_point_object<assign_rank_to_cpo, 2>
190{
192 using base_t = detail::customisation_point_object<assign_rank_to_cpo, 2>;
194 using base_t::base_t;
195
209 template <typename alphabet_t>
210 static constexpr auto
211 SEQAN3_CPO_OVERLOAD(priority_tag<2>, seqan3::alphabet_rank_t<alphabet_t> const rank, alphabet_t && alphabet)(
212 /*return*/ static_cast<alphabet_t>(seqan3::custom::alphabet<alphabet_t>::assign_rank_to(rank, alphabet)) /*;*/
213 );
214
228 template <typename alphabet_t>
229 static constexpr auto
230 SEQAN3_CPO_OVERLOAD(priority_tag<1>, seqan3::alphabet_rank_t<alphabet_t> const rank, alphabet_t && alphabet)(
231 /*return*/ static_cast<alphabet_t>(assign_rank_to(rank, alphabet)) /*;*/
232 );
233
244 template <typename alphabet_t> // least priority
245 static constexpr auto
246 SEQAN3_CPO_OVERLOAD(priority_tag<0>, seqan3::alphabet_rank_t<alphabet_t> const rank, alphabet_t && alphabet)(
247 /*return*/ static_cast<alphabet_t>(std::forward<alphabet_t>(alphabet).assign_rank(rank)) /*;*/
248 );
249};
250
251} // namespace seqan3::detail::adl_only
252
253namespace seqan3
254{
255
302inline constexpr auto assign_rank_to = detail::adl_only::assign_rank_to_cpo{};
304} // namespace seqan3
305
306// ============================================================================
307// to_char()
308// ============================================================================
309
310namespace seqan3::detail::adl_only
311{
312
314template <typename... args_t>
315void to_char(args_t...) = delete;
316
319struct to_char_cpo : public detail::customisation_point_object<to_char_cpo, 2>
320{
322 using base_t = detail::customisation_point_object<to_char_cpo, 2>;
324 using base_t::base_t;
325
330 template <typename alphabet_t>
331 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<2>, alphabet_t && alphabet)(
332 /*return*/ seqan3::custom::alphabet<alphabet_t>::to_char(std::forward<alphabet_t>(alphabet)) /*;*/
333 );
334
339 template <typename alphabet_t>
340 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<1>, alphabet_t && alphabet)(
341 /*return*/ to_char(std::forward<alphabet_t>(alphabet)) /*;*/
342 );
343
348 template <typename alphabet_t>
349 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<0>, alphabet_t && alphabet)(
350 /*return*/ std::forward<alphabet_t>(alphabet).to_char() /*;*/
351 );
352};
353
354} // namespace seqan3::detail::adl_only
355
356namespace seqan3
357{
358
401inline constexpr auto to_char = detail::adl_only::to_char_cpo{};
403
409template <typename alphabet_type>
410 requires requires (alphabet_type const a) {
411 {
413 };
414 }
415using alphabet_char_t = decltype(seqan3::to_char(std::declval<alphabet_type const>()));
416
417} // namespace seqan3
418
419// ============================================================================
420// assign_char_to()
421// ============================================================================
422
423namespace seqan3::detail::adl_only
424{
425
427template <typename... args_t>
428void assign_char_to(args_t...) = delete;
429
432struct assign_char_to_cpo : public detail::customisation_point_object<assign_char_to_cpo, 2>
433{
435 using base_t = detail::customisation_point_object<assign_char_to_cpo, 2>;
437 using base_t::base_t;
438
452 template <typename alphabet_t>
453 static constexpr auto
454 SEQAN3_CPO_OVERLOAD(priority_tag<2>, seqan3::alphabet_char_t<alphabet_t> const chr, alphabet_t && alphabet)(
455 /*return*/ static_cast<alphabet_t>(seqan3::custom::alphabet<alphabet_t>::assign_char_to(chr, alphabet)) /*;*/
456 );
457
471 template <typename alphabet_t>
472 static constexpr auto
473 SEQAN3_CPO_OVERLOAD(priority_tag<1>, seqan3::alphabet_char_t<alphabet_t> const chr, alphabet_t && alphabet)(
474 /*return*/ static_cast<alphabet_t>(assign_char_to(chr, alphabet)) /*;*/
475 );
476
487 template <typename alphabet_t> // least priority
488 static constexpr auto
489 SEQAN3_CPO_OVERLOAD(priority_tag<0>, seqan3::alphabet_char_t<alphabet_t> const chr, alphabet_t && alphabet)(
490 /*return*/ static_cast<alphabet_t>(alphabet.assign_char(chr)) /*;*/
491 );
492};
493
494} // namespace seqan3::detail::adl_only
495
496namespace seqan3
497{
498
545inline constexpr auto assign_char_to = detail::adl_only::assign_char_to_cpo{};
547} // namespace seqan3
548
549// ============================================================================
550// char_is_valid_for()
551// ============================================================================
552
553namespace seqan3::detail::adl_only
554{
555
557template <typename... args_t>
558void char_is_valid_for(args_t...) = delete;
559
564template <typename alphabet_t>
565struct char_is_valid_for_cpo : public detail::customisation_point_object<char_is_valid_for_cpo<alphabet_t>, 3>
566{
568 using base_t = detail::customisation_point_object<char_is_valid_for_cpo<alphabet_t>, 3>;
570 using base_t::base_t;
571
575 template <typename alphabet_type>
576 using alphabet_or_type_identity =
580
585 template <typename alphabet_type = alphabet_t>
586 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<3>, alphabet_char_t<alphabet_type> const chr)(
588 );
589
600 template <typename alphabet_type = alphabet_t>
601 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<2>, alphabet_char_t<alphabet_type> const chr)(
602 /*return*/ char_is_valid_for(chr, alphabet_or_type_identity<alphabet_type>{}) == true /*;*/
603 );
604
609 template <typename alphabet_type = alphabet_t>
610 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<1>, alphabet_char_t<alphabet_type> const chr)(
611 /*return*/ std::remove_cvref_t<alphabet_type>::char_is_valid(chr) == true /*;*/
612 );
613
634 template <typename alphabet_type = alphabet_t>
635 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<0>, alphabet_char_t<alphabet_type> const chr)(
636 /*return*/ seqan3::to_char(seqan3::assign_char_to(chr, alphabet_or_type_identity<alphabet_type>{})) == chr /*;*/
637 );
638};
639
640} // namespace seqan3::detail::adl_only
641
642namespace seqan3
643{
644
693template <typename alph_t>
694 requires requires {
695 {
696 to_char(std::declval<alph_t>())
697 };
698 } // to_char() is required by some defs
699inline constexpr auto char_is_valid_for = detail::adl_only::char_is_valid_for_cpo<alph_t>{};
701} // namespace seqan3
702
703// ============================================================================
704// assign_char_strictly_to()
705// ============================================================================
706
707namespace seqan3::detail::adl_only
708{
709
712struct assign_char_strictly_to_fn
713{
715 template <typename alphabet_t>
716 constexpr decltype(auto) operator()(seqan3::alphabet_char_t<alphabet_t> const chr, alphabet_t && alphabet) const
717 requires requires () {
718 {
719 seqan3::assign_char_to(chr, std::forward<alphabet_t>(alphabet))
720 } -> std::convertible_to<alphabet_t>;
721 {
722 seqan3::char_is_valid_for<alphabet_t>(chr)
723 } -> std::same_as<bool>;
724 }
725 {
726 if (!seqan3::char_is_valid_for<alphabet_t>(chr))
727 throw seqan3::invalid_char_assignment{detail::type_name_as_string<alphabet_t>, chr};
728
729 return seqan3::assign_char_to(chr, std::forward<alphabet_t>(alphabet));
730 }
732
733} // namespace seqan3::detail::adl_only
734
735namespace seqan3
736{
737
763inline constexpr auto assign_char_strictly_to = detail::adl_only::assign_char_strictly_to_fn{};
765} // namespace seqan3
766
767// ============================================================================
768// alphabet_size
769// ============================================================================
770
771namespace seqan3::detail::adl_only
772{
773
775template <typename... args_t>
776void alphabet_size(args_t...) = delete;
777
782template <typename alphabet_t>
783struct alphabet_size_cpo : public detail::customisation_point_object<alphabet_size_cpo<alphabet_t>, 2>
784{
786 using base_t = detail::customisation_point_object<alphabet_size_cpo<alphabet_t>, 2>;
788 using base_t::base_t;
789
793 template <typename alphabet_type>
794 using alphabet_or_type_identity =
796 && seqan3::is_constexpr_default_constructible_v<std::remove_cvref_t<alphabet_type>>,
799
803 template <typename alphabet_type = alphabet_t>
804 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<2>)(
806 );
807
816 template <typename alphabet_type = alphabet_t>
817 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<1>)(
818 /*return*/ alphabet_size(alphabet_or_type_identity<alphabet_type>{}) /*;*/
819 );
820
824 template <typename alphabet_type = alphabet_t>
825 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<0>)(
827 );
828};
829
830} // namespace seqan3::detail::adl_only
831
832namespace seqan3
833{
834
878template <typename alph_t>
879 requires requires {
880 {
881 detail::adl_only::alphabet_size_cpo<alph_t>{}()
882 };
883 }
884inline constexpr auto alphabet_size = detail::adl_only::alphabet_size_cpo<alph_t>{}();
885
886// ============================================================================
887// semialphabet
888// ============================================================================
889
932template <typename t>
933concept semialphabet = std::totally_ordered<t> && std::copy_constructible<t> && std::is_nothrow_copy_constructible_v<t>
934 && requires (t v) {
935 {
936 seqan3::alphabet_size<t>
937 };
938 {
940 };
941 };
943
944// ============================================================================
945// writable_semialphabet
946// ============================================================================
947
983template <typename t>
984concept writable_semialphabet = semialphabet<t> && requires (t v, alphabet_rank_t<t> r) {
985 {
987 };
988 };
990
991// ============================================================================
992// alphabet
993// ============================================================================
994
1023template <typename t>
1024concept alphabet = semialphabet<t> && requires (t v) {
1025 {
1027 };
1028 };
1030
1031// ============================================================================
1032// writable_alphabet
1033// ============================================================================
1034
1072template <typename t>
1073concept writable_alphabet = alphabet<t> && writable_semialphabet<t> && requires (t v, alphabet_char_t<t> c) {
1074 {
1076 };
1077 };
1079
1080// ============================================================================
1081// serialisation
1082// ============================================================================
1083
1105template <cereal_output_archive archive_t, semialphabet alphabet_t>
1106alphabet_rank_t<alphabet_t> CEREAL_SAVE_MINIMAL_FUNCTION_NAME(archive_t const &, alphabet_t const & l)
1107{
1108 return to_rank(l);
1109}
1110
1124template <cereal_input_archive archive_t, typename wrapped_alphabet_t>
1125void CEREAL_LOAD_MINIMAL_FUNCTION_NAME(archive_t const &,
1126 wrapped_alphabet_t && l,
1127 alphabet_rank_t<detail::strip_cereal_wrapper_t<wrapped_alphabet_t>> const & r)
1129{
1130 assign_rank_to(r, static_cast<detail::strip_cereal_wrapper_t<wrapped_alphabet_t> &>(l));
1131}
1136} // namespace seqan3
1137
1138namespace seqan3::detail
1139{
1140// ============================================================================
1141// constexpr_semialphabet
1142// ============================================================================
1143
1153template <typename t>
1154concept constexpr_semialphabet =
1155 semialphabet<t> && requires {
1156 // currently only tests rvalue interfaces, because we have no constexpr values in this scope to get references to
1157 requires SEQAN3_IS_CONSTEXPR(to_rank(std::remove_reference_t<t>{}));
1158 };
1160
1161// ============================================================================
1162// writable_constexpr_semialphabet
1163// ============================================================================
1164
1175template <typename t>
1176concept writable_constexpr_semialphabet =
1177 constexpr_semialphabet<t> && writable_semialphabet<t>
1178 && requires {
1179 // currently only tests rvalue interfaces, because we have no constexpr values in this scope to get references to
1180 requires SEQAN3_IS_CONSTEXPR(seqan3::assign_rank_to(alphabet_rank_t<t>{}, std::remove_reference_t<t>{}));
1181 };
1183
1184// ============================================================================
1185// constexpr_alphabet
1186// ============================================================================
1187
1198template <typename t>
1199concept constexpr_alphabet =
1200 constexpr_semialphabet<t> && alphabet<t> && requires {
1201 // currently only tests rvalue interfaces, because we have no constexpr values in this scope to get references to
1202 requires SEQAN3_IS_CONSTEXPR(to_char(std::remove_reference_t<t>{}));
1203 };
1205
1206// ============================================================================
1207// writable_constexpr_alphabet
1208// ============================================================================
1209
1221template <typename t>
1222concept writable_constexpr_alphabet =
1223 constexpr_alphabet<t> && writable_constexpr_semialphabet<t> && writable_alphabet<t>
1224 && requires {
1225 // currently only tests rvalue interfaces, because we have no constexpr values in this scope to get references to
1226 requires SEQAN3_IS_CONSTEXPR(seqan3::assign_char_to(alphabet_char_t<t>{}, std::remove_reference_t<t>{}));
1227 };
1229
1230} // 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).
#define SEQAN3_CPO_OVERLOAD(...)
A macro that helps to define a seqan3::detail::customisation_point_object.
Definition customisation_point.hpp:104
constexpr auto assign_char_to
Assign a character to an alphabet object.
Definition alphabet/concept.hpp:521
constexpr auto to_char
Return the char representation of an alphabet object.
Definition alphabet/concept.hpp:383
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:166
constexpr auto alphabet_size
A type trait that holds the size of a (semi-)alphabet.
Definition alphabet/concept.hpp:846
constexpr auto assign_rank_to
Assign a rank to an alphabet object.
Definition alphabet/concept.hpp:290
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:397
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:667
constexpr auto assign_char_strictly_to
Assign a character to an alphabet object, throw if the character is not valid.
Definition alphabet/concept.hpp:731
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:39
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