valarray_meta.h

Go to the documentation of this file.
00001 // The template and inlines for the -*- C++ -*- internal _Meta class. 00002 00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 2, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // You should have received a copy of the GNU General Public License along 00017 // with this library; see the file COPYING. If not, write to the Free 00018 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 00019 // USA. 00020 00021 // As a special exception, you may use this file as part of a free software 00022 // library without restriction. Specifically, if other files instantiate 00023 // templates or use macros or inline functions from this file, or you compile 00024 // this file and link it with other files to produce an executable, this 00025 // file does not by itself cause the resulting executable to be covered by 00026 // the GNU General Public License. This exception does not however 00027 // invalidate any other reasons why the executable file might be covered by 00028 // the GNU General Public License. 00029 00030 // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr> 00031 00032 /** @file valarray_meta.h 00033 * This is an internal header file, included by other library headers. 00034 * You should not attempt to use it directly. 00035 */ 00036 00037 #ifndef _CPP_VALARRAY_META_H 00038 #define _CPP_VALARRAY_META_H 1 00039 00040 #pragma GCC system_header 00041 00042 namespace std 00043 { 00044 // 00045 // Implementing a loosened valarray return value is tricky. 00046 // First we need to meet 26.3.1/3: we should not add more than 00047 // two levels of template nesting. Therefore we resort to template 00048 // template to "flatten" loosened return value types. 00049 // At some point we use partial specialization to remove one level 00050 // template nesting due to _Expr<> 00051 // 00052 00053 // This class is NOT defined. It doesn't need to. 00054 template<typename _Tp1, typename _Tp2> class _Constant; 00055 00056 // Implementations of unary functions applied to valarray<>s. 00057 // I use hard-coded object functions here instead of a generic 00058 // approach like pointers to function: 00059 // 1) correctness: some functions take references, others values. 00060 // we can't deduce the correct type afterwards. 00061 // 2) efficiency -- object functions can be easily inlined 00062 // 3) be Koenig-lookup-friendly 00063 00064 struct __abs 00065 { 00066 template<typename _Tp> 00067 _Tp operator()(const _Tp& __t) const { return abs(__t); } 00068 }; 00069 00070 struct __cos 00071 { 00072 template<typename _Tp> 00073 _Tp operator()(const _Tp& __t) const { return cos(__t); } 00074 }; 00075 00076 struct __acos 00077 { 00078 template<typename _Tp> 00079 _Tp operator()(const _Tp& __t) const { return acos(__t); } 00080 }; 00081 00082 struct __cosh 00083 { 00084 template<typename _Tp> 00085 _Tp operator()(const _Tp& __t) const { return cosh(__t); } 00086 }; 00087 00088 struct __sin 00089 { 00090 template<typename _Tp> 00091 _Tp operator()(const _Tp& __t) const { return sin(__t); } 00092 }; 00093 00094 struct __asin 00095 { 00096 template<typename _Tp> 00097 _Tp operator()(const _Tp& __t) const { return asin(__t); } 00098 }; 00099 00100 struct __sinh 00101 { 00102 template<typename _Tp> 00103 _Tp operator()(const _Tp& __t) const { return sinh(__t); } 00104 }; 00105 00106 struct __tan 00107 { 00108 template<typename _Tp> 00109 _Tp operator()(const _Tp& __t) const { return tan(__t); } 00110 }; 00111 00112 struct __atan 00113 { 00114 template<typename _Tp> 00115 _Tp operator()(const _Tp& __t) const { return atan(__t); } 00116 }; 00117 00118 struct __tanh 00119 { 00120 template<typename _Tp> 00121 _Tp operator()(const _Tp& __t) const { return tanh(__t); } 00122 }; 00123 00124 struct __exp 00125 { 00126 template<typename _Tp> 00127 _Tp operator()(const _Tp& __t) const { return exp(__t); } 00128 }; 00129 00130 struct __log 00131 { 00132 template<typename _Tp> 00133 _Tp operator()(const _Tp& __t) const { return log(__t); } 00134 }; 00135 00136 struct __log10 00137 { 00138 template<typename _Tp> 00139 _Tp operator()(const _Tp& __t) const { return log10(__t); } 00140 }; 00141 00142 struct __sqrt 00143 { 00144 template<typename _Tp> 00145 _Tp operator()(const _Tp& __t) const { return sqrt(__t); } 00146 }; 00147 00148 // In the past, we used to tailor operator applications semantics 00149 // to the specialization of standard function objects (i.e. plus<>, etc.) 00150 // That is incorrect. Therefore we provide our own surrogates. 00151 00152 struct __unary_plus 00153 { 00154 template<typename _Tp> 00155 _Tp operator()(const _Tp& __t) const { return +__t; } 00156 }; 00157 00158 struct __negate 00159 { 00160 template<typename _Tp> 00161 _Tp operator()(const _Tp& __t) const { return -__t; } 00162 }; 00163 00164 struct __bitwise_not 00165 { 00166 template<typename _Tp> 00167 _Tp operator()(const _Tp& __t) const { return ~__t; } 00168 }; 00169 00170 struct __plus 00171 { 00172 template<typename _Tp> 00173 _Tp operator()(const _Tp& __x, const _Tp& __y) const 00174 { return __x + __y; } 00175 }; 00176 00177 struct __minus 00178 { 00179 template<typename _Tp> 00180 _Tp operator()(const _Tp& __x, const _Tp& __y) const 00181 { return __x - __y; } 00182 }; 00183 00184 struct __multiplies 00185 { 00186 template<typename _Tp> 00187 _Tp operator()(const _Tp& __x, const _Tp& __y) const 00188 { return __x * __y; } 00189 }; 00190 00191 struct __divides 00192 { 00193 template<typename _Tp> 00194 _Tp operator()(const _Tp& __x, const _Tp& __y) const 00195 { return __x / __y; } 00196 }; 00197 00198 struct __modulus 00199 { 00200 template<typename _Tp> 00201 _Tp operator()(const _Tp& __x, const _Tp& __y) const 00202 { return __x % __y; } 00203 }; 00204 00205 struct __bitwise_xor 00206 { 00207 template<typename _Tp> 00208 _Tp operator()(const _Tp& __x, const _Tp& __y) const 00209 { return __x ^ __y; } 00210 }; 00211 00212 struct __bitwise_and 00213 { 00214 template<typename _Tp> 00215 _Tp operator()(const _Tp& __x, const _Tp& __y) const 00216 { return __x & __y; } 00217 }; 00218 00219 struct __bitwise_or 00220 { 00221 template<typename _Tp> 00222 _Tp operator()(const _Tp& __x, const _Tp& __y) const 00223 { return __x | __y; } 00224 }; 00225 00226 struct __shift_left 00227 { 00228 template<typename _Tp> 00229 _Tp operator()(const _Tp& __x, const _Tp& __y) const 00230 { return __x << __y; } 00231 }; 00232 00233 struct __shift_right 00234 { 00235 template<typename _Tp> 00236 _Tp operator()(const _Tp& __x, const _Tp& __y) const 00237 { return __x >> __y; } 00238 }; 00239 00240 struct __logical_and 00241 { 00242 template<typename _Tp> 00243 bool operator()(const _Tp& __x, const _Tp& __y) const 00244 { return __x && __y; } 00245 }; 00246 00247 struct __logical_or 00248 { 00249 template<typename _Tp> 00250 bool operator()(const _Tp& __x, const _Tp& __y) const 00251 { return __x || __y; } 00252 }; 00253 00254 struct __logical_not 00255 { 00256 template<typename _Tp> 00257 bool operator()(const _Tp& __x) const { return !__x; } 00258 }; 00259 00260 struct __equal_to 00261 { 00262 template<typename _Tp> 00263 bool operator()(const _Tp& __x, const _Tp& __y) const 00264 { return __x == __y; } 00265 }; 00266 00267 struct __not_equal_to 00268 { 00269 template<typename _Tp> 00270 bool operator()(const _Tp& __x, const _Tp& __y) const 00271 { return __x != __y; } 00272 }; 00273 00274 struct __less 00275 { 00276 template<typename _Tp> 00277 bool operator()(const _Tp& __x, const _Tp& __y) const 00278 { return __x < __y; } 00279 }; 00280 00281 struct __greater 00282 { 00283 template<typename _Tp> 00284 bool operator()(const _Tp& __x, const _Tp& __y) const 00285 { return __x > __y; } 00286 }; 00287 00288 struct __less_equal 00289 { 00290 template<typename _Tp> 00291 bool operator()(const _Tp& __x, const _Tp& __y) const 00292 { return __x <= __y; } 00293 }; 00294 00295 struct __greater_equal 00296 { 00297 template<typename _Tp> 00298 bool operator()(const _Tp& __x, const _Tp& __y) const 00299 { return __x >= __y; } 00300 }; 00301 00302 // The few binary functions we miss. 00303 struct __atan2 00304 { 00305 template<typename _Tp> 00306 _Tp operator()(const _Tp& __x, const _Tp& __y) const 00307 { return atan2(__x, __y); } 00308 }; 00309 00310 struct __pow 00311 { 00312 template<typename _Tp> 00313 _Tp operator()(const _Tp& __x, const _Tp& __y) const 00314 { return pow(__x, __y); } 00315 }; 00316 00317 00318 // We need these bits in order to recover the return type of 00319 // some functions/operators now that we're no longer using 00320 // function templates. 00321 template<typename, typename _Tp> 00322 struct __fun 00323 { 00324 typedef _Tp result_type; 00325 }; 00326 00327 // several specializations for relational operators. 00328 template<typename _Tp> 00329 struct __fun<__logical_not, _Tp> 00330 { 00331 typedef bool result_type; 00332 }; 00333 00334 template<typename _Tp> 00335 struct __fun<__logical_and, _Tp> 00336 { 00337 typedef bool result_type; 00338 }; 00339 00340 template<typename _Tp> 00341 struct __fun<__logical_or, _Tp> 00342 { 00343 typedef bool result_type; 00344 }; 00345 00346 template<typename _Tp> 00347 struct __fun<__less, _Tp> 00348 { 00349 typedef bool result_type; 00350 }; 00351 00352 template<typename _Tp> 00353 struct __fun<__greater, _Tp> 00354 { 00355 typedef bool result_type; 00356 }; 00357 00358 template<typename _Tp> 00359 struct __fun<__less_equal, _Tp> 00360 { 00361 typedef bool result_type; 00362 }; 00363 00364 template<typename _Tp> 00365 struct __fun<__greater_equal, _Tp> 00366 { 00367 typedef bool result_type; 00368 }; 00369 00370 template<typename _Tp> 00371 struct __fun<__equal_to, _Tp> 00372 { 00373 typedef bool result_type; 00374 }; 00375 00376 template<typename _Tp> 00377 struct __fun<__not_equal_to, _Tp> 00378 { 00379 typedef bool result_type; 00380 }; 00381 00382 // 00383 // Apply function taking a value/const reference closure 00384 // 00385 00386 template<typename _Dom, typename _Arg> 00387 class _FunBase 00388 { 00389 public: 00390 typedef typename _Dom::value_type value_type; 00391 00392 _FunBase(const _Dom& __e, value_type __f(_Arg)) 00393 : _M_expr(__e), _M_func(__f) {} 00394 00395 value_type operator[](size_t __i) const 00396 { return _M_func (_M_expr[__i]); } 00397 00398 size_t size() const { return _M_expr.size ();} 00399 00400 private: 00401 const _Dom& _M_expr; 00402 value_type (*_M_func)(_Arg); 00403 }; 00404 00405 template<class _Dom> 00406 struct _ValFunClos<_Expr,_Dom> : _FunBase<_Dom, typename _Dom::value_type> 00407 { 00408 typedef _FunBase<_Dom, typename _Dom::value_type> _Base; 00409 typedef typename _Base::value_type value_type; 00410 typedef value_type _Tp; 00411 00412 _ValFunClos(const _Dom& __e, _Tp __f(_Tp)) : _Base(__e, __f) {} 00413 }; 00414 00415 template<typename _Tp> 00416 struct _ValFunClos<_ValArray,_Tp> : _FunBase<valarray<_Tp>, _Tp> 00417 { 00418 typedef _FunBase<valarray<_Tp>, _Tp> _Base; 00419 typedef _Tp value_type; 00420 00421 _ValFunClos(const valarray<_Tp>& __v, _Tp __f(_Tp)) : _Base(__v, __f) {} 00422 }; 00423 00424 template<class _Dom> 00425 struct _RefFunClos<_Expr,_Dom> : 00426 _FunBase<_Dom, const typename _Dom::value_type&> 00427 { 00428 typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base; 00429 typedef typename _Base::value_type value_type; 00430 typedef value_type _Tp; 00431 00432 _RefFunClos(const _Dom& __e, _Tp __f(const _Tp&)) 00433 : _Base(__e, __f) {} 00434 }; 00435 00436 template<typename _Tp> 00437 struct _RefFunClos<_ValArray,_Tp> : _FunBase<valarray<_Tp>, const _Tp&> 00438 { 00439 typedef _FunBase<valarray<_Tp>, const _Tp&> _Base; 00440 typedef _Tp value_type; 00441 00442 _RefFunClos(const valarray<_Tp>& __v, _Tp __f(const _Tp&)) 00443 : _Base(__v, __f) {} 00444 }; 00445 00446 // 00447 // Unary expression closure. 00448 // 00449 00450 template<class _Oper, class _Arg> 00451 class _UnBase 00452 { 00453 public: 00454 typedef typename _Arg::value_type _Vt; 00455 typedef typename __fun<_Oper, _Vt>::result_type value_type; 00456 00457 _UnBase(const _Arg& __e) : _M_expr(__e) {} 00458 00459 value_type operator[](size_t __i) const 00460 { return _Oper()(_M_expr[__i]); } 00461 00462 size_t size() const { return _M_expr.size(); } 00463 00464 private: 00465 const _Arg& _M_expr; 00466 }; 00467 00468 template<class _Oper, class _Dom> 00469 struct _UnClos<_Oper, _Expr, _Dom> : _UnBase<_Oper, _Dom> 00470 { 00471 typedef _Dom _Arg; 00472 typedef _UnBase<_Oper, _Dom> _Base; 00473 typedef typename _Base::value_type value_type; 00474 00475 _UnClos(const _Arg& __e) : _Base(__e) {} 00476 }; 00477 00478 template<class _Oper, typename _Tp> 00479 struct _UnClos<_Oper, _ValArray, _Tp> : _UnBase<_Oper, valarray<_Tp> > 00480 { 00481 typedef valarray<_Tp> _Arg; 00482 typedef _UnBase<_Oper, valarray<_Tp> > _Base; 00483 typedef typename _Base::value_type value_type; 00484 00485 _UnClos(const _Arg& __e) : _Base(__e) {} 00486 }; 00487 00488 00489 // 00490 // Binary expression closure. 00491 // 00492 00493 template<class _Oper, class _FirstArg, class _SecondArg> 00494 class _BinBase 00495 { 00496 public: 00497 typedef typename _FirstArg::value_type _Vt; 00498 typedef typename __fun<_Oper, _Vt>::result_type value_type; 00499 00500 _BinBase(const _FirstArg& __e1, const _SecondArg& __e2) 00501 : _M_expr1(__e1), _M_expr2(__e2) {} 00502 00503 value_type operator[](size_t __i) const 00504 { return _Oper()(_M_expr1[__i], _M_expr2[__i]); } 00505 00506 size_t size() const { return _M_expr1.size(); } 00507 00508 private: 00509 const _FirstArg& _M_expr1; 00510 const _SecondArg& _M_expr2; 00511 }; 00512 00513 00514 template<class _Oper, class _Clos> 00515 class _BinBase2 00516 { 00517 public: 00518 typedef typename _Clos::value_type _Vt; 00519 typedef typename __fun<_Oper, _Vt>::result_type value_type; 00520 00521 _BinBase2(const _Clos& __e, const _Vt& __t) 00522 : _M_expr1(__e), _M_expr2(__t) {} 00523 00524 value_type operator[](size_t __i) const 00525 { return _Oper()(_M_expr1[__i], _M_expr2); } 00526 00527 size_t size() const { return _M_expr1.size(); } 00528 00529 private: 00530 const _Clos& _M_expr1; 00531 const _Vt& _M_expr2; 00532 }; 00533 00534 template<class _Oper, class _Clos> 00535 class _BinBase1 00536 { 00537 public: 00538 typedef typename _Clos::value_type _Vt; 00539 typedef typename __fun<_Oper, _Vt>::result_type value_type; 00540 00541 _BinBase1(const _Vt& __t, const _Clos& __e) 00542 : _M_expr1(__t), _M_expr2(__e) {} 00543 00544 value_type operator[](size_t __i) const 00545 { return _Oper()(_M_expr1, _M_expr2[__i]); } 00546 00547 size_t size() const { return _M_expr2.size(); } 00548 00549 private: 00550 const _Vt& _M_expr1; 00551 const _Clos& _M_expr2; 00552 }; 00553 00554 template<class _Oper, class _Dom1, class _Dom2> 00555 struct _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2> 00556 : _BinBase<_Oper,_Dom1,_Dom2> 00557 { 00558 typedef _BinBase<_Oper,_Dom1,_Dom2> _Base; 00559 typedef typename _Base::value_type value_type; 00560 00561 _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {} 00562 }; 00563 00564 template<class _Oper, typename _Tp> 00565 struct _BinClos<_Oper,_ValArray,_ValArray,_Tp,_Tp> 00566 : _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > 00567 { 00568 typedef _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > _Base; 00569 typedef _Tp value_type; 00570 00571 _BinClos(const valarray<_Tp>& __v, const valarray<_Tp>& __w) 00572 : _Base(__v, __w) {} 00573 }; 00574 00575 template<class _Oper, class _Dom> 00576 struct _BinClos<_Oper,_Expr,_ValArray,_Dom,typename _Dom::value_type> 00577 : _BinBase<_Oper,_Dom,valarray<typename _Dom::value_type> > 00578 { 00579 typedef typename _Dom::value_type _Tp; 00580 typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base; 00581 typedef typename _Base::value_type value_type; 00582 00583 _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2) 00584 : _Base(__e1, __e2) {} 00585 }; 00586 00587 template<class _Oper, class _Dom> 00588 struct _BinClos<_Oper,_ValArray,_Expr,typename _Dom::value_type,_Dom> 00589 : _BinBase<_Oper,valarray<typename _Dom::value_type>,_Dom> 00590 { 00591 typedef typename _Dom::value_type _Tp; 00592 typedef _BinBase<_Oper,valarray<_Tp>,_Dom> _Base; 00593 typedef typename _Base::value_type value_type; 00594 00595 _BinClos(const valarray<_Tp>& __e1, const _Dom& __e2) 00596 : _Base(__e1, __e2) {} 00597 }; 00598 00599 template<class _Oper, class _Dom> 00600 struct _BinClos<_Oper,_Expr,_Constant,_Dom,typename _Dom::value_type> 00601 : _BinBase2<_Oper,_Dom> 00602 { 00603 typedef typename _Dom::value_type _Tp; 00604 typedef _BinBase2<_Oper,_Dom> _Base; 00605 typedef typename _Base::value_type value_type; 00606 00607 _BinClos(const _Dom& __e1, const _Tp& __e2) : _Base(__e1, __e2) {} 00608 }; 00609 00610 template<class _Oper, class _Dom> 00611 struct _BinClos<_Oper,_Constant,_Expr,typename _Dom::value_type,_Dom> 00612 : _BinBase1<_Oper,_Dom> 00613 { 00614 typedef typename _Dom::value_type _Tp; 00615 typedef _BinBase1<_Oper,_Dom> _Base; 00616 typedef typename _Base::value_type value_type; 00617 00618 _BinClos(const _Tp& __e1, const _Dom& __e2) : _Base(__e1, __e2) {} 00619 }; 00620 00621 template<class _Oper, typename _Tp> 00622 struct _BinClos<_Oper,_ValArray,_Constant,_Tp,_Tp> 00623 : _BinBase2<_Oper,valarray<_Tp> > 00624 { 00625 typedef _BinBase2<_Oper,valarray<_Tp> > _Base; 00626 typedef typename _Base::value_type value_type; 00627 00628 _BinClos(const valarray<_Tp>& __v, const _Tp& __t) : _Base(__v, __t) {} 00629 }; 00630 00631 template<class _Oper, typename _Tp> 00632 struct _BinClos<_Oper,_Constant,_ValArray,_Tp,_Tp> 00633 : _BinBase1<_Oper,valarray<_Tp> > 00634 { 00635 typedef _BinBase1<_Oper,valarray<_Tp> > _Base; 00636 typedef typename _Base::value_type value_type; 00637 00638 _BinClos(const _Tp& __t, const valarray<_Tp>& __v) : _Base(__t, __v) {} 00639 }; 00640 00641 00642 // 00643 // slice_array closure. 00644 // 00645 template<typename _Dom> class _SBase { 00646 public: 00647 typedef typename _Dom::value_type value_type; 00648 00649 _SBase (const _Dom& __e, const slice& __s) 00650 : _M_expr (__e), _M_slice (__s) {} 00651 value_type operator[] (size_t __i) const 00652 { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; } 00653 size_t size() const { return _M_slice.size (); } 00654 00655 private: 00656 const _Dom& _M_expr; 00657 const slice& _M_slice; 00658 }; 00659 00660 template<typename _Tp> class _SBase<_Array<_Tp> > { 00661 public: 00662 typedef _Tp value_type; 00663 00664 _SBase (_Array<_Tp> __a, const slice& __s) 00665 : _M_array (__a._M_data+__s.start()), _M_size (__s.size()), 00666 _M_stride (__s.stride()) {} 00667 value_type operator[] (size_t __i) const 00668 { return _M_array._M_data[__i * _M_stride]; } 00669 size_t size() const { return _M_size; } 00670 00671 private: 00672 const _Array<_Tp> _M_array; 00673 const size_t _M_size; 00674 const size_t _M_stride; 00675 }; 00676 00677 template<class _Dom> struct _SClos<_Expr,_Dom> : _SBase<_Dom> { 00678 typedef _SBase<_Dom> _Base; 00679 typedef typename _Base::value_type value_type; 00680 00681 _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {} 00682 }; 00683 00684 template<typename _Tp> 00685 struct _SClos<_ValArray,_Tp> : _SBase<_Array<_Tp> > { 00686 typedef _SBase<_Array<_Tp> > _Base; 00687 typedef _Tp value_type; 00688 00689 _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {} 00690 }; 00691 00692 // 00693 // gslice_array closure. 00694 // 00695 template<class _Dom> class _GBase { 00696 public: 00697 typedef typename _Dom::value_type value_type; 00698 00699 _GBase (const _Dom& __e, const valarray<size_t>& __i) 00700 : _M_expr (__e), _M_index(__i) {} 00701 value_type operator[] (size_t __i) const 00702 { return _M_expr[_M_index[__i]]; } 00703 size_t size () const { return _M_index.size(); } 00704 00705 private: 00706 const _Dom& _M_expr; 00707 const valarray<size_t>& _M_index; 00708 }; 00709 00710 template<typename _Tp> class _GBase<_Array<_Tp> > { 00711 public: 00712 typedef _Tp value_type; 00713 00714 _GBase (_Array<_Tp> __a, const valarray<size_t>& __i) 00715 : _M_array (__a), _M_index(__i) {} 00716 value_type operator[] (size_t __i) const 00717 { return _M_array._M_data[_M_index[__i]]; } 00718 size_t size () const { return _M_index.size(); } 00719 00720 private: 00721 const _Array<_Tp> _M_array; 00722 const valarray<size_t>& _M_index; 00723 }; 00724 00725 template<class _Dom> struct _GClos<_Expr,_Dom> : _GBase<_Dom> { 00726 typedef _GBase<_Dom> _Base; 00727 typedef typename _Base::value_type value_type; 00728 00729 _GClos (const _Dom& __e, const valarray<size_t>& __i) 00730 : _Base (__e, __i) {} 00731 }; 00732 00733 template<typename _Tp> 00734 struct _GClos<_ValArray,_Tp> : _GBase<_Array<_Tp> > { 00735 typedef _GBase<_Array<_Tp> > _Base; 00736 typedef typename _Base::value_type value_type; 00737 00738 _GClos (_Array<_Tp> __a, const valarray<size_t>& __i) 00739 : _Base (__a, __i) {} 00740 }; 00741 00742 // 00743 // indirect_array closure 00744 // 00745 00746 template<class _Dom> class _IBase { 00747 public: 00748 typedef typename _Dom::value_type value_type; 00749 00750 _IBase (const _Dom& __e, const valarray<size_t>& __i) 00751 : _M_expr (__e), _M_index (__i) {} 00752 value_type operator[] (size_t __i) const 00753 { return _M_expr[_M_index[__i]]; } 00754 size_t size() const { return _M_index.size(); } 00755 00756 private: 00757 const _Dom& _M_expr; 00758 const valarray<size_t>& _M_index; 00759 }; 00760 00761 template<class _Dom> struct _IClos<_Expr,_Dom> : _IBase<_Dom> { 00762 typedef _IBase<_Dom> _Base; 00763 typedef typename _Base::value_type value_type; 00764 00765 _IClos (const _Dom& __e, const valarray<size_t>& __i) 00766 : _Base (__e, __i) {} 00767 }; 00768 00769 template<typename _Tp> 00770 struct _IClos<_ValArray,_Tp> : _IBase<valarray<_Tp> > { 00771 typedef _IBase<valarray<_Tp> > _Base; 00772 typedef _Tp value_type; 00773 00774 _IClos (const valarray<_Tp>& __a, const valarray<size_t>& __i) 00775 : _Base (__a, __i) {} 00776 }; 00777 00778 // 00779 // class _Expr 00780 // 00781 template<class _Clos, typename _Tp> 00782 class _Expr 00783 { 00784 public: 00785 typedef _Tp value_type; 00786 00787 _Expr(const _Clos&); 00788 00789 const _Clos& operator()() const; 00790 00791 value_type operator[](size_t) const; 00792 valarray<value_type> operator[](slice) const; 00793 valarray<value_type> operator[](const gslice&) const; 00794 valarray<value_type> operator[](const valarray<bool>&) const; 00795 valarray<value_type> operator[](const valarray<size_t>&) const; 00796 00797 _Expr<_UnClos<__unary_plus,std::_Expr,_Clos>, value_type> 00798 operator+() const; 00799 00800 _Expr<_UnClos<__negate,std::_Expr,_Clos>, value_type> 00801 operator-() const; 00802 00803 _Expr<_UnClos<__bitwise_not,std::_Expr,_Clos>, value_type> 00804 operator~() const; 00805 00806 _Expr<_UnClos<__logical_not,std::_Expr,_Clos>, bool> 00807 operator!() const; 00808 00809 size_t size() const; 00810 value_type sum() const; 00811 00812 valarray<value_type> shift(int) const; 00813 valarray<value_type> cshift(int) const; 00814 00815 value_type min() const; 00816 value_type max() const; 00817 00818 valarray<value_type> apply(value_type (*)(const value_type&)) const; 00819 valarray<value_type> apply(value_type (*)(value_type)) const; 00820 00821 private: 00822 const _Clos _M_closure; 00823 }; 00824 00825 template<class _Clos, typename _Tp> 00826 inline 00827 _Expr<_Clos,_Tp>::_Expr(const _Clos& __c) : _M_closure(__c) {} 00828 00829 template<class _Clos, typename _Tp> 00830 inline const _Clos& 00831 _Expr<_Clos,_Tp>::operator()() const 00832 { return _M_closure; } 00833 00834 template<class _Clos, typename _Tp> 00835 inline _Tp 00836 _Expr<_Clos,_Tp>::operator[](size_t __i) const 00837 { return _M_closure[__i]; } 00838 00839 template<class _Clos, typename _Tp> 00840 inline valarray<_Tp> 00841 _Expr<_Clos,_Tp>::operator[](slice __s) const 00842 { return _M_closure[__s]; } 00843 00844 template<class _Clos, typename _Tp> 00845 inline valarray<_Tp> 00846 _Expr<_Clos,_Tp>::operator[](const gslice& __gs) const 00847 { return _M_closure[__gs]; } 00848 00849 template<class _Clos, typename _Tp> 00850 inline valarray<_Tp> 00851 _Expr<_Clos,_Tp>::operator[](const valarray<bool>& __m) const 00852 { return _M_closure[__m]; } 00853 00854 template<class _Clos, typename _Tp> 00855 inline valarray<_Tp> 00856 _Expr<_Clos,_Tp>::operator[](const valarray<size_t>& __i) const 00857 { return _M_closure[__i]; } 00858 00859 template<class _Clos, typename _Tp> 00860 inline size_t 00861 _Expr<_Clos,_Tp>::size() const { return _M_closure.size (); } 00862 00863 template<class _Clos, typename _Tp> 00864 inline valarray<_Tp> 00865 _Expr<_Clos, _Tp>::shift(int __n) const 00866 { return valarray<_Tp>(_M_closure).shift(__n); } 00867 00868 template<class _Clos, typename _Tp> 00869 inline valarray<_Tp> 00870 _Expr<_Clos, _Tp>::cshift(int __n) const 00871 { return valarray<_Tp>(_M_closure).cshift(__n); } 00872 00873 template<class _Clos, typename _Tp> 00874 inline valarray<_Tp> 00875 _Expr<_Clos, _Tp>::apply(_Tp __f(const _Tp&)) const 00876 { return valarray<_Tp>(_M_closure).apply(__f); } 00877 00878 template<class _Clos, typename _Tp> 00879 inline valarray<_Tp> 00880 _Expr<_Clos, _Tp>::apply(_Tp __f(_Tp)) const 00881 { return valarray<_Tp>(_M_closure).apply(__f); } 00882 00883 // XXX: replace this with a more robust summation algorithm. 00884 template<class _Clos, typename _Tp> 00885 inline _Tp 00886 _Expr<_Clos,_Tp>::sum() const 00887 { 00888 size_t __n = _M_closure.size(); 00889 if (__n == 0) 00890 return _Tp(); 00891 else 00892 { 00893 _Tp __s = _M_closure[--__n]; 00894 while (__n != 0) 00895 __s += _M_closure[--__n]; 00896 return __s; 00897 } 00898 } 00899 00900 template<class _Clos, typename _Tp> 00901 inline _Tp 00902 _Expr<_Clos, _Tp>::min() const 00903 { return __valarray_min(_M_closure); } 00904 00905 template<class _Clos, typename _Tp> 00906 inline _Tp 00907 _Expr<_Clos, _Tp>::max() const 00908 { return __valarray_max(_M_closure); } 00909 00910 template<class _Dom, typename _Tp> 00911 inline _Expr<_UnClos<__logical_not,_Expr,_Dom>, bool> 00912 _Expr<_Dom,_Tp>::operator!() const 00913 { 00914 typedef _UnClos<__logical_not,std::_Expr,_Dom> _Closure; 00915 return _Expr<_Closure,_Tp>(_Closure(this->_M_closure)); 00916 } 00917 00918 #define _DEFINE_EXPR_UNARY_OPERATOR(_Op, _Name) \ 00919 template<class _Dom, typename _Tp> \ 00920 inline _Expr<_UnClos<_Name,std::_Expr,_Dom>,_Tp> \ 00921 _Expr<_Dom,_Tp>::operator _Op() const \ 00922 { \ 00923 typedef _UnClos<_Name,std::_Expr,_Dom> _Closure; \ 00924 return _Expr<_Closure,_Tp>(_Closure(this->_M_closure)); \ 00925 } 00926 00927 _DEFINE_EXPR_UNARY_OPERATOR(+, __unary_plus) 00928 _DEFINE_EXPR_UNARY_OPERATOR(-, __negate) 00929 _DEFINE_EXPR_UNARY_OPERATOR(~, __bitwise_not) 00930 00931 #undef _DEFINE_EXPR_UNARY_OPERATOR 00932 00933 00934 #define _DEFINE_EXPR_BINARY_OPERATOR(_Op, _Name) \ 00935 template<class _Dom1, class _Dom2> \ 00936 inline _Expr<_BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2>, \ 00937 typename __fun<_Name, typename _Dom1::value_type>::result_type>\ 00938 operator _Op(const _Expr<_Dom1,typename _Dom1::value_type>& __v, \ 00939 const _Expr<_Dom2,typename _Dom2::value_type>& __w) \ 00940 { \ 00941 typedef typename _Dom1::value_type _Arg; \ 00942 typedef typename __fun<_Name, _Arg>::result_type _Value; \ 00943 typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure; \ 00944 return _Expr<_Closure,_Value>(_Closure(__v(), __w())); \ 00945 } \ 00946 \ 00947 template<class _Dom> \ 00948 inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>,\ 00949 typename __fun<_Name, typename _Dom::value_type>::result_type>\ 00950 operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __v, \ 00951 const typename _Dom::value_type& __t) \ 00952 { \ 00953 typedef typename _Dom::value_type _Arg; \ 00954 typedef typename __fun<_Name, _Arg>::result_type _Value; \ 00955 typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure; \ 00956 return _Expr<_Closure,_Value>(_Closure(__v(), __t)); \ 00957 } \ 00958 \ 00959 template<class _Dom> \ 00960 inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>,\ 00961 typename __fun<_Name, typename _Dom::value_type>::result_type>\ 00962 operator _Op(const typename _Dom::value_type& __t, \ 00963 const _Expr<_Dom,typename _Dom::value_type>& __v) \ 00964 { \ 00965 typedef typename _Dom::value_type _Arg; \ 00966 typedef typename __fun<_Name, _Arg>::result_type _Value; \ 00967 typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure; \ 00968 return _Expr<_Closure,_Value>(_Closure(__t, __v())); \ 00969 } \ 00970 \ 00971 template<class _Dom> \ 00972 inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>,\ 00973 typename __fun<_Name, typename _Dom::value_type>::result_type>\ 00974 operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e, \ 00975 const valarray<typename _Dom::value_type>& __v) \ 00976 { \ 00977 typedef typename _Dom::value_type _Arg; \ 00978 typedef typename __fun<_Name, _Arg>::result_type _Value; \ 00979 typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Arg> _Closure; \ 00980 return _Expr<_Closure,_Value>(_Closure(__e(), __v)); \ 00981 } \ 00982 \ 00983 template<class _Dom> \ 00984 inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>,\ 00985 typename __fun<_Name, typename _Dom::value_type>::result_type>\ 00986 operator _Op(const valarray<typename _Dom::value_type>& __v, \ 00987 const _Expr<_Dom,typename _Dom::value_type>& __e) \ 00988 { \ 00989 typedef typename _Dom::value_type _Tp; \ 00990 typedef typename __fun<_Name, _Tp>::result_type _Value; \ 00991 typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure; \ 00992 return _Expr<_Closure,_Value> (_Closure (__v, __e ())); \ 00993 } 00994 00995 _DEFINE_EXPR_BINARY_OPERATOR(+, __plus) 00996 _DEFINE_EXPR_BINARY_OPERATOR(-, __minus) 00997 _DEFINE_EXPR_BINARY_OPERATOR(*, __multiplies) 00998 _DEFINE_EXPR_BINARY_OPERATOR(/, __divides) 00999 _DEFINE_EXPR_BINARY_OPERATOR(%, __modulus) 01000 _DEFINE_EXPR_BINARY_OPERATOR(^, __bitwise_xor) 01001 _DEFINE_EXPR_BINARY_OPERATOR(&, __bitwise_and) 01002 _DEFINE_EXPR_BINARY_OPERATOR(|, __bitwise_or) 01003 _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left) 01004 _DEFINE_EXPR_BINARY_OPERATOR(>>, __shift_right) 01005 _DEFINE_EXPR_BINARY_OPERATOR(&&, __logical_and) 01006 _DEFINE_EXPR_BINARY_OPERATOR(||, __logical_or) 01007 _DEFINE_EXPR_BINARY_OPERATOR(==, __equal_to) 01008 _DEFINE_EXPR_BINARY_OPERATOR(!=, __not_equal_to) 01009 _DEFINE_EXPR_BINARY_OPERATOR(<, __less) 01010 _DEFINE_EXPR_BINARY_OPERATOR(>, __greater) 01011 _DEFINE_EXPR_BINARY_OPERATOR(<=, __less_equal) 01012 _DEFINE_EXPR_BINARY_OPERATOR(>=, __greater_equal) 01013 01014 #undef _DEFINE_EXPR_BINARY_OPERATOR 01015 01016 #define _DEFINE_EXPR_UNARY_FUNCTION(_Name) \ 01017 template<class _Dom> \ 01018 inline _Expr<_UnClos<__##_Name,_Expr,_Dom>,typename _Dom::value_type>\ 01019 _Name(const _Expr<_Dom,typename _Dom::value_type>& __e) \ 01020 { \ 01021 typedef typename _Dom::value_type _Tp; \ 01022 typedef _UnClos<__##_Name,_Expr,_Dom> _Closure; \ 01023 return _Expr<_Closure,_Tp>(_Closure(__e())); \ 01024 } \ 01025 \ 01026 template<typename _Tp> \ 01027 inline _Expr<_UnClos<__##_Name,_ValArray,_Tp>,_Tp> \ 01028 _Name(const valarray<_Tp>& __v) \ 01029 { \ 01030 typedef _UnClos<__##_Name,_ValArray,_Tp> _Closure; \ 01031 return _Expr<_Closure,_Tp>(_Closure(__v)); \ 01032 } 01033 01034 _DEFINE_EXPR_UNARY_FUNCTION(abs) 01035 _DEFINE_EXPR_UNARY_FUNCTION(cos) 01036 _DEFINE_EXPR_UNARY_FUNCTION(acos) 01037 _DEFINE_EXPR_UNARY_FUNCTION(cosh) 01038 _DEFINE_EXPR_UNARY_FUNCTION(sin) 01039 _DEFINE_EXPR_UNARY_FUNCTION(asin) 01040 _DEFINE_EXPR_UNARY_FUNCTION(sinh) 01041 _DEFINE_EXPR_UNARY_FUNCTION(tan) 01042 _DEFINE_EXPR_UNARY_FUNCTION(tanh) 01043 _DEFINE_EXPR_UNARY_FUNCTION(atan) 01044 _DEFINE_EXPR_UNARY_FUNCTION(exp) 01045 _DEFINE_EXPR_UNARY_FUNCTION(log) 01046 _DEFINE_EXPR_UNARY_FUNCTION(log10) 01047 _DEFINE_EXPR_UNARY_FUNCTION(sqrt) 01048 01049 #undef _DEFINE_EXPR_UNARY_FUNCTION 01050 01051 #define _DEFINE_EXPR_BINARY_FUNCTION(_Fun) \ 01052 template<class _Dom1, class _Dom2> \ 01053 inline _Expr<_BinClos<__##_Fun,_Expr,_Expr,_Dom1,_Dom2>, \ 01054 typename _Dom1::value_type> \ 01055 _Fun(const _Expr<_Dom1,typename _Dom1::value_type>& __e1, \ 01056 const _Expr<_Dom2,typename _Dom2::value_type>& __e2) \ 01057 { \ 01058 typedef typename _Dom1::value_type _Tp; \ 01059 typedef _BinClos<__##_Fun,_Expr,_Expr,_Dom1,_Dom2> _Closure; \ 01060 return _Expr<_Closure,_Tp>(_Closure(__e1(), __e2())); \ 01061 } \ 01062 \ 01063 template<class _Dom> \ 01064 inline _Expr<_BinClos<__##_Fun, _Expr, _ValArray, _Dom, \ 01065 typename _Dom::value_type>, \ 01066 typename _Dom::value_type> \ 01067 _Fun(const _Expr<_Dom,typename _Dom::value_type>& __e, \ 01068 const valarray<typename _Dom::value_type>& __v) \ 01069 { \ 01070 typedef typename _Dom::value_type _Tp; \ 01071 typedef _BinClos<__##_Fun, _Expr, _ValArray, _Dom, _Tp> _Closure;\ 01072 return _Expr<_Closure,_Tp>(_Closure(__e(), __v)); \ 01073 } \ 01074 \ 01075 template<class _Dom> \ 01076 inline _Expr<_BinClos<__##_Fun, _ValArray, _Expr, \ 01077 typename _Dom::value_type,_Dom>, \ 01078 typename _Dom::value_type> \ 01079 _Fun(const valarray<typename _Dom::valarray>& __v, \ 01080 const _Expr<_Dom,typename _Dom::value_type>& __e) \ 01081 { \ 01082 typedef typename _Dom::value_type _Tp; \ 01083 typedef _BinClos<__##_Fun,_ValArray,_Expr,_Tp,_Dom> _Closure; \ 01084 return _Expr<_Closure,_Tp>(_Closure(__v, __e())); \ 01085 } \ 01086 \ 01087 template<class _Dom> \ 01088 inline _Expr<_BinClos<__##_Fun,_Expr,_Constant,_Dom, \ 01089 typename _Dom::value_type>, \ 01090 typename _Dom::value_type> \ 01091 _Fun(const _Expr<_Dom, typename _Dom::value_type>& __e, \ 01092 const typename _Dom::value_type& __t) \ 01093 { \ 01094 typedef typename _Dom::value_type _Tp; \ 01095 typedef _BinClos<__##_Fun,_Expr,_Constant,_Dom,_Tp> _Closure; \ 01096 return _Expr<_Closure,_Tp>(_Closure(__e(), __t)); \ 01097 } \ 01098 \ 01099 template<class _Dom> \ 01100 inline _Expr<_BinClos<__##_Fun,_Constant,_Expr, \ 01101 typename _Dom::value_type,_Dom>, \ 01102 typename _Dom::value_type> \ 01103 _Fun(const typename _Dom::value_type& __t, \ 01104 const _Expr<_Dom,typename _Dom::value_type>& __e) \ 01105 { \ 01106 typedef typename _Dom::value_type _Tp; \ 01107 typedef _BinClos<__##_Fun, _Constant,_Expr,_Tp,_Dom> _Closure; \ 01108 return _Expr<_Closure,_Tp>(_Closure(__t, __e())); \ 01109 } \ 01110 \ 01111 template<typename _Tp> \ 01112 inline _Expr<_BinClos<__##_Fun,_ValArray,_ValArray,_Tp,_Tp>, _Tp> \ 01113 _Fun(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \ 01114 { \ 01115 typedef _BinClos<__##_Fun,_ValArray,_ValArray,_Tp,_Tp> _Closure; \ 01116 return _Expr<_Closure,_Tp>(_Closure(__v, __w)); \ 01117 } \ 01118 \ 01119 template<typename _Tp> \ 01120 inline _Expr<_BinClos<__##_Fun,_ValArray,_Constant,_Tp,_Tp>,_Tp> \ 01121 _Fun(const valarray<_Tp>& __v, const _Tp& __t) \ 01122 { \ 01123 typedef _BinClos<__##_Fun,_ValArray,_Constant,_Tp,_Tp> _Closure; \ 01124 return _Expr<_Closure,_Tp>(_Closure(__v, __t)); \ 01125 } \ 01126 \ 01127 template<typename _Tp> \ 01128 inline _Expr<_BinClos<__##_Fun,_Constant,_ValArray,_Tp,_Tp>,_Tp> \ 01129 _Fun(const _Tp& __t, const valarray<_Tp>& __v) \ 01130 { \ 01131 typedef _BinClos<__##_Fun,_Constant,_ValArray,_Tp,_Tp> _Closure; \ 01132 return _Expr<_Closure,_Tp>(_Closure(__t, __v)); \ 01133 } 01134 01135 _DEFINE_EXPR_BINARY_FUNCTION(atan2) 01136 _DEFINE_EXPR_BINARY_FUNCTION(pow) 01137 01138 #undef _DEFINE_EXPR_BINARY_FUNCTION 01139 01140 } // std:: 01141 01142 01143 #endif /* _CPP_VALARRAY_META_H */ 01144 01145 // Local Variables: 01146 // mode:c++ 01147 // End:

Generated on Sun Sep 19 16:34:04 2004 for libstdc++-v3 Source by doxygen 1.3.8