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_FUNCTIONS_H
00025 #define TVMET_VECTOR_FUNCTIONS_H
00026
00027 #include <tvmet/Extremum.h>
00028
00029 namespace tvmet {
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #define TVMET_DECLARE_MACRO(NAME) \
00048 template<class T1, class T2, std::size_t Sz> \
00049 XprVector< \
00050 XprBinOp< \
00051 Fcnl_##NAME<T1, T2>, \
00052 VectorConstReference<T1, Sz>, \
00053 VectorConstReference<T2, Sz> \
00054 >, \
00055 Sz \
00056 > \
00057 NAME (const Vector<T1, Sz>& lhs, \
00058 const Vector<T2, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE; \
00059 \
00060 template<class E, class T, std::size_t Sz> \
00061 XprVector< \
00062 XprBinOp< \
00063 Fcnl_##NAME<typename E::value_type, T>, \
00064 XprVector<E, Sz>, \
00065 VectorConstReference<T, Sz> \
00066 >, \
00067 Sz \
00068 > \
00069 NAME (const XprVector<E, Sz>& lhs, \
00070 const Vector<T, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE; \
00071 \
00072 template<class E, class T, std::size_t Sz> \
00073 XprVector< \
00074 XprBinOp< \
00075 Fcnl_##NAME<T, typename E::value_type>, \
00076 VectorConstReference<T, Sz>, \
00077 XprVector<E, Sz> \
00078 >, \
00079 Sz \
00080 > \
00081 NAME (const Vector<T, Sz>& lhs, \
00082 const XprVector<E, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
00083
00084 TVMET_DECLARE_MACRO(add)
00085 TVMET_DECLARE_MACRO(sub)
00086 TVMET_DECLARE_MACRO(mul)
00087 namespace element_wise {
00088 TVMET_DECLARE_MACRO(div)
00089 }
00090
00091 #undef TVMET_DECLARE_MACRO
00092
00093
00094
00095
00096
00097
00098
00099 #define TVMET_DECLARE_MACRO(NAME, POD) \
00100 template<class T, std::size_t Sz> \
00101 XprVector< \
00102 XprBinOp< \
00103 Fcnl_##NAME< T, POD >, \
00104 VectorConstReference<T, Sz>, \
00105 XprLiteral< POD > \
00106 >, \
00107 Sz \
00108 > \
00109 NAME (const Vector<T, Sz>& lhs, \
00110 POD rhs) TVMET_CXX_ALWAYS_INLINE; \
00111 \
00112 template<class T, std::size_t Sz> \
00113 XprVector< \
00114 XprBinOp< \
00115 Fcnl_##NAME< POD, T>, \
00116 XprLiteral< POD >, \
00117 VectorConstReference<T, Sz> \
00118 >, \
00119 Sz \
00120 > \
00121 NAME (POD lhs, \
00122 const Vector<T, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
00123
00124 TVMET_DECLARE_MACRO(add, int)
00125 TVMET_DECLARE_MACRO(sub, int)
00126 TVMET_DECLARE_MACRO(mul, int)
00127 TVMET_DECLARE_MACRO(div, int)
00128
00129 #if defined(TVMET_HAVE_LONG_LONG)
00130 TVMET_DECLARE_MACRO(add, long long int)
00131 TVMET_DECLARE_MACRO(sub, long long int)
00132 TVMET_DECLARE_MACRO(mul, long long int)
00133 TVMET_DECLARE_MACRO(div, long long int)
00134 #endif
00135
00136 TVMET_DECLARE_MACRO(add, float)
00137 TVMET_DECLARE_MACRO(sub, float)
00138 TVMET_DECLARE_MACRO(mul, float)
00139 TVMET_DECLARE_MACRO(div, float)
00140
00141 TVMET_DECLARE_MACRO(add, double)
00142 TVMET_DECLARE_MACRO(sub, double)
00143 TVMET_DECLARE_MACRO(mul, double)
00144 TVMET_DECLARE_MACRO(div, double)
00145
00146 #if defined(TVMET_HAVE_LONG_DOUBLE)
00147 TVMET_DECLARE_MACRO(add, long double)
00148 TVMET_DECLARE_MACRO(sub, long double)
00149 TVMET_DECLARE_MACRO(mul, long double)
00150 TVMET_DECLARE_MACRO(div, long double)
00151 #endif
00152
00153 #undef TVMET_DECLARE_MACRO
00154
00155
00156 #if defined(TVMET_HAVE_COMPLEX)
00157
00158
00159
00160
00161
00162
00163 #define TVMET_DECLARE_MACRO(NAME) \
00164 template<class T, std::size_t Sz> \
00165 XprVector< \
00166 XprBinOp< \
00167 Fcnl_##NAME< std::complex<T>, std::complex<T> >, \
00168 VectorConstReference< std::complex<T>, Sz>, \
00169 XprLiteral< std::complex<T> > \
00170 >, \
00171 Sz \
00172 > \
00173 NAME (const Vector<std::complex<T>, Sz>& lhs, \
00174 const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE; \
00175 \
00176 template<class T, std::size_t Sz> \
00177 XprVector< \
00178 XprBinOp< \
00179 Fcnl_##NAME< std::complex<T>, std::complex<T> >, \
00180 XprLiteral< std::complex<T> >, \
00181 VectorConstReference< std::complex<T>, Sz> \
00182 >, \
00183 Sz \
00184 > \
00185 NAME (const std::complex<T>& lhs, \
00186 const Vector< std::complex<T>, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
00187
00188 TVMET_DECLARE_MACRO(add)
00189 TVMET_DECLARE_MACRO(sub)
00190 TVMET_DECLARE_MACRO(mul)
00191 TVMET_DECLARE_MACRO(div)
00192
00193 #undef TVMET_DECLARE_MACRO
00194
00195 #endif // defined(TVMET_HAVE_COMPLEX)
00196
00197
00198
00199
00200
00201
00202
00203 template<class T, std::size_t Sz>
00204 typename NumericTraits<T>::sum_type
00205 sum(const Vector<T, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
00206
00207
00208 template<class T, std::size_t Sz>
00209 typename NumericTraits<T>::sum_type
00210 product(const Vector<T, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
00211
00212
00213 template<class T1, class T2, std::size_t Sz>
00214 typename PromoteTraits<T1, T2>::value_type
00215 dot(const Vector<T1, Sz>& lhs,
00216 const Vector<T2, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
00217
00218
00219 template<class T1, class T2>
00220 Vector<typename PromoteTraits<T1, T2>::value_type, 3>
00221 cross(const Vector<T1, 3>& lhs,
00222 const Vector<T2, 3>& rhs) TVMET_CXX_ALWAYS_INLINE;
00223
00224
00225 template<class T, std::size_t Sz>
00226 typename NumericTraits<T>::sum_type
00227 norm1(const Vector<T, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
00228
00229
00230 template<class T, std::size_t Sz>
00231 typename NumericTraits<T>::sum_type
00232 norm2(const Vector<T, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
00233
00234
00235 template<class T, std::size_t Sz>
00236 XprVector<
00237 XprBinOp<
00238 Fcnl_div<T, T>,
00239 VectorConstReference<T, Sz>,
00240 XprLiteral< T >
00241 >,
00242 Sz
00243 >
00244 normalize(const Vector<T, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
00245
00246
00247
00248
00249
00250
00251 template<class E, std::size_t Sz>
00252 Extremum<typename E::value_type, std::size_t, vector_tag>
00253 maximum(const XprVector<E, Sz>& e);
00254
00255
00256 template<class T, std::size_t Sz>
00257 Extremum<T, std::size_t, vector_tag>
00258 maximum(const Vector<T, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
00259
00260
00261 template<class E, std::size_t Sz>
00262 Extremum<typename E::value_type, std::size_t, vector_tag>
00263 minimum(const XprVector<E, Sz>& e);
00264
00265
00266 template<class T, std::size_t Sz>
00267 Extremum<T, std::size_t, vector_tag>
00268 minimum(const Vector<T, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
00269
00270
00271 template<class E, std::size_t Sz>
00272 typename E::value_type
00273 max(const XprVector<E, Sz>& e);
00274
00275
00276 template<class T, std::size_t Sz>
00277 T max(const Vector<T, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
00278
00279
00280 template<class E, std::size_t Sz>
00281 typename E::value_type
00282 min(const XprVector<E, Sz>& e);
00283
00284
00285 template<class T, std::size_t Sz>
00286 T min(const Vector<T, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
00287
00288
00289 template<class T, std::size_t Sz>
00290 XprVector<
00291 VectorConstReference<T, Sz>,
00292 Sz
00293 >
00294 cvector_ref(const T* mem) TVMET_CXX_ALWAYS_INLINE;
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 #define TVMET_IMPLEMENT_MACRO(NAME) \
00313 template<class T1, class T2, std::size_t Sz> \
00314 inline \
00315 XprVector< \
00316 XprBinOp< \
00317 Fcnl_##NAME<T1, T2>, \
00318 VectorConstReference<T1, Sz>, \
00319 VectorConstReference<T2, Sz> \
00320 >, \
00321 Sz \
00322 > \
00323 NAME (const Vector<T1, Sz>& lhs, const Vector<T2, Sz>& rhs) { \
00324 typedef XprBinOp < \
00325 Fcnl_##NAME<T1, T2>, \
00326 VectorConstReference<T1, Sz>, \
00327 VectorConstReference<T2, Sz> \
00328 > expr_type; \
00329 return XprVector<expr_type, Sz>( \
00330 expr_type(lhs.const_ref(), rhs.const_ref())); \
00331 } \
00332 \
00333 template<class E, class T, std::size_t Sz> \
00334 inline \
00335 XprVector< \
00336 XprBinOp< \
00337 Fcnl_##NAME<typename E::value_type, T>, \
00338 XprVector<E, Sz>, \
00339 VectorConstReference<T, Sz> \
00340 >, \
00341 Sz \
00342 > \
00343 NAME (const XprVector<E, Sz>& lhs, const Vector<T, Sz>& rhs) { \
00344 typedef XprBinOp< \
00345 Fcnl_##NAME<typename E::value_type, T>, \
00346 XprVector<E, Sz>, \
00347 VectorConstReference<T, Sz> \
00348 > expr_type; \
00349 return XprVector<expr_type, Sz>( \
00350 expr_type(lhs, rhs.const_ref())); \
00351 } \
00352 \
00353 template<class E, class T, std::size_t Sz> \
00354 inline \
00355 XprVector< \
00356 XprBinOp< \
00357 Fcnl_##NAME<T, typename E::value_type>, \
00358 VectorConstReference<T, Sz>, \
00359 XprVector<E, Sz> \
00360 >, \
00361 Sz \
00362 > \
00363 NAME (const Vector<T, Sz>& lhs, const XprVector<E, Sz>& rhs) { \
00364 typedef XprBinOp< \
00365 Fcnl_##NAME<T, typename E::value_type>, \
00366 VectorConstReference<T, Sz>, \
00367 XprVector<E, Sz> \
00368 > expr_type; \
00369 return XprVector<expr_type, Sz>( \
00370 expr_type(lhs.const_ref(), rhs)); \
00371 }
00372
00373 TVMET_IMPLEMENT_MACRO(add)
00374 TVMET_IMPLEMENT_MACRO(sub)
00375 TVMET_IMPLEMENT_MACRO(mul)
00376 namespace element_wise {
00377 TVMET_IMPLEMENT_MACRO(div)
00378 }
00379
00380 #undef TVMET_IMPLEMENT_MACRO
00381
00382
00383
00384
00385
00386
00387
00388 #define TVMET_IMPLEMENT_MACRO(NAME, POD) \
00389 template<class T, std::size_t Sz> \
00390 inline \
00391 XprVector< \
00392 XprBinOp< \
00393 Fcnl_##NAME< T, POD >, \
00394 VectorConstReference<T, Sz>, \
00395 XprLiteral< POD > \
00396 >, \
00397 Sz \
00398 > \
00399 NAME (const Vector<T, Sz>& lhs, POD rhs) { \
00400 typedef XprBinOp< \
00401 Fcnl_##NAME<T, POD >, \
00402 VectorConstReference<T, Sz>, \
00403 XprLiteral< POD > \
00404 > expr_type; \
00405 return XprVector<expr_type, Sz>( \
00406 expr_type(lhs.const_ref(), XprLiteral< POD >(rhs))); \
00407 } \
00408 \
00409 template<class T, std::size_t Sz> \
00410 inline \
00411 XprVector< \
00412 XprBinOp< \
00413 Fcnl_##NAME< POD, T>, \
00414 XprLiteral< POD >, \
00415 VectorConstReference<T, Sz> \
00416 >, \
00417 Sz \
00418 > \
00419 NAME (POD lhs, const Vector<T, Sz>& rhs) { \
00420 typedef XprBinOp< \
00421 Fcnl_##NAME< POD, T>, \
00422 XprLiteral< POD >, \
00423 VectorConstReference<T, Sz> \
00424 > expr_type; \
00425 return XprVector<expr_type, Sz>( \
00426 expr_type(XprLiteral< POD >(lhs), rhs.const_ref())); \
00427 }
00428
00429 TVMET_IMPLEMENT_MACRO(add, int)
00430 TVMET_IMPLEMENT_MACRO(sub, int)
00431 TVMET_IMPLEMENT_MACRO(mul, int)
00432 TVMET_IMPLEMENT_MACRO(div, int)
00433
00434 #if defined(TVMET_HAVE_LONG_LONG)
00435 TVMET_IMPLEMENT_MACRO(add, long long int)
00436 TVMET_IMPLEMENT_MACRO(sub, long long int)
00437 TVMET_IMPLEMENT_MACRO(mul, long long int)
00438 TVMET_IMPLEMENT_MACRO(div, long long int)
00439 #endif
00440
00441 TVMET_IMPLEMENT_MACRO(add, float)
00442 TVMET_IMPLEMENT_MACRO(sub, float)
00443 TVMET_IMPLEMENT_MACRO(mul, float)
00444 TVMET_IMPLEMENT_MACRO(div, float)
00445
00446 TVMET_IMPLEMENT_MACRO(add, double)
00447 TVMET_IMPLEMENT_MACRO(sub, double)
00448 TVMET_IMPLEMENT_MACRO(mul, double)
00449 TVMET_IMPLEMENT_MACRO(div, double)
00450
00451 #if defined(TVMET_HAVE_LONG_DOUBLE)
00452 TVMET_IMPLEMENT_MACRO(add, long double)
00453 TVMET_IMPLEMENT_MACRO(sub, long double)
00454 TVMET_IMPLEMENT_MACRO(mul, long double)
00455 TVMET_IMPLEMENT_MACRO(div, long double)
00456 #endif
00457
00458 #undef TVMET_IMPLEMENT_MACRO
00459
00460
00461 #if defined(TVMET_HAVE_COMPLEX)
00462
00463
00464
00465
00466
00467
00468 #define TVMET_IMPLEMENT_MACRO(NAME) \
00469 template<class T, std::size_t Sz> \
00470 inline \
00471 XprVector< \
00472 XprBinOp< \
00473 Fcnl_##NAME< std::complex<T>, std::complex<T> >, \
00474 VectorConstReference< std::complex<T>, Sz>, \
00475 XprLiteral< std::complex<T> > \
00476 >, \
00477 Sz \
00478 > \
00479 NAME (const Vector<std::complex<T>, Sz>& lhs, const std::complex<T>& rhs) { \
00480 typedef XprBinOp< \
00481 Fcnl_##NAME< std::complex<T>, std::complex<T> >, \
00482 VectorConstReference< std::complex<T>, Sz>, \
00483 XprLiteral< std::complex<T> > \
00484 > expr_type; \
00485 return XprVector<expr_type, Sz>( \
00486 expr_type(lhs.const_ref(), XprLiteral< std::complex<T> >(rhs))); \
00487 } \
00488 \
00489 template<class T, std::size_t Sz> \
00490 inline \
00491 XprVector< \
00492 XprBinOp< \
00493 Fcnl_##NAME< std::complex<T>, std::complex<T> >, \
00494 XprLiteral< std::complex<T> >, \
00495 VectorConstReference< std::complex<T>, Sz> \
00496 >, \
00497 Sz \
00498 > \
00499 NAME (const std::complex<T>& lhs, const Vector< std::complex<T>, Sz>& rhs) { \
00500 typedef XprBinOp< \
00501 Fcnl_##NAME< std::complex<T>, std::complex<T> >, \
00502 XprLiteral< std::complex<T> >, \
00503 VectorConstReference< std::complex<T>, Sz> \
00504 > expr_type; \
00505 return XprVector<expr_type, Sz>( \
00506 expr_type(XprLiteral< std::complex<T> >(lhs), rhs.const_ref())); \
00507 }
00508
00509 TVMET_IMPLEMENT_MACRO(add)
00510 TVMET_IMPLEMENT_MACRO(sub)
00511 TVMET_IMPLEMENT_MACRO(mul)
00512 TVMET_IMPLEMENT_MACRO(div)
00513
00514 #undef TVMET_IMPLEMENT_MACRO
00515
00516 #endif // defined(TVMET_HAVE_COMPLEX)
00517
00518
00519
00520
00521
00522
00523
00534 template<class T, std::size_t Sz>
00535 inline
00536 typename NumericTraits<T>::sum_type
00537 sum(const Vector<T, Sz>& v) {
00538 return meta::Vector<Sz>::sum(v);
00539 }
00540
00541
00552 template<class T, std::size_t Sz>
00553 inline
00554 typename NumericTraits<T>::sum_type
00555 product(const Vector<T, Sz>& v) {
00556 return meta::Vector<Sz>::product(v);
00557 }
00558
00559
00572 template<class T1, class T2, std::size_t Sz>
00573 inline
00574 typename PromoteTraits<T1, T2>::value_type
00575 dot(const Vector<T1, Sz>& lhs, const Vector<T2, Sz>& rhs) {
00576 return meta::Vector<Sz>::dot(lhs, rhs);
00577 }
00578
00579
00587 template<class T1, class T2>
00588 inline
00589 Vector<typename PromoteTraits<T1, T2>::value_type, 3>
00590 cross(const Vector<T1, 3>& lhs, const Vector<T2, 3>& rhs) {
00591 typedef typename PromoteTraits<T1, T2>::value_type value_type;
00592 return Vector<value_type, 3>(lhs(1)*rhs(2) - rhs(1)*lhs(2),
00593 rhs(0)*lhs(2) - lhs(0)*rhs(2),
00594 lhs(0)*rhs(1) - rhs(0)*lhs(1));
00595 }
00596
00597
00609 template<class T, std::size_t Sz>
00610 inline
00611 typename NumericTraits<T>::sum_type
00612 norm1(const Vector<T, Sz>& v) {
00613 return sum(abs(v));
00614 }
00615
00616
00630 template<class T, std::size_t Sz>
00631 inline
00632 typename NumericTraits<T>::sum_type
00633 norm2(const Vector<T, Sz>& v) {
00634 return static_cast<T>( std::sqrt(static_cast<typename NumericTraits<T>::float_type>(dot(v, v))) );
00635 }
00636
00637
00649 template<class T, std::size_t Sz>
00650 inline
00651 XprVector<
00652 XprBinOp<
00653 Fcnl_div<T, T>,
00654 VectorConstReference<T, Sz>,
00655 XprLiteral< T >
00656 >,
00657 Sz
00658 >
00659 normalize(const Vector<T, Sz>& v) {
00660 typedef XprBinOp<
00661 Fcnl_div<T, T>,
00662 VectorConstReference<T, Sz>,
00663 XprLiteral< T >
00664 > expr_type;
00665 return XprVector<expr_type, Sz>(
00666 expr_type(v.const_ref(), XprLiteral< T >(norm2(v))));
00667 }
00668
00669
00670
00671
00672
00673
00674
00680 template<class E, std::size_t Sz>
00681 inline
00682 Extremum<typename E::value_type, std::size_t, vector_tag>
00683 maximum(const XprVector<E, Sz>& e) {
00684 typedef typename E::value_type value_type;
00685
00686 value_type m_max(e(0));
00687 std::size_t m_idx(0);
00688
00689
00690 for(std::size_t i = 1; i != Sz; ++i) {
00691 if(e(i) > m_max) {
00692 m_max = e(i);
00693 m_idx = i;
00694 }
00695 }
00696
00697 return Extremum<value_type, std::size_t, vector_tag>(m_max, m_idx);
00698 }
00699
00700
00706 template<class T, std::size_t Sz>
00707 inline
00708 Extremum<T, std::size_t, vector_tag>
00709 maximum(const Vector<T, Sz>& v) { return maximum(v.as_expr()); }
00710
00711
00717 template<class E, std::size_t Sz>
00718 inline
00719 Extremum<typename E::value_type, std::size_t, vector_tag>
00720 minimum(const XprVector<E, Sz>& e) {
00721 typedef typename E::value_type value_type;
00722
00723 value_type m_min(e(0));
00724 std::size_t m_idx(0);
00725
00726
00727 for(std::size_t i = 1; i != Sz; ++i) {
00728 if(e(i) < m_min) {
00729 m_min = e(i);
00730 m_idx = i;
00731 }
00732 }
00733
00734 return Extremum<value_type, std::size_t, vector_tag>(m_min, m_idx);
00735 }
00736
00737
00743 template<class T, std::size_t Sz>
00744 inline
00745 Extremum<T, std::size_t, vector_tag>
00746 minimum(const Vector<T, Sz>& v) { return minimum(v.as_expr()); }
00747
00748
00754 template<class E, std::size_t Sz>
00755 inline
00756 typename E::value_type
00757 max(const XprVector<E, Sz>& e) {
00758 typedef typename E::value_type value_type;
00759
00760 value_type m_max(e(0));
00761
00762
00763 for(std::size_t i = 1; i != Sz; ++i)
00764 if(e(i) > m_max)
00765 m_max = e(i);
00766
00767 return m_max;
00768 }
00769
00770
00776 template<class T, std::size_t Sz>
00777 inline
00778 T max(const Vector<T, Sz>& v) {
00779 typedef T value_type;
00780 typedef typename Vector<T, Sz>::const_iterator const_iterator;
00781
00782 const_iterator iter(v.begin());
00783 const_iterator last(v.end());
00784 value_type temp(*iter);
00785
00786 for( ; iter != last; ++iter)
00787 if(*iter > temp)
00788 temp = *iter;
00789
00790 return temp;
00791 }
00792
00793
00799 template<class E, std::size_t Sz>
00800 inline
00801 typename E::value_type
00802 min(const XprVector<E, Sz>& e) {
00803 typedef typename E::value_type value_type;
00804
00805 value_type m_min(e(0));
00806
00807
00808 for(std::size_t i = 1; i != Sz; ++i)
00809 if(e(i) < m_min)
00810 m_min = e(i);
00811
00812 return m_min;
00813 }
00814
00815
00821 template<class T, std::size_t Sz>
00822 inline
00823 T min(const Vector<T, Sz>& v) {
00824 typedef T value_type;
00825 typedef typename Vector<T, Sz>::const_iterator const_iterator;
00826
00827 const_iterator iter(v.begin());
00828 const_iterator last(v.end());
00829 value_type temp(*iter);
00830
00831 for( ; iter != last; ++iter)
00832 if(*iter < temp)
00833 temp = *iter;
00834
00835 return temp;
00836 }
00837
00838
00863 template<class T, std::size_t Sz>
00864 inline
00865 XprVector<
00866 VectorConstReference<T, Sz>,
00867 Sz
00868 >
00869 cvector_ref(const T* mem) {
00870 typedef VectorConstReference<T, Sz> expr_type;
00871
00872 return XprVector<expr_type, Sz>(expr_type(mem));
00873 }
00874
00875
00876 }
00877
00878 #endif // TVMET_VECTOR_FUNCTIONS_H
00879
00880
00881
00882
00883