SeqAn3 3.1.0
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 <optional>
16
19#include <seqan3/std/concepts>
21
22// ============================================================================
23// is_pair_open()
24// ============================================================================
25
26namespace seqan3::detail::adl_only
27{
28
30template <typename ...args_t>
31void is_pair_open(args_t ...) = delete;
32
36struct is_pair_open_cpo : public detail::customisation_point_object<is_pair_open_cpo, 2>
37{
39 using base_t = detail::customisation_point_object<is_pair_open_cpo, 2>;
41 using base_t::base_t;
42
47 template <typename alphabet_t>
48 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<2>, alphabet_t && alphabet)
49 (
50 /*return*/ seqan3::custom::alphabet<alphabet_t>::is_pair_open(std::forward<alphabet_t>(alphabet)) == true /*;*/
51 );
52
57 template <typename alphabet_t>
58 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<1>, alphabet_t && alphabet)
59 (
60 /*return*/ is_pair_open(std::forward<alphabet_t>(alphabet)) == true /*;*/
61 );
62
67 template <typename alphabet_t>
68 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<0>, alphabet_t && alphabet)
69 (
70 /*return*/ std::forward<alphabet_t>(alphabet).is_pair_open() == true /*;*/
71 );
72};
73
74} // namespace seqan3::detail::adl_only
75
76namespace seqan3
77{
109inline constexpr auto is_pair_open = detail::adl_only::is_pair_open_cpo{};
110
111} // namespace seqan3
112
113// ============================================================================
114// is_pair_close()
115// ============================================================================
116
117namespace seqan3::detail::adl_only
118{
119
121template <typename ...args_t>
122void is_pair_close(args_t ...) = delete;
123
127struct is_pair_close_cpo : public detail::customisation_point_object<is_pair_close_cpo, 2>
128{
130 using base_t = detail::customisation_point_object<is_pair_close_cpo, 2>;
132 using base_t::base_t;
133
138 template <typename alphabet_t>
139 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<2>, alphabet_t && alphabet)
140 (
141 /*return*/ seqan3::custom::alphabet<alphabet_t>::is_pair_close(std::forward<alphabet_t>(alphabet)) == true /*;*/
142 );
143
148 template <typename alphabet_t>
149 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<1>, alphabet_t && alphabet)
150 (
151 /*return*/ is_pair_close(std::forward<alphabet_t>(alphabet)) == true /*;*/
152 );
153
158 template <typename alphabet_t>
159 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<0>, alphabet_t && alphabet)
160 (
161 /*return*/ std::forward<alphabet_t>(alphabet).is_pair_close() == true /*;*/
162 );
163};
164
165} // namespace seqan3::detail::adl_only
166
167namespace seqan3
168{
200inline constexpr auto is_pair_close = detail::adl_only::is_pair_close_cpo{};
201
202} // namespace seqan3
203
204// ============================================================================
205// is_unpaired()
206// ============================================================================
207
208namespace seqan3::detail::adl_only
209{
210
212template <typename ...args_t>
213void is_unpaired(args_t ...) = delete;
214
218struct is_unpaired_cpo : public detail::customisation_point_object<is_unpaired_cpo, 2>
219{
221 using base_t = detail::customisation_point_object<is_unpaired_cpo, 2>;
223 using base_t::base_t;
224
229 template <typename alphabet_t>
230 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<2>, alphabet_t && alphabet)
231 (
232 /*return*/ seqan3::custom::alphabet<alphabet_t>::is_unpaired(std::forward<alphabet_t>(alphabet)) == true /*;*/
233 );
234
239 template <typename alphabet_t>
240 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<1>, alphabet_t && alphabet)
241 (
242 /*return*/ is_unpaired(std::forward<alphabet_t>(alphabet)) == true /*;*/
243 );
244
249 template <typename alphabet_t>
250 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<0>, alphabet_t && alphabet)
251 (
252 /*return*/ std::forward<alphabet_t>(alphabet).is_unpaired() == true /*;*/
253 );
254};
255
256} // namespace seqan3::detail::adl_only
257
258namespace seqan3
259{
291inline constexpr auto is_unpaired = detail::adl_only::is_unpaired_cpo{};
292
293} // namespace seqan3
294
295// ============================================================================
296// max_pseudoknot_depth
297// ============================================================================
298
299namespace seqan3::detail::adl_only
300{
301
303template <typename ...args_t>
304void max_pseudoknot_depth(args_t ...) = delete;
305
310template <typename alphabet_t>
311struct max_pseudoknot_depth_cpo : public detail::customisation_point_object<max_pseudoknot_depth_cpo<alphabet_t>, 2>
312{
314 using base_t = detail::customisation_point_object<max_pseudoknot_depth_cpo<alphabet_t>, 2>;
316 using base_t::base_t;
317
321 template <typename alphabet_type>
322 using alphabet_or_type_identity
324 seqan3::is_constexpr_default_constructible_v<std::remove_cvref_t<alphabet_type>>,
327
331 template <typename alphabet_type = alphabet_t>
332 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<2>)
333 (
335 );
336
346 template <typename alphabet_type = alphabet_t>
347 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<1>)
348 (
349 /*return*/ max_pseudoknot_depth(alphabet_or_type_identity<alphabet_type>{}) /*;*/
350 );
351
355 template <typename alphabet_type = alphabet_t>
356 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<0>)
357 (
359 );
360};
361
362#if SEQAN3_WORKAROUND_GCC_89953
363template <typename alph_t>
364 requires requires { { max_pseudoknot_depth_cpo<alph_t>{} }; }
365inline constexpr auto max_pseudoknot_depth_obj = max_pseudoknot_depth_cpo<alph_t>{};
366#endif // SEQAN3_WORKAROUND_GCC_89953
367
368} // namespace seqan3::detail::adl_only
369
370namespace seqan3
371{
412#if SEQAN3_WORKAROUND_GCC_89953
413template <typename alph_t>
415 requires requires { { detail::adl_only::max_pseudoknot_depth_cpo<alph_t>{} }; } &&
416 requires { { detail::adl_only::max_pseudoknot_depth_obj<alph_t>() }; }
418inline constexpr auto max_pseudoknot_depth = detail::adl_only::max_pseudoknot_depth_obj<alph_t>();
419#else // ^^^ workaround / no workaround vvv
420template <typename alph_t>
422 requires requires { { detail::adl_only::max_pseudoknot_depth_cpo<alph_t>{}() }; }
424inline constexpr auto max_pseudoknot_depth = detail::adl_only::max_pseudoknot_depth_cpo<alph_t>{}();
425#endif // SEQAN3_WORKAROUND_GCC_89953
426
427} // namespace seqan3
428
429// ============================================================================
430// pseudoknot_id()
431// ============================================================================
432
433namespace seqan3::detail::adl_only
434{
435
437template <typename ...args_t>
438void pseudoknot_id(args_t ...) = delete;
439
442struct pseudoknot_id_cpo : public detail::customisation_point_object<pseudoknot_id_cpo, 2>
443{
445 using base_t = detail::customisation_point_object<pseudoknot_id_cpo, 2>;
447 using base_t::base_t;
448
453 template <typename alphabet_t>
454 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<2>, alphabet_t && alphabet)
455 (
456 /*return*/ seqan3::custom::alphabet<alphabet_t>::pseudoknot_id(std::forward<alphabet_t>(alphabet)) /*;*/
457 );
458
463 template <typename alphabet_t>
464 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<1>, alphabet_t && alphabet)
465 (
466 /*return*/ pseudoknot_id(std::forward<alphabet_t>(alphabet)) /*;*/
467 );
468
473 template <typename alphabet_t>
474 static constexpr auto SEQAN3_CPO_OVERLOAD(priority_tag<0>, alphabet_t && alphabet)
475 (
476 /*return*/ std::forward<alphabet_t>(alphabet).pseudoknot_id() /*;*/
477 );
478};
479
480} // namespace seqan3::detail::adl_only
481
482namespace seqan3
483{
517inline constexpr auto pseudoknot_id = detail::adl_only::pseudoknot_id_cpo{};
518
519} // namespace seqan3
520
521// ============================================================================
522// rna_structure_alphabet concept
523// ============================================================================
524
525namespace seqan3
526{
560template <typename t>
561SEQAN3_CONCEPT rna_structure_alphabet = seqan3::alphabet<t> && requires(t val)
562{
563 { seqan3::is_pair_open(val) };
564 { seqan3::is_pair_close(val) };
565 { seqan3::is_unpaired(val) };
566 { seqan3::pseudoknot_id(val) };
567
568 // this is delegated to a static class variable, which must not be 0
569 requires seqan3::max_pseudoknot_depth<t> > 0;
570};
572
573} // namespace seqan3
Core alphabet concept and free function/type trait wrappers.
The <concepts> header from C++20's standard 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:102
constexpr auto is_unpaired
Check whether the given character represents an unpaired nucleotide in an RNA structure.
Definition: concept.hpp:264
constexpr auto pseudoknot_id
Retrieve an id for the level of a pseudoknotted interaction (also known as 'page number').
Definition: concept.hpp:472
constexpr auto is_pair_close
Check whether the given character represents a leftward interaction in an RNA structure.
Definition: concept.hpp:182
constexpr auto max_pseudoknot_depth
A type trait that holds the ability of the structure alphabet to represent pseudoknots,...
Definition: concept.hpp:388
constexpr auto is_pair_open
Check whether the given character represents a rightward interaction in an RNA structure.
Definition: concept.hpp:100
The generic alphabet concept that covers most data types used in ranges.
A concept that indicates whether an alphabet represents RNA structure.
The main SeqAn3 namespace.
Definition: cigar_operation_table.hpp:2
A type that can be specialised to provide customisation point implementations so that third party typ...
Definition: concept.hpp:49
The <type_traits> header from C++20's standard library.