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