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