00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef TVMET_VECTOR_BINARY_FUNCTIONS_H
00025 #define TVMET_VECTOR_BINARY_FUNCTIONS_H
00026
00027 #include <tvmet/NumericTraits.h>
00028 #include <tvmet/Extremum.h>
00029
00030 namespace tvmet {
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #define TVMET_DECLARE_MACRO(NAME) \
00043 template<class T1, class T2, std::size_t Sz> \
00044 inline \
00045 XprVector< \
00046 XprBinOp< \
00047 Fcnl_##NAME<T1, T2>, \
00048 VectorConstReference<T1, Sz>, \
00049 VectorConstReference<T2, Sz> \
00050 >, \
00051 Sz \
00052 > \
00053 NAME(const Vector<T1, Sz>& lhs, \
00054 const Vector<T2, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE; \
00055 \
00056 template<class E, class T, std::size_t Sz> \
00057 inline \
00058 XprVector< \
00059 XprBinOp< \
00060 Fcnl_##NAME<typename E::value_type, T>, \
00061 VectorConstReference<T, Sz>, \
00062 XprVector<E, Sz> \
00063 >, \
00064 Sz \
00065 > \
00066 NAME(const XprVector<E, Sz>& lhs, \
00067 const Vector<T, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE; \
00068 \
00069 template<class E, class T, std::size_t Sz> \
00070 inline \
00071 XprVector< \
00072 XprBinOp< \
00073 Fcnl_##NAME<T, typename E::value_type>, \
00074 VectorConstReference<T, Sz>, \
00075 XprVector<E, Sz> \
00076 >, \
00077 Sz \
00078 > \
00079 NAME(const Vector<T, Sz>& lhs, \
00080 const XprVector<E, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
00081
00082 TVMET_DECLARE_MACRO(atan2)
00083 TVMET_DECLARE_MACRO(fmod)
00084 TVMET_DECLARE_MACRO(pow)
00085 #if defined(TVMET_HAVE_DREM)
00086 TVMET_DECLARE_MACRO(drem)
00087 #endif
00088 #if defined(TVMET_HAVE_HYPOT)
00089 TVMET_DECLARE_MACRO(hypot)
00090 #endif
00091 #if defined(TVMET_HAVE_JN)
00092 TVMET_DECLARE_MACRO(jn)
00093 #endif
00094 #if defined(TVMET_HAVE_YN)
00095 TVMET_DECLARE_MACRO(yn)
00096 #endif
00097
00098 #undef TVMET_DECLARE_MACRO
00099
00100
00101
00102
00103
00104 #define TVMET_DECLARE_MACRO(NAME, TP) \
00105 template<class T, std::size_t Sz> \
00106 inline \
00107 XprVector< \
00108 XprBinOp< \
00109 Fcnl_##NAME<T, TP >, \
00110 VectorConstReference<T, Sz>, \
00111 XprLiteral< TP > \
00112 >, \
00113 Sz \
00114 > \
00115 NAME(const Vector<T, Sz>& lhs, TP rhs) TVMET_CXX_ALWAYS_INLINE;
00116
00117 TVMET_DECLARE_MACRO(atan2, int)
00118 TVMET_DECLARE_MACRO(fmod, int)
00119 TVMET_DECLARE_MACRO(pow, int)
00120 #if defined(TVMET_HAVE_DREM)
00121 TVMET_DECLARE_MACRO(drem, int)
00122 #endif
00123 #if defined(TVMET_HAVE_HYPOT)
00124 TVMET_DECLARE_MACRO(hypot, int)
00125 #endif
00126 #if defined(TVMET_HAVE_JN)
00127 TVMET_DECLARE_MACRO(jn, int)
00128 #endif
00129 #if defined(TVMET_HAVE_YN)
00130 TVMET_DECLARE_MACRO(yn, int)
00131 #endif
00132
00133
00134 #if defined(TVMET_HAVE_LONG_LONG)
00135 TVMET_DECLARE_MACRO(atan2, long long int)
00136 TVMET_DECLARE_MACRO(fmod, long long int)
00137 TVMET_DECLARE_MACRO(pow, long long int)
00138 #if defined(TVMET_HAVE_DREM)
00139 TVMET_DECLARE_MACRO(drem, long long int)
00140 #endif
00141 #if defined(TVMET_HAVE_HYPOT)
00142 TVMET_DECLARE_MACRO(hypot, long long int)
00143 #endif
00144 #if defined(TVMET_HAVE_JN)
00145 TVMET_DECLARE_MACRO(jn, long long int)
00146 #endif
00147 #if defined(TVMET_HAVE_YN)
00148 TVMET_DECLARE_MACRO(yn, long long int)
00149 #endif
00150 #endif // defined(TVMET_HAVE_LONG_LONG)
00151
00152
00153 TVMET_DECLARE_MACRO(atan2, float)
00154 TVMET_DECLARE_MACRO(fmod, float)
00155 TVMET_DECLARE_MACRO(pow, float)
00156 #if defined(TVMET_HAVE_DREM)
00157 TVMET_DECLARE_MACRO(drem, float)
00158 #endif
00159 #if defined(TVMET_HAVE_HYPOT)
00160 TVMET_DECLARE_MACRO(hypot, float)
00161 #endif
00162 #if defined(TVMET_HAVE_JN)
00163 TVMET_DECLARE_MACRO(jn, float)
00164 #endif
00165 #if defined(TVMET_HAVE_YN)
00166 TVMET_DECLARE_MACRO(yn, float)
00167 #endif
00168
00169
00170 TVMET_DECLARE_MACRO(atan2, double)
00171 TVMET_DECLARE_MACRO(fmod, double)
00172 TVMET_DECLARE_MACRO(pow, double)
00173 #if defined(TVMET_HAVE_DREM)
00174 TVMET_DECLARE_MACRO(drem, double)
00175 #endif
00176 #if defined(TVMET_HAVE_HYPOT)
00177 TVMET_DECLARE_MACRO(hypot, double)
00178 #endif
00179 #if defined(TVMET_HAVE_JN)
00180 TVMET_DECLARE_MACRO(jn, double)
00181 #endif
00182 #if defined(TVMET_HAVE_YN)
00183 TVMET_DECLARE_MACRO(yn, double)
00184 #endif
00185
00186
00187 #if defined(TVMET_HAVE_LONG_DOUBLE)
00188 TVMET_DECLARE_MACRO(atan2, long double)
00189 TVMET_DECLARE_MACRO(fmod, long double)
00190 TVMET_DECLARE_MACRO(pow, long double)
00191 #if defined(TVMET_HAVE_DREM)
00192 TVMET_DECLARE_MACRO(drem, long double)
00193 #endif
00194 #if defined(TVMET_HAVE_HYPOT)
00195 TVMET_DECLARE_MACRO(hypot, long double)
00196 #endif
00197 #if defined(TVMET_HAVE_JN)
00198 TVMET_DECLARE_MACRO(jn, long double)
00199 #endif
00200 #if defined(TVMET_HAVE_YN)
00201 TVMET_DECLARE_MACRO(yn, long double)
00202 #endif
00203 #endif // defined(TVMET_HAVE_LONG_DOUBLE)
00204
00205 #undef TVMET_DECLARE_MACRO
00206
00207
00208
00209
00210
00211
00212 #if defined(TVMET_HAVE_COMPLEX) && defined(TVMET_HAVE_COMPLEX_MATH1)
00213 template<class T, std::size_t Sz>
00214 XprVector<
00215 XprBinOp<
00216 Fcnl_pow<T, std::complex<T> >,
00217 VectorConstReference<T, Sz>,
00218 XprLiteral< std::complex<T> >
00219 >,
00220 Sz
00221 >
00222 pow(const Vector<T, Sz>& lhs,
00223 const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE;
00224
00225
00226 template<class T, std::size_t Sz>
00227 XprVector<
00228 XprBinOp<
00229 Fcnl_pow<std::complex<T>, std::complex<T> >,
00230 VectorConstReference<std::complex<T>, Sz>,
00231 XprLiteral< std::complex<T> >
00232 >,
00233 Sz
00234 >
00235 pow(const Vector<std::complex<T>, Sz>& lhs,
00236 const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE;
00237
00238
00239 template<class T, std::size_t Sz>
00240 XprVector<
00241 XprBinOp<
00242 Fcnl_pow<std::complex<T>, T>,
00243 VectorConstReference<std::complex<T>, Sz>,
00244 XprLiteral<T>
00245 >,
00246 Sz
00247 >
00248 pow(const Vector<std::complex<T>, Sz>& lhs,
00249 const T& rhs) TVMET_CXX_ALWAYS_INLINE;
00250
00251
00252 template<class T, std::size_t Sz>
00253 XprVector<
00254 XprBinOp<
00255 Fcnl_pow<std::complex<T>, int>,
00256 VectorConstReference<std::complex<T>, Sz>,
00257 XprLiteral<int>
00258 >,
00259 Sz
00260 >
00261 pow(const Vector<std::complex<T>, Sz>& lhs,
00262 int rhs) TVMET_CXX_ALWAYS_INLINE;
00263
00264
00265 template<class T, std::size_t Sz>
00266 XprVector<
00267 XprBinOp<
00268 Fcnl_polar<T, T>,
00269 VectorConstReference<T, Sz>,
00270 XprLiteral<T>
00271 >,
00272 Sz
00273 >
00274 polar(const Vector<T, Sz>& lhs, const T& rhs) TVMET_CXX_ALWAYS_INLINE;
00275
00276 #endif // defined(TVMET_HAVE_COMPLEX) && defined(TVMET_HAVE_COMPLEX_MATH1)
00277
00278 #if defined(TVMET_HAVE_COMPLEX) && defined(TVMET_HAVE_COMPLEX_MATH2)
00279
00280 #endif // defined(TVMET_HAVE_COMPLEX) && defined(TVMET_HAVE_COMPLEX_MATH2)
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292 #define TVMET_IMPLEMENT_MACRO(NAME) \
00293 template<class T1, class T2, std::size_t Sz> \
00294 inline \
00295 XprVector< \
00296 XprBinOp< \
00297 Fcnl_##NAME<T1, T2>, \
00298 VectorConstReference<T1, Sz>, \
00299 VectorConstReference<T2, Sz> \
00300 >, \
00301 Sz \
00302 > \
00303 NAME(const Vector<T1, Sz>& lhs, const Vector<T2, Sz>& rhs) { \
00304 typedef XprBinOp < \
00305 Fcnl_##NAME<T1, T2>, \
00306 VectorConstReference<T1, Sz>, \
00307 VectorConstReference<T2, Sz> \
00308 > expr_type; \
00309 return XprVector<expr_type, Sz>( \
00310 expr_type(lhs.const_ref(), rhs.const_ref())); \
00311 } \
00312 \
00313 template<class E, class T, std::size_t Sz> \
00314 inline \
00315 XprVector< \
00316 XprBinOp< \
00317 Fcnl_##NAME<typename E::value_type, T>, \
00318 VectorConstReference<T, Sz>, \
00319 XprVector<E, Sz> \
00320 >, \
00321 Sz \
00322 > \
00323 NAME(const XprVector<E, Sz>& lhs, const Vector<T, Sz>& rhs) { \
00324 typedef XprBinOp< \
00325 Fcnl_##NAME<typename E::value_type, T>, \
00326 XprVector<E, Sz>, \
00327 VectorConstReference<T, Sz> \
00328 > expr_type; \
00329 return XprVector<expr_type, Sz>( \
00330 expr_type(lhs, rhs.const_ref())); \
00331 } \
00332 \
00333 template<class E, class T, std::size_t Sz> \
00334 inline \
00335 XprVector< \
00336 XprBinOp< \
00337 Fcnl_##NAME<T, typename E::value_type>, \
00338 VectorConstReference<T, Sz>, \
00339 XprVector<E, Sz> \
00340 >, \
00341 Sz \
00342 > \
00343 NAME(const Vector<T, Sz>& lhs, const XprVector<E, Sz>& rhs) { \
00344 typedef XprBinOp< \
00345 Fcnl_##NAME<T, typename E::value_type>, \
00346 VectorConstReference<T, Sz>, \
00347 XprVector<E, Sz> \
00348 > expr_type; \
00349 return XprVector<expr_type, Sz>( \
00350 expr_type(lhs.const_ref(), rhs)); \
00351 }
00352
00353 TVMET_IMPLEMENT_MACRO(atan2)
00354 TVMET_IMPLEMENT_MACRO(fmod)
00355 TVMET_IMPLEMENT_MACRO(pow)
00356 #if defined(TVMET_HAVE_DREM)
00357 TVMET_IMPLEMENT_MACRO(drem)
00358 #endif
00359 #if defined(TVMET_HAVE_HYPOT)
00360 TVMET_IMPLEMENT_MACRO(hypot)
00361 #endif
00362 #if defined(TVMET_HAVE_JN)
00363 TVMET_IMPLEMENT_MACRO(jn)
00364 #endif
00365 #if defined(TVMET_HAVE_YN)
00366 TVMET_IMPLEMENT_MACRO(yn)
00367 #endif
00368
00369 #undef TVMET_IMPLEMENT_MACRO
00370
00371
00372
00373
00374
00375 #define TVMET_IMPLEMENT_MACRO(NAME, TP) \
00376 template<class T, std::size_t Sz> \
00377 inline \
00378 XprVector< \
00379 XprBinOp< \
00380 Fcnl_##NAME<T, TP >, \
00381 VectorConstReference<T, Sz>, \
00382 XprLiteral< TP > \
00383 >, \
00384 Sz \
00385 > \
00386 NAME(const Vector<T, Sz>& lhs, TP rhs) { \
00387 typedef XprBinOp< \
00388 Fcnl_##NAME<T, TP >, \
00389 VectorConstReference<T, Sz>, \
00390 XprLiteral< TP > \
00391 > expr_type; \
00392 return XprVector<expr_type, Sz>( \
00393 expr_type(lhs.const_ref(), XprLiteral< TP >(rhs))); \
00394 }
00395
00396 TVMET_IMPLEMENT_MACRO(atan2, int)
00397 TVMET_IMPLEMENT_MACRO(fmod, int)
00398 TVMET_IMPLEMENT_MACRO(pow, int)
00399 #if defined(TVMET_HAVE_DREM)
00400 TVMET_IMPLEMENT_MACRO(drem, int)
00401 #endif
00402 #if defined(TVMET_HAVE_HYPOT)
00403 TVMET_IMPLEMENT_MACRO(hypot, int)
00404 #endif
00405 #if defined(TVMET_HAVE_JN)
00406 TVMET_IMPLEMENT_MACRO(jn, int)
00407 #endif
00408 #if defined(TVMET_HAVE_YN)
00409 TVMET_IMPLEMENT_MACRO(yn, int)
00410 #endif
00411
00412
00413 #if defined(TVMET_HAVE_LONG_LONG)
00414 TVMET_IMPLEMENT_MACRO(atan2, long long int)
00415 TVMET_IMPLEMENT_MACRO(fmod, long long int)
00416 TVMET_IMPLEMENT_MACRO(pow, long long int)
00417 #if defined(TVMET_HAVE_DREM)
00418 TVMET_IMPLEMENT_MACRO(drem, long long int)
00419 #endif
00420 #if defined(TVMET_HAVE_HYPOT)
00421 TVMET_IMPLEMENT_MACRO(hypot, long long int)
00422 #endif
00423 #if defined(TVMET_HAVE_JN)
00424 TVMET_IMPLEMENT_MACRO(jn, long long int)
00425 #endif
00426 #if defined(TVMET_HAVE_YN)
00427 TVMET_IMPLEMENT_MACRO(yn, long long int)
00428 #endif
00429 #endif // defined(TVMET_HAVE_LONG_LONG)
00430
00431
00432 TVMET_IMPLEMENT_MACRO(atan2, float)
00433 TVMET_IMPLEMENT_MACRO(fmod, float)
00434 TVMET_IMPLEMENT_MACRO(pow, float)
00435 #if defined(TVMET_HAVE_DREM)
00436 TVMET_IMPLEMENT_MACRO(drem, float)
00437 #endif
00438 #if defined(TVMET_HAVE_HYPOT)
00439 TVMET_IMPLEMENT_MACRO(hypot, float)
00440 #endif
00441 #if defined(TVMET_HAVE_JN)
00442 TVMET_IMPLEMENT_MACRO(jn, float)
00443 #endif
00444 #if defined(TVMET_HAVE_YN)
00445 TVMET_IMPLEMENT_MACRO(yn, float)
00446 #endif
00447
00448
00449 TVMET_IMPLEMENT_MACRO(atan2, double)
00450 TVMET_IMPLEMENT_MACRO(fmod, double)
00451 TVMET_IMPLEMENT_MACRO(pow, double)
00452 #if defined(TVMET_HAVE_DREM)
00453 TVMET_IMPLEMENT_MACRO(drem, double)
00454 #endif
00455 #if defined(TVMET_HAVE_HYPOT)
00456 TVMET_IMPLEMENT_MACRO(hypot, double)
00457 #endif
00458 #if defined(TVMET_HAVE_JN)
00459 TVMET_IMPLEMENT_MACRO(jn, double)
00460 #endif
00461 #if defined(TVMET_HAVE_YN)
00462 TVMET_IMPLEMENT_MACRO(yn, double)
00463 #endif
00464
00465
00466 #if defined(TVMET_HAVE_LONG_DOUBLE)
00467 TVMET_IMPLEMENT_MACRO(atan2, long double)
00468 TVMET_IMPLEMENT_MACRO(fmod, long double)
00469 TVMET_IMPLEMENT_MACRO(pow, long double)
00470 #if defined(TVMET_HAVE_DREM)
00471 TVMET_IMPLEMENT_MACRO(drem, long double)
00472 #endif
00473 #if defined(TVMET_HAVE_HYPOT)
00474 TVMET_IMPLEMENT_MACRO(hypot, long double)
00475 #endif
00476 #if defined(TVMET_HAVE_JN)
00477 TVMET_IMPLEMENT_MACRO(jn, long double)
00478 #endif
00479 #if defined(TVMET_HAVE_YN)
00480 TVMET_IMPLEMENT_MACRO(yn, long double)
00481 #endif
00482 #endif // defined(TVMET_HAVE_LONG_DOUBLE)
00483
00484 #undef TVMET_IMPLEMENT_MACRO
00485
00486
00487
00488
00489
00490
00491 #if defined(TVMET_HAVE_COMPLEX) && defined(TVMET_HAVE_COMPLEX_MATH1)
00492
00496 template<class T, std::size_t Sz>
00497 inline
00498 XprVector<
00499 XprBinOp<
00500 Fcnl_pow<T, std::complex<T> >,
00501 VectorConstReference<T, Sz>,
00502 XprLiteral< std::complex<T> >
00503 >,
00504 Sz
00505 >
00506 pow(const Vector<T, Sz>& lhs, const std::complex<T>& rhs) {
00507 typedef XprBinOp<
00508 Fcnl_pow<T, std::complex<T> >,
00509 VectorConstReference<T, Sz>,
00510 XprLiteral< std::complex<T> >
00511 > expr_type;
00512 return XprVector<expr_type, Sz>(
00513 expr_type(lhs.const_ref(), XprLiteral< std::complex<T> >(rhs)));
00514 }
00515
00516
00521 template<class T, std::size_t Sz>
00522 inline
00523 XprVector<
00524 XprBinOp<
00525 Fcnl_pow<std::complex<T>, std::complex<T> >,
00526 VectorConstReference<std::complex<T>, Sz>,
00527 XprLiteral< std::complex<T> >
00528 >,
00529 Sz
00530 >
00531 pow(const Vector<std::complex<T>, Sz>& lhs, const std::complex<T>& rhs) {
00532 typedef XprBinOp<
00533 Fcnl_pow<std::complex<T>, std::complex<T> >,
00534 VectorConstReference<std::complex<T>, Sz>,
00535 XprLiteral< std::complex<T> >
00536 > expr_type;
00537 return XprVector<expr_type, Sz>(
00538 expr_type(lhs.const_ref(), XprLiteral< std::complex<T> >(rhs)));
00539 }
00540
00541
00546 template<class T, std::size_t Sz>
00547 inline
00548 XprVector<
00549 XprBinOp<
00550 Fcnl_pow<std::complex<T>, T>,
00551 VectorConstReference<std::complex<T>, Sz>,
00552 XprLiteral<T>
00553 >,
00554 Sz
00555 >
00556 pow(const Vector<std::complex<T>, Sz>& lhs, const T& rhs) {
00557 typedef XprBinOp<
00558 Fcnl_pow<std::complex<T>, T>,
00559 VectorConstReference<std::complex<T>, Sz>,
00560 XprLiteral<T>
00561 > expr_type;
00562 return XprVector<expr_type, Sz>(
00563 expr_type(lhs.const_ref(), XprLiteral<T>(rhs)));
00564 }
00565
00566
00571 template<class T, std::size_t Sz>
00572 inline
00573 XprVector<
00574 XprBinOp<
00575 Fcnl_pow<std::complex<T>, int>,
00576 VectorConstReference<std::complex<T>, Sz>,
00577 XprLiteral<int>
00578 >,
00579 Sz
00580 >
00581 pow(const Vector<std::complex<T>, Sz>& lhs, int rhs) {
00582 typedef XprBinOp<
00583 Fcnl_pow<std::complex<T>, int>,
00584 VectorConstReference<std::complex<T>, Sz>,
00585 XprLiteral<int>
00586 > expr_type;
00587 return XprVector<expr_type, Sz>(
00588 expr_type(lhs.const_ref(), XprLiteral<int>(rhs)));
00589 }
00590
00591
00596 template<class T, std::size_t Sz>
00597 inline
00598 XprVector<
00599 XprBinOp<
00600 Fcnl_polar<T, T>,
00601 VectorConstReference<T, Sz>,
00602 XprLiteral<T>
00603 >,
00604 Sz
00605 >
00606 polar(const Vector<T, Sz>& lhs, const T& rhs) {
00607 typedef XprBinOp<
00608 Fcnl_polar<T, T>,
00609 VectorConstReference<T, Sz>,
00610 XprLiteral<T>
00611 > expr_type;
00612 return XprVector<expr_type, Sz>(
00613 expr_type(lhs.const_ref(), XprLiteral<T>(rhs)));
00614 }
00615 #endif // defined(TVMET_HAVE_COMPLEX) && defined(TVMET_HAVE_COMPLEX_MATH1)
00616
00617 #if defined(TVMET_HAVE_COMPLEX) && defined(TVMET_HAVE_COMPLEX_MATH2)
00618
00619 #endif // defined(TVMET_HAVE_COMPLEX) && defined(TVMET_HAVE_COMPLEX_MATH2)
00620
00621
00622 }
00623
00624 #endif // TVMET_VECTOR_BINARY_FUNCTIONS_H
00625
00626
00627
00628
00629