(root)/
gcc-13.2.0/
libstdc++-v3/
include/
bits/
valarray_before.h
       1  // The template and inlines for the -*- C++ -*- internal _Meta class.
       2  
       3  // Copyright (C) 1997-2023 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@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 */