valarray_meta.h

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

Generated on Thu Feb 10 23:23:00 2005 for libstdc++-v3 Source by  doxygen 1.4.0