ICRS Eurobot 2013

Dependencies:   mbed mbed-rtos Servo QEI

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers VectorOperators.h Source File

VectorOperators.h

00001 /*
00002  * Tiny Vector Matrix Library
00003  * Dense Vector Matrix Libary of Tiny size using Expression Templates
00004  *
00005  * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  *
00021  * $Id: VectorOperators.h,v 1.17 2007-06-23 15:59:00 opetzold Exp $
00022  */
00023 
00024 #ifndef TVMET_XPR_VECTOR_OPERATORS_H
00025 #define TVMET_XPR_VECTOR_OPERATORS_H
00026 
00027 namespace tvmet {
00028 
00029 
00030 /*********************************************************
00031  * PART I: DECLARATION
00032  *********************************************************/
00033 
00034 
00035 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00036  * Vector arithmetic operators implemented by functions
00037  * add, sub, mul and div
00038  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00039 
00040 
00041 /*
00042  * operator(XprVector<E1, Sz>, XprVector<E2, Sz>)
00043  */
00044 #define TVMET_DECLARE_MACRO(NAME, OP)                    \
00045 template<class E1, class E2, std::size_t Sz>                \
00046 inline                                    \
00047 XprVector<                                \
00048   XprBinOp<                                \
00049     Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,    \
00050     XprVector<E1, Sz>,                            \
00051     XprVector<E2, Sz>                            \
00052   >,                                    \
00053   Sz                                    \
00054 >                                    \
00055 operator OP (const XprVector<E1, Sz>& lhs,                 \
00056          const XprVector<E2, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
00057 
00058 TVMET_DECLARE_MACRO(add, +)        // per se element wise
00059 TVMET_DECLARE_MACRO(sub, -)        // per se element wise
00060 TVMET_DECLARE_MACRO(mul, *)        // per se element wise
00061 namespace element_wise {
00062   TVMET_DECLARE_MACRO(div, /)        // not defined for vectors
00063 }
00064 
00065 #undef TVMET_DECLARE_MACRO
00066 
00067 
00068 /*
00069  * operator(XprVector<E, Sz>, POD)
00070  * operator(POD, XprVector<E, Sz>)
00071  * Note: operations +,-,*,/ are per se element wise
00072  */
00073 #define TVMET_DECLARE_MACRO(NAME, OP, POD)                \
00074 template<class E, std::size_t Sz>                    \
00075 inline                                    \
00076 XprVector<                                \
00077   XprBinOp<                                \
00078     Fcnl_##NAME<typename E::value_type, POD >,                \
00079     XprVector<E, Sz>,                            \
00080     XprLiteral< POD >                            \
00081   >,                                    \
00082   Sz                                    \
00083 >                                    \
00084 operator OP (const XprVector<E, Sz>& lhs,                 \
00085          POD rhs) TVMET_CXX_ALWAYS_INLINE;                \
00086                                     \
00087 template<class E, std::size_t Sz>                    \
00088 inline                                    \
00089 XprVector<                                \
00090   XprBinOp<                                \
00091     Fcnl_##NAME< POD, typename E::value_type >,                \
00092     XprLiteral< POD >,                            \
00093     XprVector< E, Sz>                            \
00094   >,                                    \
00095   Sz                                    \
00096 >                                    \
00097 operator OP (POD lhs,                             \
00098          const XprVector<E, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
00099 
00100 TVMET_DECLARE_MACRO(add, +, int)
00101 TVMET_DECLARE_MACRO(sub, -, int)
00102 TVMET_DECLARE_MACRO(mul, *, int)
00103 TVMET_DECLARE_MACRO(div, /, int)
00104 
00105 #if defined(TVMET_HAVE_LONG_LONG)
00106 TVMET_DECLARE_MACRO(add, +, long long int)
00107 TVMET_DECLARE_MACRO(sub, -, long long int)
00108 TVMET_DECLARE_MACRO(mul, *, long long int)
00109 TVMET_DECLARE_MACRO(div, /, long long int)
00110 #endif
00111 
00112 TVMET_DECLARE_MACRO(add, +, float)
00113 TVMET_DECLARE_MACRO(sub, -, float)
00114 TVMET_DECLARE_MACRO(mul, *, float)
00115 TVMET_DECLARE_MACRO(div, /, float)
00116 
00117 TVMET_DECLARE_MACRO(add, +, double)
00118 TVMET_DECLARE_MACRO(sub, -, double)
00119 TVMET_DECLARE_MACRO(mul, *, double)
00120 TVMET_DECLARE_MACRO(div, /, double)
00121 
00122 #if defined(TVMET_HAVE_LONG_DOUBLE)
00123 TVMET_DECLARE_MACRO(add, +, long double)
00124 TVMET_DECLARE_MACRO(sub, -, long double)
00125 TVMET_DECLARE_MACRO(mul, *, long double)
00126 TVMET_DECLARE_MACRO(div, /, long double)
00127 #endif
00128 
00129 #undef TVMET_DECLARE_MACRO
00130 
00131 
00132 #if defined(TVMET_HAVE_COMPLEX)
00133 /*
00134  * operator(XprVector<E, Sz>, complex<T>)
00135  * operator(complex<T>, XprVector<E, Sz>)
00136  * Note: operations +,-,*,/ are per se element wise
00137  */
00138 #define TVMET_DECLARE_MACRO(NAME, OP)                    \
00139 template<class E, std::size_t Sz, class T>                \
00140 inline                                    \
00141 XprVector<                                \
00142   XprBinOp<                                \
00143     Fcnl_##NAME<typename E::value_type, std::complex<T> >,        \
00144     XprVector<E, Sz>,                            \
00145     XprLiteral< std::complex<T> >                    \
00146   >,                                    \
00147   Sz                                    \
00148 >                                    \
00149 operator OP (const XprVector<E, Sz>& lhs,                \
00150          const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE;    \
00151                                     \
00152 template<class E, std::size_t Sz, class T>                \
00153 inline                                    \
00154 XprVector<                                \
00155   XprBinOp<                                \
00156     Fcnl_##NAME< std::complex<T>, typename E::value_type >,        \
00157     XprLiteral< std::complex<T> >,                    \
00158     XprVector< E, Sz>                            \
00159   >,                                    \
00160   Sz                                    \
00161 >                                    \
00162 operator OP (const std::complex<T>& lhs,                \
00163          const XprVector<E, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
00164 
00165 TVMET_DECLARE_MACRO(add, +)        // per se element wise
00166 TVMET_DECLARE_MACRO(sub, -)        // per se element wise
00167 TVMET_DECLARE_MACRO(mul, *)        // per se element wise
00168 TVMET_DECLARE_MACRO(div, /)        // per se element wise
00169 
00170 #undef TVMET_DECLARE_MACRO
00171 
00172 #endif // defined(TVMET_HAVE_COMPLEX)
00173 
00174 
00175 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00176  * Vector integer and compare operators
00177  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00178 
00179 
00180 /*
00181  * operator(XprVector, XprVector)
00182  */
00183 #define TVMET_DECLARE_MACRO(NAME, OP)                    \
00184 template<class E1, class E2, std::size_t Sz>                \
00185 inline                                    \
00186 XprVector<                                \
00187   XprBinOp<                                \
00188     Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,    \
00189     XprVector<E1, Sz>,                            \
00190     XprVector<E2, Sz>                            \
00191   >,                                    \
00192   Sz                                    \
00193 >                                    \
00194 operator OP (const XprVector<E1, Sz>& lhs,                \
00195          const XprVector<E2, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
00196 
00197 // integer operators only, e.g used on double you wil get an error
00198 namespace element_wise {
00199   TVMET_DECLARE_MACRO(mod, %)
00200   TVMET_DECLARE_MACRO(bitxor, ^)
00201   TVMET_DECLARE_MACRO(bitand, &)
00202   TVMET_DECLARE_MACRO(bitor, |)
00203   TVMET_DECLARE_MACRO(shl, <<)
00204   TVMET_DECLARE_MACRO(shr, >>)
00205 }
00206 
00207 // necessary operators for eval functions
00208 TVMET_DECLARE_MACRO(greater, >)
00209 TVMET_DECLARE_MACRO(less, <)
00210 TVMET_DECLARE_MACRO(greater_eq, >=)
00211 TVMET_DECLARE_MACRO(less_eq, <=)
00212 TVMET_DECLARE_MACRO(eq, ==)
00213 TVMET_DECLARE_MACRO(not_eq, !=)
00214 TVMET_DECLARE_MACRO(and, &&)
00215 TVMET_DECLARE_MACRO(or, ||)
00216 
00217 #undef TVMET_DECLARE_MACRO
00218 
00219 
00220 /*
00221  * operator(Vector<T, Sz>, POD)
00222  * operator(POD, Vector<T, Sz>)
00223  * Note: operations are per se element_wise
00224  */
00225 #define TVMET_DECLARE_MACRO(NAME, OP, TP)                \
00226 template<class E, std::size_t Sz>                    \
00227 inline                                    \
00228 XprVector<                                \
00229   XprBinOp<                                \
00230     Fcnl_##NAME<typename E::value_type, TP >,                \
00231     XprVector<E, Sz>,                            \
00232     XprLiteral< TP >                            \
00233   >,                                    \
00234   Sz                                    \
00235 >                                    \
00236 operator OP (const XprVector<E, Sz>& lhs,                 \
00237          TP rhs) TVMET_CXX_ALWAYS_INLINE;                \
00238                                     \
00239 template<class E, std::size_t Sz>                    \
00240 inline                                    \
00241 XprVector<                                \
00242   XprBinOp<                                \
00243     Fcnl_##NAME<TP, typename E::value_type>,                \
00244     XprLiteral< TP >,                            \
00245     XprVector<E, Sz>                            \
00246   >,                                    \
00247   Sz                                    \
00248 >                                    \
00249 operator OP (TP lhs,                             \
00250          const XprVector<E, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
00251 
00252 // integer operators only, e.g used on double you wil get an error
00253 namespace element_wise {
00254   TVMET_DECLARE_MACRO(mod, %, int)
00255   TVMET_DECLARE_MACRO(bitxor, ^, int)
00256   TVMET_DECLARE_MACRO(bitand, &, int)
00257   TVMET_DECLARE_MACRO(bitor, |, int)
00258   TVMET_DECLARE_MACRO(shl, <<, int)
00259   TVMET_DECLARE_MACRO(shr, >>, int)
00260 }
00261 
00262 // necessary operators for eval functions
00263 TVMET_DECLARE_MACRO(greater, >, int)
00264 TVMET_DECLARE_MACRO(less, <, int)
00265 TVMET_DECLARE_MACRO(greater_eq, >=, int)
00266 TVMET_DECLARE_MACRO(less_eq, <=, int)
00267 TVMET_DECLARE_MACRO(eq, ==, int)
00268 TVMET_DECLARE_MACRO(not_eq, !=, int)
00269 TVMET_DECLARE_MACRO(and, &&, int)
00270 TVMET_DECLARE_MACRO(or, ||, int)
00271 
00272 
00273 #if defined(TVMET_HAVE_LONG_LONG)
00274 // integer operators only
00275 namespace element_wise {
00276   TVMET_DECLARE_MACRO(mod, %, long long int)
00277   TVMET_DECLARE_MACRO(bitxor, ^, long long int)
00278   TVMET_DECLARE_MACRO(bitand, &, long long int)
00279   TVMET_DECLARE_MACRO(bitor, |, long long int)
00280   TVMET_DECLARE_MACRO(shl, <<, long long int)
00281   TVMET_DECLARE_MACRO(shr, >>, long long int)
00282 }
00283 
00284 // necessary operators for eval functions
00285 TVMET_DECLARE_MACRO(greater, >, long long int)
00286 TVMET_DECLARE_MACRO(less, <, long long int)
00287 TVMET_DECLARE_MACRO(greater_eq, >=, long long int)
00288 TVMET_DECLARE_MACRO(less_eq, <=, long long int)
00289 TVMET_DECLARE_MACRO(eq, ==, long long int)
00290 TVMET_DECLARE_MACRO(not_eq, !=, long long int)
00291 TVMET_DECLARE_MACRO(and, &&, long long int)
00292 TVMET_DECLARE_MACRO(or, ||, long long int)
00293 #endif // defined(TVMET_HAVE_LONG_LONG)
00294 
00295 // necessary operators for eval functions
00296 TVMET_DECLARE_MACRO(greater, >, float)
00297 TVMET_DECLARE_MACRO(less, <, float)
00298 TVMET_DECLARE_MACRO(greater_eq, >=, float)
00299 TVMET_DECLARE_MACRO(less_eq, <=, float)
00300 TVMET_DECLARE_MACRO(eq, ==, float)
00301 TVMET_DECLARE_MACRO(not_eq, !=, float)
00302 
00303 // necessary operators for eval functions
00304 TVMET_DECLARE_MACRO(greater, >, double)
00305 TVMET_DECLARE_MACRO(less, <, double)
00306 TVMET_DECLARE_MACRO(greater_eq, >=, double)
00307 TVMET_DECLARE_MACRO(less_eq, <=, double)
00308 TVMET_DECLARE_MACRO(eq, ==, double)
00309 TVMET_DECLARE_MACRO(not_eq, !=, double)
00310 
00311 #if defined(TVMET_HAVE_LONG_DOUBLE)
00312 // necessary operators for eval functions
00313 TVMET_DECLARE_MACRO(greater, >, long double)
00314 TVMET_DECLARE_MACRO(less, <, long double)
00315 TVMET_DECLARE_MACRO(greater_eq, >=, long double)
00316 TVMET_DECLARE_MACRO(less_eq, <=, long double)
00317 TVMET_DECLARE_MACRO(eq, ==, long double)
00318 TVMET_DECLARE_MACRO(not_eq, !=, long double)
00319 #endif // defined(TVMET_HAVE_LONG_DOUBLE)
00320 
00321 #undef TVMET_DECLARE_MACRO
00322 
00323 
00324 #if defined(TVMET_HAVE_COMPLEX)
00325 /*
00326  * operator(Vector<std::complex<T>, Sz>, std::complex<T>)
00327  * operator(std::complex<T>, Vector<std::complex<T>, Sz>)
00328  * Note: - per se element wise
00329  *       - bit ops on complex<int> doesn't make sense, stay away
00330  * \todo type promotion
00331  */
00332 #define TVMET_DECLARE_MACRO(NAME, OP)                    \
00333 template<class E, std::size_t Sz, class T>                \
00334 inline                                    \
00335 XprVector<                                \
00336   XprBinOp<                                \
00337     Fcnl_##NAME<typename E::value_type, std::complex<T> >,        \
00338     XprVector<E, Sz>,                            \
00339     XprLiteral< std::complex<T> >                    \
00340   >,                                    \
00341   Sz                                    \
00342 >                                    \
00343 operator OP (const XprVector<E, Sz>& lhs,                \
00344          const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE;    \
00345                                     \
00346 template<class E, std::size_t Sz, class T>                \
00347 inline                                    \
00348 XprVector<                                \
00349   XprBinOp<                                \
00350     Fcnl_##NAME<std::complex<T>, typename E::value_type>,        \
00351     XprLiteral< std::complex<T> >,                    \
00352     XprVector<E, Sz>                            \
00353   >,                                    \
00354   Sz                                    \
00355 >                                    \
00356 operator OP (const std::complex<T>& lhs,                \
00357          const XprVector<E, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
00358 
00359 // necessary operators for eval functions
00360 TVMET_DECLARE_MACRO(greater, >)
00361 TVMET_DECLARE_MACRO(less, <)
00362 TVMET_DECLARE_MACRO(greater_eq, >=)
00363 TVMET_DECLARE_MACRO(less_eq, <=)
00364 TVMET_DECLARE_MACRO(eq, ==)
00365 TVMET_DECLARE_MACRO(not_eq, !=)
00366 TVMET_DECLARE_MACRO(and, &&)
00367 TVMET_DECLARE_MACRO(or, ||)
00368 
00369 #undef TVMET_DECLARE_MACRO
00370 
00371 #endif // defined(TVMET_HAVE_COMPLEX)
00372 
00373 
00374 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00375  * global unary operators
00376  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00377 
00378 
00379 /*
00380  * Unary Operator on XprVector<E, Sz>
00381  */
00382 #define TVMET_DECLARE_MACRO(NAME, OP)                    \
00383 template <class E, std::size_t Sz>                    \
00384 inline                                    \
00385 XprVector<                                \
00386   XprUnOp<                                \
00387     Fcnl_##NAME<typename E::value_type>,                \
00388     XprVector<E, Sz>                            \
00389   >,                                    \
00390   Sz                                    \
00391 >                                    \
00392 operator OP (const XprVector<E, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
00393 
00394 TVMET_DECLARE_MACRO(not, !)
00395 TVMET_DECLARE_MACRO(compl, ~)
00396 TVMET_DECLARE_MACRO(neg, -)
00397 
00398 #undef TVMET_DECLARE_MACRO
00399 
00400 
00401 /*********************************************************
00402  * PART II: IMPLEMENTATION
00403  *********************************************************/
00404 
00405 
00406 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00407  * Vector arithmetic operators implemented by functions
00408  * add, sub, mul and div
00409  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00410 
00411 
00412 /*
00413  * operator(XprVector<E1, Sz>, XprVector<E2, Sz>)
00414  */
00415 #define TVMET_IMPLEMENT_MACRO(NAME, OP)                    \
00416 template<class E1, class E2, std::size_t Sz>                \
00417 inline                                    \
00418 XprVector<                                \
00419   XprBinOp<                                \
00420     Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,    \
00421     XprVector<E1, Sz>,                            \
00422     XprVector<E2, Sz>                            \
00423   >,                                    \
00424   Sz                                    \
00425 >                                    \
00426 operator OP (const XprVector<E1, Sz>& lhs,                 \
00427          const XprVector<E2, Sz>& rhs) {                \
00428   return NAME (lhs, rhs);                        \
00429 }
00430 
00431 TVMET_IMPLEMENT_MACRO(add, +)        // per se element wise
00432 TVMET_IMPLEMENT_MACRO(sub, -)        // per se element wise
00433 TVMET_IMPLEMENT_MACRO(mul, *)        // per se element wise
00434 namespace element_wise {
00435   TVMET_IMPLEMENT_MACRO(div, /)        // not defined for vectors
00436 }
00437 
00438 #undef TVMET_IMPLEMENT_MACRO
00439 
00440 
00441 /*
00442  * operator(XprVector<E, Sz>, POD)
00443  * operator(POD, XprVector<E, Sz>)
00444  * Note: operations +,-,*,/ are per se element wise
00445  */
00446 #define TVMET_IMPLEMENT_MACRO(NAME, OP, POD)        \
00447 template<class E, std::size_t Sz>            \
00448 inline                            \
00449 XprVector<                        \
00450   XprBinOp<                        \
00451     Fcnl_##NAME<typename E::value_type, POD >,        \
00452     XprVector<E, Sz>,                    \
00453     XprLiteral< POD >                    \
00454   >,                            \
00455   Sz                            \
00456 >                            \
00457 operator OP (const XprVector<E, Sz>& lhs, POD rhs) {    \
00458   return NAME (lhs, rhs);                \
00459 }                            \
00460                             \
00461 template<class E, std::size_t Sz>            \
00462 inline                            \
00463 XprVector<                        \
00464   XprBinOp<                        \
00465     Fcnl_##NAME< POD, typename E::value_type >,        \
00466     XprLiteral< POD >,                    \
00467     XprVector< E, Sz>                    \
00468   >,                            \
00469   Sz                            \
00470 >                            \
00471 operator OP (POD lhs, const XprVector<E, Sz>& rhs) {    \
00472   return NAME (lhs, rhs);                \
00473 }
00474 
00475 TVMET_IMPLEMENT_MACRO(add, +, int)
00476 TVMET_IMPLEMENT_MACRO(sub, -, int)
00477 TVMET_IMPLEMENT_MACRO(mul, *, int)
00478 TVMET_IMPLEMENT_MACRO(div, /, int)
00479 
00480 #if defined(TVMET_HAVE_LONG_LONG)
00481 TVMET_IMPLEMENT_MACRO(add, +, long long int)
00482 TVMET_IMPLEMENT_MACRO(sub, -, long long int)
00483 TVMET_IMPLEMENT_MACRO(mul, *, long long int)
00484 TVMET_IMPLEMENT_MACRO(div, /, long long int)
00485 #endif
00486 
00487 TVMET_IMPLEMENT_MACRO(add, +, float)
00488 TVMET_IMPLEMENT_MACRO(sub, -, float)
00489 TVMET_IMPLEMENT_MACRO(mul, *, float)
00490 TVMET_IMPLEMENT_MACRO(div, /, float)
00491 
00492 TVMET_IMPLEMENT_MACRO(add, +, double)
00493 TVMET_IMPLEMENT_MACRO(sub, -, double)
00494 TVMET_IMPLEMENT_MACRO(mul, *, double)
00495 TVMET_IMPLEMENT_MACRO(div, /, double)
00496 
00497 #if defined(TVMET_HAVE_LONG_DOUBLE)
00498 TVMET_IMPLEMENT_MACRO(add, +, long double)
00499 TVMET_IMPLEMENT_MACRO(sub, -, long double)
00500 TVMET_IMPLEMENT_MACRO(mul, *, long double)
00501 TVMET_IMPLEMENT_MACRO(div, /, long double)
00502 #endif
00503 
00504 #undef TVMET_IMPLEMENT_MACRO
00505 
00506 
00507 #if defined(TVMET_HAVE_COMPLEX)
00508 /*
00509  * operator(XprVector<E, Sz>, complex<T>)
00510  * operator(complex<T>, XprVector<E, Sz>)
00511  * Note: operations +,-,*,/ are per se element wise
00512  */
00513 #define TVMET_IMPLEMENT_MACRO(NAME, OP)                \
00514 template<class E, std::size_t Sz, class T>            \
00515 inline                                \
00516 XprVector<                            \
00517   XprBinOp<                            \
00518     Fcnl_##NAME<typename E::value_type, std::complex<T> >,    \
00519     XprVector<E, Sz>,                        \
00520     XprLiteral< std::complex<T> >                \
00521   >,                                \
00522   Sz                                \
00523 >                                \
00524 operator OP (const XprVector<E, Sz>& lhs,            \
00525          const std::complex<T>& rhs) {            \
00526   return NAME (lhs, rhs);                    \
00527 }                                \
00528                                 \
00529 template<class E, std::size_t Sz, class T>            \
00530 inline                                \
00531 XprVector<                            \
00532   XprBinOp<                            \
00533     Fcnl_##NAME< std::complex<T>, typename E::value_type >,    \
00534     XprLiteral< std::complex<T> >,                \
00535     XprVector< E, Sz>                        \
00536   >,                                \
00537   Sz                                \
00538 >                                \
00539 operator OP (const std::complex<T>& lhs,            \
00540          const XprVector<E, Sz>& rhs) {            \
00541   return NAME (lhs, rhs);                    \
00542 }
00543 
00544 TVMET_IMPLEMENT_MACRO(add, +)        // per se element wise
00545 TVMET_IMPLEMENT_MACRO(sub, -)        // per se element wise
00546 TVMET_IMPLEMENT_MACRO(mul, *)        // per se element wise
00547 TVMET_IMPLEMENT_MACRO(div, /)        // per se element wise
00548 
00549 #undef TVMET_IMPLEMENT_MACRO
00550 
00551 #endif // defined(TVMET_HAVE_COMPLEX)
00552 
00553 
00554 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00555  * Vector integer and compare operators
00556  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00557 
00558 
00559 /*
00560  * operator(XprVector, XprVector)
00561  */
00562 #define TVMET_IMPLEMENT_MACRO(NAME, OP)                    \
00563 template<class E1, class E2, std::size_t Sz>                \
00564 inline                                    \
00565 XprVector<                                \
00566   XprBinOp<                                \
00567     Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,    \
00568     XprVector<E1, Sz>,                            \
00569     XprVector<E2, Sz>                            \
00570   >,                                    \
00571   Sz                                    \
00572 >                                    \
00573 operator OP (const XprVector<E1, Sz>& lhs,                \
00574          const XprVector<E2, Sz>& rhs) {                \
00575   typedef XprBinOp<                            \
00576     Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,    \
00577     XprVector<E1, Sz>,                            \
00578     XprVector<E2, Sz>                            \
00579   >                                expr_type;    \
00580   return XprVector<expr_type, Sz>(expr_type(lhs, rhs));            \
00581 }
00582 
00583 // integer operators only, e.g used on double you wil get an error
00584 namespace element_wise {
00585   TVMET_IMPLEMENT_MACRO(mod, %)
00586   TVMET_IMPLEMENT_MACRO(bitxor, ^)
00587   TVMET_IMPLEMENT_MACRO(bitand, &)
00588   TVMET_IMPLEMENT_MACRO(bitor, |)
00589   TVMET_IMPLEMENT_MACRO(shl, <<)
00590   TVMET_IMPLEMENT_MACRO(shr, >>)
00591 }
00592 
00593 // necessary operators for eval functions
00594 TVMET_IMPLEMENT_MACRO(greater, >)
00595 TVMET_IMPLEMENT_MACRO(less, <)
00596 TVMET_IMPLEMENT_MACRO(greater_eq, >=)
00597 TVMET_IMPLEMENT_MACRO(less_eq, <=)
00598 TVMET_IMPLEMENT_MACRO(eq, ==)
00599 TVMET_IMPLEMENT_MACRO(not_eq, !=)
00600 TVMET_IMPLEMENT_MACRO(and, &&)
00601 TVMET_IMPLEMENT_MACRO(or, ||)
00602 
00603 #undef TVMET_IMPLEMENT_MACRO
00604 
00605 
00606 /*
00607  * operator(Vector<T, Sz>, POD)
00608  * operator(POD, Vector<T, Sz>)
00609  * Note: operations are per se element_wise
00610  */
00611 #define TVMET_IMPLEMENT_MACRO(NAME, OP, TP)                \
00612 template<class E, std::size_t Sz>                    \
00613 inline                                    \
00614 XprVector<                                \
00615   XprBinOp<                                \
00616     Fcnl_##NAME<typename E::value_type, TP >,                \
00617     XprVector<E, Sz>,                            \
00618     XprLiteral< TP >                            \
00619   >,                                    \
00620   Sz                                    \
00621 >                                    \
00622 operator OP (const XprVector<E, Sz>& lhs, TP rhs) {            \
00623   typedef XprBinOp<                            \
00624     Fcnl_##NAME<typename E::value_type, TP >,                \
00625     XprVector<E, Sz>,                            \
00626     XprLiteral< TP >                            \
00627   >                            expr_type;    \
00628   return XprVector<expr_type, Sz>(                    \
00629     expr_type(lhs, XprLiteral< TP >(rhs)));                \
00630 }                                    \
00631                                     \
00632 template<class E, std::size_t Sz>                    \
00633 inline                                    \
00634 XprVector<                                \
00635   XprBinOp<                                \
00636     Fcnl_##NAME<TP, typename E::value_type>,                \
00637     XprLiteral< TP >,                            \
00638     XprVector<E, Sz>                            \
00639   >,                                    \
00640   Sz                                    \
00641 >                                    \
00642 operator OP (TP lhs, const XprVector<E, Sz>& rhs) {            \
00643   typedef XprBinOp<                            \
00644     Fcnl_##NAME< TP, typename E::value_type>,                \
00645     XprLiteral< TP >,                            \
00646     XprVector<E, Sz>                            \
00647   >                            expr_type;    \
00648   return XprVector<expr_type, Sz>(                    \
00649     expr_type(XprLiteral< TP >(lhs), rhs));                \
00650 }
00651 
00652 // integer operators only, e.g used on double you wil get an error
00653 namespace element_wise {
00654   TVMET_IMPLEMENT_MACRO(mod, %, int)
00655   TVMET_IMPLEMENT_MACRO(bitxor, ^, int)
00656   TVMET_IMPLEMENT_MACRO(bitand, &, int)
00657   TVMET_IMPLEMENT_MACRO(bitor, |, int)
00658   TVMET_IMPLEMENT_MACRO(shl, <<, int)
00659   TVMET_IMPLEMENT_MACRO(shr, >>, int)
00660 }
00661 
00662 // necessary operators for eval functions
00663 TVMET_IMPLEMENT_MACRO(greater, >, int)
00664 TVMET_IMPLEMENT_MACRO(less, <, int)
00665 TVMET_IMPLEMENT_MACRO(greater_eq, >=, int)
00666 TVMET_IMPLEMENT_MACRO(less_eq, <=, int)
00667 TVMET_IMPLEMENT_MACRO(eq, ==, int)
00668 TVMET_IMPLEMENT_MACRO(not_eq, !=, int)
00669 TVMET_IMPLEMENT_MACRO(and, &&, int)
00670 TVMET_IMPLEMENT_MACRO(or, ||, int)
00671 
00672 
00673 #if defined(TVMET_HAVE_LONG_LONG)
00674 // integer operators only
00675 namespace element_wise {
00676   TVMET_IMPLEMENT_MACRO(mod, %, long long int)
00677   TVMET_IMPLEMENT_MACRO(bitxor, ^, long long int)
00678   TVMET_IMPLEMENT_MACRO(bitand, &, long long int)
00679   TVMET_IMPLEMENT_MACRO(bitor, |, long long int)
00680   TVMET_IMPLEMENT_MACRO(shl, <<, long long int)
00681   TVMET_IMPLEMENT_MACRO(shr, >>, long long int)
00682 }
00683 
00684 // necessary operators for eval functions
00685 TVMET_IMPLEMENT_MACRO(greater, >, long long int)
00686 TVMET_IMPLEMENT_MACRO(less, <, long long int)
00687 TVMET_IMPLEMENT_MACRO(greater_eq, >=, long long int)
00688 TVMET_IMPLEMENT_MACRO(less_eq, <=, long long int)
00689 TVMET_IMPLEMENT_MACRO(eq, ==, long long int)
00690 TVMET_IMPLEMENT_MACRO(not_eq, !=, long long int)
00691 TVMET_IMPLEMENT_MACRO(and, &&, long long int)
00692 TVMET_IMPLEMENT_MACRO(or, ||, long long int)
00693 #endif // defined(TVMET_HAVE_LONG_LONG)
00694 
00695 // necessary operators for eval functions
00696 TVMET_IMPLEMENT_MACRO(greater, >, float)
00697 TVMET_IMPLEMENT_MACRO(less, <, float)
00698 TVMET_IMPLEMENT_MACRO(greater_eq, >=, float)
00699 TVMET_IMPLEMENT_MACRO(less_eq, <=, float)
00700 TVMET_IMPLEMENT_MACRO(eq, ==, float)
00701 TVMET_IMPLEMENT_MACRO(not_eq, !=, float)
00702 
00703 // necessary operators for eval functions
00704 TVMET_IMPLEMENT_MACRO(greater, >, double)
00705 TVMET_IMPLEMENT_MACRO(less, <, double)
00706 TVMET_IMPLEMENT_MACRO(greater_eq, >=, double)
00707 TVMET_IMPLEMENT_MACRO(less_eq, <=, double)
00708 TVMET_IMPLEMENT_MACRO(eq, ==, double)
00709 TVMET_IMPLEMENT_MACRO(not_eq, !=, double)
00710 
00711 #if defined(TVMET_HAVE_LONG_DOUBLE)
00712 // necessary operators for eval functions
00713 TVMET_IMPLEMENT_MACRO(greater, >, long double)
00714 TVMET_IMPLEMENT_MACRO(less, <, long double)
00715 TVMET_IMPLEMENT_MACRO(greater_eq, >=, long double)
00716 TVMET_IMPLEMENT_MACRO(less_eq, <=, long double)
00717 TVMET_IMPLEMENT_MACRO(eq, ==, long double)
00718 TVMET_IMPLEMENT_MACRO(not_eq, !=, long double)
00719 #endif // defined(TVMET_HAVE_LONG_DOUBLE)
00720 
00721 #undef TVMET_IMPLEMENT_MACRO
00722 
00723 
00724 #if defined(TVMET_HAVE_COMPLEX)
00725 /*
00726  * operator(Vector<std::complex<T>, Sz>, std::complex<T>)
00727  * operator(std::complex<T>, Vector<std::complex<T>, Sz>)
00728  * Note: - per se element wise
00729  *       - bit ops on complex<int> doesn't make sense, stay away
00730  * \todo type promotion
00731  */
00732 #define TVMET_IMPLEMENT_MACRO(NAME, OP)                    \
00733 template<class E, std::size_t Sz, class T>                \
00734 inline                                    \
00735 XprVector<                                \
00736   XprBinOp<                                \
00737     Fcnl_##NAME<typename E::value_type, std::complex<T> >,        \
00738     XprVector<E, Sz>,                            \
00739     XprLiteral< std::complex<T> >                    \
00740   >,                                    \
00741   Sz                                    \
00742 >                                    \
00743 operator OP (const XprVector<E, Sz>& lhs,                \
00744          const std::complex<T>& rhs) {                \
00745   typedef XprBinOp<                            \
00746     Fcnl_##NAME<typename E::value_type, std::complex<T> >,        \
00747     XprVector<E, Sz>,                            \
00748     XprLiteral< std::complex<T> >                    \
00749   >                            expr_type;    \
00750   return XprVector<expr_type, Sz>(                    \
00751     expr_type(lhs, XprLiteral< std::complex<T> >(rhs)));        \
00752 }                                    \
00753                                     \
00754 template<class E, std::size_t Sz, class T>                \
00755 inline                                    \
00756 XprVector<                                \
00757   XprBinOp<                                \
00758     Fcnl_##NAME<std::complex<T>, typename E::value_type>,        \
00759     XprLiteral< std::complex<T> >,                    \
00760     XprVector<E, Sz>                            \
00761   >,                                    \
00762   Sz                                    \
00763 >                                    \
00764 operator OP (const std::complex<T>& lhs,                \
00765          const XprVector<E, Sz>& rhs) {                \
00766   typedef XprBinOp<                            \
00767     Fcnl_##NAME< std::complex<T>, typename E::value_type>,        \
00768     XprLiteral< std::complex<T> >,                    \
00769     XprVector<E, Sz>                            \
00770   >                            expr_type;    \
00771   return XprVector<expr_type, Sz>(                    \
00772     expr_type(XprLiteral< std::complex<T> >(lhs), rhs));        \
00773 }
00774 
00775 // necessary operators for eval functions
00776 TVMET_IMPLEMENT_MACRO(greater, >)
00777 TVMET_IMPLEMENT_MACRO(less, <)
00778 TVMET_IMPLEMENT_MACRO(greater_eq, >=)
00779 TVMET_IMPLEMENT_MACRO(less_eq, <=)
00780 TVMET_IMPLEMENT_MACRO(eq, ==)
00781 TVMET_IMPLEMENT_MACRO(not_eq, !=)
00782 TVMET_IMPLEMENT_MACRO(and, &&)
00783 TVMET_IMPLEMENT_MACRO(or, ||)
00784 
00785 #undef TVMET_IMPLEMENT_MACRO
00786 
00787 #endif // defined(TVMET_HAVE_COMPLEX)
00788 
00789 
00790 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00791  * global unary operators
00792  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00793 
00794 
00795 /*
00796  * Unary Operator on XprVector<E, Sz>
00797  */
00798 #define TVMET_IMPLEMENT_MACRO(NAME, OP)                    \
00799 template <class E, std::size_t Sz>                    \
00800 inline                                    \
00801 XprVector<                                \
00802   XprUnOp<                                \
00803     Fcnl_##NAME<typename E::value_type>,                \
00804     XprVector<E, Sz>                            \
00805   >,                                    \
00806   Sz                                    \
00807 >                                    \
00808 operator OP (const XprVector<E, Sz>& rhs) {                \
00809   typedef XprUnOp<                            \
00810     Fcnl_##NAME<typename E::value_type>,                \
00811     XprVector<E, Sz>                            \
00812   >                               expr_type;    \
00813   return XprVector<expr_type, Sz>(expr_type(rhs));            \
00814 }
00815 
00816 TVMET_IMPLEMENT_MACRO(not, !)
00817 TVMET_IMPLEMENT_MACRO(compl, ~)
00818 TVMET_IMPLEMENT_MACRO(neg, -)
00819 
00820 #undef TVMET_IMPLEMENT_MACRO
00821 
00822 
00823 } // namespace tvmet
00824 
00825 #endif // TVMET_XPR_VECTOR_OPERATORS_H
00826 
00827 // Local Variables:
00828 // mode:C++
00829 // tab-width:8
00830 // End: