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 C, nat n>
00104 struct vec_unary_test_helper {
00105 static const nat n1= (n>>1), n2= n-n1;
00106 static inline void op (const C* s) {
00107 if (!vec_unary_test_helper <Op, C, n1>::op (s)) return false;
00108 return vec_unary_test_helper <Op, C, n2>::op (s+n1);
00109 }
00110 };
00111
00112 template<typename Op, typename C>
00113 struct vec_unary_test_helper<Op, C, 1> {
00114 static inline void op (const C* s) {
00115 return Op::op (*s);
00116 }
00117 };
00118
00119 template<typename Op, typename C1, typename C2, nat n>
00120 struct vec_binary_test_helper {
00121 static const nat n1= (n>>1), n2= n-n1;
00122 static inline bool op (const C1* s1, const C2* s2) {
00123 return vec_binary_test_helper <Op, C1, C2, n1>::op (s1 , s2)
00124 && vec_binary_test_helper <Op, C1, C2, n2>::op (s1+n1, s2+n1);
00125 }
00126 };
00127
00128 template<typename Op, typename C1, typename C2>
00129 struct vec_binary_test_helper<Op, C1, C2, 1> {
00130 static inline bool op (const C1* s1, const C2* s2) {
00131 return !Op::not_op (*s1, *s2);
00132 }
00133 };
00134
00135 template<typename Op, typename C, typename X, nat n>
00136 struct vec_binary_test_scalar_helper {
00137 static const nat n1= (n>>1), n2= n-n1;
00138 static inline bool op (const C* s, const X& x) {
00139 return vec_binary_test_scalar_helper <Op, C, X, n1>::op (s , x)
00140 && vec_binary_test_scalar_helper <Op, C, X, n2>::op (s+n1, x);
00141 }
00142 };
00143
00144 template<typename Op, typename C, typename X>
00145 struct vec_binary_test_scalar_helper<Op, C, X, 1> {
00146 static inline bool op (const C* s, const X& x) {
00147 return !Op::not_op (*s, x);
00148 }
00149 };
00150
00151 template<typename Op, typename R, typename C, nat n>
00152 struct vec_unary_big_helper {
00153 static const nat n1= (n>>1), n2= n-n1;
00154 static inline void set_op (R& r, const C* s) {
00155 vec_unary_big_helper <Op, R, C, n1>::set_op (r, s);
00156 vec_unary_big_helper <Op, R, C, n2>::set_op (r, s+n1);
00157 }
00158 static inline void set_op (R& r, const C* s, const format<C>& fm) {
00159 vec_unary_big_helper <Op, R, C, n1>::set_op (r, s, fm);
00160 vec_unary_big_helper <Op, R, C, n2>::set_op (r, s+n1, fm);
00161 }
00162 };
00163
00164 template<typename Op, typename R, typename C>
00165 struct vec_unary_big_helper<Op, R, C, 1> {
00166 static inline void set_op (R& r, const C* s) {
00167 Op::set_op (r, *s);
00168 }
00169 static inline void set_op (R& r, const C* s, const format<C>& fm) {
00170 (void) fm;
00171 Op::set_op (r, *s);
00172 }
00173 };
00174
00175 template<typename Op, typename C1, typename C2, nat n>
00176 struct vec_binary_big_helper {
00177 static const nat n1= (n>>1), n2= n-n1;
00178 static inline void _op (C1& r, const C1* s1, const C2* s2) {
00179 vec_binary_big_helper <Op, C1, C2, n1>::_op (r, s1 , s2);
00180 vec_binary_big_helper <Op, C1, C2, n2>::_op (r, s1+n1, s2+n1);
00181 }
00182 static inline void _op (C1& r, const C1* s1, const C2* s2,
00183 const format<C1>& fm1, const format<C2>& fm2) {
00184 (void) fm1; (void) fm2;
00185 vec_binary_big_helper <Op, C1, C2, n1>::_op (r, s1 , s2);
00186 vec_binary_big_helper <Op, C1, C2, n2>::_op (r, s1+n1, s2+n1);
00187 }
00188 static inline C1 op (const C1* s1, const C2* s2) {
00189 C1 r= Op::template neutral<C1> ();
00190 vec_binary_big_helper <Op, C1, C2, n1>::_op (r, s1 , s2);
00191 vec_binary_big_helper <Op, C1, C2, n2>::_op (r, s1+n1, s2+n1);
00192 return r;
00193 }
00194 static inline C1 op (const C1* s1, const C2* s2,
00195 const format<C1>& fm1, const format<C2>& fm2) {
00196 C1 r= get_sample (binary_map<Op> (fm1, fm2));
00197 Op::set_neutral (r);
00198 vec_binary_big_helper <Op, C1, C2, n1>::_op (r, s1 , s2);
00199 vec_binary_big_helper <Op, C1, C2, n2>::_op (r, s1+n1, s2+n1);
00200 return r;
00201 }
00202 };
00203
00204 template<typename Op, typename C1, typename C2>
00205 struct vec_binary_big_helper<Op, C1, C2, 1> {
00206 static inline void _op (C1& r, const C1* s1, const C2* s2) {
00207 Op::set_op (r, *s1, *s2);
00208 }
00209 static inline void _op (C1& r, const C1* s1, const C2* s2,
00210 const format<C1>& fm1, const format<C2>& fm2) {
00211 (void) fm1; (void) fm2;
00212 Op::set_op (r, *s1, *s2);
00213 }
00214 static inline C1 op (const C1* s1, const C2* s2) {
00215 C1 r= Op::template neutral<C1> ();
00216 Op::set_op (r, *s1, *s2);
00217 return r;
00218 }
00219 static inline C1 op (const C1* s1, const C2* s2,
00220 const format<C1>& fm1, const format<C2>& fm2) {
00221 C1 r= get_sample (binary_map<Op> (fm1, fm2));
00222 Op::set_neutral (r);
00223 Op::set_op (r, *s1, *s2);
00224 return r;
00225 }
00226 };
00227
00228
00229 template<typename C1, typename C2>
00230 struct vec_binary_big_helper<mul_add_op, C1, C2, 2> {
00231 static inline void _op (C1& r, const C1* s1, const C2* s2) {
00232 r += (*s1) * (*s2) + (*(s1+1)) * (*(s2+1));
00233 }
00234 static inline void _op (C1& r, const C1* s1, const C2* s2,
00235 const format<C1>& fm1, const format<C2>& fm2) {
00236 (void) fm1; (void) fm2;
00237 r += (*s1) * (*s2) + (*(s1+1)) * (*(s2+1));
00238 }
00239 static inline C1 op (const C1* s1, const C2* s2) {
00240 return (*s1) * (*s2) + (*(s1+1)) * (*(s2+1));
00241 }
00242 static inline C1 op (const C1* s1, const C2* s2,
00243 const format<C1>& fm1, const format<C2>& fm2) {
00244 (void) fm1; (void) fm2;
00245 return (*s1) * (*s2) + (*(s1+1)) * (*(s2+1));
00246 }
00247 };
00248
00249 }
00250 #endif //__MMX__VECTOR_FIXED__HPP