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