00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
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     
00046     
00047     
00048     
00049     
00050     
00051     
00052     
00053     
00054 
00055     
00056     template<typename _Tp1, typename _Tp2> class _Constant;
00057 
00058     
00059     
00060     
00061     template<class _Dom> class _UnFunBase {
00062     public:
00063         typedef typename _Dom::value_type value_type;
00064         typedef value_type _Vt;
00065         
00066         _UnFunBase (const _Dom& __e, _Vt __f(_Vt))
00067                 : _M_expr(__e), _M_func(__f) {}
00068         
00069         _Vt operator[] (size_t __i) const { return _M_func(_M_expr[__i]); }
00070         size_t size () const { return _M_expr.size(); }
00071         
00072     private:
00073         const _Dom& _M_expr;
00074         _Vt (*_M_func)(_Vt);
00075     };
00076 
00077     template<template<class, class> class _Meta, class _Dom>
00078         class _UnFunClos;
00079     
00080     template<class _Dom>
00081     struct _UnFunClos<_Expr,_Dom> : _UnFunBase<_Dom> {
00082         typedef _UnFunBase<_Dom> _Base;
00083         typedef typename _Base::value_type value_type;
00084         
00085         _UnFunClos (const _Dom& __e, value_type __f(value_type))
00086                 : _Base (__e, __f) {}
00087     };
00088     
00089     template<typename _Tp>
00090     struct _UnFunClos<_ValArray,_Tp> : _UnFunBase<valarray<_Tp> > {
00091         typedef _UnFunBase<valarray<_Tp> > _Base;
00092         typedef typename _Base::value_type value_type;
00093         
00094         _UnFunClos (const valarray<_Tp>& __v, _Tp __f(_Tp))
00095                 : _Base (__v, __f) {}
00096     };
00097 
00098     
00099     
00100     
00101     template<template<class, class> class _Meta1,
00102         template<class, class> class Meta2,
00103         class _Dom1, class _Dom2> class _BinFunClos;
00104     
00105     template<class _Dom1, class _Dom2> class _BinFunBase {
00106     public:
00107         typedef typename _Dom1::value_type value_type;
00108         typedef value_type _Vt;
00109 
00110         _BinFunBase (const _Dom1& __e1, const _Dom2& __e2,
00111                       _Vt __f (_Vt, _Vt))
00112                 : _M_expr1 (__e1), _M_expr2 (__e2), _M_func (__f) {}
00113 
00114         value_type operator[] (size_t __i) const
00115         { return _M_func (_M_expr1[__i], _M_expr2[__i]); }
00116         size_t size () const { return _M_expr1.size (); }
00117 
00118     private:
00119         const _Dom1& _M_expr1;
00120         const _Dom2& _M_expr2;
00121         _Vt (*_M_func)(_Vt, _Vt);
00122     };
00123 
00124     template<class _Dom> class _BinFunBase1 {
00125     public:
00126         typedef typename _Dom::value_type value_type ;
00127         typedef value_type _Vt;
00128 
00129         _BinFunBase1 (const _Vt& __c, const _Dom& __e, _Vt __f(_Vt, _Vt))
00130                 : _M_expr1 (__c), _M_expr2 (__e), _M_func (__f) {}
00131 
00132         value_type operator[] (size_t __i) const
00133         { return _M_func (_M_expr1, _M_expr2[__i]); }
00134         size_t size () const { return _M_expr2.size (); }
00135 
00136     private:
00137         const _Vt& _M_expr1;
00138         const _Dom& _M_expr2;
00139         _Vt (*_M_func)(_Vt, _Vt);
00140     };
00141 
00142     template<class _Dom> class _BinFunBase2 {
00143     public:
00144         typedef typename _Dom::value_type value_type;
00145         typedef value_type _Vt;
00146 
00147         _BinFunBase2 (const _Dom& __e, const _Vt& __c, _Vt __f(_Vt, _Vt))
00148                 : _M_expr1 (__e), _M_expr2 (__c), _M_func (__f) {}
00149 
00150         value_type operator[] (size_t __i) const
00151         { return _M_func (_M_expr1[__i], _M_expr2); }
00152         size_t size () const { return _M_expr1.size (); }
00153 
00154     private:
00155         const _Dom& _M_expr1;
00156         const _Vt& _M_expr2;
00157         _Vt (*_M_func)(_Vt, _Vt);
00158     };
00159 
00160     template<class _Dom1, class _Dom2>
00161     struct _BinFunClos<_Expr,_Expr,_Dom1,_Dom2> : _BinFunBase<_Dom1,_Dom2> {
00162         typedef _BinFunBase<_Dom1,_Dom2> _Base;
00163         typedef typename _Base::value_type value_type;
00164         typedef value_type _Tp;
00165 
00166         _BinFunClos (const _Dom1& __e1, const _Dom2& __e2,
00167                      _Tp __f(_Tp, _Tp))
00168                 : _Base (__e1, __e2, __f) {}
00169     };
00170 
00171     template<typename _Tp>
00172     struct _BinFunClos<_ValArray,_ValArray,_Tp,_Tp>
00173         : _BinFunBase<valarray<_Tp>, valarray<_Tp> > {
00174         typedef _BinFunBase<valarray<_Tp>, valarray<_Tp> > _Base;
00175         typedef _Tp value_type;
00176 
00177         _BinFunClos (const valarray<_Tp>& __v, const valarray<_Tp>& __w,
00178                      _Tp __f(_Tp, _Tp))
00179                 : _Base (__v, __w, __f) {}
00180     };
00181     
00182     template<class _Dom>
00183     struct _BinFunClos<_Expr,_ValArray,_Dom,typename _Dom::value_type>
00184         : _BinFunBase<_Dom,valarray<typename _Dom::value_type> > {
00185         typedef typename _Dom::value_type _Tp;
00186         typedef _BinFunBase<_Dom,valarray<_Tp> > _Base;
00187         typedef _Tp value_type;
00188 
00189         _BinFunClos (const _Dom& __e, const valarray<_Tp>& __v,
00190                      _Tp __f(_Tp, _Tp))
00191                 : _Base (__e, __v, __f) {}
00192     };
00193 
00194     template<class _Dom>
00195     struct _BinFunClos<_ValArray,_Expr,typename _Dom::value_type,_Dom>
00196         : _BinFunBase<valarray<typename _Dom::value_type>,_Dom> {
00197         typedef typename _Dom::value_type _Tp;
00198         typedef _BinFunBase<_Dom,valarray<_Tp> > _Base;
00199         typedef _Tp value_type;
00200 
00201         _BinFunClos (const valarray<_Tp>& __v, const _Dom& __e,
00202                      _Tp __f(_Tp, _Tp))
00203                 : _Base (__v, __e, __f) {}
00204     };
00205 
00206     template<class _Dom>
00207     struct _BinFunClos<_Expr,_Constant,_Dom,typename _Dom::value_type>
00208         : _BinFunBase2<_Dom> {
00209         typedef typename _Dom::value_type _Tp;
00210         typedef _Tp value_type;
00211         typedef _BinFunBase2<_Dom> _Base;
00212 
00213         _BinFunClos (const _Dom& __e, const _Tp& __t, _Tp __f (_Tp, _Tp))
00214                 : _Base (__e, __t, __f) {}
00215     };
00216 
00217     template<class _Dom>
00218     struct _BinFunClos<_Constant,_Expr,_Dom,typename _Dom::value_type>
00219         : _BinFunBase1<_Dom> {
00220         typedef typename _Dom::value_type _Tp;
00221         typedef _Tp value_type;
00222         typedef _BinFunBase1<_Dom> _Base;
00223 
00224         _BinFunClos (const _Tp& __t, const _Dom& __e, _Tp __f (_Tp, _Tp))
00225                 : _Base (__t, __e, __f) {}
00226     };
00227 
00228     template<typename _Tp>
00229     struct _BinFunClos<_ValArray,_Constant,_Tp,_Tp>
00230         : _BinFunBase2<valarray<_Tp> > {
00231         typedef _BinFunBase2<valarray<_Tp> > _Base;
00232         typedef _Tp value_type;
00233 
00234         _BinFunClos (const valarray<_Tp>& __v, const _Tp& __t,
00235                      _Tp __f(_Tp, _Tp))
00236                 : _Base (__v, __t, __f) {}
00237     };
00238 
00239     template<typename _Tp>
00240     struct _BinFunClos<_Constant,_ValArray,_Tp,_Tp>
00241         : _BinFunBase1<valarray<_Tp> > {
00242         typedef _BinFunBase1<valarray<_Tp> > _Base;
00243         typedef _Tp value_type;
00244 
00245         _BinFunClos (const _Tp& __t, const valarray<_Tp>& __v,
00246                      _Tp __f (_Tp, _Tp))
00247                 : _Base (__t, __v, __f) {}
00248     };
00249 
00250     
00251     
00252     
00253 
00254     template<typename _Dom, typename _Arg> class _FunBase {
00255     public:
00256         typedef typename _Dom::value_type value_type;
00257 
00258         _FunBase (const _Dom& __e, value_type __f(_Arg))
00259                 : _M_expr (__e), _M_func (__f) {}
00260 
00261         value_type operator[] (size_t __i) const
00262         { return _M_func (_M_expr[__i]); }
00263         size_t size() const { return _M_expr.size ();}
00264 
00265     private:
00266         const _Dom& _M_expr;
00267         value_type (*_M_func)(_Arg);
00268     };
00269 
00270     template<class _Dom>
00271     struct _ValFunClos<_Expr,_Dom>
00272         : _FunBase<_Dom, typename _Dom::value_type> {
00273         typedef _FunBase<_Dom, typename _Dom::value_type> _Base;
00274         typedef typename _Base::value_type value_type;
00275         typedef value_type _Tp;
00276     
00277         _ValFunClos (const _Dom& __e, _Tp __f (_Tp)) : _Base (__e, __f) {}
00278     };
00279 
00280     template<typename _Tp>
00281     struct _ValFunClos<_ValArray,_Tp>
00282         : _FunBase<valarray<_Tp>, _Tp> {
00283         typedef _FunBase<valarray<_Tp>, _Tp> _Base;
00284         typedef _Tp value_type;
00285 
00286         _ValFunClos (const valarray<_Tp>& __v, _Tp __f(_Tp))
00287                 : _Base (__v, __f) {}
00288     };
00289 
00290     template<class _Dom>
00291     struct _RefFunClos<_Expr,_Dom> :
00292         _FunBase<_Dom, const typename _Dom::value_type&> {
00293         typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base;
00294         typedef typename _Base::value_type value_type;
00295         typedef value_type _Tp;
00296 
00297         _RefFunClos (const _Dom& __e, _Tp __f (const _Tp&))
00298                 : _Base (__e, __f) {}
00299     };
00300 
00301     template<typename _Tp>
00302     struct _RefFunClos<_ValArray,_Tp>
00303         : _FunBase<valarray<_Tp>, const _Tp&> {
00304         typedef _FunBase<valarray<_Tp>, const _Tp&> _Base;
00305         typedef _Tp value_type;
00306         
00307         _RefFunClos (const valarray<_Tp>& __v, _Tp __f(const _Tp&))
00308                 : _Base (__v, __f) {}
00309     };
00310     
00311     
00312     
00313     
00314 
00315     template<template<class> class _Oper, typename _Arg>
00316     class _UnBase {
00317     public:
00318         typedef _Oper<typename _Arg::value_type> _Op;
00319         typedef typename _Op::result_type value_type;
00320 
00321         _UnBase (const _Arg& __e) : _M_expr(__e) {}
00322         value_type operator[] (size_t) const;
00323         size_t size () const { return _M_expr.size (); }
00324 
00325     private:
00326         const _Arg& _M_expr;
00327     };
00328 
00329     template<template<class> class _Oper, typename _Arg>
00330     inline typename _UnBase<_Oper, _Arg>::value_type
00331     _UnBase<_Oper, _Arg>::operator[] (size_t __i) const
00332     { return _Op() (_M_expr[__i]); }
00333     
00334     template<template<class> class _Oper, class _Dom>
00335     struct _UnClos<_Oper, _Expr, _Dom> :  _UnBase<_Oper, _Dom> {
00336         typedef _Dom _Arg;
00337         typedef _UnBase<_Oper, _Dom> _Base;
00338         typedef typename _Base::value_type value_type;
00339         
00340         _UnClos (const _Arg& __e) : _Base(__e) {}
00341     };
00342 
00343     template<template<class> class _Oper, typename _Tp>
00344     struct _UnClos<_Oper, _ValArray, _Tp> : _UnBase<_Oper, valarray<_Tp> > {
00345         typedef valarray<_Tp> _Arg;
00346         typedef _UnBase<_Oper, valarray<_Tp> > _Base;
00347         typedef typename _Base::value_type value_type;
00348 
00349         _UnClos (const _Arg& __e) : _Base(__e) {}
00350     };
00351 
00352 
00353     
00354     
00355     
00356 
00357     template<template<class> class _Oper,
00358         typename _FirstArg, typename _SecondArg>
00359     class _BinBase {
00360     public:
00361         typedef _Oper<typename _FirstArg::value_type> _Op;
00362         typedef typename _Op::result_type value_type;
00363 
00364         _BinBase (const _FirstArg& __e1, const _SecondArg& __e2)
00365                 : _M_expr1 (__e1), _M_expr2 (__e2) {}
00366         value_type operator[] (size_t) const;
00367         size_t size () const { return _M_expr1.size (); }
00368         
00369     private:
00370         const _FirstArg& _M_expr1;
00371         const _SecondArg& _M_expr2;
00372     };
00373 
00374     template<template<class> class _Oper,
00375         typename _FirstArg, typename _SecondArg>
00376     inline typename _BinBase<_Oper,_FirstArg,_SecondArg>::value_type
00377     _BinBase<_Oper,_FirstArg,_SecondArg>::operator[] (size_t __i) const
00378     { return _Op() (_M_expr1[__i], _M_expr2[__i]); }
00379 
00380 
00381     template<template<class> class _Oper, class _Clos>
00382     class _BinBase2 {
00383     public:
00384         typedef typename _Clos::value_type _Vt;
00385         typedef _Oper<_Vt> _Op;
00386         typedef typename _Op::result_type value_type;
00387 
00388         _BinBase2 (const _Clos& __e, const _Vt& __t)
00389                 : _M_expr1 (__e), _M_expr2 (__t) {}
00390         value_type operator[] (size_t) const;
00391         size_t size () const { return _M_expr1.size (); }
00392 
00393     private:
00394         const _Clos& _M_expr1;
00395         const _Vt& _M_expr2;
00396     };
00397 
00398     template<template<class> class _Oper, class _Clos>
00399     inline typename _BinBase2<_Oper,_Clos>::value_type
00400     _BinBase2<_Oper,_Clos>::operator[] (size_t __i) const
00401     { return _Op() (_M_expr1[__i], _M_expr2); }
00402 
00403 
00404     template<template<class> class _Oper, class _Clos>
00405     class _BinBase1 {
00406     public:
00407         typedef typename _Clos::value_type _Vt;
00408         typedef _Oper<_Vt> _Op;
00409         typedef typename _Op::result_type value_type;
00410 
00411         _BinBase1 (const _Vt& __t, const _Clos& __e)
00412                 : _M_expr1 (__t), _M_expr2 (__e) {}
00413         value_type operator[] (size_t) const;
00414         size_t size () const { return _M_expr2.size (); }
00415 
00416     private:
00417         const _Vt& _M_expr1;
00418         const _Clos& _M_expr2;
00419     };
00420 
00421     template<template<class> class _Oper, class _Clos>
00422     inline typename
00423     _BinBase1<_Oper,_Clos>::value_type
00424     _BinBase1<_Oper,_Clos>:: operator[] (size_t __i) const
00425     { return _Op() (_M_expr1, _M_expr2[__i]); }
00426 
00427     
00428     template<template<class> class _Oper, class _Dom1, class _Dom2>
00429     struct  _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2>
00430         : _BinBase<_Oper,_Dom1,_Dom2> {
00431         typedef _BinBase<_Oper,_Dom1,_Dom2> _Base;
00432         typedef typename _Base::value_type value_type;
00433         
00434         _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {}
00435     };
00436 
00437     template<template<class> class _Oper, typename _Tp>
00438     struct _BinClos<_Oper,_ValArray,_ValArray,_Tp,_Tp>
00439         : _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > {
00440         typedef _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > _Base;
00441         typedef _Tp value_type;
00442 
00443         _BinClos (const valarray<_Tp>& __v, const valarray<_Tp>& __w)
00444                 : _Base (__v, __w) {}
00445     };
00446 
00447     template<template<class> class _Oper, class _Dom>
00448     struct  _BinClos<_Oper,_Expr,_ValArray,_Dom,typename _Dom::value_type>
00449         : _BinBase<_Oper,_Dom,valarray<typename _Dom::value_type> > {
00450         typedef typename _Dom::value_type _Tp;
00451         typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base;
00452         typedef typename _Base::value_type value_type;
00453 
00454         _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2)
00455                 : _Base (__e1, __e2) {}
00456     };
00457 
00458     template<template<class> class _Oper, class _Dom>
00459     struct  _BinClos<_Oper,_ValArray,_Expr,typename _Dom::value_type,_Dom>
00460         : _BinBase<_Oper,valarray<typename _Dom::value_type>,_Dom> {
00461         typedef typename _Dom::value_type _Tp;
00462         typedef _BinBase<_Oper,valarray<_Tp>,_Dom> _Base;
00463         typedef typename _Base::value_type value_type;
00464 
00465         _BinClos (const valarray<_Tp>& __e1, const _Dom& __e2)
00466                 : _Base (__e1, __e2) {}
00467     };
00468 
00469     template<template<class> class _Oper, class _Dom>
00470     struct _BinClos<_Oper,_Expr,_Constant,_Dom,typename _Dom::value_type>
00471         : _BinBase2<_Oper,_Dom> {
00472         typedef typename _Dom::value_type _Tp;
00473         typedef _BinBase2<_Oper,_Dom> _Base;
00474         typedef typename _Base::value_type value_type;
00475 
00476         _BinClos (const _Dom& __e1, const _Tp& __e2) : _Base (__e1, __e2) {}
00477     };
00478 
00479     template<template<class> class _Oper, class _Dom>
00480     struct _BinClos<_Oper,_Constant,_Expr,typename _Dom::value_type,_Dom>
00481         : _BinBase1<_Oper,_Dom> {
00482         typedef typename _Dom::value_type _Tp;
00483         typedef _BinBase1<_Oper,_Dom> _Base;
00484         typedef typename _Base::value_type value_type;
00485 
00486         _BinClos (const _Tp& __e1, const _Dom& __e2) : _Base (__e1, __e2) {}
00487     };
00488     
00489     template<template<class> class _Oper, typename _Tp>
00490     struct _BinClos<_Oper,_ValArray,_Constant,_Tp,_Tp>
00491         : _BinBase2<_Oper,valarray<_Tp> > {
00492         typedef _BinBase2<_Oper,valarray<_Tp> > _Base;
00493         typedef typename _Base::value_type value_type;
00494 
00495         _BinClos (const valarray<_Tp>& __v, const _Tp& __t)
00496                 : _Base (__v, __t) {}
00497     };
00498 
00499     template<template<class> class _Oper, typename _Tp>
00500     struct _BinClos<_Oper,_Constant,_ValArray,_Tp,_Tp>
00501         : _BinBase1<_Oper,valarray<_Tp> > {
00502         typedef _BinBase1<_Oper,valarray<_Tp> > _Base;
00503         typedef typename _Base::value_type value_type;
00504 
00505         _BinClos (const _Tp& __t, const valarray<_Tp>& __v)
00506                 : _Base (__t, __v) {}
00507     };
00508         
00509 
00510     
00511     
00512     
00513     template<typename _Dom>  class _SBase {
00514     public:
00515         typedef typename _Dom::value_type value_type;
00516 
00517         _SBase (const _Dom& __e, const slice& __s)
00518                 : _M_expr (__e), _M_slice (__s) {}
00519         value_type operator[] (size_t __i) const
00520         { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; }
00521         size_t size() const { return _M_slice.size (); }
00522 
00523     private:
00524         const _Dom& _M_expr;
00525         const slice& _M_slice;
00526     };
00527 
00528     template<typename _Tp> class _SBase<_Array<_Tp> > {
00529     public:
00530         typedef _Tp value_type;
00531 
00532         _SBase (_Array<_Tp> __a, const slice& __s)
00533                 : _M_array (__a._M_data+__s.start()), _M_size (__s.size()),
00534                   _M_stride (__s.stride()) {}
00535         value_type operator[] (size_t __i) const
00536         { return _M_array._M_data[__i * _M_stride]; }
00537         size_t size() const { return _M_size; }
00538 
00539     private:
00540         const _Array<_Tp> _M_array;
00541         const size_t _M_size;
00542         const size_t _M_stride;
00543     };
00544 
00545     template<class _Dom> struct  _SClos<_Expr,_Dom> : _SBase<_Dom> {
00546         typedef _SBase<_Dom> _Base;
00547         typedef typename _Base::value_type value_type;
00548         
00549         _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {}
00550     };
00551 
00552     template<typename _Tp>
00553     struct _SClos<_ValArray,_Tp> : _SBase<_Array<_Tp> > {
00554         typedef  _SBase<_Array<_Tp> > _Base;
00555         typedef _Tp value_type;
00556 
00557         _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {}
00558     };
00559 
00560     
00561     
00562     
00563     template<class _Dom> class _GBase {
00564     public:
00565         typedef typename _Dom::value_type value_type;
00566         
00567         _GBase (const _Dom& __e, const valarray<size_t>& __i)
00568                 : _M_expr (__e), _M_index(__i) {}
00569         value_type operator[] (size_t __i) const
00570         { return _M_expr[_M_index[__i]]; }
00571         size_t size () const { return _M_index.size(); }
00572         
00573     private:
00574         const _Dom&  _M_expr;
00575         const valarray<size_t>& _M_index;
00576     };
00577     
00578     template<typename _Tp> class _GBase<_Array<_Tp> > {
00579     public:
00580         typedef _Tp value_type;
00581         
00582         _GBase (_Array<_Tp> __a, const valarray<size_t>& __i)
00583                 : _M_array (__a), _M_index(__i) {}
00584         value_type operator[] (size_t __i) const
00585         { return _M_array._M_data[_M_index[__i]]; }
00586         size_t size () const { return _M_index.size(); }
00587         
00588     private:
00589         const _Array<_Tp>     _M_array;
00590         const valarray<size_t>& _M_index;
00591     };
00592 
00593     template<class _Dom> struct _GClos<_Expr,_Dom> : _GBase<_Dom> {
00594         typedef _GBase<_Dom> _Base;
00595         typedef typename _Base::value_type value_type;
00596 
00597         _GClos (const _Dom& __e, const valarray<size_t>& __i)
00598                 : _Base (__e, __i) {}
00599     };
00600 
00601     template<typename _Tp>
00602     struct _GClos<_ValArray,_Tp> : _GBase<_Array<_Tp> > {
00603         typedef _GBase<_Array<_Tp> > _Base;
00604         typedef typename _Base::value_type value_type;
00605 
00606         _GClos (_Array<_Tp> __a, const valarray<size_t>& __i)
00607                 : _Base (__a, __i) {}
00608     };
00609 
00610     
00611     
00612     
00613 
00614     template<class _Dom> class _IBase {
00615     public:
00616         typedef typename _Dom::value_type value_type;
00617 
00618         _IBase (const _Dom& __e, const valarray<size_t>& __i)
00619                 : _M_expr (__e), _M_index (__i) {}
00620         value_type operator[] (size_t __i) const
00621         { return _M_expr[_M_index[__i]]; }
00622         size_t size() const { return _M_index.size(); }
00623         
00624     private:
00625         const _Dom&         _M_expr;
00626         const valarray<size_t>& _M_index;
00627     };
00628 
00629     template<class _Dom> struct _IClos<_Expr,_Dom> : _IBase<_Dom> {
00630         typedef _IBase<_Dom> _Base;
00631         typedef typename _Base::value_type value_type;
00632 
00633         _IClos (const _Dom& __e, const valarray<size_t>& __i)
00634                 : _Base (__e, __i) {}
00635     };
00636 
00637     template<typename _Tp>
00638     struct _IClos<_ValArray,_Tp>  : _IBase<valarray<_Tp> > {
00639         typedef _IBase<valarray<_Tp> > _Base;
00640         typedef _Tp value_type;
00641 
00642         _IClos (const valarray<_Tp>& __a, const valarray<size_t>& __i)
00643                 : _Base (__a, __i) {}
00644     };
00645 
00646     
00647     
00648     
00649     template<class _Clos, typename _Tp> class _Expr {
00650     public:
00651         typedef _Tp value_type;
00652         
00653         _Expr (const _Clos&);
00654         
00655         const _Clos& operator() () const;
00656         
00657         value_type operator[] (size_t) const;
00658         valarray<value_type> operator[] (slice) const;
00659         valarray<value_type> operator[] (const gslice&) const;
00660         valarray<value_type> operator[] (const valarray<bool>&) const;
00661         valarray<value_type> operator[] (const valarray<size_t>&) const;
00662     
00663         _Expr<_UnClos<_Unary_plus,std::_Expr,_Clos>, value_type>
00664         operator+ () const;
00665 
00666         _Expr<_UnClos<negate,std::_Expr,_Clos>, value_type>
00667         operator- () const;
00668 
00669         _Expr<_UnClos<_Bitwise_not,std::_Expr,_Clos>, value_type>
00670         operator~ () const;
00671 
00672         _Expr<_UnClos<logical_not,std::_Expr,_Clos>, bool>
00673         operator! () const;
00674 
00675         size_t size () const;
00676         value_type sum () const;
00677         
00678         valarray<value_type> shift (int) const;
00679         valarray<value_type> cshift (int) const;
00680 
00681       value_type min() const;
00682       value_type max() const;
00683 
00684       valarray<value_type> apply(value_type (*) (const value_type&)) const;
00685       valarray<value_type> apply(value_type (*) (value_type)) const;
00686         
00687     private:
00688         const _Clos _M_closure;
00689     };
00690     
00691     template<class _Clos, typename _Tp>
00692     inline
00693     _Expr<_Clos,_Tp>::_Expr (const _Clos& __c) : _M_closure(__c) {}
00694     
00695     template<class _Clos, typename _Tp>
00696     inline const _Clos&
00697     _Expr<_Clos,_Tp>::operator() () const
00698     { return _M_closure; }
00699 
00700     template<class _Clos, typename _Tp>
00701     inline _Tp
00702     _Expr<_Clos,_Tp>::operator[] (size_t __i) const
00703     { return _M_closure[__i]; }
00704 
00705     template<class _Clos, typename _Tp>
00706     inline valarray<_Tp>
00707     _Expr<_Clos,_Tp>::operator[] (slice __s) const
00708     { return _M_closure[__s]; }
00709     
00710     template<class _Clos, typename _Tp>
00711     inline valarray<_Tp>
00712     _Expr<_Clos,_Tp>::operator[] (const gslice& __gs) const
00713     { return _M_closure[__gs]; }
00714     
00715     template<class _Clos, typename _Tp>
00716     inline valarray<_Tp>
00717     _Expr<_Clos,_Tp>::operator[] (const valarray<bool>& __m) const
00718     { return _M_closure[__m]; }
00719     
00720     template<class _Clos, typename _Tp>
00721     inline valarray<_Tp>
00722     _Expr<_Clos,_Tp>::operator[] (const valarray<size_t>& __i) const
00723     { return _M_closure[__i]; }
00724     
00725     template<class _Clos, typename _Tp>
00726     inline size_t
00727     _Expr<_Clos,_Tp>::size () const  { return _M_closure.size (); }
00728 
00729   template<class _Clos, typename _Tp>
00730   inline valarray<_Tp>
00731   _Expr<_Clos, _Tp>::shift(int __n) const
00732   { return valarray<_Tp>(_M_closure).shift(__n); }
00733 
00734   template<class _Clos, typename _Tp>
00735   inline valarray<_Tp>
00736   _Expr<_Clos, _Tp>::cshift(int __n) const
00737   { return valarray<_Tp>(_M_closure).cshift(__n); }
00738 
00739   template<class _Clos, typename _Tp>
00740   inline valarray<_Tp>
00741   _Expr<_Clos, _Tp>::apply(_Tp __f(const _Tp&)) const
00742   { return valarray<_Tp>(_M_closure).apply(__f); }
00743     
00744   template<class _Clos, typename _Tp>
00745   inline valarray<_Tp>
00746   _Expr<_Clos, _Tp>::apply(_Tp __f(_Tp)) const
00747   { return valarray<_Tp>(_M_closure).apply(__f); }
00748 
00749     
00750     template<class _Clos, typename _Tp>
00751     inline _Tp
00752     _Expr<_Clos,_Tp>::sum () const
00753     {
00754         size_t __n = _M_closure.size();
00755         if (__n == 0) return _Tp();
00756         else {
00757             _Tp __s = _M_closure[--__n];
00758             while (__n != 0) __s += _M_closure[--__n];
00759             return __s;
00760         }
00761     }
00762 
00763   template<class _Clos, typename _Tp>
00764   inline _Tp
00765   _Expr<_Clos, _Tp>::min() const
00766   { return __valarray_min(_M_closure); }
00767 
00768   template<class _Clos, typename _Tp>
00769   inline _Tp
00770   _Expr<_Clos, _Tp>::max() const
00771   { return __valarray_max(_M_closure); }
00772     
00773     template<class _Dom, typename _Tp>
00774     inline _Expr<_UnClos<logical_not,_Expr,_Dom>, bool>
00775     _Expr<_Dom,_Tp>::operator! () const
00776     {
00777         typedef _UnClos<logical_not,std::_Expr,_Dom> _Closure;
00778         return _Expr<_Closure,_Tp> (_Closure(this->_M_closure));
00779     }
00780 
00781 #define _DEFINE_EXPR_UNARY_OPERATOR(_Op, _Name)                         \
00782 template<class _Dom, typename _Tp>                                      \
00783 inline _Expr<_UnClos<_Name,std::_Expr,_Dom>,_Tp>                        \
00784 _Expr<_Dom,_Tp>::operator _Op () const                                 \
00785 {                                                                       \
00786     typedef _UnClos<_Name,std::_Expr,_Dom> _Closure;                    \
00787     return _Expr<_Closure,_Tp> (_Closure (this->_M_closure));           \
00788 }
00789 
00790     _DEFINE_EXPR_UNARY_OPERATOR(+, _Unary_plus)
00791     _DEFINE_EXPR_UNARY_OPERATOR(-, negate)
00792     _DEFINE_EXPR_UNARY_OPERATOR(~, _Bitwise_not)
00793 
00794 #undef _DEFINE_EXPR_UNARY_OPERATOR
00795 
00796 
00797 #define _DEFINE_EXPR_BINARY_OPERATOR(_Op, _Name)                        \
00798 template<class _Dom1, class _Dom2>                  \
00799 inline _Expr<_BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2>,                   \
00800              typename _Name<typename _Dom1::value_type>::result_type>   \
00801 operator _Op (const _Expr<_Dom1,typename _Dom1::value_type>& __v,      \
00802               const _Expr<_Dom2,typename _Dom2::value_type>& __w)       \
00803 {                                                                       \
00804     typedef typename _Dom1::value_type _Arg;                            \
00805     typedef typename _Name<_Arg>::result_type _Value;                   \
00806     typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure;           \
00807     return _Expr<_Closure,_Value> (_Closure (__v (), __w ()));          \
00808 }                                                                       \
00809                                                                         \
00810 template<class _Dom>                                                    \
00811 inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>, \
00812              typename _Name<typename _Dom::value_type>::result_type>    \
00813 operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __v,        \
00814               const typename _Dom::value_type& __t)                     \
00815 {                                                                       \
00816     typedef typename _Dom::value_type _Arg;                             \
00817     typedef typename _Name<_Arg>::result_type _Value;                   \
00818     typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure;         \
00819     return _Expr<_Closure,_Value> (_Closure (__v (), __t));             \
00820 }                                                                       \
00821                                                                         \
00822 template<class _Dom>                                                    \
00823 inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>, \
00824              typename _Name<typename _Dom::value_type>::result_type>    \
00825 operator _Op (const typename _Dom::value_type& __t,                    \
00826                const _Expr<_Dom,typename _Dom::value_type>& __v)        \
00827 {                                                                       \
00828     typedef typename _Dom::value_type _Arg;                             \
00829     typedef typename _Name<_Arg>::result_type _Value;                   \
00830     typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure;         \
00831     return _Expr<_Closure,_Value> (_Closure (__t, __v ()));             \
00832 }                                                                       \
00833                                                                         \
00834 template<class _Dom>                                                    \
00835 inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>, \
00836              typename _Name<typename _Dom::value_type>::result_type>    \
00837 operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __e,        \
00838                const valarray<typename _Dom::value_type>& __v)          \
00839 {                                                                       \
00840     typedef typename _Dom::value_type _Arg;                             \
00841     typedef typename _Name<_Arg>::result_type _Value;                   \
00842     typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Arg> _Closure;         \
00843     return  _Expr<_Closure,_Value> (_Closure (__e (), __v));            \
00844 }                                                                       \
00845                                                                         \
00846 template<class _Dom>                                                    \
00847 inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>, \
00848              typename _Name<typename _Dom::value_type>::result_type>    \
00849 operator _Op (const valarray<typename _Dom::value_type>& __v,          \
00850                const _Expr<_Dom,typename _Dom::value_type>& __e)        \
00851 {                                                                       \
00852     typedef typename _Dom::value_type _Tp;                              \
00853     typedef typename _Name<_Tp>::result_type _Value;                    \
00854     typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure;          \
00855     return _Expr<_Closure,_Value> (_Closure (__v, __e ()));             \
00856 }
00857 
00858     _DEFINE_EXPR_BINARY_OPERATOR(+, plus)
00859     _DEFINE_EXPR_BINARY_OPERATOR(-, minus)
00860     _DEFINE_EXPR_BINARY_OPERATOR(*, multiplies)
00861     _DEFINE_EXPR_BINARY_OPERATOR(/, divides)
00862     _DEFINE_EXPR_BINARY_OPERATOR(%, modulus)
00863     _DEFINE_EXPR_BINARY_OPERATOR(^, _Bitwise_xor)
00864     _DEFINE_EXPR_BINARY_OPERATOR(&, _Bitwise_and)
00865     _DEFINE_EXPR_BINARY_OPERATOR(|, _Bitwise_or)
00866     _DEFINE_EXPR_BINARY_OPERATOR(<<, _Shift_left)
00867     _DEFINE_EXPR_BINARY_OPERATOR(>>, _Shift_right)
00868 
00869 #undef _DEFINE_EXPR_BINARY_OPERATOR
00870     
00871 #define _DEFINE_EXPR_RELATIONAL_OPERATOR(_Op, _Name)                    \
00872 template<class _Dom1, class _Dom2>                  \
00873 inline _Expr<_BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2>, bool>             \
00874 operator _Op (const _Expr<_Dom1,typename _Dom1::value_type>& __v,      \
00875               const _Expr<_Dom2,typename _Dom2::value_type>& __w)       \
00876 {                                                                       \
00877     typedef typename _Dom1::value_type _Arg;                            \
00878     typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure;           \
00879     return _Expr<_Closure,bool> (_Closure (__v (), __w ()));            \
00880 }                                                                       \
00881                                                                         \
00882 template<class _Dom>                                                    \
00883 inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>, \
00884              bool>                                                      \
00885 operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __v,        \
00886               const typename _Dom::value_type& __t)                     \
00887 {                                                                       \
00888     typedef typename _Dom::value_type _Arg;                             \
00889     typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure;         \
00890     return _Expr<_Closure,bool> (_Closure (__v (), __t));               \
00891 }                                                                       \
00892                                                                         \
00893 template<class _Dom>                                                    \
00894 inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>, \
00895              bool>                                                      \
00896 operator _Op (const typename _Dom::value_type& __t,                    \
00897                const _Expr<_Dom,typename _Dom::value_type>& __v)        \
00898 {                                                                       \
00899     typedef typename _Dom::value_type _Arg;                             \
00900     typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure;         \
00901     return _Expr<_Closure,bool> (_Closure (__t, __v ()));               \
00902 }                                                                       \
00903                                                                         \
00904 template<class _Dom>                                                    \
00905 inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>, \
00906              bool>                                                      \
00907 operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __e,        \
00908                const valarray<typename _Dom::value_type>& __v)          \
00909 {                                                                       \
00910     typedef typename _Dom::value_type _Tp;                              \
00911     typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Tp> _Closure;          \
00912     return  _Expr<_Closure,bool> (_Closure (__e (), __v));              \
00913 }                                                                       \
00914                                                                         \
00915 template<class _Dom>                                                    \
00916 inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>, \
00917              bool>                                                      \
00918 operator _Op (const valarray<typename _Dom::value_type>& __v,          \
00919                const _Expr<_Dom,typename _Dom::value_type>& __e)        \
00920 {                                                                       \
00921     typedef typename _Dom::value_type _Tp;                              \
00922     typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure;          \
00923     return _Expr<_Closure,bool> (_Closure (__v, __e ()));               \
00924 }
00925 
00926     _DEFINE_EXPR_RELATIONAL_OPERATOR(&&, logical_and)
00927     _DEFINE_EXPR_RELATIONAL_OPERATOR(||, logical_or)
00928     _DEFINE_EXPR_RELATIONAL_OPERATOR(==, equal_to)
00929     _DEFINE_EXPR_RELATIONAL_OPERATOR(!=, not_equal_to)
00930     _DEFINE_EXPR_RELATIONAL_OPERATOR(<, less)
00931     _DEFINE_EXPR_RELATIONAL_OPERATOR(>, greater)
00932     _DEFINE_EXPR_RELATIONAL_OPERATOR(<=, less_equal)
00933     _DEFINE_EXPR_RELATIONAL_OPERATOR(>=, greater_equal)
00934 
00935 #undef _DEFINE_EXPR_RELATIONAL_OPERATOR
00936 
00937 
00938 
00939 #define _DEFINE_EXPR_UNARY_FUNCTION(_Name)                              \
00940 template<class _Dom>                                                    \
00941 inline _Expr<_UnFunClos<_Expr,_Dom>,typename _Dom::value_type>          \
00942 _Name(const _Expr<_Dom,typename _Dom::value_type>& __e)                 \
00943 {                                                                       \
00944     typedef typename _Dom::value_type _Tp;                              \
00945     typedef _UnFunClos<_Expr,_Dom> _Closure;                            \
00946     return _Expr<_Closure,_Tp>(_Closure(__e(), (_Tp(*)(_Tp))(&_Name))); \
00947 }                                                                       \
00948                                                                         \
00949 template<typename _Tp>                                                  \
00950 inline _Expr<_UnFunClos<_ValArray,_Tp>,_Tp>                             \
00951 _Name(const valarray<_Tp>& __v)                                         \
00952 {                                                                       \
00953     typedef _UnFunClos<_ValArray,_Tp> _Closure;                         \
00954     return _Expr<_Closure,_Tp> (_Closure (__v, (_Tp(*)(_Tp))(&_Name))); \
00955 }
00956 
00957 
00958     _DEFINE_EXPR_UNARY_FUNCTION(abs)
00959     _DEFINE_EXPR_UNARY_FUNCTION(cos)
00960     _DEFINE_EXPR_UNARY_FUNCTION(acos)
00961     _DEFINE_EXPR_UNARY_FUNCTION(cosh)    
00962     _DEFINE_EXPR_UNARY_FUNCTION(sin)
00963     _DEFINE_EXPR_UNARY_FUNCTION(asin)
00964     _DEFINE_EXPR_UNARY_FUNCTION(sinh)    
00965     _DEFINE_EXPR_UNARY_FUNCTION(tan)
00966     _DEFINE_EXPR_UNARY_FUNCTION(tanh)
00967     _DEFINE_EXPR_UNARY_FUNCTION(atan)
00968     _DEFINE_EXPR_UNARY_FUNCTION(exp)    
00969     _DEFINE_EXPR_UNARY_FUNCTION(log)
00970     _DEFINE_EXPR_UNARY_FUNCTION(log10)
00971     _DEFINE_EXPR_UNARY_FUNCTION(sqrt)
00972 
00973 #undef _DEFINE_EXPR_UNARY_FUNCTION
00974 
00975 
00976 #define _DEFINE_EXPR_BINARY_FUNCTION(_Name)                             \
00977 template<class _Dom1, class _Dom2>                                      \
00978 inline _Expr<_BinFunClos<_Expr,_Expr,_Dom1,_Dom2>,typename _Dom1::value_type>\
00979 _Name (const _Expr<_Dom1,typename _Dom1::value_type>& __e1,             \
00980        const _Expr<_Dom2,typename _Dom2::value_type>& __e2)             \
00981 {                                                                       \
00982     typedef typename _Dom1::value_type _Tp;                             \
00983     typedef _BinFunClos<_Expr,_Expr,_Dom1,_Dom2> _Closure;              \
00984     return _Expr<_Closure,_Tp>                                          \
00985         (_Closure (__e1 (), __e2 (), (_Tp(*)(_Tp, _Tp))(&_Name)));      \
00986 }                                                                       \
00987                                                                         \
00988 template<class _Dom>                                                    \
00989 inline _Expr<_BinFunClos<_Expr,_ValArray,_Dom,typename _Dom::value_type>, \
00990              typename _Dom::value_type>                                 \
00991 _Name (const _Expr<_Dom,typename _Dom::value_type>& __e,                \
00992        const valarray<typename _Dom::value_type>& __v)                  \
00993 {                                                                       \
00994     typedef typename _Dom::value_type _Tp;                              \
00995     typedef _BinFunClos<_Expr,_ValArray,_Dom,_Tp> _Closure;             \
00996     return _Expr<_Closure,_Tp>                                          \
00997         (_Closure (__e (), __v, (_Tp(*)(_Tp, _Tp))(&_Name)));           \
00998 }                                                                       \
00999                                                                         \
01000 template<class _Dom>                                                    \
01001 inline _Expr<_BinFunClos<_ValArray,_Expr,typename _Dom::value_type,_Dom>, \
01002              typename _Dom::value_type>                                 \
01003 _Name (const valarray<typename _Dom::valarray>& __v,                    \
01004        const _Expr<_Dom,typename _Dom::value_type>& __e)                \
01005 {                                                                       \
01006     typedef typename _Dom::value_type _Tp;                              \
01007     typedef _BinFunClos<_ValArray,_Expr,_Tp,_Dom> _Closure;             \
01008     return _Expr<_Closure,_Tp>                                          \
01009         (_Closure (__v, __e (), (_Tp(*)(_Tp, _Tp))(&_Name)));           \
01010 }                                                                       \
01011                                                                         \
01012 template<class _Dom>                                                    \
01013 inline _Expr<_BinFunClos<_Expr,_Constant,_Dom,typename _Dom::value_type>, \
01014              typename _Dom::value_type>                                 \
01015 _Name (const _Expr<_Dom, typename _Dom::value_type>& __e,               \
01016        const typename _Dom::value_type& __t)                            \
01017 {                                                                       \
01018     typedef typename _Dom::value_type _Tp;                              \
01019     typedef _BinFunClos<_Expr,_Constant,_Dom,_Tp> _Closure;             \
01020     return _Expr<_Closure,_Tp>                                          \
01021         (_Closure (__e (), __t, (_Tp(*)(_Tp, _Tp))(&_Name)));           \
01022 }                                                                       \
01023                                                                         \
01024 template<class _Dom>                                                    \
01025 inline _Expr<_BinFunClos<_Constant,_Expr,typename _Dom::value_type,_Dom>, \
01026              typename _Dom::value_type>                                 \
01027 _Name (const typename _Dom::value_type& __t,                            \
01028        const _Expr<_Dom,typename _Dom::value_type>& __e)                \
01029 {                                                                       \
01030     typedef typename _Dom::value_type _Tp;                              \
01031     typedef _BinFunClos<_Constant,_Expr,_Tp,_Dom> _Closure;             \
01032     return _Expr<_Closure,_Tp>                                          \
01033         (_Closure (__t, __e (), (_Tp(*)(_Tp, _Tp))(&_Name)));           \
01034 }                                                                       \
01035                                                                         \
01036 template<typename _Tp>                                                  \
01037 inline _Expr<_BinFunClos<_ValArray,_ValArray,_Tp,_Tp>, _Tp>             \
01038 _Name (const valarray<_Tp>& __v, const valarray<_Tp>& __w)              \
01039 {                                                                       \
01040     typedef _BinFunClos<_ValArray,_ValArray,_Tp,_Tp> _Closure;          \
01041     return _Expr<_Closure,_Tp>                                          \
01042         (_Closure (__v, __w, (_Tp(*)(_Tp,_Tp))(&_Name)));               \
01043 }                                                                       \
01044                                                                         \
01045 template<typename _Tp>                                                  \
01046 inline _Expr<_BinFunClos<_ValArray,_Constant,_Tp,_Tp>,_Tp>              \
01047 _Name (const valarray<_Tp>& __v, const _Tp& __t)                        \
01048 {                                                                       \
01049     typedef _BinFunClos<_ValArray,_Constant,_Tp,_Tp> _Closure;          \
01050     return _Expr<_Closure,_Tp>                                          \
01051         (_Closure (__v, __t, (_Tp(*)(_Tp,_Tp))(&_Name)));               \
01052 }                                                                       \
01053                                                                         \
01054 template<typename _Tp>                                                  \
01055 inline _Expr<_BinFunClos<_Constant,_ValArray,_Tp,_Tp>,_Tp>              \
01056 _Name (const _Tp& __t, const valarray<_Tp>& __v)                        \
01057 {                                                                       \
01058     typedef _BinFunClos<_Constant,_ValArray,_Tp,_Tp> _Closure;          \
01059     return _Expr<_Closure,_Tp>                                          \
01060         (_Closure (__t, __v, (_Tp(*)(_Tp,_Tp))(&_Name)));               \
01061 }
01062 
01063 _DEFINE_EXPR_BINARY_FUNCTION(atan2)
01064 _DEFINE_EXPR_BINARY_FUNCTION(pow)
01065 
01066 #undef _DEFINE_EXPR_BINARY_FUNCTION
01067 
01068 } 
01069 
01070 
01071 #endif 
01072 
01073 
01074 
01075