# 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: