SeqAn3  3.0.0
The Modern C++ library for sequence analysis.
concept.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2019, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2019, 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>
18 #include <seqan3/std/concepts>
19 #include <seqan3/std/type_traits>
20 
21 // ============================================================================
22 // forwards
23 // ============================================================================
24 
26 namespace seqan3::custom
27 {
28 
29 void is_pair_open();
30 void is_pair_close();
31 void is_unpaired();
33 void pseudoknot_id();
34 
35 } // namespace seqan3::custom
37 
38 // ============================================================================
39 // is_pair_open()
40 // ============================================================================
41 
43 {
44 
46 struct is_pair_open_fn
47 {
48 private:
49  SEQAN3_CPO_IMPL(2, is_pair_open(v) ) // ADL
50  SEQAN3_CPO_IMPL(1, seqan3::custom::is_pair_open(v) ) // customisation namespace
51  SEQAN3_CPO_IMPL(0, v.is_pair_open() ) // member
52 
53 public:
55  template <typename rna_structure_t>
57  requires requires (rna_structure_t const chr) { { impl(priority_tag<2>{}, chr) }; }
59  constexpr auto operator()(rna_structure_t const chr) const noexcept
60  {
61  static_assert(noexcept(impl(priority_tag<2>{}, chr)),
62  "Only overloads that are marked noexcept are picked up by seqan3::is_pair_open().");
63  static_assert(std::Same<bool, decltype(impl(priority_tag<2>{}, chr))>,
64  "The return type of your is_pair_open() implementation must be 'bool'.");
65 
66  return impl(priority_tag<2>{}, chr);
67  }
68 };
69 
70 } // namespace seqan3::detail::adl::only
71 
72 namespace seqan3
73 {
74 
110 inline constexpr auto is_pair_open = detail::adl::only::is_pair_open_fn{};
112 
113 } // namespace seqan3
114 
115 // ============================================================================
116 // is_pair_close()
117 // ============================================================================
118 
120 {
121 
123 struct is_pair_close_fn
124 {
125 private:
126  SEQAN3_CPO_IMPL(2, is_pair_close(v) ) // ADL
127  SEQAN3_CPO_IMPL(1, seqan3::custom::is_pair_close(v) ) // customisation namespace
128  SEQAN3_CPO_IMPL(0, v.is_pair_close() ) // member
129 
130 public:
132  template <typename rna_structure_t>
134  requires requires (rna_structure_t const chr) { { impl(priority_tag<2>{}, chr) }; }
136  constexpr auto operator()(rna_structure_t const chr) const noexcept
137  {
138  static_assert(noexcept(impl(priority_tag<2>{}, chr)),
139  "Only overloads that are marked noexcept are picked up by seqan3::is_pair_close().");
140  static_assert(std::Same<bool, decltype(impl(priority_tag<2>{}, chr))>,
141  "The return type of your is_pair_close() implementation must be 'bool'.");
142 
143  return impl(priority_tag<2>{}, chr);
144  }
145 };
146 
147 } // namespace seqan3::detail::adl::only
148 
149 namespace seqan3
150 {
151 
187 inline constexpr auto is_pair_close = detail::adl::only::is_pair_close_fn{};
189 
190 } // namespace seqan3
191 
192 // ============================================================================
193 // is_unpaired()
194 // ============================================================================
195 
197 {
198 
200 struct is_unpaired_fn
201 {
202 private:
203  SEQAN3_CPO_IMPL(2, is_unpaired(v) ) // ADL
204  SEQAN3_CPO_IMPL(1, seqan3::custom::is_unpaired(v) ) // customisation namespace
205  SEQAN3_CPO_IMPL(0, v.is_unpaired() ) // member
206 
207 public:
209  template <typename rna_structure_t>
211  requires requires (rna_structure_t const chr) { { impl(priority_tag<2>{}, chr) }; }
213  constexpr auto operator()(rna_structure_t const chr) const noexcept
214  {
215  static_assert(noexcept(impl(priority_tag<2>{}, chr)),
216  "Only overloads that are marked noexcept are picked up by seqan3::is_unpaired().");
217  static_assert(std::Same<bool, decltype(impl(priority_tag<2>{}, chr))>,
218  "The return type of your is_unpaired() implementation must be 'bool'.");
219 
220  return impl(priority_tag<2>{}, chr);
221  }
222 };
223 
224 } // namespace seqan3::detail::adl::only
225 
226 namespace seqan3
227 {
228 
264 inline constexpr auto is_unpaired = detail::adl::only::is_unpaired_fn{};
266 
267 } // namespace seqan3
268 
269 // ============================================================================
270 // max_pseudoknot_depth
271 // ============================================================================
272 
274 {
275 
281 template <typename alph_t,
283  seqan3::is_constexpr_default_constructible_v<remove_cvref_t<alph_t>>,
284  remove_cvref_t<alph_t>,
286 struct max_pseudoknot_depth_fn
287 {
288 private:
289  SEQAN3_CPO_IMPL(2, (max_pseudoknot_depth(v) )) // ADL
291  SEQAN3_CPO_IMPL(0, (deferred_type_t<remove_cvref_t<alph_t>, decltype(v)>::max_pseudoknot_depth )) // member
292 
293 public:
295  template <typename dummy = int>
297  requires requires { { impl(priority_tag<2>{}, s_alph_t{}, dummy{}) }; }
299  constexpr auto operator()() const noexcept
300  {
301  static_assert(noexcept(impl(priority_tag<2>{}, s_alph_t{})),
302  "Only overloads that are marked noexcept are picked up by seqan3::max_pseudoknot_depth.");
303  static_assert(std::Constructible<size_t, decltype(impl(priority_tag<2>{}, s_alph_t{}))>,
304  "The return type of your max_pseudoknot_depth implementation must be convertible to size_t.");
305  static_assert(SEQAN3_IS_CONSTEXPR(impl(priority_tag<2>{}, s_alph_t{})),
306  "Only overloads that are marked constexpr are picked up by seqan3::max_pseudoknot_depth.");
307 
308  return impl(priority_tag<2>{}, s_alph_t{});
309  }
310 };
311 
313 // required to prevent https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89953
314 template <typename alph_t>
315  requires requires { { max_pseudoknot_depth_fn<alph_t>{} }; }
316 inline constexpr auto max_pseudoknot_depth_obj = max_pseudoknot_depth_fn<alph_t>{};
318 
319 } // namespace seqan3::detail::adl::only
320 
321 namespace seqan3
322 {
323 
365 template <typename alph_t>
367  requires requires { { detail::adl::only::max_pseudoknot_depth_fn<alph_t>{} }; } &&
368  requires { { detail::adl::only::max_pseudoknot_depth_obj<alph_t>() }; }
370 inline constexpr auto max_pseudoknot_depth = detail::adl::only::max_pseudoknot_depth_obj<alph_t>();
371 
372 } // namespace seqan3
373 
374 // ============================================================================
375 // pseudoknot_id()
376 // ============================================================================
377 
379 {
380 
382 struct pseudoknot_id_fn
383 {
384 private:
385  SEQAN3_CPO_IMPL(2, pseudoknot_id(v) ) // ADL
386  SEQAN3_CPO_IMPL(1, seqan3::custom::pseudoknot_id(v) ) // customisation namespace
387  SEQAN3_CPO_IMPL(0, v.pseudoknot_id() ) // member
388 
389 public:
391  template <typename rna_structure_t>
393  requires requires (rna_structure_t const chr) { { impl(priority_tag<2>{}, chr) }; }
395  constexpr auto operator()(rna_structure_t const chr) const noexcept
396  {
397  static_assert(noexcept(impl(priority_tag<2>{}, chr)),
398  "Only overloads that are marked noexcept are picked up by seqan3::pseudoknot_id().");
399  static_assert(std::Constructible<std::optional<size_t>, decltype(impl(priority_tag<2>{}, chr))>,
400  "The return type of your pseudoknot_id() implementation must be convertible to std::optional<size_t>.");
401 
402  return impl(priority_tag<2>{}, chr);
403  }
404 };
405 
406 } // namespace seqan3::detail::adl::only
407 
408 namespace seqan3
409 {
410 
448 inline constexpr auto pseudoknot_id = detail::adl::only::pseudoknot_id_fn{};
450 
451 } // namespace seqan3
452 
453 // ============================================================================
454 // RnaStructureAlphabet concept
455 // ============================================================================
456 
457 namespace seqan3
458 {
489 template <typename t>
491 SEQAN3_CONCEPT RnaStructureAlphabet = seqan3::Alphabet<t> && requires(t val)
492 {
493  { seqan3::is_pair_open(val) };
494  { seqan3::is_pair_close(val) };
495  { seqan3::is_unpaired(val) };
496  { seqan3::pseudoknot_id(val) };
497 
498  // this is delegated to a static class variable, which must not be 0
499  requires seqan3::max_pseudoknot_depth<t> > 0;
500 };
502 
503 } // namespace seqan3
The generic alphabet concept that covers most data types used in ranges.
#define SEQAN3_CPO_IMPL(PRIO, TERM)
A macro that helps defining the overload set of a customisation point.
Definition: customisation_point.hpp:45
Definition: concept.hpp:32
The main SeqAn3 namespace.
#define SEQAN3_IS_CONSTEXPR(...)
Returns true if the expression passed to this macro can be evaluated at compile time, false otherwise.
Definition: function.hpp:25
The Concepts library.
Helper utilities for defining customisation point objects.
constexpr auto pseudoknot_id
Retrieve an id for the level of a pseudoknotted interaction (also known as &#39;page number&#39;).
Definition: concept.hpp:448
constexpr auto is_pair_close
Check whether the given character represents a leftward interaction in an RNA structure.
Definition: concept.hpp:187
constexpr auto is_pair_open
Check whether the given character represents a rightward interaction in an RNA structure.
Definition: concept.hpp:110
The std::Constructible concept specifies that a variable of type T can be initialized with the given ...
Provides C++20 additions to the type_traits header.
constexpr auto max_pseudoknot_depth
A type trait that holds the ability of the structure alphabet to represent pseudoknots, i.e. crossing interactions, up to a certain depth.
Definition: concept.hpp:370
The identity transformation (a TransformationTrait that returns the input).
Definition: type_traits:30
Core alphabet concept and free function/type trait wrappers.
A namespace for third party and standard library specialisations of SeqAn customisation points...
Definition: char.hpp:47
The concept std::Same<T, U> is satisfied if and only if T and U denote the same type.
constexpr auto is_unpaired
Check whether the given character represents an unpaired nucleotide in an RNA structure.
Definition: concept.hpp:264