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)