Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // The template and inlines for the -*- C++ -*- internal _Meta class.
  2.  
  3. // Copyright (C) 1997-2015 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.   //
  410.   // Apply function taking a value/const reference closure
  411.   //
  412.  
  413.   template<typename _Dom, typename _Arg>
  414.     class _FunBase
  415.     {
  416.     public:
  417.       typedef typename _Dom::value_type value_type;
  418.  
  419.       _FunBase(const _Dom& __e, value_type __f(_Arg))
  420.       : _M_expr(__e), _M_func(__f) {}
  421.  
  422.       value_type operator[](size_t __i) const
  423.       { return _M_func (_M_expr[__i]); }
  424.  
  425.       size_t size() const { return _M_expr.size ();}
  426.  
  427.     private:
  428.       const _Dom& _M_expr;
  429.       value_type (*_M_func)(_Arg);
  430.     };
  431.  
  432.   template<class _Dom>
  433.     struct _ValFunClos<_Expr,_Dom> : _FunBase<_Dom, typename _Dom::value_type>
  434.     {
  435.       typedef _FunBase<_Dom, typename _Dom::value_type> _Base;
  436.       typedef typename _Base::value_type value_type;
  437.       typedef value_type _Tp;
  438.  
  439.       _ValFunClos(const _Dom& __e, _Tp __f(_Tp)) : _Base(__e, __f) {}
  440.     };
  441.  
  442.   template<typename _Tp>
  443.     struct _ValFunClos<_ValArray,_Tp> : _FunBase<valarray<_Tp>, _Tp>
  444.     {
  445.       typedef _FunBase<valarray<_Tp>, _Tp> _Base;
  446.       typedef _Tp value_type;
  447.  
  448.       _ValFunClos(const valarray<_Tp>& __v, _Tp __f(_Tp)) : _Base(__v, __f) {}
  449.     };
  450.  
  451.   template<class _Dom>
  452.     struct _RefFunClos<_Expr, _Dom>
  453.     : _FunBase<_Dom, const typename _Dom::value_type&>
  454.     {
  455.       typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base;
  456.       typedef typename _Base::value_type value_type;
  457.       typedef value_type _Tp;
  458.  
  459.       _RefFunClos(const _Dom& __e, _Tp __f(const _Tp&))
  460.       : _Base(__e, __f) {}
  461.     };
  462.  
  463.   template<typename _Tp>
  464.     struct _RefFunClos<_ValArray, _Tp>
  465.     : _FunBase<valarray<_Tp>, const _Tp&>
  466.     {
  467.       typedef _FunBase<valarray<_Tp>, const _Tp&> _Base;
  468.       typedef _Tp value_type;
  469.  
  470.       _RefFunClos(const valarray<_Tp>& __v, _Tp __f(const _Tp&))
  471.       : _Base(__v, __f) {}
  472.     };
  473.  
  474.   //
  475.   // Unary expression closure.
  476.   //
  477.  
  478.   template<class _Oper, class _Arg>
  479.     class _UnBase
  480.     {
  481.     public:
  482.       typedef typename _Arg::value_type _Vt;
  483.       typedef typename __fun<_Oper, _Vt>::result_type value_type;
  484.  
  485.       _UnBase(const _Arg& __e) : _M_expr(__e) {}
  486.  
  487.       value_type operator[](size_t __i) const
  488.       { return _Oper()(_M_expr[__i]); }
  489.  
  490.       size_t size() const { return _M_expr.size(); }
  491.      
  492.     private:
  493.       const _Arg& _M_expr;
  494.     };
  495.  
  496.   template<class _Oper, class _Dom>
  497.     struct _UnClos<_Oper, _Expr, _Dom>
  498.     : _UnBase<_Oper, _Dom>
  499.     {
  500.       typedef _Dom _Arg;
  501.       typedef _UnBase<_Oper, _Dom> _Base;
  502.       typedef typename _Base::value_type value_type;
  503.  
  504.       _UnClos(const _Arg& __e) : _Base(__e) {}
  505.     };
  506.  
  507.   template<class _Oper, typename _Tp>
  508.     struct _UnClos<_Oper, _ValArray, _Tp>
  509.     : _UnBase<_Oper, valarray<_Tp> >
  510.     {
  511.       typedef valarray<_Tp> _Arg;
  512.       typedef _UnBase<_Oper, valarray<_Tp> > _Base;
  513.       typedef typename _Base::value_type value_type;
  514.  
  515.       _UnClos(const _Arg& __e) : _Base(__e) {}
  516.     };
  517.  
  518.  
  519.   //
  520.   // Binary expression closure.
  521.   //
  522.  
  523.   template<class _Oper, class _FirstArg, class _SecondArg>
  524.     class _BinBase
  525.     {
  526.     public:
  527.       typedef typename _FirstArg::value_type _Vt;
  528.       typedef typename __fun<_Oper, _Vt>::result_type value_type;
  529.  
  530.       _BinBase(const _FirstArg& __e1, const _SecondArg& __e2)
  531.       : _M_expr1(__e1), _M_expr2(__e2) {}
  532.  
  533.       value_type operator[](size_t __i) const
  534.       { return _Oper()(_M_expr1[__i], _M_expr2[__i]); }
  535.  
  536.       size_t size() const { return _M_expr1.size(); }
  537.  
  538.     private:
  539.       const _FirstArg& _M_expr1;
  540.       const _SecondArg& _M_expr2;
  541.     };
  542.  
  543.  
  544.   template<class _Oper, class _Clos>
  545.     class _BinBase2
  546.     {
  547.     public:
  548.       typedef typename _Clos::value_type _Vt;
  549.       typedef typename __fun<_Oper, _Vt>::result_type value_type;
  550.  
  551.       _BinBase2(const _Clos& __e, const _Vt& __t)
  552.       : _M_expr1(__e), _M_expr2(__t) {}
  553.  
  554.       value_type operator[](size_t __i) const
  555.       { return _Oper()(_M_expr1[__i], _M_expr2); }
  556.  
  557.       size_t size() const { return _M_expr1.size(); }
  558.  
  559.     private:
  560.       const _Clos& _M_expr1;
  561.       const _Vt& _M_expr2;
  562.     };
  563.  
  564.   template<class _Oper, class _Clos>
  565.     class _BinBase1
  566.     {
  567.     public:
  568.       typedef typename _Clos::value_type _Vt;
  569.       typedef typename __fun<_Oper, _Vt>::result_type value_type;
  570.  
  571.       _BinBase1(const _Vt& __t, const _Clos& __e)
  572.       : _M_expr1(__t), _M_expr2(__e) {}
  573.  
  574.       value_type operator[](size_t __i) const
  575.       { return _Oper()(_M_expr1, _M_expr2[__i]); }
  576.  
  577.       size_t size() const { return _M_expr2.size(); }
  578.  
  579.     private:
  580.       const _Vt& _M_expr1;
  581.       const _Clos& _M_expr2;
  582.     };
  583.  
  584.   template<class _Oper, class _Dom1, class _Dom2>
  585.     struct _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2>
  586.     : _BinBase<_Oper, _Dom1, _Dom2>
  587.     {
  588.       typedef _BinBase<_Oper, _Dom1, _Dom2> _Base;
  589.       typedef typename _Base::value_type value_type;
  590.  
  591.       _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {}
  592.     };
  593.  
  594.   template<class _Oper, typename _Tp>
  595.     struct _BinClos<_Oper,_ValArray, _ValArray, _Tp, _Tp>
  596.     : _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> >
  597.     {
  598.       typedef _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> > _Base;
  599.       typedef typename _Base::value_type value_type;
  600.  
  601.       _BinClos(const valarray<_Tp>& __v, const valarray<_Tp>& __w)
  602.       : _Base(__v, __w) {}
  603.     };
  604.  
  605.   template<class _Oper, class _Dom>
  606.     struct _BinClos<_Oper, _Expr, _ValArray, _Dom, typename _Dom::value_type>
  607.     : _BinBase<_Oper, _Dom, valarray<typename _Dom::value_type> >
  608.     {
  609.       typedef typename _Dom::value_type _Tp;
  610.       typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base;
  611.       typedef typename _Base::value_type value_type;
  612.  
  613.       _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2)
  614.       : _Base(__e1, __e2) {}
  615.     };
  616.  
  617.   template<class _Oper, class _Dom>
  618.     struct _BinClos<_Oper, _ValArray, _Expr, typename _Dom::value_type, _Dom>
  619.     : _BinBase<_Oper, valarray<typename _Dom::value_type>,_Dom>
  620.     {
  621.       typedef typename _Dom::value_type _Tp;
  622.       typedef _BinBase<_Oper, valarray<_Tp>, _Dom> _Base;
  623.       typedef typename _Base::value_type value_type;
  624.  
  625.       _BinClos(const valarray<_Tp>& __e1, const _Dom& __e2)
  626.       : _Base(__e1, __e2) {}
  627.     };
  628.  
  629.   template<class _Oper, class _Dom>
  630.     struct _BinClos<_Oper, _Expr, _Constant, _Dom, typename _Dom::value_type>
  631.     : _BinBase2<_Oper, _Dom>
  632.     {
  633.       typedef typename _Dom::value_type _Tp;
  634.       typedef _BinBase2<_Oper,_Dom> _Base;
  635.       typedef typename _Base::value_type value_type;
  636.  
  637.       _BinClos(const _Dom& __e1, const _Tp& __e2) : _Base(__e1, __e2) {}
  638.     };
  639.  
  640.   template<class _Oper, class _Dom>
  641.     struct _BinClos<_Oper, _Constant, _Expr, typename _Dom::value_type, _Dom>
  642.     : _BinBase1<_Oper, _Dom>
  643.     {
  644.       typedef typename _Dom::value_type _Tp;
  645.       typedef _BinBase1<_Oper, _Dom> _Base;
  646.       typedef typename _Base::value_type value_type;
  647.  
  648.       _BinClos(const _Tp& __e1, const _Dom& __e2) : _Base(__e1, __e2) {}
  649.     };
  650.  
  651.   template<class _Oper, typename _Tp>
  652.     struct _BinClos<_Oper, _ValArray, _Constant, _Tp, _Tp>
  653.     : _BinBase2<_Oper, valarray<_Tp> >
  654.     {
  655.       typedef _BinBase2<_Oper,valarray<_Tp> > _Base;
  656.       typedef typename _Base::value_type value_type;
  657.  
  658.       _BinClos(const valarray<_Tp>& __v, const _Tp& __t) : _Base(__v, __t) {}
  659.     };
  660.  
  661.   template<class _Oper, typename _Tp>
  662.     struct _BinClos<_Oper, _Constant, _ValArray, _Tp, _Tp>
  663.     : _BinBase1<_Oper, valarray<_Tp> >
  664.     {
  665.       typedef _BinBase1<_Oper, valarray<_Tp> > _Base;
  666.       typedef typename _Base::value_type value_type;
  667.  
  668.       _BinClos(const _Tp& __t, const valarray<_Tp>& __v) : _Base(__t, __v) {}
  669.     };
  670.  
  671.     //
  672.     // slice_array closure.
  673.     //
  674.   template<typename _Dom>
  675.     class _SBase
  676.     {
  677.     public:
  678.       typedef typename _Dom::value_type value_type;
  679.      
  680.       _SBase (const _Dom& __e, const slice& __s)
  681.       : _M_expr (__e), _M_slice (__s) {}
  682.        
  683.       value_type
  684.       operator[] (size_t __i) const
  685.       { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; }
  686.        
  687.       size_t
  688.       size() const
  689.       { return _M_slice.size (); }
  690.  
  691.     private:
  692.       const _Dom& _M_expr;
  693.       const slice& _M_slice;
  694.     };
  695.  
  696.   template<typename _Tp>
  697.     class _SBase<_Array<_Tp> >
  698.     {
  699.     public:
  700.       typedef _Tp value_type;
  701.      
  702.       _SBase (_Array<_Tp> __a, const slice& __s)
  703.       : _M_array (__a._M_data+__s.start()), _M_size (__s.size()),
  704.         _M_stride (__s.stride()) {}
  705.        
  706.       value_type
  707.       operator[] (size_t __i) const
  708.       { return _M_array._M_data[__i * _M_stride]; }
  709.      
  710.       size_t
  711.       size() const
  712.       { return _M_size; }
  713.  
  714.     private:
  715.       const _Array<_Tp> _M_array;
  716.       const size_t _M_size;
  717.       const size_t _M_stride;
  718.     };
  719.  
  720.   template<class _Dom>
  721.     struct _SClos<_Expr, _Dom>
  722.     : _SBase<_Dom>
  723.     {
  724.       typedef _SBase<_Dom> _Base;
  725.       typedef typename _Base::value_type value_type;
  726.      
  727.       _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {}
  728.     };
  729.  
  730.   template<typename _Tp>
  731.     struct _SClos<_ValArray, _Tp>
  732.     : _SBase<_Array<_Tp> >
  733.     {
  734.       typedef  _SBase<_Array<_Tp> > _Base;
  735.       typedef _Tp value_type;
  736.      
  737.       _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {}
  738.     };
  739.  
  740. _GLIBCXX_END_NAMESPACE_VERSION
  741. } // namespace
  742.  
  743. #endif /* _CPP_VALARRAY_BEFORE_H */
  744.