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>
20 #include <seqan3/std/type_traits>
21 
22 // ============================================================================
23 // is_pair_open()
24 // ============================================================================
25 
26 namespace seqan3::detail::adl_only
27 {
28 
30 template <typename ...args_t>
31 void is_pair_open(args_t ...) = delete;
32 
36 struct 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 
76 namespace seqan3
77 {
109 inline constexpr auto is_pair_open = detail::adl_only::is_pair_open_cpo{};
110 
111 } // namespace seqan3
112 
113 // ============================================================================
114 // is_pair_close()
115 // ============================================================================
116 
117 namespace seqan3::detail::adl_only
118 {
119 
121 template <typename ...args_t>
122 void is_pair_close(args_t ...) = delete;
123 
127 struct 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 
167 namespace seqan3
168 {
200 inline constexpr auto is_pair_close = detail::adl_only::is_pair_close_cpo{};
201 
202 } // namespace seqan3
203 
204 // ============================================================================
205 // is_unpaired()
206 // ============================================================================
207 
208 namespace seqan3::detail::adl_only
209 {
210 
212 template <typename ...args_t>
213 void is_unpaired(args_t ...) = delete;
214 
218 struct 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 
258 namespace seqan3
259 {
291 inline constexpr auto is_unpaired = detail::adl_only::is_unpaired_cpo{};
292 
293 } // namespace seqan3
294 
295 // ============================================================================
296 // max_pseudoknot_depth
297 // ============================================================================
298 
299 namespace seqan3::detail::adl_only
300 {
301 
303 template <typename ...args_t>
304 void max_pseudoknot_depth(args_t ...) = delete;
305 
310 template <typename alphabet_t>
311 struct 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
363 template <typename alph_t>
364  requires requires { { max_pseudoknot_depth_cpo<alph_t>{} }; }
365 inline 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 
370 namespace seqan3
371 {
412 #if SEQAN3_WORKAROUND_GCC_89953
413 template <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>() }; }
418 inline constexpr auto max_pseudoknot_depth = detail::adl_only::max_pseudoknot_depth_obj<alph_t>();
419 #else // ^^^ workaround / no workaround vvv
420 template <typename alph_t>
422  requires requires { { detail::adl_only::max_pseudoknot_depth_cpo<alph_t>{}() }; }
424 inline 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 
433 namespace seqan3::detail::adl_only
434 {
435 
437 template <typename ...args_t>
438 void pseudoknot_id(args_t ...) = delete;
439 
442 struct 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 
482 namespace seqan3
483 {
517 inline constexpr auto pseudoknot_id = detail::adl_only::pseudoknot_id_cpo{};
518 
519 } // namespace seqan3
520 
521 // ============================================================================
522 // rna_structure_alphabet concept
523 // ============================================================================
524 
525 namespace seqan3
526 {
560 template <typename t>
561 SEQAN3_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
typename remove_cvref< t >::type remove_cvref_t
Return the input type with const, volatile and references removed (transformation_trait shortcut).
Definition: type_traits:73
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: aligned_sequence_concept.hpp:29
A type that can be specialised to provide customisation point implementations so that third party typ...
Definition: concept.hpp:49
The identity transformation (a transformation_trait that returns the input).
Definition: type_traits:87
The <type_traits> header from C++20's standard library.