SeqAn3  3.2.0-rc.1
The Modern C++ library for sequence analysis.
utility/simd/concept.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2022, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2022, 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 <concepts>
16 #include <type_traits>
17 
19 
20 namespace seqan3::detail
21 {
23 template <template <typename> typename rebind>
24 struct simd_traits_has_rebind : std::true_type
25 {};
26 // NOTE: this definition should be used for seqan3::simd, but gcc has a bug that it will not fail silently if
27 // simd_t is a pointer to a incomplete type. Furthermore the is_pointer_v should prevent those cases by checking the type
28 // beforehand, but for some reasons the short-circuit semantic of `&&` does not work in this case and gcc still evaluates
29 // the requires clause which in turn triggers the error.
30 //
31 // If this concept is used directly on incomplete types it will produces this compiler error:
32 // error: invalid use of incomplete type ‘struct incomplete::template_type<int>’
33 // requires std::same_as<decltype(a - b), simd_t>;
34 template <typename simd_t>
35 concept simd_concept =
36  requires (simd_t a, simd_t b) {
37  typename simd_traits<std::remove_reference_t<simd_t>>::scalar_type;
38  typename simd_traits<std::remove_reference_t<simd_t>>::mask_type;
39  typename simd_traits<std::remove_reference_t<simd_t>>::swizzle_type;
40  requires simd_traits_has_rebind<simd_traits<std::remove_reference_t<simd_t>>::template rebind>::value;
41 
42  // require that static member variables are defined
43  requires std::integral<decltype(simd_traits<std::remove_reference_t<simd_t>>::length)>;
44  requires std::integral<decltype(simd_traits<std::remove_reference_t<simd_t>>::max_length)>;
45 
46  // assume array access that returns a scalar_type type
47  {
48  a[0]
49  } -> std::convertible_to<typename simd_traits<std::remove_reference_t<simd_t>>::scalar_type>;
50 
51  // require comparison operators
52  {
53  a == b
54  } -> std::same_as<typename simd_traits<std::remove_reference_t<simd_t>>::mask_type>;
55  {
56  a != b
57  } -> std::same_as<typename simd_traits<std::remove_reference_t<simd_t>>::mask_type>;
58  {
59  a < b
60  } -> std::same_as<typename simd_traits<std::remove_reference_t<simd_t>>::mask_type>;
61  {
62  a > b
63  } -> std::same_as<typename simd_traits<std::remove_reference_t<simd_t>>::mask_type>;
64  {
65  a <= b
66  } -> std::same_as<typename simd_traits<std::remove_reference_t<simd_t>>::mask_type>;
67  {
68  a >= b
69  } -> std::same_as<typename simd_traits<std::remove_reference_t<simd_t>>::mask_type>;
70 
71  // require arithmetic operators
72  {
73  a + b
74  } -> std::same_as<std::remove_reference_t<simd_t>>;
75  {
76  a - b
77  } -> std::same_as<std::remove_reference_t<simd_t>>;
78  {
79  a * b
80  } -> std::same_as<std::remove_reference_t<simd_t>>;
81  {
82  a / b
83  } -> std::same_as<std::remove_reference_t<simd_t>>;
84  {
85  a += b
86  } -> std::same_as<std::remove_reference_t<simd_t> &>;
87  {
88  a -= b
89  } -> std::same_as<std::remove_reference_t<simd_t> &>;
90  {
91  a *= b
92  } -> std::same_as<std::remove_reference_t<simd_t> &>;
93  {
94  a /= b
95  } -> std::same_as<std::remove_reference_t<simd_t> &>;
96  };
98 
99 } // namespace seqan3::detail
100 
101 namespace seqan3
102 {
103 
104 inline namespace simd
105 {
106 
121 template <typename simd_t>
122 concept simd_concept = !
123 std::is_pointer_v<std::decay_t<simd_t>> && detail::simd_concept<simd_t>;
125 
135 template <typename t>
136 concept simd_index =
137  simd::simd_concept<t>
138  && requires () { requires std::integral<typename simd_traits<std::remove_reference_t<t>>::scalar_type>; };
140 
141 } // namespace simd
142 
143 } // namespace seqan3
The <concepts> header from C++20's standard library.
requires requires
The rank_type of the semi-alphabet; defined as the return type of seqan3::to_rank....
Definition: alphabet/concept.hpp:164
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
Provides seqan3::simd::simd_traits.