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
23
24// ============================================================================
25// forwards
26// ============================================================================
27
28namespace seqan3::custom
29{
30
47template <typename t>
49{};
50
52template <typename t>
53struct alphabet<t const> : alphabet<t>
54{};
55
56template <typename t>
57struct alphabet<t &> : alphabet<t>
58{};
59
60template <typename t>
61struct alphabet<t const &> : alphabet<t>
62{};
64
65} // namespace seqan3::custom
66
67// ============================================================================
68// to_rank()
69// ============================================================================
70
71namespace seqan3::detail::adl_only
72{
73
75template <typename ...args_t>
76void to_rank(args_t ...) = delete;
77
80struct to_rank_cpo : public detail::customisation_point_object<to_rank_cpo, 2>
81{
85 using base_t::base_t;
86
91 template <typename alphabet_t>
92 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<2>, alphabet_t && alphabet)
93 (
94 /*return*/ seqan3::custom::alphabet<alphabet_t>::to_rank(std::forward<alphabet_t>(alphabet)) /*;*/
95 );
96
101 template <typename alphabet_t>
102 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<1>, alphabet_t && alphabet)
103 (
104 /*return*/ to_rank(std::forward<alphabet_t>(alphabet)) /*;*/
105 );
111 template <typename alphabet_t>
112 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<0>, alphabet_t && alphabet)
113 (
114 /*return*/ std::forward<alphabet_t>(alphabet).to_rank() /*;*/
115 );
116};
117
118} // namespace seqan3::detail::adl_only
119
120namespace seqan3
121{
122
164inline constexpr auto to_rank = detail::adl_only::to_rank_cpo{};
166
172template <typename semi_alphabet_type>
174 requires requires { { seqan3::to_rank(std::declval<semi_alphabet_type>()) }; }
176using alphabet_rank_t = decltype(seqan3::to_rank(std::declval<semi_alphabet_type>()));
177
178} // namespace seqan3
179
180// ============================================================================
181// assign_rank_to()
182// ============================================================================
183
184namespace seqan3::detail::adl_only
185{
186
188template <typename ...args_t>
189void assign_rank_to(args_t ...) = delete;
190
193struct assign_rank_to_cpo : public detail::customisation_point_object<assign_rank_to_cpo, 2>
194{
198 using base_t::base_t;
199
213 template <typename alphabet_t>
214 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<2>,
216 alphabet_t && alphabet)
217 (
218 /*return*/ static_cast<alphabet_t>(seqan3::custom::alphabet<alphabet_t>::assign_rank_to(rank, alphabet)) /*;*/
219 );
220
234 template <typename alphabet_t>
235 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<1>,
237 alphabet_t && alphabet)
238 (
239 /*return*/ static_cast<alphabet_t>(assign_rank_to(rank, alphabet)) /*;*/
240 );
241
252 template <typename alphabet_t> // least priority
253 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<0>,
255 alphabet_t && alphabet)
256 (
257 /*return*/ static_cast<alphabet_t>(std::forward<alphabet_t>(alphabet).assign_rank(rank)) /*;*/
258 );
259};
260
261} // namespace seqan3::detail::adl_only
262
263namespace seqan3
264{
265
314} // namespace seqan3
315
316// ============================================================================
317// to_char()
318// ============================================================================
319
320namespace seqan3::detail::adl_only
321{
322
324template <typename ...args_t>
325void to_char(args_t ...) = delete;
326
329struct to_char_cpo : public detail::customisation_point_object<to_char_cpo, 2>
334 using base_t::base_t;
335
340 template <typename alphabet_t>
341 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<2>, alphabet_t && alphabet)
342 (
343 /*return*/ seqan3::custom::alphabet<alphabet_t>::to_char(std::forward<alphabet_t>(alphabet)) /*;*/
344 );
345
350 template <typename alphabet_t>
351 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<1>, alphabet_t && alphabet)
352 (
353 /*return*/ to_char(std::forward<alphabet_t>(alphabet)) /*;*/
354 );
355
360 template <typename alphabet_t>
361 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<0>, alphabet_t && alphabet)
362 (
363 /*return*/ std::forward<alphabet_t>(alphabet).to_char() /*;*/
364 );
365};
366
367} // namespace seqan3::detail::adl_only
368
369namespace seqan3
370{
371
414inline constexpr auto to_char = detail::adl_only::to_char_cpo{};
422template <typename alphabet_type>
424 requires requires (alphabet_type const a) { { seqan3::to_char(a) }; }
426using alphabet_char_t = decltype(seqan3::to_char(std::declval<alphabet_type const>()));
427
428} // namespace seqan3
429
430// ============================================================================
431// assign_char_to()
432// ============================================================================
433
434namespace seqan3::detail::adl_only
435{
436
438template <typename ...args_t>
439void assign_char_to(args_t ...) = delete;
440
443struct assign_char_to_cpo : public detail::customisation_point_object<assign_char_to_cpo, 2>
444{
448 using base_t::base_t;
449
463 template <typename alphabet_t>
464 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<2>,
466 alphabet_t && alphabet)
467 (
468 /*return*/ static_cast<alphabet_t>(seqan3::custom::alphabet<alphabet_t>::assign_char_to(chr, alphabet)) /*;*/
469 );
470
484 template <typename alphabet_t>
485 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<1>,
487 alphabet_t && alphabet)
488 (
489 /*return*/ static_cast<alphabet_t>(assign_char_to(chr, alphabet)) /*;*/
490 );
491
502 template <typename alphabet_t> // least priority
503 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<0>,
505 alphabet_t && alphabet)
506 (
507 /*return*/ static_cast<alphabet_t>(alphabet.assign_char(chr)) /*;*/
508 );
509};
510
511} // namespace seqan3::detail::adl_only
512
513namespace seqan3
514{
515
564} // namespace seqan3
565
566// ============================================================================
567// char_is_valid_for()
568// ============================================================================
569
570namespace seqan3::detail::adl_only
571{
572
574template <typename ...args_t>
575void char_is_valid_for(args_t ...) = delete;
576
581template <typename alphabet_t>
582struct char_is_valid_for_cpo : public detail::customisation_point_object<char_is_valid_for_cpo<alphabet_t>, 3>
583{
587 using base_t::base_t;
588
592 template <typename alphabet_type>
597
602 template <typename alphabet_type = alphabet_t>
604 (
606 );
607
618 template <typename alphabet_type = alphabet_t>
620 (
621 /*return*/ char_is_valid_for(chr, alphabet_or_type_identity<alphabet_type>{}) == true /*;*/
622 );
623
628 template <typename alphabet_type = alphabet_t>
630 (
631 /*return*/ std::remove_cvref_t<alphabet_type>::char_is_valid(chr) == true /*;*/
632 );
633
654 template <typename alphabet_type = alphabet_t>
656 (
657 /*return*/ seqan3::to_char(seqan3::assign_char_to(chr, alphabet_or_type_identity<alphabet_type>{})) == chr /*;*/
658 );
659};
660
661} // namespace seqan3::detail::adl_only
662
663namespace seqan3
664{
665
714template <typename alph_t>
716 requires requires { { to_char(std::declval<alph_t>()) }; } // to_char() is required by some defs
718inline constexpr auto char_is_valid_for = detail::adl_only::char_is_valid_for_cpo<alph_t>{};
720} // namespace seqan3
721
722// ============================================================================
723// assign_char_strictly_to()
724// ============================================================================
725
726namespace seqan3::detail::adl_only
727{
728
731struct assign_char_strictly_to_fn
732{
734 template <typename alphabet_t>
735 constexpr decltype(auto) operator()(seqan3::alphabet_char_t<alphabet_t> const chr, alphabet_t && alphabet) const
737 requires requires ()
738 {
739 {seqan3::assign_char_to(chr, std::forward<alphabet_t>(alphabet))} -> std::convertible_to<alphabet_t>;
740 {seqan3::char_is_valid_for<alphabet_t>(chr)} -> std::same_as<bool>;
741 }
743 {
744 if (!seqan3::char_is_valid_for<alphabet_t>(chr))
745 throw seqan3::invalid_char_assignment{detail::type_name_as_string<alphabet_t>, chr};
747 return seqan3::assign_char_to(chr, std::forward<alphabet_t>(alphabet));
748 }
749};
750
751} // namespace seqan3::detail::adl_only
752
753namespace seqan3
754{
755
783} // namespace seqan3
784
785// ============================================================================
786// alphabet_size
787// ============================================================================
788
789namespace seqan3::detail::adl_only
790{
793template <typename ...args_t>
794void alphabet_size(args_t ...) = delete;
795
800template <typename alphabet_t>
801struct alphabet_size_cpo : public detail::customisation_point_object<alphabet_size_cpo<alphabet_t>, 2>
802{
806 using base_t::base_t;
807
811 template <typename alphabet_type>
814 seqan3::is_constexpr_default_constructible_v<std::remove_cvref_t<alphabet_type>>,
817
821 template <typename alphabet_type = alphabet_t>
822 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<2>)
823 (
825 );
826
835 template <typename alphabet_type = alphabet_t>
836 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<1>)
837 (
839 );
840
844 template <typename alphabet_type = alphabet_t>
845 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<0>)
848 );
849};
850
851} // namespace seqan3::detail::adl_only
853namespace seqan3
854{
855
899template <typename alph_t>
901 requires requires { { detail::adl_only::alphabet_size_cpo<alph_t>{}() }; }
903inline constexpr auto alphabet_size = detail::adl_only::alphabet_size_cpo<alph_t>{}();
904
905// ============================================================================
906// semialphabet
907// ============================================================================
908
951template <typename t>
952concept semialphabet =
953 std::totally_ordered<t> &&
954 std::copy_constructible<t> &&
955 std::is_nothrow_copy_constructible_v<t> &&
956 requires (t v)
957{
958 { seqan3::alphabet_size<t> };
959 { seqan3::to_rank(v) };
960};
962
963// ============================================================================
964// writable_semialphabet
965// ============================================================================
966
1002template <typename t>
1003concept writable_semialphabet = semialphabet<t> && requires (t v, alphabet_rank_t<t> r)
1004{
1005 { seqan3::assign_rank_to(r, v) };
1006};
1008
1009// ============================================================================
1010// alphabet
1011// ============================================================================
1012
1041template <typename t>
1042concept alphabet = semialphabet<t> && requires (t v)
1043{
1044 { seqan3::to_char(v) };
1045};
1047
1048// ============================================================================
1049// writable_alphabet
1050// ============================================================================
1051
1089template <typename t>
1090concept writable_alphabet = alphabet<t> && writable_semialphabet<t> && requires (t v, alphabet_char_t<t> c)
1091{
1092 { seqan3::assign_char_to(c, v) };
1093};
1095
1096// ============================================================================
1097// serialisation
1098// ============================================================================
1099
1121template <cereal_output_archive archive_t, semialphabet alphabet_t>
1122alphabet_rank_t<alphabet_t> CEREAL_SAVE_MINIMAL_FUNCTION_NAME(archive_t const &, alphabet_t const & l)
1123{
1124 return to_rank(l);
1125}
1126
1140template <cereal_input_archive archive_t, typename wrapped_alphabet_t>
1141void CEREAL_LOAD_MINIMAL_FUNCTION_NAME(archive_t const &,
1142 wrapped_alphabet_t && l,
1143 alphabet_rank_t<detail::strip_cereal_wrapper_t<wrapped_alphabet_t>> const & r)
1145{
1146 assign_rank_to(r, static_cast<detail::strip_cereal_wrapper_t<wrapped_alphabet_t> &>(l));
1147}
1152} // namespace seqan3
1153
1154namespace seqan3::detail
1155{
1156// ============================================================================
1157// constexpr_semialphabet
1158// ============================================================================
1159
1169template <typename t>
1170concept constexpr_semialphabet = semialphabet<t> && requires
1171{
1172 // currently only tests rvalue interfaces, because we have no constexpr values in this scope to get references to
1174};
1176
1177// ============================================================================
1178// writable_constexpr_semialphabet
1179// ============================================================================
1180
1191template <typename t>
1193{
1194 // currently only tests rvalue interfaces, because we have no constexpr values in this scope to get references to
1196};
1198
1199// ============================================================================
1200// constexpr_alphabet
1201// ============================================================================
1202
1213template <typename t>
1215{
1216 // currently only tests rvalue interfaces, because we have no constexpr values in this scope to get references to
1218};
1220
1221// ============================================================================
1222// writable_constexpr_alphabet
1223// ============================================================================
1224
1236template <typename t>
1239{
1240 // currently only tests rvalue interfaces, because we have no constexpr values in this scope to get references to
1242};
1244
1245} // 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:526
constexpr auto to_char
Return the char representation of an alphabet object.
Definition: concept.hpp:387
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:167
constexpr auto alphabet_size
A type trait that holds the size of a (semi-)alphabet.
Definition: concept.hpp:846
constexpr auto assign_rank_to
Assign a rank to an alphabet object.
Definition: concept.hpp:294
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:399
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:670
constexpr auto assign_char_strictly_to
Assign a character to an alphabet object, throw if the character is not valid.
Definition: concept.hpp:733
constexpr auto to_rank
Return the rank representation of a (semi-)alphabet object.
Definition: concept.hpp:155
#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:49
seqan3::detail::customisation_point_object (CPO) definition for seqan3::alphabet_size.
Definition: concept.hpp:754
Function object definition for seqan3::assign_char_strictly_to.
Definition: concept.hpp:684
seqan3::detail::customisation_point_object (CPO) definition for seqan3::assign_char_to.
Definition: concept.hpp:417
seqan3::detail::customisation_point_object (CPO) definition for seqan3::assign_rank_to.
Definition: concept.hpp:185
seqan3::detail::customisation_point_object (CPO) definition for seqan3::char_is_valid_for.
Definition: concept.hpp:547
seqan3::detail::customisation_point_object (CPO) definition for seqan3::to_char.
Definition: concept.hpp:312
seqan3::detail::customisation_point_object (CPO) definition for seqan3::to_rank.
Definition: concept.hpp:81
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.
Provides concepts that do not have equivalents in C++20.