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
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_RETURN_TYPE_CONSTRAINT(seqan3::assign_char_to(chr, std::forward<alphabet_t>(alphabet)),
740 std::convertible_to, alphabet_t);
741 SEQAN3_RETURN_TYPE_CONSTRAINT(seqan3::char_is_valid_for<alphabet_t>(chr), std::same_as, bool);
742 }
744 {
745 if (!seqan3::char_is_valid_for<alphabet_t>(chr))
746 throw seqan3::invalid_char_assignment{detail::type_name_as_string<alphabet_t>, chr};
748 return seqan3::assign_char_to(chr, std::forward<alphabet_t>(alphabet));
749 }
750};
751
752} // namespace seqan3::detail::adl_only
753
754namespace seqan3
755{
756
784} // namespace seqan3
785
786// ============================================================================
787// alphabet_size
788// ============================================================================
789
790namespace seqan3::detail::adl_only
791{
794template <typename ...args_t>
795void alphabet_size(args_t ...) = delete;
796
801template <typename alphabet_t>
802struct alphabet_size_cpo : public detail::customisation_point_object<alphabet_size_cpo<alphabet_t>, 2>
803{
807 using base_t::base_t;
808
812 template <typename alphabet_type>
815 seqan3::is_constexpr_default_constructible_v<std::remove_cvref_t<alphabet_type>>,
818
822 template <typename alphabet_type = alphabet_t>
823 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<2>)
824 (
826 );
827
836 template <typename alphabet_type = alphabet_t>
837 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<1>)
838 (
840 );
841
845 template <typename alphabet_type = alphabet_t>
846 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<0>)
847 (
849 );
850};
851
852#if SEQAN3_WORKAROUND_GCC_89953
853template <typename alph_t>
854 requires requires { { alphabet_size_cpo<alph_t>{} }; }
855inline constexpr auto alphabet_size_obj = alphabet_size_cpo<alph_t>{};
856#endif // SEQAN3_WORKAROUND_GCC_89953
857
858} // namespace seqan3::detail::adl_only
859
860namespace seqan3
862
906#if SEQAN3_WORKAROUND_GCC_89953
907template <typename alph_t>
909 requires requires { { detail::adl_only::alphabet_size_cpo<alph_t>{} }; } &&
910 requires { { detail::adl_only::alphabet_size_obj<alph_t>() }; } // ICE workarounds
912inline constexpr auto alphabet_size = detail::adl_only::alphabet_size_obj<alph_t>();
913#else // ^^^ workaround / no workaround vvv
914template <typename alph_t>
916 requires requires { { detail::adl_only::alphabet_size_cpo<alph_t>{}() }; }
919#endif // SEQAN3_WORKAROUND_GCC_89953
920
921// ============================================================================
922// semialphabet
923// ============================================================================
924
967template <typename t>
968concept semialphabet =
969 std::totally_ordered<t> &&
970 std::copy_constructible<t> &&
971 std::is_nothrow_copy_constructible_v<t> &&
972 requires (t v)
973{
974 { seqan3::alphabet_size<t> };
975 { seqan3::to_rank(v) };
976};
978
979// ============================================================================
980// writable_semialphabet
981// ============================================================================
982
1018template <typename t>
1019concept writable_semialphabet = semialphabet<t> && requires (t v, alphabet_rank_t<t> r)
1020{
1021 { seqan3::assign_rank_to(r, v) };
1022};
1024
1025// ============================================================================
1026// alphabet
1027// ============================================================================
1028
1057template <typename t>
1058concept alphabet = semialphabet<t> && requires (t v)
1059{
1060 { seqan3::to_char(v) };
1061};
1063
1064// ============================================================================
1065// writable_alphabet
1066// ============================================================================
1067
1105template <typename t>
1106concept writable_alphabet = alphabet<t> && writable_semialphabet<t> && requires (t v, alphabet_char_t<t> c)
1107{
1108 { seqan3::assign_char_to(c, v) };
1109};
1111
1112// ============================================================================
1113// serialisation
1114// ============================================================================
1115
1137template <cereal_output_archive archive_t, semialphabet alphabet_t>
1138alphabet_rank_t<alphabet_t> CEREAL_SAVE_MINIMAL_FUNCTION_NAME(archive_t const &, alphabet_t const & l)
1139{
1140 return to_rank(l);
1141}
1142
1156template <cereal_input_archive archive_t, typename wrapped_alphabet_t>
1157void CEREAL_LOAD_MINIMAL_FUNCTION_NAME(archive_t const &,
1158 wrapped_alphabet_t && l,
1159 alphabet_rank_t<detail::strip_cereal_wrapper_t<wrapped_alphabet_t>> const & r)
1161{
1162 assign_rank_to(r, static_cast<detail::strip_cereal_wrapper_t<wrapped_alphabet_t> &>(l));
1163}
1168} // namespace seqan3
1169
1170namespace seqan3::detail
1171{
1172// ============================================================================
1173// constexpr_semialphabet
1174// ============================================================================
1175
1185template <typename t>
1186concept constexpr_semialphabet = semialphabet<t> && requires
1187{
1188 // currently only tests rvalue interfaces, because we have no constexpr values in this scope to get references to
1190};
1192
1193// ============================================================================
1194// writable_constexpr_semialphabet
1195// ============================================================================
1196
1207template <typename t>
1209{
1210 // currently only tests rvalue interfaces, because we have no constexpr values in this scope to get references to
1212};
1214
1215// ============================================================================
1216// constexpr_alphabet
1217// ============================================================================
1218
1229template <typename t>
1231{
1232 // currently only tests rvalue interfaces, because we have no constexpr values in this scope to get references to
1234};
1236
1237// ============================================================================
1238// writable_constexpr_alphabet
1239// ============================================================================
1240
1252template <typename t>
1255{
1256 // currently only tests rvalue interfaces, because we have no constexpr values in this scope to get references to
1258};
1260
1261} // 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.
Provides concepts for core language types and relations that don't have concepts in C++20 (yet).
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:861
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:734
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:153
#define CEREAL_SAVE_MINIMAL_FUNCTION_NAME
Macro for Cereal's save_minimal function.
Definition: platform.hpp:155
#define SEQAN3_RETURN_TYPE_CONSTRAINT(expression, concept_name,...)
Same as writing {expression} -> concept_name<type1[, ...]> in a concept definition.
Definition: platform.hpp:77
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:755
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.
The <type_traits> header from C++20's standard library.