6 template<
typename Cond,
typename T>
struct EnableIfNeitherIntegerNorVector :
public EnableIf<!CanConvertToInt<Cond>::Value, T> {};
7 template<
typename Cond,
typename T>
struct EnableIfNeitherIntegerNorVector<Vector<Cond>,
T>;
9 template<
typename T>
struct IsVector {
enum {
Value =
false }; };
10 template<
typename T>
struct IsVector<Vector<
T> > {
enum {
Value =
true }; };
12 template<
typename T0,
typename T1,
typename V0,
typename V1>
struct IsTypeCombinationOf
27 ( IsEqualType<T0, V0>::
Value && IsEqualType<
T1, V1>::
Value) ||
28 ( IsEqualType<T0, V1>::
Value && IsEqualType<
T1, V0>::
Value)
33 template<
typename T0,
typename T1,
typename V>
struct IsVectorOperands
72 #define VC_OPERATOR_FORWARD_(ret, op) \
73 template<typename T0, typename T1> static Vc_ALWAYS_INLINE typename EnableIf< \
74 IsVectorOperands<T0, T1, double_v>::Value || \
75 ((IsEqualType<T0, float>::Value || IsLikeInteger<T0>::Value) && HasImplicitCast<T1, double_v>::Value && !HasImplicitCast<T1, int>::Value) || \
76 ((IsEqualType<T1, float>::Value || IsLikeInteger<T1>::Value) && HasImplicitCast<T0, double_v>::Value && !HasImplicitCast<T0, int>::Value) || \
77 false, double_##ret>::Value operator op(const T0 &x, const T1 &y) { return double_v(x) op double_v(y); } \
79 template<typename T0, typename T1> static Vc_ALWAYS_INLINE typename EnableIf< \
80 IsVectorOperands<T0, T1, float_v>::Value || \
81 IsTypeCombinationOf<T0, T1, int_v, float_v>::Value || \
82 IsTypeCombinationOf<T0, T1, uint_v, float_v>::Value || \
83 IsTypeCombinationOf<T0, T1, int_v, float>::Value || \
84 IsTypeCombinationOf<T0, T1, uint_v, float>::Value || \
85 (IsLikeInteger<T0>::Value && HasImplicitCast<T1, float_v>::Value && !HasImplicitCast<T1, int>::Value) || \
86 (IsLikeInteger<T1>::Value && HasImplicitCast<T0, float_v>::Value && !HasImplicitCast<T0, int>::Value) || \
87 false, float_##ret>::Value operator op(const T0 &x, const T1 &y) { return float_v(x) op float_v(y); } \
89 template<typename T0, typename T1> static Vc_ALWAYS_INLINE typename EnableIf< \
90 IsVectorOperands<T0, T1, sfloat_v>::Value || \
91 IsTypeCombinationOf<T0, T1, short_v, sfloat_v>::Value || \
92 IsTypeCombinationOf<T0, T1, ushort_v, sfloat_v>::Value || \
93 IsTypeCombinationOf<T0, T1, short_v, float>::Value || \
94 IsTypeCombinationOf<T0, T1, ushort_v, float>::Value || \
95 (IsLikeInteger<T0>::Value && HasImplicitCast<T1, sfloat_v>::Value && !HasImplicitCast<T1, int>::Value) || \
96 (IsLikeInteger<T1>::Value && HasImplicitCast<T0, sfloat_v>::Value && !HasImplicitCast<T0, int>::Value) || \
97 false, sfloat_##ret>::Value operator op(const T0 &x, const T1 &y) { return sfloat_v(x) op sfloat_v(y); } \
99 template<typename T0, typename T1> static Vc_ALWAYS_INLINE typename EnableIf< \
100 IsVectorOperands<T0, T1, uint_v>::Value || \
101 IsTypeCombinationOf<T0, T1, int_v, uint_v>::Value || \
102 (IsUnsignedInteger<T0>::Value && HasImplicitCast<T1, int_v>::Value && !HasImplicitCast<T1, int>::Value) || \
103 (IsUnsignedInteger<T1>::Value && HasImplicitCast<T0, int_v>::Value && !HasImplicitCast<T0, int>::Value) || \
104 (IsLikeInteger<T0>::Value && !IsEqualType<T0, unsigned int>::Value && HasImplicitCast<T1, uint_v>::Value && !HasImplicitCast<T1, int>::Value) || \
105 (IsLikeInteger<T1>::Value && !IsEqualType<T1, unsigned int>::Value && HasImplicitCast<T0, uint_v>::Value && !HasImplicitCast<T0, int>::Value) || \
106 false, uint_##ret>::Value operator op(const T0 &x, const T1 &y) { return uint_v(x) op uint_v(y); } \
107 template<typename T0, typename T1> static Vc_ALWAYS_INLINE typename EnableIf< \
108 IsVectorOperands<T0, T1, int_v>::Value || \
109 (IsLikeSignedInteger<T0>::Value && !IsEqualType<T0, int>::Value && HasImplicitCast<T1, int_v>::Value && !HasImplicitCast<T1, int>::Value) || \
110 (IsLikeSignedInteger<T1>::Value && !IsEqualType<T1, int>::Value && HasImplicitCast<T0, int_v>::Value && !HasImplicitCast<T0, int>::Value) || \
111 false, int_##ret>::Value operator op(const T0 &x, const T1 &y) { return int_v(x) op int_v(y); } \
113 template<typename T0, typename T1> static Vc_ALWAYS_INLINE typename EnableIf< \
114 IsVectorOperands<T0, T1, ushort_v>::Value || \
115 IsTypeCombinationOf<T0, T1, short_v, ushort_v>::Value || \
116 (IsUnsignedInteger<T0>::Value && HasImplicitCast<T1, short_v>::Value && !HasImplicitCast<T1, int>::Value) || \
117 (IsUnsignedInteger<T1>::Value && HasImplicitCast<T0, short_v>::Value && !HasImplicitCast<T0, int>::Value) || \
118 (IsLikeInteger<T0>::Value && !IsEqualType<T0, unsigned short>::Value && HasImplicitCast<T1, ushort_v>::Value && !HasImplicitCast<T1, int>::Value) || \
119 (IsLikeInteger<T1>::Value && !IsEqualType<T1, unsigned short>::Value && HasImplicitCast<T0, ushort_v>::Value && !HasImplicitCast<T0, int>::Value) || \
120 false, ushort_##ret>::Value operator op(const T0 &x, const T1 &y) { return ushort_v(x) op ushort_v(y); } \
121 template<typename T0, typename T1> static Vc_ALWAYS_INLINE typename EnableIf< \
122 IsVectorOperands<T0, T1, short_v>::Value || \
123 (IsLikeSignedInteger<T0>::Value && !IsEqualType<T0, short>::Value && HasImplicitCast<T1, short_v>::Value && !HasImplicitCast<T1, int>::Value) || \
124 (IsLikeSignedInteger<T1>::Value && !IsEqualType<T1, short>::Value && HasImplicitCast<T0, short_v>::Value && !HasImplicitCast<T0, int>::Value) || \
125 false, short_##ret>::Value operator op(const T0 &x, const T1 &y) { return short_v(x) op short_v(y); }
129 #define VC_OPERATOR_INTENTIONAL_ERROR_1(V, op) \
130 template<typename T> static inline typename EnableIfNeitherIntegerNorVector<T, Vc::Error::invalid_operands_of_types<V, T> >::Value operator op(const V &, const T &) { return Vc::Error::invalid_operands_of_types<V, T>(); } \
131 template<typename T> static inline typename EnableIfNeitherIntegerNorVector<T, Vc::Error::invalid_operands_of_types<T, V> >::Value operator op(const T &, const V &) { return Vc::Error::invalid_operands_of_types<T, V>(); }
133 #define VC_OPERATOR_INTENTIONAL_ERROR_2(V1, V2, op) \
134 static inline Vc::Error::invalid_operands_of_types<V1, V2> operator op(V1::AsArg, V2::AsArg) { return Vc::Error::invalid_operands_of_types<V1, V2>(); } \
135 static inline Vc::Error::invalid_operands_of_types<V2, V1> operator op(V2::AsArg, V1::AsArg) { return Vc::Error::invalid_operands_of_types<V2, V1>(); }
137 #define VC_OPERATOR_INTENTIONAL_ERROR_3(V, _T, op) \
138 template<typename T> static inline typename EnableIf<IsEqualType<T, _T>::Value, Vc::Error::invalid_operands_of_types<V, T> >::Value operator op(const V &, const T &) { return Vc::Error::invalid_operands_of_types<V, T>(); } \
139 template<typename T> static inline typename EnableIf<IsEqualType<T, _T>::Value, Vc::Error::invalid_operands_of_types<T, V> >::Value operator op(const T &, const V &) { return Vc::Error::invalid_operands_of_types<T, V>(); }
142 #ifdef VC_EXTRA_CHECKING
143 #define VC_OPERATOR_INTENTIONAL_ERROR(op) \
144 VC_OPERATOR_INTENTIONAL_ERROR_2(double_v, sfloat_v, op) \
145 VC_OPERATOR_INTENTIONAL_ERROR_2(double_v, float_v, op) \
146 VC_OPERATOR_INTENTIONAL_ERROR_2(double_v, int_v, op) \
147 VC_OPERATOR_INTENTIONAL_ERROR_2(double_v, uint_v, op) \
148 VC_OPERATOR_INTENTIONAL_ERROR_2(double_v, short_v, op) \
149 VC_OPERATOR_INTENTIONAL_ERROR_2(double_v, ushort_v, op) \
150 VC_OPERATOR_INTENTIONAL_ERROR_2( int_v, short_v, op) \
151 VC_OPERATOR_INTENTIONAL_ERROR_2( uint_v, short_v, op) \
152 VC_OPERATOR_INTENTIONAL_ERROR_2( int_v, ushort_v, op) \
153 VC_OPERATOR_INTENTIONAL_ERROR_2( uint_v, ushort_v, op) \
154 VC_APPLY_1(VC_LIST_VECTOR_TYPES, VC_OPERATOR_INTENTIONAL_ERROR_1, op) \
155 VC_OPERATOR_INTENTIONAL_ERROR_2( float_v, short_v, op) \
156 VC_OPERATOR_INTENTIONAL_ERROR_2( float_v, ushort_v, op) \
157 VC_OPERATOR_INTENTIONAL_ERROR_2(sfloat_v, float_v, op) \
158 VC_OPERATOR_INTENTIONAL_ERROR_2(sfloat_v, int_v, op) \
159 VC_OPERATOR_INTENTIONAL_ERROR_2(sfloat_v, uint_v, op) \
160 VC_OPERATOR_INTENTIONAL_ERROR_3( float_v, double, op) \
161 VC_OPERATOR_INTENTIONAL_ERROR_3(sfloat_v, double, op)
163 #define VC_OPERATOR_INTENTIONAL_ERROR(op)
166 #define VC_OPERATOR_FORWARD_COMMUTATIVE(ret, op, op2) \
167 template<typename T> static Vc_ALWAYS_INLINE VC_EXACT_TYPE(T, double, double_##ret) operator op(T x, double_v::AsArg y) { return y op2 x; } \
168 template<typename T> static Vc_ALWAYS_INLINE VC_EXACT_TYPE(T, float, sfloat_##ret) operator op(T x, sfloat_v::AsArg y) { return y op2 x; } \
169 template<typename T> static Vc_ALWAYS_INLINE VC_EXACT_TYPE(T, float, float_##ret) operator op(T x, float_v::AsArg y) { return y op2 x; } \
170 template<typename T> static Vc_ALWAYS_INLINE VC_EXACT_TYPE(T, int, int_##ret) operator op(T x, int_v::AsArg y) { return y op2 x; } \
171 template<typename T> static Vc_ALWAYS_INLINE VC_EXACT_TYPE(T, unsigned int, uint_##ret) operator op(T x, uint_v::AsArg y) { return y op2 x; } \
172 template<typename T> static Vc_ALWAYS_INLINE VC_EXACT_TYPE(T, short, short_##ret) operator op(T x, short_v::AsArg y) { return y op2 x; } \
173 template<typename T> static Vc_ALWAYS_INLINE VC_EXACT_TYPE(T, unsigned short, ushort_##ret) operator op(T x, ushort_v::AsArg y) { return y op2 x; } \
174 VC_OPERATOR_FORWARD_(ret, op) \
175 VC_OPERATOR_INTENTIONAL_ERROR(op)
177 #define VC_OPERATOR_FORWARD(ret, op) \
178 template<typename T> static Vc_ALWAYS_INLINE VC_EXACT_TYPE(T, double, double_##ret) operator op(T x, double_v::AsArg y) { return double_v(x) op y; } \
179 template<typename T> static Vc_ALWAYS_INLINE VC_EXACT_TYPE(T, float, sfloat_##ret) operator op(T x, sfloat_v::AsArg y) { return sfloat_v(x) op y; } \
180 template<typename T> static Vc_ALWAYS_INLINE VC_EXACT_TYPE(T, float, float_##ret) operator op(T x, float_v::AsArg y) { return float_v(x) op y; } \
181 template<typename T> static Vc_ALWAYS_INLINE VC_EXACT_TYPE(T, int, int_##ret) operator op(T x, int_v::AsArg y) { return int_v(x) op y; } \
182 template<typename T> static Vc_ALWAYS_INLINE VC_EXACT_TYPE(T, unsigned int, uint_##ret) operator op(T x, uint_v::AsArg y) { return uint_v(x) op y; } \
183 template<typename T> static Vc_ALWAYS_INLINE VC_EXACT_TYPE(T, short, short_##ret) operator op(T x, short_v::AsArg y) { return short_v(x) op y; } \
184 template<typename T> static Vc_ALWAYS_INLINE VC_EXACT_TYPE(T, unsigned short, ushort_##ret) operator op(T x, ushort_v::AsArg y) { return ushort_v(x) op y; } \
185 VC_OPERATOR_FORWARD_(ret, op) \
186 VC_OPERATOR_INTENTIONAL_ERROR(op)
202 #undef VC_OPERATOR_FORWARD_
203 #undef VC_OPERATOR_INTENTIONAL_ERROR_1
204 #undef VC_OPERATOR_INTENTIONAL_ERROR_2
205 #undef VC_OPERATOR_INTENTIONAL_ERROR
206 #undef VC_OPERATOR_FORWARD_COMMUTATIVE
207 #undef VC_OPERATOR_FORWARD
#define VC_OPERATOR_FORWARD(ret, op)
#define VC_OPERATOR_FORWARD_COMMUTATIVE(ret, op, op2)