SourceForge Logo Tiny Vector Matrix library using Expression Templates Sourceforge Project Page

include/tvmet/xpr/VectorOperators.h

Go to the documentation of this file.
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:

Author: