xref: /aosp_15_r20/external/intel-media-driver/media_driver/linux/common/cm/hal/cm_type.h (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
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 };