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