Line data Source code
1 : ///////////////////////////////////////////////////////////////////////////
2 : // Inastemp - Berenger Bramas MPCDF - 2016
3 : // Under MIT Licence, please you must read the LICENCE file.
4 : ///////////////////////////////////////////////////////////////////////////
5 : #ifndef INAVECINTERFACE_HPP
6 : #define INAVECINTERFACE_HPP
7 :
8 : #include <type_traits>
9 :
10 : template <class MaskType>
11 : class InaVecMaskInterface : public MaskType{
12 : public:
13 : using Parent = MaskType;
14 :
15 : // Classic constructors
16 14 : inline InaVecMaskInterface(){}
17 :
18 : inline InaVecMaskInterface(const MaskType& other)
19 : : Parent(other){
20 : }
21 :
22 : inline InaVecMaskInterface& operator=(const MaskType& other){
23 : this->Parent::operator=(other);
24 : return *this;
25 : }
26 :
27 : // Native data type compatibility
28 : inline /*not explicit*/ InaVecMaskInterface(const bool inMask)
29 : : Parent(inMask){}
30 :
31 : inline InaVecMaskInterface& operator=(const bool inMask){
32 : this->Parent::operator=(inMask);
33 : return (*this);
34 : }
35 :
36 : inline explicit operator bool() const{
37 : return this->Parent::operator bool();
38 : }
39 :
40 : inline bool getMask() const{
41 : return Parent::getMask();
42 : }
43 :
44 : // Binary methods
45 : inline InaVecMaskInterface Not() const{
46 : return Parent::Not();
47 : }
48 :
49 : // Double args methods
50 : inline static InaVecMaskInterface And(const InaVecMaskInterface& inMask1, const InaVecMaskInterface& inMask2){
51 : return Parent::And(inMask1, inMask2);
52 : }
53 :
54 : inline static InaVecMaskInterface NotAnd(const InaVecMaskInterface& inMask1, const InaVecMaskInterface& inMask2){
55 : return Parent::NotAnd(inMask1, inMask2);
56 : }
57 :
58 : inline static InaVecMaskInterface Or(const InaVecMaskInterface& inMask1, const InaVecMaskInterface& inMask2){
59 : return Parent::Or(inMask1, inMask2);
60 : }
61 :
62 : inline static InaVecMaskInterface Xor(const InaVecMaskInterface& inMask1, const InaVecMaskInterface& inMask2){
63 : return Parent::Xor(inMask1, inMask2);
64 : }
65 : };
66 :
67 : // Mask must have operators
68 : template <class MaskType>
69 : inline InaVecMaskInterface<MaskType> operator&(const InaVecMaskInterface<MaskType>& inMask1, const InaVecMaskInterface<MaskType>& inMask2){
70 : return InaVecMaskInterface<MaskType>::And(inMask1, inMask2);
71 : }
72 :
73 : template <class MaskType>
74 : inline InaVecMaskInterface<MaskType> operator|(const InaVecMaskInterface<MaskType>& inMask1, const InaVecMaskInterface<MaskType>& inMask2){
75 : return InaVecMaskInterface<MaskType>::Or(inMask1, inMask2);
76 : }
77 :
78 : template <class MaskType>
79 : inline InaVecMaskInterface<MaskType> operator^(const InaVecMaskInterface<MaskType>& inMask1, const InaVecMaskInterface<MaskType>& inMask2){
80 : return InaVecMaskInterface<MaskType>::Xor(inMask1, inMask2);
81 : }
82 :
83 :
84 : /**
85 : * This class defines the interface that each vector
86 : * type must provide.
87 : * It is not made to be use as an abstract data type
88 : * by having for example a pointer on InaVecInterface.
89 : * It simply help to implement each type.
90 : */
91 : template < class VecType >
92 : class InaVecInterface : public VecType {
93 : public:
94 : using Parent = VecType;
95 : using VecRawType = typename VecType::VecRawType;
96 : using MaskType = typename VecType::MaskType;
97 : using RealType = typename VecType::RealType;
98 : static const int Alignement= VecType::Alignement;
99 : static const bool IsOfFixedSize = VecType::IsOfFixedSize;
100 :
101 : using VecType::GetVecLength;
102 :
103 9726 : using VecType::VecType;
104 :
105 373 : inline InaVecInterface(){}
106 : inline InaVecInterface(const InaVecInterface&) = default;
107 : inline InaVecInterface& operator = (const InaVecInterface&) = default;
108 :
109 2403 : inline InaVecInterface(const VecType& inVec) : Parent(inVec){};
110 : inline InaVecInterface& operator = (const VecType& inVec){
111 : this->Parent::operator=(inVec);
112 : return *this;
113 : }
114 :
115 : inline InaVecInterface(const std::initializer_list<RealType> lst)
116 82 : : Parent(lst.begin()){
117 : }
118 :
119 : /** Load and store */
120 :
121 : inline /*not explicit*/ InaVecInterface(const VecRawType inVec)
122 822 : : Parent(inVec){
123 : }
124 :
125 : inline VecType& operator=(const VecRawType inVec){
126 : this->Parent::operator =(inVec);
127 : return *this;
128 : }
129 :
130 : //! Convert inValue into a VecType by duplicating it and
131 : //! setting all the values of the array equal to inValue
132 : //! @code VecType[0:last-val-idx] = inValue
133 : inline VecType setFromRawType(const VecRawType inValue) const {
134 : return Parent::setFromRawType(inValue);
135 : }
136 :
137 : inline explicit operator VecRawType() const{
138 : return this->Parent::operator VecRawType();
139 : }
140 :
141 : inline VecRawType getVec() const{
142 : return Parent::getVec();
143 : }
144 :
145 : // inline /*not explicit*/ InaVecInterface(const RealType inVal)
146 : // : Parent(inVal){
147 : // }
148 :
149 : // inline VecType& operator=(const RealType inVal){
150 : // this->Parent::operator =(inVal);
151 : // return *this;
152 : // }
153 :
154 : inline void setFromScalar(const RealType inVal){
155 : this->Parent::setFromScalar(inVal);
156 : }
157 :
158 : // Constructor from vec
159 : inline explicit InaVecInterface(const RealType ptr[])
160 5758 : : Parent(ptr){
161 : }
162 :
163 : //! Convert values from inArray into a VecType
164 : //! inArray might not be aligned
165 : //! @code idx in [0:last-val-idx] => VecType[idx] = inArray[idx]
166 : inline VecType& setFromArray(const RealType ptr[]){
167 592 : Parent::setFromArray(ptr);
168 : return *this;
169 : }
170 :
171 : //! Convert values from inArray into a VecType
172 : //! inArray must be aligned
173 : //! @code idx in [0:last-val-idx] => VecType[idx] = inArray[idx]
174 : inline VecType& setFromAlignedArray(const RealType ptr[]){
175 132 : Parent::setFromAlignedArray(ptr);
176 : return *this;
177 : }
178 :
179 : //! Convert values at position inIndirection from inArray into a VecType
180 : //! inArray might not be aligned
181 : //! @code idx in [0:last-val-idx] => VecType[idx] = inArray[inIndirection[idx]]
182 : inline VecType& setFromIndirectArray(const RealType values[], const int inIndirection[]) {
183 72 : Parent::setFromIndirectArray(values, inIndirection);
184 : return *this;
185 : }
186 :
187 : //! Convert values at position inIndirection from inArray into a VecType
188 : //! inArray might not be aligned
189 : //! @code idx in [0:last-val-idx] => VecType[idx] = inArray[inIndirection1[idx]*inLeadingDimension
190 : //! @code + inIndirection2[idx]]
191 : inline VecType& setFromIndirect2DArray(const RealType inArray[], const int inIndirection1[],
192 : const int inLeadingDimension, const int inIndirection2[]){
193 60 : Parent::setFromIndirect2DArray(inArray, inIndirection1, inLeadingDimension, inIndirection2);
194 : return *this;
195 : }
196 :
197 : //! inArray
198 : //! @code idx in [0:last-val-idx] => outArray[idx] = inVec[idx]
199 : inline void storeInArray(RealType ptr[]) const {
200 23436 : Parent::storeInArray(ptr);
201 : }
202 :
203 : //! inArray might must be aligned
204 : //! @code idx in [0:last-val-idx] => outArray[idx] = inVec[idx]
205 : inline void storeInAlignedArray(RealType ptr[]) const {
206 6472 : Parent::storeInAlignedArray(ptr);
207 : }
208 :
209 : // Acce to individual values
210 : //! Return the value at position inIdx in inVec
211 : //! @code return inVec[inIdx]
212 : inline RealType at(const int index) const {
213 33992 : return Parent::at(index);
214 : }
215 :
216 : // Horizontal operation
217 : //! Sum all the values from inVec
218 : //! @code return inVec[0] + ... + inVec[last-val-idx]
219 : inline RealType horizontalSum() const {
220 4862 : return Parent::horizontalSum();
221 : }
222 :
223 : //! Multiply all the values from inVec
224 : //! @code return inVec[0] * ... * inVec[last-val-idx]
225 : inline RealType horizontalMul() const {
226 78 : return Parent::horizontalMul();
227 : }
228 :
229 : //! Return the smallest value in the vector
230 : inline RealType minInVec() const {
231 196 : return Parent::minInVec();
232 : }
233 :
234 : //! Return the greatest value in the vector
235 : inline RealType maxInVec() const {
236 196 : return Parent::maxInVec();
237 : }
238 :
239 : //! Apply Sqrt to all values from inVec
240 : //! @code idx in [0:last-val-idx] => resVec[idx] = Sqrt(inVec[idx])
241 : inline VecType sqrt() const {
242 32 : return Parent::sqrt();
243 : }
244 :
245 : //! Apply exponential to all values from inVec
246 : //! @code idx in [0:last-val-idx] => resVec[idx] = Exp(inVec[idx])
247 : inline VecType exp() const {
248 44 : return Parent::exp();
249 : }
250 :
251 : //! Apply exponential to all values from inVec with low accuracy
252 : //! @code idx in [0:last-val-idx] => resVec[idx] = ExpLowExp(inVec[idx])
253 : inline VecType expLowAcc() const {
254 25 : return Parent::expLowAcc();
255 : }
256 :
257 : //! Apply 1/Sqrt to all values from inVec
258 : //! @code idx in [0:last-val-idx] => resVec[idx] = 1/Sqrt(inVec[idx])
259 : inline VecType rsqrt() const {
260 32 : return Parent::rsqrt();
261 : }
262 :
263 : //! Return the abs value of inVec
264 : //! @code idx in [0:last-val-idx] => resVec[idx] = abs(inVec[idx])
265 : inline VecType abs() const {
266 96 : return Parent::abs();
267 : }
268 :
269 : //! Convert inVal in integer and then to real
270 : //! @code idx in [0:last-val-idx] => floor(inVal[idx])
271 : inline VecType floor() const {
272 130 : return Parent::floor();
273 : }
274 :
275 : //! Return 1 or -1 for each value in inVec
276 : //! @code idx in [0:last-val-idx] => resVec[idx] = (inVec[idx]<0?-1:1)
277 : inline VecType signOf() const {
278 160 : return Parent::signOf();
279 : }
280 :
281 : //! Return 1 if positive or zero, else 0 for each value
282 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec[idx]>=0?1:0
283 : inline VecType isPositive() const {
284 160 : return Parent::isPositive();
285 : }
286 :
287 : //! Return 1 if negative or zero, else 0 for each value
288 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec[idx]<=0?1:0
289 : inline VecType isNegative() const {
290 160 : return Parent::isNegative();
291 : }
292 :
293 : //! Return 1 if positive, else 0 for each value
294 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec[idx]>0?1:0
295 : inline VecType isPositiveStrict() const {
296 160 : return Parent::isPositiveStrict();
297 : }
298 :
299 : //! Return 1 if negative, else 0 for each value
300 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec[idx]<0?1:0
301 : inline VecType isNegativeStrict() const {
302 160 : return Parent::isNegativeStrict();
303 : }
304 :
305 : //! Return 1 if equal to, else 0 for each value
306 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec[idx]==0?1:0
307 : inline VecType isZero() const {
308 96 : return Parent::isZero();
309 : }
310 :
311 : //! Return 1 if not equal to, else 0 for each value
312 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec[idx]!=0?1:0
313 : inline VecType isNotZero() const {
314 96 : return Parent::isNotZero();
315 : }
316 :
317 : //! Return ~0 if positive or zero, else 0 for each value
318 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec[idx]>=0?~0:0
319 : inline MaskType isPositiveMask() const {
320 140 : return Parent::isPositiveMask();
321 : }
322 :
323 : //! Return ~0 if negative or zero, else 0 for each value
324 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec[idx]<=0?~0:0
325 : inline MaskType isNegativeMask() const {
326 140 : return Parent::isNegativeMask();
327 : }
328 :
329 : //! Return ~0 if positive, else 0 for each value
330 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec[idx]>0?~0:0
331 : inline MaskType isPositiveStrictMask() const {
332 140 : return Parent::isPositiveStrictMask();
333 : }
334 :
335 : //! Return ~0 if negative, else 0 for each value
336 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec[idx]<0?~0:0
337 : inline MaskType isNegativeStrictMask() const {
338 140 : return Parent::isNegativeStrictMask();
339 : }
340 :
341 : //! Return ~0 if equal to, else 0 for each value
342 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec[idx]==0?~0:0
343 : inline MaskType isZeroMask() const {
344 84 : return Parent::isZeroMask();
345 : }
346 :
347 : //! Return ~0 if not equal to, else 0 for each value
348 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec[idx]!=0?~0:0
349 : inline MaskType isNotZeroMask() const {
350 84 : return Parent::isNotZeroMask();
351 : }
352 :
353 : // Static basic methods
354 : //! Return a vector where all values are 1
355 : //! @code VecType[0:last-val-idx] = 1
356 : //! Might be implemtented as ScalarToSimd(1)
357 : inline static VecType GetZero() {
358 12 : return Parent::GetZero();
359 : }
360 :
361 : //! Return a vector where all values are 0
362 : //! @code VecType[0:last-val-idx] = 0
363 : //! Might be implemtented as ScalarToSimd(0)
364 : inline static VecType GetOne() {
365 12 : return Parent::GetOne();
366 : }
367 :
368 : //! Return the minimum value between inVec1 and inVec2
369 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]<=inVec2[idx]?inVec1[idx]:inVec2[idx]
370 : inline static VecType Min(const VecType& inVec1, const VecType& inVec2) {
371 78 : return Parent::Min(inVec1, inVec2);
372 : }
373 :
374 : //! Return the maximum value between inVec1 and inVec2
375 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]>=inVec2[idx]?inVec1[idx]:inVec2[idx]
376 : inline static VecType Max(const VecType& inVec1, const VecType& inVec2) {
377 78 : return Parent::Max(inVec1, inVec2);
378 : }
379 :
380 : //! Return 1 if inVec1 <= inVec2, else 0 for each value
381 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]<=inVec2[idx]?1:0
382 : inline static VecType IsLowerOrEqual(const VecType& inVec1, const VecType& inVec2) {
383 104 : return Parent::IsLowerOrEqual(inVec1, inVec2);
384 : }
385 :
386 : //! Return 1 if inVec1 < inVec2, else 0 for each value
387 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]<inVec2[idx]?1:0
388 : inline static VecType IsLower(const VecType& inVec1, const VecType& inVec2) {
389 104 : return Parent::IsLower(inVec1, inVec2);
390 : }
391 :
392 : //! Return 1 if inVec1 >= inVec2, else 0 for each value
393 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]>=inVec2[idx]?1:0
394 : inline static VecType IsGreaterOrEqual(const VecType& inVec1, const VecType& inVec2) {
395 104 : return Parent::IsGreaterOrEqual(inVec1, inVec2);
396 : }
397 :
398 : //! Return 1 if inVec1 > inVec2, else 0 for each value
399 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]>inVec2[idx]?1:0
400 : inline static VecType IsGreater(const VecType& inVec1, const VecType& inVec2) {
401 104 : return Parent::IsGreater(inVec1, inVec2);
402 : }
403 :
404 : //! Return 1 if inVec1 == inVec2, else 0 for each value
405 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]==inVec2[idx]?1:0
406 : inline static VecType IsEqual(const VecType& inVec1, const VecType& inVec2) {
407 104 : return Parent::IsEqual(inVec1, inVec2);
408 : }
409 :
410 : //! Return 1 if inVec1 == inVec2, else 0 for each value
411 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]!=inVec2[idx]?1:0
412 : inline static VecType IsNotEqual(const VecType& inVec1, const VecType& inVec2) {
413 104 : return Parent::IsNotEqual(inVec1, inVec2);
414 : }
415 :
416 : //! Return ~0 if inVec1 <= inVec2, else 0 for each value
417 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]<=inVec2[idx]?~0:0
418 : inline static MaskType IsLowerOrEqualMask(const VecType& inVec1, const VecType& inVec2) {
419 88 : return Parent::IsLowerOrEqualMask(inVec1, inVec2);
420 : }
421 :
422 : //! Return ~0 if inVec1 < inVec2, else 0 for each value
423 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]<inVec2[idx]?~0:0
424 : inline static MaskType IsLowerMask(const VecType& inVec1, const VecType& inVec2) {
425 88 : return Parent::IsLowerMask(inVec1, inVec2);
426 : }
427 :
428 : //! Return ~0 if inVec1 >= inVec2, else 0 for each value
429 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]>=inVec2[idx]?~0:0
430 : inline static MaskType IsGreaterOrEqualMask(const VecType& inVec1, const VecType& inVec2) {
431 88 : return Parent::IsGreaterOrEqualMask(inVec1, inVec2);
432 : }
433 :
434 : //! Return ~0 if inVec1 > inVec2, else 0 for each value
435 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]>inVec2[idx]?~0:0
436 : inline static MaskType IsGreaterMask(const VecType& inVec1, const VecType& inVec2) {
437 88 : return Parent::IsGreaterMask(inVec1, inVec2);
438 : }
439 :
440 : //! Return ~0 if inVec1 == inVec2, else 0 for each value
441 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]==inVec2[idx]?~0:0
442 : inline static MaskType IsEqualMask(const VecType& inVec1, const VecType& inVec2) {
443 88 : return Parent::IsEqualMask(inVec1, inVec2);
444 : }
445 :
446 : //! Return ~0 if inVec1 == inVec2, else 0 for each value
447 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]!=inVec2[idx]?~0:0
448 : inline static MaskType IsNotEqualMask(const VecType& inVec1, const VecType& inVec2) {
449 88 : return Parent::IsNotEqualMask(inVec1, inVec2);
450 : }
451 :
452 : /** Bits operations */
453 : //! Return inVec1 AND inVec2, for each value
454 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]&inVec2[idx]
455 : inline static VecType BitsAnd(const VecType& inVec1, const VecType& inVec2) {
456 78 : return Parent::BitsAnd(inVec1, inVec2);
457 : }
458 :
459 : //! Return NOT inVec1 AND inVec2, for each value
460 : //! @code idx in [0:last-val-idx] => resVec[idx] = (~inVec1[idx])&inVec2[idx]
461 : inline static VecType BitsNotAnd(const VecType& inVec1, const VecType& inVec2) {
462 104 : return Parent::BitsNotAnd(inVec1, inVec2);
463 : }
464 :
465 : //! Return inVec1 OR inVec2, for each value
466 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]|inVec2[idx]
467 : inline static VecType BitsOr(const VecType& inVec1, const VecType& inVec2) {
468 78 : return Parent::BitsOr(inVec1, inVec2);
469 : }
470 :
471 : //! Return inVec1 XOR inVec2, for each value
472 : //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx] ^ inVec2[idx]
473 : inline static VecType BitsXor(const VecType& inVec1, const VecType& inVec2) {
474 78 : return Parent::BitsXor(inVec1, inVec2);
475 : }
476 :
477 : //! Return the name identifier of the vectorizer
478 : inline static const char* GetName() {
479 : return Parent::GetName();
480 : }
481 :
482 : //! The method cannot be because the return type is unknown
483 : inline static typename InaIfElse< VecType >::ThenClass If(const MaskType& inTest) {
484 : return Parent::If(inTest);
485 : }
486 :
487 : //! This is a ternary if/else test
488 : //! It can be implemented as : return (inMask & inIfTrue) | (~inMask & inIfFalse)
489 : //! @code idx in [0:last-val-idx] => resVec[idx] = inMask ? inIfTrue[idx] : inIfFalse[idx]
490 : inline static VecType IfElse(const MaskType& inMask, const VecType& inIfTrue, const VecType& inIfFalse) {
491 : return Parent::IfElse(inMask, inIfTrue, inIfFalse);
492 : }
493 :
494 : //! This is a ternary if/else test with 0 as else case
495 : //! It can be implemented as : return (inMask & inIfTrue)
496 : //! @code idx in [0:last-val-idx] => resVec[idx] = inMask ? inIfTrue[idx] : 0
497 : inline static VecType IfTrue(const MaskType& inMask, const VecType& inIfTrue) {
498 2600 : return Parent::IfTrue(inMask, inIfTrue);
499 : }
500 :
501 : //! This is a ternary if/else test with 0 as if case
502 : //! It can be implemented as : return (!inMask & inIfFalse)
503 : //! @code idx in [0:last-val-idx] => resVec[idx] = inMask ? 0 : inIfFalse[idx]
504 : inline static VecType IfFalse(const MaskType& inMask, const VecType& inIfFalse) {
505 : return Parent::IfFalse(inMask, inIfFalse);
506 : }
507 :
508 : // Inner operators
509 : inline VecType& operator+=(const VecType& inVec){
510 132 : this->Parent::operator +=(inVec);
511 : return *this;
512 : }
513 :
514 : inline VecType& operator-=(const VecType& inVec){
515 104 : this->Parent::operator -=(inVec);
516 : return *this;
517 : }
518 :
519 : inline VecType& operator/=(const VecType& inVec){
520 52 : this->Parent::operator /=(inVec);
521 : return *this;
522 : }
523 :
524 : inline VecType& operator*=(const VecType& inVec){
525 104 : this->Parent::operator *=(inVec);
526 : return *this;
527 : }
528 :
529 :
530 : inline VecType pow(size_t power) const{
531 192 : return this->Parent::pow(power);
532 : }
533 :
534 : };
535 :
536 : // Bits operators
537 : template <class VecType>
538 : inline InaVecInterface<VecType> operator&(const InaVecInterface<VecType>& inVec1, const InaVecInterface<VecType>& inVec2){
539 : return InaVecInterface<VecType>::BitsAnd(inVec1, inVec2);
540 : }
541 :
542 : template <class VecType>
543 : inline InaVecInterface<VecType> operator|(const InaVecInterface<VecType>& inVec1, const InaVecInterface<VecType>& inVec2){
544 : return InaVecInterface<VecType>::BitsOr(inVec1, inVec2);
545 : }
546 :
547 : template <class VecType>
548 : inline InaVecInterface<VecType> operator^(const InaVecInterface<VecType>& inVec1, const InaVecInterface<VecType>& inVec2){
549 : return InaVecInterface<VecType>::BitsXor(inVec1, inVec2);
550 : }
551 :
552 : // Dual operators
553 : template <class VecType>
554 : inline InaVecInterface<VecType> operator+(const InaVecInterface<VecType>& inVec1, const InaVecInterface<VecType>& inVec2){
555 144 : return static_cast<const VecType&>(inVec1) + static_cast<const VecType&>(inVec2);
556 : }
557 :
558 : template <class VecType>
559 : inline InaVecInterface<VecType> operator-(const InaVecInterface<VecType>& inVec1, const InaVecInterface<VecType>& inVec2){
560 144 : return static_cast<const VecType&>(inVec1) - static_cast<const VecType&>(inVec2);
561 : }
562 :
563 : template <class VecType>
564 : inline InaVecInterface<VecType> operator/(const InaVecInterface<VecType>& inVec1, const InaVecInterface<VecType>& inVec2){
565 72 : return static_cast<const VecType&>(inVec1) / static_cast<const VecType&>(inVec2);
566 : }
567 :
568 : template <class VecType>
569 : inline InaVecInterface<VecType> operator*(const InaVecInterface<VecType>& inVec1, const InaVecInterface<VecType>& inVec2){
570 180 : return static_cast<const VecType&>(inVec1) * static_cast<const VecType&>(inVec2);
571 : }
572 :
573 : // Tests and comparions
574 : template <class VecType>
575 : inline typename InaVecInterface<VecType>::MaskType operator<(const InaVecInterface<VecType>& inVec1, const InaVecInterface<VecType>& inVec2){
576 : return InaVecInterface<VecType>::IsLowerMask(inVec1,inVec2);
577 : }
578 :
579 : template <class VecType>
580 : inline typename InaVecInterface<VecType>::MaskType operator<=(const InaVecInterface<VecType>& inVec1, const InaVecInterface<VecType>& inVec2){
581 : return InaVecInterface<VecType>::IsLowerOrEqualMask(inVec1,inVec2);
582 : }
583 :
584 : template <class VecType>
585 : inline typename InaVecInterface<VecType>::MaskType operator>(const InaVecInterface<VecType>& inVec1, const InaVecInterface<VecType>& inVec2){
586 : return InaVecInterface<VecType>::IsGreaterMask(inVec1,inVec2);
587 : }
588 :
589 : template <class VecType>
590 : inline typename InaVecInterface<VecType>::MaskType operator>=(const InaVecInterface<VecType>& inVec1, const InaVecInterface<VecType>& inVec2){
591 : return InaVecInterface<VecType>::IsGreaterOrEqualMask(inVec1,inVec2);
592 : }
593 :
594 : template <class VecType>
595 : inline typename InaVecInterface<VecType>::MaskType operator==(const InaVecInterface<VecType>& inVec1, const InaVecInterface<VecType>& inVec2){
596 : return InaVecInterface<VecType>::IsEqualMask(inVec1,inVec2);
597 : }
598 :
599 : template <class VecType>
600 : inline typename InaVecInterface<VecType>::MaskType operator!=(const InaVecInterface<VecType>& inVec1, const InaVecInterface<VecType>& inVec2){
601 : return InaVecInterface<VecType>::IsNotEqualMask(inVec1,inVec2);
602 : }
603 :
604 :
605 : #endif // INAVECINTERFACE_HPP
|