00001 #ifndef SHCONCRETECTYPEOPIMPL_HPP
00002 #define SHCONCRETECTYPEOPIMPL_HPP
00003
00004 #include <numeric>
00005 #include "ShEval.hpp"
00006 #include "ShVariant.hpp"
00007 #include "ShDebug.hpp"
00008 #include "ShError.hpp"
00009 #include "ShTypeInfo.hpp"
00010
00011 namespace {
00013 template<typename T1, typename T2>
00014 T1 _sh_intpow(T1 x, T2 pow)
00015 {
00016 T1 result = 1;
00017 if(pow < 0) {
00018 x = 1 / x;
00019 pow = -pow;
00020 }
00021 for(;pow; pow >>= 1, x *= x) {
00022 if(pow & 1) result *= x;
00023 }
00024 return result;
00025 }
00026 }
00027 namespace SH {
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #define SHCCTO_UNARY_OP(op, opsrc)\
00046 template<typename T>\
00047 struct ShConcreteCTypeOp<op, T>\
00048 { \
00049 typedef ShDataVariant<T, SH_HOST> Variant; \
00050 typedef Variant* DataPtr; \
00051 typedef const Variant* DataCPtr; \
00052 \
00053 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) \
00054 {\
00055 SH_DEBUG_ASSERT(dest && a);\
00056 int ao = a->size() > 1;\
00057 \
00058 typename Variant::iterator D = dest->begin();\
00059 typename Variant::const_iterator A = a->begin();\
00060 for(; D != dest->end(); A += ao, ++D) {\
00061 (*D) = opsrc;\
00062 }\
00063 } \
00064 };
00065
00066
00067 #define SHCCTO_BINARY_OP(op, opsrc)\
00068 template<typename T>\
00069 struct ShConcreteCTypeOp<op, T>\
00070 { \
00071 typedef ShDataVariant<T, SH_HOST> Variant; \
00072 typedef Variant* DataPtr; \
00073 typedef const Variant* DataCPtr; \
00074 \
00075 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) \
00076 {\
00077 SH_DEBUG_ASSERT(dest && a && b);\
00078 int ao = a->size() > 1;\
00079 int bo = b->size() > 1;\
00080 \
00081 typename Variant::iterator D = dest->begin();\
00082 typename Variant::const_iterator A, B;\
00083 A = a->begin();\
00084 B = b->begin();\
00085 for(; D != dest->end(); A += ao, B += bo, ++D) {\
00086 (*D) = opsrc;\
00087 }\
00088 } \
00089 };
00090
00091
00092 #define SHCCTO_TERNARY_OP(op, opsrc)\
00093 template<typename T>\
00094 struct ShConcreteCTypeOp<op, T>\
00095 { \
00096 typedef ShDataVariant<T, SH_HOST> Variant; \
00097 typedef Variant* DataPtr; \
00098 typedef const Variant* DataCPtr; \
00099 \
00100 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) \
00101 {\
00102 SH_DEBUG_ASSERT(dest && a && b && c);\
00103 int ao = a->size() > 1;\
00104 int bo = b->size() > 1;\
00105 int co = c->size() > 1;\
00106 \
00107 typename Variant::iterator D = dest->begin();\
00108 typename Variant::const_iterator A, B, C;\
00109 A = a->begin();\
00110 B = b->begin();\
00111 C = c->begin();\
00112 for(; D != dest->end(); A += ao, B += bo, C += co, ++D) {\
00113 (*D) = opsrc;\
00114 }\
00115 }\
00116 };
00117
00118 #define SHCCTO_OP_SPEC(T, op)\
00119 template<>\
00120 struct \
00121 SH_DLLEXPORT \
00122 ShConcreteCTypeOp<op, T>\
00123 { \
00124 typedef ShDataVariant<T, SH_HOST> Variant; \
00125 typedef Variant* DataPtr; \
00126 typedef const Variant* DataCPtr; \
00127 \
00128 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0); \
00129 };
00130
00131 #define SHCCTO_OP_CMATH_SPEC(op)\
00132 SHCCTO_OP_SPEC(double, op);\
00133 SHCCTO_OP_SPEC(float, op);
00134
00135
00136
00137
00138
00139
00140 SHCCTO_UNARY_OP(SH_OP_ABS, (shDataTypeIsPositive(*A) ? (*A) : -(*A)));
00141
00142 SHCCTO_OP_CMATH_SPEC(SH_OP_ACOS);
00143 SHCCTO_OP_CMATH_SPEC(SH_OP_ASIN);
00144
00145 SHCCTO_UNARY_OP(SH_OP_ASN, (*A));
00146
00147 SHCCTO_OP_CMATH_SPEC(SH_OP_ATAN);
00148 SHCCTO_OP_CMATH_SPEC(SH_OP_CBRT);
00149 SHCCTO_OP_CMATH_SPEC(SH_OP_CEIL);
00150
00151 template<typename T>
00152 struct ShConcreteCTypeOp<SH_OP_CMUL, T>
00153 {
00154 typedef ShDataVariant<T, SH_HOST> Variant;
00155 typedef Variant* DataPtr;
00156 typedef const Variant* DataCPtr;
00157
00158 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0)
00159 {
00160
00161 (*dest)[0] = std::accumulate(a->begin(), a->end(),
00162 ShDataTypeInfo<T, SH_HOST>::Zero,
00163 std::multiplies<typename Variant::DataType>());
00164 }
00165 };
00166
00167 SHCCTO_OP_CMATH_SPEC(SH_OP_COS);
00168
00169 template<typename T>
00170 struct ShConcreteCTypeOp<SH_OP_CSUM, T>
00171 {
00172 typedef ShDataVariant<T, SH_HOST> Variant;
00173 typedef Variant* DataPtr;
00174 typedef const Variant* DataCPtr;
00175
00176 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0)
00177 {
00178
00179 (*dest)[0] = std::accumulate(a->begin(), a->end(),
00180 ShDataTypeInfo<T, SH_HOST>::Zero,
00181 std::plus<typename Variant::DataType>());
00182 }
00183 };
00184
00185 SHCCTO_OP_CMATH_SPEC(SH_OP_EXP);
00186 SHCCTO_OP_CMATH_SPEC(SH_OP_EXP2);
00187 SHCCTO_OP_CMATH_SPEC(SH_OP_EXP10);
00188 SHCCTO_OP_CMATH_SPEC(SH_OP_FLR);
00189 SHCCTO_OP_CMATH_SPEC(SH_OP_FRAC);
00190 SHCCTO_OP_CMATH_SPEC(SH_OP_LOG);
00191 SHCCTO_OP_CMATH_SPEC(SH_OP_LOG2);
00192 SHCCTO_OP_CMATH_SPEC(SH_OP_LOG10);
00193 SHCCTO_OP_CMATH_SPEC(SH_OP_NORM);
00194
00195 SHCCTO_UNARY_OP(SH_OP_RCP, 1 / (*A));
00196
00197 SHCCTO_OP_CMATH_SPEC(SH_OP_RND);
00198 SHCCTO_OP_CMATH_SPEC(SH_OP_RSQ);
00199 SHCCTO_OP_CMATH_SPEC(SH_OP_SIN);
00200
00201 SHCCTO_UNARY_OP(SH_OP_SGN, (*A) > 0 ? 1 : (*A) < 0 ? -1 : 0);
00202
00203 SHCCTO_OP_CMATH_SPEC(SH_OP_SQRT);
00204 SHCCTO_OP_CMATH_SPEC(SH_OP_TAN);
00205
00206
00207
00208 SHCCTO_BINARY_OP(SH_OP_ADD, (*A) + (*B));
00209
00210 SHCCTO_OP_CMATH_SPEC(SH_OP_ATAN2);
00211
00212 SHCCTO_BINARY_OP(SH_OP_DIV, (*A) / (*B));
00213
00214 template<typename T>
00215 struct ShConcreteCTypeOp<SH_OP_DOT, T>
00216 {
00217 typedef ShDataVariant<T, SH_HOST> Variant;
00218 typedef Variant* DataPtr;
00219 typedef const Variant* DataCPtr;
00220
00221 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0)
00222 {
00223
00224 (*dest)[0] = std::inner_product(a->begin(), a->end(), b->begin(),
00225 ShDataTypeInfo<T, SH_HOST>::Zero);
00226 }
00227 };
00228
00229 SHCCTO_BINARY_OP(SH_OP_MAX, std::max((*A), (*B)));
00230 SHCCTO_BINARY_OP(SH_OP_MIN, std::min((*A), (*B)));
00231
00232 SHCCTO_BINARY_OP(SH_OP_MOD, (*A) % (*B));
00233 SHCCTO_OP_CMATH_SPEC(SH_OP_MOD);
00234
00235 SHCCTO_BINARY_OP(SH_OP_MUL, (*A) * (*B));
00236
00237
00238 SHCCTO_BINARY_OP(SH_OP_POW, _sh_intpow((*A), (*B)));
00239 SHCCTO_OP_CMATH_SPEC(SH_OP_POW);
00240
00241
00242 SHCCTO_BINARY_OP(SH_OP_SEQ, (shDataTypeCond<T, SH_HOST>((*A) == (*B))));
00243 SHCCTO_BINARY_OP(SH_OP_SGE, (shDataTypeCond<T, SH_HOST>((*A) >= (*B))));
00244 SHCCTO_BINARY_OP(SH_OP_SGT, (shDataTypeCond<T, SH_HOST>((*A) > (*B))));
00245 SHCCTO_BINARY_OP(SH_OP_SLE, (shDataTypeCond<T, SH_HOST>((*A) <= (*B))));
00246 SHCCTO_BINARY_OP(SH_OP_SLT, (shDataTypeCond<T, SH_HOST>((*A) < (*B))));
00247 SHCCTO_BINARY_OP(SH_OP_SNE, (shDataTypeCond<T, SH_HOST>((*A) != (*B))));
00248
00249 template<typename T>
00250 struct ShConcreteCTypeOp<SH_OP_XPD, T>
00251 {
00252 typedef ShDataVariant<T, SH_HOST> Variant;
00253 typedef Variant* DataPtr;
00254 typedef const Variant* DataCPtr;
00255
00256 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0)
00257 {
00258
00259
00260 typename Variant::DataType t0, t1;
00261 t0 = (*a)[1] * (*b)[2] - (*a)[2] * (*b)[1];
00262 t1 = -((*a)[0] * (*b)[2] - (*a)[2] * (*b)[0]);
00263 (*dest)[2] = (*a)[0] * (*b)[1] - (*a)[1] * (*b)[0];
00264 (*dest)[0] = t0;
00265 (*dest)[1] = t1;
00266 }
00267 };
00268
00269
00270 SHCCTO_TERNARY_OP(SH_OP_COND, ((*A) > 0 ? (*B) : (*C)));
00271 SHCCTO_TERNARY_OP(SH_OP_LRP, (*A) * (*B) + (1 - (*A)) * (*C));
00272 SHCCTO_TERNARY_OP(SH_OP_MAD, (*A) * (*B) + (*C));
00273
00274
00275 }
00276
00277 #endif