Nektar++
traits.hpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File: traits.hpp
4 //
5 // For more information, please see: http://www.nektar.info
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining a
14 // copy of this software and associated documentation files (the "Software"),
15 // to deal in the Software without restriction, including without limitation
16 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 // and/or sell copies of the Software, and to permit persons to whom the
18 // Software is furnished to do so, subject to the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be included
21 // in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 // DEALINGS IN THE SOFTWARE.
30 //
31 // Description: Vector type traits and tags.
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
35 #ifndef NEKTAR_LIB_LIBUTILITES_SIMDLIB_TRAITS_H
36 #define NEKTAR_LIB_LIBUTILITES_SIMDLIB_TRAITS_H
37 
38 #include <type_traits>
39 
40 namespace tinysimd
41 {
42 
43 // Load tags
44 static constexpr struct is_aligned_t
45 {
47 static constexpr struct is_not_aligned_t
48 {
50 static constexpr struct is_not_reused_t
51 {
52 } is_not_reused{}; // streaming, skip cache
53 
54 // Check load tags
55 template <class T>
57  : std::integral_constant<
58  bool,
59  std::is_same<is_aligned_t, typename std::remove_cv<T>::type>::value ||
60  std::is_same<is_not_aligned_t,
61  typename std::remove_cv<T>::type>::value ||
62  std::is_same<is_not_reused_t,
63  typename std::remove_cv<T>::type>::value>
64 {
65 };
66 
67 template <class T>
69  : std::integral_constant<
70  bool, std::is_same<is_not_reused_t,
71  typename std::remove_cv<T>::type>::value>
72 {
73 };
74 
75 template <class T>
77  : std::integral_constant<
78  bool,
79  std::is_same<is_aligned_t, typename std::remove_cv<T>::type>::value ||
80  is_streaming<T>::value>
81 {
82 };
83 
84 // Helper c++17 style
85 // template <class T>
86 // inline constexpr bool is_load_tag_v = is_load_tag<T>::value;
87 // template <class T>
88 // inline constexpr bool is_streaming_v = is_streaming<T>::value;
89 // template <class T>
90 // inline constexpr bool is_requiring_alignment_v =
91 // is_requiring_alignment<T>::value;
92 
93 namespace details
94 {
95 // has width type primary template
96 template <class T, class U = unsigned int> struct has_width : std::false_type
97 {
98 };
99 // Specialization for U = unsigned int
100 template <class T>
101 struct has_width<T, decltype((void)T::width, 0u)> : std::true_type
102 {
103 };
104 
105 // has alignment type primary template
106 template <class T, class U = unsigned int>
107 struct has_alignment : std::false_type
108 {
109 };
110 // Specialization for U = unsigned int
111 template <class T>
112 struct has_alignment<T, decltype((void)T::alignment, 0u)> : std::true_type
113 {
114 };
115 
116 // Patch for missing std::void_t in pre C++17 compilers
117 template <class... Ts> struct make_void
118 {
119  typedef void type;
120 };
121 template <class... Ts> using void_t = typename make_void<Ts...>::type;
122 
123 // Generic template handles types that have no nested ::scalarType member:
124 template <class, class = void_t<>> struct has_scalarType : std::false_type
125 {
126 };
127 // Specialization recognizes types that do have a nested ::scalarType member:
128 template <class T>
129 struct has_scalarType<T, void_t<typename T::scalarType>> : std::true_type
130 {
131 };
132 } // namespace details
133 
134 // If it quacks...
135 template <class T>
136 struct is_vector
137  : std::integral_constant<bool, details::has_alignment<T>::value &&
138  details::has_width<T>::value &&
139  details::has_scalarType<T>::value>
140 {
141 };
142 
143 // Helper c++17 style
144 // template <class T>
145 // inline constexpr bool is_vector_v = is_vector<T>::value;
146 
147 // Generic template handles cases that are not vector type
148 template <class T, class = void>
149 struct is_vector_floating_point : std::false_type
150 {
151 };
152 
153 // Specialized template handles cases that are vector types
154 template <class T>
156  T, typename std::enable_if<is_vector<T>::value>::type>
157  : std::integral_constant<
158  bool, std::is_floating_point<typename T::scalarType>::value>
159 {
160 };
161 
162 // Helper c++17 style
163 // template <class T>
164 // inline constexpr bool is_vector_floating_point_v =
165 // is_vector_floating_point<T>::value;
166 
167 // Generic template handles cases that are not vector type
168 template <class T, class = void> struct is_vector_integral : std::false_type
169 {
170 };
171 
172 // Specialized template handles cases that are vector types
173 template <class T>
174 struct is_vector_integral<T, typename std::enable_if<is_vector<T>::value>::type>
175  : std::integral_constant<bool,
176  std::is_integral<typename T::scalarType>::value>
177 {
178 };
179 
180 // Helper c++17 style
181 // template <class T>
182 // inline constexpr bool is_vector_floating_point_v =
183 // is_vector_floating_point<T>::value;
184 
185 } // namespace tinysimd
186 
187 #endif
typename make_void< Ts... >::type void_t
Definition: traits.hpp:121
static constexpr struct tinysimd::is_aligned_t is_aligned
static constexpr struct tinysimd::is_not_aligned_t is_not_aligned
static constexpr struct tinysimd::is_not_reused_t is_not_reused