SeqAn3 3.2.0
The Modern C++ library for sequence analysis.
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
20namespace seqan3::detail
21{
23template <template <typename> typename rebind>
24struct 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>;
34template <typename simd_t>
35concept 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
101namespace seqan3
102{
103
104inline namespace simd
105{
106
121template <typename simd_t>
122concept simd_concept = !
123std::is_pointer_v<std::decay_t<simd_t>> && detail::simd_concept<simd_t>;
125
135template <typename t>
136concept 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 main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
Provides seqan3::simd::simd_traits.