1 /*
2 * Copyright (c) 2017, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file cm_type.h
24 //! \brief Contains CM related type definitions
25 //!
26
27 #include <assert.h>
28 #include <iostream>
29 #include <string>
30 #include <string.h>
31 #include <stddef.h> //offsetof()
32 #include <limits>
33 #include <limits.h>
34 #include <stdlib.h>
35
36 #ifdef CM_DEBUG
37 #include <sstream>
38 #endif /* CM_DEBUG */
39
40 #define OBJ_COUNTER 0
41
42 #ifdef CM_GENX
43 #define OFFSET ushort
44 #else
45 #define OFFSET uint
46 #endif /* CM_GENX */
47
48 #ifndef CM_TYPES_H
49 #define CM_TYPES_H
50
51 #define CM_KERNEL_FUNCTION(...) CM_KERNEL_FUNCTION2(__VA_ARGS__)
52 #define CM_KERNEL_FUNCTION2(...) #__VA_ARGS__
53
54 namespace CMRT_UMD {
55
56 typedef unsigned int uint;
57 typedef unsigned short ushort;
58 typedef unsigned char uchar;
59
60 #ifndef __int8
61 typedef char __int8;
62 #endif
63
64 #ifndef __int16
65 typedef short __int16;
66 #endif
67
68 #ifndef __int32
69 typedef int __int32;
70 #endif
71
72 #ifndef __int64
73 typedef long long __int64;
74 #endif
75
76 #ifndef __uint64
77 typedef unsigned long long __uint64;
78 #endif
79
80 #if !defined(__CLANG_CM)
81 #include <stdint.h>
82 #else
83 typedef signed __int8 int8_t;
84 typedef signed __int16 int16_t;
85 typedef signed __int32 int32_t;
86 typedef signed __int64 int64_t;
87 typedef unsigned __int8 uint8_t;
88 typedef unsigned __int16 uint16_t;
89 typedef unsigned __int32 uint32_t;
90 typedef unsigned __int64 uint64_t;
91 #endif
92
93
94 #define SAT 1
95
96 typedef enum _CmAtomicOpType_
97 {
98 ATOMIC_ADD = 0x0,
99 ATOMIC_SUB = 0x1,
100 ATOMIC_INC = 0x2,
101 ATOMIC_DEC = 0x3,
102 ATOMIC_MIN = 0x4,
103 ATOMIC_MAX = 0x5,
104 ATOMIC_XCHG = 0x6,
105 ATOMIC_CMPXCHG = 0x7,
106 ATOMIC_AND = 0x8,
107 ATOMIC_OR = 0x9,
108 ATOMIC_XOR = 0xa,
109 ATOMIC_MINSINT = 0xb,
110 ATOMIC_MAXSINT = 0xc
111 } CmAtomicOpType;
112
113
114 typedef enum _ChannelMaskType_
115 { CM_R_ENABLE = 1,
116 CM_G_ENABLE = 2,
117 CM_GR_ENABLE = 3,
118 CM_B_ENABLE = 4,
119 CM_BR_ENABLE = 5,
120 CM_BG_ENABLE = 6,
121 CM_BGR_ENABLE = 7,
122 CM_A_ENABLE = 8,
123 CM_AR_ENABLE = 9,
124 CM_AG_ENABLE = 10,
125 CM_AGR_ENABLE = 11,
126 CM_AB_ENABLE = 12,
127 CM_ABR_ENABLE = 13,
128 CM_ABG_ENABLE = 14,
129 CM_ABGR_ENABLE = 15
130 } ChannelMaskType;
131
132 // Moved from cm_sampler8x8.h as now used in cm_sampler.h as well
133 typedef enum _OutputFormatControl_
134 { CM_16_FULL = 0,
135 CM_16_DOWN_SAMPLE = 1,
136 CM_8_FULL = 2,
137 CM_8_DOWN_SAMPLE = 3
138 } OutputFormatControl;
139
140 typedef enum _CmRoundingMode_
141 {
142 // These values are stored pre-shifted to remove the need to shift the values when applying to
143 // the control word
144 CM_RTE = 0, // Round to nearest or even
145 CM_RTP = 1 << 4, // Round towards +ve inf
146 CM_RTN = 2 << 4, // Round towards -ve inf
147 CM_RTZ = 3 << 4 // Round towards zero
148 } CmRoundingMode;
149
150 typedef enum _CmFPMode_
151 {
152 CM_IEEE = 0,
153 CM_ALT = 1
154 } CmFPMode;
155
156
157 namespace CmEmulSys
158 {
159
160 static long long
abs(long long a)161 abs(long long a)
162 {
163 if (a < 0) {
164 return -a;
165 } else {
166 return a;
167 }
168 }
169
170 template<typename RT>
171 struct satur {
172 template<typename T> static RT
saturatesatur173 saturate(const T val, const int flags) {
174 if ((flags & SAT) == 0) {
175 return (RT) val;
176 }
177
178 #pragma push_macro("max")
179 #pragma push_macro("min")
180
181 #ifdef max
182 #undef max
183 #undef min
184 #endif
185 const RT t_max = std::numeric_limits<RT>::max();
186 const RT t_min = std::numeric_limits<RT>::min();
187
188
189 if (val > t_max) {
190 return t_max;
191 } else if ((val >= 0 ) && (t_min < 0)) {
192 // RT is "signed" if t_min < 0
193 // when comparing a signed and a unsigned variable, the signed one cast to unsigned first.
194 return (RT) val;
195 } else if (val < t_min) {
196 return t_min;
197 } else {
198 return (RT) val;
199 }
200
201 #pragma pop_macro("min")
202 #pragma pop_macro("max")
203 }
204 };
205
206
207 template<>
208 struct satur<float> {
209 template<typename T> static float
210 saturate(const T val, const int flags) {
211 if ((flags & SAT) == 0) {
212 return (float) val;
213 }
214
215 if (val < 0.) {
216 return 0;
217 } else if (val > 1.) {
218 return 1.;
219 } else {
220 return (float) val;
221 }
222 }
223 };
224
225 template<>
226 struct satur<double> {
227 template<typename T> static double
228 saturate(const T val, const int flags) {
229 if ((flags & SAT) == 0) {
230 return (double) val;
231 }
232
233 if (val < 0.) {
234 return 0;
235 } else if (val > 1.) {
236 return 1.;
237 } else {
238 return (double) val;
239 }
240 }
241 };
242
243 template<typename T1, bool B> struct _SetSatur {
244 static uint SetSatur() {
245 return 0;
246 }
247 };
248
249 template <> struct _SetSatur<float, true> {
250 static uint SetSatur() {
251 return SAT;
252 }
253 };
254
255 template <> struct _SetSatur<double, true> {
256 static uint SetSatur() {
257 return SAT;
258 }
259 };
260
261 } /* ::CmEmulSys */
262
263 template <typename T1, typename T2> struct restype {
264 private:
265 restype();
266 };
267
268 //#if defined(CM_NOCONV) || defined(CM_NONSTRICT)
269 #if defined(CM_NOCONV)
270
271 template <> struct restype<char, char> { typedef short type; };
272 template <> struct restype<char, unsigned char> { typedef short type; };
273 template <> struct restype<char, short> { typedef short type; };
274 template <> struct restype<char, unsigned short> { typedef short type; };
275 template <> struct restype<char, int> { typedef int type; };
276 template <> struct restype<char, unsigned int> { typedef int type; };
277 template <> struct restype<char, float> { typedef float type; };
278 template <> struct restype<char, double> { typedef double type; };
279 template <> struct restype<char, long long> { typedef long long type; };
280 template <> struct restype<char, unsigned long long> { typedef long long type; };
281
282 template <> struct restype<unsigned char, char> { typedef short type; };
283 template <> struct restype<unsigned char, unsigned char> { typedef short type; };
284 template <> struct restype<unsigned char, short> { typedef short type; };
285 template <> struct restype<unsigned char, unsigned short> { typedef short type; };
286 template <> struct restype<unsigned char, int> { typedef int type; };
287 template <> struct restype<unsigned char, unsigned int> { typedef int type; };
288 template <> struct restype<unsigned char, float> { typedef float type; };
289 template <> struct restype<unsigned char, double> { typedef double type; };
290 template <> struct restype<unsigned char, long long> { typedef long long type; };
291 template <> struct restype<unsigned char, unsigned long long> { typedef long long type; };
292
293 template <> struct restype<short, char> { typedef short type; };
294 template <> struct restype<short, unsigned char> { typedef short type; };
295 template <> struct restype<short, short> { typedef short type; };
296 template <> struct restype<short, unsigned short> { typedef short type; };
297 template <> struct restype<short, int> { typedef int type; };
298 template <> struct restype<short, unsigned int> { typedef int type; };
299 template <> struct restype<short, float> { typedef float type; };
300 template <> struct restype<short, double> { typedef double type; };
301 template <> struct restype<short, long long> { typedef long long type; };
302 template <> struct restype<short, unsigned long long> { typedef long long type; };
303
304 template <> struct restype<unsigned short, char> { typedef short type; };
305 template <> struct restype<unsigned short, unsigned char> { typedef short type; };
306 template <> struct restype<unsigned short, short> { typedef short type; };
307 template <> struct restype<unsigned short, unsigned short> { typedef short type; };
308 template <> struct restype<unsigned short, int> { typedef int type; };
309 template <> struct restype<unsigned short, unsigned int> { typedef int type; };
310 template <> struct restype<unsigned short, float> { typedef float type; };
311 template <> struct restype<unsigned short, double> { typedef double type; };
312 template <> struct restype<unsigned short, long long> { typedef long long type; };
313 template <> struct restype<unsigned short, unsigned long long> { typedef long long type; };
314
315 template <> struct restype<int, char> { typedef int type; };
316 template <> struct restype<int, unsigned char> { typedef int type; };
317 template <> struct restype<int, short> { typedef int type; };
318 template <> struct restype<int, unsigned short> { typedef int type; };
319 template <> struct restype<int, int> { typedef int type; };
320 template <> struct restype<int, unsigned int> { typedef int type; };
321 template <> struct restype<int, float> { typedef float type; };
322 template <> struct restype<int, double> { typedef double type; };
323 template <> struct restype<int, long long> { typedef long long type; };
324 template <> struct restype<int, unsigned long long> { typedef long long type; };
325
326 template <> struct restype<unsigned int, char> { typedef int type; };
327 template <> struct restype<unsigned int, unsigned char> { typedef int type; };
328 template <> struct restype<unsigned int, short> { typedef int type; };
329 template <> struct restype<unsigned int, unsigned short> { typedef int type; };
330 template <> struct restype<unsigned int, int> { typedef int type; };
331 template <> struct restype<unsigned int, unsigned int> { typedef int type; };
332 template <> struct restype<unsigned int, float> { typedef float type; };
333 template <> struct restype<unsigned int, double> { typedef double type; };
334 template <> struct restype<unsigned int, long long> { typedef long long type; };
335 template <> struct restype<unsigned int, unsigned long long> { typedef long long type; };
336
337 template <> struct restype<float, char> { typedef float type; };
338 template <> struct restype<float, unsigned char> { typedef float type; };
339 template <> struct restype<float, short> { typedef float type; };
340 template <> struct restype<float, unsigned short> { typedef float type; };
341 template <> struct restype<float, int> { typedef float type; };
342 template <> struct restype<float, unsigned int> { typedef float type; };
343 template <> struct restype<float, float> { typedef float type; };
344 template <> struct restype<float, double> { typedef double type; };
345 template <> struct restype<float, long long> { typedef float type; };
346 template <> struct restype<float, unsigned long long> { typedef float type; };
347
348 template <> struct restype<double, char> { typedef double type; };
349 template <> struct restype<double, unsigned char> { typedef double type; };
350 template <> struct restype<double, short> { typedef double type; };
351 template <> struct restype<double, unsigned short> { typedef double type; };
352 template <> struct restype<double, int> { typedef double type; };
353 template <> struct restype<double, unsigned int> { typedef double type; };
354 template <> struct restype<double, float> { typedef double type; };
355 template <> struct restype<double, double> { typedef double type; };
356 template <> struct restype<double, long long> { typedef double type; };
357 template <> struct restype<double, unsigned long long> { typedef double type; };
358
359 template <> struct restype<long long, char> { typedef long long type; };
360 template <> struct restype<long long, unsigned char> { typedef long long type; };
361 template <> struct restype<long long, short> { typedef long long type; };
362 template <> struct restype<long long, unsigned short> { typedef long long type; };
363 template <> struct restype<long long, int> { typedef long long type; };
364 template <> struct restype<long long, unsigned int> { typedef long long type; };
365 template <> struct restype<long long, float> { typedef float type; };
366 template <> struct restype<long long, double> { typedef double type; };
367 template <> struct restype<long long, long long> { typedef long long type; };
368 template <> struct restype<long long, unsigned long long> { typedef long long type; };
369
370 template <> struct restype<unsigned long long, char> { typedef long long type; };
371 template <> struct restype<unsigned long long, unsigned char> { typedef long long type; };
372 template <> struct restype<unsigned long long, short> { typedef long long type; };
373 template <> struct restype<unsigned long long, unsigned short> { typedef long long type; };
374 template <> struct restype<unsigned long long, int> { typedef long long type; };
375 template <> struct restype<unsigned long long, unsigned int> { typedef long long type; };
376 template <> struct restype<unsigned long long, float> { typedef float type; };
377 template <> struct restype<unsigned long long, double> { typedef double type; };
378 template <> struct restype<unsigned long long, long long> { typedef long long type; };
379 template <> struct restype<unsigned long long, unsigned long long> { typedef long long type; };
380
381 #else
382
383 template <> struct restype<char, char> { typedef int type; };
384 template <> struct restype<char, unsigned char> { typedef int type; };
385 template <> struct restype<char, short> { typedef int type; };
386 template <> struct restype<char, unsigned short> { typedef int type; };
387 template <> struct restype<char, int> { typedef int type; };
388 template <> struct restype<char, unsigned int> { typedef unsigned int type; };
389 template <> struct restype<char, float> { typedef float type; };
390 template <> struct restype<char, double> { typedef double type; };
391 template <> struct restype<char, long long> { typedef long long type; };
392 template <> struct restype<char, unsigned long long> { typedef unsigned long long type; };
393
394 template <> struct restype<unsigned char, char> { typedef int type; };
395 template <> struct restype<unsigned char, unsigned char> { typedef int type; };
396 template <> struct restype<unsigned char, short> { typedef int type; };
397 template <> struct restype<unsigned char, unsigned short> { typedef int type; };
398 template <> struct restype<unsigned char, int> { typedef int type; };
399 template <> struct restype<unsigned char, unsigned int> { typedef unsigned int type; };
400 template <> struct restype<unsigned char, float> { typedef float type; };
401 template <> struct restype<unsigned char, double> { typedef double type; };
402 template <> struct restype<unsigned char, long long> { typedef long long type; };
403 template <> struct restype<unsigned char, unsigned long long> { typedef unsigned long long type; };
404
405 template <> struct restype<short, char> { typedef int type; };
406 template <> struct restype<short, unsigned char> { typedef int type; };
407 template <> struct restype<short, short> { typedef int type; };
408 template <> struct restype<short, unsigned short> { typedef int type; };
409 template <> struct restype<short, int> { typedef int type; };
410 template <> struct restype<short, unsigned int> { typedef unsigned int type; };
411 template <> struct restype<short, float> { typedef float type; };
412 template <> struct restype<short, double> { typedef double type; };
413 template <> struct restype<short, long long> { typedef long long type; };
414 template <> struct restype<short, unsigned long long> { typedef unsigned long long type; };
415
416 template <> struct restype<unsigned short, char> { typedef int type; };
417 template <> struct restype<unsigned short, unsigned char> { typedef int type; };
418 template <> struct restype<unsigned short, short> { typedef int type; };
419 template <> struct restype<unsigned short, unsigned short> { typedef int type; };
420 template <> struct restype<unsigned short, int> { typedef int type; };
421 template <> struct restype<unsigned short, unsigned int> { typedef unsigned int type; };
422 template <> struct restype<unsigned short, float> { typedef float type; };
423 template <> struct restype<unsigned short, double> { typedef double type; };
424 template <> struct restype<unsigned short, long long> { typedef long long type; };
425 template <> struct restype<unsigned short, unsigned long long> { typedef unsigned long long type; };
426
427 template <> struct restype<int, char> { typedef int type; };
428 template <> struct restype<int, unsigned char> { typedef int type; };
429 template <> struct restype<int, short> { typedef int type; };
430 template <> struct restype<int, unsigned short> { typedef int type; };
431 template <> struct restype<int, int> { typedef int type; };
432 template <> struct restype<int, unsigned int> { typedef unsigned int type; };
433 template <> struct restype<int, float> { typedef float type; };
434 template <> struct restype<int, double> { typedef double type; };
435 template <> struct restype<int, long long> { typedef long long type; };
436 template <> struct restype<int, unsigned long long> { typedef unsigned long long type; };
437
438 template <> struct restype<unsigned int, char> { typedef unsigned int type; };
439 template <> struct restype<unsigned int, unsigned char> { typedef unsigned int type; };
440 template <> struct restype<unsigned int, short> { typedef unsigned int type; };
441 template <> struct restype<unsigned int, unsigned short> { typedef unsigned int type; };
442 template <> struct restype<unsigned int, int> { typedef unsigned int type; };
443 template <> struct restype<unsigned int, unsigned int> { typedef unsigned int type; };
444 template <> struct restype<unsigned int, float> { typedef float type; };
445 template <> struct restype<unsigned int, double> { typedef double type; };
446 template <> struct restype<unsigned int, long long> { typedef long long type; };
447 template <> struct restype<unsigned int, unsigned long long> { typedef unsigned long long type; };
448
449 template <> struct restype<float, char> { typedef float type; };
450 template <> struct restype<float, unsigned char> { typedef float type; };
451 template <> struct restype<float, short> { typedef float type; };
452 template <> struct restype<float, unsigned short> { typedef float type; };
453 template <> struct restype<float, int> { typedef float type; };
454 template <> struct restype<float, unsigned int> { typedef float type; };
455 template <> struct restype<float, float> { typedef float type; };
456 template <> struct restype<float, double> { typedef double type; };
457 template <> struct restype<float, long long> { typedef float type; };
458 template <> struct restype<float, unsigned long long> { typedef float type; };
459
460 template <> struct restype<double, char> { typedef double type; };
461 template <> struct restype<double, unsigned char> { typedef double type; };
462 template <> struct restype<double, short> { typedef double type; };
463 template <> struct restype<double, unsigned short> { typedef double type; };
464 template <> struct restype<double, int> { typedef double type; };
465 template <> struct restype<double, unsigned int> { typedef double type; };
466 template <> struct restype<double, float> { typedef double type; };
467 template <> struct restype<double, double> { typedef double type; };
468 template <> struct restype<double, long long> { typedef double type; };
469 template <> struct restype<double, unsigned long long> { typedef double type; };
470
471 template <> struct restype<unsigned long long, char> { typedef unsigned long long type; };
472 template <> struct restype<unsigned long long, unsigned char> { typedef unsigned long long type; };
473 template <> struct restype<unsigned long long, short> { typedef unsigned long long type; };
474 template <> struct restype<unsigned long long, unsigned short> { typedef unsigned long long type; };
475 template <> struct restype<unsigned long long, int> { typedef unsigned long long type; };
476 template <> struct restype<unsigned long long, unsigned int> { typedef unsigned long long type; };
477 template <> struct restype<unsigned long long, float> { typedef float type; };
478 template <> struct restype<unsigned long long, double> { typedef double type; };
479 template <> struct restype<unsigned long long, long long> { typedef unsigned long long type; };
480 template <> struct restype<unsigned long long, unsigned long long> { typedef unsigned long long type; };
481
482 template <> struct restype<long long, char> { typedef long long type; };
483 template <> struct restype<long long, unsigned char> { typedef long long type; };
484 template <> struct restype<long long, short> { typedef long long type; };
485 template <> struct restype<long long, unsigned short> { typedef long long type; };
486 template <> struct restype<long long, int> { typedef long long type; };
487 template <> struct restype<long long, unsigned int> { typedef long long type; };
488 template <> struct restype<long long, float> { typedef float type; };
489 template <> struct restype<long long, double> { typedef double type; };
490 template <> struct restype<long long, long long> { typedef long long type; };
491 template <> struct restype<long long, unsigned long long> { typedef unsigned long long type; };
492
493 #endif
494
495 template <typename T1, typename T2> struct bitwise_restype {
496 private:
497 bitwise_restype();
498 };
499
500 #if defined(CM_NOCONV)
501
502 template <> struct bitwise_restype<char, char> { typedef char type; };
503 template <> struct bitwise_restype<char, unsigned char> { typedef short type; };
504 template <> struct bitwise_restype<char, short> { typedef short type; };
505 template <> struct bitwise_restype<char, unsigned short> { typedef short type; };
506 template <> struct bitwise_restype<char, int> { typedef int type; };
507 template <> struct bitwise_restype<char, unsigned int> { typedef int type; };
508 template <> struct bitwise_restype<char, float> { typedef float type; };
509 template <> struct bitwise_restype<char, double> { typedef double type; };
510 template <> struct bitwise_restype<char, long long> { typedef long long type; };
511 template <> struct bitwise_restype<char, unsigned long long> { typedef long long type; };
512
513 template <> struct bitwise_restype<unsigned char, char> { typedef char type; };
514 template <> struct bitwise_restype<unsigned char, unsigned char> { typedef char type; };
515 template <> struct bitwise_restype<unsigned char, short> { typedef short type; };
516 template <> struct bitwise_restype<unsigned char, unsigned short> { typedef short type; };
517 template <> struct bitwise_restype<unsigned char, int> { typedef int type; };
518 template <> struct bitwise_restype<unsigned char, unsigned int> { typedef int type; };
519 template <> struct bitwise_restype<unsigned char, float> { typedef float type; };
520 template <> struct bitwise_restype<unsigned char, double> { typedef double type; };
521 template <> struct bitwise_restype<unsigned char, long long> { typedef long long type; };
522 template <> struct bitwise_restype<unsigned char, unsigned long long> { typedef long long type; };
523
524 template <> struct bitwise_restype<short, char> { typedef short type; };
525 template <> struct bitwise_restype<short, unsigned char> { typedef short type; };
526 template <> struct bitwise_restype<short, short> { typedef short type; };
527 template <> struct bitwise_restype<short, unsigned short> { typedef short type; };
528 template <> struct bitwise_restype<short, int> { typedef int type; };
529 template <> struct bitwise_restype<short, unsigned int> { typedef int type; };
530 template <> struct bitwise_restype<short, float> { typedef float type; };
531 template <> struct bitwise_restype<short, double> { typedef double type; };
532 template <> struct bitwise_restype<short, long long> { typedef long long type; };
533 template <> struct bitwise_restype<short, unsigned long long> { typedef long long type; };
534
535 template <> struct bitwise_restype<unsigned short, char> { typedef short type; };
536 template <> struct bitwise_restype<unsigned short, unsigned char> { typedef short type; };
537 template <> struct bitwise_restype<unsigned short, short> { typedef short type; };
538 template <> struct bitwise_restype<unsigned short, unsigned short> { typedef short type; };
539 template <> struct bitwise_restype<unsigned short, int> { typedef int type; };
540 template <> struct bitwise_restype<unsigned short, unsigned int> { typedef int type; };
541 template <> struct bitwise_restype<unsigned short, float> { typedef float type; };
542 template <> struct bitwise_restype<unsigned short, double> { typedef double type; };
543 template <> struct bitwise_restype<unsigned short, long long> { typedef long long type; };
544 template <> struct bitwise_restype<unsigned short, unsigned long long> { typedef long long type; };
545
546 template <> struct bitwise_restype<int, char> { typedef int type; };
547 template <> struct bitwise_restype<int, unsigned char> { typedef int type; };
548 template <> struct bitwise_restype<int, short> { typedef int type; };
549 template <> struct bitwise_restype<int, unsigned short> { typedef int type; };
550 template <> struct bitwise_restype<int, int> { typedef int type; };
551 template <> struct bitwise_restype<int, unsigned int> { typedef int type; };
552 template <> struct bitwise_restype<int, float> { typedef float type; };
553 template <> struct bitwise_restype<int, double> { typedef double type; };
554 template <> struct bitwise_restype<int, long long> { typedef long long type; };
555 template <> struct bitwise_restype<int, unsigned long long> { typedef long long type; };
556
557 template <> struct bitwise_restype<unsigned int, char> { typedef int type; };
558 template <> struct bitwise_restype<unsigned int, unsigned char> { typedef int type; };
559 template <> struct bitwise_restype<unsigned int, short> { typedef int type; };
560 template <> struct bitwise_restype<unsigned int, unsigned short> { typedef int type; };
561 template <> struct bitwise_restype<unsigned int, int> { typedef int type; };
562 template <> struct bitwise_restype<unsigned int, unsigned int> { typedef int type; };
563 template <> struct bitwise_restype<unsigned int, float> { typedef float type; };
564 template <> struct bitwise_restype<unsigned int, double> { typedef double type; };
565 template <> struct bitwise_restype<unsigned int, long long> { typedef long long type; };
566 template <> struct bitwise_restype<unsigned int, unsigned long long> { typedef long long type; };
567
568 template <> struct bitwise_restype<float, char> { typedef float type; };
569 template <> struct bitwise_restype<float, unsigned char> { typedef float type; };
570 template <> struct bitwise_restype<float, short> { typedef float type; };
571 template <> struct bitwise_restype<float, unsigned short> { typedef float type; };
572 template <> struct bitwise_restype<float, int> { typedef float type; };
573 template <> struct bitwise_restype<float, unsigned int> { typedef float type; };
574 template <> struct bitwise_restype<float, float> { typedef float type; };
575 template <> struct bitwise_restype<float, double> { typedef double type; };
576 template <> struct bitwise_restype<float, long long> { typedef float type; };
577 template <> struct bitwise_restype<float, unsigned long long> { typedef float type; };
578
579 template <> struct bitwise_restype<double, char> { typedef double type; };
580 template <> struct bitwise_restype<double, unsigned char> { typedef double type; };
581 template <> struct bitwise_restype<double, short> { typedef double type; };
582 template <> struct bitwise_restype<double, unsigned short> { typedef double type; };
583 template <> struct bitwise_restype<double, int> { typedef double type; };
584 template <> struct bitwise_restype<double, unsigned int> { typedef double type; };
585 template <> struct bitwise_restype<double, float> { typedef double type; };
586 template <> struct bitwise_restype<double, double> { typedef double type; };
587 template <> struct bitwise_restype<double, long long> { typedef double type; };
588 template <> struct bitwise_restype<double, unsigned long long> { typedef double type; };
589
590 template <> struct bitwise_restype<long long, char> { typedef long long type; };
591 template <> struct bitwise_restype<long long, unsigned char> { typedef long long type; };
592 template <> struct bitwise_restype<long long, short> { typedef long long type; };
593 template <> struct bitwise_restype<long long, unsigned short> { typedef long long type; };
594 template <> struct bitwise_restype<long long, int> { typedef long long type; };
595 template <> struct bitwise_restype<long long, unsigned int> { typedef long long type; };
596 template <> struct bitwise_restype<long long, float> { typedef float type; };
597 template <> struct bitwise_restype<long long, double> { typedef double type; };
598 template <> struct bitwise_restype<long long, long long> { typedef long long type; };
599 template <> struct bitwise_restype<long long, unsigned long long> { typedef long long type; };
600
601 template <> struct bitwise_restype<unsigned long long, char> { typedef long long type; };
602 template <> struct bitwise_restype<unsigned long long, unsigned char> { typedef long long type; };
603 template <> struct bitwise_restype<unsigned long long, short> { typedef long long type; };
604 template <> struct bitwise_restype<unsigned long long, unsigned short> { typedef long long type; };
605 template <> struct bitwise_restype<unsigned long long, int> { typedef long long type; };
606 template <> struct bitwise_restype<unsigned long long, unsigned int> { typedef long long type; };
607 template <> struct bitwise_restype<unsigned long long, float> { typedef float type; };
608 template <> struct bitwise_restype<unsigned long long, double> { typedef double type; };
609 template <> struct bitwise_restype<unsigned long long, long long> { typedef long long type; };
610 template <> struct bitwise_restype<unsigned long long, unsigned long long> { typedef long long type; };
611 #else
612
613 template <> struct bitwise_restype<char, char> { typedef char type; };
614 template <> struct bitwise_restype<char, unsigned char> { typedef unsigned char type; };
615 template <> struct bitwise_restype<char, short> { typedef short type; };
616 template <> struct bitwise_restype<char, unsigned short> { typedef unsigned short type; };
617 template <> struct bitwise_restype<char, int> { typedef int type; };
618 template <> struct bitwise_restype<char, unsigned int> { typedef unsigned int type; };
619 template <> struct bitwise_restype<char, float> { typedef float type; };
620 template <> struct bitwise_restype<char, double> { typedef double type; };
621 template <> struct bitwise_restype<char, long long> { typedef long long type; };
622 template <> struct bitwise_restype<char, unsigned long long> { typedef unsigned long long type; };
623
624 template <> struct bitwise_restype<unsigned char, char> { typedef char type; };
625 template <> struct bitwise_restype<unsigned char, unsigned char> { typedef unsigned char type; };
626 template <> struct bitwise_restype<unsigned char, short> { typedef short type; };
627 template <> struct bitwise_restype<unsigned char, unsigned short> { typedef unsigned short type; };
628 template <> struct bitwise_restype<unsigned char, int> { typedef int type; };
629 template <> struct bitwise_restype<unsigned char, unsigned int> { typedef unsigned int type; };
630 template <> struct bitwise_restype<unsigned char, float> { typedef float type; };
631 template <> struct bitwise_restype<unsigned char, double> { typedef double type; };
632 template <> struct bitwise_restype<unsigned char, long long> { typedef long long type; };
633 template <> struct bitwise_restype<unsigned char, unsigned long long> { typedef unsigned long long type; };
634
635 template <> struct bitwise_restype<short, char> { typedef short type; };
636 template <> struct bitwise_restype<short, unsigned char> { typedef short type; };
637 template <> struct bitwise_restype<short, short> { typedef short type; };
638 template <> struct bitwise_restype<short, unsigned short> { typedef unsigned short type; };
639 template <> struct bitwise_restype<short, int> { typedef int type; };
640 template <> struct bitwise_restype<short, unsigned int> { typedef unsigned int type; };
641 template <> struct bitwise_restype<short, float> { typedef float type; };
642 template <> struct bitwise_restype<short, double> { typedef double type; };
643 template <> struct bitwise_restype<short, long long> { typedef long long type; };
644 template <> struct bitwise_restype<short, unsigned long long> { typedef unsigned long long type; };
645
646 template <> struct bitwise_restype<unsigned short, char> { typedef unsigned short type; };
647 template <> struct bitwise_restype<unsigned short, unsigned char> { typedef unsigned short type; };
648 template <> struct bitwise_restype<unsigned short, short> { typedef unsigned short type; };
649 template <> struct bitwise_restype<unsigned short, unsigned short> { typedef unsigned short type; };
650 template <> struct bitwise_restype<unsigned short, int> { typedef int type; };
651 template <> struct bitwise_restype<unsigned short, unsigned int> { typedef unsigned int type; };
652 template <> struct bitwise_restype<unsigned short, float> { typedef float type; };
653 template <> struct bitwise_restype<unsigned short, double> { typedef double type; };
654 template <> struct bitwise_restype<unsigned short, long long> { typedef long long type; };
655 template <> struct bitwise_restype<unsigned short, unsigned long long> { typedef unsigned long long type; };
656
657 template <> struct bitwise_restype<int, char> { typedef int type; };
658 template <> struct bitwise_restype<int, unsigned char> { typedef int type; };
659 template <> struct bitwise_restype<int, short> { typedef int type; };
660 template <> struct bitwise_restype<int, unsigned short> { typedef int type; };
661 template <> struct bitwise_restype<int, int> { typedef int type; };
662 template <> struct bitwise_restype<int, unsigned int> { typedef unsigned int type; };
663 template <> struct bitwise_restype<int, float> { typedef float type; };
664 template <> struct bitwise_restype<int, double> { typedef double type; };
665 template <> struct bitwise_restype<int, long long> { typedef long long type; };
666 template <> struct bitwise_restype<int, unsigned long long> { typedef unsigned long long type; };
667
668 template <> struct bitwise_restype<unsigned int, char> { typedef unsigned int type; };
669 template <> struct bitwise_restype<unsigned int, unsigned char> { typedef unsigned int type; };
670 template <> struct bitwise_restype<unsigned int, short> { typedef unsigned int type; };
671 template <> struct bitwise_restype<unsigned int, unsigned short> { typedef unsigned int type; };
672 template <> struct bitwise_restype<unsigned int, int> { typedef unsigned int type; };
673 template <> struct bitwise_restype<unsigned int, unsigned int> { typedef unsigned int type; };
674 template <> struct bitwise_restype<unsigned int, float> { typedef float type; };
675 template <> struct bitwise_restype<unsigned int, double> { typedef double type; };
676 template <> struct bitwise_restype<unsigned int, long long> { typedef long long type; };
677 template <> struct bitwise_restype<unsigned int, unsigned long long> { typedef unsigned long long type; };
678
679 template <> struct bitwise_restype<float, char> { typedef float type; };
680 template <> struct bitwise_restype<float, unsigned char> { typedef float type; };
681 template <> struct bitwise_restype<float, short> { typedef float type; };
682 template <> struct bitwise_restype<float, unsigned short> { typedef float type; };
683 template <> struct bitwise_restype<float, int> { typedef float type; };
684 template <> struct bitwise_restype<float, unsigned int> { typedef float type; };
685 template <> struct bitwise_restype<float, float> { typedef float type; };
686 template <> struct bitwise_restype<float, double> { typedef double type; };
687 template <> struct bitwise_restype<float, long long> { typedef float type; };
688 template <> struct bitwise_restype<float, unsigned long long> { typedef float type; };
689
690 template <> struct bitwise_restype<double, char> { typedef double type; };
691 template <> struct bitwise_restype<double, unsigned char> { typedef double type; };
692 template <> struct bitwise_restype<double, short> { typedef double type; };
693 template <> struct bitwise_restype<double, unsigned short> { typedef double type; };
694 template <> struct bitwise_restype<double, int> { typedef double type; };
695 template <> struct bitwise_restype<double, unsigned int> { typedef double type; };
696 template <> struct bitwise_restype<double, float> { typedef double type; };
697 template <> struct bitwise_restype<double, double> { typedef double type; };
698 template <> struct bitwise_restype<double, long long> { typedef double type; };
699 template <> struct bitwise_restype<double, unsigned long long> { typedef double type; };
700
701 template <> struct bitwise_restype<long long, char> { typedef long long type; };
702 template <> struct bitwise_restype<long long, unsigned char> { typedef long long type; };
703 template <> struct bitwise_restype<long long, short> { typedef long long type; };
704 template <> struct bitwise_restype<long long, unsigned short> { typedef long long type; };
705 template <> struct bitwise_restype<long long, int> { typedef long long type; };
706 template <> struct bitwise_restype<long long, unsigned int> { typedef long long type; };
707 template <> struct bitwise_restype<long long, float> { typedef float type; };
708 template <> struct bitwise_restype<long long, double> { typedef double type; };
709 template <> struct bitwise_restype<long long, long long> { typedef long long type; };
710 template <> struct bitwise_restype<long long, unsigned long long> { typedef unsigned long long type; };
711
712 template <> struct bitwise_restype<unsigned long long, char> { typedef unsigned long long type; };
713 template <> struct bitwise_restype<unsigned long long, unsigned char> { typedef unsigned long long type; };
714 template <> struct bitwise_restype<unsigned long long, short> { typedef unsigned long long type; };
715 template <> struct bitwise_restype<unsigned long long, unsigned short> { typedef unsigned long long type; };
716 template <> struct bitwise_restype<unsigned long long, int> { typedef unsigned long long type; };
717 template <> struct bitwise_restype<unsigned long long, unsigned int> { typedef unsigned long long type; };
718 template <> struct bitwise_restype<unsigned long long, float> { typedef float type; };
719 template <> struct bitwise_restype<unsigned long long, double> { typedef double type; };
720 template <> struct bitwise_restype<unsigned long long, long long> { typedef unsigned long long type; };
721 template <> struct bitwise_restype<unsigned long long, unsigned long long> { typedef unsigned long long type; };
722
723 #endif
724
725 template <typename T1, typename T2> struct restype_ex {
726 private:
727 restype_ex();
728 };
729 //#ifdef CM_NONSTRICT
730 #if 0
731 template <> struct restype_ex<char, char> { typedef short type; };
732 template <> struct restype_ex<char, unsigned char> { typedef short type; };
733 template <> struct restype_ex<char, short> { typedef short type; };
734 template <> struct restype_ex<char, unsigned short> { typedef short type; };
735 template <> struct restype_ex<char, int> { typedef int type; };
736 template <> struct restype_ex<char, unsigned int> { typedef int type; };
737 template <> struct restype_ex<char, float> { typedef float type; };
738 template <> struct restype_ex<char, double> { typedef double type; };
739
740 template <> struct restype_ex<unsigned char, char> { typedef short type; };
741 template <> struct restype_ex<unsigned char, unsigned char> { typedef short type; };
742 template <> struct restype_ex<unsigned char, short> { typedef short type; };
743 template <> struct restype_ex<unsigned char, unsigned short> { typedef short type; };
744 template <> struct restype_ex<unsigned char, int> { typedef int type; };
745 template <> struct restype_ex<unsigned char, unsigned int> { typedef int type; };
746 template <> struct restype_ex<unsigned char, float> { typedef float type; };
747 template <> struct restype_ex<unsigned char, double> { typedef double type; };
748
749 template <> struct restype_ex<short, char> { typedef short type; };
750 template <> struct restype_ex<short, unsigned char> { typedef short type; };
751 template <> struct restype_ex<short, short> { typedef short type; };
752 template <> struct restype_ex<short, unsigned short> { typedef short type; };
753 template <> struct restype_ex<short, int> { typedef int type; };
754 template <> struct restype_ex<short, unsigned int> { typedef int type; };
755 template <> struct restype_ex<short, float> { typedef float type; };
756 template <> struct restype_ex<short, double> { typedef double type; };
757
758 template <> struct restype_ex<unsigned short, char> { typedef short type; };
759 template <> struct restype_ex<unsigned short, unsigned char> { typedef short type; };
760 template <> struct restype_ex<unsigned short, short> { typedef short type; };
761 template <> struct restype_ex<unsigned short, unsigned short> { typedef short type; };
762 template <> struct restype_ex<unsigned short, int> { typedef int type; };
763 template <> struct restype_ex<unsigned short, unsigned int> { typedef int type; };
764 template <> struct restype_ex<unsigned short, float> { typedef float type; };
765 template <> struct restype_ex<unsigned short, double> { typedef double type; };
766
767 template <> struct restype_ex<int, char> { typedef int type; };
768 template <> struct restype_ex<int, unsigned char> { typedef int type; };
769 template <> struct restype_ex<int, short> { typedef int type; };
770 template <> struct restype_ex<int, unsigned short> { typedef int type; };
771 template <> struct restype_ex<int, int> { typedef int type; };
772 template <> struct restype_ex<int, unsigned int> { typedef int type; };
773 template <> struct restype_ex<int, float> { typedef float type; };
774 template <> struct restype_ex<int, double> { typedef double type; };
775
776 template <> struct restype_ex<unsigned int, char> { typedef int type; };
777 template <> struct restype_ex<unsigned int, unsigned char> { typedef int type; };
778 template <> struct restype_ex<unsigned int, short> { typedef int type; };
779 template <> struct restype_ex<unsigned int, unsigned short> { typedef int type; };
780 template <> struct restype_ex<unsigned int, int> { typedef int type; };
781 template <> struct restype_ex<unsigned int, unsigned int> { typedef int type; };
782 template <> struct restype_ex<unsigned int, float> { typedef float type; };
783 template <> struct restype_ex<unsigned int, double> { typedef double type; };
784
785 template <> struct restype_ex<float, char> { typedef float type; };
786 template <> struct restype_ex<float, unsigned char> { typedef float type; };
787 template <> struct restype_ex<float, short> { typedef float type; };
788 template <> struct restype_ex<float, unsigned short> { typedef float type; };
789 template <> struct restype_ex<float, int> { typedef float type; };
790 template <> struct restype_ex<float, unsigned int> { typedef float type; };
791 template <> struct restype_ex<float, float> { typedef float type; };
792 template <> struct restype_ex<float, double> { typedef double type; };
793
794 template <> struct restype_ex<double, char> { typedef double type; };
795 template <> struct restype_ex<double, unsigned char> { typedef double type; };
796 template <> struct restype_ex<double, short> { typedef double type; };
797 template <> struct restype_ex<double, unsigned short> { typedef double type; };
798 template <> struct restype_ex<double, int> { typedef double type; };
799 template <> struct restype_ex<double, unsigned int> { typedef double type; };
800 template <> struct restype_ex<double, float> { typedef double type; };
801 template <> struct restype_ex<double, double> { typedef double type; };
802
803 template <> struct restype_ex<long long, char> { typedef long long type; };
804 template <> struct restype_ex<long long, unsigned char> { typedef long long type; };
805 template <> struct restype_ex<long long, short> { typedef long long type; };
806 template <> struct restype_ex<long long, unsigned short> { typedef long long type; };
807 template <> struct restype_ex<long long, int> { typedef long long type; };
808 template <> struct restype_ex<long long, unsigned int> { typedef long long type; };
809 template <> struct restype_ex<long long, float> { typedef float type; };
810 template <> struct restype_ex<long long, double> { typedef double type; };
811 template <> struct restype_ex<long long, long long> { typedef long long type; };
812 template <> struct restype_ex<long long, unsigned long long> { typedef long long type; };
813
814 template <> struct restype_ex<unsigned long long, char> { typedef long long type; };
815 template <> struct restype_ex<unsigned long long, unsigned char> { typedef long long type; };
816 template <> struct restype_ex<unsigned long long, short> { typedef long long type; };
817 template <> struct restype_ex<unsigned long long, unsigned short> { typedef long long type; };
818 template <> struct restype_ex<unsigned long long, int> { typedef long long type; };
819 template <> struct restype_ex<unsigned long long, unsigned int> { typedef long long type; };
820 template <> struct restype_ex<unsigned long long, float> { typedef float type; };
821 template <> struct restype_ex<unsigned long long, double> { typedef double type; };
822 template <> struct restype_ex<unsigned long long, long long> { typedef long long type; };
823 template <> struct restype_ex<unsigned long long, unsigned long long> { typedef long long type; };
824
825 template <typename T> struct maxtype;
826 template<> struct maxtype<float> { typedef float type; };
827 template<> struct maxtype<char> { typedef char type; };
828 template<> struct maxtype<short> { typedef short type; };
829 template<> struct maxtype<int> { typedef int type; };
830 template<> struct maxtype<uchar> { typedef uchar type; };
831 template<> struct maxtype<ushort> { typedef ushort type; };
832 template<> struct maxtype<uint> { typedef uint type; };
833 template<> struct maxtype<double> { typedef double type; };
834 template<> struct maxtype<long long> { typedef long long type; };
835 template<> struct maxtype<unsigned long long> { typedef unsigned long long type; };
836
837 #else
838
839 template <> struct restype_ex<char, char> { typedef int type; };
840 template <> struct restype_ex<char, unsigned char> { typedef int type; };
841 template <> struct restype_ex<char, short> { typedef int type; };
842 template <> struct restype_ex<char, unsigned short> { typedef int type; };
843 template <> struct restype_ex<char, int> { typedef long long type; };
844 template <> struct restype_ex<char, unsigned int> { typedef long long type; };
845 template <> struct restype_ex<char, float> { typedef float type; };
846 template <> struct restype_ex<char, double> { typedef double type; };
847
848 template <> struct restype_ex<unsigned char, char> { typedef int type; };
849 template <> struct restype_ex<unsigned char, unsigned char> { typedef int type; };
850 template <> struct restype_ex<unsigned char, short> { typedef int type; };
851 template <> struct restype_ex<unsigned char, unsigned short> { typedef int type; };
852 template <> struct restype_ex<unsigned char, int> { typedef long long type; };
853 template <> struct restype_ex<unsigned char, unsigned int> { typedef long long type; };
854 template <> struct restype_ex<unsigned char, float> { typedef float type; };
855 template <> struct restype_ex<unsigned char, double> { typedef double type; };
856 template <> struct restype_ex<unsigned char, long long> { typedef long long type; };
857 template <> struct restype_ex<unsigned char, unsigned long long> { typedef long long type; };
858
859 template <> struct restype_ex<short, char> { typedef int type; };
860 template <> struct restype_ex<short, unsigned char> { typedef int type; };
861 template <> struct restype_ex<short, short> { typedef int type; };
862 template <> struct restype_ex<short, unsigned short> { typedef int type; };
863 template <> struct restype_ex<short, int> { typedef long long type; };
864 template <> struct restype_ex<short, unsigned int> { typedef long long type; };
865 template <> struct restype_ex<short, float> { typedef float type; };
866 template <> struct restype_ex<short, double> { typedef double type; };
867 template <> struct restype_ex<short, long long> { typedef long long type; };
868 template <> struct restype_ex<short, unsigned long long> { typedef long long type; };
869
870 template <> struct restype_ex<unsigned short, char> { typedef int type; };
871 template <> struct restype_ex<unsigned short, unsigned char> { typedef int type; };
872 template <> struct restype_ex<unsigned short, short> { typedef int type; };
873 template <> struct restype_ex<unsigned short, unsigned short> { typedef int type; };
874 template <> struct restype_ex<unsigned short, int> { typedef long long type; };
875 template <> struct restype_ex<unsigned short, unsigned int> { typedef long long type; };
876 template <> struct restype_ex<unsigned short, float> { typedef float type; };
877 template <> struct restype_ex<unsigned short, double> { typedef double type; };
878 template <> struct restype_ex<unsigned short, long long> { typedef long long type; };
879 template <> struct restype_ex<unsigned short, unsigned long long> { typedef long long type; };
880
881 template <> struct restype_ex<int, char> { typedef long long type; };
882 template <> struct restype_ex<int, unsigned char> { typedef long long type; };
883 template <> struct restype_ex<int, short> { typedef long long type; };
884 template <> struct restype_ex<int, unsigned short> { typedef long long type; };
885 template <> struct restype_ex<int, int> { typedef long long type; };
886 template <> struct restype_ex<int, unsigned int> { typedef long long type; };
887 template <> struct restype_ex<int, float> { typedef float type; };
888 template <> struct restype_ex<int, double> { typedef double type; };
889 template <> struct restype_ex<int, long long> { typedef long long type; };
890 template <> struct restype_ex<int, unsigned long long> { typedef long long type; };
891
892 template <> struct restype_ex<unsigned int, char> { typedef long long type; };
893 template <> struct restype_ex<unsigned int, unsigned char> { typedef long long type; };
894 template <> struct restype_ex<unsigned int, short> { typedef long long type; };
895 template <> struct restype_ex<unsigned int, unsigned short> { typedef long long type; };
896 template <> struct restype_ex<unsigned int, int> { typedef long long type; };
897 template <> struct restype_ex<unsigned int, unsigned int> { typedef long long type; };
898 template <> struct restype_ex<unsigned int, float> { typedef float type; };
899 template <> struct restype_ex<unsigned int, double> { typedef double type; };
900 template <> struct restype_ex<unsigned int, long long> { typedef long long type; };
901 template <> struct restype_ex<unsigned int, unsigned long long> { typedef long long type; };
902
903 template <> struct restype_ex<float, char> { typedef float type; };
904 template <> struct restype_ex<float, unsigned char> { typedef float type; };
905 template <> struct restype_ex<float, short> { typedef float type; };
906 template <> struct restype_ex<float, unsigned short> { typedef float type; };
907 template <> struct restype_ex<float, int> { typedef float type; };
908 template <> struct restype_ex<float, unsigned int> { typedef float type; };
909 template <> struct restype_ex<float, float> { typedef float type; };
910 template <> struct restype_ex<float, double> { typedef double type; };
911 template <> struct restype_ex<float, long long> { typedef float type; };
912 template <> struct restype_ex<float, unsigned long long> { typedef float type; };
913
914 template <> struct restype_ex<double, char> { typedef double type; };
915 template <> struct restype_ex<double, unsigned char> { typedef double type; };
916 template <> struct restype_ex<double, short> { typedef double type; };
917 template <> struct restype_ex<double, unsigned short> { typedef double type; };
918 template <> struct restype_ex<double, int> { typedef double type; };
919 template <> struct restype_ex<double, unsigned int> { typedef double type; };
920 template <> struct restype_ex<double, float> { typedef double type; };
921 template <> struct restype_ex<double, double> { typedef double type; };
922 template <> struct restype_ex<double, long long> { typedef double type; };
923 template <> struct restype_ex<double, unsigned long long> { typedef double type; };
924
925 template <> struct restype_ex<long long, char> { typedef long long type; };
926 template <> struct restype_ex<long long, unsigned char> { typedef long long type; };
927 template <> struct restype_ex<long long, short> { typedef long long type; };
928 template <> struct restype_ex<long long, unsigned short> { typedef long long type; };
929 template <> struct restype_ex<long long, int> { typedef long long type; };
930 template <> struct restype_ex<long long, unsigned int> { typedef long long type; };
931 template <> struct restype_ex<long long, float> { typedef float type; };
932 template <> struct restype_ex<long long, double> { typedef double type; };
933 template <> struct restype_ex<long long, long long> { typedef long long type; };
934 template <> struct restype_ex<long long, unsigned long long> { typedef long long type; };
935
936 template <> struct restype_ex<unsigned long long, char> { typedef long long type; };
937 template <> struct restype_ex<unsigned long long, unsigned char> { typedef long long type; };
938 template <> struct restype_ex<unsigned long long, short> { typedef long long type; };
939 template <> struct restype_ex<unsigned long long, unsigned short> { typedef long long type; };
940 template <> struct restype_ex<unsigned long long, int> { typedef long long type; };
941 template <> struct restype_ex<unsigned long long, unsigned int> { typedef long long type; };
942 template <> struct restype_ex<unsigned long long, float> { typedef float type; };
943 template <> struct restype_ex<unsigned long long, double> { typedef double type; };
944 template <> struct restype_ex<unsigned long long, long long> { typedef long long type; };
945 template <> struct restype_ex<unsigned long long, unsigned long long> { typedef long long type; };
946
947 template <typename T> struct maxtype;
948 template<> struct maxtype<float> { typedef float type; };
949 template<> struct maxtype<char> { typedef int type; };
950 template<> struct maxtype<short> { typedef int type; };
951 template<> struct maxtype<int> { typedef int type; };
952 template<> struct maxtype<uchar> { typedef uint type; };
953 template<> struct maxtype<ushort> { typedef uint type; };
954 template<> struct maxtype<uint> { typedef uint type; };
955 template<> struct maxtype<double> { typedef double type; };
956 template<> struct maxtype<long long> { typedef long long type; };
957 template<> struct maxtype<unsigned long long> { typedef unsigned long long type; };
958
959 #endif
960
961 template <typename T1, typename T2> struct uchar_type {
962 private:
963 uchar_type();
964 };
965 template <> struct uchar_type<char, char> { typedef uchar type; };
966 template <> struct uchar_type<char, unsigned char> { typedef uchar type; };
967 template <> struct uchar_type<char, short> { typedef uchar type; };
968 template <> struct uchar_type<char, unsigned short> { typedef uchar type; };
969 template <> struct uchar_type<char, int> { typedef uchar type; };
970 template <> struct uchar_type<char, unsigned int> { typedef uchar type; };
971 template <> struct uchar_type<char, float> { typedef uchar type; };
972 template <> struct uchar_type<char, double> { typedef uchar type; };
973 template <> struct uchar_type<char, long long> { typedef uchar type; };
974 template <> struct uchar_type<char, unsigned long long> { typedef uchar type; };
975
976 template <> struct uchar_type<unsigned char, char> { typedef uchar type; };
977 template <> struct uchar_type<unsigned char, unsigned char> { typedef uchar type; };
978 template <> struct uchar_type<unsigned char, short> { typedef uchar type; };
979 template <> struct uchar_type<unsigned char, unsigned short> { typedef uchar type; };
980 template <> struct uchar_type<unsigned char, int> { typedef uchar type; };
981 template <> struct uchar_type<unsigned char, unsigned int> { typedef uchar type; };
982 template <> struct uchar_type<unsigned char, float> { typedef uchar type; };
983 template <> struct uchar_type<unsigned char, double> { typedef uchar type; };
984 template <> struct uchar_type<unsigned char, long long> { typedef uchar type; };
985 template <> struct uchar_type<unsigned char, unsigned long long> { typedef uchar type; };
986
987 template <> struct uchar_type<short, char> { typedef uchar type; };
988 template <> struct uchar_type<short, unsigned char> { typedef uchar type; };
989 template <> struct uchar_type<short, short> { typedef uchar type; };
990 template <> struct uchar_type<short, unsigned short> { typedef uchar type; };
991 template <> struct uchar_type<short, int> { typedef uchar type; };
992 template <> struct uchar_type<short, unsigned int> { typedef uchar type; };
993 template <> struct uchar_type<short, float> { typedef uchar type; };
994 template <> struct uchar_type<short, double> { typedef uchar type; };
995 template <> struct uchar_type<short, long long> { typedef uchar type; };
996 template <> struct uchar_type<short, unsigned long long> { typedef uchar type; };
997
998 template <> struct uchar_type<unsigned short, char> { typedef uchar type; };
999 template <> struct uchar_type<unsigned short, unsigned char> { typedef uchar type; };
1000 template <> struct uchar_type<unsigned short, short> { typedef uchar type; };
1001 template <> struct uchar_type<unsigned short, unsigned short> { typedef uchar type; };
1002 template <> struct uchar_type<unsigned short, int> { typedef uchar type; };
1003 template <> struct uchar_type<unsigned short, unsigned int> { typedef uchar type; };
1004 template <> struct uchar_type<unsigned short, float> { typedef uchar type; };
1005 template <> struct uchar_type<unsigned short, double> { typedef uchar type; };
1006 template <> struct uchar_type<unsigned short, long long> { typedef uchar type; };
1007 template <> struct uchar_type<unsigned short, unsigned long long> { typedef uchar type; };
1008
1009 template <> struct uchar_type<int, char> { typedef uchar type; };
1010 template <> struct uchar_type<int, unsigned char> { typedef uchar type; };
1011 template <> struct uchar_type<int, short> { typedef uchar type; };
1012 template <> struct uchar_type<int, unsigned short> { typedef uchar type; };
1013 template <> struct uchar_type<int, int> { typedef uchar type; };
1014 template <> struct uchar_type<int, unsigned int> { typedef uchar type; };
1015 template <> struct uchar_type<int, float> { typedef uchar type; };
1016 template <> struct uchar_type<int, double> { typedef uchar type; };
1017 template <> struct uchar_type<int, long long> { typedef uchar type; };
1018 template <> struct uchar_type<int, unsigned long long> { typedef uchar type; };
1019
1020 template <> struct uchar_type<unsigned int, char> { typedef uchar type; };
1021 template <> struct uchar_type<unsigned int, unsigned char> { typedef uchar type; };
1022 template <> struct uchar_type<unsigned int, short> { typedef uchar type; };
1023 template <> struct uchar_type<unsigned int, unsigned short> { typedef uchar type; };
1024 template <> struct uchar_type<unsigned int, int> { typedef uchar type; };
1025 template <> struct uchar_type<unsigned int, unsigned int> { typedef uchar type; };
1026 template <> struct uchar_type<unsigned int, float> { typedef uchar type; };
1027 template <> struct uchar_type<unsigned int, double> { typedef uchar type; };
1028 template <> struct uchar_type<unsigned int, long long> { typedef uchar type; };
1029 template <> struct uchar_type<unsigned int, unsigned long long> { typedef uchar type; };
1030
1031 template <> struct uchar_type<float, char> { typedef uchar type; };
1032 template <> struct uchar_type<float, unsigned char> { typedef uchar type; };
1033 template <> struct uchar_type<float, short> { typedef uchar type; };
1034 template <> struct uchar_type<float, unsigned short> { typedef uchar type; };
1035 template <> struct uchar_type<float, int> { typedef uchar type; };
1036 template <> struct uchar_type<float, unsigned int> { typedef uchar type; };
1037 template <> struct uchar_type<float, float> { typedef uchar type; };
1038 template <> struct uchar_type<float, double> { typedef uchar type; };
1039 template <> struct uchar_type<float, long long> { typedef uchar type; };
1040 template <> struct uchar_type<float, unsigned long long> { typedef uchar type; };
1041
1042 template <> struct uchar_type<double, char> { typedef uchar type; };
1043 template <> struct uchar_type<double, unsigned char> { typedef uchar type; };
1044 template <> struct uchar_type<double, short> { typedef uchar type; };
1045 template <> struct uchar_type<double, unsigned short> { typedef uchar type; };
1046 template <> struct uchar_type<double, int> { typedef uchar type; };
1047 template <> struct uchar_type<double, unsigned int> { typedef uchar type; };
1048 template <> struct uchar_type<double, float> { typedef uchar type; };
1049 template <> struct uchar_type<double, double> { typedef uchar type; };
1050 template <> struct uchar_type<double, long long> { typedef uchar type; };
1051 template <> struct uchar_type<double, unsigned long long> { typedef uchar type; };
1052
1053 template <> struct uchar_type<long long, char> { typedef uchar type; };
1054 template <> struct uchar_type<long long, unsigned char> { typedef uchar type; };
1055 template <> struct uchar_type<long long, short> { typedef uchar type; };
1056 template <> struct uchar_type<long long, unsigned short> { typedef uchar type; };
1057 template <> struct uchar_type<long long, int> { typedef uchar type; };
1058 template <> struct uchar_type<long long, unsigned int> { typedef uchar type; };
1059 template <> struct uchar_type<long long, float> { typedef uchar type; };
1060 template <> struct uchar_type<long long, double> { typedef uchar type; };
1061 template <> struct uchar_type<long long, long long> { typedef uchar type; };
1062 template <> struct uchar_type<long long, unsigned long long> { typedef uchar type; };
1063
1064 template <> struct uchar_type<unsigned long long, char> { typedef uchar type; };
1065 template <> struct uchar_type<unsigned long long, unsigned char> { typedef uchar type; };
1066 template <> struct uchar_type<unsigned long long, short> { typedef uchar type; };
1067 template <> struct uchar_type<unsigned long long, unsigned short> { typedef uchar type; };
1068 template <> struct uchar_type<unsigned long long, int> { typedef uchar type; };
1069 template <> struct uchar_type<unsigned long long, unsigned int> { typedef uchar type; };
1070 template <> struct uchar_type<unsigned long long, float> { typedef uchar type; };
1071 template <> struct uchar_type<unsigned long long, double> { typedef uchar type; };
1072 template <> struct uchar_type<unsigned long long, long long> { typedef uchar type; };
1073 template <> struct uchar_type<unsigned long long, unsigned long long> { typedef uchar type; };
1074
1075 template <typename T1, typename T2> struct ushort_type {
1076 private:
1077 ushort_type();
1078 };
1079 template <> struct ushort_type<char, char> { typedef ushort type; };
1080 template <> struct ushort_type<char, unsigned char> { typedef ushort type; };
1081 template <> struct ushort_type<char, short> { typedef ushort type; };
1082 template <> struct ushort_type<char, unsigned short> { typedef ushort type; };
1083 template <> struct ushort_type<char, int> { typedef ushort type; };
1084 template <> struct ushort_type<char, unsigned int> { typedef ushort type; };
1085 template <> struct ushort_type<char, float> { typedef ushort type; };
1086 template <> struct ushort_type<char, double> { typedef ushort type; };
1087 template <> struct ushort_type<char, long long> { typedef ushort type; };
1088 template <> struct ushort_type<char, unsigned long long> { typedef ushort type; };
1089
1090 template <> struct ushort_type<unsigned char, char> { typedef ushort type; };
1091 template <> struct ushort_type<unsigned char, unsigned char> { typedef ushort type; };
1092 template <> struct ushort_type<unsigned char, short> { typedef ushort type; };
1093 template <> struct ushort_type<unsigned char, unsigned short> { typedef ushort type; };
1094 template <> struct ushort_type<unsigned char, int> { typedef ushort type; };
1095 template <> struct ushort_type<unsigned char, unsigned int> { typedef ushort type; };
1096 template <> struct ushort_type<unsigned char, float> { typedef ushort type; };
1097 template <> struct ushort_type<unsigned char, double> { typedef ushort type; };
1098 template <> struct ushort_type<unsigned char, long long> { typedef ushort type; };
1099 template <> struct ushort_type<unsigned char, unsigned long long> { typedef ushort type; };
1100
1101 template <> struct ushort_type<short, char> { typedef ushort type; };
1102 template <> struct ushort_type<short, unsigned char> { typedef ushort type; };
1103 template <> struct ushort_type<short, short> { typedef ushort type; };
1104 template <> struct ushort_type<short, unsigned short> { typedef ushort type; };
1105 template <> struct ushort_type<short, int> { typedef ushort type; };
1106 template <> struct ushort_type<short, unsigned int> { typedef ushort type; };
1107 template <> struct ushort_type<short, float> { typedef ushort type; };
1108 template <> struct ushort_type<short, double> { typedef ushort type; };
1109 template <> struct ushort_type<short, long long> { typedef ushort type; };
1110 template <> struct ushort_type<short, unsigned long long> { typedef ushort type; };
1111
1112 template <> struct ushort_type<unsigned short, char> { typedef ushort type; };
1113 template <> struct ushort_type<unsigned short, unsigned char> { typedef ushort type; };
1114 template <> struct ushort_type<unsigned short, short> { typedef ushort type; };
1115 template <> struct ushort_type<unsigned short, unsigned short> { typedef ushort type; };
1116 template <> struct ushort_type<unsigned short, int> { typedef ushort type; };
1117 template <> struct ushort_type<unsigned short, unsigned int> { typedef ushort type; };
1118 template <> struct ushort_type<unsigned short, float> { typedef ushort type; };
1119 template <> struct ushort_type<unsigned short, double> { typedef ushort type; };
1120 template <> struct ushort_type<unsigned short, long long> { typedef ushort type; };
1121 template <> struct ushort_type<unsigned short, unsigned long long> { typedef ushort type; };
1122
1123 template <> struct ushort_type<int, char> { typedef ushort type; };
1124 template <> struct ushort_type<int, unsigned char> { typedef ushort type; };
1125 template <> struct ushort_type<int, short> { typedef ushort type; };
1126 template <> struct ushort_type<int, unsigned short> { typedef ushort type; };
1127 template <> struct ushort_type<int, int> { typedef ushort type; };
1128 template <> struct ushort_type<int, unsigned int> { typedef ushort type; };
1129 template <> struct ushort_type<int, float> { typedef ushort type; };
1130 template <> struct ushort_type<int, double> { typedef ushort type; };
1131 template <> struct ushort_type<int, long long> { typedef ushort type; };
1132 template <> struct ushort_type<int, unsigned long long> { typedef ushort type; };
1133
1134 template <> struct ushort_type<unsigned int, char> { typedef ushort type; };
1135 template <> struct ushort_type<unsigned int, unsigned char> { typedef ushort type; };
1136 template <> struct ushort_type<unsigned int, short> { typedef ushort type; };
1137 template <> struct ushort_type<unsigned int, unsigned short> { typedef ushort type; };
1138 template <> struct ushort_type<unsigned int, int> { typedef ushort type; };
1139 template <> struct ushort_type<unsigned int, unsigned int> { typedef ushort type; };
1140 template <> struct ushort_type<unsigned int, float> { typedef ushort type; };
1141 template <> struct ushort_type<unsigned int, double> { typedef ushort type; };
1142 template <> struct ushort_type<unsigned int, long long> { typedef ushort type; };
1143 template <> struct ushort_type<unsigned int, unsigned long long> { typedef ushort type; };
1144
1145 template <> struct ushort_type<float, char> { typedef ushort type; };
1146 template <> struct ushort_type<float, unsigned char> { typedef ushort type; };
1147 template <> struct ushort_type<float, short> { typedef ushort type; };
1148 template <> struct ushort_type<float, unsigned short> { typedef ushort type; };
1149 template <> struct ushort_type<float, int> { typedef ushort type; };
1150 template <> struct ushort_type<float, unsigned int> { typedef ushort type; };
1151 template <> struct ushort_type<float, float> { typedef ushort type; };
1152 template <> struct ushort_type<float, double> { typedef ushort type; };
1153 template <> struct ushort_type<float, long long> { typedef ushort type; };
1154 template <> struct ushort_type<float, unsigned long long> { typedef ushort type; };
1155
1156 template <> struct ushort_type<double, char> { typedef ushort type; };
1157 template <> struct ushort_type<double, unsigned char> { typedef ushort type; };
1158 template <> struct ushort_type<double, short> { typedef ushort type; };
1159 template <> struct ushort_type<double, unsigned short> { typedef ushort type; };
1160 template <> struct ushort_type<double, int> { typedef ushort type; };
1161 template <> struct ushort_type<double, unsigned int> { typedef ushort type; };
1162 template <> struct ushort_type<double, float> { typedef ushort type; };
1163 template <> struct ushort_type<double, double> { typedef ushort type; };
1164 template <> struct ushort_type<double, long long> { typedef ushort type; };
1165 template <> struct ushort_type<double, unsigned long long> { typedef ushort type; };
1166
1167 template <> struct ushort_type<long long, char> { typedef ushort type; };
1168 template <> struct ushort_type<long long, unsigned char> { typedef ushort type; };
1169 template <> struct ushort_type<long long, short> { typedef ushort type; };
1170 template <> struct ushort_type<long long, unsigned short> { typedef ushort type; };
1171 template <> struct ushort_type<long long, int> { typedef ushort type; };
1172 template <> struct ushort_type<long long, unsigned int> { typedef ushort type; };
1173 template <> struct ushort_type<long long, float> { typedef ushort type; };
1174 template <> struct ushort_type<long long, double> { typedef ushort type; };
1175 template <> struct ushort_type<long long, long long> { typedef ushort type; };
1176 template <> struct ushort_type<long long, unsigned long long> { typedef ushort type; };
1177
1178 template <> struct ushort_type<unsigned long long, char> { typedef ushort type; };
1179 template <> struct ushort_type<unsigned long long, unsigned char> { typedef ushort type; };
1180 template <> struct ushort_type<unsigned long long, short> { typedef ushort type; };
1181 template <> struct ushort_type<unsigned long long, unsigned short> { typedef ushort type; };
1182 template <> struct ushort_type<unsigned long long, int> { typedef ushort type; };
1183 template <> struct ushort_type<unsigned long long, unsigned int> { typedef ushort type; };
1184 template <> struct ushort_type<unsigned long long, float> { typedef ushort type; };
1185 template <> struct ushort_type<unsigned long long, double> { typedef ushort type; };
1186 template <> struct ushort_type<unsigned long long, long long> { typedef ushort type; };
1187 template <> struct ushort_type<unsigned long long, unsigned long long> { typedef ushort type; };
1188
1189 template <typename T1, typename T2> struct uint_type {
1190 private:
1191 uint_type();
1192 };
1193 template <> struct uint_type<char, char> { typedef uint type; };
1194 template <> struct uint_type<char, unsigned char> { typedef uint type; };
1195 template <> struct uint_type<char, short> { typedef uint type; };
1196 template <> struct uint_type<char, unsigned short> { typedef uint type; };
1197 template <> struct uint_type<char, int> { typedef uint type; };
1198 template <> struct uint_type<char, unsigned int> { typedef uint type; };
1199 template <> struct uint_type<char, float> { typedef uint type; };
1200 template <> struct uint_type<char, double> { typedef uint type; };
1201 template <> struct uint_type<char, long long> { typedef uint type; };
1202 template <> struct uint_type<char, unsigned long long> { typedef uint type; };
1203
1204 template <> struct uint_type<unsigned char, char> { typedef uint type; };
1205 template <> struct uint_type<unsigned char, unsigned char> { typedef uint type; };
1206 template <> struct uint_type<unsigned char, short> { typedef uint type; };
1207 template <> struct uint_type<unsigned char, unsigned short> { typedef uint type; };
1208 template <> struct uint_type<unsigned char, int> { typedef uint type; };
1209 template <> struct uint_type<unsigned char, unsigned int> { typedef uint type; };
1210 template <> struct uint_type<unsigned char, float> { typedef uint type; };
1211 template <> struct uint_type<unsigned char, double> { typedef uint type; };
1212 template <> struct uint_type<unsigned char, long long> { typedef uint type; };
1213 template <> struct uint_type<unsigned char, unsigned long long> { typedef uint type; };
1214
1215 template <> struct uint_type<short, char> { typedef uint type; };
1216 template <> struct uint_type<short, unsigned char> { typedef uint type; };
1217 template <> struct uint_type<short, short> { typedef uint type; };
1218 template <> struct uint_type<short, unsigned short> { typedef uint type; };
1219 template <> struct uint_type<short, int> { typedef uint type; };
1220 template <> struct uint_type<short, unsigned int> { typedef uint type; };
1221 template <> struct uint_type<short, float> { typedef uint type; };
1222 template <> struct uint_type<short, double> { typedef uint type; };
1223 template <> struct uint_type<short, long long> { typedef uint type; };
1224 template <> struct uint_type<short, unsigned long long> { typedef uint type; };
1225
1226 template <> struct uint_type<unsigned short, char> { typedef uint type; };
1227 template <> struct uint_type<unsigned short, unsigned char> { typedef uint type; };
1228 template <> struct uint_type<unsigned short, short> { typedef uint type; };
1229 template <> struct uint_type<unsigned short, unsigned short> { typedef uint type; };
1230 template <> struct uint_type<unsigned short, int> { typedef uint type; };
1231 template <> struct uint_type<unsigned short, unsigned int> { typedef uint type; };
1232 template <> struct uint_type<unsigned short, float> { typedef uint type; };
1233 template <> struct uint_type<unsigned short, double> { typedef uint type; };
1234 template <> struct uint_type<unsigned short, long long> { typedef uint type; };
1235 template <> struct uint_type<unsigned short, unsigned long long> { typedef uint type; };
1236
1237 template <> struct uint_type<int, char> { typedef uint type; };
1238 template <> struct uint_type<int, unsigned char> { typedef uint type; };
1239 template <> struct uint_type<int, short> { typedef uint type; };
1240 template <> struct uint_type<int, unsigned short> { typedef uint type; };
1241 template <> struct uint_type<int, int> { typedef uint type; };
1242 template <> struct uint_type<int, unsigned int> { typedef uint type; };
1243 template <> struct uint_type<int, float> { typedef uint type; };
1244 template <> struct uint_type<int, double> { typedef uint type; };
1245 template <> struct uint_type<int, long long> { typedef uint type; };
1246 template <> struct uint_type<int, unsigned long long> { typedef uint type; };
1247
1248 template <> struct uint_type<unsigned int, char> { typedef uint type; };
1249 template <> struct uint_type<unsigned int, unsigned char> { typedef uint type; };
1250 template <> struct uint_type<unsigned int, short> { typedef uint type; };
1251 template <> struct uint_type<unsigned int, unsigned short> { typedef uint type; };
1252 template <> struct uint_type<unsigned int, int> { typedef uint type; };
1253 template <> struct uint_type<unsigned int, unsigned int> { typedef uint type; };
1254 template <> struct uint_type<unsigned int, float> { typedef uint type; };
1255 template <> struct uint_type<unsigned int, double> { typedef uint type; };
1256 template <> struct uint_type<unsigned int, long long> { typedef uint type; };
1257 template <> struct uint_type<unsigned int, unsigned long long> { typedef uint type; };
1258
1259 template <> struct uint_type<float, char> { typedef uint type; };
1260 template <> struct uint_type<float, unsigned char> { typedef uint type; };
1261 template <> struct uint_type<float, short> { typedef uint type; };
1262 template <> struct uint_type<float, unsigned short> { typedef uint type; };
1263 template <> struct uint_type<float, int> { typedef uint type; };
1264 template <> struct uint_type<float, unsigned int> { typedef uint type; };
1265 template <> struct uint_type<float, float> { typedef uint type; };
1266 template <> struct uint_type<float, double> { typedef uint type; };
1267 template <> struct uint_type<float, long long> { typedef uint type; };
1268 template <> struct uint_type<float, unsigned long long> { typedef uint type; };
1269
1270 template <> struct uint_type<double, char> { typedef uint type; };
1271 template <> struct uint_type<double, unsigned char> { typedef uint type; };
1272 template <> struct uint_type<double, short> { typedef uint type; };
1273 template <> struct uint_type<double, unsigned short> { typedef uint type; };
1274 template <> struct uint_type<double, int> { typedef uint type; };
1275 template <> struct uint_type<double, unsigned int> { typedef uint type; };
1276 template <> struct uint_type<double, float> { typedef uint type; };
1277 template <> struct uint_type<double, double> { typedef uint type; };
1278 template <> struct uint_type<double, long long> { typedef uint type; };
1279 template <> struct uint_type<double, unsigned long long> { typedef uint type; };
1280
1281 template <> struct uint_type<long long, char> { typedef uint type; };
1282 template <> struct uint_type<long long, unsigned char> { typedef uint type; };
1283 template <> struct uint_type<long long, short> { typedef uint type; };
1284 template <> struct uint_type<long long, unsigned short> { typedef uint type; };
1285 template <> struct uint_type<long long, int> { typedef uint type; };
1286 template <> struct uint_type<long long, unsigned int> { typedef uint type; };
1287 template <> struct uint_type<long long, float> { typedef uint type; };
1288 template <> struct uint_type<long long, double> { typedef uint type; };
1289 template <> struct uint_type<long long, long long> { typedef uint type; };
1290 template <> struct uint_type<long long, unsigned long long> { typedef uint type; };
1291
1292 template <> struct uint_type<unsigned long long, char> { typedef uint type; };
1293 template <> struct uint_type<unsigned long long, unsigned char> { typedef uint type; };
1294 template <> struct uint_type<unsigned long long, short> { typedef uint type; };
1295 template <> struct uint_type<unsigned long long, unsigned short> { typedef uint type; };
1296 template <> struct uint_type<unsigned long long, int> { typedef uint type; };
1297 template <> struct uint_type<unsigned long long, unsigned int> { typedef uint type; };
1298 template <> struct uint_type<unsigned long long, float> { typedef uint type; };
1299 template <> struct uint_type<unsigned long long, double> { typedef uint type; };
1300 template <> struct uint_type<unsigned long long, long long> { typedef uint type; };
1301 template <> struct uint_type<unsigned long long, unsigned long long> { typedef uint type; };
1302
1303 template <typename T1> struct int_uint_type {
1304 private:
1305 int_uint_type();
1306 };
1307 template <> struct int_uint_type<char> { typedef int type; };
1308 template <> struct int_uint_type<short> { typedef int type; };
1309 template <> struct int_uint_type<int> { typedef int type; };
1310 template <> struct int_uint_type<long long> { typedef long long type; };
1311 template <> struct int_uint_type<unsigned char> { typedef unsigned int type; };
1312 template <> struct int_uint_type<unsigned short> { typedef unsigned int type; };
1313 template <> struct int_uint_type<unsigned int> { typedef unsigned int type; };
1314 template <> struct int_uint_type<unsigned long long> { typedef unsigned long long type; };
1315
1316 template <typename T1, typename T2> struct restype_sat {
1317 private:
1318 restype_sat();
1319 };
1320
1321 template <> struct restype_sat<char, char> { typedef int type; };
1322 template <> struct restype_sat<char, unsigned char> { typedef int type; };
1323 template <> struct restype_sat<char, short> { typedef int type; };
1324 template <> struct restype_sat<char, unsigned short> { typedef int type; };
1325 template <> struct restype_sat<char, int> { typedef long long type; };
1326 template <> struct restype_sat<char, unsigned int> { typedef long long type; };
1327 template <> struct restype_sat<char, float> { typedef float type; };
1328 template <> struct restype_sat<char, double> { typedef double type; };
1329 template <> struct restype_sat<char, long long> { typedef long long type; };
1330 template <> struct restype_sat<char, unsigned long long> { typedef long long type; };
1331
1332 template <> struct restype_sat<unsigned char, char> { typedef int type; };
1333 template <> struct restype_sat<unsigned char, unsigned char> { typedef int type; };
1334 template <> struct restype_sat<unsigned char, short> { typedef int type; };
1335 template <> struct restype_sat<unsigned char, unsigned short> { typedef int type; };
1336 template <> struct restype_sat<unsigned char, int> { typedef long long type; };
1337 template <> struct restype_sat<unsigned char, unsigned int> { typedef long long type; };
1338 template <> struct restype_sat<unsigned char, float> { typedef float type; };
1339 template <> struct restype_sat<unsigned char, double> { typedef double type; };
1340 template <> struct restype_sat<unsigned char, long long> { typedef long long type; };
1341 template <> struct restype_sat<unsigned char, unsigned long long> { typedef long long type; };
1342
1343 template <> struct restype_sat<short, char> { typedef int type; };
1344 template <> struct restype_sat<short, unsigned char> { typedef int type; };
1345 template <> struct restype_sat<short, short> { typedef int type; };
1346 template <> struct restype_sat<short, unsigned short> { typedef int type; };
1347 template <> struct restype_sat<short, int> { typedef long long type; };
1348 template <> struct restype_sat<short, unsigned int> { typedef long long type; };
1349 template <> struct restype_sat<short, float> { typedef float type; };
1350 template <> struct restype_sat<short, double> { typedef double type; };
1351 template <> struct restype_sat<short, long long> { typedef long long type; };
1352 template <> struct restype_sat<short, unsigned long long> { typedef long long type; };
1353
1354 template <> struct restype_sat<unsigned short, char> { typedef int type; };
1355 template <> struct restype_sat<unsigned short, unsigned char> { typedef int type; };
1356 template <> struct restype_sat<unsigned short, short> { typedef int type; };
1357 template <> struct restype_sat<unsigned short, unsigned short> { typedef unsigned int type; };
1358 template <> struct restype_sat<unsigned short, int> { typedef long long type; };
1359 template <> struct restype_sat<unsigned short, unsigned int> { typedef long long type; };
1360 template <> struct restype_sat<unsigned short, float> { typedef float type; };
1361 template <> struct restype_sat<unsigned short, double> { typedef double type; };
1362 template <> struct restype_sat<unsigned short, long long> { typedef long long type; };
1363 template <> struct restype_sat<unsigned short, unsigned long long> { typedef long long type; };
1364
1365 template <> struct restype_sat<int, char> { typedef long long type; };
1366 template <> struct restype_sat<int, unsigned char> { typedef long long type; };
1367 template <> struct restype_sat<int, short> { typedef long long type; };
1368 template <> struct restype_sat<int, unsigned short> { typedef long long type; };
1369 template <> struct restype_sat<int, int> { typedef long long type; };
1370 template <> struct restype_sat<int, unsigned int> { typedef long long type; };
1371 template <> struct restype_sat<int, float> { typedef float type; };
1372 template <> struct restype_sat<int, double> { typedef double type; };
1373 template <> struct restype_sat<int, long long> { typedef long long type; };
1374 template <> struct restype_sat<int, unsigned long long> { typedef long long type; };
1375
1376 template <> struct restype_sat<unsigned int, char> { typedef long long type; };
1377 template <> struct restype_sat<unsigned int, unsigned char> { typedef long long type; };
1378 template <> struct restype_sat<unsigned int, short> { typedef long long type; };
1379 template <> struct restype_sat<unsigned int, unsigned short> { typedef long long type; };
1380 template <> struct restype_sat<unsigned int, int> { typedef long long type; };
1381 template <> struct restype_sat<unsigned int, unsigned int> { typedef long long type; };
1382 template <> struct restype_sat<unsigned int, float> { typedef float type; };
1383 template <> struct restype_sat<unsigned int, double> { typedef double type; };
1384 template <> struct restype_sat<unsigned int, long long> { typedef long long type; };
1385 template <> struct restype_sat<unsigned int, unsigned long long> { typedef long long type; };
1386
1387 template <> struct restype_sat<float, char> { typedef float type; };
1388 template <> struct restype_sat<float, unsigned char> { typedef float type; };
1389 template <> struct restype_sat<float, short> { typedef float type; };
1390 template <> struct restype_sat<float, unsigned short> { typedef float type; };
1391 template <> struct restype_sat<float, int> { typedef float type; };
1392 template <> struct restype_sat<float, unsigned int> { typedef float type; };
1393 template <> struct restype_sat<float, float> { typedef float type; };
1394 template <> struct restype_sat<float, double> { typedef double type; };
1395
1396 template <> struct restype_sat<double, char> { typedef double type; };
1397 template <> struct restype_sat<double, unsigned char> { typedef double type; };
1398 template <> struct restype_sat<double, short> { typedef double type; };
1399 template <> struct restype_sat<double, unsigned short> { typedef double type; };
1400 template <> struct restype_sat<double, int> { typedef double type; };
1401 template <> struct restype_sat<double, unsigned int> { typedef double type; };
1402 template <> struct restype_sat<double, float> { typedef double type; };
1403 template <> struct restype_sat<double, double> { typedef double type; };
1404 template <> struct restype_sat<double, long long> { typedef double type; };
1405 template <> struct restype_sat<double, unsigned long long> { typedef double type; };
1406
1407 template <typename T> struct abstype;
1408 template<> struct abstype<float> { typedef float type; };
1409 template<> struct abstype<char> { typedef uchar type; };
1410 template<> struct abstype<short> { typedef ushort type; };
1411 template<> struct abstype<int> { typedef int type; };
1412 template<> struct abstype<uchar> { typedef uchar type; };
1413 template<> struct abstype<ushort> { typedef ushort type; };
1414 template<> struct abstype<uint> { typedef uint type; };
1415 template<> struct abstype<double> { typedef double type; };
1416 template<> struct abstype<long long> { typedef unsigned long long type; };
1417 template<> struct abstype<unsigned long long> { typedef unsigned long long type; };
1418
1419 template <typename T>
1420 struct to_int {
1421 typedef T Int;
1422 };
1423 template<> struct to_int<float> { typedef int Int; };
1424 template<> struct to_int<double> { typedef int Int; };
1425
1426 template <bool VALUE> struct check_true{
1427 static const bool value = false;
1428 };
1429 template <> struct check_true<true> {
1430 static const bool value = true;
1431 };
1432
1433 template <typename T> struct inttype;
1434 template <> struct inttype<char> {
1435 static const bool value = true;
1436 };
1437 template <> struct inttype<unsigned char> {
1438 static const bool value = true;
1439 };
1440 template <> struct inttype<short> {
1441 static const bool value = true;
1442 };
1443 template <> struct inttype<unsigned short> {
1444 static const bool value = true;
1445 };
1446 template <> struct inttype<int> {
1447 static const bool value = true;
1448 };
1449 template <> struct inttype<unsigned int> {
1450 static const bool value = true;
1451 };
1452 template <> struct inttype<long long> {
1453 static const bool value = true;
1454 };
1455 template <> struct inttype<unsigned long long> {
1456 static const bool value = true;
1457 };
1458
1459 template <typename T> struct is_inttype {
1460 static const bool value = false;
1461 };
1462 template <> struct is_inttype<char> {
1463 static const bool value = true;
1464 };
1465 template <> struct is_inttype<unsigned char> {
1466 static const bool value = true;
1467 };
1468 template <> struct is_inttype<short> {
1469 static const bool value = true;
1470 };
1471 template <> struct is_inttype<unsigned short> {
1472 static const bool value = true;
1473 };
1474 template <> struct is_inttype<int> {
1475 static const bool value = true;
1476 };
1477 template <> struct is_inttype<unsigned int> {
1478 static const bool value = true;
1479 };
1480 template <> struct is_inttype<long long> {
1481 static const bool value = true;
1482 };
1483 template <> struct is_inttype<unsigned long long> {
1484 static const bool value = true;
1485 };
1486
1487 template <typename T> struct is_byte_type {
1488 static const bool value = false;
1489 };
1490 template <> struct is_byte_type<char> {
1491 static const bool value = true;
1492 };
1493 template <> struct is_byte_type<uchar> {
1494 static const bool value = true;
1495 };
1496
1497 template <typename T> struct is_word_type {
1498 static const bool value = false;
1499 };
1500 template <> struct is_word_type<short> {
1501 static const bool value = true;
1502 };
1503 template <> struct is_word_type<ushort> {
1504 static const bool value = true;
1505 };
1506
1507 template <typename T> struct is_dword_type {
1508 static const bool value = false;
1509 };
1510 template <> struct is_dword_type<int> {
1511 static const bool value = true;
1512 };
1513 template <> struct is_dword_type<uint> {
1514 static const bool value = true;
1515 };
1516
1517 template <typename T> struct is_hf_type {
1518 static const bool value = false;
1519 };
1520
1521 template <typename T> struct is_fp_type {
1522 static const bool value = false;
1523 };
1524 template <> struct is_fp_type<float> {
1525 static const bool value = true;
1526 };
1527
1528 template <typename T> struct is_df_type {
1529 static const bool value = false;
1530 };
1531 template <> struct is_df_type<double> {
1532 static const bool value = true;
1533 };
1534
1535 template <typename T> struct is_fp_or_dword_type {
1536 static const bool value = false;
1537 };
1538 template <> struct is_fp_or_dword_type<int> {
1539 static const bool value = true;
1540 };
1541 template <> struct is_fp_or_dword_type<uint> {
1542 static const bool value = true;
1543 };
1544 template <> struct is_fp_or_dword_type<float> {
1545 static const bool value = true;
1546 };
1547 // The check is only used for dataport APIs,
1548 // which also support df data type.
1549 template <> struct is_fp_or_dword_type<double> {
1550 static const bool value = true;
1551 };
1552
1553 template <typename T> struct is_ushort_type {
1554 static const bool value = false;
1555 };
1556 template <> struct is_ushort_type<ushort> {
1557 static const bool value = true;
1558 };
1559
1560 template <typename T1, typename T2> struct is_float_dword {
1561 static const bool value = false;
1562 };
1563 template <> struct is_float_dword<float, int> {
1564 static const bool value = true;
1565 };
1566 template <> struct is_float_dword<float, uint> {
1567 static const bool value = true;
1568 };
1569 template <> struct is_float_dword<int, float> {
1570 static const bool value = true;
1571 };
1572 template <> struct is_float_dword<uint, float> {
1573 static const bool value = true;
1574 };
1575
1576 template <typename T> struct hftype {
1577 static const bool value = false;
1578 };
1579
1580 template <typename T> struct fptype {
1581 static const bool value = false;
1582 };
1583 template <> struct fptype<float> {
1584 static const bool value = true;
1585 };
1586
1587 template <typename T> struct dftype {
1588 static const bool value = false;
1589 };
1590 template <> struct dftype<double> {
1591 static const bool value = true;
1592 };
1593
1594 template <typename T> struct cmtype;
1595 template <> struct cmtype<char> {
1596 static const bool value = true;
1597 };
1598
1599 template <> struct cmtype<signed char> {
1600 static const bool value = true;
1601 };
1602
1603 template <> struct cmtype<unsigned char> {
1604 static const bool value = true;
1605 };
1606
1607 template <> struct cmtype<short> {
1608 static const bool value = true;
1609 };
1610
1611 template <> struct cmtype<unsigned short> {
1612 static const bool value = true;
1613 };
1614 template <> struct cmtype<int> {
1615 static const bool value = true;
1616 };
1617
1618 template <> struct cmtype<unsigned int> {
1619 static const bool value = true;
1620 };
1621
1622 template <> struct cmtype<unsigned long> {
1623 static const bool value = true;
1624 };
1625
1626 template <> struct cmtype<float> {
1627 static const bool value = true;
1628 };
1629
1630 template <> struct cmtype<double> {
1631 static const bool value = true;
1632 };
1633
1634 template <> struct cmtype<long long> {
1635 static const bool value = true;
1636 };
1637
1638 template <> struct cmtype<unsigned long long> {
1639 static const bool value = true;
1640 };
1641
1642 template <> struct cmtype<CMRT_UMD::SurfaceIndex> {
1643 static const bool value = true;
1644 };
1645
1646 template<typename T> struct bytetype;
1647 template<> struct bytetype<char> {
1648 static const bool value = true;
1649 };
1650 template<> struct bytetype<uchar> {
1651 static const bool value = true;
1652 };
1653
1654 template<typename T> struct wordtype;
1655 template<> struct wordtype<short> {
1656 static const bool value = true;
1657 };
1658 template<> struct wordtype<ushort> {
1659 static const bool value = true;
1660 };
1661
1662 template<typename T> struct dwordtype;
1663 template<> struct dwordtype<int> {
1664 static const bool value = true;
1665 };
1666 template<> struct dwordtype<uint> {
1667 static const bool value = true;
1668 };
1669
1670 template<typename T> struct unsignedtype{
1671 static const bool value = false;
1672 };
1673 template<> struct unsignedtype<uint> {
1674 static const bool value = true;
1675 };
1676 template<> struct unsignedtype<ushort> {
1677 static const bool value = true;
1678 };
1679 template<> struct unsignedtype<uchar> {
1680 static const bool value = true;
1681 };
1682 template<> struct unsignedtype<unsigned long long> {
1683 static const bool value = true;
1684 };
1685
1686 template<typename T> struct uinttype;
1687 template<> struct uinttype<uint> {
1688 static const bool value = true;
1689 };
1690
1691 template <uint N1, uint N2> struct ressize {
1692 static const uint size = (N1 > N2)?N1:N2;
1693 static const bool conformable = check_true<N1%size == 0 && N2%size == 0>::value;
1694 };
1695
1696 // used to control generation of compile time assertions
1697 #if defined(__CLANG_CM) && _MSC_VER >= 1600
1698 // CM_STATIC_ERROR uses the static_assert mechanism
1699 #include <assert.h>
1700 // type traits are often used in CM_STATIC_ERROR conditions
1701 #include <type_traits>
1702 #define CM_STATIC_ERROR(C,M) static_assert((C),"CM:e:" M)
1703 #define CM_STATIC_WARNING(C,M) static_assert((C),"CM:w:" M)
1704 #else
1705 #define CM_STATIC_ERROR(C,M)
1706 #define CM_STATIC_WARNING(C,M)
1707 #endif
1708
1709 #ifndef CM_COMMON_MACROS_H
1710 #define CM_COMMON_MACROS_H
1711
1712 #ifndef NEW_CM_RT
1713 #define NEW_CM_RT // Defined for new CM Runtime APIs
1714 #endif
1715
1716 #ifndef AUTO_CM_MODE_SET
1717 #if defined(__CM)
1718 /// Defined these macros for the Intel CM Compiler.
1719 #define _GENX_MAIN_ __attribute__((genx_main))
1720 #define _GENX_ __attribute__((genx))
1721 #define _GENX_STACKCALL_ __attribute__((genx_stackcall))
1722 #define _CM_INPUT_ __attribute__((cm_input))
1723 #define _CM_OUTPUT_ __attribute__((cm_output))
1724 #define _CM_INPUT_OUTPUT_ __attribute__(cm_input_output)
1725 #define _CM_OUTPUT_INPUT_ __attribute__(cm_input_output)
1726 #define _CM_CALLABLE_ __attribute__((cm_callable))
1727 #else
1728 /// Defined these macros for MSVC and GCC.
1729 #define CM_GENX
1730 #define _GENX_MAIN_
1731 #define _GENX_
1732 #define _GENX_STACKCALL_
1733 #define _CM_INPUT_
1734 #define _CM_OUTPUT_
1735 #define _CM_INPUT_OUTPUT_
1736 #define _CM_OUTPUT_INPUT_
1737 #define _CM_CALLABLE_
1738 #endif /* __CM */
1739 #define AUTO_CM_MODE_SET
1740 #endif /* AUTO_CM_MODE_SET */
1741
1742 #ifndef CM_NOINLINE
1743 #define CM_NOINLINE __attribute__((noinline))
1744 #endif
1745
1746 #ifndef CM_INLINE
1747 #define CM_INLINE inline __attribute__((always_inline))
1748 #endif
1749
1750 #ifndef CM_API
1751 #if defined(NEW_CM_RT) && defined(LIBCM_TEST_EXPORTS)
1752 #define CM_API __attribute__((visibility("default")))
1753 #elif defined(NEW_CM_RT)
1754 #define CM_API
1755 #else
1756 #define CM_API
1757 #endif
1758 #endif /* CM_API */
1759
1760 #ifndef CMRT_LIBCM_API
1761 #if defined(NEW_CM_RT) && defined(LIBCM_TEST_EXPORTS)
1762 #define CMRT_LIBCM_API __attribute__((visibility("default")))
1763 #elif defined(NEW_CM_RT)
1764 #define CMRT_LIBCM_API __attribute__((visibility("default")))
1765 #else
1766 #define CMRT_LIBCM_API
1767 #endif
1768 #endif /* CMRT_LIBCM_API */
1769
1770 #define CM_CHK_RESULT(cm_call) \
1771 do { \
1772 int result = cm_call; \
1773 if (result != CM_SUCCESS) { \
1774 fprintf(stderr, "Invalid CM call at %s:%d. Error %d: ", \
1775 __FILE__, __LINE__, result); \
1776 fprintf(stderr, ".\n"); \
1777 exit(EXIT_FAILURE); \
1778 } \
1779 } while(false)
1780
1781
1782 #endif
1783
1784 template <typename T, uint R, uint C> class matrix;
1785 template <typename T, uint R, uint C> class matrix_ref;
1786 template <typename T, uint SZ> class vector;
1787 template <typename T, uint SZ> class vector_ref;
1788
1789 namespace cm {
1790 template<typename ty>
1791 struct pointer_traits
1792 {
1793 enum { dim = 0 };
1794 typedef ty tail_pointee_type;
1795 };
1796
1797 template<typename ty, int n>
1798 struct pointer_traits<ty [n]>
1799 {
1800 enum { dim = pointer_traits<ty>::dim + 1 };
1801 typedef typename pointer_traits<ty>::tail_pointee_type tail_pointee_type;
1802 };
1803
1804 template<typename ty>
1805 struct pointer_traits<ty *>
1806 {
1807 enum { dim = pointer_traits<ty>::dim + 1 };
1808 typedef typename pointer_traits<ty>::tail_pointee_type tail_pointee_type;
1809 };
1810
1811 };
1812
1813 /* Basic stream. Non template class. */
1814 class basic_stream {
1815 public:
1816 virtual int extract_data(void *buf, uint size = 0xffffffff) = 0; /* extract datas to CmEmulSys::iobuffer */
1817 virtual void* get_addr(uint i) = 0; /* return address of data element */
1818 virtual void* get_addr_data() = 0;
1819 virtual void* get_addr_obj() = 0; /* return address of this */
1820 virtual uint get_size_of_element() const = 0; /* return size of one element */
1821 virtual uint get_number_of_elements() const = 0; /* return number of elements */
1822 virtual uint get_size_data() const = 0;
1823 virtual uint get_size_object() const =0;
1824 };
1825
1826 // stream
1827 template <typename T, uint SZ>
1828 class stream: public basic_stream {
1829 static const bool type_conformable = cmtype<T>::value;
1830 public:
1831 typedef T _Type;
1832
1833 CM_INLINE int n_elems() const { return SZ; }
1834
1835 virtual T get(uint i) const = 0; // call to this virtual function won't appear in IL0
1836 virtual T& getref(uint i) = 0; // call to this virtual function won't appear in IL0
1837 virtual void* get_addr(uint i) = 0; // call to this virtual function won't appear in IL0
1838 virtual void* get_addr_data() = 0;
1839 virtual void* get_addr_obj() =0;
1840 int extract_data(void *buf,uint size = 0xffffffff);
1841 virtual uint get_size_of_element() const { return sizeof(T);};
1842 virtual uint get_number_of_elements() const {return SZ;};
1843 virtual uint get_size_data() const = 0;
1844 virtual uint get_size_object() const =0;
1845
1846 /* merge */
1847 CM_NOINLINE void merge(const T x, const uint c);
1848 template <typename T1> void CM_NOINLINE merge(const stream<T1,SZ> &x, const uint c);
1849 template <typename T1, typename T2> CM_NOINLINE void merge(const stream<T1,SZ> &x, const stream<T2,SZ> &c);
1850 template <typename T1> CM_NOINLINE void merge(const T x, const stream<T1,SZ> &c);
1851 template <typename T1, typename T2> CM_NOINLINE void merge(const stream<T1,SZ>& x, const stream<T2,SZ>& y, const uint c);
1852 template <typename T1> CM_NOINLINE void merge(const T x, const stream<T1,SZ>& y, const uint c);
1853 template <typename T1> CM_NOINLINE void merge(const stream<T1,SZ>& x, const T y, const uint c);
1854 CM_NOINLINE void merge(const T x, const T y, const uint c);
1855 template <typename T1, typename T2, typename T3> CM_NOINLINE void merge(const stream<T1,SZ>& x, const stream<T2,SZ>& y, const stream<T3,SZ>& c);
1856 template <typename T1, typename T2> CM_NOINLINE void merge(const T x, const stream<T1,SZ>& y, const stream<T2,SZ>& c);
1857 template <typename T1, typename T2> CM_NOINLINE void merge(const stream<T1,SZ>& x, const T y, const stream<T2,SZ>& c);
1858 template <typename T1> CM_NOINLINE void merge(const T x, const T y, const stream<T1,SZ>& c);
1859
1860 // any,all
1861 CM_NOINLINE ushort any( void ) const;
1862 CM_NOINLINE ushort all( void ) const;
1863
1864 // for debug
1865 #ifdef CM_DEBUG
1866 virtual std::string type_name() const = 0;
1867 virtual std::string obj_name() const = 0;
1868 #endif /* CM_DEBUG */
1869 };
1870
1871 // matrix
1872 template <typename T, uint R, uint C>
1873 class matrix : public stream<T,R*C> {
1874 public:
1875 template <typename T1, uint R1, uint C1> friend class matrix;
1876 template <typename T1, uint R1, uint C1> friend class matrix_ref;
1877 template <typename T1, uint SZ1> friend class vector;
1878 template <typename T1, uint SZ1> friend class vector_ref;
1879
1880 enum { SZ = R*C };
1881 enum { ROWS=R, COLS=C, ELEMS=R*C };
1882
1883 CM_INLINE int n_rows() const { return R; }
1884 CM_INLINE int n_cols() const { return C; }
1885
1886 template <uint REP> CM_INLINE
1887 const vector<T, R*C*REP> replicate(OFFSET ioff=0, OFFSET joff=0)
1888 { return genx_select<REP,0,R*C,1>(ioff, joff); };
1889 template <uint REP, uint W> CM_INLINE
1890 const vector<T, W*REP> replicate(OFFSET ioff=0, OFFSET joff=0)
1891 { return genx_select<REP,0,W,1>(ioff, joff); };
1892 template <uint REP, uint VS, uint W> CM_INLINE
1893 const vector<T, W*REP> replicate(OFFSET ioff=0, OFFSET joff=0)
1894 { return genx_select<REP,VS,W,1>(ioff, joff); };
1895 template <uint REP, uint VS, uint W, uint HS> CM_INLINE
1896 const vector<T, W*REP> replicate(OFFSET ioff=0, OFFSET joff=0)
1897 { return genx_select<REP,VS,W,HS>(ioff, joff); };
1898
1899 virtual T get(uint i) const { return data[i]; }
1900 virtual T& getref(uint i) { return data[i]; }
1901 virtual void* get_addr(uint i) { return &data[i]; }
1902 virtual void* get_addr_data() {
1903 return &data[0];
1904 }
1905 virtual void* get_addr_obj() { return this; }
1906 virtual uint get_size_data() const {
1907 return sizeof(data);
1908 }
1909 virtual uint get_size_object() const { return sizeof(*this); }
1910
1911 CM_NOINLINE T operator () (OFFSET i, OFFSET j) const {
1912 assert(i < R && j < C);
1913 return get(i*C+j);
1914 }
1915
1916 CM_NOINLINE T& operator () (OFFSET i, OFFSET j) {
1917 assert(i < R && j < C);
1918 return data[i*C+j];
1919 }
1920
1921 template <typename T1, uint R1, uint C1>
1922 class inner_hack {
1923 matrix* m_t;
1924 OFFSET _i;
1925 public:
1926 inner_hack(matrix* m, OFFSET i):m_t(m){_i=i;}
1927 CM_NOINLINE const T1 operator[](OFFSET j) const{return (*m_t)(_i,j);}
1928 CM_NOINLINE T1& operator[](OFFSET j){return (*m_t)(_i,j);}
1929
1930 };
1931
1932 CM_NOINLINE inner_hack<T,R,C> operator [] (OFFSET i) const {
1933 return inner_hack<T,R,C>(this,i);
1934 }
1935
1936 CM_NOINLINE inner_hack<T,R,C> operator [] (OFFSET i) {
1937 return inner_hack<T,R,C>(this,i);
1938 }
1939
1940 // constructors
1941 CM_NOINLINE matrix();
1942 // CM_NOINLINE matrix(void *ptr); /* constructor for preload datas from URB */
1943 template <typename T2> CM_NOINLINE matrix(const T2 initArray[]); // constructor with array initializer
1944 CM_NOINLINE matrix(const matrix<T,R,C>& src); // copy constructor
1945 template <typename T2> CM_NOINLINE matrix(const T2& src);
1946 template <typename T2, uint R2, uint C2> CM_NOINLINE matrix(const matrix<T2,R2,C2>& src, const uint sat = 0 );
1947 template <typename T2, uint R2, uint C2> CM_NOINLINE matrix(const matrix_ref<T2,R2,C2>& src, const uint sat = 0);
1948 template <typename T2> CM_NOINLINE matrix(const vector<T2,R*C>& src)
1949 { new (this) matrix<T,R,C>((matrix<T2,1,R*C>&)src); }
1950
1951 template <typename T2> CM_NOINLINE matrix(const vector_ref<T2,R*C>& src)
1952 { new (this) matrix<T,R,C>((matrix_ref<T2,1,R*C>&)src); }
1953
1954 //operator =
1955 CM_NOINLINE matrix<T,R,C>& operator = (const matrix<T,R,C>& src); // assignment operator
1956 template <typename T2> CM_NOINLINE matrix<T,R,C>& operator = (const T2 src);
1957 template <typename T2, uint R2, uint C2> CM_NOINLINE matrix<T,R,C>& operator = (const matrix<T2,R2,C2>& src);
1958 template <typename T2, uint R2, uint C2> CM_NOINLINE matrix<T,R,C>& operator = (const matrix_ref<T2,R2,C2>& src);
1959 template <typename T2> CM_NOINLINE matrix<T,R,C>& operator = (const vector<T2,R*C>& src) { return this->operator=((const matrix<T2,1,R*C>&)src); };
1960 template <typename T2> CM_NOINLINE matrix<T,R,C>& operator = (const vector_ref<T2,R*C>& src) { return this->operator=((const matrix_ref<T2,1,R*C>&)src); };
1961
1962 //selects
1963 template <typename T2> CM_NOINLINE vector_ref<T2,R*C*sizeof(T)/sizeof(T2)> format(); // to vector
1964 template <typename T2, uint R2, uint C2> CM_NOINLINE matrix_ref<T2,R2,C2> format(); // to matrix R2xC2
1965 template <typename T2> CM_NOINLINE const vector_ref<T2,R*C*sizeof(T)/sizeof(T2)> format() const; // to vector
1966 template <typename T2, uint R2, uint C2> CM_NOINLINE const matrix_ref<T2,R2,C2> format() const; // to matrix R2xC2
1967 vector_ref<T, C> CM_NOINLINE row(OFFSET i);
1968 matrix_ref<T,R,1> CM_NOINLINE column(OFFSET i);
1969 template <uint R2, uint RS, uint C2, uint CS> CM_NOINLINE matrix_ref<T,R2,C2> select(OFFSET ioff=0, OFFSET joff=0);
1970 template <uint R2, uint RS, uint C2, uint CS> CM_NOINLINE const matrix_ref<T,R2,C2> select(OFFSET ioff=0, OFFSET joff=0) const;
1971
1972 //1D iselect
1973 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> iselect(const vector<T2,WD>& index);
1974 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> iselect(const vector_ref<T2,WD>& index);
1975 #if _MSC_VER >= 1700
1976 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> iselect(const vector<T2,WD>& index, std::true_type);
1977 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> iselect(const vector<T2,WD>& index, std::false_type);
1978 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> iselect(const vector_ref<T2,WD>& index, std::true_type);
1979 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> iselect(const vector_ref<T2,WD>& index, std::false_type);
1980 #endif
1981
1982 //2D iselect
1983 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> iselect(const vector<T2,WD>& index_x, const vector<T2,WD>& index_y);
1984
1985 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> iselect(const vector<T2,WD>& index_x, const vector_ref<T2,WD>& index_y);
1986
1987 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> iselect(const vector_ref<T2,WD>& index_x, const vector<T2,WD>& index_y);
1988
1989 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> iselect(const vector_ref<T2,WD>& index_x, const vector_ref<T2,WD>& index_y);
1990 //end of iselect
1991
1992 template <uint R2, uint VS, uint WD, uint HS> CM_NOINLINE const vector<T, R2*WD> genx_select(OFFSET ioff=0, OFFSET joff=0);
1993
1994 matrix_ref<T, R, C> CM_NOINLINE select_all();
1995 const matrix_ref<T, R, C> CM_NOINLINE select_all() const;
1996
1997 // operators +=, -=, ...
1998 #define declare_operation(OP) \
1999 template <typename T2> CM_NOINLINE matrix<T,R,C>& operator OP (const T2 x);\
2000 template <typename T2, uint R2, uint C2> CM_NOINLINE matrix<T,R,C>& operator OP (const matrix<T2,R2,C2>& x);\
2001 template <typename T2, uint R2, uint C2> CM_NOINLINE matrix<T,R,C>& operator OP (const matrix_ref<T2,R2,C2>& x);\
2002 template <typename T2> CM_NOINLINE matrix<T,R,C>& operator OP (const vector<T2,SZ>& x);\
2003 template <typename T2> CM_NOINLINE matrix<T,R,C>& operator OP (const vector_ref<T2,SZ>& x);\
2004
2005 declare_operation(+=) // +=
2006 declare_operation(-=) // -=
2007 declare_operation(*=) // *=
2008 declare_operation(/=) // /=
2009 declare_operation(%=) // %=
2010 declare_operation(&=) // &=
2011 declare_operation(|=) // |=
2012 declare_operation(^=) // ^=
2013 declare_operation(>>=) // >>=
2014 declare_operation(<<=) // <<=
2015 #undef declare_operation
2016
2017 // for debug
2018 uint id() const { return number; }
2019
2020 #ifdef CM_DEBUG
2021 virtual std::string type_name() const {std::stringstream ss; ss << "M<" << typeid(T).name() << "," << R << "," << C << ">"; return ss.str();}
2022 virtual std::string obj_name() const {std::stringstream ss; ss << typeid(T).name() << "[" << /*id()*/SZ << "]"; return ss.str();}
2023 #endif /* CM_DEBUG */
2024
2025 private:
2026
2027 T data[SZ];
2028 CM_NOINLINE T operator () (uint i) const {
2029 assert(i < SZ);
2030 return get(i);
2031 }
2032
2033 CM_NOINLINE T& operator () (uint i) {
2034 assert(i < SZ);
2035 return data[i];
2036 }
2037 /*
2038 CM_NOINLINE T operator [] (uint i) const {
2039 assert(i < SZ);
2040 return get(i);
2041 }
2042
2043 CM_NOINLINE T& operator [] (uint i) {
2044 assert(i < SZ);
2045 return data[i];
2046 }
2047 */
2048 // for debug
2049 uint number;
2050 };
2051
2052 // matrix_ref
2053 template <typename T, uint R, uint C>
2054 class matrix_ref : public stream<T,R*C> {
2055 public:
2056 template <typename T1, uint R1, uint C1> friend class matrix;
2057 template <typename T1, uint R1, uint C1> friend class matrix_ref;
2058 template <typename T1, uint SZ1> friend class vector;
2059 template <typename T1, uint SZ1> friend class vector_ref;
2060
2061 enum { SZ = R*C };
2062 enum { ROWS=R, COLS=C, ELEMS=R*C };
2063
2064 CM_INLINE int n_rows() const { return R; }
2065 CM_INLINE int n_cols() const { return C; }
2066
2067 template <uint REP> CM_INLINE
2068 const vector<T, R*C*REP> replicate(OFFSET ioff=0, OFFSET joff=0)
2069 { return genx_select<REP,0,R*C,1>(ioff, joff); };
2070 template <uint REP, uint W> CM_INLINE
2071 const vector<T, W*REP> replicate(OFFSET ioff=0, OFFSET joff=0)
2072 { return genx_select<REP,0,W,1>(ioff, joff); };
2073 template <uint REP, uint VS, uint W> CM_INLINE
2074 const vector<T, W*REP> replicate(OFFSET ioff=0, OFFSET joff=0)
2075 { return genx_select<REP,VS,W,1>(ioff, joff); };
2076 template <uint REP, uint VS, uint W, uint HS> CM_INLINE
2077 const vector<T, W*REP> replicate(OFFSET ioff=0, OFFSET joff=0)
2078 { return genx_select<REP,VS,W,HS>(ioff, joff); };
2079
2080 virtual T get(uint i) const { return *data[i]; }
2081 virtual T& getref(uint i) { return *data[i]; }
2082
2083 virtual void* get_addr(uint i) { return data[i]; }
2084 virtual void* get_addr_data() {
2085 return &data[0];
2086 }
2087 virtual void* get_addr_obj() { return this; }
2088 void set_elem_ref(uint i, T* ptr) { data[i] = ptr; }
2089 virtual uint get_size_data() const {
2090 return sizeof(*data);
2091 }
2092 virtual uint get_size_object() const { return sizeof(*this); }
2093
2094 CM_NOINLINE T operator () (OFFSET i, OFFSET j) const {
2095 assert(i < R && j < C);
2096 return get(i*C+j);
2097 }
2098
2099 CM_NOINLINE T& operator () (OFFSET i, OFFSET j) {
2100 assert(i < R && j < C);
2101 return *data[i*C+j];
2102 }
2103
2104 template <typename T1, uint R1, uint C1>
2105 class inner_hack {
2106 matrix_ref* m_t;
2107 OFFSET _i;
2108 public:
2109 inner_hack(matrix_ref* m, OFFSET i):m_t(m){_i=i;}
2110 CM_NOINLINE const T1 operator[](OFFSET j) const{return (*m_t)(_i,j);}
2111 CM_NOINLINE T1& operator[](OFFSET j){return (*m_t)(_i,j);}
2112
2113 };
2114
2115 CM_NOINLINE inner_hack<T,R,C> operator [] (OFFSET i) const {
2116 return inner_hack<T,R,C>(this,i);
2117 }
2118
2119 CM_NOINLINE inner_hack<T,R,C> operator [] (OFFSET i) {
2120 return inner_hack<T,R,C>(this,i);
2121 }
2122
2123 // constructors
2124 CM_NOINLINE matrix_ref(const matrix_ref<T,R,C>& src); // copy constructor
2125 CM_NOINLINE matrix_ref(matrix<T,R,C>& src); // Point reference on matrix
2126 #if defined(__CLANG_CM)
2127 CM_NOINLINE matrix_ref(const vector<T,R*C>& src);
2128 CM_NOINLINE matrix_ref(const vector_ref<T,R*C>& src);
2129 #endif
2130
2131 //operator =
2132 CM_NOINLINE matrix_ref<T,R,C>& operator = (const matrix<T,R,C>& src); // assignment operator
2133 CM_NOINLINE matrix_ref<T,R,C>& operator = (const matrix_ref<T,R,C>& src);
2134 template <typename T2> CM_NOINLINE matrix_ref<T,R,C>& operator = (const T2 src);
2135 template <typename T2, uint R2, uint C2> CM_NOINLINE matrix_ref<T,R,C>& operator = (const matrix<T2,R2,C2>& src);
2136 template <typename T2, uint R2, uint C2> CM_NOINLINE matrix_ref<T,R,C>& operator = (const matrix_ref<T2,R2,C2>& src);
2137 template <typename T2> CM_NOINLINE matrix_ref<T,R,C>& operator = (const vector<T2,R*C>& src) { return this->operator=((const matrix<T2,1,R*C>&)src); };
2138 template <typename T2> CM_NOINLINE matrix_ref<T,R,C>& operator = (const vector_ref<T2,R*C>& src) { return this->operator=((const matrix_ref<T2,1,R*C>&)src); };
2139
2140 // operators +=, -=, ...
2141 #define declare_operation(OP) \
2142 template <typename T2> CM_NOINLINE matrix_ref<T,R,C>& operator OP (const T2 x);\
2143 template <typename T2, uint R2, uint C2> CM_NOINLINE matrix_ref<T,R,C>& operator OP (const matrix<T2,R2,C2>& x);\
2144 template <typename T2, uint R2, uint C2> CM_NOINLINE matrix_ref<T,R,C>& operator OP (const matrix_ref<T2,R2,C2>& x);\
2145 template <typename T2> CM_NOINLINE matrix_ref<T,R,C>& operator OP (const vector<T2,SZ>& x);\
2146 template <typename T2> CM_NOINLINE matrix_ref<T,R,C>& operator OP (const vector_ref<T2,SZ>& x);\
2147
2148 declare_operation(+=) // +=
2149 declare_operation(-=) // -=
2150 declare_operation(*=) // *=
2151 declare_operation(/=) // /=
2152 declare_operation(%=) // %=
2153 declare_operation(&=) // &=
2154 declare_operation(|=) // |=
2155 declare_operation(^=) // ^=
2156 declare_operation(>>=) // >>=
2157 declare_operation(<<=) // <<=
2158 #undef declare_operation
2159
2160 bool is_contiguous() const;
2161 bool is_contiguous(const uint start, const uint end) const;
2162 //selects
2163 template <typename T2> CM_NOINLINE vector_ref<T2,R*C*sizeof(T)/sizeof(T2)> format(); // to vector
2164 template <typename T2, uint R2, uint C2> CM_NOINLINE matrix_ref<T2,R2,C2> format(); // to matrix R2xC2
2165 template <typename T2> CM_NOINLINE const vector_ref<T2,R*C*sizeof(T)/sizeof(T2)> format() const; // to vector
2166 template <typename T2, uint R2, uint C2> CM_NOINLINE const matrix_ref<T2,R2,C2> format() const; // to matrix R2xC2
2167 vector_ref<T, C> CM_NOINLINE row(OFFSET i);
2168 matrix_ref<T,R,1> CM_NOINLINE column(OFFSET i);
2169 template <uint R2, uint RS, uint C2, uint CS> CM_NOINLINE matrix_ref<T,R2,C2> select(OFFSET ioff=0, OFFSET joff=0);
2170 template <uint R2, uint RS, uint C2, uint CS> CM_NOINLINE const matrix_ref<T,R2,C2> select(OFFSET ioff=0, OFFSET joff=0) const;
2171 template <uint R2, uint VS, uint WD, uint HS> CM_NOINLINE const vector<T, R2*WD> genx_select(OFFSET ioff=0, OFFSET joff=0);
2172
2173 //1D iselect
2174 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> iselect(const vector<T2,WD>& index);
2175 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> iselect(const vector_ref<T2,WD>& index);
2176 #if _MSC_VER >= 1700
2177 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> iselect(const vector<T2,WD>& index, std::true_type);
2178 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> iselect(const vector<T2,WD>& index, std::false_type);
2179 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> iselect(const vector_ref<T2,WD>& index, std::true_type);
2180 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> iselect(const vector_ref<T2,WD>& index, std::false_type);
2181 #endif
2182
2183
2184 //2D iselect
2185 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> iselect(const vector<T2,WD>& index_x, const vector<T2,WD>& index_y);
2186
2187 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> iselect(const vector<T2,WD>& index_x, const vector_ref<T2,WD>& index_y);
2188
2189 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> iselect(const vector_ref<T2,WD>& index_x, const vector<T2,WD>& index_y);
2190
2191 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> iselect(const vector_ref<T2,WD>& index_x, const vector_ref<T2,WD>& index_y);
2192 //end of 2D iselect
2193
2194 // for debug
2195 uint id() const { return number; }
2196
2197 T* dummy() { return &_dummy; }
2198
2199 #ifdef CM_DEBUG
2200 virtual std::string type_name() const {std::stringstream ss; ss << "M<" << typeid(T).name() << "," << R << "," << C << ">"; return ss.str();}
2201 virtual std::string obj_name() const {std::stringstream ss; ss << typeid(T).name() << "[" << id() << "]"; return ss.str();}
2202 #endif /* CM_DEBUG */
2203
2204 private:
2205 matrix_ref(const uint id) : number(id) { } // id for debug
2206 T* data[SZ];
2207
2208 T _dummy;
2209
2210 CM_NOINLINE T operator () (uint i) const {
2211 assert(i < SZ);
2212 return get(i);
2213 }
2214
2215 CM_NOINLINE T& operator () (uint i) {
2216 assert(i < SZ);
2217 return *data[i];
2218 }
2219 /*
2220 CM_NOINLINE T operator [] (uint i) const {
2221 assert(i < SZ);
2222 return get(i);
2223 }
2224
2225 CM_NOINLINE T& operator [] (uint i) {
2226 assert(i < SZ);
2227 return *data[i];
2228 }
2229 */
2230 // for debug
2231 uint number;
2232 };
2233
2234 // vector
2235 template <typename T, uint SZ>
2236 class vector : public matrix<T,1,SZ> {
2237 void assign(const stream<T, SZ> &src); //special member-function, not for CM language
2238 public:
2239 template <typename T1, uint R1, uint C1> friend class matrix;
2240 template <typename T1, uint R1, uint C1> friend class matrix_ref;
2241 template <typename T1, uint SZ1> friend class vector_ref;
2242 template <typename T1, uint SZ1> friend class stream;
2243
2244 template <uint REP> CM_INLINE
2245 vector<T,SZ*REP> replicate(OFFSET joff=0)
2246 {return ((matrix<T,1,SZ> *)this)->template replicate<REP>(0, joff);};
2247 template <uint REP, uint W> CM_INLINE
2248 vector<T,W*REP> replicate(OFFSET joff=0)
2249 {return ((matrix<T,1,SZ> *)this)->template replicate<REP,W>(0, joff);};
2250 template <uint REP, uint VS, uint W> CM_INLINE
2251 vector<T,W*REP> replicate(OFFSET joff=0)
2252 {return ((matrix<T,1,SZ> *)this)->template replicate<REP,VS,W>(0, joff);};
2253 template <uint REP, uint VS, uint W, uint HS> CM_INLINE
2254 vector<T,W*REP> replicate(OFFSET joff=0)
2255 {return ((matrix<T,1,SZ> *)this)->template replicate<REP,VS,W,HS>(0, joff);};
2256
2257 // constructors: call base versions of constructors
2258 CM_NOINLINE vector() : CMRT_UMD::matrix<T,1,SZ>() {}
2259 template <typename T2> CM_NOINLINE vector(const T2 initArray[]) : CMRT_UMD::matrix<T,1,SZ>(initArray) {
2260 // constructor with array initializer
2261 CM_STATIC_ERROR(!std::is_floating_point<T2>::value, "floating point array initialization values are not supported");
2262 }
2263 CM_NOINLINE vector(const vector<T,SZ>& src) : CMRT_UMD::matrix<T,1,SZ>((const matrix<T,1,SZ>&)src) {} // copy constructor
2264 template <typename T2> CM_NOINLINE vector(const T2& src) : CMRT_UMD::matrix<T,1,SZ>(src) {}
2265 template <typename T2, uint R2, uint C2> CM_NOINLINE vector(const matrix<T2,R2,C2>& src, uint sat = 0) : CMRT_UMD::matrix<T,1,SZ>(src, sat) {}
2266 template <typename T2, uint R2, uint C2> CM_NOINLINE vector(const matrix_ref<T2,R2,C2>& src, uint sat = 0) : CMRT_UMD::matrix<T,1,SZ>(src, sat) {}
2267 template <typename T2> CM_NOINLINE vector(const vector<T2,SZ>& src) : CMRT_UMD::matrix<T,1,SZ>(src) {}
2268 template <typename T2> CM_NOINLINE vector(const vector_ref<T2,SZ>& src) : CMRT_UMD::matrix<T,1,SZ>(src) {}
2269
2270
2271 CM_NOINLINE T operator () (OFFSET i) const {
2272 assert(i < SZ);
2273 return matrix<T,1,SZ>::get(i);
2274 }
2275
2276 CM_NOINLINE T& operator () (OFFSET i) {
2277 assert(i < SZ);
2278 return matrix<T,1,SZ>::data[i];
2279 }
2280
2281 CM_NOINLINE T operator [] (OFFSET i) const {
2282 assert(i < SZ);
2283 return matrix<T,1,SZ>::get(i);
2284 }
2285
2286 CM_NOINLINE T& operator [] (OFFSET i) {
2287 assert(i < SZ);
2288 return matrix<T,1,SZ>::data[i];
2289 }
2290
2291 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> operator () (const vector<T2,WD>& index) {
2292 return matrix<T,1,SZ>::template iselect<T2,WD>(index);
2293 }
2294
2295 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> operator () (const vector_ref<T2,WD>& index) {
2296 return matrix<T,1,SZ>::template iselect<T2,WD>(index);
2297 }
2298
2299 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> operator [] (const vector<T2,WD>& index) {
2300 return matrix<T,1,SZ>::template iselect<T2,WD>(index);
2301 }
2302
2303 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> operator [] (const vector_ref<T2,WD>& index) {
2304 return matrix<T,1,SZ>::template iselect<T2,WD>(index);
2305 }
2306
2307 //1D iselect only
2308 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> iselect(const vector<T2,WD>& index) {
2309 CM_STATIC_WARNING((std::is_unsigned<T2>::value), "iselect index vector element type must be unsigned");
2310 return matrix<T,1,SZ>::template iselect<T2,WD>(index);
2311 }
2312
2313 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> iselect(const vector_ref<T2,WD>& index) {
2314 CM_STATIC_WARNING((std::is_unsigned<T2>::value), "iselect index vector element type must be unsigned");
2315 return matrix<T,1,SZ>::template iselect<T2,WD>(index);
2316 }
2317 //end of iselect
2318
2319 //operator =: call base versions of operator =
2320 CM_NOINLINE vector<T,SZ>& operator = (const vector<T,SZ>& src) { ((matrix<T,1,SZ>*)this)->operator=(src); return *this; } // assignment operator
2321 template <typename T2> CM_NOINLINE vector<T,SZ>& operator = (const T2 src) {
2322 ((matrix<T,1,SZ>*)this)->operator=(src); return *this;
2323 }
2324 template <typename T2, uint R2, uint C2> CM_NOINLINE vector<T,SZ>& operator = (const matrix<T2,R2,C2>& src) { ((matrix<T,1,SZ>*)this)->operator=(src); return *this; }
2325 template <typename T2, uint R2, uint C2> CM_NOINLINE vector<T,SZ>& operator = (const matrix_ref<T2,R2,C2>& src) { ((matrix<T,1,SZ>*)this)->operator=(src); return *this; }
2326 template <typename T2> CM_NOINLINE vector<T,SZ>& operator = (const vector<T2,SZ>& src) { ((matrix<T,1,SZ>*)this)->operator=(src); return *this; }
2327 template <typename T2> CM_NOINLINE vector<T,SZ>& operator = (const vector_ref<T2,SZ>& src) { ((matrix<T,1,SZ>*)this)->operator=(src); return *this; }
2328
2329 //vector select
2330 template <uint C, uint CS> CM_NOINLINE const vector_ref<T,C> select(OFFSET joff=0) const {
2331 CM_STATIC_ERROR(((SZ) >= (C)), "select size is greater than source vector size");
2332 CM_STATIC_ERROR(((SZ) >= ((C-1)*(CS))+1) || (CS == 1), "select range exceeds source vector bounds");
2333 return ((matrix<T,1,SZ>*)this)->template select<1,1,C,CS>(0,joff);
2334 }
2335 template <uint C, uint CS> CM_NOINLINE vector_ref<T,C> select(OFFSET joff=0) {
2336 CM_STATIC_ERROR(((SZ) >= (C)), "select size is greater than source vector size");
2337 CM_STATIC_ERROR(((SZ) >= ((C-1)*(CS))+1) || (CS == 1), "select range exceeds source vector bounds");
2338 return ((matrix<T,1,SZ>*)this)->template select<1,1,C,CS>(0,joff);
2339 }
2340
2341 //vector genx_select
2342 template <uint R, uint VS, uint WD, uint HS> CM_NOINLINE const vector<T, R*WD> genx_select(OFFSET joff=0) {
2343 CM_STATIC_ERROR((!std::is_same<T, double>::value), "genx_select is not supported for vectors with element type 'double'");
2344 CM_STATIC_ERROR(((SZ) >= (WD)), "genx_select width is greater than source vector size");
2345 return ((matrix<T,1,SZ>*)this)->template genx_select<R,VS,WD,HS>(0, joff);
2346 }
2347 };
2348
2349 // vector_ref
2350 template <typename T, uint SZ>
2351 class vector_ref : public matrix_ref<T,1,SZ> {
2352 public:
2353 template <typename T1, uint R1, uint C1> friend class matrix;
2354 template <typename T1, uint R1, uint C1> friend class matrix_ref;
2355 template <typename T1, uint SZ1> friend class vector;
2356 template <typename T1, uint SZ1> friend class vector_ref;
2357
2358 template <uint REP> CM_INLINE
2359 vector<T,SZ*REP> replicate(OFFSET joff = 0)
2360 {return ((matrix_ref<T,1,SZ> *)this)->template replicate<REP>(0, joff);};
2361 template <uint REP, uint W> CM_INLINE
2362 vector<T,W*REP> replicate(OFFSET joff = 0)
2363 {return ((matrix_ref<T,1,SZ> *)this)->template replicate<REP,W>(0, joff);};
2364 template <uint REP, uint VS, uint W> CM_INLINE
2365 vector<T,W*REP> replicate(OFFSET joff = 0)
2366 {return ((matrix_ref<T,1,SZ> *)this)->template replicate<REP,VS,W>(0, joff);};
2367 template <uint REP, uint VS, uint W, uint HS> CM_INLINE
2368 vector<T,W*REP> replicate(OFFSET joff = 0)
2369 {return ((matrix_ref<T,1,SZ> *)this)->template replicate<REP,VS,W,HS>(0, joff);};
2370
2371 // constructors
2372 CM_NOINLINE vector_ref(const vector_ref<T,SZ>& src) : CMRT_UMD::matrix_ref<T,1,SZ>((const matrix_ref<T,1,SZ>&)src) {} // copy constructor
2373 CM_NOINLINE vector_ref(vector<T,SZ>& src) : CMRT_UMD::matrix_ref<T,1,SZ>((matrix<T,1,SZ>&)src) {} //assign vector_ref to vector
2374 CM_NOINLINE vector_ref(const matrix_ref<T,1,SZ>& src) : CMRT_UMD::matrix_ref<T,1,SZ>(src) {}
2375 CM_NOINLINE vector_ref(matrix<T,1,SZ>& src) : CMRT_UMD::matrix_ref<T,1,SZ>(src) {}
2376 #if defined(__CLANG_CM)
2377 CM_NOINLINE vector_ref(matrix<T,1,SZ> src) : CMRT_UMD::matrix_ref<T,1,SZ>(src) {}
2378 CM_NOINLINE vector_ref(matrix_ref<T,1,SZ>& src) : CMRT_UMD::matrix_ref<T,1,SZ>(src) {}
2379 #endif
2380
2381 CM_NOINLINE T operator () (OFFSET i) const {
2382 assert(i < SZ);
2383 return matrix_ref<T,1,SZ>::get(i);
2384 }
2385
2386 CM_NOINLINE T& operator () (OFFSET i) {
2387 assert(i < SZ);
2388 return *matrix_ref<T,1,SZ>::data[i];
2389 }
2390
2391 CM_NOINLINE T operator [] (OFFSET i) const {
2392 assert(i < SZ);
2393 return matrix_ref<T,1,SZ>::get(i);
2394 }
2395
2396 CM_NOINLINE T& operator [] (OFFSET i) {
2397 assert(i < SZ);
2398 return *matrix_ref<T,1,SZ>::data[i];
2399 }
2400
2401 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> operator () (const vector<T2,WD>& index) const{
2402 return matrix_ref<T,1,SZ>::template iselect<T,WD>(index);
2403 }
2404
2405 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> operator () (const vector_ref<T2,WD>& index) const{
2406 return matrix_ref<T,1,SZ>::template iselect<T,WD>(index);
2407 }
2408
2409 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> operator [] (const vector<T2,WD>& index) const{
2410 return matrix_ref<T,1,SZ>::template iselect<T,WD>(index);
2411 }
2412
2413 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> operator [] (const vector_ref<T2,WD>& index) const{
2414 return matrix_ref<T,1,SZ>::template iselect<T,WD>(index);
2415 }
2416
2417 //1D iselect only
2418 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> iselect(const vector<T2,WD >& index) {
2419 CM_STATIC_WARNING((std::is_unsigned<T2>::value), "iselect index vector element type must be unsigned");
2420 return matrix_ref<T,1,SZ>::template iselect<T2,WD>(index);
2421 }
2422
2423 template <typename T2, uint WD> CM_NOINLINE vector<T,WD> iselect(const vector_ref<T2,WD>& index) {
2424 CM_STATIC_WARNING((std::is_unsigned<T2>::value), "iselect index vector element type must be unsigned");
2425 return matrix_ref<T,1,SZ>::template iselect<T2,WD>(index);
2426 }
2427 //end of iselect
2428
2429
2430 //operator =: call base versions of operator =
2431 CM_NOINLINE vector_ref<T,SZ>& operator = (const vector_ref<T,SZ>& src) { ((matrix_ref<T,1,SZ>*)this)->operator=(src); return *this; } //assignment operator
2432 template <typename T2> CM_NOINLINE vector_ref<T,SZ>& operator = (const T2 src) { ((matrix_ref<T,1,SZ>*)this)->operator=(src); return *this; }
2433 template <typename T2, uint R2, uint C2> CM_NOINLINE vector_ref<T,SZ>& operator = (const matrix<T2,R2,C2>& src){ ((matrix_ref<T,1,SZ>*)this)->operator=(src); return *this; }
2434 template <typename T2, uint R2, uint C2> CM_NOINLINE vector_ref<T,SZ>& operator = (const matrix_ref<T2,R2,C2>& src){ ((matrix_ref<T,1,SZ>*)this)->operator=(src); return *this; }
2435 template <typename T2> CM_NOINLINE vector_ref<T,SZ>& operator = (const vector<T2,SZ>& src) { ((matrix_ref<T,1,SZ>*)this)->operator=(src); return *this; }
2436 template <typename T2> CM_NOINLINE vector_ref<T,SZ>& operator = (const vector_ref<T2,SZ>& src) { ((matrix_ref<T,1,SZ>*)this)->operator=(src); return *this; }
2437
2438 //vector_ref select
2439 template <uint C, uint CS> CM_NOINLINE vector_ref<T,C> select(OFFSET joff=0) {return ((matrix_ref<T,1,SZ>*)this)->template select<1,1,C,CS>(0,joff);}
2440 template <uint C, uint CS> CM_NOINLINE const vector_ref<T,C> select(OFFSET joff=0) const {return ((matrix_ref<T,1,SZ>*)this)->template select<1,1,C,CS>(0,joff);}
2441
2442 //vector_ref genx_select
2443 template <uint R, uint VS, uint WD, uint HS> CM_NOINLINE const vector<T, R*WD> genx_select(OFFSET joff=0) {
2444 CM_STATIC_WARNING((!std::is_same<T, double>::value), "genx_select is not supported for vectors with element type of 'double'");
2445 CM_STATIC_ERROR(((SZ) >= (WD)), "genx_select width is greater than source vector size");
2446 return ((matrix_ref<T,1,SZ>*)this)->template genx_select<R,VS,WD,HS>(0, joff);
2447 };
2448
2449 private:
2450 CM_NOINLINE vector_ref(const uint id) : CMRT_UMD::matrix_ref<T,1,SZ>(id) {}
2451 };
2452
2453 #ifdef CM_DEBUG
2454 template <typename T, uint R, uint C>
2455 std::ostream& operator << (std::ostream &out, const matrix<T,R,C>& m)
2456 {
2457 out << "---" << m.obj_name() << ":" << std::endl;
2458 for (uint i=0; i<R; ++i) {
2459 for (uint j=0; j<C; ++j) {
2460 out << m(i,j) << " ";
2461 }
2462 out << std::endl;
2463 }
2464 return out;
2465 }
2466 template <uint R, uint C>
2467 std::ostream& operator << (std::ostream &out, const matrix<char,R,C>& m)
2468 {
2469 out << "---" << m.obj_name() << ":" << std::endl;
2470 for (uint i=0; i<R; ++i) {
2471 for (uint j=0; j<C; ++j) {
2472 out << (int)m(i,j) << " ";
2473 }
2474 out << std::endl;
2475 }
2476 return out;
2477 }
2478 #endif /* CM_DEBUG */
2479
2480 /*******************************************************************
2481 /
2482 / stream
2483 /
2484 *******************************************************************/
2485
2486 template <typename T, uint SZ>
2487 int stream<T,SZ>::extract_data(void *buf, uint size)
2488 {
2489 uint i;
2490
2491 assert(SZ*sizeof(T) <= size);
2492
2493 for (i=0; i< SZ; i++) {
2494 ((T*)buf)[i] = get(i);
2495 }
2496
2497 return SZ*sizeof(T);
2498 }
2499
2500
2501 #define SIMDCF_WRAPPER(X, SZ, i) X
2502
2503 #define SIMDCF_ELEMENT_SKIP(i)
2504
2505
2506 /*
2507 * merge
2508 */
2509 template <typename T, uint SZ>
2510 void stream<T,SZ>::merge(const T x, const uint c)
2511 {
2512 T* p;
2513 for (uint i=0; i<SZ; i++) {
2514 SIMDCF_ELEMENT_SKIP(i);
2515 if (((c >> i) & 1) != 0) {
2516 p = (T*)this->get_addr(i);
2517 *p = x;
2518 }
2519 }
2520 }
2521
2522 template <typename T, uint SZ>
2523 template <typename T1>
2524 void stream<T,SZ>::merge(const stream<T1,SZ> &x, const uint c)
2525 {
2526 vector<T1, SZ> in_x; in_x.assign(x);
2527 T* p;
2528 for (uint i=0; i<SZ; i++) {
2529 SIMDCF_ELEMENT_SKIP(i);
2530 if (((c >> i) & 1) != 0) {
2531 p = (T*)this->get_addr(i);
2532 *p = in_x.get(i);
2533 }
2534 }
2535 }
2536
2537
2538 template <typename T, uint SZ>
2539 template <typename T1, typename T2>
2540 void stream<T,SZ>::merge(const stream<T1,SZ> &x, const stream<T2,SZ> &c)
2541 {
2542 vector<T1, SZ> in_x; in_x.assign(x);
2543 vector<T2, SZ> in_c; in_c.assign(c);
2544 T* p;
2545 for (uint i=0; i<SZ; i++) {
2546 SIMDCF_ELEMENT_SKIP(i);
2547 if ((in_c.get(i) & 1) != 0) {
2548 p = (T*)this->get_addr(i);
2549 *p = (T) in_x.get(i);
2550 }
2551 }
2552 }
2553
2554 template <typename T, uint SZ>
2555 template <typename T1>
2556 void stream<T,SZ>::merge(const T x, const stream<T1,SZ> &c)
2557 {
2558 vector<T1, SZ> in_c; in_c.assign(c);
2559 T* p;
2560 for (uint i=0; i<SZ; i++) {
2561 SIMDCF_ELEMENT_SKIP(i);
2562 if ((in_c.get(i) & 1) != 0) {
2563 p = (T*)this->get_addr(i);
2564 *p = x;
2565 }
2566 }
2567 }
2568
2569 template <typename T, uint SZ>
2570 template <typename T1, typename T2>
2571 void stream<T,SZ>::merge(const stream<T1,SZ>& x, const stream<T2,SZ>& y,
2572 const uint c)
2573 {
2574 vector<T1, SZ> in_x; in_x.assign(x);
2575 vector<T2, SZ> in_y; in_y.assign(y);
2576 T* p;
2577 for (uint i=0; i<SZ; i++) {
2578 SIMDCF_ELEMENT_SKIP(i);
2579 p = (T*)this->get_addr(i);
2580 if (((c >> i) & 1) != 0) {
2581 *p = in_x.get(i);
2582 } else {
2583 *p = in_y.get(i);
2584 }
2585 }
2586 }
2587
2588 template <typename T, uint SZ>
2589 template <typename T1>
2590 void stream<T,SZ>::merge(const T x, const stream<T1,SZ>& y, const uint c)
2591 {
2592 vector<T1, SZ> in_y; in_y.assign(y);
2593 T* p;
2594 for (uint i=0; i<SZ; i++) {
2595 SIMDCF_ELEMENT_SKIP(i);
2596 p = (T*)this->get_addr(i);
2597 if (((c >> i) & 1) != 0) {
2598 *p = x;
2599 } else {
2600 *p = in_y.get(i);
2601 }
2602 }
2603 }
2604
2605 template <typename T, uint SZ>
2606 template <typename T1>
2607 void stream<T,SZ>::merge(const stream<T1,SZ>& x, const T y, const uint c)
2608 {
2609 vector<T1, SZ> in_x; in_x.assign(x);
2610 T* p;
2611 for (uint i=0; i<SZ; i++) {
2612 SIMDCF_ELEMENT_SKIP(i);
2613 p = (T*)this->get_addr(i);
2614 if (((c >> i) & 1) != 0) {
2615 *p = in_x.get(i);
2616 } else {
2617 *p = y;
2618 }
2619 }
2620 }
2621
2622 template <typename T, uint SZ>
2623 void stream<T,SZ>::merge(const T x, const T y, const uint c)
2624 {
2625 T* p;
2626 for (uint i=0; i<SZ; i++) {
2627 SIMDCF_ELEMENT_SKIP(i);
2628 p = (T*)this->get_addr(i);
2629 if (((c >> i) & 1) != 0) {
2630 *p = x;
2631 } else {
2632 *p = y;
2633 }
2634 }
2635 }
2636
2637 template <typename T, uint SZ>
2638 template <typename T1, typename T2, typename T3>
2639 void stream<T,SZ>::merge(const stream<T1,SZ>& x, const stream<T2,SZ>& y, const stream<T3,SZ>& c)
2640 {
2641 vector<T1, SZ> in_x; in_x.assign(x);
2642 vector<T2, SZ> in_y; in_y.assign(y);
2643 vector<T3, SZ> in_c; in_c.assign(c);
2644
2645 T* p;
2646 for (uint i=0; i<SZ; i++) {
2647 SIMDCF_ELEMENT_SKIP(i);
2648 p = (T*)this->get_addr(i);
2649 if ((in_c.get(i) & 1) != 0) {
2650 *p = in_x.get(i);
2651 } else
2652 {
2653 *p = in_y.get(i);
2654 }
2655 }
2656 }
2657
2658 template <typename T, uint SZ>
2659 template <typename T1, typename T2>
2660 void stream<T,SZ>::merge(const T x, const stream<T1,SZ>& y, const stream<T2,SZ>& c)
2661 {
2662 vector<T1, SZ> in_y; in_y.assign(y);
2663 vector<T2, SZ> in_c; in_c.assign(c);
2664 T* p;
2665 for (uint i=0; i<SZ; i++) {
2666 SIMDCF_ELEMENT_SKIP(i);
2667 p = (T*)this->get_addr(i);
2668 if ((in_c.get(i) & 1) != 0) {
2669 *p = x;
2670 } else
2671 {
2672 *p = in_y.get(i);
2673 }
2674 }
2675 }
2676
2677 template <typename T, uint SZ>
2678 template <typename T1, typename T2>
2679 void stream<T,SZ>::merge(const stream<T1,SZ>& x, const T y,
2680 const stream<T2,SZ>& c)
2681 {
2682 vector<T1, SZ> in_x; in_x.assign(x);
2683 vector<T2, SZ> in_c; in_c.assign(c);
2684 T* p;
2685 for (uint i=0; i<SZ; i++) {
2686 SIMDCF_ELEMENT_SKIP(i);
2687 p = (T*)this->get_addr(i);
2688 if ((in_c.get(i) & 1) != 0) {
2689 *p = in_x.get(i);
2690 } else
2691 {
2692 *p = y;
2693 }
2694 }
2695 }
2696
2697 template <typename T, uint SZ>
2698 template <typename T1>
2699 void stream<T,SZ>::merge(const T x, const T y, const stream<T1,SZ>& c)
2700 {
2701 vector<T1, SZ> in_c; in_c.assign(c);
2702 T* p;
2703 for (uint i=0; i<SZ; i++) {
2704 SIMDCF_ELEMENT_SKIP(i);
2705 p = (T*)this->get_addr(i);
2706 if ((in_c.get(i) & 1) != 0) {
2707 *p = x;
2708 } else
2709 {
2710 *p = y;
2711 }
2712 }
2713 }
2714
2715
2716 /*******************************************************************
2717 /
2718 / matrix
2719 /
2720 *******************************************************************/
2721
2722 /*
2723 * matrix constructors
2724 */
2725
2726 // Matrix Initialization with array
2727 template <typename T, uint R, uint C>
2728 template <typename T2>
2729 matrix<T,R,C>::matrix(const T2 initArray[])
2730 {
2731 CM_STATIC_ERROR(!std::is_floating_point<T2>::value, "floating point array initialization values are not supported");
2732 //int i;
2733
2734 //for (i = 0; i < SZ; i++) {
2735 // // data[i] = (T)initArray[i];
2736 // data[i] = *((T *)((char *)initArray + i*sizeof(T)));
2737 //}
2738 typedef typename cm::pointer_traits<T2>::tail_pointee_type tail_pointee_type;
2739 for (int i = 0; i < SZ; i++) {
2740 SIMDCF_WRAPPER(data[i] = (T)((tail_pointee_type *)initArray)[i], SZ, i);
2741 }
2742 }
2743
2744 template <typename T, uint R, uint C>
2745 matrix<T,R,C>::matrix()
2746 {
2747 number = 0;
2748 //number = OBJ_COUNTER ? ++CmEmulSys::_count : 0;
2749 }
2750
2751 //copy constructor
2752 template <typename T, uint R, uint C>
2753 matrix<T,R,C>::matrix(const matrix<T,R,C>& src)
2754 {
2755 //number = OBJ_COUNTER ? ++CmEmulSys::_count : 0;
2756 (*this) = src;
2757 }
2758 template <typename T, uint R, uint C>
2759 template <typename T2>
2760 matrix<T,R,C>::matrix(const T2& src)
2761 {
2762 //number = OBJ_COUNTER ? ++CmEmulSys::_count : 0;
2763 (*this) = src;
2764 }
2765 template <typename T, uint R, uint C>
2766 template <typename T2, uint R2, uint C2>
2767 matrix<T,R,C>::matrix(const matrix<T2,R2,C2>& src, const uint sat)
2768 {
2769 //number = OBJ_COUNTER ? ++CmEmulSys::_count : 0;
2770 static const bool conformable = check_true<R*C == R2*C2>::value;
2771 assert(R*C == R2*C2);
2772
2773 uint sat1 = 0;
2774 //uint sat1 = CmEmulSys::_SetSatur<T2, is_inttype<T>::value>::SetSatur();
2775 vector<T2, SZ> in_src; in_src.assign(src);
2776
2777 for (uint i=0; i < SZ; i++) {
2778 SIMDCF_WRAPPER((*this)(i) = CmEmulSys::satur<T>::saturate(in_src(i), sat | sat1), SZ, i);
2779 }
2780 }
2781 template <typename T, uint R, uint C>
2782 template <typename T2, uint R2, uint C2>
2783 matrix<T,R,C>::matrix(const matrix_ref<T2,R2,C2>& src, const uint sat)
2784 {
2785 //number = OBJ_COUNTER ? ++CmEmulSys::_count : 0;
2786 static const bool conformable = check_true<R*C == R2*C2>::value;
2787 assert(R*C == R2*C2);
2788
2789 uint sat1 = 0;
2790 //uint sat1 = CmEmulSys::_SetSatur<T2, is_inttype<T>::value>::SetSatur();
2791 vector<T2, SZ> in_src; in_src.assign(src);
2792
2793 for (uint i=0; i < SZ; i++) {
2794 SIMDCF_WRAPPER((*this)(i) = CmEmulSys::satur<T>::saturate(in_src(i), sat), SZ, i);
2795 }
2796 }
2797 //
2798 // matrix operator =
2799 //
2800 template <typename T, uint R, uint C>
2801 matrix<T,R,C>& matrix<T,R,C>::operator = (const matrix<T,R,C>& src)
2802 {
2803 vector<T, SZ> in_src; in_src.assign(src);
2804 for (uint i=0; i<SZ; ++i) {
2805 SIMDCF_WRAPPER(this->getref(i) = in_src(i), SZ, i);
2806 }
2807 return *this;
2808 }
2809
2810 template <typename T, uint R, uint C>
2811 template <typename T2>
2812 matrix<T,R,C>& matrix<T,R,C>::operator = (const T2 src)
2813 {
2814 uint sat1 = 0;
2815 //uint sat1 = CmEmulSys::_SetSatur<T2, is_inttype<T>::value>::SetSatur();
2816
2817 for (uint i=0; i < SZ; i++) {
2818 SIMDCF_WRAPPER(this->getref(i) = CmEmulSys::satur<T>::saturate(src, sat1), SZ, i);
2819 }
2820
2821 return *this;
2822 }
2823 template <typename T, uint R, uint C>
2824 template <typename T2, uint R2, uint C2>
2825 matrix<T,R,C>& matrix<T,R,C>::operator = (const matrix<T2,R2,C2>& src)
2826 {
2827 CM_STATIC_ERROR(R*C == R2*C2, "matrices have different dimensions"); \
2828 static const bool conformable = check_true<R*C == R2*C2>::value;
2829 assert(R*C == R2*C2);
2830
2831 uint sat1 = 0;
2832 //uint sat1 = CmEmulSys::_SetSatur<T2, is_inttype<T>::value>::SetSatur();
2833 vector<T2, SZ> in_src; in_src.assign(src);
2834
2835 for (uint i=0; i < SZ; i++) {
2836 SIMDCF_WRAPPER(this->getref(i) = CmEmulSys::satur<T>::saturate(in_src(i), sat1), SZ, i);
2837 }
2838
2839 return *this;
2840 }
2841 template <typename T, uint R, uint C>
2842 template <typename T2, uint R2, uint C2>
2843 matrix<T,R,C>& matrix<T,R,C>::operator = (const matrix_ref<T2,R2,C2>& src)
2844 {
2845 CM_STATIC_ERROR(R*C == R2*C2, "matrices have different dimensions"); \
2846 static const bool conformable = check_true<R*C == R2*C2>::value;
2847 assert(R*C == R2*C2);
2848
2849 uint sat1 = 0;
2850 //uint sat1 = CmEmulSys::_SetSatur<T2, is_inttype<T>::value>::SetSatur();
2851 vector<T2, SZ> in_src; in_src.assign(src);
2852
2853 for (uint i=0; i < SZ; i++) {
2854 SIMDCF_WRAPPER(this->getref(i) = CmEmulSys::satur<T>::saturate(in_src(i), sat1), SZ, i);
2855 }
2856
2857 return *this;
2858 }
2859
2860
2861 //Should be inserted for GenX style of float->integer conversions
2862 //sat1 = CmEmulSys::_SetSatur<T2, is_inttype<T>::value>::SetSatur();
2863 #define matrix_operation(OP) \
2864 \
2865 template <typename T, uint R, uint C> \
2866 template <typename T2> \
2867 matrix<T,R,C>& matrix<T,R,C>::operator OP##= (const T2 x) \
2868 { \
2869 static const bool type_conformable = cmtype<T2>::value; \
2870 uint sat1 = 0; \
2871 for (uint i=0; i < SZ; i++) { \
2872 SIMDCF_WRAPPER(this->getref(i) = CmEmulSys::satur<T>::saturate((*this).get(i) OP x, sat1), SZ, i); \
2873 } \
2874 return *this; \
2875 } \
2876 template <typename T, uint R, uint C> \
2877 template <typename T2, uint R2, uint C2> \
2878 matrix<T,R,C>& matrix<T,R,C>::operator OP##= (const matrix<T2,R2,C2>& x) \
2879 { \
2880 CM_STATIC_ERROR(R*C == R2*C2, "matrices have different dimensions"); \
2881 static const bool conformable = check_true<R*C == R2*C2>::value; \
2882 assert(R*C == R2*C2); \
2883 uint sat1 = 0; \
2884 vector<T2, /*SZ*/R*C> in_x; in_x.assign(x); \
2885 for (uint i=0; i < SZ; i++) { \
2886 SIMDCF_WRAPPER(this->getref(i) = CmEmulSys::satur<T>::saturate((*this).get(i) OP in_x(i), sat1), SZ, i);\
2887 } \
2888 return *this; \
2889 } \
2890 template <typename T, uint R, uint C> \
2891 template <typename T2, uint R2, uint C2> \
2892 matrix<T,R,C>& matrix<T,R,C>::operator OP##= (const matrix_ref<T2,R2,C2>& x) \
2893 { \
2894 CM_STATIC_ERROR(R*C == R2*C2, "matrices have different dimensions"); \
2895 static const bool conformable = check_true<R*C == R2*C2>::value; \
2896 assert(R*C == R2*C2); \
2897 uint sat1 = 0; \
2898 vector<T2, /*SZ*/R*C> in_x; in_x.assign(x); \
2899 for (uint i=0; i < SZ; i++) { \
2900 SIMDCF_WRAPPER(this->getref(i) = CmEmulSys::satur<T>::saturate((*this).get(i) OP in_x(i), sat1), SZ, i);\
2901 } \
2902 return *this; \
2903 } \
2904 template <typename T, uint R, uint C> \
2905 template <typename T2> \
2906 matrix<T,R,C>& matrix<T,R,C>::operator OP##= (const vector<T2,SZ>& x) \
2907 { \
2908 uint sat1 = 0; \
2909 vector<T2, SZ> in_x; in_x.assign(x); \
2910 for (uint i=0; i < SZ; i++) { \
2911 SIMDCF_WRAPPER(this->getref(i) = CmEmulSys::satur<T>::saturate((*this).get(i) OP in_x(i), sat1), SZ, i);\
2912 } \
2913 return *this; \
2914 } \
2915 template <typename T, uint R, uint C> \
2916 template <typename T2> \
2917 matrix<T,R,C>& matrix<T,R,C>::operator OP##= (const vector_ref<T2,SZ>& x) \
2918 { \
2919 uint sat1 = 0; \
2920 vector<T2, SZ> in_x; in_x.assign(x); \
2921 for (uint i=0; i < SZ; i++) { \
2922 SIMDCF_WRAPPER(this->getref(i) = CmEmulSys::satur<T>::saturate((*this).get(i) OP in_x(i), sat1), SZ, i);\
2923 } \
2924 return *this; \
2925 } \
2926
2927
2928 matrix_operation(+) // +=
2929 matrix_operation(-) // -=
2930 matrix_operation(*) // *=
2931 matrix_operation(/) // /=
2932 matrix_operation(%) // %=
2933 matrix_operation(&) // &=
2934 matrix_operation(|) // |=
2935 matrix_operation(^) // ^=
2936 matrix_operation(>>) // >>=
2937 matrix_operation(<<) // <<=
2938 #undef matrix_operation
2939
2940
2941 //
2942 // matrix selects
2943 //
2944 template <typename T, uint R, uint C>
2945 template <typename T2>
2946 vector_ref<T2,R*C*sizeof(T)/sizeof(T2)> matrix<T,R,C>::format()
2947 {
2948 CM_STATIC_ERROR(R>0, "format row size is zero");
2949 CM_STATIC_ERROR(C>0, "format column size is zero");
2950 CM_STATIC_WARNING(((R*C*sizeof(T)%sizeof(T2)) == 0), "source matrix size is not exactly divisible by format type size");
2951 const uint N = R*C*sizeof(T)/sizeof(T2);
2952 static const bool conformable = check_true<(R*C*sizeof(T))%sizeof(T2) == 0>::value;
2953 assert((R*C*sizeof(T))%sizeof(T2) == 0);
2954 vector_ref<T2,N> ret(id());
2955 for (uint i=0; i<N; ++i) {
2956 SIMDCF_WRAPPER(ret.set_elem_ref(i, ((T2*)data) + i), N, i);
2957 }
2958
2959 return ret;
2960 }
2961 template <typename T, uint R, uint C>
2962 template <typename T2, uint R2, uint C2>
2963 matrix_ref<T2,R2,C2> matrix<T,R,C>::format()
2964 {
2965 CM_STATIC_ERROR(R2>0, "format row size is zero");
2966 CM_STATIC_ERROR(C2>0, "format column size is zero");
2967 CM_STATIC_ERROR((R2 == 0) || (C2 == 0) || (sizeof(T)*R*C >= sizeof(T2)*R2*C2), "format result size is larger than source size");
2968 CM_STATIC_WARNING((R2 == 0) || (C2 == 0) || (sizeof(T)*R*C <= sizeof(T2)*R2*C2), "format result size is smaller than source size");
2969 static const bool conformable1 = check_true<(R2 >= 0)>::value;
2970 static const bool conformable2 = check_true<(C2 >= 0)>::value;
2971 static const bool conformable = check_true<sizeof(T)*R*C == sizeof(T2)*R2*C2>::value;
2972 assert(sizeof(T)*R*C == sizeof(T2)*R2*C2);
2973 matrix_ref<T2,R2,C2> ret(id());
2974 for (uint i=0; i<R2*C2; ++i) {
2975 SIMDCF_WRAPPER(ret.set_elem_ref(i, ((T2*)data) + i), R2*C2, i);
2976 }
2977
2978 return ret;
2979 }
2980 template <typename T, uint R, uint C>
2981 template <typename T2>
2982 const vector_ref<T2,R*C*sizeof(T)/sizeof(T2)> matrix<T,R,C>::format() const
2983 {
2984 CM_STATIC_ERROR(R>0, "format row size is zero");
2985 CM_STATIC_ERROR(C>0, "format column size is zero");
2986 CM_STATIC_WARNING(((R*C*sizeof(T)%sizeof(T2)) == 0), "source matrix size is not exactly divisible by format type size");
2987 const uint N = R*C*sizeof(T)/sizeof(T2);
2988 static const bool conformable = check_true<(R*C*sizeof(T))%sizeof(T2) == 0>::value;
2989 assert((R*C*sizeof(T))%sizeof(T2) == 0);
2990 vector_ref<T2,N> ret(id());
2991 for (uint i=0; i<N; ++i) {
2992 SIMDCF_WRAPPER(ret.set_elem_ref(i, ((T2*)data) + i), N, i);
2993 }
2994
2995 return ret;
2996 }
2997 template <typename T, uint R, uint C>
2998 template <typename T2, uint R2, uint C2>
2999 const matrix_ref<T2,R2,C2> matrix<T,R,C>::format() const
3000 {
3001 CM_STATIC_ERROR(R2>0, "format row size is zero");
3002 CM_STATIC_ERROR(C2>0, "format column size is zero");
3003 CM_STATIC_ERROR((R2 == 0) || (C2 == 0) || (sizeof(T)*R*C >= sizeof(T2)*R2*C2), "format result size is larger than source size");
3004 CM_STATIC_WARNING((R2 == 0) || (C2 == 0) || (sizeof(T)*R*C <= sizeof(T2)*R2*C2), "format result size is smaller than source size");
3005 static const bool conformable1 = check_true<(R2 >= 0)>::value;
3006 static const bool conformable2 = check_true<(C2 >= 0)>::value;
3007 static const bool conformable = check_true<sizeof(T)*R*C == sizeof(T2)*R2*C2>::value;
3008 assert(sizeof(T)*R*C == sizeof(T2)*R2*C2);
3009 matrix_ref<T2,R2,C2> ret(id());
3010 for (uint i=0; i<R2*C2; ++i) {
3011 SIMDCF_WRAPPER(ret.set_elem_ref(i, ((T2*)data) + i), R2*C2, i);
3012 }
3013
3014 return ret;
3015 }
3016 template <typename T, uint R, uint C>
3017 vector_ref<T, C> matrix<T,R,C>::row(OFFSET index)
3018 {
3019 CM_STATIC_ERROR(R>0, "row size is zero");
3020 CM_STATIC_ERROR(C>0, "column size is zero");
3021 assert(index < R);
3022
3023 vector_ref<T, C> ret(id());
3024 for (uint i=0; i<C; ++i) {
3025 SIMDCF_WRAPPER(ret.set_elem_ref(i, data + C*index + i), C, i);
3026 }
3027 return ret;
3028 }
3029 template <typename T, uint R, uint C>
3030 matrix_ref<T,R,1> matrix<T,R,C>::column(OFFSET index)
3031 {
3032 CM_STATIC_ERROR(R>0, "row size is zero");
3033 CM_STATIC_ERROR(C>0, "column size is zero");
3034 assert(index < C);
3035
3036 matrix_ref<T,R,1> ret(id());
3037 for (uint i=0; i<R; ++i) {
3038 SIMDCF_WRAPPER(ret.set_elem_ref(i, data + C*i + index), R, i);
3039 }
3040 return ret;
3041 }
3042 template <typename T, uint R, uint C>
3043 template <uint R2, uint RS, uint C2, uint CS>
3044 matrix_ref<T,R2,C2> matrix<T,R,C>::select(OFFSET ioff, OFFSET joff)
3045 {
3046 CM_STATIC_ERROR((RS > 0), "select does not support a row stride of 0");
3047 CM_STATIC_ERROR((CS > 0), "select does not support a column stride of 0");
3048 CM_STATIC_WARNING(!(R2 == 1 && RS != 1), "when row size is 1 the row stride must also be 1");
3049 CM_STATIC_WARNING(!(C2 == 1 && CS != 1), "when column size is 1 the column stride must also be 1");
3050 CM_STATIC_WARNING(((C2 - 1) * CS + 1 <= C), "new row must fit inside the source row (new row out of bounds wrt original)");
3051 CM_STATIC_WARNING(((R2 - 1) * RS + 1 <= R), "new matrix must fit inside the source matrix (new matrix out of bounds wrt original)");
3052
3053 static const bool conformable1 = check_true<((R2 - 1) * RS < R)>::value;
3054 static const bool conformable2 = check_true<((C2 - 1) * CS < C)>::value;
3055 static const bool conformable3 = check_true<(RS > 0)>::value;
3056 static const bool conformable4 = check_true<(CS > 0)>::value;
3057 static const bool conformable5 = check_true<!(R2 == 1 && RS != 1)>::value;
3058 static const bool conformable6 = check_true<!(C2 == 1 && CS != 1)>::value;
3059
3060 assert(ioff < R - (R2 - 1) * RS);
3061 assert(joff < C - (C2 - 1) * CS);
3062
3063 matrix_ref<T,R2,C2> ret(id());
3064 for (uint i=0; i<R2; i++) {
3065 for (uint j=0; j<C2; j++) {
3066 if ((CS*j + joff) >= C) {
3067 // We go off the end of the source row
3068 // Fire an assert in debug mode
3069 #ifdef CM_DEBUG
3070 assert( 0 && "select statement access is out-of-bounds on source matrix");
3071 #endif
3072 SIMDCF_WRAPPER(ret.set_elem_ref(C2*i + j, ret.dummy()), R2 * C2, i * C2 + j);
3073 } else if ((C*(RS*i + ioff) + (CS*j) + joff) >= (C * R)) {
3074 // We go off the end of the source matrix
3075 // Fire an assert in debug mode
3076 #ifdef CM_DEBUG
3077 assert( 0 && "select statement access is out-of-bounds on source matrix");
3078 #endif
3079 SIMDCF_WRAPPER(ret.set_elem_ref(C2*i + j, ret.dummy()), R2 * C2, i * C2 + j );
3080 } else {
3081 // Everything is within bounds
3082 SIMDCF_WRAPPER(ret.set_elem_ref(C2*i + j, ((T*)data) + C*(RS*i + ioff) + (CS*j) + joff), R2 * C2, i * C2 + j);
3083 }
3084 }
3085 }
3086 return ret;
3087 }
3088
3089 template <typename T, uint R, uint C>
3090 template <uint R2, uint RS, uint C2, uint CS>
3091 const matrix_ref<T,R2,C2> matrix<T,R,C>::select(OFFSET ioff, OFFSET joff) const
3092 {
3093 CM_STATIC_ERROR((RS > 0), "select does not support a row stride of 0");
3094 CM_STATIC_ERROR((CS > 0), "select does not support a column stride of 0");
3095 CM_STATIC_WARNING(!(R2 == 1 && RS != 1), "when row size is 1 the row stride must also be 1");
3096 CM_STATIC_WARNING(!(C2 == 1 && CS != 1), "when column size is 1 the column stride must also be 1");
3097 CM_STATIC_WARNING(((C2 - 1) * CS + 1 <= C), "new row must fit inside the source row (new row out of bounds wrt original)");
3098 CM_STATIC_WARNING(((R2 - 1) * RS + 1 <= R), "new matrix must fit inside the source matrix (new matrix out of bounds wrt original)");
3099
3100 static const bool conformable1 = check_true<((R2 - 1) * RS < R)>::value;
3101 static const bool conformable2 = check_true<((C2 - 1) * CS < C)>::value;
3102 static const bool conformable3 = check_true<(RS > 0)>::value;
3103 static const bool conformable4 = check_true<(CS > 0)>::value;
3104 static const bool conformable5 = check_true<!(R2 == 1 && RS != 1)>::value;
3105 static const bool conformable6 = check_true<!(C2 == 1 && CS != 1)>::value;
3106
3107 assert(ioff < R - (R2 - 1) * RS);
3108 assert(joff < C - (C2 - 1) * CS);
3109
3110 matrix_ref<T,R2,C2> ret(id());
3111 for (uint i=0; i<R2; i++) {
3112 for (uint j=0; j<C2; j++) {
3113 if ((CS*j + joff) >= C) {
3114 // We go off the end of the source row
3115 // Fire an assert in debug mode
3116 #ifdef CM_DEBUG
3117 assert( 0 && "select statement access is out-of-bounds on source matrix");
3118 #endif
3119 SIMDCF_WRAPPER(ret.set_elem_ref(C2*i + j, ret.dummy()), R2 * C2, i * C2 + j);
3120 } else if ((C*(RS*i + ioff) + (CS*j) + joff) >= (C * R)) {
3121 // We go off the end of the source matrix
3122 // Fire an assert in debug mode
3123 #ifdef CM_DEBUG
3124 assert( 0 && "select statement access is out-of-bounds on source matrix");
3125 #endif
3126 SIMDCF_WRAPPER(ret.set_elem_ref(C2*i + j, ret.dummy()), R2 * C2, i * C2 + j );
3127 } else {
3128 // Everything is within bounds
3129 SIMDCF_WRAPPER(ret.set_elem_ref(C2*i + j, ((T*)data) + C*(RS*i + ioff) + (CS*j) + joff), R2 * C2, i * C2 + j);
3130 }
3131 }
3132 }
3133 return ret;
3134 }
3135
3136 template <typename T, uint R, uint C>
3137 template <uint R2, uint VS, uint WD, uint HS>
3138 const vector<T, R2*WD> matrix<T,R,C>::genx_select(OFFSET ioff, OFFSET joff)
3139 {
3140 CM_STATIC_ERROR((!std::is_same<T, double>::value), "genx_select is not supported for matrices with element type of 'double'");
3141 static const bool conformable1 = check_true<(R2 > 0)>::value;
3142 static const bool conformable2 = check_true<(VS >= 0)>::value;
3143 static const bool conformable3 = check_true<(WD > 0)>::value;
3144 static const bool conformable4 = check_true<(HS >= 0)>::value;
3145 assert(R2>=0 && VS>=0 && WD>=0 && HS >=0);
3146
3147 assert(ioff < R);
3148 assert(joff < C);
3149
3150 vector<T,R2*WD> ret(id());
3151 for (uint i=0; i < R2*WD; i++) {
3152 SIMDCF_WRAPPER(ret(i) = data[C*ioff + joff + (i/WD)*VS + (i%WD)*HS], R2*WD, i);
3153 }
3154 return ret;
3155 }
3156
3157 //1D iselect for matrix
3158 #if _MSC_VER >= 1700
3159 template <typename T, uint R, uint C>
3160 template <typename T2, uint WD>
3161 vector<T,WD> matrix<T,R,C>::iselect(const vector<T2,WD>& index)
3162 {
3163 return iselect(index, std::is_integral<T2>());
3164 }
3165
3166 template <typename T, uint R, uint C>
3167 template <typename T2, uint WD>
3168 vector<T,WD> matrix<T,R,C>::iselect(const vector<T2,WD>& index, std::true_type)
3169 {
3170 static const bool conformable1 = check_true<(WD > 0)>::value;
3171 static const bool type_conformable = is_inttype<T2>::value;
3172 assert(WD>=0 && R>=0 && C>=0);
3173
3174 for (uint i=0; i < WD; i++) {
3175 SIMDCF_WRAPPER(assert(index.get(i) < SZ), WD, i);
3176 }
3177
3178 vector<T,WD> ret(id());
3179 for (uint i=0; i < WD; i++) {
3180 SIMDCF_WRAPPER(ret(i) = data[index.get(i)], WD, i);
3181 }
3182 return ret;
3183 }
3184
3185 template <typename T, uint R, uint C>
3186 template <typename T2, uint WD>
3187 vector<T,WD> matrix<T,R,C>::iselect(const vector<T2,WD>& index, std::false_type)
3188 {
3189 static const bool conformable1 = check_true<(WD > 0)>::value;
3190 static const bool type_conformable = is_inttype<T2>::value;
3191 assert(WD>=0 && R>=0 && C>=0);
3192
3193 for (uint i=0; i < WD; i++) {
3194 SIMDCF_WRAPPER(assert(index.get(i) < SZ), WD, i);
3195 }
3196
3197 vector<T,WD> ret(id());
3198 for (uint i=0; i < WD; i++) {
3199 // in this case index doesn't have integral type elements
3200 // so can't be used - we will have already generated an error,
3201 // so just use 0 to allow compilation to continue (in case there
3202 // are more errors to find...)
3203 SIMDCF_WRAPPER(ret(i) = data[0], WD, i);
3204 }
3205 return ret;
3206 }
3207
3208 template <typename T, uint R, uint C>
3209 template <typename T2, uint WD>
3210 vector<T,WD> matrix<T,R,C>::iselect(const vector_ref<T2,WD>& index)
3211 {
3212 return iselect(index, std::is_integral<T2>());
3213 }
3214
3215 template <typename T, uint R, uint C>
3216 template <typename T2, uint WD>
3217 vector<T,WD> matrix<T,R,C>::iselect(const vector_ref<T2,WD>& index, std::true_type)
3218 {
3219 static const bool conformable1 = check_true<(WD > 0)>::value;
3220 static const bool type_conformable = is_inttype<T2>::value;
3221 assert(WD>=0 && R>=0 && C>=0);
3222
3223 for (uint i=0; i < WD; i++) {
3224 SIMDCF_WRAPPER(assert(index.get(i) < SZ), WD, i);
3225 }
3226
3227 vector<T,WD> ret(id());
3228 for (uint i=0; i < WD; i++) {
3229 SIMDCF_WRAPPER(ret(i) = data[index.get(i)], WD, i);
3230 }
3231 return ret;
3232 }
3233
3234 template <typename T, uint R, uint C>
3235 template <typename T2, uint WD>
3236 vector<T,WD> matrix<T,R,C>::iselect(const vector_ref<T2,WD>& index, std::false_type)
3237 {
3238 static const bool conformable1 = check_true<(WD > 0)>::value;
3239 static const bool type_conformable = is_inttype<T2>::value;
3240 assert(WD>=0 && R>=0 && C>=0);
3241
3242 for (uint i=0; i < WD; i++) {
3243 SIMDCF_WRAPPER(assert(index.get(i) < SZ), WD, i);
3244 }
3245
3246 vector<T,WD> ret(id());
3247 for (uint i=0; i < WD; i++) {
3248 // in this case index doesn't have integral type elements
3249 // so can't be used - we will have already generated an error,
3250 // so just use 0 to allow compilation to continue (in case there
3251 // are more errors to find...)
3252 SIMDCF_WRAPPER(ret(i) = data[0], WD, i);
3253 }
3254 return ret;
3255 }
3256 #else
3257 template <typename T, uint R, uint C>
3258 template <typename T2, uint WD>
3259 vector<T,WD> matrix<T,R,C>::iselect(const vector<T2,WD>& index)
3260 {
3261 static const bool conformable1 = check_true<(WD > 0)>::value;
3262 static const bool type_conformable = is_inttype<T2>::value;
3263 assert(WD>=0 && R>=0 && C>=0);
3264
3265 for (uint i=0; i < WD; i++) {
3266 SIMDCF_WRAPPER(assert(index.get(i) < SZ), WD, i);
3267 }
3268
3269 vector<T,WD> ret(id());
3270 for (uint i=0; i < WD; i++) {
3271 SIMDCF_WRAPPER(ret(i) = data[index.get(i)], WD, i);
3272 }
3273 return ret;
3274 }
3275
3276 template <typename T, uint R, uint C>
3277 template <typename T2, uint WD>
3278 vector<T,WD> matrix<T,R,C>::iselect(const vector_ref<T2,WD>& index)
3279 {
3280 static const bool conformable1 = check_true<(WD > 0)>::value;
3281 static const bool type_conformable = is_inttype<T2>::value;
3282 assert(WD>=0 && R>=0 && C>=0);
3283
3284 for (uint i=0; i < WD; i++) {
3285 SIMDCF_WRAPPER(assert(index.get(i) < SZ), WD, i);
3286 }
3287
3288 vector<T,WD> ret(id());
3289 for (uint i=0; i < WD; i++) {
3290 SIMDCF_WRAPPER(ret(i) = data[index.get(i)], WD, i);
3291 }
3292 return ret;
3293 }
3294 #endif
3295
3296 //below are 2D iselect for matrix
3297 template <typename T, uint R, uint C>
3298 template <typename T2, uint WD>
3299 vector<T,WD> matrix<T,R,C>::iselect(const vector<T2,WD>& index_x, const vector<T2,WD>& index_y)
3300 {
3301 CM_STATIC_WARNING((std::is_unsigned<T2>::value), "iselect index vector element type must be unsigned");
3302 static const bool conformable1 = check_true<(WD > 0)>::value;
3303 static const bool type_conformable = is_inttype<T2>::value;
3304 assert(WD>=0 && R>=0 && C>=0);
3305
3306 for (uint i=0; i < WD; i++) {
3307 SIMDCF_WRAPPER(assert(index_x.get(i) < R), WD, i);
3308 SIMDCF_WRAPPER(assert(index_y.get(i) < C), WD, i);
3309 }
3310
3311 vector<T,WD> ret(id());
3312 for (uint i=0; i < WD; i++) {
3313 SIMDCF_WRAPPER(ret(i) = data[index_x.get(i)*C + index_y.get(i)], WD, i);
3314 }
3315 return ret;
3316 }
3317
3318 template <typename T, uint R, uint C>
3319 template <typename T2, uint WD>
3320 vector<T,WD> matrix<T,R,C>::iselect(const vector_ref<T2,WD>& index_x, const vector<T2,WD>& index_y)
3321 {
3322 CM_STATIC_WARNING((std::is_unsigned<T2>::value), "iselect index vector element type must be unsigned");
3323 static const bool conformable1 = check_true<(WD > 0)>::value;
3324 static const bool type_conformable = is_inttype<T2>::value;
3325 assert(WD>=0 && R>=0 && C>=0);
3326
3327 for (uint i=0; i < WD; i++) {
3328 SIMDCF_WRAPPER(assert(index_x.get(i) < R), WD, i);
3329 SIMDCF_WRAPPER(assert(index_y.get(i) < C), WD, i);
3330 }
3331
3332 vector<T,WD> ret(id());
3333 for (uint i=0; i < WD; i++) {
3334 SIMDCF_WRAPPER(ret(i) = data[index_x.get(i)*C + index_y.get(i)], WD, i);
3335 }
3336 return ret;
3337 }
3338
3339
3340 template <typename T, uint R, uint C>
3341 template <typename T2, uint WD>
3342 vector<T,WD> matrix<T,R,C>::iselect(const vector<T2,WD>& index_x, const vector_ref<T2,WD>& index_y)
3343 {
3344 CM_STATIC_WARNING((std::is_unsigned<T2>::value), "iselect index vector element type must be unsigned");
3345 static const bool conformable1 = check_true<(WD > 0)>::value;
3346 static const bool type_conformable = is_inttype<T2>::value;
3347 assert(WD>=0 && R>=0 && C>=0);
3348
3349 for (uint i=0; i < WD; i++) {
3350 SIMDCF_WRAPPER(assert(index_x.get(i) < R), WD, i);
3351 SIMDCF_WRAPPER(assert(index_y.get(i) < C), WD, i);
3352 }
3353
3354 vector<T,WD> ret(id());
3355 for (uint i=0; i < WD; i++) {
3356 SIMDCF_WRAPPER(ret(i) = data[index_x.get(i)*C + index_y.get(i)], WD, i);
3357 }
3358 return ret;
3359 }
3360
3361 template <typename T, uint R, uint C>
3362 template <typename T2, uint WD>
3363 vector<T,WD> matrix<T,R,C>::iselect(const vector_ref<T2,WD>& index_x, const vector_ref<T2,WD>& index_y)
3364 {
3365 CM_STATIC_WARNING((std::is_unsigned<T2>::value), "iselect index vector element type must be unsigned");
3366 static const bool conformable1 = check_true<(WD > 0)>::value;
3367 static const bool type_conformable = is_inttype<T2>::value;
3368 assert(WD>=0 && R>=0 && C>=0);
3369
3370 for (uint i=0; i < WD; i++) {
3371 SIMDCF_WRAPPER(assert(index_x.get(i) < R), WD, i);
3372 SIMDCF_WRAPPER(assert(index_y.get(i) < C), WD, i);
3373 }
3374
3375 vector<T,WD> ret(id());
3376 for (uint i=0; i < WD; i++) {
3377 SIMDCF_WRAPPER(ret(i) = data[index_x.get(i)*C + index_y.get(i)], WD, i);
3378 }
3379 return ret;
3380 }
3381 // end of iselect for 2D matrix
3382
3383 template <typename T, uint R, uint C>
3384 matrix_ref<T, R, C> CM_NOINLINE matrix<T,R,C>::select_all()
3385 {
3386 matrix_ref<T,R,C> ret = this->select<R, 1, C, 1>();
3387 return ret;
3388 }
3389
3390 template <typename T, uint R, uint C>
3391 const matrix_ref<T, R, C> CM_NOINLINE matrix<T,R,C>::select_all() const
3392 {
3393 const matrix_ref<T,R,C> ret = this->select<R, 1, C, 1>();
3394 return ret;
3395 }
3396
3397 /*******************************************************************
3398 /
3399 / matrix_ref
3400 /
3401 *******************************************************************/
3402 template <typename T, uint R, uint C>
3403 bool matrix_ref<T,R,C>::is_contiguous() const
3404 {
3405 if (SZ == 1)
3406 return true;
3407
3408 for (uint i=0; i<SZ-1; ++i) {
3409 if (data[i+1]-data[i] != 1)
3410 return false;
3411 }
3412 return true;
3413 }
3414
3415 template <typename T, uint R, uint C>
3416 bool matrix_ref<T,R,C>::is_contiguous(const uint start, const uint end) const
3417 {
3418 if (start == end)
3419 return true;
3420
3421 if (SZ == 1)
3422 return true;
3423
3424 for (uint i=start; i != end; ++i) {
3425 if (data[i+1]-data[i] != 1)
3426 return false;
3427 }
3428 return true;
3429 }
3430
3431 //
3432 // matrix_ref copy constructor
3433 //
3434 template <typename T, uint R, uint C>
3435 matrix_ref<T,R,C>::matrix_ref(const matrix_ref<T,R,C>& src)
3436 {
3437 number = src.number;
3438
3439 matrix_ref<T,R,C> in_src(id());
3440 memcpy(in_src.data, src.data, sizeof(T*) * SZ);
3441
3442 memcpy(data, in_src.data,sizeof(T*)*SZ);
3443 }
3444
3445 template <typename T, uint R, uint C>
3446 matrix_ref<T,R,C>::matrix_ref(matrix<T,R,C>& src)
3447 {
3448 number = src.id();
3449 for (uint i = 0; i < ROWS; i++)
3450 for (uint j = 0; j < COLS; j++) {
3451 SIMDCF_WRAPPER(
3452 set_elem_ref(i * COLS + j, (T*)(src.get_addr(i * COLS + j))),
3453 SZ, j);
3454 }
3455 }
3456 //
3457 // matrix_ref assignment operator
3458 //
3459 template <typename T, uint R, uint C>
3460 matrix_ref<T,R,C>& matrix_ref<T,R,C>::operator = (const matrix<T,R,C>& src)
3461 {
3462 vector<T, SZ> in_src; in_src.assign(src);
3463 for (uint i=0; i<SZ; ++i) {
3464 SIMDCF_WRAPPER((*this)(i) = in_src(i), SZ, i);
3465 }
3466 return *this;
3467 }
3468
3469 //
3470 // matrix_ref operator =
3471 //
3472 template <typename T, uint R, uint C>
3473 template <typename T2>
3474 matrix_ref<T,R,C>& matrix_ref<T,R,C>::operator = (const T2 src)
3475 {
3476 uint sat1 = 0;
3477 //uint sat1 = CmEmulSys::_SetSatur<T2, is_inttype<T>::value>::SetSatur();
3478 for (uint i=0; i < SZ; i++) {
3479 SIMDCF_WRAPPER(this->getref(i) = CmEmulSys::satur<T>::saturate(src, sat1), SZ, i);
3480 }
3481
3482 return *this;
3483 }
3484 template <typename T, uint R, uint C>
3485 template <typename T2, uint R2, uint C2>
3486 matrix_ref<T,R,C>& matrix_ref<T,R,C>::operator = (const matrix<T2,R2,C2>& src)
3487 {
3488 CM_STATIC_ERROR(R*C == R2*C2, "matrices have different dimensions"); \
3489 static const bool conformable = check_true<R*C == R2*C2>::value;
3490 assert(R*C == R2*C2);
3491
3492 uint sat1 = 0;
3493 //uint sat1 = CmEmulSys::_SetSatur<T2, is_inttype<T>::value>::SetSatur();
3494 vector<T2, SZ> in_src; in_src.assign(src);
3495 for (uint i=0; i < SZ; i++) {
3496 SIMDCF_WRAPPER(this->getref(i) = CmEmulSys::satur<T>::saturate(in_src(i), sat1), SZ, i);
3497 }
3498
3499 return *this;
3500 }
3501
3502 template <typename T, uint R, uint C>
3503 matrix_ref<T,R,C>& matrix_ref<T,R,C>::operator = (const matrix_ref<T,R,C>& src)
3504 {
3505 vector<T, SZ> in_src; in_src.assign(src);
3506 for (uint i=0; i<SZ; ++i) {
3507 SIMDCF_WRAPPER(this->getref(i) = T(in_src(i)), SZ, i);
3508 }
3509 return *this;
3510 }
3511
3512 template <typename T, uint R, uint C>
3513 template <typename T2, uint R2, uint C2>
3514 matrix_ref<T,R,C>& matrix_ref<T,R,C>::operator = (const matrix_ref<T2,R2,C2>& src)
3515 {
3516 CM_STATIC_ERROR(R*C == R2*C2, "matrices have different dimensions"); \
3517 static const bool conformable = check_true<R*C == R2*C2>::value;
3518 assert(R*C == R2*C2);
3519
3520 uint sat1 = 0;
3521 //uint sat1 = CmEmulSys::_SetSatur<T2, is_inttype<T>::value>::SetSatur();
3522 vector<T2, SZ> in_src; in_src.assign(src);
3523 for (uint i=0; i < SZ; i++) {
3524 SIMDCF_WRAPPER(this->getref(i) = CmEmulSys::satur<T>::saturate(in_src(i), sat1), SZ, i);
3525 }
3526
3527 return *this;
3528 }
3529
3530 //Should be inserted for GenX style of float->integer conversions
3531 //sat1 = CmEmulSys::_SetSatur<T2, is_inttype<T>::value>::SetSatur();
3532 #define matrix_ref_operation(OP) \
3533 \
3534 template <typename T, uint R, uint C> \
3535 template <typename T2> \
3536 matrix_ref<T,R,C>& matrix_ref<T,R,C>::operator OP##= (const T2 x) \
3537 { \
3538 static const bool type_conformable = cmtype<T2>::value; \
3539 uint sat1 = 0; \
3540 for (uint i=0; i < SZ; i++) { \
3541 SIMDCF_WRAPPER(this->getref(i) = CmEmulSys::satur<T>::saturate((*this).get(i) OP x, sat1), SZ, i);\
3542 } \
3543 return *this; \
3544 } \
3545 template <typename T, uint R, uint C> \
3546 template <typename T2, uint R2, uint C2> \
3547 matrix_ref<T,R,C>& matrix_ref<T,R,C>::operator OP##= (const matrix<T2,R2,C2>& x) \
3548 { \
3549 CM_STATIC_ERROR(R*C == R2*C2, "matrices have different dimensions"); \
3550 static const bool conformable = check_true<R*C == R2*C2>::value; \
3551 assert(R*C == R2*C2); \
3552 uint sat1 = 0; \
3553 vector<T2, SZ> in_x; in_x.assign(x); \
3554 for (uint i=0; i < SZ; i++) { \
3555 SIMDCF_WRAPPER(this->getref(i) = CmEmulSys::satur<T>::saturate((*this).get(i) OP in_x(i), sat1), SZ, i);\
3556 } \
3557 return *this; \
3558 } \
3559 template <typename T, uint R, uint C> \
3560 template <typename T2, uint R2, uint C2> \
3561 matrix_ref<T,R,C>& matrix_ref<T,R,C>::operator OP##= (const matrix_ref<T2,R2,C2>& x) \
3562 { \
3563 CM_STATIC_ERROR(R*C == R2*C2, "matrices have different dimensions"); \
3564 static const bool conformable = check_true<R*C == R2*C2>::value; \
3565 assert(R*C == R2*C2); \
3566 uint sat1 = 0; \
3567 vector<T2, SZ> in_x; in_x.assign(x); \
3568 for (uint i=0; i < SZ; i++) { \
3569 SIMDCF_WRAPPER(this->getref(i) = CmEmulSys::satur<T>::saturate((*this).get(i) OP in_x(i), sat1), SZ, i);\
3570 } \
3571 return *this; \
3572 } \
3573 template <typename T, uint R, uint C> \
3574 template <typename T2> \
3575 matrix_ref<T,R,C>& matrix_ref<T,R,C>::operator OP##= (const vector<T2,SZ>& x) \
3576 { \
3577 CM_STATIC_ERROR(R*C == SZ, "matrix and vector have a different number of elements"); \
3578 uint sat1 = 0; \
3579 vector<T2, SZ> in_x; in_x.assign(x); \
3580 for (uint i=0; i < SZ; i++) { \
3581 SIMDCF_WRAPPER(this->getref(i) = CmEmulSys::satur<T>::saturate((*this).get(i) OP in_x(i), sat1), SZ, i);\
3582 } \
3583 return *this; \
3584 } \
3585 template <typename T, uint R, uint C> \
3586 template <typename T2> \
3587 matrix_ref<T,R,C>& matrix_ref<T,R,C>::operator OP##= (const vector_ref<T2,SZ>& x) \
3588 { \
3589 uint sat1 = 0; \
3590 vector<T2, SZ> in_x; in_x.assign(x); \
3591 for (uint i=0; i < SZ; i++) { \
3592 SIMDCF_WRAPPER(this->getref(i) = CmEmulSys::satur<T>::saturate((*this).get(i) OP in_x(i), sat1), SZ, i); \
3593 } \
3594 return *this; \
3595 } \
3596
3597 matrix_ref_operation(+) // +=
3598 matrix_ref_operation(-) // -=
3599 matrix_ref_operation(*) // *=
3600 matrix_ref_operation(/) // /=
3601 matrix_ref_operation(%) // %=
3602 matrix_ref_operation(&) // &=
3603 matrix_ref_operation(|) // |=
3604 matrix_ref_operation(^) // ^=
3605 matrix_ref_operation(>>) // >>=
3606 matrix_ref_operation(<<) // <<=
3607 #undef matrix_operation
3608
3609 //
3610 // matrix_ref selects
3611 //
3612 template <typename T, uint R, uint C>
3613 template <typename T2>
3614 vector_ref<T2,R*C*sizeof(T)/sizeof(T2)> matrix_ref<T,R,C>::format()
3615 {
3616 CM_STATIC_ERROR(R>0, "format row size is zero");
3617 CM_STATIC_ERROR(C>0, "format column size is zero");
3618 CM_STATIC_WARNING(((R*C*sizeof(T)%sizeof(T2)) == 0), "source matrix size is not exactly divisible by format type size");
3619
3620 // assert(is_contiguous());
3621
3622 const uint N = R*C*sizeof(T)/sizeof(T2);
3623 static const bool conformable = check_true<(R*C*sizeof(T))%sizeof(T2) == 0>::value;
3624 assert((R*C*sizeof(T))%sizeof(T2) == 0);
3625 vector_ref<T2,N> ret(id());
3626
3627 if (sizeof(T2) < sizeof(T))
3628 {
3629 uint ratio = sizeof(T) / sizeof(T2);
3630 for (uint i = 0; i < R*C; ++i)
3631 {
3632 for (uint j = 0; j < ratio; j++)
3633 {
3634 SIMDCF_WRAPPER(ret.set_elem_ref(ratio* i + j, ((T2*)data[i]) + j), N, ratio* i + j);
3635 }
3636 }
3637 }
3638 else
3639 {
3640
3641 for (uint i = 0; i < N; ++i) {
3642 SIMDCF_WRAPPER(ret.set_elem_ref(i, (T2*)(data[i * sizeof(T2) / sizeof(T)])), N, i);
3643 }
3644 }
3645 return ret;
3646 }
3647 template <typename T, uint R, uint C>
3648 template <typename T2, uint R2, uint C2>
3649 matrix_ref<T2,R2,C2> matrix_ref<T,R,C>::format()
3650 {
3651 CM_STATIC_ERROR(R2>0, "format row size is zero");
3652 CM_STATIC_ERROR(C2>0, "format column size is zero");
3653 CM_STATIC_ERROR((R2 == 0) || (C2 == 0) || (sizeof(T)*R*C >= sizeof(T2)*R2*C2), "format result size is larger than source size");
3654 CM_STATIC_WARNING((R2 == 0) || (C2 == 0) || (sizeof(T)*R*C <= sizeof(T2)*R2*C2), "format result size is smaller than source size");
3655 static const bool conformable1 = check_true<(R2 >= 0)>::value;
3656 static const bool conformable2 = check_true<(C2 >= 0)>::value;
3657 static const bool conformable = check_true<sizeof(T)*R*C == sizeof(T2)*R2*C2>::value;
3658
3659 // assert(is_contiguous());
3660
3661 assert(sizeof(T)*R*C == sizeof(T2)*R2*C2);
3662 matrix_ref<T2,R2,C2> ret(id());
3663 if (sizeof(T2) < sizeof(T))
3664 {
3665 uint ratio = sizeof(T) / sizeof(T2);
3666 for (uint i = 0; i < R*C; ++i)
3667 {
3668 for (uint j = 0; j < ratio; j++)
3669 {
3670 SIMDCF_WRAPPER(ret.set_elem_ref(ratio* i + j, ((T2*)data[i]) + j), R2*C2, ratio* i + j);
3671 }
3672 }
3673 }
3674 else
3675 {
3676 for (uint i = 0; i<R2*C2; ++i) {
3677 SIMDCF_WRAPPER(ret.set_elem_ref(i, (T2*)(data[i * sizeof(T2) / sizeof(T)])), R2*C2, i);
3678 }
3679 }
3680
3681 return ret;
3682 }
3683 template <typename T, uint R, uint C>
3684 template <typename T2>
3685 const vector_ref<T2,R*C*sizeof(T)/sizeof(T2)> matrix_ref<T,R,C>::format() const
3686 {
3687 CM_STATIC_ERROR(R>0, "format row size is zero");
3688 CM_STATIC_ERROR(C>0, "format column size is zero");
3689 CM_STATIC_WARNING(((R*C*sizeof(T)%sizeof(T2)) == 0), "source matrix size is not exactly divisible by format type size");
3690
3691 // assert(is_contiguous());
3692
3693 const uint N = R*C*sizeof(T)/sizeof(T2);
3694 static const bool conformable = check_true<(R*C*sizeof(T))%sizeof(T2) == 0>::value;
3695 assert((R*C*sizeof(T))%sizeof(T2) == 0);
3696 vector_ref<T2,N> ret(id());
3697 if (sizeof(T2) < sizeof(T))
3698 {
3699 uint ratio = sizeof(T) / sizeof(T2);
3700 for (uint i = 0; i < R*C; ++i)
3701 {
3702 for (uint j = 0; j < ratio; j++)
3703 {
3704 SIMDCF_WRAPPER(ret.set_elem_ref(ratio* i + j, ((T2*)data[i]) + j), N, ratio* i + j);
3705 }
3706 }
3707 }
3708 else
3709 {
3710
3711 for (uint i = 0; i < N; ++i) {
3712 SIMDCF_WRAPPER(ret.set_elem_ref(i, (T2*)(data[i * sizeof(T2) / sizeof(T)])), N, i);
3713 }
3714 }
3715 return ret;
3716 }
3717 template <typename T, uint R, uint C>
3718 template <typename T2, uint R2, uint C2>
3719 const matrix_ref<T2,R2,C2> matrix_ref<T,R,C>::format() const
3720 {
3721 CM_STATIC_ERROR(R2>0, "format row size is zero");
3722 CM_STATIC_ERROR(C2>0, "format column size is zero");
3723 CM_STATIC_ERROR((R2 == 0) || (C2 == 0) || (sizeof(T)*R*C >= sizeof(T2)*R2*C2), "format result size is larger than source size");
3724 CM_STATIC_WARNING((R2 == 0) || (C2 == 0) || (sizeof(T)*R*C <= sizeof(T2)*R2*C2), "format result size is smaller than source size");
3725 static const bool conformable1 = check_true<(R2 >= 0)>::value;
3726 static const bool conformable2 = check_true<(C2 >= 0)>::value;
3727 static const bool conformable = check_true<sizeof(T)*R*C == sizeof(T2)*R2*C2>::value;
3728
3729 // assert(is_contiguous());
3730
3731 assert(sizeof(T)*R*C == sizeof(T2)*R2*C2);
3732 matrix_ref<T2,R2,C2> ret(id());
3733 if (sizeof(T2) < sizeof(T))
3734 {
3735 uint ratio = sizeof(T) / sizeof(T2);
3736 for (uint i = 0; i < R*C; ++i)
3737 {
3738 for (uint j = 0; j < ratio; j++)
3739 {
3740 SIMDCF_WRAPPER(ret.set_elem_ref(ratio* i + j, ((T2*)data[i]) + j), R2*C2, ratio* i + j);
3741 }
3742 }
3743 }
3744 else
3745 {
3746 for (uint i = 0; i<R2*C2; ++i) {
3747 SIMDCF_WRAPPER(ret.set_elem_ref(i, (T2*)(data[i * sizeof(T2) / sizeof(T)])), R2*C2, i);
3748 }
3749 }
3750
3751 return ret;
3752 }
3753 template <typename T, uint R, uint C>
3754 vector_ref<T, C> matrix_ref<T,R,C>::row(OFFSET index)
3755 {
3756 assert(index < R);
3757
3758 #ifdef CM_V1
3759 assert(is_contiguous());
3760 #endif
3761
3762 vector_ref<T, C> ret(id());
3763 for (uint i=0; i<C; ++i) {
3764 SIMDCF_WRAPPER(ret.set_elem_ref(i, *(data + C*index + i)), C, i);
3765 }
3766 return ret;
3767 }
3768 template <typename T, uint R, uint C>
3769 matrix_ref<T,R,1> matrix_ref<T,R,C>::column(OFFSET index)
3770 {
3771 assert(index < C);
3772
3773 #ifdef CM_V1
3774 assert(is_contiguous());
3775 #endif
3776
3777 matrix_ref<T,R,1> ret(id());
3778 for (uint i=0; i<R; ++i) {
3779 SIMDCF_WRAPPER(ret.set_elem_ref(i, data[C*i + index]), R, i);
3780 }
3781 return ret;
3782 }
3783 template <typename T, uint R, uint C>
3784 template <uint R2, uint RS, uint C2, uint CS>
3785 matrix_ref<T,R2,C2> matrix_ref<T,R,C>::select(OFFSET ioff, OFFSET joff)
3786 {
3787 CM_STATIC_ERROR((RS > 0), "select does not support a row stride of 0");
3788 CM_STATIC_ERROR((CS > 0), "select does not support a column stride of 0");
3789 CM_STATIC_WARNING(!(R2 == 1 && RS != 1), "when row size is 1 the row stride must also be 1");
3790 CM_STATIC_WARNING(!(C2 == 1 && CS != 1), "when column size is 1 the column stride must also be 1");
3791 CM_STATIC_WARNING(((C2 - 1) * CS + 1 <= C), "new row must fit inside the source row (new row out of bounds wrt original)");
3792 CM_STATIC_WARNING(((R2 - 1) * RS + 1 <= R), "new matrix must fit inside the source matrix (new matrix out of bounds wrt original)");
3793
3794 static const bool conformable1 = check_true<((R2 - 1) * RS < R)>::value;
3795 static const bool conformable2 = check_true<((C2 - 1) * CS < C)>::value;
3796 static const bool conformable3 = check_true<(RS > 0)>::value;
3797 static const bool conformable4 = check_true<(CS > 0)>::value;
3798 static const bool conformable5 = check_true<!(R2 == 1 && RS != 1)>::value;
3799 static const bool conformable6 = check_true<!(C2 == 1 && CS != 1)>::value;
3800
3801 assert(ioff < R - (R2 - 1) * RS);
3802 assert(joff < C - (C2 - 1) * CS);
3803
3804 #ifdef CM_V1
3805 assert(is_contiguous());
3806 #endif
3807
3808 matrix_ref<T,R2,C2> ret(id());
3809 for (uint i=0; i<R2; i++) {
3810 for (uint j=0; j<C2; j++) {
3811 if ((CS*j + joff) >= C) {
3812 // We go off the end of the source row
3813 // Fire an assert in debug mode
3814 #ifdef CM_DEBUG
3815 assert(0 && "select statement access is out-of-bounds on source matrix_ref");
3816 #endif
3817 ret.set_elem_ref(C2*i + j, ret.dummy());
3818 } else if ((C*(RS*i + ioff) + (CS*j) + joff) >= (C * R)) {
3819 // We go off the end of the source matrix
3820 // Fire an assert in debug mode
3821 #ifdef CM_DEBUG
3822 assert(0 && "select statement access is out-of-bounds on source matrix_ref");
3823 #endif
3824 ret.set_elem_ref(C2*i + j, ret.dummy());
3825 } else {
3826 // Everything is within bounds
3827 ret.set_elem_ref(C2*i + j, data[C*(RS*i + ioff) + (CS*j) + joff]);
3828 }
3829 }
3830 }
3831 return ret;
3832 }
3833
3834 template <typename T, uint R, uint C>
3835 template <uint R2, uint RS, uint C2, uint CS>
3836 const matrix_ref<T,R2,C2> matrix_ref<T,R,C>::select(OFFSET ioff, OFFSET joff) const
3837 {
3838 CM_STATIC_ERROR((RS > 0), "select does not support a row stride of 0");
3839 CM_STATIC_ERROR((CS > 0), "select does not support a column stride of 0");
3840 CM_STATIC_WARNING(!(R2 == 1 && RS != 1), "when row size is 1 the row stride must also be 1");
3841 CM_STATIC_WARNING(!(C2 == 1 && CS != 1), "when column size is 1 the column stride must also be 1");
3842 CM_STATIC_WARNING(((C2 - 1) * CS + 1 <= C), "new row must fit inside the source row (new row out of bounds wrt original)");
3843 CM_STATIC_WARNING(((R2 - 1) * RS + 1 <= R), "new matrix must fit inside the source matrix (new matrix out of bounds wrt original)");
3844
3845 static const bool conformable1 = check_true<((R2 - 1) * RS < R)>::value;
3846 static const bool conformable2 = check_true<((C2 - 1) * CS < C)>::value;
3847 static const bool conformable3 = check_true<(RS > 0)>::value;
3848 static const bool conformable4 = check_true<(CS > 0)>::value;
3849 static const bool conformable5 = check_true<!(R2 == 1 && RS != 1)>::value;
3850 static const bool conformable6 = check_true<!(C2 == 1 && CS != 1)>::value;
3851
3852 assert(ioff < R - (R2 - 1) * RS);
3853 assert(joff < C - (C2 - 1) * CS);
3854
3855 #ifdef CM_V1
3856 assert(is_contiguous());
3857 #endif
3858
3859 matrix_ref<T,R2,C2> ret(id());
3860 for (uint i=0; i<R2; i++) {
3861 for (uint j=0; j<C2; j++) {
3862 if ((CS*j + joff) >= C) {
3863 // We go off the end of the source row
3864 // Fire an assert in debug mode
3865 #ifdef CM_DEBUG
3866 assert(0 && "select statement access is out-of-bounds on source matrix_ref");
3867 #endif
3868 ret.set_elem_ref(C2*i + j, ret.dummy());
3869 } else if ((C*(RS*i + ioff) + (CS*j) + joff) >= (C * R)) {
3870 // We go off the end of the source matrix
3871 // Fire an assert in debug mode
3872 #ifdef CM_DEBUG
3873 assert(0 && "select statement access is out-of-bounds on source matrix_ref");
3874 #endif
3875 ret.set_elem_ref(C2*i + j, ret.dummy());
3876 } else {
3877 // Everything is within bounds
3878 ret.set_elem_ref(C2*i + j, data[C*(RS*i + ioff) + (CS*j) + joff]);
3879 }
3880 }
3881 }
3882 return ret;
3883 }
3884
3885 template <typename T, uint R, uint C>
3886 template <uint R2, uint VS, uint WD, uint HS>
3887 const vector<T, R2*WD> matrix_ref<T,R,C>::genx_select(OFFSET ioff, OFFSET joff)
3888 {
3889 static const bool conformable1 = check_true<(R2 > 0)>::value;
3890 static const bool conformable2 = check_true<(VS >= 0)>::value;
3891 static const bool conformable3 = check_true<(WD > 0)>::value;
3892 static const bool conformable4 = check_true<(HS >= 0)>::value;
3893 assert(R2>=0 && VS>=0 && WD>=0 && HS >=0);
3894
3895 assert(ioff < R);
3896 assert(joff < C);
3897
3898 vector<T,R2*WD> ret(id());
3899 for (uint i=0; i < R2*WD; i++) {
3900 SIMDCF_WRAPPER(ret(i) = *data[C*ioff + joff + (i/WD)*VS + (i%WD)*HS], R2*WD, i);
3901 }
3902 return ret;
3903 }
3904
3905 //below are 1D iselect for matrix_ref
3906 #if _MSC_VER >= 1700
3907 template <typename T, uint R, uint C>
3908 template <typename T2, uint WD>
3909 vector<T,WD> matrix_ref<T,R,C>::iselect(const vector<T2,WD>& index)
3910 {
3911 return iselect(index, std::is_integral<T2>());
3912 }
3913
3914 template <typename T, uint R, uint C>
3915 template <typename T2, uint WD>
3916 vector<T,WD> matrix_ref<T,R,C>::iselect(const vector<T2,WD>& index, std::true_type)
3917 {
3918 static const bool conformable1 = check_true<(WD > 0)>::value;
3919 static const bool type_conformable = is_inttype<T2>::value;
3920 assert(WD>=0 && R>=0 && C>=0);
3921
3922 for (uint i=0; i < WD; i++) {
3923 SIMDCF_WRAPPER(assert(index.get(i) < SZ), WD, i);
3924 }
3925
3926 vector<T,WD> ret(id());
3927 for (uint i=0; i < WD; i++) {
3928 SIMDCF_WRAPPER(ret(i) = *data[index.get(i)], WD, i);
3929 }
3930 return ret;
3931 }
3932
3933 template <typename T, uint R, uint C>
3934 template <typename T2, uint WD>
3935 vector<T,WD> matrix_ref<T,R,C>::iselect(const vector<T2,WD>& index, std::false_type)
3936 {
3937 static const bool conformable1 = check_true<(WD > 0)>::value;
3938 static const bool type_conformable = is_inttype<T2>::value;
3939 assert(WD>=0 && R>=0 && C>=0);
3940
3941 for (uint i=0; i < WD; i++) {
3942 SIMDCF_WRAPPER(assert(index.get(i) < SZ), WD, i);
3943 }
3944
3945 vector<T,WD> ret(id());
3946 for (uint i=0; i < WD; i++) {
3947 // in this case index doesn't have integral type elements
3948 // so can't be used - we will have already generated an error,
3949 // so just use 0 to allow compilation to continue (in case there
3950 // are more errors to find...)
3951 SIMDCF_WRAPPER(ret(i) = *data[0], WD, i);
3952 }
3953 return ret;
3954 }
3955
3956 template <typename T, uint R, uint C>
3957 template <typename T2, uint WD>
3958 vector<T,WD> matrix_ref<T,R,C>::iselect(const vector_ref<T2,WD>& index)
3959 {
3960 return iselect(index, std::is_integral<T2>());
3961 }
3962
3963 template <typename T, uint R, uint C>
3964 template <typename T2, uint WD>
3965 vector<T,WD> matrix_ref<T,R,C>::iselect(const vector_ref<T2,WD>& index, std::true_type)
3966 {
3967 static const bool conformable1 = check_true<(WD > 0)>::value;
3968 static const bool type_conformable = is_inttype<T2>::value;
3969 assert(WD>=0 && R>=0 && C>=0);
3970
3971 for (uint i=0; i < WD; i++) {
3972 SIMDCF_WRAPPER(assert(index.get(i) < SZ), WD, i);
3973 }
3974
3975 vector<T,WD> ret(id());
3976 for (uint i=0; i < WD; i++) {
3977 SIMDCF_WRAPPER(ret(i) = *data[index.get(i)], WD, i);
3978 }
3979 return ret;
3980 }
3981
3982 template <typename T, uint R, uint C>
3983 template <typename T2, uint WD>
3984 vector<T,WD> matrix_ref<T,R,C>::iselect(const vector_ref<T2,WD>& index, std::false_type)
3985 {
3986 static const bool conformable1 = check_true<(WD > 0)>::value;
3987 static const bool type_conformable = is_inttype<T2>::value;
3988 assert(WD>=0 && R>=0 && C>=0);
3989
3990 for (uint i=0; i < WD; i++) {
3991 SIMDCF_WRAPPER(assert(index.get(i) < SZ), WD, i);
3992 }
3993
3994 vector<T,WD> ret(id());
3995 for (uint i=0; i < WD; i++) {
3996 // in this case index doesn't have integral type elements
3997 // so can't be used - we will have already generated an error,
3998 // so just use 0 to allow compilation to continue (in case there
3999 // are more errors to find...)
4000 SIMDCF_WRAPPER(ret(i) = *data[0], WD, i);
4001 }
4002 return ret;
4003 }
4004 #else
4005 template <typename T, uint R, uint C>
4006 template <typename T2, uint WD>
4007 vector<T,WD> matrix_ref<T,R,C>::iselect(const vector<T2,WD>& index)
4008 {
4009 static const bool conformable1 = check_true<(WD > 0)>::value;
4010 static const bool type_conformable = is_inttype<T2>::value;
4011 assert(WD>=0 && R>=0 && C>=0);
4012
4013 for (uint i=0; i < WD; i++) {
4014 SIMDCF_WRAPPER(assert(index.get(i) < SZ), WD, i);
4015 }
4016
4017 vector<T,WD> ret(id());
4018 for (uint i=0; i < WD; i++) {
4019 SIMDCF_WRAPPER(ret(i) = *data[index.get(i)], WD, i);
4020 }
4021 return ret;
4022 }
4023
4024 template <typename T, uint R, uint C>
4025 template <typename T2, uint WD>
4026 vector<T,WD> matrix_ref<T,R,C>::iselect(const vector_ref<T2,WD>& index)
4027 {
4028 static const bool conformable1 = check_true<(WD > 0)>::value;
4029 static const bool type_conformable = is_inttype<T2>::value;
4030 assert(WD>=0 && R>=0 && C>=0);
4031
4032 for (uint i=0; i < WD; i++) {
4033 SIMDCF_WRAPPER(assert(index.get(i) < SZ), WD, i);
4034 }
4035
4036 vector<T,WD> ret(id());
4037 for (uint i=0; i < WD; i++) {
4038 SIMDCF_WRAPPER(ret(i) = *data[index.get(i)], WD, i);
4039 }
4040 return ret;
4041 }
4042 #endif
4043
4044 //below are 2D iselect for matrix_ref
4045 template <typename T, uint R, uint C>
4046 template <typename T2, uint WD>
4047 vector<T,WD> matrix_ref<T,R,C>::iselect(const vector<T2,WD>& index_x,
4048 const vector<T2,WD>& index_y)
4049 {
4050 static const bool conformable1 = check_true<(WD > 0)>::value;
4051 static const bool type_conformable = is_inttype<T2>::value;
4052 assert(WD>=0 && R>=0 && C>=0);
4053
4054 for (uint i=0; i < WD; i++) {
4055 SIMDCF_WRAPPER(assert(index_x.get(i) < R), WD, i);
4056 SIMDCF_WRAPPER(assert(index_y.get(i) < C), WD, i);
4057 }
4058
4059 vector<T,WD> ret(id());
4060 for (uint i=0; i < WD; i++) {
4061 SIMDCF_WRAPPER(ret(i) = *data[index_x.get(i)*C+index_y.get(i)], WD, i);
4062 }
4063 return ret;
4064 }
4065
4066 template <typename T, uint R, uint C>
4067 template <typename T2, uint WD>
4068 vector<T,WD> matrix_ref<T,R,C>::iselect(const vector_ref<T2,WD>& index_x,
4069 const vector<T2,WD>& index_y)
4070 {
4071 static const bool conformable1 = check_true<(WD > 0)>::value;
4072 static const bool type_conformable = is_inttype<T2>::value;
4073 assert(WD>=0 && R>=0 && C>=0);
4074
4075 for (uint i=0; i < WD; i++) {
4076 SIMDCF_WRAPPER(assert(index_x.get(i) < R), WD, i);
4077 SIMDCF_WRAPPER(assert(index_y.get(i) < C), WD, i);
4078 }
4079
4080 vector<T,WD> ret(id());
4081 for (uint i=0; i < WD; i++) {
4082 SIMDCF_WRAPPER(ret(i) = *data[index_x.get(i)*C + index_y.get(i)], WD, i);
4083 }
4084 return ret;
4085 }
4086
4087 template <typename T, uint R, uint C>
4088 template <typename T2, uint WD>
4089 vector<T,WD> matrix_ref<T,R,C>::iselect(const vector<T2,WD>& index_x,
4090 const vector_ref<T2,WD>& index_y)
4091 {
4092 static const bool conformable1 = check_true<(WD > 0)>::value;
4093 static const bool type_conformable = is_inttype<T2>::value;
4094 assert(WD>=0 && R>=0 && C>=0);
4095
4096 for (uint i=0; i < WD; i++) {
4097 SIMDCF_WRAPPER(assert(index_x.get(i) < R), WD, i);
4098 SIMDCF_WRAPPER(assert(index_y.get(i) < C), WD, i);
4099 }
4100
4101 vector<T,WD> ret(id());
4102 for (uint i=0; i < WD; i++) {
4103 SIMDCF_WRAPPER(ret(i) = *data[index_x.get(i)*C + index_y.get(i)], WD, i);
4104 }
4105 return ret;
4106 }
4107
4108 template <typename T, uint R, uint C>
4109 template <typename T2, uint WD>
4110 vector<T,WD> matrix_ref<T,R,C>::iselect(const vector_ref<T2,WD>& index_x,
4111 const vector_ref<T2,WD>& index_y)
4112 {
4113 static const bool conformable1 = check_true<(WD > 0)>::value;
4114 static const bool type_conformable = is_inttype<T2>::value;
4115 assert(WD>=0 && R>=0 && C>=0);
4116
4117 for (uint i=0; i < WD; i++) {
4118 SIMDCF_WRAPPER(assert(index_x.get(i) < R), WD, i);
4119 SIMDCF_WRAPPER(assert(index_y.get(i) < C), WD, i);
4120 }
4121
4122 vector<T,WD> ret(id());
4123 for (uint i=0; i < WD; i++) {
4124 SIMDCF_WRAPPER(ret(i) = *data[index_x.get(i)*C + index_y.get(i)], WD, i);
4125 }
4126 return ret;
4127 }
4128 //end of 2D iselect for matrix_ref
4129
4130 /*******************************************************************
4131 /
4132 / vector
4133 /
4134 *******************************************************************/
4135 template <typename T, uint SZ>
4136 void vector<T, SZ>::assign(const stream<T, SZ> &src) {
4137 uint i;
4138 for (i = 0; i < SZ; i++) {
4139 SIMDCF_WRAPPER((*this)(i) = src.get(i), SZ, i);
4140 }
4141 }
4142
4143
4144 /*******************************************************************
4145 /
4146 / global functions/operators
4147 /
4148 *******************************************************************/
4149 template <typename T, uint SZ>
4150 CM_NOINLINE vector<typename restype<T,int>::type,SZ> operator + (const stream<T,SZ> &x) {
4151 vector<typename restype<T,int>::type, SZ> ret;
4152
4153 for (uint i=0; i<SZ; ++i) {
4154 SIMDCF_WRAPPER(ret(i) = x.get(i), SZ, i);
4155 }
4156
4157 return ret;
4158 }
4159
4160 template <typename T, uint SZ>
4161 CM_NOINLINE vector<typename restype<T,int>::type, SZ> operator - (const stream<T,SZ>& x) {
4162 vector<typename restype<T,int>::type, SZ> ret;
4163
4164 for (uint i=0; i<SZ; ++i) {
4165 SIMDCF_WRAPPER(ret(i) = - x.get(i), SZ, i);
4166 }
4167
4168 return ret;
4169 }
4170
4171 template <typename T, uint SZ>
4172 CM_NOINLINE vector<typename restype<T,int>::type, SZ> operator ~ (const stream<T,SZ>& x) {
4173 vector<typename restype<T,int>::type, SZ> ret;
4174
4175 for (uint i=0; i<SZ; ++i) {
4176 SIMDCF_WRAPPER(ret(i) = ~ x.get(i), SZ, i);
4177 }
4178
4179 return ret;
4180 }
4181
4182 template <typename T, uint SZ>
4183 CM_NOINLINE vector<ushort, SZ> operator ! (const stream<T,SZ>& x) {
4184 vector<ushort, SZ> ret;
4185
4186 for (uint i=0; i<SZ; ++i) {
4187 SIMDCF_WRAPPER(ret(i) = ! x.get(i), SZ, i);
4188 }
4189
4190 return ret;
4191 }
4192
4193 #if 0
4194
4195 #define binary_arith_op(OP) \
4196 \
4197 template<typename T1, typename T2, uint SZ>\
4198 CM_NOINLINE vector<typename restype<T1,T2>::type,SZ> operator OP (const stream<T1,SZ>& x, const stream<T2,SZ>& y)\
4199 {\
4200 typedef typename restype<T1,T2>::type RT;\
4201 vector<RT,SZ> ret;\
4202 for (uint i=0; i<SZ; ++i) {\
4203 ret(i) = RT(x.get(i) OP y.get(i));\
4204 }\
4205 return ret;\
4206 }\
4207 \
4208 template<typename T1, typename T2, uint SZ>\
4209 CM_NOINLINE vector<typename restype<T1,T2>::type,SZ> operator OP (const stream<T1,SZ>& x, const T2 y)\
4210 {\
4211 typedef typename restype<T1,T2>::type RT;\
4212 vector<RT,SZ> ret;\
4213 for (uint i=0; i<SZ; ++i) {\
4214 ret(i) = x.get(i) OP y;\
4215 }\
4216 return ret;\
4217 }\
4218 \
4219 template<typename T1, typename T2, uint SZ>\
4220 CM_NOINLINE vector<typename restype<T1,T2>::type,SZ> operator OP (const T1 x, const stream<T2,SZ>& y)\
4221 {\
4222 typedef typename restype<T1,T2>::type RT;\
4223 vector<RT,SZ> ret;\
4224 for (uint i=0; i<SZ; ++i) {\
4225 ret(i) = x OP y.get(i);\
4226 }\
4227 return ret;\
4228 }\
4229
4230 binary_arith_op(+)
4231 binary_arith_op(-)
4232 binary_arith_op(*)
4233 binary_arith_op(/)
4234 binary_arith_op(%)
4235 binary_arith_op(&)
4236 binary_arith_op(|)
4237 binary_arith_op(^)
4238 #undef binary_arith_op
4239
4240 #else
4241
4242 #define binary_arith_op(OP) \
4243 \
4244 template<typename T1, typename T2, uint SZ>\
4245 CM_NOINLINE vector<typename restype<T1,T2>::type,SZ> operator OP (const stream<T1,SZ>& x, const stream<T2,SZ>& y)\
4246 {\
4247 typedef typename restype<T1,T2>::type RT;\
4248 vector<RT,SZ> ret;\
4249 for (uint i=0; i<SZ; ++i) {\
4250 SIMDCF_WRAPPER(ret(i) = RT(x.get(i) OP y.get(i)), SZ, i);\
4251 }\
4252 return ret;\
4253 }\
4254 \
4255 template<typename T1, typename T2, uint SZ>\
4256 CM_NOINLINE vector<typename restype<T1,T2>::type,SZ> operator OP (const stream<T1,SZ>& x, const T2 y)\
4257 {\
4258 typedef typename restype<T1,T2>::type RT;\
4259 vector<RT,SZ> ret;\
4260 RT _y = y; \
4261 for (uint i=0; i<SZ; ++i) {\
4262 SIMDCF_WRAPPER(ret(i) = x.get(i) OP _y, SZ, i);\
4263 }\
4264 return ret;\
4265 }\
4266 \
4267 template<typename T1, typename T2, uint SZ>\
4268 CM_NOINLINE vector<typename restype<T1,T2>::type,SZ> operator OP (const T1 x, const stream<T2,SZ>& y)\
4269 {\
4270 typedef typename restype<T1,T2>::type RT;\
4271 vector<RT,SZ> ret;\
4272 RT _x (x); \
4273 for (uint i=0; i<SZ; ++i) {\
4274 SIMDCF_WRAPPER(ret(i) = _x OP y.get(i), SZ, i);\
4275 }\
4276 return ret;\
4277 }\
4278
4279 binary_arith_op(+)
4280 binary_arith_op(-)
4281 binary_arith_op(*)
4282 binary_arith_op(/)
4283 binary_arith_op(%)
4284 #undef binary_arith_op
4285
4286 #define binary_bitwise_op(OP) \
4287 \
4288 template<typename T1, typename T2, uint SZ>\
4289 CM_NOINLINE vector<typename bitwise_restype<T1,T2>::type,SZ> operator OP (const stream<T1,SZ>& x, const stream<T2,SZ>& y)\
4290 {\
4291 typedef typename bitwise_restype<T1,T2>::type RT;\
4292 static const bool type_conformable = \
4293 check_true<is_inttype<T1>::value && is_inttype<T2>::value>::value; \
4294 vector<RT,SZ> ret;\
4295 for (uint i=0; i<SZ; ++i) {\
4296 SIMDCF_WRAPPER(ret(i) = RT(x.get(i) OP y.get(i)), SZ, i);\
4297 }\
4298 return ret;\
4299 }\
4300 \
4301 template<typename T1, typename T2, uint SZ>\
4302 CM_NOINLINE vector<typename bitwise_restype<T1,T2>::type,SZ> operator OP (const stream<T1,SZ>& x, const T2 y)\
4303 {\
4304 typedef typename bitwise_restype<T1,T2>::type RT;\
4305 static const bool type_conformable = \
4306 check_true<is_inttype<T1>::value && is_inttype<T2>::value>::value; \
4307 vector<RT,SZ> ret;\
4308 for (uint i=0; i<SZ; ++i) {\
4309 SIMDCF_WRAPPER(ret(i) = x.get(i) OP y, SZ, i);\
4310 }\
4311 return ret;\
4312 }\
4313 \
4314 template<typename T1, typename T2, uint SZ>\
4315 CM_NOINLINE vector<typename bitwise_restype<T1,T2>::type,SZ> operator OP (const T1 x, const stream<T2,SZ>& y)\
4316 {\
4317 typedef typename bitwise_restype<T1,T2>::type RT;\
4318 static const bool type_conformable = \
4319 check_true<is_inttype<T1>::value && is_inttype<T2>::value>::value; \
4320 vector<RT,SZ> ret;\
4321 for (uint i=0; i<SZ; ++i) {\
4322 SIMDCF_WRAPPER(ret(i) = x OP y.get(i), SZ, i); \
4323 }\
4324 return ret;\
4325 }\
4326
4327 binary_bitwise_op(&)
4328 binary_bitwise_op(|)
4329 binary_bitwise_op(^)
4330 #undef binary_bitwise_op
4331
4332 #endif
4333
4334 template <bool, class T = void> struct cm_enable_if {};
4335 template <class T> struct cm_enable_if<true, T> {
4336 typedef T type;
4337 };
4338
4339 template <typename T, T v>
4340 struct cm_integral_constant {
4341 typedef T value_type;
4342 static const value_type value = v;
4343 typedef cm_integral_constant<T, v> type;
4344 operator value_type() { return value; }
4345 };
4346
4347 typedef cm_integral_constant<bool, true> cm_true_type;
4348 typedef cm_integral_constant<bool, false> cm_false_type;
4349
4350 template<typename T, typename U> struct cm_is_same : public cm_false_type {};
4351 template<typename T> struct cm_is_same<T, T> : public cm_true_type{};
4352
4353 template <typename T> struct cm_remove_const { typedef T type; };
4354 template <typename T> struct cm_remove_const<const T> { typedef T type; };
4355
4356 template <typename T>
4357 struct is_cm_scalar : cm_integral_constant <
4358 bool,
4359 cm_is_same< float, typename cm_remove_const<T>::type>::value ||
4360 cm_is_same< double, typename cm_remove_const<T>::type>::value ||
4361 cm_is_same< char, typename cm_remove_const<T>::type>::value ||
4362 cm_is_same< signed char, typename cm_remove_const<T>::type>::value ||
4363 cm_is_same<unsigned char, typename cm_remove_const<T>::type>::value ||
4364 cm_is_same< short, typename cm_remove_const<T>::type>::value ||
4365 cm_is_same<unsigned short, typename cm_remove_const<T>::type>::value ||
4366 cm_is_same< int, typename cm_remove_const<T>::type>::value ||
4367 cm_is_same<unsigned int, typename cm_remove_const<T>::type>::value ||
4368 cm_is_same< long, typename cm_remove_const<T>::type>::value ||
4369 cm_is_same<unsigned long, typename cm_remove_const<T>::type>::value ||
4370 cm_is_same< long long, typename cm_remove_const<T>::type>::value ||
4371 cm_is_same<unsigned long long, typename cm_remove_const<T>::type>::value >
4372 {};
4373
4374
4375 #define binary_shift_op(OP) \
4376 \
4377 template<typename T1, typename T2, uint SZ>\
4378 CM_NOINLINE vector<typename int_uint_type<T1>::type,SZ> operator OP (const stream<T1,SZ>& x, const stream<T2,SZ>& y)\
4379 {\
4380 typedef typename int_uint_type<T1>::type RT;\
4381 vector<RT,SZ> ret;\
4382 for (uint i=0; i<SZ; ++i) {\
4383 SIMDCF_WRAPPER(ret(i) = RT(x.get(i) OP y.get(i)), SZ, i);\
4384 }\
4385 return ret;\
4386 }\
4387 \
4388 template<typename T1, typename T2, uint SZ>\
4389 CM_NOINLINE typename cm_enable_if<is_cm_scalar<T2>::value, vector<typename int_uint_type<T1>::type,SZ> >::type operator OP (const stream<T1,SZ>& x, const T2 y)\
4390 {\
4391 typedef typename int_uint_type<T1>::type RT;\
4392 vector<RT,SZ> ret;\
4393 for (uint i=0; i<SZ; ++i) {\
4394 SIMDCF_WRAPPER(ret(i) = x.get(i) OP y, SZ, i);\
4395 }\
4396 return ret;\
4397 }\
4398 \
4399 template<typename T1, typename T2, uint SZ>\
4400 CM_NOINLINE vector<typename int_uint_type<T1>::type,SZ> operator OP (const T1 x, const stream<T2,SZ>& y)\
4401 {\
4402 typedef typename int_uint_type<T1>::type RT;\
4403 vector<RT,SZ> ret;\
4404 for (uint i=0; i<SZ; ++i) {\
4405 SIMDCF_WRAPPER(ret(i) = x OP y.get(i), SZ, i);\
4406 }\
4407 return ret;\
4408 }\
4409
4410 binary_shift_op(>>)
4411 binary_shift_op(<<)
4412 #undef binary_shift_op
4413
4414
4415 #define binary_compare_op(OP) \
4416 \
4417 template<typename T1, uint SZ, typename T2>\
4418 CM_NOINLINE vector<typename ushort_type<T1,T2>::type, SZ> operator OP (const stream<T1, SZ>& x, const T2 y)\
4419 {\
4420 static const bool type_conformable = cmtype<T2>::value; \
4421 vector<ushort, SZ> ret((ushort)0);\
4422 for (int i=0; i<SZ; i++) {\
4423 ret(i) = 0; \
4424 SIMDCF_ELEMENT_SKIP(i);\
4425 if (x.get(i) OP y) {\
4426 ret(i) = 1;\
4427 }\
4428 }\
4429 return ret;\
4430 }\
4431 \
4432 template<typename T1, uint SZ, typename T2>\
4433 CM_NOINLINE vector<typename ushort_type<T1,T2>::type, SZ> operator OP (const T1 x, const stream<T2, SZ>& y)\
4434 {\
4435 static const bool type_conformable = cmtype<T1>::value; \
4436 vector<ushort, SZ> ret((ushort)0);\
4437 for (int i=0; i<SZ; i++) {\
4438 SIMDCF_ELEMENT_SKIP(i);\
4439 if (x OP y.get(i)) {\
4440 ret(i) = 1;\
4441 }\
4442 }\
4443 return ret;\
4444 }\
4445 \
4446 template<typename T1, uint SZ, typename T2>\
4447 CM_NOINLINE vector<ushort, SZ> operator OP (const stream<T1, SZ>& x, const stream<T2, SZ>& y)\
4448 {\
4449 vector<ushort, SZ> ret((ushort)0);\
4450 for (int i=0; i<SZ; i++) {\
4451 SIMDCF_ELEMENT_SKIP(i);\
4452 if (x.get(i) OP y.get(i)) {\
4453 ret(i) = 1;\
4454 }\
4455 }\
4456 return ret;\
4457 }\
4458 \
4459
4460 binary_compare_op(<)
4461 binary_compare_op(<=)
4462 binary_compare_op(>)
4463 binary_compare_op(>=)
4464 binary_compare_op(==)
4465 binary_compare_op(!=)
4466
4467 #define reduce_boolean_op(OP,ReduceOP,initValue) \
4468 \
4469 template<typename T, uint SZ>\
4470 CM_NOINLINE ushort stream<T, SZ>::OP ( void ) const \
4471 {\
4472 static const bool type_conformable = cmtype<T>::value; \
4473 ushort ret((ushort)initValue);\
4474 for (int i=0; i<SZ; i++) {\
4475 SIMDCF_WRAPPER(ret = (get(i) ReduceOP ret), SZ, i); \
4476 if ( ret!=initValue ) { return ret; } \
4477 }\
4478 return ret;\
4479 }\
4480 \
4481
4482 //SIMDCF_WRAPPER(ret = (get(i) ReduceOP ret), i);
4483
4484
4485 reduce_boolean_op(any,||,0)
4486 reduce_boolean_op(all,&&,1)
4487
4488 #endif /* CM_TYPES_H */
4489
4490 };