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 
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     // Implementing a loosened valarray return value is tricky.
00047     // First we need to meet 26.3.1/3: we should not add more than
00048     // two levels of template nesting. Therefore we resort to template
00049     // template to "flatten" loosened return value types.
00050     // At some point we use partial specialization to remove one level
00051     // template nesting due to _Expr<>
00052     //
00053     
00054 
00055     // This class is NOT defined. It doesn't need to.
00056     template<typename _Tp1, typename _Tp2> class _Constant;
00057 
00058     //
00059     // Unary function application closure.
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     // Binary function application closure.
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     // Apply function taking a value/const reference closure
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     // Unary expression closure.
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     // Binary expression closure.
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     // slice_array closure.
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     // gslice_array closure.
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     // indirect_array closure
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     // class _Expr
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     // XXX: replace this with a more robust summation algorithm.
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 } // std::
01069 
01070 
01071 #endif /* _CPP_VALARRAY_META_H */
01072 
01073 // Local Variables:
01074 // mode:c++
01075 // End:

Generated on Tue Dec 23 12:34:14 2003 for libstdc++-v3 Source by doxygen 1.3.4