Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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