SeqAn3 3.2.0-rc.1
The Modern C++ library for sequence analysis.
concept.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 <type_traits>
16
22
23// ============================================================================
24// forwards
25// ============================================================================
26
27namespace seqan3::custom
28{
29
46template <typename t>
48{};
49
51template <typename t>
52struct alphabet<t const> : alphabet<t>
53{};
54
55template <typename t>
56struct alphabet<t &> : alphabet<t>
57{};
58
59template <typename t>
60struct alphabet<t const &> : alphabet<t>
61{};
63
64} // namespace seqan3::custom
65
66// ============================================================================
67// to_rank()
68// ============================================================================
69
70namespace seqan3::detail::adl_only
71{
72
74template <typename ...args_t>
75void to_rank(args_t ...) = delete;
76
79struct to_rank_cpo : public detail::customisation_point_object<to_rank_cpo, 2>
80{
84 using base_t::base_t;
85
90 template <typename alphabet_t>
91 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<2>, alphabet_t && alphabet)
92 (
93 /*return*/ seqan3::custom::alphabet<alphabet_t>::to_rank(std::forward<alphabet_t>(alphabet)) /*;*/
94 );
95
100 template <typename alphabet_t>
101 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<1>, alphabet_t && alphabet)
102 (
103 /*return*/ to_rank(std::forward<alphabet_t>(alphabet)) /*;*/
104 );
110 template <typename alphabet_t>
111 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<0>, alphabet_t && alphabet)
112 (
113 /*return*/ std::forward<alphabet_t>(alphabet).to_rank() /*;*/
114 );
115};
116
117} // namespace seqan3::detail::adl_only
118
119namespace seqan3
120{
121
163inline constexpr auto to_rank = detail::adl_only::to_rank_cpo{};
165
171template <typename semi_alphabet_type>
173 requires requires { { seqan3::to_rank(std::declval<semi_alphabet_type>()) }; }
175using alphabet_rank_t = decltype(seqan3::to_rank(std::declval<semi_alphabet_type>()));
176
177} // namespace seqan3
178
179// ============================================================================
180// assign_rank_to()
181// ============================================================================
182
183namespace seqan3::detail::adl_only
184{
185
187template <typename ...args_t>
188void assign_rank_to(args_t ...) = delete;
189
192struct assign_rank_to_cpo : public detail::customisation_point_object<assign_rank_to_cpo, 2>
193{
197 using base_t::base_t;
198
212 template <typename alphabet_t>
213 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<2>,
215 alphabet_t && alphabet)
216 (
217 /*return*/ static_cast<alphabet_t>(seqan3::custom::alphabet<alphabet_t>::assign_rank_to(rank, alphabet)) /*;*/
218 );
219
233 template <typename alphabet_t>
234 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<1>,
236 alphabet_t && alphabet)
237 (
238 /*return*/ static_cast<alphabet_t>(assign_rank_to(rank, alphabet)) /*;*/
239 );
240
251 template <typename alphabet_t> // least priority
252 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<0>,
254 alphabet_t && alphabet)
255 (
256 /*return*/ static_cast<alphabet_t>(std::forward<alphabet_t>(alphabet).assign_rank(rank)) /*;*/
257 );
258};
259
260} // namespace seqan3::detail::adl_only
261
262namespace seqan3
263{
264
313} // namespace seqan3
314
315// ============================================================================
316// to_char()
317// ============================================================================
318
319namespace seqan3::detail::adl_only
320{
321
323template <typename ...args_t>
324void to_char(args_t ...) = delete;
325
328struct to_char_cpo : public detail::customisation_point_object<to_char_cpo, 2>
333 using base_t::base_t;
334
339 template <typename alphabet_t>
340 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<2>, alphabet_t && alphabet)
341 (
342 /*return*/ seqan3::custom::alphabet<alphabet_t>::to_char(std::forward<alphabet_t>(alphabet)) /*;*/
343 );
344
349 template <typename alphabet_t>
350 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<1>, alphabet_t && alphabet)
351 (
352 /*return*/ to_char(std::forward<alphabet_t>(alphabet)) /*;*/
353 );
354
359 template <typename alphabet_t>
360 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<0>, alphabet_t && alphabet)
361 (
362 /*return*/ std::forward<alphabet_t>(alphabet).to_char() /*;*/
363 );
364};
365
366} // namespace seqan3::detail::adl_only
367
368namespace seqan3
369{
370
413inline constexpr auto to_char = detail::adl_only::to_char_cpo{};
421template <typename alphabet_type>
423 requires requires (alphabet_type const a) { { seqan3::to_char(a) }; }
425using alphabet_char_t = decltype(seqan3::to_char(std::declval<alphabet_type const>()));
426
427} // namespace seqan3
428
429// ============================================================================
430// assign_char_to()
431// ============================================================================
432
433namespace seqan3::detail::adl_only
434{
435
437template <typename ...args_t>
438void assign_char_to(args_t ...) = delete;
439
442struct assign_char_to_cpo : public detail::customisation_point_object<assign_char_to_cpo, 2>
443{
447 using base_t::base_t;
448
462 template <typename alphabet_t>
463 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<2>,
465 alphabet_t && alphabet)
466 (
467 /*return*/ static_cast<alphabet_t>(seqan3::custom::alphabet<alphabet_t>::assign_char_to(chr, alphabet)) /*;*/
468 );
469
483 template <typename alphabet_t>
484 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<1>,
486 alphabet_t && alphabet)
487 (
488 /*return*/ static_cast<alphabet_t>(assign_char_to(chr, alphabet)) /*;*/
489 );
490
501 template <typename alphabet_t> // least priority
502 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<0>,
504 alphabet_t && alphabet)
505 (
506 /*return*/ static_cast<alphabet_t>(alphabet.assign_char(chr)) /*;*/
507 );
508};
509
510} // namespace seqan3::detail::adl_only
511
512namespace seqan3
513{
514
563} // namespace seqan3
564
565// ============================================================================
566// char_is_valid_for()
567// ============================================================================
568
569namespace seqan3::detail::adl_only
570{
571
573template <typename ...args_t>
574void char_is_valid_for(args_t ...) = delete;
575
580template <typename alphabet_t>
581struct char_is_valid_for_cpo : public detail::customisation_point_object<char_is_valid_for_cpo<alphabet_t>, 3>
582{
586 using base_t::base_t;
587
591 template <typename alphabet_type>
596
601 template <typename alphabet_type = alphabet_t>
603 (
605 );
606
617 template <typename alphabet_type = alphabet_t>
619 (
620 /*return*/ char_is_valid_for(chr, alphabet_or_type_identity<alphabet_type>{}) == true /*;*/
621 );
622
627 template <typename alphabet_type = alphabet_t>
629 (
630 /*return*/ std::remove_cvref_t<alphabet_type>::char_is_valid(chr) == true /*;*/
631 );
632
653 template <typename alphabet_type = alphabet_t>
655 (
656 /*return*/ seqan3::to_char(seqan3::assign_char_to(chr, alphabet_or_type_identity<alphabet_type>{})) == chr /*;*/
657 );
658};
659
660} // namespace seqan3::detail::adl_only
661
662namespace seqan3
663{
664
713template <typename alph_t>
715 requires requires { { to_char(std::declval<alph_t>()) }; } // to_char() is required by some defs
717inline constexpr auto char_is_valid_for = detail::adl_only::char_is_valid_for_cpo<alph_t>{};
719} // namespace seqan3
720
721// ============================================================================
722// assign_char_strictly_to()
723// ============================================================================
724
725namespace seqan3::detail::adl_only
726{
727
730struct assign_char_strictly_to_fn
731{
733 template <typename alphabet_t>
734 constexpr decltype(auto) operator()(seqan3::alphabet_char_t<alphabet_t> const chr, alphabet_t && alphabet) const
736 requires requires ()
737 {
738 {seqan3::assign_char_to(chr, std::forward<alphabet_t>(alphabet))} -> std::convertible_to<alphabet_t>;
739 {seqan3::char_is_valid_for<alphabet_t>(chr)} -> std::same_as<bool>;
740 }
742 {
743 if (!seqan3::char_is_valid_for<alphabet_t>(chr))
744 throw seqan3::invalid_char_assignment{detail::type_name_as_string<alphabet_t>, chr};
746 return seqan3::assign_char_to(chr, std::forward<alphabet_t>(alphabet));
747 }
748};
749
750} // namespace seqan3::detail::adl_only
751
752namespace seqan3
753{
754
782} // namespace seqan3
783
784// ============================================================================
785// alphabet_size
786// ============================================================================
787
788namespace seqan3::detail::adl_only
789{
792template <typename ...args_t>
793void alphabet_size(args_t ...) = delete;
794
799template <typename alphabet_t>
800struct alphabet_size_cpo : public detail::customisation_point_object<alphabet_size_cpo<alphabet_t>, 2>
801{
805 using base_t::base_t;
806
810 template <typename alphabet_type>
813 seqan3::is_constexpr_default_constructible_v<std::remove_cvref_t<alphabet_type>>,
816
820 template <typename alphabet_type = alphabet_t>
821 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<2>)
822 (
824 );
825
834 template <typename alphabet_type = alphabet_t>
835 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<1>)
836 (
838 );
839
843 template <typename alphabet_type = alphabet_t>
844 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<0>)
847 );
848};
849
850} // namespace seqan3::detail::adl_only
852namespace seqan3
853{
854
898template <typename alph_t>
900 requires requires { { detail::adl_only::alphabet_size_cpo<alph_t>{}() }; }
902inline constexpr auto alphabet_size = detail::adl_only::alphabet_size_cpo<alph_t>{}();
903
904// ============================================================================
905// semialphabet
906// ============================================================================
907
950template <typename t>
951concept semialphabet =
952 std::totally_ordered<t> &&
953 std::copy_constructible<t> &&
954 std::is_nothrow_copy_constructible_v<t> &&
955 requires (t v)
956{
957 { seqan3::alphabet_size<t> };
958 { seqan3::to_rank(v) };
959};
961
962// ============================================================================
963// writable_semialphabet
964// ============================================================================
965
1001template <typename t>
1002concept writable_semialphabet = semialphabet<t> && requires (t v, alphabet_rank_t<t> r)
1003{
1004 { seqan3::assign_rank_to(r, v) };
1005};
1007
1008// ============================================================================
1009// alphabet
1010// ============================================================================
1011
1040template <typename t>
1041concept alphabet = semialphabet<t> && requires (t v)
1042{
1043 { seqan3::to_char(v) };
1044};
1046
1047// ============================================================================
1048// writable_alphabet
1049// ============================================================================
1050
1088template <typename t>
1089concept writable_alphabet = alphabet<t> && writable_semialphabet<t> && requires (t v, alphabet_char_t<t> c)
1090{
1091 { seqan3::assign_char_to(c, v) };
1092};
1094
1095// ============================================================================
1096// serialisation
1097// ============================================================================
1098
1120template <cereal_output_archive archive_t, semialphabet alphabet_t>
1121alphabet_rank_t<alphabet_t> CEREAL_SAVE_MINIMAL_FUNCTION_NAME(archive_t const &, alphabet_t const & l)
1122{
1123 return to_rank(l);
1124}
1125
1139template <cereal_input_archive archive_t, typename wrapped_alphabet_t>
1140void CEREAL_LOAD_MINIMAL_FUNCTION_NAME(archive_t const &,
1141 wrapped_alphabet_t && l,
1142 alphabet_rank_t<detail::strip_cereal_wrapper_t<wrapped_alphabet_t>> const & r)
1144{
1145 assign_rank_to(r, static_cast<detail::strip_cereal_wrapper_t<wrapped_alphabet_t> &>(l));
1146}
1151} // namespace seqan3
1152
1153namespace seqan3::detail
1154{
1155// ============================================================================
1156// constexpr_semialphabet
1157// ============================================================================
1158
1168template <typename t>
1169concept constexpr_semialphabet = semialphabet<t> && requires
1170{
1171 // currently only tests rvalue interfaces, because we have no constexpr values in this scope to get references to
1173};
1175
1176// ============================================================================
1177// writable_constexpr_semialphabet
1178// ============================================================================
1179
1190template <typename t>
1192{
1193 // currently only tests rvalue interfaces, because we have no constexpr values in this scope to get references to
1195};
1197
1198// ============================================================================
1199// constexpr_alphabet
1200// ============================================================================
1201
1212template <typename t>
1214{
1215 // currently only tests rvalue interfaces, because we have no constexpr values in this scope to get references to
1217};
1219
1220// ============================================================================
1221// writable_constexpr_alphabet
1222// ============================================================================
1223
1235template <typename t>
1238{
1239 // currently only tests rvalue interfaces, because we have no constexpr values in this scope to get references to
1241};
1243
1244} // 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: concept.hpp:525
constexpr auto to_char
Return the char representation of an alphabet object.
Definition: concept.hpp:386
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: concept.hpp:166
constexpr auto alphabet_size
A type trait that holds the size of a (semi-)alphabet.
Definition: concept.hpp:845
constexpr auto assign_rank_to
Assign a rank to an alphabet object.
Definition: concept.hpp:293
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: concept.hpp:398
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: concept.hpp:669
constexpr auto assign_char_strictly_to
Assign a character to an alphabet object, throw if the character is not valid.
Definition: concept.hpp:732
constexpr auto to_rank
Return the rank representation of a (semi-)alphabet object.
Definition: concept.hpp:154
#define SEQAN3_CPO_OVERLOAD(...)
A macro that helps to define a seqan3::detail::customisation_point_object.
Definition: customisation_point.hpp:102
#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:44
The internal SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
#define CEREAL_LOAD_MINIMAL_FUNCTION_NAME
Macro for Cereal's load_minimal function.
Definition: platform.hpp:132
#define CEREAL_SAVE_MINIMAL_FUNCTION_NAME
Macro for Cereal's save_minimal function.
Definition: platform.hpp:134
A type that can be specialised to provide customisation point implementations so that third party typ...
Definition: concept.hpp:48
seqan3::detail::customisation_point_object (CPO) definition for seqan3::alphabet_size.
Definition: concept.hpp:753
Function object definition for seqan3::assign_char_strictly_to.
Definition: concept.hpp:683
seqan3::detail::customisation_point_object (CPO) definition for seqan3::assign_char_to.
Definition: concept.hpp:416
seqan3::detail::customisation_point_object (CPO) definition for seqan3::assign_rank_to.
Definition: concept.hpp:184
seqan3::detail::customisation_point_object (CPO) definition for seqan3::char_is_valid_for.
Definition: concept.hpp:546
seqan3::detail::customisation_point_object (CPO) definition for seqan3::to_char.
Definition: concept.hpp:311
seqan3::detail::customisation_point_object (CPO) definition for seqan3::to_rank.
Definition: concept.hpp:80
A CRTP base-class that defines a customisation_point_object (CPO).
Definition: customisation_point.hpp:138
Recursion anchor for seqan3::detail::priority_tag.
Definition: customisation_point.hpp:37
A tag that allows controlled overload resolution via implicit base conversion rules.
Definition: customisation_point.hpp:32
An exception typically thrown by seqan3::alphabet::assign_char_strict.
Definition: exception.hpp:30
Provides traits to inspect some information of a type, for example its name.