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

Generated on Tue Apr 21 13:13:37 2009 for libstdc++ by  doxygen 1.5.8