Home | History | Annotate | Line # | Download | only in bits
      1 // The template and inlines for the -*- C++ -*- internal _Meta class.
      2 
      3 // Copyright (C) 1997-2024 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   template<typename _Tp, bool _IsValidValarrayValue = !__is_abstract(_Tp)>
    335     struct __fun_with_valarray
    336     {
    337       typedef _Tp result_type;
    338     };
    339 
    340   template<typename _Tp>
    341     struct __fun_with_valarray<_Tp, false>
    342     {
    343       // No result type defined for invalid value types.
    344     };
    345 
    346   // We need these bits in order to recover the return type of
    347   // some functions/operators now that we're no longer using
    348   // function templates.
    349   template<typename, typename _Tp>
    350     struct __fun : __fun_with_valarray<_Tp>
    351     {
    352     };
    353 
    354   // several specializations for relational operators.
    355   template<typename _Tp>
    356     struct __fun<__logical_not, _Tp>
    357     {
    358       typedef bool result_type;
    359     };
    360 
    361   template<typename _Tp>
    362     struct __fun<__logical_and, _Tp>
    363     {
    364       typedef bool result_type;
    365     };
    366 
    367   template<typename _Tp>
    368     struct __fun<__logical_or, _Tp>
    369     {
    370       typedef bool result_type;
    371     };
    372 
    373   template<typename _Tp>
    374     struct __fun<__less, _Tp>
    375     {
    376       typedef bool result_type;
    377     };
    378 
    379   template<typename _Tp>
    380     struct __fun<__greater, _Tp>
    381     {
    382       typedef bool result_type;
    383     };
    384 
    385   template<typename _Tp>
    386     struct __fun<__less_equal, _Tp>
    387     {
    388       typedef bool result_type;
    389     };
    390 
    391   template<typename _Tp>
    392     struct __fun<__greater_equal, _Tp>
    393     {
    394       typedef bool result_type;
    395     };
    396 
    397   template<typename _Tp>
    398     struct __fun<__equal_to, _Tp>
    399     {
    400       typedef bool result_type;
    401     };
    402 
    403   template<typename _Tp>
    404     struct __fun<__not_equal_to, _Tp>
    405     {
    406       typedef bool result_type;
    407     };
    408 
    409 namespace __detail
    410 {
    411   // Closure types already have reference semantics and are often short-lived,
    412   // so store them by value to avoid (some cases of) dangling references to
    413   // out-of-scope temporaries.
    414   template<typename _Tp>
    415     struct _ValArrayRef
    416     { typedef const _Tp __type; };
    417 
    418   // Use real references for std::valarray objects.
    419   template<typename _Tp>
    420     struct _ValArrayRef< valarray<_Tp> >
    421     { typedef const valarray<_Tp>& __type; };
    422 
    423   //
    424   // Apply function taking a value/const reference closure
    425   //
    426 
    427   template<typename _Dom, typename _Arg>
    428     class _FunBase
    429     {
    430     public:
    431       typedef typename _Dom::value_type value_type;
    432 
    433       _FunBase(const _Dom& __e, value_type __f(_Arg))
    434       : _M_expr(__e), _M_func(__f) {}
    435 
    436       value_type operator[](size_t __i) const
    437       { return _M_func (_M_expr[__i]); }
    438 
    439       size_t size() const { return _M_expr.size ();}
    440 
    441     private:
    442       typename _ValArrayRef<_Dom>::__type _M_expr;
    443       value_type (*_M_func)(_Arg);
    444     };
    445 
    446   template<class _Dom>
    447     struct _ValFunClos<_Expr,_Dom> : _FunBase<_Dom, typename _Dom::value_type>
    448     {
    449       typedef _FunBase<_Dom, typename _Dom::value_type> _Base;
    450       typedef typename _Base::value_type value_type;
    451       typedef value_type _Tp;
    452 
    453       _ValFunClos(const _Dom& __e, _Tp __f(_Tp)) : _Base(__e, __f) {}
    454     };
    455 
    456   template<typename _Tp>
    457     struct _ValFunClos<_ValArray,_Tp> : _FunBase<valarray<_Tp>, _Tp>
    458     {
    459       typedef _FunBase<valarray<_Tp>, _Tp> _Base;
    460       typedef _Tp value_type;
    461 
    462       _ValFunClos(const valarray<_Tp>& __v, _Tp __f(_Tp)) : _Base(__v, __f) {}
    463     };
    464 
    465   template<class _Dom>
    466     struct _RefFunClos<_Expr, _Dom>
    467     : _FunBase<_Dom, const typename _Dom::value_type&>
    468     {
    469       typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base;
    470       typedef typename _Base::value_type value_type;
    471       typedef value_type _Tp;
    472 
    473       _RefFunClos(const _Dom& __e, _Tp __f(const _Tp&))
    474       : _Base(__e, __f) {}
    475     };
    476 
    477   template<typename _Tp>
    478     struct _RefFunClos<_ValArray, _Tp>
    479     : _FunBase<valarray<_Tp>, const _Tp&>
    480     {
    481       typedef _FunBase<valarray<_Tp>, const _Tp&> _Base;
    482       typedef _Tp value_type;
    483 
    484       _RefFunClos(const valarray<_Tp>& __v, _Tp __f(const _Tp&))
    485       : _Base(__v, __f) {}
    486     };
    487 
    488   //
    489   // Unary expression closure.
    490   //
    491 
    492   template<class _Oper, class _Arg>
    493     class _UnBase
    494     {
    495     public:
    496       typedef typename _Arg::value_type _Vt;
    497       typedef typename __fun<_Oper, _Vt>::result_type value_type;
    498 
    499       _UnBase(const _Arg& __e) : _M_expr(__e) {}
    500 
    501       value_type operator[](size_t __i) const
    502       { return _Oper()(_M_expr[__i]); }
    503 
    504       size_t size() const { return _M_expr.size(); }
    505 
    506     private:
    507       typename _ValArrayRef<_Arg>::__type _M_expr;
    508     };
    509 
    510   template<class _Oper, class _Dom>
    511     struct _UnClos<_Oper, _Expr, _Dom>
    512     : _UnBase<_Oper, _Dom>
    513     {
    514       typedef _Dom _Arg;
    515       typedef _UnBase<_Oper, _Dom> _Base;
    516       typedef typename _Base::value_type value_type;
    517 
    518       _UnClos(const _Arg& __e) : _Base(__e) {}
    519     };
    520 
    521   template<class _Oper, typename _Tp>
    522     struct _UnClos<_Oper, _ValArray, _Tp>
    523     : _UnBase<_Oper, valarray<_Tp> >
    524     {
    525       typedef valarray<_Tp> _Arg;
    526       typedef _UnBase<_Oper, valarray<_Tp> > _Base;
    527       typedef typename _Base::value_type value_type;
    528 
    529       _UnClos(const _Arg& __e) : _Base(__e) {}
    530     };
    531 
    532 
    533   //
    534   // Binary expression closure.
    535   //
    536 
    537   template<class _Oper, class _FirstArg, class _SecondArg>
    538     class _BinBase
    539     {
    540     public:
    541       typedef typename _FirstArg::value_type _Vt;
    542       typedef typename __fun<_Oper, _Vt>::result_type value_type;
    543 
    544       _BinBase(const _FirstArg& __e1, const _SecondArg& __e2)
    545       : _M_expr1(__e1), _M_expr2(__e2) {}
    546 
    547       value_type operator[](size_t __i) const
    548       { return _Oper()(_M_expr1[__i], _M_expr2[__i]); }
    549 
    550       size_t size() const { return _M_expr1.size(); }
    551 
    552     private:
    553       typename _ValArrayRef<_FirstArg>::__type _M_expr1;
    554       typename _ValArrayRef<_SecondArg>::__type _M_expr2;
    555     };
    556 
    557 
    558   template<class _Oper, class _Clos>
    559     class _BinBase2
    560     {
    561     public:
    562       typedef typename _Clos::value_type _Vt;
    563       typedef typename __fun<_Oper, _Vt>::result_type value_type;
    564 
    565       _BinBase2(const _Clos& __e, const _Vt& __t)
    566       : _M_expr1(__e), _M_expr2(__t) {}
    567 
    568       value_type operator[](size_t __i) const
    569       { return _Oper()(_M_expr1[__i], _M_expr2); }
    570 
    571       size_t size() const { return _M_expr1.size(); }
    572 
    573     private:
    574       typename _ValArrayRef<_Clos>::__type _M_expr1;
    575       _Vt _M_expr2;
    576     };
    577 
    578   template<class _Oper, class _Clos>
    579     class _BinBase1
    580     {
    581     public:
    582       typedef typename _Clos::value_type _Vt;
    583       typedef typename __fun<_Oper, _Vt>::result_type value_type;
    584 
    585       _BinBase1(const _Vt& __t, const _Clos& __e)
    586       : _M_expr1(__t), _M_expr2(__e) {}
    587 
    588       value_type operator[](size_t __i) const
    589       { return _Oper()(_M_expr1, _M_expr2[__i]); }
    590 
    591       size_t size() const { return _M_expr2.size(); }
    592 
    593     private:
    594       _Vt _M_expr1;
    595       typename _ValArrayRef<_Clos>::__type _M_expr2;
    596     };
    597 
    598   template<class _Oper, class _Dom1, class _Dom2>
    599     struct _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2>
    600     : _BinBase<_Oper, _Dom1, _Dom2>
    601     {
    602       typedef _BinBase<_Oper, _Dom1, _Dom2> _Base;
    603       typedef typename _Base::value_type value_type;
    604 
    605       _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {}
    606     };
    607 
    608   template<class _Oper, typename _Tp>
    609     struct _BinClos<_Oper, _ValArray, _ValArray, _Tp, _Tp>
    610     : _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> >
    611     {
    612       typedef _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> > _Base;
    613       typedef typename _Base::value_type value_type;
    614 
    615       _BinClos(const valarray<_Tp>& __v, const valarray<_Tp>& __w)
    616       : _Base(__v, __w) {}
    617     };
    618 
    619   template<class _Oper, class _Dom>
    620     struct _BinClos<_Oper, _Expr, _ValArray, _Dom, typename _Dom::value_type>
    621     : _BinBase<_Oper, _Dom, valarray<typename _Dom::value_type> >
    622     {
    623       typedef typename _Dom::value_type _Tp;
    624       typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base;
    625       typedef typename _Base::value_type value_type;
    626 
    627       _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2)
    628       : _Base(__e1, __e2) {}
    629     };
    630 
    631   template<class _Oper, class _Dom>
    632     struct _BinClos<_Oper, _ValArray, _Expr, typename _Dom::value_type, _Dom>
    633     : _BinBase<_Oper, valarray<typename _Dom::value_type>,_Dom>
    634     {
    635       typedef typename _Dom::value_type _Tp;
    636       typedef _BinBase<_Oper, valarray<_Tp>, _Dom> _Base;
    637       typedef typename _Base::value_type value_type;
    638 
    639       _BinClos(const valarray<_Tp>& __e1, const _Dom& __e2)
    640       : _Base(__e1, __e2) {}
    641     };
    642 
    643   template<class _Oper, class _Dom>
    644     struct _BinClos<_Oper, _Expr, _Constant, _Dom, typename _Dom::value_type>
    645     : _BinBase2<_Oper, _Dom>
    646     {
    647       typedef typename _Dom::value_type _Tp;
    648       typedef _BinBase2<_Oper,_Dom> _Base;
    649       typedef typename _Base::value_type value_type;
    650 
    651       _BinClos(const _Dom& __e1, const _Tp& __e2) : _Base(__e1, __e2) {}
    652     };
    653 
    654   template<class _Oper, class _Dom>
    655     struct _BinClos<_Oper, _Constant, _Expr, typename _Dom::value_type, _Dom>
    656     : _BinBase1<_Oper, _Dom>
    657     {
    658       typedef typename _Dom::value_type _Tp;
    659       typedef _BinBase1<_Oper, _Dom> _Base;
    660       typedef typename _Base::value_type value_type;
    661 
    662       _BinClos(const _Tp& __e1, const _Dom& __e2) : _Base(__e1, __e2) {}
    663     };
    664 
    665   template<class _Oper, typename _Tp>
    666     struct _BinClos<_Oper, _ValArray, _Constant, _Tp, _Tp>
    667     : _BinBase2<_Oper, valarray<_Tp> >
    668     {
    669       typedef _BinBase2<_Oper,valarray<_Tp> > _Base;
    670       typedef typename _Base::value_type value_type;
    671 
    672       _BinClos(const valarray<_Tp>& __v, const _Tp& __t) : _Base(__v, __t) {}
    673     };
    674 
    675   template<class _Oper, typename _Tp>
    676     struct _BinClos<_Oper, _Constant, _ValArray, _Tp, _Tp>
    677     : _BinBase1<_Oper, valarray<_Tp> >
    678     {
    679       typedef _BinBase1<_Oper, valarray<_Tp> > _Base;
    680       typedef typename _Base::value_type value_type;
    681 
    682       _BinClos(const _Tp& __t, const valarray<_Tp>& __v) : _Base(__t, __v) {}
    683     };
    684 
    685   //
    686   // slice_array closure.
    687   //
    688   template<typename _Dom>
    689     class _SBase
    690     {
    691     public:
    692       typedef typename _Dom::value_type value_type;
    693 
    694       _SBase (const _Dom& __e, const slice& __s)
    695       : _M_expr (__e), _M_slice (__s) {}
    696 
    697       value_type
    698       operator[] (size_t __i) const
    699       { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; }
    700 
    701       size_t
    702       size() const
    703       { return _M_slice.size (); }
    704 
    705     private:
    706       typename _ValArrayRef<_Dom>::__type _M_expr;
    707       const slice& _M_slice;
    708     };
    709 
    710   template<typename _Tp>
    711     class _SBase<_Array<_Tp> >
    712     {
    713     public:
    714       typedef _Tp value_type;
    715 
    716       _SBase (_Array<_Tp> __a, const slice& __s)
    717       : _M_array (__a._M_data+__s.start()), _M_size (__s.size()),
    718 	_M_stride (__s.stride()) {}
    719 
    720       value_type
    721       operator[] (size_t __i) const
    722       { return _M_array._M_data[__i * _M_stride]; }
    723 
    724       size_t
    725       size() const
    726       { return _M_size; }
    727 
    728     private:
    729       const _Array<_Tp> _M_array;
    730       const size_t _M_size;
    731       const size_t _M_stride;
    732     };
    733 
    734   template<class _Dom>
    735     struct _SClos<_Expr, _Dom>
    736     : _SBase<_Dom>
    737     {
    738       typedef _SBase<_Dom> _Base;
    739       typedef typename _Base::value_type value_type;
    740 
    741       _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {}
    742     };
    743 
    744   template<typename _Tp>
    745     struct _SClos<_ValArray, _Tp>
    746     : _SBase<_Array<_Tp> >
    747     {
    748       typedef  _SBase<_Array<_Tp> > _Base;
    749       typedef _Tp value_type;
    750 
    751       _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {}
    752     };
    753 } // namespace __detail
    754 
    755 _GLIBCXX_END_NAMESPACE_VERSION
    756 } // namespace
    757 
    758 #endif /* _CPP_VALARRAY_BEFORE_H */
    759