valarray_before.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, 2002, 2003, 2004, 2005, 2006
00004 // Free Software Foundation, Inc.
00005 //
00006 // This file is part of the GNU ISO C++ Library.  This library is free
00007 // software; you can redistribute it and/or modify it under the
00008 // terms of the GNU General Public License as published by the
00009 // Free Software Foundation; either version 2, or (at your option)
00010 // any later version.
00011 
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 
00017 // You should have received a copy of the GNU General Public License along
00018 // with this library; see the file COPYING.  If not, write to the Free
00019 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
00020 // USA.
00021 
00022 // As a special exception, you may use this file as part of a free software
00023 // library without restriction.  Specifically, if other files instantiate
00024 // templates or use macros or inline functions from this file, or you compile
00025 // this file and link it with other files to produce an executable, this
00026 // file does not by itself cause the resulting executable to be covered by
00027 // the GNU General Public License.  This exception does not however
00028 // invalidate any other reasons why the executable file might be covered by
00029 // the GNU General Public License.
00030 
00031 /** @file valarray_before.h
00032  *  This is an internal header file, included by other library headers.
00033  *  You should not attempt to use it directly.
00034  */
00035 
00036 // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr>
00037 
00038 #ifndef _VALARRAY_BEFORE_H
00039 #define _VALARRAY_BEFORE_H 1
00040 
00041 #pragma GCC system_header
00042 
00043 #include <bits/slice_array.h>
00044 
00045 _GLIBCXX_BEGIN_NAMESPACE(std)
00046 
00047   //
00048   // Implementing a loosened valarray return value is tricky.
00049   // First we need to meet 26.3.1/3: we should not add more than
00050   // two levels of template nesting. Therefore we resort to template
00051   // template to "flatten" loosened return value types.
00052   // At some point we use partial specialization to remove one level
00053   // template nesting due to _Expr<>
00054   //
00055 
00056   // This class is NOT defined. It doesn't need to.
00057   template<typename _Tp1, typename _Tp2> class _Constant;
00058 
00059   // Implementations of unary functions applied to valarray<>s.
00060   // I use hard-coded object functions here instead of a generic
00061   // approach like pointers to function:
00062   //    1) correctness: some functions take references, others values.
00063   //       we can't deduce the correct type afterwards.
00064   //    2) efficiency -- object functions can be easily inlined
00065   //    3) be Koenig-lookup-friendly
00066 
00067   struct __abs
00068   {
00069     template<typename _Tp>
00070       _Tp operator()(const _Tp& __t) const
00071       { return abs(__t); }
00072   };
00073 
00074   struct __cos
00075   {
00076     template<typename _Tp>
00077       _Tp operator()(const _Tp& __t) const
00078       { return cos(__t); }
00079   };
00080 
00081   struct __acos
00082   {
00083     template<typename _Tp>
00084       _Tp operator()(const _Tp& __t) const
00085       { return acos(__t); }
00086   };
00087 
00088   struct __cosh
00089   {
00090     template<typename _Tp>
00091       _Tp operator()(const _Tp& __t) const
00092       { return cosh(__t); }
00093   };
00094 
00095   struct __sin
00096   {
00097     template<typename _Tp>
00098       _Tp operator()(const _Tp& __t) const
00099       { return sin(__t); }
00100   };
00101 
00102   struct __asin
00103   {
00104     template<typename _Tp>
00105       _Tp operator()(const _Tp& __t) const
00106       { return asin(__t); }
00107   };
00108 
00109   struct __sinh
00110   {
00111     template<typename _Tp>
00112       _Tp operator()(const _Tp& __t) const
00113       { return sinh(__t); }
00114   };
00115 
00116   struct __tan
00117   {
00118     template<typename _Tp>
00119       _Tp operator()(const _Tp& __t) const
00120       { return tan(__t); }
00121   };
00122 
00123   struct __atan
00124   {
00125     template<typename _Tp>
00126       _Tp operator()(const _Tp& __t) const
00127       { return atan(__t); }
00128   };
00129 
00130   struct __tanh
00131   {
00132     template<typename _Tp>
00133       _Tp operator()(const _Tp& __t) const
00134       { return tanh(__t); }
00135   };
00136 
00137   struct __exp
00138   {
00139     template<typename _Tp>
00140       _Tp operator()(const _Tp& __t) const
00141       { return exp(__t); }
00142   };
00143 
00144   struct __log
00145   {
00146     template<typename _Tp>
00147       _Tp operator()(const _Tp& __t) const
00148       { return log(__t); }
00149   };
00150 
00151   struct __log10
00152   {
00153     template<typename _Tp>
00154       _Tp operator()(const _Tp& __t) const
00155       { return log10(__t); }
00156   };
00157 
00158   struct __sqrt
00159   {
00160     template<typename _Tp>
00161       _Tp operator()(const _Tp& __t) const
00162       { return sqrt(__t); }
00163   };
00164 
00165   // In the past, we used to tailor operator applications semantics
00166   // to the specialization of standard function objects (i.e. plus<>, etc.)
00167   // That is incorrect.  Therefore we provide our own surrogates.
00168 
00169   struct __unary_plus
00170   {
00171     template<typename _Tp>
00172       _Tp operator()(const _Tp& __t) const
00173       { return +__t; }
00174   };
00175 
00176   struct __negate
00177   {
00178     template<typename _Tp>
00179       _Tp operator()(const _Tp& __t) const
00180       { return -__t; }
00181   };
00182 
00183   struct __bitwise_not
00184   {
00185     template<typename _Tp>
00186       _Tp operator()(const _Tp& __t) const
00187       { return ~__t; }
00188   };
00189 
00190   struct __plus
00191   {
00192     template<typename _Tp>
00193       _Tp operator()(const _Tp& __x, const _Tp& __y) const
00194       { return __x + __y; }
00195   };
00196 
00197   struct __minus
00198   {
00199     template<typename _Tp>
00200       _Tp operator()(const _Tp& __x, const _Tp& __y) const
00201       { return __x - __y; }
00202   };
00203 
00204   struct __multiplies
00205   {
00206     template<typename _Tp>
00207       _Tp operator()(const _Tp& __x, const _Tp& __y) const
00208       { return __x * __y; }
00209   };
00210 
00211   struct __divides
00212   {
00213     template<typename _Tp>
00214       _Tp operator()(const _Tp& __x, const _Tp& __y) const
00215       { return __x / __y; }
00216   };
00217 
00218   struct __modulus
00219   {
00220     template<typename _Tp>
00221       _Tp operator()(const _Tp& __x, const _Tp& __y) const
00222       { return __x % __y; }
00223   };
00224 
00225   struct __bitwise_xor
00226   {
00227     template<typename _Tp>
00228       _Tp operator()(const _Tp& __x, const _Tp& __y) const
00229       { return __x ^ __y; }
00230   };
00231 
00232   struct __bitwise_and
00233   {
00234     template<typename _Tp>
00235       _Tp operator()(const _Tp& __x, const _Tp& __y) const
00236       { return __x & __y; }
00237   };
00238 
00239   struct __bitwise_or
00240   {
00241     template<typename _Tp>
00242       _Tp operator()(const _Tp& __x, const _Tp& __y) const
00243       { return __x | __y; }
00244   };
00245 
00246   struct __shift_left
00247   {
00248     template<typename _Tp>
00249       _Tp operator()(const _Tp& __x, const _Tp& __y) const
00250       { return __x << __y; }
00251   };
00252 
00253   struct __shift_right
00254   {
00255     template<typename _Tp>
00256       _Tp operator()(const _Tp& __x, const _Tp& __y) const
00257       { return __x >> __y; }
00258   };
00259 
00260   struct __logical_and
00261   {
00262     template<typename _Tp>
00263       bool operator()(const _Tp& __x, const _Tp& __y) const
00264       { return __x && __y; }
00265   };
00266 
00267   struct __logical_or
00268   {
00269     template<typename _Tp>
00270       bool operator()(const _Tp& __x, const _Tp& __y) const
00271       { return __x || __y; }
00272   };
00273 
00274   struct __logical_not
00275   {
00276     template<typename _Tp>
00277       bool operator()(const _Tp& __x) const { return !__x; }
00278   };
00279 
00280   struct __equal_to
00281   {
00282     template<typename _Tp>
00283       bool operator()(const _Tp& __x, const _Tp& __y) const
00284       { return __x == __y; }
00285   };
00286 
00287   struct __not_equal_to
00288   {
00289     template<typename _Tp>
00290       bool operator()(const _Tp& __x, const _Tp& __y) const
00291       { return __x != __y; }
00292   };
00293 
00294   struct __less
00295   {
00296     template<typename _Tp>
00297       bool operator()(const _Tp& __x, const _Tp& __y) const
00298       { return __x < __y; }
00299   };
00300 
00301   struct __greater
00302   {
00303     template<typename _Tp>
00304       bool operator()(const _Tp& __x, const _Tp& __y) const
00305       { return __x > __y; }
00306   };
00307 
00308   struct __less_equal
00309   {
00310     template<typename _Tp>
00311       bool operator()(const _Tp& __x, const _Tp& __y) const
00312       { return __x <= __y; }
00313   };
00314 
00315   struct __greater_equal
00316   {
00317     template<typename _Tp>
00318       bool operator()(const _Tp& __x, const _Tp& __y) const
00319       { return __x >= __y; }
00320   };
00321 
00322   // The few binary functions we miss.
00323   struct __atan2
00324   {
00325     template<typename _Tp>
00326       _Tp operator()(const _Tp& __x, const _Tp& __y) const
00327       { return atan2(__x, __y); }
00328   };
00329 
00330   struct __pow
00331   {
00332     template<typename _Tp>
00333       _Tp operator()(const _Tp& __x, const _Tp& __y) const
00334       { return pow(__x, __y); }
00335   };
00336 
00337 
00338   // We need these bits in order to recover the return type of
00339   // some functions/operators now that we're no longer using
00340   // function templates.
00341   template<typename, typename _Tp>
00342     struct __fun
00343     {
00344       typedef _Tp result_type;
00345     };
00346 
00347   // several specializations for relational operators.
00348   template<typename _Tp>
00349     struct __fun<__logical_not, _Tp>
00350     {
00351       typedef bool result_type;
00352     };
00353 
00354   template<typename _Tp>
00355     struct __fun<__logical_and, _Tp>
00356     {
00357       typedef bool result_type;
00358     };
00359 
00360   template<typename _Tp>
00361     struct __fun<__logical_or, _Tp>
00362     {
00363       typedef bool result_type;
00364     };
00365 
00366   template<typename _Tp>
00367     struct __fun<__less, _Tp>
00368     {
00369       typedef bool result_type;
00370     };
00371 
00372   template<typename _Tp>
00373     struct __fun<__greater, _Tp>
00374     {
00375       typedef bool result_type;
00376     };
00377 
00378   template<typename _Tp>
00379     struct __fun<__less_equal, _Tp>
00380     {
00381       typedef bool result_type;
00382     };
00383 
00384   template<typename _Tp>
00385     struct __fun<__greater_equal, _Tp>
00386     {
00387       typedef bool result_type;
00388     };
00389 
00390   template<typename _Tp>
00391     struct __fun<__equal_to, _Tp>
00392     {
00393       typedef bool result_type;
00394     };
00395 
00396   template<typename _Tp>
00397     struct __fun<__not_equal_to, _Tp>
00398     {
00399       typedef bool result_type;
00400     };
00401 
00402   //
00403   // Apply function taking a value/const reference closure
00404   //
00405 
00406   template<typename _Dom, typename _Arg>
00407     class _FunBase
00408     {
00409     public:
00410       typedef typename _Dom::value_type value_type;
00411 
00412       _FunBase(const _Dom& __e, value_type __f(_Arg))
00413       : _M_expr(__e), _M_func(__f) {}
00414 
00415       value_type operator[](size_t __i) const
00416       { return _M_func (_M_expr[__i]); }
00417 
00418       size_t size() const { return _M_expr.size ();}
00419 
00420     private:
00421       const _Dom& _M_expr;
00422       value_type (*_M_func)(_Arg);
00423     };
00424 
00425   template<class _Dom>
00426     struct _ValFunClos<_Expr,_Dom> : _FunBase<_Dom, typename _Dom::value_type>
00427     {
00428       typedef _FunBase<_Dom, typename _Dom::value_type> _Base;
00429       typedef typename _Base::value_type value_type;
00430       typedef value_type _Tp;
00431 
00432       _ValFunClos(const _Dom& __e, _Tp __f(_Tp)) : _Base(__e, __f) {}
00433     };
00434 
00435   template<typename _Tp>
00436     struct _ValFunClos<_ValArray,_Tp> : _FunBase<valarray<_Tp>, _Tp>
00437     {
00438       typedef _FunBase<valarray<_Tp>, _Tp> _Base;
00439       typedef _Tp value_type;
00440 
00441       _ValFunClos(const valarray<_Tp>& __v, _Tp __f(_Tp)) : _Base(__v, __f) {}
00442     };
00443 
00444   template<class _Dom>
00445     struct _RefFunClos<_Expr, _Dom>
00446     : _FunBase<_Dom, const typename _Dom::value_type&>
00447     {
00448       typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base;
00449       typedef typename _Base::value_type value_type;
00450       typedef value_type _Tp;
00451 
00452       _RefFunClos(const _Dom& __e, _Tp __f(const _Tp&))
00453       : _Base(__e, __f) {}
00454     };
00455 
00456   template<typename _Tp>
00457     struct _RefFunClos<_ValArray, _Tp>
00458     : _FunBase<valarray<_Tp>, const _Tp&>
00459     {
00460       typedef _FunBase<valarray<_Tp>, const _Tp&> _Base;
00461       typedef _Tp value_type;
00462 
00463       _RefFunClos(const valarray<_Tp>& __v, _Tp __f(const _Tp&))
00464       : _Base(__v, __f) {}
00465     };
00466 
00467   //
00468   // Unary expression closure.
00469   //
00470 
00471   template<class _Oper, class _Arg>
00472     class _UnBase
00473     {
00474     public:
00475       typedef typename _Arg::value_type _Vt;
00476       typedef typename __fun<_Oper, _Vt>::result_type value_type;
00477 
00478       _UnBase(const _Arg& __e) : _M_expr(__e) {}
00479 
00480       value_type operator[](size_t __i) const
00481       { return _Oper()(_M_expr[__i]); }
00482 
00483       size_t size() const { return _M_expr.size(); }
00484       
00485     private:
00486       const _Arg& _M_expr;
00487     };
00488 
00489   template<class _Oper, class _Dom>
00490     struct _UnClos<_Oper, _Expr, _Dom>
00491     : _UnBase<_Oper, _Dom>
00492     {
00493       typedef _Dom _Arg;
00494       typedef _UnBase<_Oper, _Dom> _Base;
00495       typedef typename _Base::value_type value_type;
00496 
00497       _UnClos(const _Arg& __e) : _Base(__e) {}
00498     };
00499 
00500   template<class _Oper, typename _Tp>
00501     struct _UnClos<_Oper, _ValArray, _Tp>
00502     : _UnBase<_Oper, valarray<_Tp> >
00503     {
00504       typedef valarray<_Tp> _Arg;
00505       typedef _UnBase<_Oper, valarray<_Tp> > _Base;
00506       typedef typename _Base::value_type value_type;
00507 
00508       _UnClos(const _Arg& __e) : _Base(__e) {}
00509     };
00510 
00511 
00512   //
00513   // Binary expression closure.
00514   //
00515 
00516   template<class _Oper, class _FirstArg, class _SecondArg>
00517     class _BinBase
00518     {
00519     public:
00520       typedef typename _FirstArg::value_type _Vt;
00521       typedef typename __fun<_Oper, _Vt>::result_type value_type;
00522 
00523       _BinBase(const _FirstArg& __e1, const _SecondArg& __e2)
00524       : _M_expr1(__e1), _M_expr2(__e2) {}
00525 
00526       value_type operator[](size_t __i) const
00527       { return _Oper()(_M_expr1[__i], _M_expr2[__i]); }
00528 
00529       size_t size() const { return _M_expr1.size(); }
00530 
00531     private:
00532       const _FirstArg& _M_expr1;
00533       const _SecondArg& _M_expr2;
00534     };
00535 
00536 
00537   template<class _Oper, class _Clos>
00538     class _BinBase2
00539     {
00540     public:
00541       typedef typename _Clos::value_type _Vt;
00542       typedef typename __fun<_Oper, _Vt>::result_type value_type;
00543 
00544       _BinBase2(const _Clos& __e, const _Vt& __t)
00545       : _M_expr1(__e), _M_expr2(__t) {}
00546 
00547       value_type operator[](size_t __i) const
00548       { return _Oper()(_M_expr1[__i], _M_expr2); }
00549 
00550       size_t size() const { return _M_expr1.size(); }
00551 
00552     private:
00553       const _Clos& _M_expr1;
00554       const _Vt& _M_expr2;
00555     };
00556 
00557   template<class _Oper, class _Clos>
00558     class _BinBase1
00559     {
00560     public:
00561       typedef typename _Clos::value_type _Vt;
00562       typedef typename __fun<_Oper, _Vt>::result_type value_type;
00563 
00564       _BinBase1(const _Vt& __t, const _Clos& __e)
00565       : _M_expr1(__t), _M_expr2(__e) {}
00566 
00567       value_type operator[](size_t __i) const
00568       { return _Oper()(_M_expr1, _M_expr2[__i]); }
00569 
00570       size_t size() const { return _M_expr2.size(); }
00571 
00572     private:
00573       const _Vt& _M_expr1;
00574       const _Clos& _M_expr2;
00575     };
00576 
00577   template<class _Oper, class _Dom1, class _Dom2>
00578     struct _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2>
00579     : _BinBase<_Oper, _Dom1, _Dom2>
00580     {
00581       typedef _BinBase<_Oper, _Dom1, _Dom2> _Base;
00582       typedef typename _Base::value_type value_type;
00583 
00584       _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {}
00585     };
00586 
00587   template<class _Oper, typename _Tp>
00588     struct _BinClos<_Oper,_ValArray, _ValArray, _Tp, _Tp>
00589     : _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> >
00590     {
00591       typedef _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> > _Base;
00592       typedef typename _Base::value_type value_type;
00593 
00594       _BinClos(const valarray<_Tp>& __v, const valarray<_Tp>& __w)
00595       : _Base(__v, __w) {}
00596     };
00597 
00598   template<class _Oper, class _Dom>
00599     struct _BinClos<_Oper, _Expr, _ValArray, _Dom, typename _Dom::value_type>
00600     : _BinBase<_Oper, _Dom, valarray<typename _Dom::value_type> >
00601     {
00602       typedef typename _Dom::value_type _Tp;
00603       typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base;
00604       typedef typename _Base::value_type value_type;
00605 
00606       _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2)
00607       : _Base(__e1, __e2) {}
00608     };
00609 
00610   template<class _Oper, class _Dom>
00611     struct _BinClos<_Oper, _ValArray, _Expr, typename _Dom::value_type, _Dom>
00612     : _BinBase<_Oper, valarray<typename _Dom::value_type>,_Dom>
00613     {
00614       typedef typename _Dom::value_type _Tp;
00615       typedef _BinBase<_Oper, valarray<_Tp>, _Dom> _Base;
00616       typedef typename _Base::value_type value_type;
00617 
00618       _BinClos(const valarray<_Tp>& __e1, const _Dom& __e2)
00619       : _Base(__e1, __e2) {}
00620     };
00621 
00622   template<class _Oper, class _Dom>
00623     struct _BinClos<_Oper, _Expr, _Constant, _Dom, typename _Dom::value_type>
00624     : _BinBase2<_Oper, _Dom>
00625     {
00626       typedef typename _Dom::value_type _Tp;
00627       typedef _BinBase2<_Oper,_Dom> _Base;
00628       typedef typename _Base::value_type value_type;
00629 
00630       _BinClos(const _Dom& __e1, const _Tp& __e2) : _Base(__e1, __e2) {}
00631     };
00632 
00633   template<class _Oper, class _Dom>
00634     struct _BinClos<_Oper, _Constant, _Expr, typename _Dom::value_type, _Dom>
00635     : _BinBase1<_Oper, _Dom>
00636     {
00637       typedef typename _Dom::value_type _Tp;
00638       typedef _BinBase1<_Oper, _Dom> _Base;
00639       typedef typename _Base::value_type value_type;
00640 
00641       _BinClos(const _Tp& __e1, const _Dom& __e2) : _Base(__e1, __e2) {}
00642     };
00643 
00644   template<class _Oper, typename _Tp>
00645     struct _BinClos<_Oper, _ValArray, _Constant, _Tp, _Tp>
00646     : _BinBase2<_Oper, valarray<_Tp> >
00647     {
00648       typedef _BinBase2<_Oper,valarray<_Tp> > _Base;
00649       typedef typename _Base::value_type value_type;
00650 
00651       _BinClos(const valarray<_Tp>& __v, const _Tp& __t) : _Base(__v, __t) {}
00652     };
00653 
00654   template<class _Oper, typename _Tp>
00655     struct _BinClos<_Oper, _Constant, _ValArray, _Tp, _Tp>
00656     : _BinBase1<_Oper, valarray<_Tp> >
00657     {
00658       typedef _BinBase1<_Oper, valarray<_Tp> > _Base;
00659       typedef typename _Base::value_type value_type;
00660 
00661       _BinClos(const _Tp& __t, const valarray<_Tp>& __v) : _Base(__t, __v) {}
00662     };
00663 
00664     //
00665     // slice_array closure.
00666     //
00667   template<typename _Dom> 
00668     class _SBase
00669     {
00670     public:
00671       typedef typename _Dom::value_type value_type;
00672       
00673       _SBase (const _Dom& __e, const slice& __s)
00674       : _M_expr (__e), _M_slice (__s) {}
00675         
00676       value_type
00677       operator[] (size_t __i) const
00678       { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; }
00679         
00680       size_t
00681       size() const
00682       { return _M_slice.size (); }
00683 
00684     private:
00685       const _Dom& _M_expr;
00686       const slice& _M_slice;
00687     };
00688 
00689   template<typename _Tp>
00690     class _SBase<_Array<_Tp> >
00691     {
00692     public:
00693       typedef _Tp value_type;
00694       
00695       _SBase (_Array<_Tp> __a, const slice& __s)
00696       : _M_array (__a._M_data+__s.start()), _M_size (__s.size()),
00697     _M_stride (__s.stride()) {}
00698         
00699       value_type
00700       operator[] (size_t __i) const
00701       { return _M_array._M_data[__i * _M_stride]; }
00702       
00703       size_t
00704       size() const
00705       { return _M_size; }
00706 
00707     private:
00708       const _Array<_Tp> _M_array;
00709       const size_t _M_size;
00710       const size_t _M_stride;
00711     };
00712 
00713   template<class _Dom>
00714     struct _SClos<_Expr, _Dom>
00715     : _SBase<_Dom>
00716     {
00717       typedef _SBase<_Dom> _Base;
00718       typedef typename _Base::value_type value_type;
00719       
00720       _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {}
00721     };
00722 
00723   template<typename _Tp>
00724     struct _SClos<_ValArray, _Tp>
00725     : _SBase<_Array<_Tp> >
00726     {
00727       typedef  _SBase<_Array<_Tp> > _Base;
00728       typedef _Tp value_type;
00729       
00730       _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {}
00731     };
00732 
00733 _GLIBCXX_END_NAMESPACE
00734 
00735 #endif /* _CPP_VALARRAY_BEFORE_H */

Generated on Thu Nov 1 13:12:59 2007 for libstdc++ by  doxygen 1.5.1