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