1/* Copyright (C) 2014 Povilas Kanapickas <povilas@radix.lt>
2
3 Distributed under the Boost Software License, Version 1.0.
4 (See accompanying file LICENSE_1_0.txt or copy at
5 http://www.boost.org/LICENSE_1_0.txt)
6*/
7
8#ifndef LIBSIMDPP_SIMD_TYPES_GENERIC_H
9#define LIBSIMDPP_SIMD_TYPES_GENERIC_H
10
11#include <simdpp/setup_arch.h>
12#include <simdpp/types.h>
13#include <type_traits>
14
15namespace simdpp {
16namespace SIMDPP_ARCH_NAMESPACE {
17
18// -----------------------------------------------------------------------------
19
20/*
21 Note: the name of the expression vector type only identifies the target
22 type. In various cases we want to change the target type, thus the arbitrary
23 conversions have been added.
24
25 Expression types are not meant to be used by the user, thus all constructors
26 are implicit.
27*/
28
29// -----------------------------------------------------------------------------
30// float32
31
32template<unsigned N, class E>
33class float32 : public any_float32<N, float32<N,E>>{
34public:
35 static const unsigned type_tag = SIMDPP_TAG_FLOAT;
36 using expr_type = E;
37 E e;
38
39 SIMDPP_INL float32(const E& a) : e(a) {}
40 template<template<unsigned, class> class V, unsigned N2> SIMDPP_INL
41 float32(const any_vec<N*4,V<N2,E>>& a) : e(a.wrapped().e) {}
42
43 SIMDPP_INL operator float32<N>() const { return eval(); }
44 SIMDPP_INL float32<N> eval() const
45 { return detail::expr_eval_wrapper<float32<N>, expr_type>::eval(e); }
46};
47
48template<unsigned N, class E>
49class mask_float32 : public any_float32<N, mask_float32<N,E>> {
50public:
51 static const unsigned type_tag = SIMDPP_TAG_MASK_FLOAT;
52 using expr_type = E;
53 E e;
54
55 SIMDPP_INL mask_float32(const E& a) : e(a) {}
56
57 SIMDPP_INL operator mask_float32<N>() const { return eval(); }
58 SIMDPP_INL operator float32<N>() const { return eval(); }
59 SIMDPP_INL mask_float32<N> eval() const
60 { return detail::expr_eval_wrapper<mask_float32<N>, expr_type>::eval(e); }
61};
62
63// -----------------------------------------------------------------------------
64// float64
65
66template<unsigned N, class E>
67class float64 : public any_float64<N, float64<N,E>> {
68public:
69 static const unsigned type_tag = SIMDPP_TAG_FLOAT;
70 using expr_type = E;
71 E e;
72
73 SIMDPP_INL float64(const E& a) : e(a) {}
74 template<template<unsigned, class> class V, unsigned N2> SIMDPP_INL
75 float64(const any_vec<N*8,V<N2,E>>& a) : e(a.wrapped().e) {}
76
77 SIMDPP_INL operator float64<N>() const { return eval(); }
78 SIMDPP_INL float64<N> eval() const
79 { return detail::expr_eval_wrapper<float64<N>, expr_type>::eval(e); }
80};
81
82template<unsigned N, class E>
83class mask_float64 : public any_float64<N, mask_float64<N,E>> {
84public:
85 static const unsigned type_tag = SIMDPP_TAG_MASK_FLOAT;
86 using expr_type = E;
87 E e;
88
89 SIMDPP_INL mask_float64(const E& a) : e(a) {}
90
91 SIMDPP_INL operator mask_float64<N>() const { return eval(); }
92 SIMDPP_INL operator float64<N>() const { return eval(); }
93 SIMDPP_INL mask_float64<N> eval() const
94 { return detail::expr_eval_wrapper<mask_float64<N>, expr_type>::eval(e); }
95};
96
97// -----------------------------------------------------------------------------
98// uint8<N>
99template<unsigned N, class E>
100class int8 : public any_int8<N, int8<N,E>> {
101public:
102 static const unsigned type_tag = SIMDPP_TAG_INT;
103 using expr_type = E;
104 E e;
105
106 SIMDPP_INL int8(const E& a) : e(a) {}
107
108 template<template<unsigned, class> class V, unsigned N2> SIMDPP_INL
109 int8(const any_vec<N,V<N2,E>>& a) : e(a.wrapped().e) {}
110
111 SIMDPP_INL operator int8<N>() const { return eval(); }
112 SIMDPP_INL int8<N> eval() const
113 { return detail::expr_eval_wrapper<int8<N>, expr_type>::eval(e); }
114};
115
116
117template<unsigned N, class E>
118class uint8 : public any_int8<N, uint8<N,E>> {
119public:
120 static const unsigned type_tag = SIMDPP_TAG_UINT;
121 using expr_type = E;
122 E e;
123
124 SIMDPP_INL uint8(const E& a) : e(a) {}
125
126 template<template<unsigned, class> class V, unsigned N2> SIMDPP_INL
127 uint8(const any_vec<N,V<N2,E>>& a) : e(a.wrapped().e) {}
128
129 SIMDPP_INL operator uint8<N>() const { return eval(); }
130 SIMDPP_INL uint8<N> eval() const
131 { return detail::expr_eval_wrapper<uint8<N>, expr_type>::eval(e); }
132};
133
134template<unsigned N, class E>
135class mask_int8 : public any_int8<N, mask_int8<N,E>> {
136public:
137 static const unsigned type_tag = SIMDPP_TAG_MASK_INT;
138 using expr_type = E;
139 E e;
140
141 SIMDPP_INL mask_int8(const E& a) : e(a) {}
142
143 SIMDPP_INL operator mask_int8<N>() const { return eval(); }
144 SIMDPP_INL operator uint8<N>() const { return eval(); }
145 SIMDPP_INL mask_int8<N> eval() const
146 { return detail::expr_eval_wrapper<mask_int8<N>, expr_type>::eval(e); }
147};
148
149// -----------------------------------------------------------------------------
150// uint16<N>
151template<unsigned N, class E>
152class int16 : public any_int16<N, int16<N,E>> {
153public:
154 static const unsigned type_tag = SIMDPP_TAG_INT;
155 using expr_type = E;
156 E e;
157
158 SIMDPP_INL int16(const E& a) : e(a) {}
159 template<template<unsigned, class> class V, unsigned N2> SIMDPP_INL
160 int16(const any_vec<N*2,V<N2,E>>& a) : e(a.wrapped().e) {}
161
162 SIMDPP_INL operator int16<N>() const { return eval(); }
163 SIMDPP_INL int16<N> eval() const
164 { return detail::expr_eval_wrapper<int16<N>, expr_type>::eval(e); }
165};
166
167
168template<unsigned N, class E>
169class uint16 : public any_int16<N, uint16<N,E>> {
170public:
171 static const unsigned type_tag = SIMDPP_TAG_UINT;
172 using expr_type = E;
173 E e;
174
175 SIMDPP_INL uint16(const E& a) : e(a) {}
176 template<template<unsigned, class> class V, unsigned N2> SIMDPP_INL
177 uint16(const any_vec<N*2,V<N2,E>>& a) : e(a.wrapped().e) {}
178
179 SIMDPP_INL operator uint16<N>() const { return eval(); }
180 SIMDPP_INL uint16<N> eval() const
181 { return detail::expr_eval_wrapper<uint16<N>, expr_type>::eval(e); }
182};
183
184template<unsigned N, class E>
185class mask_int16 : public any_int16<N, mask_int16<N,E>> {
186public:
187 static const unsigned type_tag = SIMDPP_TAG_MASK_INT;
188 using expr_type = E;
189 E e;
190
191 SIMDPP_INL mask_int16(const E& a) : e(a) {}
192
193 SIMDPP_INL operator mask_int16<N>() const { return eval(); }
194 SIMDPP_INL operator uint16<N>() const { return eval(); }
195 SIMDPP_INL mask_int16<N> eval() const
196 { return detail::expr_eval_wrapper<mask_int16<N>, expr_type>::eval(e); }
197};
198
199// -----------------------------------------------------------------------------
200// uint32<N>
201template<unsigned N, class E>
202class int32 : public any_int32<N, int32<N,E>> {
203public:
204 static const unsigned type_tag = SIMDPP_TAG_INT;
205 using expr_type = E;
206 E e;
207
208 SIMDPP_INL int32(const E& a) : e(a) {}
209 template<template<unsigned, class> class V, unsigned N2> SIMDPP_INL
210 int32(const any_vec<N*4,V<N2,E>>& a) : e(a.wrapped().e) {}
211
212 SIMDPP_INL operator int32<N>() const { return eval(); }
213 SIMDPP_INL int32<N> eval() const
214 { return detail::expr_eval_wrapper<int32<N>, expr_type>::eval(e); }
215};
216
217
218template<unsigned N, class E>
219class uint32 : public any_int32<N, uint32<N,E>> {
220public:
221 static const unsigned type_tag = SIMDPP_TAG_UINT;
222 using expr_type = E;
223 E e;
224
225 SIMDPP_INL uint32(const E& a) : e(a) {}
226 template<template<unsigned, class> class V, unsigned N2> SIMDPP_INL
227 uint32(const any_vec<N*4,V<N2,E>>& a) : e(a.wrapped().e) {}
228
229 SIMDPP_INL operator uint32<N>() const { return eval(); }
230 SIMDPP_INL uint32<N> eval() const
231 { return detail::expr_eval_wrapper<uint32<N>, expr_type>::eval(e); }
232};
233
234template<unsigned N, class E>
235class mask_int32 : public any_int32<N, mask_int32<N,E>> {
236public:
237 static const unsigned type_tag = SIMDPP_TAG_MASK_INT;
238 using expr_type = E;
239 E e;
240
241 SIMDPP_INL mask_int32(const E& a) : e(a) {}
242
243 SIMDPP_INL operator mask_int32<N>() const { return eval(); }
244 SIMDPP_INL operator uint32<N>() const { return eval(); }
245 SIMDPP_INL mask_int32<N> eval() const
246 { return detail::expr_eval_wrapper<mask_int32<N>, expr_type>::eval(e); }
247};
248
249// -----------------------------------------------------------------------------
250// int64<N>
251
252template<unsigned N, class E>
253class int64 : public any_int64<N, int64<N,E>> {
254public:
255 static const unsigned type_tag = SIMDPP_TAG_INT;
256 using expr_type = E;
257 E e;
258
259 SIMDPP_INL int64(const E& a) : e(a) {}
260 template<template<unsigned, class> class V, unsigned N2> SIMDPP_INL
261 int64(const any_vec<N*8,V<N2,E>>& a) : e(a.wrapped().e) {}
262
263 SIMDPP_INL operator int64<N>() const { return eval(); }
264 SIMDPP_INL int64<N> eval() const
265 { return detail::expr_eval_wrapper<int64<N>, expr_type>::eval(e); }
266};
267
268
269template<unsigned N, class E>
270class uint64 : public any_int64<N, uint64<N,E>> {
271public:
272 static const unsigned type_tag = SIMDPP_TAG_UINT;
273 using expr_type = E;
274 E e;
275
276 SIMDPP_INL uint64(const E& a) : e(a) {}
277 template<template<unsigned, class> class V, unsigned N2> SIMDPP_INL
278 uint64(const any_vec<N*8,V<N2,E>>& a) : e(a.wrapped().e) {}
279
280 SIMDPP_INL operator uint64<N>() const { return eval(); }
281 SIMDPP_INL uint64<N> eval() const
282 { return detail::expr_eval_wrapper<uint64<N>, expr_type>::eval(e); }
283};
284
285
286template<unsigned N, class E>
287class mask_int64 : public any_int64<N, mask_int64<N,E>> {
288public:
289 static const unsigned type_tag = SIMDPP_TAG_MASK_INT;
290 using expr_type = E;
291 E e;
292
293 SIMDPP_INL mask_int64(const E& a) : e(a) {}
294
295 SIMDPP_INL operator mask_int64<N>() const { return eval(); }
296 SIMDPP_INL operator uint64<N>() const { return eval(); }
297 SIMDPP_INL mask_int64<N> eval() const
298 { return detail::expr_eval_wrapper<mask_int64<N>, expr_type>::eval(e); }
299};
300
301} // namespace SIMDPP_ARCH_NAMESPACE
302} // namespace simdpp
303
304#endif
305
306