Home | History | Annotate | Download | only in bits
      1 // The template and inlines for the -*- C++ -*- internal _Meta class.
      2 
      3 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
      4 // 2006, 2007, 2008, 2009, 2010  Free Software Foundation, Inc.
      5 //
      6 // This file is part of the GNU ISO C++ Library.  This library is free
      7 // software; you can redistribute it and/or modify it under the
      8 // terms of the GNU General Public License as published by the
      9 // Free Software Foundation; either version 3, or (at your option)
     10 // any later version.
     11 
     12 // This library is distributed in the hope that it will be useful,
     13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 // GNU General Public License for more details.
     16 
     17 // Under Section 7 of GPL version 3, you are granted additional
     18 // permissions described in the GCC Runtime Library Exception, version
     19 // 3.1, as published by the Free Software Foundation.
     20 
     21 // You should have received a copy of the GNU General Public License and
     22 // a copy of the GCC Runtime Library Exception along with this program;
     23 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     24 // <http://www.gnu.org/licenses/>.
     25 
     26 /** @file bits/valarray_before.h
     27  *  This is an internal header file, included by other library headers.
     28  *  Do not attempt to use it directly. @headername{valarray}
     29  */
     30 
     31 // Written by Gabriel Dos Reis <Gabriel.Dos-Reis (at) cmla.ens-cachan.fr>
     32 
     33 #ifndef _VALARRAY_BEFORE_H
     34 #define _VALARRAY_BEFORE_H 1
     35 
     36 #pragma GCC system_header
     37 
     38 #include <bits/slice_array.h>
     39 
     40 namespace std _GLIBCXX_VISIBILITY(default)
     41 {
     42 _GLIBCXX_BEGIN_NAMESPACE_VERSION
     43 
     44   //
     45   // Implementing a loosened valarray return value is tricky.
     46   // First we need to meet 26.3.1/3: we should not add more than
     47   // two levels of template nesting. Therefore we resort to template
     48   // template to "flatten" loosened return value types.
     49   // At some point we use partial specialization to remove one level
     50   // template nesting due to _Expr<>
     51   //
     52 
     53   // This class is NOT defined. It doesn't need to.
     54   template<typename _Tp1, typename _Tp2> class _Constant;
     55 
     56   // Implementations of unary functions applied to valarray<>s.
     57   // I use hard-coded object functions here instead of a generic
     58   // approach like pointers to function:
     59   //    1) correctness: some functions take references, others values.
     60   //       we can't deduce the correct type afterwards.
     61   //    2) efficiency -- object functions can be easily inlined
     62   //    3) be Koenig-lookup-friendly
     63 
     64   struct _Abs
     65   {
     66     template<typename _Tp>
     67       _Tp operator()(const _Tp& __t) const
     68       { return abs(__t); }
     69   };
     70 
     71   struct _Cos
     72   {
     73     template<typename _Tp>
     74       _Tp operator()(const _Tp& __t) const
     75       { return cos(__t); }
     76   };
     77 
     78   struct _Acos
     79   {
     80     template<typename _Tp>
     81       _Tp operator()(const _Tp& __t) const
     82       { return acos(__t); }
     83   };
     84 
     85   struct _Cosh
     86   {
     87     template<typename _Tp>
     88       _Tp operator()(const _Tp& __t) const
     89       { return cosh(__t); }
     90   };
     91 
     92   struct _Sin
     93   {
     94     template<typename _Tp>
     95       _Tp operator()(const _Tp& __t) const
     96       { return sin(__t); }
     97   };
     98 
     99   struct _Asin
    100   {
    101     template<typename _Tp>
    102       _Tp operator()(const _Tp& __t) const
    103       { return asin(__t); }
    104   };
    105 
    106   struct _Sinh
    107   {
    108     template<typename _Tp>
    109       _Tp operator()(const _Tp& __t) const
    110       { return sinh(__t); }
    111   };
    112 
    113   struct _Tan
    114   {
    115     template<typename _Tp>
    116       _Tp operator()(const _Tp& __t) const
    117       { return tan(__t); }
    118   };
    119 
    120   struct _Atan
    121   {
    122     template<typename _Tp>
    123       _Tp operator()(const _Tp& __t) const
    124       { return atan(__t); }
    125   };
    126 
    127   struct _Tanh
    128   {
    129     template<typename _Tp>
    130       _Tp operator()(const _Tp& __t) const
    131       { return tanh(__t); }
    132   };
    133 
    134   struct _Exp
    135   {
    136     template<typename _Tp>
    137       _Tp operator()(const _Tp& __t) const
    138       { return exp(__t); }
    139   };
    140 
    141   struct _Log
    142   {
    143     template<typename _Tp>
    144       _Tp operator()(const _Tp& __t) const
    145       { return log(__t); }
    146   };
    147 
    148   struct _Log10
    149   {
    150     template<typename _Tp>
    151       _Tp operator()(const _Tp& __t) const
    152       { return log10(__t); }
    153   };
    154 
    155   struct _Sqrt
    156   {
    157     template<typename _Tp>
    158       _Tp operator()(const _Tp& __t) const
    159       { return sqrt(__t); }
    160   };
    161 
    162   // In the past, we used to tailor operator applications semantics
    163   // to the specialization of standard function objects (i.e. plus<>, etc.)
    164   // That is incorrect.  Therefore we provide our own surrogates.
    165 
    166   struct __unary_plus
    167   {
    168     template<typename _Tp>
    169       _Tp operator()(const _Tp& __t) const
    170       { return +__t; }
    171   };
    172 
    173   struct __negate
    174   {
    175     template<typename _Tp>
    176       _Tp operator()(const _Tp& __t) const
    177       { return -__t; }
    178   };
    179 
    180   struct __bitwise_not
    181   {
    182     template<typename _Tp>
    183       _Tp operator()(const _Tp& __t) const
    184       { return ~__t; }
    185   };
    186 
    187   struct __plus
    188   {
    189     template<typename _Tp>
    190       _Tp operator()(const _Tp& __x, const _Tp& __y) const
    191       { return __x + __y; }
    192   };
    193 
    194   struct __minus
    195   {
    196     template<typename _Tp>
    197       _Tp operator()(const _Tp& __x, const _Tp& __y) const
    198       { return __x - __y; }
    199   };
    200 
    201   struct __multiplies
    202   {
    203     template<typename _Tp>
    204       _Tp operator()(const _Tp& __x, const _Tp& __y) const
    205       { return __x * __y; }
    206   };
    207 
    208   struct __divides
    209   {
    210     template<typename _Tp>
    211       _Tp operator()(const _Tp& __x, const _Tp& __y) const
    212       { return __x / __y; }
    213   };
    214 
    215   struct __modulus
    216   {
    217     template<typename _Tp>
    218       _Tp operator()(const _Tp& __x, const _Tp& __y) const
    219       { return __x % __y; }
    220   };
    221 
    222   struct __bitwise_xor
    223   {
    224     template<typename _Tp>
    225       _Tp operator()(const _Tp& __x, const _Tp& __y) const
    226       { return __x ^ __y; }
    227   };
    228 
    229   struct __bitwise_and
    230   {
    231     template<typename _Tp>
    232       _Tp operator()(const _Tp& __x, const _Tp& __y) const
    233       { return __x & __y; }
    234   };
    235 
    236   struct __bitwise_or
    237   {
    238     template<typename _Tp>
    239       _Tp operator()(const _Tp& __x, const _Tp& __y) const
    240       { return __x | __y; }
    241   };
    242 
    243   struct __shift_left
    244   {
    245     template<typename _Tp>
    246       _Tp operator()(const _Tp& __x, const _Tp& __y) const
    247       { return __x << __y; }
    248   };
    249 
    250   struct __shift_right
    251   {
    252     template<typename _Tp>
    253       _Tp operator()(const _Tp& __x, const _Tp& __y) const
    254       { return __x >> __y; }
    255   };
    256 
    257   struct __logical_and
    258   {
    259     template<typename _Tp>
    260       bool operator()(const _Tp& __x, const _Tp& __y) const
    261       { return __x && __y; }
    262   };
    263 
    264   struct __logical_or
    265   {
    266     template<typename _Tp>
    267       bool operator()(const _Tp& __x, const _Tp& __y) const
    268       { return __x || __y; }
    269   };
    270 
    271   struct __logical_not
    272   {
    273     template<typename _Tp>
    274       bool operator()(const _Tp& __x) const
    275       { return !__x; }
    276   };
    277 
    278   struct __equal_to
    279   {
    280     template<typename _Tp>
    281       bool operator()(const _Tp& __x, const _Tp& __y) const
    282       { return __x == __y; }
    283   };
    284 
    285   struct __not_equal_to
    286   {
    287     template<typename _Tp>
    288       bool operator()(const _Tp& __x, const _Tp& __y) const
    289       { return __x != __y; }
    290   };
    291 
    292   struct __less
    293   {
    294     template<typename _Tp>
    295       bool operator()(const _Tp& __x, const _Tp& __y) const
    296       { return __x < __y; }
    297   };
    298 
    299   struct __greater
    300   {
    301     template<typename _Tp>
    302       bool operator()(const _Tp& __x, const _Tp& __y) const
    303       { return __x > __y; }
    304   };
    305 
    306   struct __less_equal
    307   {
    308     template<typename _Tp>
    309       bool operator()(const _Tp& __x, const _Tp& __y) const
    310       { return __x <= __y; }
    311   };
    312 
    313   struct __greater_equal
    314   {
    315     template<typename _Tp>
    316       bool operator()(const _Tp& __x, const _Tp& __y) const
    317       { return __x >= __y; }
    318   };
    319 
    320   // The few binary functions we miss.
    321   struct _Atan2
    322   {
    323     template<typename _Tp>
    324       _Tp operator()(const _Tp& __x, const _Tp& __y) const
    325       { return atan2(__x, __y); }
    326   };
    327 
    328   struct _Pow
    329   {
    330     template<typename _Tp>
    331       _Tp operator()(const _Tp& __x, const _Tp& __y) const
    332       { return pow(__x, __y); }
    333   };
    334 
    335 
    336   // We need these bits in order to recover the return type of
    337   // some functions/operators now that we're no longer using
    338   // function templates.
    339   template<typename, typename _Tp>
    340     struct __fun
    341     {
    342       typedef _Tp result_type;
    343     };
    344 
    345   // several specializations for relational operators.
    346   template<typename _Tp>
    347     struct __fun<__logical_not, _Tp>
    348     {
    349       typedef bool result_type;
    350     };
    351 
    352   template<typename _Tp>
    353     struct __fun<__logical_and, _Tp>
    354     {
    355       typedef bool result_type;
    356     };
    357 
    358   template<typename _Tp>
    359     struct __fun<__logical_or, _Tp>
    360     {
    361       typedef bool result_type;
    362     };
    363 
    364   template<typename _Tp>
    365     struct __fun<__less, _Tp>
    366     {
    367       typedef bool result_type;
    368     };
    369 
    370   template<typename _Tp>
    371     struct __fun<__greater, _Tp>
    372     {
    373       typedef bool result_type;
    374     };
    375 
    376   template<typename _Tp>
    377     struct __fun<__less_equal, _Tp>
    378     {
    379       typedef bool result_type;
    380     };
    381 
    382   template<typename _Tp>
    383     struct __fun<__greater_equal, _Tp>
    384     {
    385       typedef bool result_type;
    386     };
    387 
    388   template<typename _Tp>
    389     struct __fun<__equal_to, _Tp>
    390     {
    391       typedef bool result_type;
    392     };
    393 
    394   template<typename _Tp>
    395     struct __fun<__not_equal_to, _Tp>
    396     {
    397       typedef bool result_type;
    398     };
    399 
    400   //
    401   // Apply function taking a value/const reference closure
    402   //
    403 
    404   template<typename _Dom, typename _Arg>
    405     class _FunBase
    406     {
    407     public:
    408       typedef typename _Dom::value_type value_type;
    409 
    410       _FunBase(const _Dom& __e, value_type __f(_Arg))
    411       : _M_expr(__e), _M_func(__f) {}
    412 
    413       value_type operator[](size_t __i) const
    414       { return _M_func (_M_expr[__i]); }
    415 
    416       size_t size() const { return _M_expr.size ();}
    417 
    418     private:
    419       const _Dom& _M_expr;
    420       value_type (*_M_func)(_Arg);
    421     };
    422 
    423   template<class _Dom>
    424     struct _ValFunClos<_Expr,_Dom> : _FunBase<_Dom, typename _Dom::value_type>
    425     {
    426       typedef _FunBase<_Dom, typename _Dom::value_type> _Base;
    427       typedef typename _Base::value_type value_type;
    428       typedef value_type _Tp;
    429 
    430       _ValFunClos(const _Dom& __e, _Tp __f(_Tp)) : _Base(__e, __f) {}
    431     };
    432 
    433   template<typename _Tp>
    434     struct _ValFunClos<_ValArray,_Tp> : _FunBase<valarray<_Tp>, _Tp>
    435     {
    436       typedef _FunBase<valarray<_Tp>, _Tp> _Base;
    437       typedef _Tp value_type;
    438 
    439       _ValFunClos(const valarray<_Tp>& __v, _Tp __f(_Tp)) : _Base(__v, __f) {}
    440     };
    441 
    442   template<class _Dom>
    443     struct _RefFunClos<_Expr, _Dom>
    444     : _FunBase<_Dom, const typename _Dom::value_type&>
    445     {
    446       typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base;
    447       typedef typename _Base::value_type value_type;
    448       typedef value_type _Tp;
    449 
    450       _RefFunClos(const _Dom& __e, _Tp __f(const _Tp&))
    451       : _Base(__e, __f) {}
    452     };
    453 
    454   template<typename _Tp>
    455     struct _RefFunClos<_ValArray, _Tp>
    456     : _FunBase<valarray<_Tp>, const _Tp&>
    457     {
    458       typedef _FunBase<valarray<_Tp>, const _Tp&> _Base;
    459       typedef _Tp value_type;
    460 
    461       _RefFunClos(const valarray<_Tp>& __v, _Tp __f(const _Tp&))
    462       : _Base(__v, __f) {}
    463     };
    464 
    465   //
    466   // Unary expression closure.
    467   //
    468 
    469   template<class _Oper, class _Arg>
    470     class _UnBase
    471     {
    472     public:
    473       typedef typename _Arg::value_type _Vt;
    474       typedef typename __fun<_Oper, _Vt>::result_type value_type;
    475 
    476       _UnBase(const _Arg& __e) : _M_expr(__e) {}
    477 
    478       value_type operator[](size_t __i) const
    479       { return _Oper()(_M_expr[__i]); }
    480 
    481       size_t size() const { return _M_expr.size(); }
    482 
    483     private:
    484       const _Arg& _M_expr;
    485     };
    486 
    487   template<class _Oper, class _Dom>
    488     struct _UnClos<_Oper, _Expr, _Dom>
    489     : _UnBase<_Oper, _Dom>
    490     {
    491       typedef _Dom _Arg;
    492       typedef _UnBase<_Oper, _Dom> _Base;
    493       typedef typename _Base::value_type value_type;
    494 
    495       _UnClos(const _Arg& __e) : _Base(__e) {}
    496     };
    497 
    498   template<class _Oper, typename _Tp>
    499     struct _UnClos<_Oper, _ValArray, _Tp>
    500     : _UnBase<_Oper, valarray<_Tp> >
    501     {
    502       typedef valarray<_Tp> _Arg;
    503       typedef _UnBase<_Oper, valarray<_Tp> > _Base;
    504       typedef typename _Base::value_type value_type;
    505 
    506       _UnClos(const _Arg& __e) : _Base(__e) {}
    507     };
    508 
    509 
    510   //
    511   // Binary expression closure.
    512   //
    513 
    514   template<class _Oper, class _FirstArg, class _SecondArg>
    515     class _BinBase
    516     {
    517     public:
    518       typedef typename _FirstArg::value_type _Vt;
    519       typedef typename __fun<_Oper, _Vt>::result_type value_type;
    520 
    521       _BinBase(const _FirstArg& __e1, const _SecondArg& __e2)
    522       : _M_expr1(__e1), _M_expr2(__e2) {}
    523 
    524       value_type operator[](size_t __i) const
    525       { return _Oper()(_M_expr1[__i], _M_expr2[__i]); }
    526 
    527       size_t size() const { return _M_expr1.size(); }
    528 
    529     private:
    530       const _FirstArg& _M_expr1;
    531       const _SecondArg& _M_expr2;
    532     };
    533 
    534 
    535   template<class _Oper, class _Clos>
    536     class _BinBase2
    537     {
    538     public:
    539       typedef typename _Clos::value_type _Vt;
    540       typedef typename __fun<_Oper, _Vt>::result_type value_type;
    541 
    542       _BinBase2(const _Clos& __e, const _Vt& __t)
    543       : _M_expr1(__e), _M_expr2(__t) {}
    544 
    545       value_type operator[](size_t __i) const
    546       { return _Oper()(_M_expr1[__i], _M_expr2); }
    547 
    548       size_t size() const { return _M_expr1.size(); }
    549 
    550     private:
    551       const _Clos& _M_expr1;
    552       const _Vt& _M_expr2;
    553     };
    554 
    555   template<class _Oper, class _Clos>
    556     class _BinBase1
    557     {
    558     public:
    559       typedef typename _Clos::value_type _Vt;
    560       typedef typename __fun<_Oper, _Vt>::result_type value_type;
    561 
    562       _BinBase1(const _Vt& __t, const _Clos& __e)
    563       : _M_expr1(__t), _M_expr2(__e) {}
    564 
    565       value_type operator[](size_t __i) const
    566       { return _Oper()(_M_expr1, _M_expr2[__i]); }
    567 
    568       size_t size() const { return _M_expr2.size(); }
    569 
    570     private:
    571       const _Vt& _M_expr1;
    572       const _Clos& _M_expr2;
    573     };
    574 
    575   template<class _Oper, class _Dom1, class _Dom2>
    576     struct _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2>
    577     : _BinBase<_Oper, _Dom1, _Dom2>
    578     {
    579       typedef _BinBase<_Oper, _Dom1, _Dom2> _Base;
    580       typedef typename _Base::value_type value_type;
    581 
    582       _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {}
    583     };
    584 
    585   template<class _Oper, typename _Tp>
    586     struct _BinClos<_Oper,_ValArray, _ValArray, _Tp, _Tp>
    587     : _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> >
    588     {
    589       typedef _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> > _Base;
    590       typedef typename _Base::value_type value_type;
    591 
    592       _BinClos(const valarray<_Tp>& __v, const valarray<_Tp>& __w)
    593       : _Base(__v, __w) {}
    594     };
    595 
    596   template<class _Oper, class _Dom>
    597     struct _BinClos<_Oper, _Expr, _ValArray, _Dom, typename _Dom::value_type>
    598     : _BinBase<_Oper, _Dom, valarray<typename _Dom::value_type> >
    599     {
    600       typedef typename _Dom::value_type _Tp;
    601       typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base;
    602       typedef typename _Base::value_type value_type;
    603 
    604       _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2)
    605       : _Base(__e1, __e2) {}
    606     };
    607 
    608   template<class _Oper, class _Dom>
    609     struct _BinClos<_Oper, _ValArray, _Expr, typename _Dom::value_type, _Dom>
    610     : _BinBase<_Oper, valarray<typename _Dom::value_type>,_Dom>
    611     {
    612       typedef typename _Dom::value_type _Tp;
    613       typedef _BinBase<_Oper, valarray<_Tp>, _Dom> _Base;
    614       typedef typename _Base::value_type value_type;
    615 
    616       _BinClos(const valarray<_Tp>& __e1, const _Dom& __e2)
    617       : _Base(__e1, __e2) {}
    618     };
    619 
    620   template<class _Oper, class _Dom>
    621     struct _BinClos<_Oper, _Expr, _Constant, _Dom, typename _Dom::value_type>
    622     : _BinBase2<_Oper, _Dom>
    623     {
    624       typedef typename _Dom::value_type _Tp;
    625       typedef _BinBase2<_Oper,_Dom> _Base;
    626       typedef typename _Base::value_type value_type;
    627 
    628       _BinClos(const _Dom& __e1, const _Tp& __e2) : _Base(__e1, __e2) {}
    629     };
    630 
    631   template<class _Oper, class _Dom>
    632     struct _BinClos<_Oper, _Constant, _Expr, typename _Dom::value_type, _Dom>
    633     : _BinBase1<_Oper, _Dom>
    634     {
    635       typedef typename _Dom::value_type _Tp;
    636       typedef _BinBase1<_Oper, _Dom> _Base;
    637       typedef typename _Base::value_type value_type;
    638 
    639       _BinClos(const _Tp& __e1, const _Dom& __e2) : _Base(__e1, __e2) {}
    640     };
    641 
    642   template<class _Oper, typename _Tp>
    643     struct _BinClos<_Oper, _ValArray, _Constant, _Tp, _Tp>
    644     : _BinBase2<_Oper, valarray<_Tp> >
    645     {
    646       typedef _BinBase2<_Oper,valarray<_Tp> > _Base;
    647       typedef typename _Base::value_type value_type;
    648 
    649       _BinClos(const valarray<_Tp>& __v, const _Tp& __t) : _Base(__v, __t) {}
    650     };
    651 
    652   template<class _Oper, typename _Tp>
    653     struct _BinClos<_Oper, _Constant, _ValArray, _Tp, _Tp>
    654     : _BinBase1<_Oper, valarray<_Tp> >
    655     {
    656       typedef _BinBase1<_Oper, valarray<_Tp> > _Base;
    657       typedef typename _Base::value_type value_type;
    658 
    659       _BinClos(const _Tp& __t, const valarray<_Tp>& __v) : _Base(__t, __v) {}
    660     };
    661 
    662     //
    663     // slice_array closure.
    664     //
    665   template<typename _Dom>
    666     class _SBase
    667     {
    668     public:
    669       typedef typename _Dom::value_type value_type;
    670 
    671       _SBase (const _Dom& __e, const slice& __s)
    672       : _M_expr (__e), _M_slice (__s) {}
    673 
    674       value_type
    675       operator[] (size_t __i) const
    676       { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; }
    677 
    678       size_t
    679       size() const
    680       { return _M_slice.size (); }
    681 
    682     private:
    683       const _Dom& _M_expr;
    684       const slice& _M_slice;
    685     };
    686 
    687   template<typename _Tp>
    688     class _SBase<_Array<_Tp> >
    689     {
    690     public:
    691       typedef _Tp value_type;
    692 
    693       _SBase (_Array<_Tp> __a, const slice& __s)
    694       : _M_array (__a._M_data+__s.start()), _M_size (__s.size()),
    695 	_M_stride (__s.stride()) {}
    696 
    697       value_type
    698       operator[] (size_t __i) const
    699       { return _M_array._M_data[__i * _M_stride]; }
    700 
    701       size_t
    702       size() const
    703       { return _M_size; }
    704 
    705     private:
    706       const _Array<_Tp> _M_array;
    707       const size_t _M_size;
    708       const size_t _M_stride;
    709     };
    710 
    711   template<class _Dom>
    712     struct _SClos<_Expr, _Dom>
    713     : _SBase<_Dom>
    714     {
    715       typedef _SBase<_Dom> _Base;
    716       typedef typename _Base::value_type value_type;
    717 
    718       _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {}
    719     };
    720 
    721   template<typename _Tp>
    722     struct _SClos<_ValArray, _Tp>
    723     : _SBase<_Array<_Tp> >
    724     {
    725       typedef  _SBase<_Array<_Tp> > _Base;
    726       typedef _Tp value_type;
    727 
    728       _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {}
    729     };
    730 
    731 _GLIBCXX_END_NAMESPACE_VERSION
    732 } // namespace
    733 
    734 #endif /* _CPP_VALARRAY_BEFORE_H */
    735