00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __MMX__VECTOR_FIXED__HPP
00014 #define __MMX__VECTOR_FIXED__HPP
00015 #include <basix/vector_naive.hpp>
00016
00017 namespace mmx {
00018
00019
00020
00021
00022
00023 template<typename Op, typename T, nat n>
00024 struct vec_nullary_helper {
00025 static const nat n1= (n>>1), n2= n-n1;
00026 static inline void op (T* dest) {
00027 vec_nullary_helper <Op, T, n1>::op (dest);
00028 vec_nullary_helper <Op, T, n2>::op (dest+n1);
00029 }
00030 };
00031
00032 template<typename Op, typename T>
00033 struct vec_nullary_helper<Op, T, 1> {
00034 static inline void op (T* dest) {
00035 Op::set_op (*dest);
00036 }
00037 };
00038
00039 template<typename Op, typename T, typename C, nat n>
00040 struct vec_unary_helper {
00041 static const nat n1= (n>>1), n2= n-n1;
00042 static inline void op (T* dest, const C* s) {
00043 vec_unary_helper <Op, T, C, n1>::op (dest , s );
00044 vec_unary_helper <Op, T, C, n2>::op (dest+n1, s+n1);
00045 }
00046 };
00047
00048 template<typename Op, typename T, typename C>
00049 struct vec_unary_helper<Op, T, C, 1> {
00050 static inline void op (T* dest, const C* s) {
00051 Op::set_op (*dest, *s);
00052 }
00053 };
00054
00055 template<typename Op, typename T, typename C1, typename C2, nat n>
00056 struct vec_binary_helper {
00057 static const nat n1= (n>>1), n2= n-n1;
00058 static inline void op (T* dest, const C1* s1, const C2* s2) {
00059 vec_binary_helper <Op, T, C1, C2, n1>::op (dest , s1 , s2 );
00060 vec_binary_helper <Op, T, C1, C2, n2>::op (dest+n1, s1+n1, s2+n1);
00061 }
00062 };
00063
00064 template<typename Op, typename T, typename C1, typename C2>
00065 struct vec_binary_helper<Op, T, C1, C2, 1> {
00066 static inline void op (T* dest, const C1* s1, const C2* s2) {
00067 Op::set_op (*dest, *s1, *s2);
00068 }
00069 };
00070
00071 template<typename Op, typename T, typename X, nat n>
00072 struct vec_unary_scalar_helper {
00073 static const nat n1= (n>>1), n2= n-n1;
00074 static inline void op (T* dest, const X& x) {
00075 vec_unary_scalar_helper <Op, T, X, n1>::op (dest , x);
00076 vec_unary_scalar_helper <Op, T, X, n2>::op (dest+n1, x);
00077 }
00078 };
00079
00080 template<typename Op, typename T, typename X>
00081 struct vec_unary_scalar_helper<Op, T, X, 1> {
00082 static inline void op (T* dest, const X& x) {
00083 Op::set_op (*dest, x);
00084 }
00085 };
00086
00087 template<typename Op, typename T, typename C, typename X, nat n>
00088 struct vec_binary_scalar_helper {
00089 static const nat n1= (n>>1), n2= n-n1;
00090 static inline void op (T* dest, const C* s, const X& x) {
00091 vec_binary_scalar_helper <Op, T, C, X, n1>::op (dest , s , x);
00092 vec_binary_scalar_helper <Op, T, C, X, n2>::op (dest+n1, s+n1, x);
00093 }
00094 };
00095
00096 template<typename Op, typename T, typename C, typename X>
00097 struct vec_binary_scalar_helper<Op, T, C, X, 1> {
00098 static inline void op (T* dest, const C* s, const X& x) {
00099 Op::set_op (*dest, *s, x);
00100 }
00101 };
00102
00103 template<typename Op, typename T, typename C1, typename C2,
00104 typename X, nat n>
00105 struct vec_ternary_scalar_helper {
00106 static const nat n1= (n>>1), n2= n-n1;
00107 static inline void op (T* dest, const C1* s1, const C2* s2, const X& x) {
00108 vec_ternary_scalar_helper <Op, T, C1, C2, X, n1>
00109 ::op (dest, s1, s2, x);
00110 vec_ternary_scalar_helper <Op, T, C1, C2, X, n2>
00111 ::op (dest+n1, s1+n1, s2+n1, x);
00112 }
00113 };
00114
00115 template<typename Op, typename T, typename C1, typename C2, typename X>
00116 struct vec_ternary_scalar_helper<Op, T, C1, C2, X, 1> {
00117 static inline void op (T* dest, const C1* s1, const C2* s2, const X& x) {
00118 Op::set_op (*dest, *s1, *s2, x);
00119 }
00120 };
00121
00122 template<typename Op, typename T, typename C,
00123 typename X1, typename X2, nat n>
00124 struct vec_ternary_scalar_scalar_helper {
00125 static const nat n1= (n>>1), n2= n-n1;
00126 static inline void op (T* dest, const C* s, const X1& x1, const X2& x2) {
00127 vec_ternary_scalar_scalar_helper <Op, T, C, X1, X2, n1>
00128 ::op (dest, s, x1, x2);
00129 vec_ternary_scalar_scalar_helper <Op, T, C, X1, X2, n2>
00130 ::op (dest+n1, s+n1, x1, x2);
00131 }
00132 };
00133
00134 template<typename Op, typename T, typename C, typename X1, typename X2>
00135 struct vec_ternary_scalar_scalar_helper<Op, T, C, X1, X2, 1> {
00136 static inline void op (T* dest, const C* s, const X1& x1, const X2& x2) {
00137 Op::set_op (*dest, *s, x1, x2);
00138 }
00139 };
00140
00141 template<typename Op, typename C, nat n>
00142 struct vec_unary_test_helper {
00143 static const nat n1= (n>>1), n2= n-n1;
00144 static inline void op (const C* s) {
00145 if (!vec_unary_test_helper <Op, C, n1>::op (s)) return false;
00146 return vec_unary_test_helper <Op, C, n2>::op (s+n1);
00147 }
00148 };
00149
00150 template<typename Op, typename C>
00151 struct vec_unary_test_helper<Op, C, 1> {
00152 static inline void op (const C* s) {
00153 return Op::op (*s);
00154 }
00155 };
00156
00157 template<typename Op, typename C1, typename C2, nat n>
00158 struct vec_binary_test_helper {
00159 static const nat n1= (n>>1), n2= n-n1;
00160 static inline bool op (const C1* s1, const C2* s2) {
00161 return vec_binary_test_helper <Op, C1, C2, n1>::op (s1 , s2)
00162 && vec_binary_test_helper <Op, C1, C2, n2>::op (s1+n1, s2+n1);
00163 }
00164 };
00165
00166 template<typename Op, typename C1, typename C2>
00167 struct vec_binary_test_helper<Op, C1, C2, 1> {
00168 static inline bool op (const C1* s1, const C2* s2) {
00169 return !Op::not_op (*s1, *s2);
00170 }
00171 };
00172
00173 template<typename Op, typename C, typename X, nat n>
00174 struct vec_binary_test_scalar_helper {
00175 static const nat n1= (n>>1), n2= n-n1;
00176 static inline bool op (const C* s, const X& x) {
00177 return vec_binary_test_scalar_helper <Op, C, X, n1>::op (s , x)
00178 && vec_binary_test_scalar_helper <Op, C, X, n2>::op (s+n1, x);
00179 }
00180 };
00181
00182 template<typename Op, typename C, typename X>
00183 struct vec_binary_test_scalar_helper<Op, C, X, 1> {
00184 static inline bool op (const C* s, const X& x) {
00185 return !Op::not_op (*s, x);
00186 }
00187 };
00188
00189 template<typename Op, typename R, typename C, nat n>
00190 struct vec_unary_big_helper {
00191 static const nat n1= (n>>1), n2= n-n1;
00192 static inline void set_op (R& r, const C* s) {
00193 vec_unary_big_helper <Op, R, C, n1>::set_op (r, s);
00194 vec_unary_big_helper <Op, R, C, n2>::set_op (r, s+n1);
00195 }
00196 static inline void set_op (R& r, const C* s, const format<C>& fm) {
00197 vec_unary_big_helper <Op, R, C, n1>::set_op (r, s, fm);
00198 vec_unary_big_helper <Op, R, C, n2>::set_op (r, s+n1, fm);
00199 }
00200 };
00201
00202 template<typename Op, typename R, typename C>
00203 struct vec_unary_big_helper<Op, R, C, 1> {
00204 static inline void set_op (R& r, const C* s) {
00205 Op::set_op (r, *s);
00206 }
00207 static inline void set_op (R& r, const C* s, const format<C>& fm) {
00208 (void) fm;
00209 Op::set_op (r, *s);
00210 }
00211 };
00212
00213 template<typename Op, typename C1, typename C2, nat n>
00214 struct vec_binary_big_helper {
00215 static const nat n1= (n>>1), n2= n-n1;
00216 static inline void _op (C1& r, const C1* s1, const C2* s2) {
00217 vec_binary_big_helper <Op, C1, C2, n1>::_op (r, s1 , s2);
00218 vec_binary_big_helper <Op, C1, C2, n2>::_op (r, s1+n1, s2+n1);
00219 }
00220 static inline void _op (C1& r, const C1* s1, const C2* s2,
00221 const format<C1>& fm1, const format<C2>& fm2) {
00222 (void) fm1; (void) fm2;
00223 vec_binary_big_helper <Op, C1, C2, n1>::_op (r, s1 , s2);
00224 vec_binary_big_helper <Op, C1, C2, n2>::_op (r, s1+n1, s2+n1);
00225 }
00226 static inline C1 op (const C1* s1, const C2* s2) {
00227 C1 r= Op::template neutral<C1> ();
00228 vec_binary_big_helper <Op, C1, C2, n1>::_op (r, s1 , s2);
00229 vec_binary_big_helper <Op, C1, C2, n2>::_op (r, s1+n1, s2+n1);
00230 return r;
00231 }
00232 static inline C1 op (const C1* s1, const C2* s2,
00233 const format<C1>& fm1, const format<C2>& fm2) {
00234 C1 r= get_sample (binary_map<Op> (fm1, fm2));
00235 Op::set_neutral (r);
00236 vec_binary_big_helper <Op, C1, C2, n1>::_op (r, s1 , s2);
00237 vec_binary_big_helper <Op, C1, C2, n2>::_op (r, s1+n1, s2+n1);
00238 return r;
00239 }
00240 };
00241
00242 template<typename Op, typename C1, typename C2>
00243 struct vec_binary_big_helper<Op, C1, C2, 1> {
00244 static inline void _op (C1& r, const C1* s1, const C2* s2) {
00245 Op::set_op (r, *s1, *s2);
00246 }
00247 static inline void _op (C1& r, const C1* s1, const C2* s2,
00248 const format<C1>& fm1, const format<C2>& fm2) {
00249 (void) fm1; (void) fm2;
00250 Op::set_op (r, *s1, *s2);
00251 }
00252 static inline C1 op (const C1* s1, const C2* s2) {
00253 C1 r= Op::template neutral<C1> ();
00254 Op::set_op (r, *s1, *s2);
00255 return r;
00256 }
00257 static inline C1 op (const C1* s1, const C2* s2,
00258 const format<C1>& fm1, const format<C2>& fm2) {
00259 C1 r= get_sample (binary_map<Op> (fm1, fm2));
00260 Op::set_neutral (r);
00261 Op::set_op (r, *s1, *s2);
00262 return r;
00263 }
00264 };
00265
00266
00267 template<typename C1, typename C2>
00268 struct vec_binary_big_helper<mul_add_op, C1, C2, 2> {
00269 static inline void _op (C1& r, const C1* s1, const C2* s2) {
00270 r += (*s1) * (*s2) + (*(s1+1)) * (*(s2+1));
00271 }
00272 static inline void _op (C1& r, const C1* s1, const C2* s2,
00273 const format<C1>& fm1, const format<C2>& fm2) {
00274 (void) fm1; (void) fm2;
00275 r += (*s1) * (*s2) + (*(s1+1)) * (*(s2+1));
00276 }
00277 static inline C1 op (const C1* s1, const C2* s2) {
00278 return (*s1) * (*s2) + (*(s1+1)) * (*(s2+1));
00279 }
00280 static inline C1 op (const C1* s1, const C2* s2,
00281 const format<C1>& fm1, const format<C2>& fm2) {
00282 (void) fm1; (void) fm2;
00283 return (*s1) * (*s2) + (*(s1+1)) * (*(s2+1));
00284 }
00285 };
00286
00287 }
00288 #endif //__MMX__VECTOR_FIXED__HPP