Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of Eurobot_2012_Secondary by
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.18 2007-06-23 15:58:58 opetzold Exp $ 00022 */ 00023 00024 #ifndef TVMET_VECTOR_OPERATORS_H 00025 #define TVMET_VECTOR_OPERATORS_H 00026 00027 namespace tvmet { 00028 00029 00030 /********************************************************* 00031 * PART I: DECLARATION 00032 *********************************************************/ 00033 00034 00035 template<class T, std::size_t Sz> 00036 inline 00037 std::ostream& operator<<(std::ostream& os, 00038 const Vector<T, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE; 00039 00040 00041 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00042 * Member operators (arithmetic and bit ops) 00043 *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 00044 00045 00046 /* 00047 * update_operator(Vector<T1, Sz>, Vector<T2, Sz>) 00048 * update_operator(Vector<T1, Sz>, XprVector<E, Sz>) 00049 * Note: per se element wise 00050 */ 00051 #define TVMET_DECLARE_MACRO(NAME, OP) \ 00052 template<class T1, class T2, std::size_t Sz> \ 00053 Vector<T1, Sz>& \ 00054 operator OP (Vector<T1, Sz>& lhs, \ 00055 const Vector<T2, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE; \ 00056 \ 00057 template<class T, class E, std::size_t Sz> \ 00058 Vector<T, Sz>& \ 00059 operator OP (Vector<T, Sz>& lhs, \ 00060 const XprVector<E, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE; 00061 00062 TVMET_DECLARE_MACRO(add_eq, +=) // per se element wise 00063 TVMET_DECLARE_MACRO(sub_eq, -=) // per se element wise 00064 TVMET_DECLARE_MACRO(mul_eq, *=) // per se element wise 00065 namespace element_wise { 00066 TVMET_DECLARE_MACRO(div_eq, /=) // not defined for vectors 00067 } 00068 00069 // integer operators only, e.g used on double you wil get an error 00070 namespace element_wise { 00071 TVMET_DECLARE_MACRO(mod_eq, %=) 00072 TVMET_DECLARE_MACRO(xor_eq, ^=) 00073 TVMET_DECLARE_MACRO(and_eq, &=) 00074 TVMET_DECLARE_MACRO(or_eq, |=) 00075 TVMET_DECLARE_MACRO(shl_eq, <<=) 00076 TVMET_DECLARE_MACRO(shr_eq, >>=) 00077 } 00078 00079 #undef TVMET_DECLARE_MACRO 00080 00081 00082 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00083 * Vector arithmetic operators implemented by functions 00084 * add, sub, mul and div 00085 *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 00086 00087 00088 /* 00089 * operator(Vector<T1, Sz>, Vector<T2, Sz>) 00090 * operator(Vector<T1, Sz>, XprVector<E, Sz>) 00091 * operator(XprVector<E, Sz>, Vector<T1, Sz>) 00092 */ 00093 #define TVMET_DECLARE_MACRO(NAME, OP) \ 00094 template<class T1, class T2, std::size_t Sz> \ 00095 XprVector< \ 00096 XprBinOp< \ 00097 Fcnl_##NAME<T1, T2>, \ 00098 VectorConstReference<T1, Sz>, \ 00099 VectorConstReference<T2, Sz> \ 00100 >, \ 00101 Sz \ 00102 > \ 00103 operator OP (const Vector<T1, Sz>& lhs, \ 00104 const Vector<T2, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE; \ 00105 \ 00106 template<class E, class T, std::size_t Sz> \ 00107 XprVector< \ 00108 XprBinOp< \ 00109 Fcnl_##NAME<typename E::value_type, T>, \ 00110 XprVector<E, Sz>, \ 00111 VectorConstReference<T, Sz> \ 00112 >, \ 00113 Sz \ 00114 > \ 00115 operator OP (const XprVector<E, Sz>& lhs, \ 00116 const Vector<T, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE; \ 00117 \ 00118 template<class E, class T, std::size_t Sz> \ 00119 XprVector< \ 00120 XprBinOp< \ 00121 Fcnl_##NAME<T, typename E::value_type>, \ 00122 VectorConstReference<T, Sz>, \ 00123 XprVector<E, Sz> \ 00124 >, \ 00125 Sz \ 00126 > \ 00127 operator OP (const Vector<T, Sz>& lhs, \ 00128 const XprVector<E, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE; 00129 00130 TVMET_DECLARE_MACRO(add, +) // per se element wise 00131 TVMET_DECLARE_MACRO(sub, -) // per se element wise 00132 TVMET_DECLARE_MACRO(mul, *) // per se element wise 00133 namespace element_wise { 00134 TVMET_DECLARE_MACRO(div, /) // not defined for vectors 00135 } 00136 00137 #undef TVMET_DECLARE_MACRO 00138 00139 00140 /* 00141 * operator(Vector<T, Sz>, POD) 00142 * operator(POD, Vector<T, Sz>) 00143 * Note: operations +,-,*,/ are per se element wise 00144 */ 00145 #define TVMET_DECLARE_MACRO(NAME, OP, POD) \ 00146 template<class T, std::size_t Sz> \ 00147 XprVector< \ 00148 XprBinOp< \ 00149 Fcnl_##NAME< T, POD >, \ 00150 VectorConstReference<T, Sz>, \ 00151 XprLiteral< POD > \ 00152 >, \ 00153 Sz \ 00154 > \ 00155 operator OP (const Vector<T, Sz>& lhs, \ 00156 POD rhs) TVMET_CXX_ALWAYS_INLINE; \ 00157 \ 00158 template<class T, std::size_t Sz> \ 00159 XprVector< \ 00160 XprBinOp< \ 00161 Fcnl_##NAME< POD, T>, \ 00162 XprLiteral< POD >, \ 00163 VectorConstReference<T, Sz> \ 00164 >, \ 00165 Sz \ 00166 > \ 00167 operator OP (POD lhs, \ 00168 const Vector<T, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE; 00169 00170 TVMET_DECLARE_MACRO(add, +, int) 00171 TVMET_DECLARE_MACRO(sub, -, int) 00172 TVMET_DECLARE_MACRO(mul, *, int) 00173 TVMET_DECLARE_MACRO(div, /, int) 00174 00175 #if defined(TVMET_HAVE_LONG_LONG) 00176 TVMET_DECLARE_MACRO(add, +, long long int) 00177 TVMET_DECLARE_MACRO(sub, -, long long int) 00178 TVMET_DECLARE_MACRO(mul, *, long long int) 00179 TVMET_DECLARE_MACRO(div, /, long long int) 00180 #endif 00181 00182 TVMET_DECLARE_MACRO(add, +, float) 00183 TVMET_DECLARE_MACRO(sub, -, float) 00184 TVMET_DECLARE_MACRO(mul, *, float) 00185 TVMET_DECLARE_MACRO(div, /, float) 00186 00187 TVMET_DECLARE_MACRO(add, +, double) 00188 TVMET_DECLARE_MACRO(sub, -, double) 00189 TVMET_DECLARE_MACRO(mul, *, double) 00190 TVMET_DECLARE_MACRO(div, /, double) 00191 00192 #if defined(TVMET_HAVE_LONG_DOUBLE) 00193 TVMET_DECLARE_MACRO(add, +, long double) 00194 TVMET_DECLARE_MACRO(sub, -, long double) 00195 TVMET_DECLARE_MACRO(mul, *, long double) 00196 TVMET_DECLARE_MACRO(div, /, long double) 00197 #endif 00198 00199 #undef TVMET_DECLARE_MACRO 00200 00201 00202 #if defined(TVMET_HAVE_COMPLEX) 00203 /* 00204 * operator(Vector<std::complex<T>, Sz>, std::complex<T>) 00205 * operator(std::complex<T>, Vector<std::complex<T>, Sz>) 00206 * Note: operations +,-,*,/ are per se element wise 00207 * \todo type promotion 00208 */ 00209 #define TVMET_DECLARE_MACRO(NAME, OP) \ 00210 template<class T, std::size_t Sz> \ 00211 XprVector< \ 00212 XprBinOp< \ 00213 Fcnl_##NAME< std::complex<T>, std::complex<T> >, \ 00214 VectorConstReference< std::complex<T>, Sz>, \ 00215 XprLiteral< std::complex<T> > \ 00216 >, \ 00217 Sz \ 00218 > \ 00219 operator OP (const Vector<std::complex<T>, Sz>& lhs, \ 00220 const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE; \ 00221 \ 00222 template<class T, std::size_t Sz> \ 00223 XprVector< \ 00224 XprBinOp< \ 00225 Fcnl_##NAME< std::complex<T>, std::complex<T> >, \ 00226 XprLiteral< std::complex<T> >, \ 00227 VectorConstReference< std::complex<T>, Sz> \ 00228 >, \ 00229 Sz \ 00230 > \ 00231 operator OP (const std::complex<T>& lhs, \ 00232 const Vector< std::complex<T>, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE; 00233 00234 TVMET_DECLARE_MACRO(add, +) // per se element wise 00235 TVMET_DECLARE_MACRO(sub, -) // per se element wise 00236 TVMET_DECLARE_MACRO(mul, *) // per se element wise 00237 TVMET_DECLARE_MACRO(div, /) // per se element wise 00238 #undef TVMET_DECLARE_MACRO 00239 00240 #endif // defined(TVMET_HAVE_COMPLEX) 00241 00242 00243 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00244 * Vector integer and compare operators 00245 *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 00246 00247 00248 /* 00249 * operator(Vector<T1, Sz>, Vector<T2, Sz>) 00250 * operator(XprVector<E, Sz>, Vector<T, Sz>) 00251 * operator(Vector<T, Sz>, XprVector<E, Sz>) 00252 * Note: operations are per se element wise 00253 */ 00254 #define TVMET_DECLARE_MACRO(NAME, OP) \ 00255 template<class T1, class T2, std::size_t Sz> \ 00256 XprVector< \ 00257 XprBinOp< \ 00258 Fcnl_##NAME<T1, T2>, \ 00259 VectorConstReference<T1, Sz>, \ 00260 VectorConstReference<T2, Sz> \ 00261 >, \ 00262 Sz \ 00263 > \ 00264 operator OP (const Vector<T1, Sz>& lhs, \ 00265 const Vector<T2, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE; \ 00266 \ 00267 template<class E, class T, std::size_t Sz> \ 00268 XprVector< \ 00269 XprBinOp< \ 00270 Fcnl_##NAME<typename E::value_type, T>, \ 00271 XprVector<E, Sz>, \ 00272 VectorConstReference<T, Sz> \ 00273 >, \ 00274 Sz \ 00275 > \ 00276 operator OP (const XprVector<E, Sz>& lhs, \ 00277 const Vector<T, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE; \ 00278 \ 00279 template<class E, class T, std::size_t Sz> \ 00280 XprVector< \ 00281 XprBinOp< \ 00282 Fcnl_##NAME<T, typename E::value_type>, \ 00283 VectorConstReference<T, Sz>, \ 00284 XprVector<E, Sz> \ 00285 >, \ 00286 Sz \ 00287 > \ 00288 operator OP (const Vector<T, Sz>& lhs, \ 00289 const XprVector<E, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE; 00290 00291 // integer operators only, e.g used on double you wil get an error 00292 namespace element_wise { 00293 TVMET_DECLARE_MACRO(mod, %) 00294 TVMET_DECLARE_MACRO(bitxor, ^) 00295 TVMET_DECLARE_MACRO(bitand, &) 00296 TVMET_DECLARE_MACRO(bitor, |) 00297 TVMET_DECLARE_MACRO(shl, <<) 00298 TVMET_DECLARE_MACRO(shr, >>) 00299 } 00300 00301 // necessary operators for eval functions 00302 TVMET_DECLARE_MACRO(greater, >) 00303 TVMET_DECLARE_MACRO(less, <) 00304 TVMET_DECLARE_MACRO(greater_eq, >=) 00305 TVMET_DECLARE_MACRO(less_eq, <=) 00306 TVMET_DECLARE_MACRO(eq, ==) 00307 TVMET_DECLARE_MACRO(not_eq, !=) 00308 TVMET_DECLARE_MACRO(and, &&) 00309 TVMET_DECLARE_MACRO(or, ||) 00310 00311 #undef TVMET_DECLARE_MACRO 00312 00313 00314 00315 #if defined(TVMET_HAVE_COMPLEX) 00316 /* 00317 * operator(Vector<std::complex<T>, Sz>, std::complex<T>) 00318 * operator(std::complex<T>, Vector<std::complex<T>, Sz>) 00319 * Note: - per se element wise 00320 * - bit ops on complex<int> doesn't make sense, stay away 00321 * \todo type promotion 00322 */ 00323 #define TVMET_DECLARE_MACRO(NAME, OP) \ 00324 template<class T, std::size_t Sz> \ 00325 XprVector< \ 00326 XprBinOp< \ 00327 Fcnl_##NAME< std::complex<T>, std::complex<T> >, \ 00328 VectorConstReference< std::complex<T>, Sz>, \ 00329 XprLiteral< std::complex<T> > \ 00330 >, \ 00331 Sz \ 00332 > \ 00333 operator OP (const Vector<std::complex<T>, Sz>& lhs, \ 00334 const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE; \ 00335 \ 00336 template<class T, std::size_t Sz> \ 00337 XprVector< \ 00338 XprBinOp< \ 00339 Fcnl_##NAME< std::complex<T>, std::complex<T> >, \ 00340 XprLiteral< std::complex<T> >, \ 00341 VectorConstReference< std::complex<T>, Sz> \ 00342 >, \ 00343 Sz \ 00344 > \ 00345 operator OP (const std::complex<T>& lhs, \ 00346 const Vector< std::complex<T>, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE; 00347 00348 // necessary operators for eval functions 00349 TVMET_DECLARE_MACRO(greater, >) 00350 TVMET_DECLARE_MACRO(less, <) 00351 TVMET_DECLARE_MACRO(greater_eq, >=) 00352 TVMET_DECLARE_MACRO(less_eq, <=) 00353 TVMET_DECLARE_MACRO(eq, ==) 00354 TVMET_DECLARE_MACRO(not_eq, !=) 00355 TVMET_DECLARE_MACRO(and, &&) 00356 TVMET_DECLARE_MACRO(or, ||) 00357 00358 #undef TVMET_DECLARE_MACRO 00359 00360 #endif // defined(TVMET_HAVE_COMPLEX) 00361 00362 00363 /* 00364 * operator(Vector<T, Sz>, POD) 00365 * operator(POD, Vector<T, Sz>) 00366 * Note: operations are per se element_wise 00367 */ 00368 #define TVMET_DECLARE_MACRO(NAME, OP, TP) \ 00369 template<class T, std::size_t Sz> \ 00370 XprVector< \ 00371 XprBinOp< \ 00372 Fcnl_##NAME< T, TP >, \ 00373 VectorConstReference<T, Sz>, \ 00374 XprLiteral< TP > \ 00375 >, \ 00376 Sz \ 00377 > \ 00378 operator OP (const Vector<T, Sz>& lhs, TP rhs) TVMET_CXX_ALWAYS_INLINE; \ 00379 \ 00380 template<class T, std::size_t Sz> \ 00381 XprVector< \ 00382 XprBinOp< \ 00383 Fcnl_##NAME< TP, T>, \ 00384 XprLiteral< TP >, \ 00385 VectorConstReference<T, Sz> \ 00386 >, \ 00387 Sz \ 00388 > \ 00389 operator OP (TP lhs, const Vector<T, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE; 00390 00391 // integer operators only, e.g used on double you wil get an error 00392 namespace element_wise { 00393 TVMET_DECLARE_MACRO(mod, %, int) 00394 TVMET_DECLARE_MACRO(bitxor, ^, int) 00395 TVMET_DECLARE_MACRO(bitand, &, int) 00396 TVMET_DECLARE_MACRO(bitor, |, int) 00397 TVMET_DECLARE_MACRO(shl, <<, int) 00398 TVMET_DECLARE_MACRO(shr, >>, int) 00399 } 00400 00401 // necessary operators for eval functions 00402 TVMET_DECLARE_MACRO(greater, >, int) 00403 TVMET_DECLARE_MACRO(less, <, int) 00404 TVMET_DECLARE_MACRO(greater_eq, >=, int) 00405 TVMET_DECLARE_MACRO(less_eq, <=, int) 00406 TVMET_DECLARE_MACRO(eq, ==, int) 00407 TVMET_DECLARE_MACRO(not_eq, !=, int) 00408 TVMET_DECLARE_MACRO(and, &&, int) 00409 TVMET_DECLARE_MACRO(or, ||, int) 00410 00411 #if defined(TVMET_HAVE_LONG_LONG) 00412 // integer operators only 00413 namespace element_wise { 00414 TVMET_DECLARE_MACRO(mod, %, long long int) 00415 TVMET_DECLARE_MACRO(bitxor, ^, long long int) 00416 TVMET_DECLARE_MACRO(bitand, &, long long int) 00417 TVMET_DECLARE_MACRO(bitor, |, long long int) 00418 TVMET_DECLARE_MACRO(shl, <<, long long int) 00419 TVMET_DECLARE_MACRO(shr, >>, long long int) 00420 } 00421 00422 // necessary operators for eval functions 00423 TVMET_DECLARE_MACRO(greater, >, long long int) 00424 TVMET_DECLARE_MACRO(less, <, long long int) 00425 TVMET_DECLARE_MACRO(greater_eq, >=, long long int) 00426 TVMET_DECLARE_MACRO(less_eq, <=, long long int) 00427 TVMET_DECLARE_MACRO(eq, ==, long long int) 00428 TVMET_DECLARE_MACRO(not_eq, !=, long long int) 00429 TVMET_DECLARE_MACRO(and, &&, long long int) 00430 TVMET_DECLARE_MACRO(or, ||, long long int) 00431 #endif // defined(TVMET_HAVE_LONG_LONG) 00432 00433 // necessary operators for eval functions 00434 TVMET_DECLARE_MACRO(greater, >, float) 00435 TVMET_DECLARE_MACRO(less, <, float) 00436 TVMET_DECLARE_MACRO(greater_eq, >=, float) 00437 TVMET_DECLARE_MACRO(less_eq, <=, float) 00438 TVMET_DECLARE_MACRO(eq, ==, float) 00439 TVMET_DECLARE_MACRO(not_eq, !=, float) 00440 TVMET_DECLARE_MACRO(and, &&, float) 00441 TVMET_DECLARE_MACRO(or, ||, float) 00442 00443 // necessary operators for eval functions 00444 TVMET_DECLARE_MACRO(greater, >, double) 00445 TVMET_DECLARE_MACRO(less, <, double) 00446 TVMET_DECLARE_MACRO(greater_eq, >=, double) 00447 TVMET_DECLARE_MACRO(less_eq, <=, double) 00448 TVMET_DECLARE_MACRO(eq, ==, double) 00449 TVMET_DECLARE_MACRO(not_eq, !=, double) 00450 TVMET_DECLARE_MACRO(and, &&, double) 00451 TVMET_DECLARE_MACRO(or, ||, double) 00452 00453 #if defined(TVMET_HAVE_LONG_DOUBLE) 00454 // necessary operators for eval functions 00455 TVMET_DECLARE_MACRO(greater, >, long double) 00456 TVMET_DECLARE_MACRO(less, <, long double) 00457 TVMET_DECLARE_MACRO(greater_eq, >=, long double) 00458 TVMET_DECLARE_MACRO(less_eq, <=, long double) 00459 TVMET_DECLARE_MACRO(eq, ==, long double) 00460 TVMET_DECLARE_MACRO(not_eq, !=, long double) 00461 TVMET_DECLARE_MACRO(and, &&, long double) 00462 TVMET_DECLARE_MACRO(or, ||, long double) 00463 #endif // defined(TVMET_HAVE_LONG_DOUBLE) 00464 00465 #undef TVMET_DECLARE_MACRO 00466 00467 00468 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00469 * global unary operators 00470 *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 00471 00472 00473 /* 00474 * unary_operator(Vector<T, Sz>) 00475 * Note: per se element wise 00476 */ 00477 #define TVMET_DECLARE_MACRO(NAME, OP) \ 00478 template <class T, std::size_t Sz> \ 00479 XprVector< \ 00480 XprUnOp< \ 00481 Fcnl_##NAME<T>, \ 00482 VectorConstReference<T, Sz> \ 00483 >, \ 00484 Sz \ 00485 > \ 00486 operator OP (const Vector<T, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE; 00487 00488 TVMET_DECLARE_MACRO(not, !) 00489 TVMET_DECLARE_MACRO(compl, ~) 00490 TVMET_DECLARE_MACRO(neg, -) 00491 #undef TVMET_DECLARE_MACRO 00492 00493 00494 /********************************************************* 00495 * PART II: IMPLEMENTATION 00496 *********************************************************/ 00497 00498 00499 /** 00500 * \fn operator<<(std::ostream& os, const Vector<T, Sz>& rhs) 00501 * \brief Overload operator for i/o 00502 * \ingroup _binary_operator 00503 */ 00504 template<class T, std::size_t Sz> 00505 inline 00506 std::ostream& operator<<(std::ostream& os, const Vector<T, Sz>& rhs) { 00507 return rhs.print_on(os); 00508 } 00509 00510 00511 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00512 * Member operators (arithmetic and bit ops) 00513 *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 00514 00515 00516 /* 00517 * update_operator(Vector<T1, Sz>, Vector<T2, Sz>) 00518 * update_operator(Vector<T1, Sz>, XprVector<E, Sz>) 00519 * Note: per se element wise 00520 */ 00521 #define TVMET_IMPLEMENT_MACRO(NAME, OP) \ 00522 template<class T1, class T2, std::size_t Sz> \ 00523 inline Vector<T1, Sz>& \ 00524 operator OP (Vector<T1, Sz>& lhs, const Vector<T2, Sz>& rhs) { \ 00525 return lhs.M_##NAME(rhs); \ 00526 } \ 00527 \ 00528 template<class T, class E, std::size_t Sz> \ 00529 inline Vector<T, Sz>& \ 00530 operator OP (Vector<T, Sz>& lhs, const XprVector<E, Sz>& rhs) { \ 00531 return lhs.M_##NAME(rhs); \ 00532 } 00533 00534 TVMET_IMPLEMENT_MACRO(add_eq, +=) // per se element wise 00535 TVMET_IMPLEMENT_MACRO(sub_eq, -=) // per se element wise 00536 TVMET_IMPLEMENT_MACRO(mul_eq, *=) // per se element wise 00537 namespace element_wise { 00538 TVMET_IMPLEMENT_MACRO(div_eq, /=) // not defined for vectors 00539 } 00540 00541 // integer operators only, e.g used on double you wil get an error 00542 namespace element_wise { 00543 TVMET_IMPLEMENT_MACRO(mod_eq, %=) 00544 TVMET_IMPLEMENT_MACRO(xor_eq, ^=) 00545 TVMET_IMPLEMENT_MACRO(and_eq, &=) 00546 TVMET_IMPLEMENT_MACRO(or_eq, |=) 00547 TVMET_IMPLEMENT_MACRO(shl_eq, <<=) 00548 TVMET_IMPLEMENT_MACRO(shr_eq, >>=) 00549 } 00550 00551 #undef TVMET_IMPLEMENT_MACRO 00552 00553 00554 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00555 * Vector arithmetic operators implemented by functions 00556 * add, sub, mul and div 00557 *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 00558 00559 00560 /* 00561 * operator(Vector<T1, Sz>, Vector<T2, Sz>) 00562 * operator(Vector<T1, Sz>, XprVector<E, Sz>) 00563 * operator(XprVector<E, Sz>, Vector<T1, Sz>) 00564 */ 00565 #define TVMET_IMPLEMENT_MACRO(NAME, OP) \ 00566 template<class T1, class T2, std::size_t Sz> \ 00567 inline \ 00568 XprVector< \ 00569 XprBinOp< \ 00570 Fcnl_##NAME<T1, T2>, \ 00571 VectorConstReference<T1, Sz>, \ 00572 VectorConstReference<T2, Sz> \ 00573 >, \ 00574 Sz \ 00575 > \ 00576 operator OP (const Vector<T1, Sz>& lhs, const Vector<T2, Sz>& rhs) { \ 00577 return NAME (lhs, rhs); \ 00578 } \ 00579 \ 00580 template<class E, class T, std::size_t Sz> \ 00581 inline \ 00582 XprVector< \ 00583 XprBinOp< \ 00584 Fcnl_##NAME<typename E::value_type, T>, \ 00585 XprVector<E, Sz>, \ 00586 VectorConstReference<T, Sz> \ 00587 >, \ 00588 Sz \ 00589 > \ 00590 operator OP (const XprVector<E, Sz>& lhs, const Vector<T, Sz>& rhs) { \ 00591 return NAME (lhs, rhs); \ 00592 } \ 00593 \ 00594 template<class E, class T, std::size_t Sz> \ 00595 inline \ 00596 XprVector< \ 00597 XprBinOp< \ 00598 Fcnl_##NAME<T, typename E::value_type>, \ 00599 VectorConstReference<T, Sz>, \ 00600 XprVector<E, Sz> \ 00601 >, \ 00602 Sz \ 00603 > \ 00604 operator OP (const Vector<T, Sz>& lhs, const XprVector<E, Sz>& rhs) { \ 00605 return NAME (lhs, rhs); \ 00606 } 00607 00608 TVMET_IMPLEMENT_MACRO(add, +) // per se element wise 00609 TVMET_IMPLEMENT_MACRO(sub, -) // per se element wise 00610 TVMET_IMPLEMENT_MACRO(mul, *) // per se element wise 00611 namespace element_wise { 00612 TVMET_IMPLEMENT_MACRO(div, /) // not defined for vectors 00613 } 00614 00615 #undef TVMET_IMPLEMENT_MACRO 00616 00617 00618 /* 00619 * operator(Vector<T, Sz>, POD) 00620 * operator(POD, Vector<T, Sz>) 00621 * Note: operations +,-,*,/ are per se element wise 00622 */ 00623 #define TVMET_IMPLEMENT_MACRO(NAME, OP, POD) \ 00624 template<class T, std::size_t Sz> \ 00625 inline \ 00626 XprVector< \ 00627 XprBinOp< \ 00628 Fcnl_##NAME< T, POD >, \ 00629 VectorConstReference<T, Sz>, \ 00630 XprLiteral< POD > \ 00631 >, \ 00632 Sz \ 00633 > \ 00634 operator OP (const Vector<T, Sz>& lhs, POD rhs) { \ 00635 return NAME (lhs, rhs); \ 00636 } \ 00637 \ 00638 template<class T, std::size_t Sz> \ 00639 inline \ 00640 XprVector< \ 00641 XprBinOp< \ 00642 Fcnl_##NAME< POD, T>, \ 00643 XprLiteral< POD >, \ 00644 VectorConstReference<T, Sz> \ 00645 >, \ 00646 Sz \ 00647 > \ 00648 operator OP (POD lhs, const Vector<T, Sz>& rhs) { \ 00649 return NAME (lhs, rhs); \ 00650 } 00651 00652 TVMET_IMPLEMENT_MACRO(add, +, int) 00653 TVMET_IMPLEMENT_MACRO(sub, -, int) 00654 TVMET_IMPLEMENT_MACRO(mul, *, int) 00655 TVMET_IMPLEMENT_MACRO(div, /, int) 00656 00657 #if defined(TVMET_HAVE_LONG_LONG) 00658 TVMET_IMPLEMENT_MACRO(add, +, long long int) 00659 TVMET_IMPLEMENT_MACRO(sub, -, long long int) 00660 TVMET_IMPLEMENT_MACRO(mul, *, long long int) 00661 TVMET_IMPLEMENT_MACRO(div, /, long long int) 00662 #endif 00663 00664 TVMET_IMPLEMENT_MACRO(add, +, float) 00665 TVMET_IMPLEMENT_MACRO(sub, -, float) 00666 TVMET_IMPLEMENT_MACRO(mul, *, float) 00667 TVMET_IMPLEMENT_MACRO(div, /, float) 00668 00669 TVMET_IMPLEMENT_MACRO(add, +, double) 00670 TVMET_IMPLEMENT_MACRO(sub, -, double) 00671 TVMET_IMPLEMENT_MACRO(mul, *, double) 00672 TVMET_IMPLEMENT_MACRO(div, /, double) 00673 00674 #if defined(TVMET_HAVE_LONG_DOUBLE) 00675 TVMET_IMPLEMENT_MACRO(add, +, long double) 00676 TVMET_IMPLEMENT_MACRO(sub, -, long double) 00677 TVMET_IMPLEMENT_MACRO(mul, *, long double) 00678 TVMET_IMPLEMENT_MACRO(div, /, long double) 00679 #endif 00680 00681 #undef TVMET_IMPLEMENT_MACRO 00682 00683 00684 #if defined(TVMET_HAVE_COMPLEX) 00685 /* 00686 * operator(Vector<std::complex<T>, Sz>, std::complex<T>) 00687 * operator(std::complex<T>, Vector<std::complex<T>, Sz>) 00688 * Note: operations +,-,*,/ are per se element wise 00689 * \todo type promotion 00690 */ 00691 #define TVMET_IMPLEMENT_MACRO(NAME, OP) \ 00692 template<class T, std::size_t Sz> \ 00693 inline \ 00694 XprVector< \ 00695 XprBinOp< \ 00696 Fcnl_##NAME< std::complex<T>, std::complex<T> >, \ 00697 VectorConstReference< std::complex<T>, Sz>, \ 00698 XprLiteral< std::complex<T> > \ 00699 >, \ 00700 Sz \ 00701 > \ 00702 operator OP (const Vector<std::complex<T>, Sz>& lhs, \ 00703 const std::complex<T>& rhs) { \ 00704 return NAME (lhs, rhs); \ 00705 } \ 00706 \ 00707 template<class T, std::size_t Sz> \ 00708 inline \ 00709 XprVector< \ 00710 XprBinOp< \ 00711 Fcnl_##NAME< std::complex<T>, std::complex<T> >, \ 00712 XprLiteral< std::complex<T> >, \ 00713 VectorConstReference< std::complex<T>, Sz> \ 00714 >, \ 00715 Sz \ 00716 > \ 00717 operator OP (const std::complex<T>& lhs, \ 00718 const Vector< std::complex<T>, Sz>& rhs) { \ 00719 return NAME (lhs, rhs); \ 00720 } 00721 00722 TVMET_IMPLEMENT_MACRO(add, +) // per se element wise 00723 TVMET_IMPLEMENT_MACRO(sub, -) // per se element wise 00724 TVMET_IMPLEMENT_MACRO(mul, *) // per se element wise 00725 TVMET_IMPLEMENT_MACRO(div, /) // per se element wise 00726 00727 #undef TVMET_IMPLEMENT_MACRO 00728 00729 #endif // defined(TVMET_HAVE_COMPLEX) 00730 00731 00732 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00733 * Vector integer and compare operators 00734 *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 00735 00736 00737 /* 00738 * operator(Vector<T1, Sz>, Vector<T2, Sz>) 00739 * operator(XprVector<E, Sz>, Vector<T, Sz>) 00740 * operator(Vector<T, Sz>, XprVector<E, Sz>) 00741 * Note: operations are per se element wise 00742 */ 00743 #define TVMET_IMPLEMENT_MACRO(NAME, OP) \ 00744 template<class T1, class T2, std::size_t Sz> \ 00745 inline \ 00746 XprVector< \ 00747 XprBinOp< \ 00748 Fcnl_##NAME<T1, T2>, \ 00749 VectorConstReference<T1, Sz>, \ 00750 VectorConstReference<T2, Sz> \ 00751 >, \ 00752 Sz \ 00753 > \ 00754 operator OP (const Vector<T1, Sz>& lhs, const Vector<T2, Sz>& rhs) { \ 00755 typedef XprBinOp < \ 00756 Fcnl_##NAME<T1, T2>, \ 00757 VectorConstReference<T1, Sz>, \ 00758 VectorConstReference<T2, Sz> \ 00759 > expr_type; \ 00760 return XprVector<expr_type, Sz>( \ 00761 expr_type(lhs.const_ref(), rhs.const_ref())); \ 00762 } \ 00763 \ 00764 template<class E, class T, std::size_t Sz> \ 00765 inline \ 00766 XprVector< \ 00767 XprBinOp< \ 00768 Fcnl_##NAME<typename E::value_type, T>, \ 00769 XprVector<E, Sz>, \ 00770 VectorConstReference<T, Sz> \ 00771 >, \ 00772 Sz \ 00773 > \ 00774 operator OP (const XprVector<E, Sz>& lhs, const Vector<T, Sz>& rhs) { \ 00775 typedef XprBinOp< \ 00776 Fcnl_##NAME<typename E::value_type, T>, \ 00777 XprVector<E, Sz>, \ 00778 VectorConstReference<T, Sz> \ 00779 > expr_type; \ 00780 return XprVector<expr_type, Sz>( \ 00781 expr_type(lhs, rhs.const_ref())); \ 00782 } \ 00783 \ 00784 template<class E, class T, std::size_t Sz> \ 00785 inline \ 00786 XprVector< \ 00787 XprBinOp< \ 00788 Fcnl_##NAME<T, typename E::value_type>, \ 00789 VectorConstReference<T, Sz>, \ 00790 XprVector<E, Sz> \ 00791 >, \ 00792 Sz \ 00793 > \ 00794 operator OP (const Vector<T, Sz>& lhs, const XprVector<E, Sz>& rhs) { \ 00795 typedef XprBinOp< \ 00796 Fcnl_##NAME<T, typename E::value_type>, \ 00797 VectorConstReference<T, Sz>, \ 00798 XprVector<E, Sz> \ 00799 > expr_type; \ 00800 return XprVector<expr_type, Sz>( \ 00801 expr_type(lhs.const_ref(), rhs)); \ 00802 } 00803 00804 // integer operators only, e.g used on double you wil get an error 00805 namespace element_wise { 00806 TVMET_IMPLEMENT_MACRO(mod, %) 00807 TVMET_IMPLEMENT_MACRO(bitxor, ^) 00808 TVMET_IMPLEMENT_MACRO(bitand, &) 00809 TVMET_IMPLEMENT_MACRO(bitor, |) 00810 TVMET_IMPLEMENT_MACRO(shl, <<) 00811 TVMET_IMPLEMENT_MACRO(shr, >>) 00812 } 00813 00814 // necessary operators for eval functions 00815 TVMET_IMPLEMENT_MACRO(greater, >) 00816 TVMET_IMPLEMENT_MACRO(less, <) 00817 TVMET_IMPLEMENT_MACRO(greater_eq, >=) 00818 TVMET_IMPLEMENT_MACRO(less_eq, <=) 00819 TVMET_IMPLEMENT_MACRO(eq, ==) 00820 TVMET_IMPLEMENT_MACRO(not_eq, !=) 00821 TVMET_IMPLEMENT_MACRO(and, &&) 00822 TVMET_IMPLEMENT_MACRO(or, ||) 00823 00824 #undef TVMET_IMPLEMENT_MACRO 00825 00826 00827 #if defined(TVMET_HAVE_COMPLEX) 00828 /* 00829 * operator(Vector<std::complex<T>, Sz>, std::complex<T>) 00830 * operator(std::complex<T>, Vector<std::complex<T>, Sz>) 00831 * Note: - per se element wise 00832 * - bit ops on complex<int> doesn't make sense, stay away 00833 * \todo type promotion 00834 */ 00835 #define TVMET_IMPLEMENT_MACRO(NAME, OP) \ 00836 template<class T, std::size_t Sz> \ 00837 inline \ 00838 XprVector< \ 00839 XprBinOp< \ 00840 Fcnl_##NAME< std::complex<T>, std::complex<T> >, \ 00841 VectorConstReference< std::complex<T>, Sz>, \ 00842 XprLiteral< std::complex<T> > \ 00843 >, \ 00844 Sz \ 00845 > \ 00846 operator OP (const Vector<std::complex<T>, Sz>& lhs, const std::complex<T>& rhs) { \ 00847 typedef XprBinOp< \ 00848 Fcnl_##NAME< std::complex<T>, std::complex<T> >, \ 00849 VectorConstReference< std::complex<T>, Sz>, \ 00850 XprLiteral< std::complex<T> > \ 00851 > expr_type; \ 00852 return XprVector<expr_type, Sz>( \ 00853 expr_type(lhs.const_ref(), XprLiteral< std::complex<T> >(rhs))); \ 00854 } \ 00855 \ 00856 template<class T, std::size_t Sz> \ 00857 inline \ 00858 XprVector< \ 00859 XprBinOp< \ 00860 Fcnl_##NAME< std::complex<T>, std::complex<T> >, \ 00861 XprLiteral< std::complex<T> >, \ 00862 VectorConstReference< std::complex<T>, Sz> \ 00863 >, \ 00864 Sz \ 00865 > \ 00866 operator OP (const std::complex<T>& lhs, const Vector< std::complex<T>, Sz>& rhs) { \ 00867 typedef XprBinOp< \ 00868 Fcnl_##NAME< std::complex<T>, std::complex<T> >, \ 00869 XprLiteral< std::complex<T> >, \ 00870 VectorConstReference< std::complex<T>, Sz> \ 00871 > expr_type; \ 00872 return XprVector<expr_type, Sz>( \ 00873 expr_type(XprLiteral< std::complex<T> >(lhs), rhs.const_ref())); \ 00874 } 00875 00876 // necessary operators for eval functions 00877 TVMET_IMPLEMENT_MACRO(greater, >) 00878 TVMET_IMPLEMENT_MACRO(less, <) 00879 TVMET_IMPLEMENT_MACRO(greater_eq, >=) 00880 TVMET_IMPLEMENT_MACRO(less_eq, <=) 00881 TVMET_IMPLEMENT_MACRO(eq, ==) 00882 TVMET_IMPLEMENT_MACRO(not_eq, !=) 00883 TVMET_IMPLEMENT_MACRO(and, &&) 00884 TVMET_IMPLEMENT_MACRO(or, ||) 00885 00886 #undef TVMET_IMPLEMENT_MACRO 00887 00888 #endif // defined(TVMET_HAVE_COMPLEX) 00889 00890 00891 /* 00892 * operator(Vector<T, Sz>, POD) 00893 * operator(POD, Vector<T, Sz>) 00894 * Note: operations are per se element_wise 00895 */ 00896 #define TVMET_IMPLEMENT_MACRO(NAME, OP, TP) \ 00897 template<class T, std::size_t Sz> \ 00898 inline \ 00899 XprVector< \ 00900 XprBinOp< \ 00901 Fcnl_##NAME< T, TP >, \ 00902 VectorConstReference<T, Sz>, \ 00903 XprLiteral< TP > \ 00904 >, \ 00905 Sz \ 00906 > \ 00907 operator OP (const Vector<T, Sz>& lhs, TP rhs) { \ 00908 typedef XprBinOp< \ 00909 Fcnl_##NAME<T, TP >, \ 00910 VectorConstReference<T, Sz>, \ 00911 XprLiteral< TP > \ 00912 > expr_type; \ 00913 return XprVector<expr_type, Sz>( \ 00914 expr_type(lhs.const_ref(), XprLiteral< TP >(rhs))); \ 00915 } \ 00916 \ 00917 template<class T, std::size_t Sz> \ 00918 inline \ 00919 XprVector< \ 00920 XprBinOp< \ 00921 Fcnl_##NAME< TP, T>, \ 00922 XprLiteral< TP >, \ 00923 VectorConstReference<T, Sz> \ 00924 >, \ 00925 Sz \ 00926 > \ 00927 operator OP (TP lhs, const Vector<T, Sz>& rhs) { \ 00928 typedef XprBinOp< \ 00929 Fcnl_##NAME< TP, T>, \ 00930 XprLiteral< TP >, \ 00931 VectorConstReference<T, Sz> \ 00932 > expr_type; \ 00933 return XprVector<expr_type, Sz>( \ 00934 expr_type(XprLiteral< TP >(lhs), rhs.const_ref())); \ 00935 } 00936 00937 // integer operators only, e.g used on double you wil get an error 00938 namespace element_wise { 00939 TVMET_IMPLEMENT_MACRO(mod, %, int) 00940 TVMET_IMPLEMENT_MACRO(bitxor, ^, int) 00941 TVMET_IMPLEMENT_MACRO(bitand, &, int) 00942 TVMET_IMPLEMENT_MACRO(bitor, |, int) 00943 TVMET_IMPLEMENT_MACRO(shl, <<, int) 00944 TVMET_IMPLEMENT_MACRO(shr, >>, int) 00945 } 00946 00947 // necessary operators for eval functions 00948 TVMET_IMPLEMENT_MACRO(greater, >, int) 00949 TVMET_IMPLEMENT_MACRO(less, <, int) 00950 TVMET_IMPLEMENT_MACRO(greater_eq, >=, int) 00951 TVMET_IMPLEMENT_MACRO(less_eq, <=, int) 00952 TVMET_IMPLEMENT_MACRO(eq, ==, int) 00953 TVMET_IMPLEMENT_MACRO(not_eq, !=, int) 00954 TVMET_IMPLEMENT_MACRO(and, &&, int) 00955 TVMET_IMPLEMENT_MACRO(or, ||, int) 00956 00957 #if defined(TVMET_HAVE_LONG_LONG) 00958 // integer operators only 00959 namespace element_wise { 00960 TVMET_IMPLEMENT_MACRO(mod, %, long long int) 00961 TVMET_IMPLEMENT_MACRO(bitxor, ^, long long int) 00962 TVMET_IMPLEMENT_MACRO(bitand, &, long long int) 00963 TVMET_IMPLEMENT_MACRO(bitor, |, long long int) 00964 TVMET_IMPLEMENT_MACRO(shl, <<, long long int) 00965 TVMET_IMPLEMENT_MACRO(shr, >>, long long int) 00966 } 00967 00968 // necessary operators for eval functions 00969 TVMET_IMPLEMENT_MACRO(greater, >, long long int) 00970 TVMET_IMPLEMENT_MACRO(less, <, long long int) 00971 TVMET_IMPLEMENT_MACRO(greater_eq, >=, long long int) 00972 TVMET_IMPLEMENT_MACRO(less_eq, <=, long long int) 00973 TVMET_IMPLEMENT_MACRO(eq, ==, long long int) 00974 TVMET_IMPLEMENT_MACRO(not_eq, !=, long long int) 00975 TVMET_IMPLEMENT_MACRO(and, &&, long long int) 00976 TVMET_IMPLEMENT_MACRO(or, ||, long long int) 00977 #endif // defined(TVMET_HAVE_LONG_LONG) 00978 00979 // necessary operators for eval functions 00980 TVMET_IMPLEMENT_MACRO(greater, >, float) 00981 TVMET_IMPLEMENT_MACRO(less, <, float) 00982 TVMET_IMPLEMENT_MACRO(greater_eq, >=, float) 00983 TVMET_IMPLEMENT_MACRO(less_eq, <=, float) 00984 TVMET_IMPLEMENT_MACRO(eq, ==, float) 00985 TVMET_IMPLEMENT_MACRO(not_eq, !=, float) 00986 TVMET_IMPLEMENT_MACRO(and, &&, float) 00987 TVMET_IMPLEMENT_MACRO(or, ||, float) 00988 00989 // necessary operators for eval functions 00990 TVMET_IMPLEMENT_MACRO(greater, >, double) 00991 TVMET_IMPLEMENT_MACRO(less, <, double) 00992 TVMET_IMPLEMENT_MACRO(greater_eq, >=, double) 00993 TVMET_IMPLEMENT_MACRO(less_eq, <=, double) 00994 TVMET_IMPLEMENT_MACRO(eq, ==, double) 00995 TVMET_IMPLEMENT_MACRO(not_eq, !=, double) 00996 TVMET_IMPLEMENT_MACRO(and, &&, double) 00997 TVMET_IMPLEMENT_MACRO(or, ||, double) 00998 00999 #if defined(TVMET_HAVE_LONG_DOUBLE) 01000 // necessary operators for eval functions 01001 TVMET_IMPLEMENT_MACRO(greater, >, long double) 01002 TVMET_IMPLEMENT_MACRO(less, <, long double) 01003 TVMET_IMPLEMENT_MACRO(greater_eq, >=, long double) 01004 TVMET_IMPLEMENT_MACRO(less_eq, <=, long double) 01005 TVMET_IMPLEMENT_MACRO(eq, ==, long double) 01006 TVMET_IMPLEMENT_MACRO(not_eq, !=, long double) 01007 TVMET_IMPLEMENT_MACRO(and, &&, long double) 01008 TVMET_IMPLEMENT_MACRO(or, ||, long double) 01009 #endif // defined(TVMET_HAVE_LONG_DOUBLE) 01010 01011 #undef TVMET_IMPLEMENT_MACRO 01012 01013 01014 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 01015 * global unary operators 01016 *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 01017 01018 01019 /* 01020 * unary_operator(Vector<T, Sz>) 01021 * Note: per se element wise 01022 */ 01023 #define TVMET_IMPLEMENT_MACRO(NAME, OP) \ 01024 template <class T, std::size_t Sz> \ 01025 inline \ 01026 XprVector< \ 01027 XprUnOp< \ 01028 Fcnl_##NAME<T>, \ 01029 VectorConstReference<T, Sz> \ 01030 >, \ 01031 Sz \ 01032 > \ 01033 operator OP (const Vector<T, Sz>& rhs) { \ 01034 typedef XprUnOp< \ 01035 Fcnl_##NAME<T>, \ 01036 VectorConstReference<T, Sz> \ 01037 > expr_type; \ 01038 return XprVector<expr_type, Sz>(expr_type(rhs.const_ref())); \ 01039 } 01040 01041 TVMET_IMPLEMENT_MACRO(not, !) 01042 TVMET_IMPLEMENT_MACRO(compl, ~) 01043 TVMET_IMPLEMENT_MACRO(neg, -) 01044 01045 #undef TVMET_IMPLEMENT_MACRO 01046 01047 01048 } // namespace tvmet 01049 01050 #endif // TVMET_VECTOR_OPERATORS_H 01051 01052 // Local Variables: 01053 // mode:C++ 01054 // tab-width:8 01055 // End:
Generated on Tue Jul 12 2022 21:02:14 by
