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