SeqAn3  3.0.1
The Modern C++ library for sequence analysis.
concept.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2020, 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 
34 struct is_pair_open_fn
35 {
36 public:
37  SEQAN3_CPO_IMPL(2, seqan3::custom::alphabet<decltype(v)>::is_pair_open(v)) // explicit customisation
38  SEQAN3_CPO_IMPL(1, is_pair_open(v) ) // ADL
39  SEQAN3_CPO_IMPL(0, v.is_pair_open() ) // member
40 
41 public:
43  template <typename rna_structure_t>
45  requires requires (rna_structure_t const chr) { { impl(priority_tag<2>{}, chr) }; }
47  constexpr auto operator()(rna_structure_t const chr) const noexcept
48  {
49  static_assert(noexcept(impl(priority_tag<2>{}, chr)),
50  "Only overloads that are marked noexcept are picked up by seqan3::is_pair_open().");
51  static_assert(std::same_as<bool, decltype(impl(priority_tag<2>{}, chr))>,
52  "The return type of your is_pair_open() implementation must be 'bool'.");
53 
54  return impl(priority_tag<2>{}, chr);
55  }
56 };
57 
58 } // namespace seqan3::detail::adl_only
59 
60 namespace seqan3
61 {
62 
96 inline constexpr auto is_pair_open = detail::adl_only::is_pair_open_fn{};
98 
99 } // namespace seqan3
100 
101 // ============================================================================
102 // is_pair_close()
103 // ============================================================================
104 
105 namespace seqan3::detail::adl_only
106 {
107 
109 template <typename ...args_t>
110 void is_pair_close(args_t ...) = delete;
111 
113 struct is_pair_close_fn
114 {
115 public:
116  SEQAN3_CPO_IMPL(2, seqan3::custom::alphabet<decltype(v)>::is_pair_close(v)) // explicit customisation
117  SEQAN3_CPO_IMPL(1, is_pair_close(v) ) // ADL
118  SEQAN3_CPO_IMPL(0, v.is_pair_close() ) // member
119 
120 public:
122  template <typename rna_structure_t>
124  requires requires (rna_structure_t const chr) { { impl(priority_tag<2>{}, chr) }; }
126  constexpr auto operator()(rna_structure_t const chr) const noexcept
127  {
128  static_assert(noexcept(impl(priority_tag<2>{}, chr)),
129  "Only overloads that are marked noexcept are picked up by seqan3::is_pair_close().");
130  static_assert(std::same_as<bool, decltype(impl(priority_tag<2>{}, chr))>,
131  "The return type of your is_pair_close() implementation must be 'bool'.");
132 
133  return impl(priority_tag<2>{}, chr);
134  }
135 };
136 
137 } // namespace seqan3::detail::adl_only
138 
139 namespace seqan3
140 {
141 
175 inline constexpr auto is_pair_close = detail::adl_only::is_pair_close_fn{};
177 
178 } // namespace seqan3
179 
180 // ============================================================================
181 // is_unpaired()
182 // ============================================================================
183 
184 namespace seqan3::detail::adl_only
185 {
186 
188 template <typename ...args_t>
189 void is_unpaired(args_t ...) = delete;
190 
192 struct is_unpaired_fn
193 {
194 public:
195  SEQAN3_CPO_IMPL(2, seqan3::custom::alphabet<decltype(v)>::is_unpaired(v)) // explicit customisation
196  SEQAN3_CPO_IMPL(1, is_unpaired(v) ) // ADL
197  SEQAN3_CPO_IMPL(0, v.is_unpaired() ) // member
198 
199 public:
201  template <typename rna_structure_t>
203  requires requires (rna_structure_t const chr) { { impl(priority_tag<2>{}, chr) }; }
205  constexpr auto operator()(rna_structure_t const chr) const noexcept
206  {
207  static_assert(noexcept(impl(priority_tag<2>{}, chr)),
208  "Only overloads that are marked noexcept are picked up by seqan3::is_unpaired().");
209  static_assert(std::same_as<bool, decltype(impl(priority_tag<2>{}, chr))>,
210  "The return type of your is_unpaired() implementation must be 'bool'.");
211 
212  return impl(priority_tag<2>{}, chr);
213  }
214 };
215 
216 } // namespace seqan3::detail::adl_only
217 
218 namespace seqan3
219 {
220 
254 inline constexpr auto is_unpaired = detail::adl_only::is_unpaired_fn{};
256 
257 } // namespace seqan3
258 
259 // ============================================================================
260 // max_pseudoknot_depth
261 // ============================================================================
262 
263 namespace seqan3::detail::adl_only
264 {
265 
267 template <typename ...args_t>
268 void max_pseudoknot_depth(args_t ...) = delete;
269 
275 template <typename alph_t,
277  seqan3::is_constexpr_default_constructible_v<remove_cvref_t<alph_t>>,
278  remove_cvref_t<alph_t>,
280 struct max_pseudoknot_depth_fn
281 {
282 public:
283  SEQAN3_CPO_IMPL(2, (deferred_type_t<seqan3::custom::alphabet<alph_t>, decltype(v)>::max_pseudoknot_depth)) // custom
284  SEQAN3_CPO_IMPL(1, (max_pseudoknot_depth(v) )) // ADL
285  SEQAN3_CPO_IMPL(0, (deferred_type_t<remove_cvref_t<alph_t>, decltype(v)>::max_pseudoknot_depth )) // member
286 
287 public:
289  template <typename dummy = int>
291  requires requires { { impl(priority_tag<2>{}, s_alph_t{}, dummy{}) }; }
293  constexpr auto operator()() const noexcept
294  {
295  static_assert(noexcept(impl(priority_tag<2>{}, s_alph_t{})),
296  "Only overloads that are marked noexcept are picked up by seqan3::max_pseudoknot_depth.");
297  static_assert(std::constructible_from<size_t, decltype(impl(priority_tag<2>{}, s_alph_t{}))>,
298  "The return type of your max_pseudoknot_depth implementation must be convertible to size_t.");
299  static_assert(SEQAN3_IS_CONSTEXPR(impl(priority_tag<2>{}, s_alph_t{})),
300  "Only overloads that are marked constexpr are picked up by seqan3::max_pseudoknot_depth.");
301 
302  return impl(priority_tag<2>{}, s_alph_t{});
303  }
304 };
305 
307 // required to prevent https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89953
308 template <typename alph_t>
309  requires requires { { max_pseudoknot_depth_fn<alph_t>{} }; }
310 inline constexpr auto max_pseudoknot_depth_obj = max_pseudoknot_depth_fn<alph_t>{};
312 
313 } // namespace seqan3::detail::adl_only
314 
315 namespace seqan3
316 {
317 
360 template <typename alph_t>
362  requires requires { { detail::adl_only::max_pseudoknot_depth_fn<alph_t>{} }; } &&
363  requires { { detail::adl_only::max_pseudoknot_depth_obj<alph_t>() }; }
365 inline constexpr auto max_pseudoknot_depth = detail::adl_only::max_pseudoknot_depth_obj<alph_t>();
366 
367 } // namespace seqan3
368 
369 // ============================================================================
370 // pseudoknot_id()
371 // ============================================================================
372 
373 namespace seqan3::detail::adl_only
374 {
375 
377 template <typename ...args_t>
378 void pseudoknot_id(args_t ...) = delete;
379 
381 struct pseudoknot_id_fn
382 {
383 public:
384  SEQAN3_CPO_IMPL(2, seqan3::custom::alphabet<decltype(v)>::pseudoknot_id(v)) // explicit customisation
385  SEQAN3_CPO_IMPL(1, pseudoknot_id(v) ) // ADL
386  SEQAN3_CPO_IMPL(0, v.pseudoknot_id() ) // member
387 
388 public:
390  template <typename rna_structure_t>
392  requires requires (rna_structure_t const chr) { { impl(priority_tag<2>{}, chr) }; }
394  constexpr auto operator()(rna_structure_t const chr) const noexcept
395  {
396  static_assert(noexcept(impl(priority_tag<2>{}, chr)),
397  "Only overloads that are marked noexcept are picked up by seqan3::pseudoknot_id().");
398  static_assert(std::constructible_from<std::optional<size_t>, decltype(impl(priority_tag<2>{}, chr))>,
399  "The return type of your pseudoknot_id() implementation must be convertible to std::optional<size_t>.");
400 
401  return impl(priority_tag<2>{}, chr);
402  }
403 };
404 
405 } // namespace seqan3::detail::adl_only
406 
407 namespace seqan3
408 {
409 
445 inline constexpr auto pseudoknot_id = detail::adl_only::pseudoknot_id_fn{};
447 
448 } // namespace seqan3
449 
450 // ============================================================================
451 // rna_structure_alphabet concept
452 // ============================================================================
453 
454 namespace seqan3
455 {
486 template <typename t>
488 SEQAN3_CONCEPT rna_structure_alphabet = seqan3::alphabet<t> && requires(t val)
489 {
490  { seqan3::is_pair_open(val) };
491  { seqan3::is_pair_close(val) };
492  { seqan3::is_unpaired(val) };
493  { seqan3::pseudoknot_id(val) };
494 
495  // this is delegated to a static class variable, which must not be 0
496  requires seqan3::max_pseudoknot_depth<t> > 0;
497 };
499 
500 } // namespace seqan3
type_traits
Provides C++20 additions to the type_traits header.
seqan3::custom::alphabet
A type that can be specialised to provide customisation point implementations so that third party typ...
Definition: concept.hpp:46
constructible_from
The std::constructible_from concept specifies that a variable of type T can be initialized with the g...
SEQAN3_CPO_IMPL
#define SEQAN3_CPO_IMPL(PRIO, TERM)
A macro that helps defining the overload set of a customisation point.
Definition: customisation_point.hpp:45
concepts
The Concepts library.
same_as
The concept std::same_as<T, U> is satisfied if and only if T and U denote the same type.
rna_structure_alphabet
A concept that indicates whether an alphabet represents RNA structure.
seqan3
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:36
seqan3::pseudoknot_id
constexpr auto pseudoknot_id
Retrieve an id for the level of a pseudoknotted interaction (also known as 'page number').
Definition: concept.hpp:445
seqan3::is_pair_close
constexpr auto is_pair_close
Check whether the given character represents a leftward interaction in an RNA structure.
Definition: concept.hpp:175
SEQAN3_IS_CONSTEXPR
#define SEQAN3_IS_CONSTEXPR(...)
Returns true if the expression passed to this macro can be evaluated at compile time,...
Definition: function.hpp:25
seqan3::is_pair_open
constexpr auto is_pair_open
Check whether the given character represents a rightward interaction in an RNA structure.
Definition: concept.hpp:96
std::type_identity
The identity transformation (a transformation_trait that returns the input).
Definition: type_traits:31
alphabet
The generic alphabet concept that covers most data types used in ranges.
optional
seqan3::max_pseudoknot_depth
constexpr auto max_pseudoknot_depth
A type trait that holds the ability of the structure alphabet to represent pseudoknots,...
Definition: concept.hpp:365
std::conditional_t
seqan3::is_unpaired
constexpr auto is_unpaired
Check whether the given character represents an unpaired nucleotide in an RNA structure.
Definition: concept.hpp:254
concept.hpp
Core alphabet concept and free function/type trait wrappers.
customisation_point.hpp
Helper utilities for defining customisation point objects.