This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Efficiency of memmove vs. generic typed copy


Gabriel Dos Reis <gdr@integrable-solutions.net> writes:

| I agree.  But, I cannot promise to do that now;  I'll send what I have
| for valarray (be prepared to scream for ABI breakage for no "good" reasons).

My attention has been called on something more urgent.  Here is the
diffs I have for valarray -- no guarantee it compilers and all
reasonable instantiations or does something useful.  It contains fixes
to issue DJ raised a few week ago and fixes to the non-POD uses with
valarray.  I'll flesh it out later.

One thing I don't quite remember is what problems we were solving with
the explicit instantiations in src/valarray-inst.cc.  Most of the
changes here affect inline functions.  You may want to look over ABI
breakage issue and see whether they are acceptable to you.

-- Gaby

*** bits/gslice.h	(revision 108262)
--- bits/gslice.h	(local)
*************** namespace std
*** 64,70 ****
    {
    public:
      ///  Construct an empty slice.
!     gslice ();
  
      /**
       *  @brief  Construct a slice.
--- 64,70 ----
    {
    public:
      ///  Construct an empty slice.
!     gslice();
  
      /**
       *  @brief  Construct a slice.
*************** namespace std
*** 80,86 ****
  
      // XXX: the IS says the copy-ctor and copy-assignment operators are
      //      synthetized by the compiler but they are just unsuitable
!     //      for a ref-counted semantic
      ///  Copy constructor.
      gslice(const gslice&);
  
--- 80,86 ----
  
      // XXX: the IS says the copy-ctor and copy-assignment operators are
      //      synthetized by the compiler but they are just unsuitable
!     //      for a ref-counted semantics
      ///  Copy constructor.
      gslice(const gslice&);
  
*************** namespace std
*** 101,106 ****
--- 101,113 ----
      valarray<size_t> stride() const;
  
    private:
+     // A glisce is internally represented as a linear array of
+     // indices  constructed out of the lengths and strides as
+     // specified in the gslice constructor.  Because of the curious
+     // query interface for stride() and size(), we store those
+     // data too, although they are nearly useless after the constructor
+     // for gslice completed.  Additionally, we use a reference
+     // counted implementation.
      struct _Indexer
      {
        size_t _M_count;
*************** namespace std
*** 125,142 ****
    };
  
    inline size_t
!   gslice::start () const
    { return _M_index ? _M_index->_M_start : 0; }
  
    inline valarray<size_t>
!   gslice::size () const
    { return _M_index ? _M_index->_M_size : valarray<size_t>(); }
  
    inline valarray<size_t>
!   gslice::stride () const
    { return _M_index ? _M_index->_M_stride : valarray<size_t>(); }
  
!   inline gslice::gslice () : _M_index(0) {}
  
    inline
    gslice::gslice(size_t __o, const valarray<size_t>& __l,
--- 132,149 ----
    };
  
    inline size_t
!   gslice::start() const
    { return _M_index ? _M_index->_M_start : 0; }
  
    inline valarray<size_t>
!   gslice::size() const
    { return _M_index ? _M_index->_M_size : valarray<size_t>(); }
  
    inline valarray<size_t>
!   gslice::stride() const
    { return _M_index ? _M_index->_M_stride : valarray<size_t>(); }
  
!   inline gslice::gslice() : _M_index(0) {}
  
    inline
    gslice::gslice(size_t __o, const valarray<size_t>& __l,
*************** namespace std
*** 155,161 ****
    }
  
    inline gslice&
!   gslice::operator= (const gslice& __g)
    {
      if (__g._M_index)
        __g._M_index->_M_increment_use();
--- 162,168 ----
    }
  
    inline gslice&
!   gslice::operator=(const gslice& __g)
    {
      if (__g._M_index)
        __g._M_index->_M_increment_use();
*** bits/gslice_array.h	(revision 108262)
--- bits/gslice_array.h	(local)
*************** namespace std
*** 65,71 ****
        // 253. valarray helper functions are almost entirely useless
  
        ///  Copy constructor.  Both slices refer to the same underlying array.
!       gslice_array(const gslice_array&);
  
        ///  Assignment operator.  Assigns slice elements to corresponding
        ///  elements of @a a.
--- 65,71 ----
        // 253. valarray helper functions are almost entirely useless
  
        ///  Copy constructor.  Both slices refer to the same underlying array.
!       // gslice_array(const gslice_array&);
  
        ///  Assignment operator.  Assigns slice elements to corresponding
        ///  elements of @a a.
*************** namespace std
*** 138,154 ****
      : _M_array(__a), _M_index(__i) {}
  
    template<typename _Tp>
-     inline
-     gslice_array<_Tp>::gslice_array(const gslice_array<_Tp>& __a)
-     : _M_array(__a._M_array), _M_index(__a._M_index) {}
- 
-   template<typename _Tp>
      inline gslice_array<_Tp>&
      gslice_array<_Tp>::operator=(const gslice_array<_Tp>& __a)
      {
!       std::__valarray_copy(_Array<_Tp>(__a._M_array),
! 			   _Array<size_t>(__a._M_index), _M_index.size(),
! 			   _M_array, _Array<size_t>(_M_index));
        return *this;
      }
  
--- 138,149 ----
      : _M_array(__a), _M_index(__i) {}
  
    template<typename _Tp>
      inline gslice_array<_Tp>&
      gslice_array<_Tp>::operator=(const gslice_array<_Tp>& __a)
      {
!       std::__valarray_assign(__a._M_array, _M_index.size(),
!                              __a._M_index.__values(),
!                              _M_array, _M_index.__values());
        return *this;
      }
  
*************** namespace std
*** 156,171 ****
      inline void
      gslice_array<_Tp>::operator=(const _Tp& __t) const
      {
!       std::__valarray_fill(_M_array, _Array<size_t>(_M_index),
! 			   _M_index.size(), __t);
      }
  
    template<typename _Tp>
      inline void
      gslice_array<_Tp>::operator=(const valarray<_Tp>& __v) const
      {
!       std::__valarray_copy(_Array<_Tp>(__v), __v.size(),
! 			   _M_array, _Array<size_t>(_M_index));
      }
  
    template<typename _Tp>
--- 151,166 ----
      inline void
      gslice_array<_Tp>::operator=(const _Tp& __t) const
      {
!       std::__valarray_assign(_M_index.size(), __t, _M_array,
!                              _M_index.__values());
      }
  
    template<typename _Tp>
      inline void
      gslice_array<_Tp>::operator=(const valarray<_Tp>& __v) const
      {
!       std::__valarray_assign(__v._values(), __v.size(),
!                              _M_array, _M_index.__values());
      }
  
    template<typename _Tp>
*************** namespace std
*** 173,180 ****
        inline void
        gslice_array<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e) const
        {
! 	std::__valarray_copy (__e, _M_index.size(), _M_array,
! 			      _Array<size_t>(_M_index));
        }
  
  #undef _DEFINE_VALARRAY_OPERATOR
--- 168,175 ----
        inline void
        gslice_array<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e) const
        {
! 	std::__valarray_assign(__e, _M_index.size(), _M_array,
!                                _M_index.__values());
        }
  
  #undef _DEFINE_VALARRAY_OPERATOR
*************** namespace std
*** 183,190 ****
      inline void								\
      gslice_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const	\
      {									\
!       _Array_augmented_##_Name(_M_array, _Array<size_t>(_M_index),	\
! 			       _Array<_Tp>(__v), __v.size());		\
      }									\
  									\
    template<typename _Tp>                                                \
--- 178,185 ----
      inline void								\
      gslice_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const	\
      {									\
!       _Array_augmented_##_Name(_M_array, _M_index.__values(),           \
! 			       __v.__values(), __v.size());		\
      }									\
  									\
    template<typename _Tp>                                                \
*************** namespace std
*** 192,198 ****
        inline void							\
        gslice_array<_Tp>::operator _Op##= (const _Expr<_Dom, _Tp>& __e) const\
        {									\
! 	_Array_augmented_##_Name(_M_array, _Array<size_t>(_M_index), __e,\
  				 _M_index.size());			\
        }
  
--- 187,193 ----
        inline void							\
        gslice_array<_Tp>::operator _Op##= (const _Expr<_Dom, _Tp>& __e) const\
        {									\
! 	_Array_augmented_##_Name(_M_array, _M_index.__values(), __e,    \
  				 _M_index.size());			\
        }
  
*** bits/indirect_array.h	(revision 108262)
--- bits/indirect_array.h	(local)
*************** namespace std
*** 67,73 ****
        // 253. valarray helper functions are almost entirely useless
  
        ///  Copy constructor.  Both slices refer to the same underlying array.
!       indirect_array(const indirect_array&);
  
        ///  Assignment operator.  Assigns elements to corresponding elements
        ///  of @a a.
--- 67,73 ----
        // 253. valarray helper functions are almost entirely useless
  
        ///  Copy constructor.  Both slices refer to the same underlying array.
!       // indirect_array(const indirect_array&);
  
        ///  Assignment operator.  Assigns elements to corresponding elements
        ///  of @a a.
*************** namespace std
*** 122,136 ****
        template<class _Dom>
        void operator>>=(const _Expr<_Dom, _Tp>&) const;
  
!     private:
!       ///  Copy constructor.  Both slices refer to the same underlying array.
!       indirect_array(_Array<_Tp>, size_t, _Array<size_t>);
  
!       friend class valarray<_Tp>;
!       friend class gslice_array<_Tp>;
  
        const size_t	 _M_sz;
!       const _Array<size_t> _M_index;
        const _Array<_Tp>	 _M_array;
  
        // not implemented
--- 122,136 ----
        template<class _Dom>
        void operator>>=(const _Expr<_Dom, _Tp>&) const;
  
!       _Index __indices() const;
!       _Array<_Tp> __values() const;
  
!     private:
!       //  Make an indirect_array out of its components.
!       indirect_array(_Array<_Tp>, size_t, _Index);
  
        const size_t	 _M_sz;
!       const _Index _M_index;
        const _Array<_Tp>	 _M_array;
  
        // not implemented
*************** namespace std
*** 138,177 ****
      };
  
    template<typename _Tp>
!     inline
!     indirect_array<_Tp>::indirect_array(const indirect_array<_Tp>& __a)
!     : _M_sz(__a._M_sz), _M_index(__a._M_index), _M_array(__a._M_array) {}
  
    template<typename _Tp>
      inline
      indirect_array<_Tp>::indirect_array(_Array<_Tp> __a, size_t __s,
! 					_Array<size_t> __i)
      : _M_sz(__s), _M_index(__i), _M_array(__a) {}
  
    template<typename _Tp>
      inline indirect_array<_Tp>&
      indirect_array<_Tp>::operator=(const indirect_array<_Tp>& __a)
      {
!       std::__valarray_copy(__a._M_array, _M_sz, __a._M_index, _M_array,
! 			   _M_index);
        return *this;
      }
  
    template<typename _Tp>
      inline void
      indirect_array<_Tp>::operator=(const _Tp& __t) const
!     { std::__valarray_fill(_M_array, _M_index, _M_sz, __t); }
  
    template<typename _Tp>
      inline void
      indirect_array<_Tp>::operator=(const valarray<_Tp>& __v) const
!     { std::__valarray_copy(_Array<_Tp>(__v), _M_sz, _M_array, _M_index); }
  
    template<typename _Tp>
      template<class _Dom>
        inline void
        indirect_array<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e) const
!       { std::__valarray_copy(__e, _M_sz, _M_array, _M_index); }
  
  #undef _DEFINE_VALARRAY_OPERATOR
  #define _DEFINE_VALARRAY_OPERATOR(_Op, _Name)				\
--- 138,180 ----
      };
  
    template<typename _Tp>
!     inline _Array<_Tp>
!     indirect_array<_Tp>::__values() const { return _M_array; }
! 
!   template<typename _Tp>
!     inline _Index
!     indirect_array<_Tp>::__indices() const { return _M_index; }
  
    template<typename _Tp>
      inline
      indirect_array<_Tp>::indirect_array(_Array<_Tp> __a, size_t __s,
!                                         _Index __i)
      : _M_sz(__s), _M_index(__i), _M_array(__a) {}
  
    template<typename _Tp>
      inline indirect_array<_Tp>&
      indirect_array<_Tp>::operator=(const indirect_array<_Tp>& __a)
      {
!       std::__valarray_assign(__a._M_array, __a._M_sz, __a._M_index, _M_array,
!                              _M_index);
        return *this;
      }
  
    template<typename _Tp>
      inline void
      indirect_array<_Tp>::operator=(const _Tp& __t) const
!     { std::__valarray_assign(_M_sz, __t, _M_array, _M_index); }
  
    template<typename _Tp>
      inline void
      indirect_array<_Tp>::operator=(const valarray<_Tp>& __v) const
!     { std::__valarray_assign(__v.__values(), __v.size(), _M_array, _M_index); }
  
    template<typename _Tp>
      template<class _Dom>
        inline void
        indirect_array<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e) const
!       { std::__valarray_assign(__e, _M_sz, _M_array, _M_index); }
  
  #undef _DEFINE_VALARRAY_OPERATOR
  #define _DEFINE_VALARRAY_OPERATOR(_Op, _Name)				\
*************** namespace std
*** 179,185 ****
      inline void								\
      indirect_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const\
      {									\
!       _Array_augmented_##_Name(_M_array, _M_index, _Array<_Tp>(__v), _M_sz); \
      }									\
  									\
    template<typename _Tp>                                                \
--- 182,188 ----
      inline void								\
      indirect_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const\
      {									\
!       _Array_augmented_##_Name(_M_array, _M_index, __v.__values(), _M_sz); \
      }									\
  									\
    template<typename _Tp>                                                \
*** bits/mask_array.h	(revision 108262)
--- bits/mask_array.h	(local)
*************** namespace std
*** 67,73 ****
        // 253. valarray helper functions are almost entirely useless
  
        ///  Copy constructor.  Both slices refer to the same underlying array.
!       mask_array (const mask_array&);
        
        ///  Assignment operator.  Assigns elements to corresponding elements
        ///  of @a a.
--- 67,73 ----
        // 253. valarray helper functions are almost entirely useless
  
        ///  Copy constructor.  Both slices refer to the same underlying array.
!       // mask_array (const mask_array&);
        
        ///  Assignment operator.  Assigns elements to corresponding elements
        ///  of @a a.
*************** namespace std
*** 135,144 ****
      };
  
    template<typename _Tp>
-     inline mask_array<_Tp>::mask_array(const mask_array<_Tp>& a)
-     : _M_sz(a._M_sz), _M_mask(a._M_mask), _M_array(a._M_array) {}
- 
-   template<typename _Tp>
      inline
      mask_array<_Tp>::mask_array(_Array<_Tp> __a, size_t __s, _Array<bool> __m)
      : _M_sz(__s), _M_mask(__m), _M_array(__a) {}
--- 135,140 ----
*************** namespace std
*** 147,172 ****
      inline mask_array<_Tp>&
      mask_array<_Tp>::operator=(const mask_array<_Tp>& __a)
      {
!       std::__valarray_copy(__a._M_array, __a._M_mask,
! 			   _M_sz, _M_array, _M_mask);
        return *this;
      }
  
    template<typename _Tp>
      inline void
      mask_array<_Tp>::operator=(const _Tp& __t) const
!     { std::__valarray_fill(_M_array, _M_sz, _M_mask, __t); }
  
    template<typename _Tp>
      inline void
      mask_array<_Tp>::operator=(const valarray<_Tp>& __v) const
!     { std::__valarray_copy(_Array<_Tp>(__v), __v.size(), _M_array, _M_mask); }
  
    template<typename _Tp>
      template<class _Ex>
        inline void
        mask_array<_Tp>::operator=(const _Expr<_Ex, _Tp>& __e) const
!       { std::__valarray_copy(__e, __e.size(), _M_array, _M_mask); }
  
  #undef _DEFINE_VALARRAY_OPERATOR
  #define _DEFINE_VALARRAY_OPERATOR(_Op, _Name)				\
--- 143,168 ----
      inline mask_array<_Tp>&
      mask_array<_Tp>::operator=(const mask_array<_Tp>& __a)
      {
!       std::__valarray_assign(__a._M_array, __a._M_sz, __a._M_mask,
!                              _M_array, _M_mask);
        return *this;
      }
  
    template<typename _Tp>
      inline void
      mask_array<_Tp>::operator=(const _Tp& __t) const
!     { std::__valarray_assign(_M_sz, __t, _M_array, _M_mask); }
  
    template<typename _Tp>
      inline void
      mask_array<_Tp>::operator=(const valarray<_Tp>& __v) const
!     { std::__valarray_assign(__v.__values(), __v.size(), _M_array, _M_mask); }
  
    template<typename _Tp>
      template<class _Ex>
        inline void
        mask_array<_Tp>::operator=(const _Expr<_Ex, _Tp>& __e) const
!       { std::__valarray_assign(__e, __e.size(), _M_array, _M_mask); }
  
  #undef _DEFINE_VALARRAY_OPERATOR
  #define _DEFINE_VALARRAY_OPERATOR(_Op, _Name)				\
*************** namespace std
*** 175,181 ****
      mask_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const	\
      {									\
        _Array_augmented_##_Name(_M_array, _M_mask,			\
! 			       _Array<_Tp>(__v), __v.size());		\
      }									\
  									\
    template<typename _Tp>                                                \
--- 171,177 ----
      mask_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const	\
      {									\
        _Array_augmented_##_Name(_M_array, _M_mask,			\
! 			       __v.__values(), __v.size());		\
      }									\
  									\
    template<typename _Tp>                                                \
*** bits/slice_array.h	(revision 108262)
--- bits/slice_array.h	(local)
*************** namespace std
*** 127,133 ****
        // 253. valarray helper functions are almost entirely useless
  
        ///  Copy constructor.  Both slices refer to the same underlying array.
!       slice_array(const slice_array&);
  
        ///  Assignment operator.  Assigns slice elements to corresponding
        ///  elements of @a a.
--- 127,133 ----
        // 253. valarray helper functions are almost entirely useless
  
        ///  Copy constructor.  Both slices refer to the same underlying array.
!       // slice_array(const slice_array&);
  
        ///  Assignment operator.  Assigns slice elements to corresponding
        ///  elements of @a a.
*************** namespace std
*** 200,210 ****
      : _M_sz(__s.size()), _M_stride(__s.stride()),
        _M_array(__a.begin() + __s.start()) {}
  
-   template<typename _Tp>
-     inline
-     slice_array<_Tp>::slice_array(const slice_array<_Tp>& a)
-     : _M_sz(a._M_sz), _M_stride(a._M_stride), _M_array(a._M_array) {}
- 
    //    template<typename _Tp>
    //    inline slice_array<_Tp>::~slice_array () {}
  
--- 200,205 ----
*************** namespace std
*** 212,237 ****
      inline slice_array<_Tp>&
      slice_array<_Tp>::operator=(const slice_array<_Tp>& __a)
      {
!       std::__valarray_copy(__a._M_array, __a._M_sz, __a._M_stride,
! 			   _M_array, _M_stride);
        return *this;
      }
  
    template<typename _Tp>
      inline void
      slice_array<_Tp>::operator=(const _Tp& __t) const
!     { std::__valarray_fill(_M_array, _M_sz, _M_stride, __t); }
  
    template<typename _Tp>
      inline void
      slice_array<_Tp>::operator=(const valarray<_Tp>& __v) const
!     { std::__valarray_copy(_Array<_Tp>(__v), _M_array, _M_sz, _M_stride); }
  
    template<typename _Tp>
    template<class _Dom>
      inline void
      slice_array<_Tp>::operator=(const _Expr<_Dom,_Tp>& __e) const
!     { std::__valarray_copy(__e, _M_sz, _M_array, _M_stride); }
  
  #undef _DEFINE_VALARRAY_OPERATOR
  #define _DEFINE_VALARRAY_OPERATOR(_Op,_Name)				\
--- 207,235 ----
      inline slice_array<_Tp>&
      slice_array<_Tp>::operator=(const slice_array<_Tp>& __a)
      {
!       std::__valarray_assign(__a._M_array, __a._M_sz, __a._M_stride,
!                              _M_array, _M_stride);
        return *this;
      }
  
    template<typename _Tp>
      inline void
      slice_array<_Tp>::operator=(const _Tp& __t) const
!     { std::__valarray_assign(_M_sz, __t, _M_array, _M_stride); }
  
    template<typename _Tp>
      inline void
      slice_array<_Tp>::operator=(const valarray<_Tp>& __v) const
!     {
!        std::__valarray_assign
!           (__v.__values(), __v.size(), _M_array, _M_stride);
!     }
  
    template<typename _Tp>
    template<class _Dom>
      inline void
      slice_array<_Tp>::operator=(const _Expr<_Dom,_Tp>& __e) const
!     { std::__valarray_assign(__e, _M_sz, _M_array, _M_stride); }
  
  #undef _DEFINE_VALARRAY_OPERATOR
  #define _DEFINE_VALARRAY_OPERATOR(_Op,_Name)				\
*************** namespace std
*** 239,245 ****
      inline void								\
      slice_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const	\
      {									\
!       _Array_augmented_##_Name(_M_array, _M_sz, _M_stride, _Array<_Tp>(__v));\
      }									\
  									\
    template<typename _Tp>                                                \
--- 237,243 ----
      inline void								\
      slice_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const	\
      {									\
!       _Array_augmented_##_Name(_M_array, _M_sz, _M_stride, __v.__values());\
      }									\
  									\
    template<typename _Tp>                                                \
*** bits/valarray_after.h	(revision 108262)
--- bits/valarray_after.h	(local)
*************** namespace std
*** 222,243 ****
    template<class _Clos, typename _Tp>
      inline valarray<_Tp>
      _Expr<_Clos, _Tp>::operator[](slice __s) const
!     { return _M_closure[__s]; }
  
    template<class _Clos, typename _Tp>
      inline valarray<_Tp>
      _Expr<_Clos, _Tp>::operator[](const gslice& __gs) const
!     { return _M_closure[__gs]; }
  
    template<class _Clos, typename _Tp>
      inline valarray<_Tp>
      _Expr<_Clos, _Tp>::operator[](const valarray<bool>& __m) const
!     { return _M_closure[__m]; }
  
    template<class _Clos, typename _Tp>
      inline valarray<_Tp>
      _Expr<_Clos, _Tp>::operator[](const valarray<size_t>& __i) const
!     { return _M_closure[__i]; }
  
    template<class _Clos, typename _Tp>
      inline size_t
--- 222,255 ----
    template<class _Clos, typename _Tp>
      inline valarray<_Tp>
      _Expr<_Clos, _Tp>::operator[](slice __s) const
!     {
!       valarray<_Tp> __v = valarray<_Tp>(_M_closure)[__s];
!       return __v;
!     }
  
    template<class _Clos, typename _Tp>
      inline valarray<_Tp>
      _Expr<_Clos, _Tp>::operator[](const gslice& __gs) const
!     {
!       valarray<_Tp> __v = valarray<_Tp>(_M_closure)[__gs];
!       return __v;
!     }
  
    template<class _Clos, typename _Tp>
      inline valarray<_Tp>
      _Expr<_Clos, _Tp>::operator[](const valarray<bool>& __m) const
!     {
!       valarray<_Tp> __v = valarray<_Tp>(_M_closure)[__m];
!       return __v;
!     }
  
    template<class _Clos, typename _Tp>
      inline valarray<_Tp>
      _Expr<_Clos, _Tp>::operator[](const valarray<size_t>& __i) const
!     {
!       valarray<_Tp> __v = valarray<_Tp>(_M_closure)[__i];
!       return __v;
!     }
  
    template<class _Clos, typename _Tp>
      inline size_t
*** bits/valarray_array.h	(revision 108262)
--- bits/valarray_array.h	(local)
*************** namespace std
*** 65,75 ****
  	(std::__valarray_get_memory(__n * sizeof(_Tp)));
      }
  
-   // Return memory to the system
-   inline void
-   __valarray_release_memory(void* __p)
-   { operator delete(__p); }
- 
    // Turn a raw-memory into an array of _Tp filled with _Tp()
    // This is required in 'valarray<T> v(n);'
    template<typename _Tp, bool>
--- 65,70 ----
*************** namespace std
*** 78,87 ****
        // Please note that this isn't exception safe.  But
        // valarrays aren't required to be exception safe.
        inline static void
!       _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
        {
! 	while (__b != __e)
! 	  new(__b++) _Tp();
        }
      };
  
--- 73,82 ----
        // Please note that this isn't exception safe.  But
        // valarrays aren't required to be exception safe.
        inline static void
!       _S_do_it(_Tp* __restrict__ __b, size_t __n)
        {
!         for (size_t __i = 0; __i < __n; ++__i)
! 	  new(__b + __i) _Tp();
        }
      };
  
*************** namespace std
*** 90,382 ****
      {
        // For fundamental types, it suffices to say 'memset()'
        inline static void
!       _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
!       { std::memset(__b, 0, (__e - __b) * sizeof(_Tp)); }
      };
  
    template<typename _Tp>
!     inline void
!     __valarray_default_construct(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
!     {
!       _Array_default_ctor<_Tp, __is_fundamental<_Tp>::__value>::
! 	_S_do_it(__b, __e);
!     }
  
    // Turn a raw-memory into an array of _Tp filled with __t
!   // This is the required in valarray<T> v(n, t).  Also
    // used in valarray<>::resize().
    template<typename _Tp, bool>
!     struct _Array_init_ctor
      {
        // Please note that this isn't exception safe.  But
        // valarrays aren't required to be exception safe.
        inline static void
!       _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e, const _Tp __t)
        {
! 	while (__b != __e)
! 	  new(__b++) _Tp(__t);
        }
      };
  
    template<typename _Tp>
!     struct _Array_init_ctor<_Tp, true>
      {
        inline static void
!       _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e,  const _Tp __t)
        {
! 	while (__b != __e)
! 	  *__b++ = __t;
        }
      };
  
    template<typename _Tp>
      inline void
!     __valarray_fill_construct(_Tp* __restrict__ __b, _Tp* __restrict__ __e,
! 			      const _Tp __t)
      {
!       _Array_init_ctor<_Tp, __is_fundamental<_Tp>::__value>::
! 	_S_do_it(__b, __e, __t);
      }
  
    //
!   // copy-construct raw array [__o, *) from plain array [__b, __e)
!   // We can't just say 'memcpy()'
    //
    template<typename _Tp, bool>
      struct _Array_copy_ctor
      {
        // Please note that this isn't exception safe.  But
        // valarrays aren't required to be exception safe.
        inline static void
!       _S_do_it(const _Tp* __restrict__ __b, const _Tp* __restrict__ __e,
! 	       _Tp* __restrict__ __o)
        {
! 	while (__b != __e)
! 	  new(__o++) _Tp(*__b++);
        }
      };
  
    template<typename _Tp>
      struct _Array_copy_ctor<_Tp, true>
      {
        inline static void
!       _S_do_it(const _Tp* __restrict__ __b, const _Tp* __restrict__ __e,
! 	       _Tp* __restrict__ __o)
!       { std::memcpy(__o, __b, (__e - __b)*sizeof(_Tp)); }
      };
  
    template<typename _Tp>
      inline void
!     __valarray_copy_construct(const _Tp* __restrict__ __b,
! 			      const _Tp* __restrict__ __e,
! 			      _Tp* __restrict__ __o)
      {
!       _Array_copy_ctor<_Tp, __is_fundamental<_Tp>::__value>::
! 	_S_do_it(__b, __e, __o);
      }
  
!   // copy-construct raw array [__o, *) from strided array __a[<__n : __s>]
    template<typename _Tp>
      inline void
!     __valarray_copy_construct (const _Tp* __restrict__ __a, size_t __n,
! 			       size_t __s, _Tp* __restrict__ __o)
      {
!       if (__is_fundamental<_Tp>::__value)
! 	while (__n--)
! 	  {
! 	    *__o++ = *__a;
! 	    __a += __s;
! 	  }
!       else
! 	while (__n--)
! 	  {
! 	    new(__o++) _Tp(*__a);
! 	    __a += __s;
! 	  }
      }
  
!   // copy-construct raw array [__o, *) from indexed array __a[__i[<__n>]]
    template<typename _Tp>
      inline void
!     __valarray_copy_construct (const _Tp* __restrict__ __a,
! 			       const size_t* __restrict__ __i,
! 			       _Tp* __restrict__ __o, size_t __n)
      {
!       if (__is_fundamental<_Tp>::__value)
! 	while (__n--)
! 	  *__o++ = __a[*__i++];
!       else
! 	while (__n--)
! 	  new (__o++) _Tp(__a[*__i++]);
      }
  
!   // Do the necessary cleanup when we're done with arrays.
    template<typename _Tp>
!     inline void
!     __valarray_destroy_elements(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
      {
!       if (!__is_fundamental<_Tp>::__value)
! 	while (__b != __e)
! 	  {
! 	    __b->~_Tp();
! 	    ++__b;
! 	  }
!     }
  
-   // Fill a plain array __a[<__n>] with __t
    template<typename _Tp>
      inline void
!     __valarray_fill(_Tp* __restrict__ __a, size_t __n, const _Tp& __t)
      {
!       while (__n--)
! 	*__a++ = __t;
      }
!   
!   // fill strided array __a[<__n-1 : __s>] with __t
    template<typename _Tp>
      inline void
!     __valarray_fill(_Tp* __restrict__ __a, size_t __n,
! 		    size_t __s, const _Tp& __t)
!     { 
!       for (size_t __i = 0; __i < __n; ++__i, __a += __s)
! 	*__a = __t;
      }
  
!   // fill indir   ect array __a[__i[<__n>]] with __i
    template<typename _Tp>
      inline void
!     __valarray_fill(_Tp* __restrict__ __a, const size_t* __restrict__ __i,
! 		    size_t __n, const _Tp& __t)
      {
!       for (size_t __j = 0; __j < __n; ++__j, ++__i)
! 	__a[*__i] = __t;
      }
-   
-   // copy plain array __a[<__n>] in __b[<__n>]
-   // For non-fundamental types, it is wrong to say 'memcpy()'
-   template<typename _Tp, bool>
-     struct _Array_copier
-     {
-       inline static void
-       _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b)
-       {
- 	while(__n--)
- 	  *__b++ = *__a++;
-       }
-     };
  
    template<typename _Tp>
!     struct _Array_copier<_Tp, true>
      {
!       inline static void
!       _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b)
!       { std::memcpy (__b, __a, __n * sizeof (_Tp)); }
!     };
  
!   // Copy a plain array __a[<__n>] into a play array __b[<>]
    template<typename _Tp>
      inline void
!     __valarray_copy(const _Tp* __restrict__ __a, size_t __n,
! 		    _Tp* __restrict__ __b)
      {
!       _Array_copier<_Tp, __is_fundamental<_Tp>::__value>::
! 	_S_do_it(__a, __n, __b);
      }
  
!   // Copy strided array __a[<__n : __s>] in plain __b[<__n>]
    template<typename _Tp>
      inline void
!     __valarray_copy(const _Tp* __restrict__ __a, size_t __n, size_t __s,
! 		    _Tp* __restrict__ __b)
      {
!       for (size_t __i = 0; __i < __n; ++__i, ++__b, __a += __s)
! 	*__b = *__a;
      }
  
!   // Copy a plain array  __a[<__n>] into a strided array __b[<__n : __s>]
    template<typename _Tp>
      inline void
!     __valarray_copy(const _Tp* __restrict__ __a, _Tp* __restrict__ __b,
! 		    size_t __n, size_t __s)
      {
!       for (size_t __i = 0; __i < __n; ++__i, ++__a, __b += __s)
! 	*__b = *__a;
      }
  
!   // Copy strided array __src[<__n : __s1>] into another
!   // strided array __dst[< : __s2>].  Their sizes must match.
    template<typename _Tp>
      inline void
!     __valarray_copy(const _Tp* __restrict__ __src, size_t __n, size_t __s1,
! 		    _Tp* __restrict__ __dst, size_t __s2)
      {
!       for (size_t __i = 0; __i < __n; ++__i)
! 	__dst[__i * __s2] = __src[__i * __s1];
      }
  
!   // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>]
    template<typename _Tp>
      inline void
!     __valarray_copy(const _Tp* __restrict__ __a,
! 		    const size_t* __restrict__ __i,
! 		    _Tp* __restrict__ __b, size_t __n)
      {
!       for (size_t __j = 0; __j < __n; ++__j, ++__b, ++__i)
! 	*__b = __a[*__i];
      }
  
!   // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]]
    template<typename _Tp>
      inline void
!     __valarray_copy(const _Tp* __restrict__ __a, size_t __n,
! 		    _Tp* __restrict__ __b, const size_t* __restrict__ __i)
      {
!       for (size_t __j = 0; __j < __n; ++__j, ++__a, ++__i)
! 	__b[*__i] = *__a;
      }
  
!   // Copy the __n first elements of an indexed array __src[<__i>] into
!   // another indexed array __dst[<__j>].
    template<typename _Tp>
      inline void
!     __valarray_copy(const _Tp* __restrict__ __src, size_t __n,
! 		    const size_t* __restrict__ __i,
! 		    _Tp* __restrict__ __dst, const size_t* __restrict__ __j)
      {
        for (size_t __k = 0; __k < __n; ++__k)
! 	__dst[*__j++] = __src[*__i++];
      }
  
!   //
!   // Compute the sum of elements in range [__f, __l)
    // This is a naive algorithm.  It suffers from cancelling.
    // In the future try to specialize
    // for _Tp = float, double, long double using a more accurate
    // algorithm.
    //
!   template<typename _Tp>
!     inline _Tp
!     __valarray_sum(const _Tp* __restrict__ __f, const _Tp* __restrict__ __l)
      {
!       _Tp __r = _Tp();
!       while (__f != __l)
! 	__r += *__f++;
        return __r;
      }
  
!   // Compute the product of all elements in range [__f, __l)
!   template<typename _Tp>
!     inline _Tp
!     __valarray_product(const _Tp* __restrict__ __f,
! 		       const _Tp* __restrict__ __l)
!     {
!       _Tp __r = _Tp(1);
!       while (__f != __l)
! 	__r = __r * *__f++;
        return __r;
      }
  
!   // Compute the min/max of an array-expression
    template<typename _Ta>
      inline typename _Ta::value_type
      __valarray_min(const _Ta& __a)
--- 85,501 ----
      {
        // For fundamental types, it suffices to say 'memset()'
        inline static void
!       _S_do_it(_Tp* __restrict__ __b, size_t __n)
!       { std::memset(__b, 0, __n * sizeof(_Tp)); }
      };
  
    template<typename _Tp>
!   inline void
!   __valarray_default_construct(_Tp* __restrict__ __a, size_t __n)
!   {
!     _Array_default_ctor<_Tp, __is_pod<_Tp>::__value>::_S_do_it(__a, __n);
!   }
  
    // Turn a raw-memory into an array of _Tp filled with __t
!   // This is used for example in valarray<T> v(n, t).  Also
    // used in valarray<>::resize().
    template<typename _Tp, bool>
!     struct _Array_filler
      {
        // Please note that this isn't exception safe.  But
        // valarrays aren't required to be exception safe.
        inline static void
!       _S_do_it(_Tp* __restrict__ __b, size_t __n, const _Tp& __t)
        {
!         for (size_t __i = 0; __i < __n; ++__i)
! 	  new(__b + __i) _Tp(__t);
        }
      };
  
    template<typename _Tp>
!     struct _Array_filler<_Tp, true>
      {
        inline static void
!       _S_do_it(_Tp* __restrict__ __b, size_t __n,
!                _Tp /* intentionally not a reference.  */ __t)  
        {
!         for (size_t __i = 0; __i < __n; ++__i)
! 	  __b[__i] = __t;
        }
      };
  
    template<typename _Tp>
      inline void
!      __valarray_fill(_Tp* __restrict__ __b, size_t __n, const _Tp& __t)
      {
!       _Array_filler<_Tp, __is_pod<_Tp>::__value>::_S_do_it(__b, __n, __t);
      }
  
    //
!   // Helper class _Array, first layer of valarray abstraction.
!   // All operations on valarray should be forwarded to this class
!   // whenever possible. -- gdr
!   // We maintain that _Array<> shall be a POD so that systems with
!   // reasonable C++ ABI see exactly zero abstraction penalty for uses
!   // of Array<> values as function arguments. -- gdr, 2005-12-10.
!   // 
!   template<typename _Tp>
!     struct _Array
!     {
!       _Tp* const __restrict__ data;
!       _Tp* begin() const;
! 
!       _Tp& operator[](size_t __i) { return data[__i]; }
!       const _Tp& operator[](size_t __i) const { return data[__i]; }
!     };
! 
!   // Allocate storage necessary to hold n values of type T.
!   template<typename _Tp>
!   inline _Array<_Tp>
!   __valarray_allocate(size_t __n)
!   {
!     _Array<_Tp> __a = { static_cast<_Tp*>(operator new(__n * sizeof (_Tp))) };
!     return __a;
!   }
! 
!   // Return storage, previously allocated by __valarray_allocate, to the
!   // system.
!   template<typename _Tp>
!   inline void
!   __valarray_deallocate(_Array<_Tp> __a)
!   { operator delete(__a.data); }
! 
!   // 
!   // Terminology and notation:
!   //    There are many helper functions operationg on _Array<>s, with various
!   //    arguments combinations.
!   //    There are five kinds of arrays:
!   //      (a) plain array -- one contiguous, one-dimenesional, array.
!   //      (b) slice array -- one-dimemsional regular *view* into a plain
!   //                         array with a given stride.  One may conceive
!   //                         of a plain array as a stried array, with
!   //                         stride equal to 1.
!   //      (c) gslice array -- a multi-dimensional *view* into a plain array
!   //                          with given lenghts and strides in each
!   //                          direction.
!   //      (d) indirect array -- one-dimensional possibly irregular *view*
!   //                            into a plain array.
!   //      (e) mask array -- one-dimensional *view* into a plain array where
!   //                        "active" slots are those where the mask values
!   //                        are true.  This more or less corresponds to
!   //                        Fortran's where/elsewhere construct.
    //
+   //   The core of array expressions/views are implemented here with
+   //   _Array<>.  We use the following notation in comments:
+   //       (i) a[<>]         -- plain array
+   //      (ii) a[<n : s>]    -- slide array of lenght n and stride s
+   //     (iii) a[(idx)]      -- indirec array with index values idx
+   //      (iv) a[{m}]        -- mask array with mask m.
+   //   We don't have a special notation for gslice arrays because they
+   //   transformed into indirect array before they reach this abstraction
+   //   layer.  So they don't exist here.
+   //
+   //   As a convention, all functions operating on arrays have at most on
+   //   array as output.  The output is the last argument.  To maintain
+   //   that consistency, and to avoid confusion in the myriad of
+   //   nearly similary arguments to functions defined below, we introduce
+   //   a type to tag arrays supposed to designate indices.  That is a
+   //   worthwhile inflation.
+ 
+   struct _Index
+   {
+     const size_t* const __restrict__ data;
+   };
+   
+ 
+   // 
+   // 1. _Array filler.
+   //    Fill the __n first slots of __dst[<>] with values equivalent to __t.
+   template<typename _Tp>
+     inline void
+     __valarray_fill(size_t __n, const _Tp& __t, _Array<_Tp> __dst)
+     {
+       std::__valarray_fill(__dst.data, __n, __t);
+     }
+ 
+   // 2. _Array copier.
+ 
+   // 2a. Copy-construct __dst[<>] with the __n first values of __src[<>]
+ 
+   // This helper class copy-constructs raw array __dst from plain
+   // array __src.  We can't just say 'memcpy()' because the value
+   // type is not necessarily a POD even with the "numerical type restriction".
+   // The second template parameter (with value "false" when used) controls
+   // the non-PODness.
    template<typename _Tp, bool>
      struct _Array_copy_ctor
      {
        // Please note that this isn't exception safe.  But
        // valarrays aren't required to be exception safe.
        inline static void
!       _S_do_it(_Array<_Tp> __src, size_t __n, _Array<_Tp> __dst)
!       {
!         const _Tp* __restrict__ __p = __src.data;
!         _Tp* __restrict__ __q = __dst.data;
!         for (size_t __i = 0; __i < __n; ++__i)
! 	  new(__q + __i) _Tp(__p[__i]);
!       }
! 
!       inline static void
!       _S_do_it(_Array<_Tp> __src, size_t __n, size_t __s, _Array<_Tp> __dst)
        {
!         const _Tp* __restrict__ __p = __src.data;
!         _Tp* __restrict__ __q = __dst.data;
!         for (size_t __i = 0; __i < __n; ++__i, __p += __s)
!           new (__q + __i) _Tp(*__p);
!       }
! 
!       inline static void
!       _S_do_it(_Array<_Tp> __src, size_t __n, _Index __idx, _Array<_Tp> __dst)
!       {
!         const _Tp* __restrict__ __p = __src.data;
!         const size_t* __restrict__ __i = __idx.data;
!         _Tp* __restrict__ __q = __dst.data;
!         for (size_t __j = 0; __j < __n; ++__j)
!           new (__q + __j) _Tp(__p[__i[__j]]);
        }
      };
  
+   // This specialization handles the cases where the value type is a POD.
+   // With a good optimizer in both front end and middle end, we would not
+   // need it.  Oh, well.
    template<typename _Tp>
      struct _Array_copy_ctor<_Tp, true>
      {
        inline static void
!       _S_do_it(_Array<_Tp> __src, size_t __n, _Array<_Tp> __dst)
!       { __valarray_assign(__src, __n, __dst); }
! 
!       inline static void
!       _S_do_it(_Array<_Tp> __src, size_t __n, size_t __s, _Array<_Tp> __dst)
!       { __valarray_assign(__src, __n, __s, __dst); }
! 
!       inline static void
!       _S_do_it(_Array<_Tp> __src, size_t __n, _Index __idx, _Array<_Tp> __dst)
!       { __valarray_assign(__src, __idx, __dst, __n); }
      };
  
    template<typename _Tp>
      inline void
!      __valarray_copy_construct(_Array<_Tp> __src, size_t __n,
!                                _Array<_Tp> __dst)
      {
!       _Array_copy_ctor<_Tp, __is_pod<_Tp>::__value>::
!         _S_do_it(__src, __n, __dst);
      }
  
!   // 2b. Copy-construct __dst[<>] from strided array __src[<__n : __s>]
    template<typename _Tp>
      inline void
!     __valarray_copy_construct(_Array<_Tp> __src, size_t __n,
! 			       size_t __s, _Array<_Tp> __dst)
      {
!       _Array_copy_ctor<_Tp, __is_pod<_Tp>::__value>::
!         _S_do_it(__src, __n, __s, __dst);
      }
  
!   // 2c. Copy-construct __dst[<>] from indexed array __src[(__i)]
    template<typename _Tp>
      inline void
!     __valarray_copy_construct(_Array<_Tp> __src, size_t __n, _Index __idx,
! 			       _Array<_Tp> __dst)
      {
!       _Array_copy_ctor<_Tp, __is_pod<_Tp>::__value>::
!         _S_do_it(__src, __idx, __dst, __n);
      }
  
!   // 3. _Array destructor.
!   template<typename _Tp, bool>
!     struct _Array_dtor
!     {
!       inline static void
!       _S_do_it(_Array<_Tp> __a, size_t __n)
!       {
!         _Tp* __restrict__ __p = __a.data;
!         for (size_t __i = 0; __i < __n; ++__i)
!           __p[__i].~_Tp();
!       }
!     };
! 
    template<typename _Tp>
!     struct _Array_dtor<_Tp, true>
      {
!       // PODs' estructors are trivial
!       inline static void _S_do_it(_Array<_Tp>, size_t) { }
!     };
  
    template<typename _Tp>
      inline void
!      __valarray_destroy_elements(_Array<_Tp> __a, size_t __n)
      {
!       _Array_dtor<_Tp, __is_pod<_Tp>::__value>::_S_do_it(__a, __n);
      }
! 
!   // 
!   // 4. _Array assigner.
!   //
! 
!   // 4a. Broadcast values equivalent to __t into __dst[<__n>]
    template<typename _Tp>
      inline void
!     __valarray_assign(size_t __n, const _Tp& __t, _Array<_Tp> __dst)
!     {
!       _Tp* __restrict__ __p = __dst.data;
!       for (size_t __i = 0; __i < __n; ++__i)
!         __p[__i] = __t;
      }
  
!   // 4b. Broadcast values equivalent to __t into __dst[<__n : __s>]
    template<typename _Tp>
      inline void
!     __valarray_assign(size_t __n, const _Tp& __t,
!                       _Array<_Tp> __dst, size_t __s)
      {
!       _Tp* __restrict__ __p = __dst.data;
!       for (size_t __i = 0; __i < __n; ++__i, __p += __s)
!         *__p = __t;
      }
  
+   // 4c. Broadcast __n values equivalent to __t in indexed array __dst[(__i)]
    template<typename _Tp>
!     inline void
!     __valarray_assign(size_t __n, const _Tp& __t,
!                       _Array<_Tp> __dst, _Index __idx)
      {
!       _Tp* __restrict__ __p = __dst.data;
!       const size_t* __restrict__ __i = __idx.data;
!       for (size_t __j = 0; __j < __n; ++__j, ++__i)
!         __p[*__i] = __t;
!     }
  
!   // 4d. Assign the __n first values of __src[<>] to  __dst[<>]
    template<typename _Tp>
      inline void
!     __valarray_assign(_Array<_Tp> __src, size_t __n, _Array<_Tp> __dst)
      {
!       const _Tp* __restrict__ __p = __src.data;
!       _Tp* __restrict__ __q = __dst.data;
!       for (size_t __i = 0; __i < __n; ++__i)
!         __q[__i] = __p[__i];
      }
  
!   // 4e. Assign the __n first values of strided array __src[< : __s>]
!   //     to __dst[<>]
    template<typename _Tp>
      inline void
!     __valarray_assign(_Array<_Tp> __src, size_t __n, size_t __s,
!                       _Array<_Tp> __dst)
      {
!       const _Tp* __restrict__ __p = __src.data;
!       _Tp* __restrict__ __q = __dst.data;
!       for (size_t __i = 0; __i < __n; __p += __s)
!         __q[__i] = *__p;
      }
  
!   // 4f. Assign the __n first values of __src[<>] to __dst[< : __s>]
    template<typename _Tp>
      inline void
!     __valarray_assign(_Array<_Tp> __src, size_t __n,
!                       _Array<_Tp> __dst, size_t __s)
      {
!       const _Tp* __restrict__ __p = __src.data;
!       _Tp* __restrict__ __q = __dst.data;
!       for (size_t __i = 0; __i < __n; ++__i, __q += __s)
!         *__q = __p[__i];
      }
  
!   // 4g. Assign the __n first values of __src[< : __s1>] __dst[< : __s2>]. 
    template<typename _Tp>
      inline void
!     __valarray_assign(_Array<_Tp> __src, size_t __n, size_t __s1,
!                       _Array<_Tp> __dst, size_t __s2)
      {
!       const _Tp* __restrict__ __p = __src.data;
!       _Tp* __restrict__ __q = __dst.data;
!       for (size_t __i = 0; __i < __n; __i, __p += __s1, __q += __s2)
!         *__q = *__p;
      }
  
!   // 4h.  Assign the __n first values of __src[(__i)] to __dst[<>]
    template<typename _Tp>
      inline void
!     __valarray_assign(_Array<_Tp> __src, size_t __n, _Index __idx,
!                       _Array<_Tp> __dst)
      {
!       const _Tp* __restrict__ __p = __src.data;
!       _Tp* __restrict__ __q = __dst.data;
!       const size_t* __restrict__ __i = __idx.data;
!       for (size_t __j = 0; __j < __n; ++__j)
!         __q[__j] = __p[__i[__j]];
      }
  
!   // 4i. Assign the __n first values of __src[<>] to __dst[(__i)]
    template<typename _Tp>
      inline void
!     __valarray_assign(_Array<_Tp> __src, size_t __n, _Array<_Tp> __dst,
!                       _Index __idx)
      {
!       const _Tp* __restrict__ __p = __src.data;
!       _Tp* __restrict__ __q = __dst.data;
!       const size_t* __restrict__ __i = __idx.data;
!       for (size_t __j = 0; __j < __n; ++__j)
!         __q[__i[__j]] = __p[__i];
      }
  
!   // 4j. Assign the __n first values of __src[(__i)] __dst[(__j)].
    template<typename _Tp>
      inline void
!     __valarray_assign(_Array<_Tp> __src, size_t __n, _Index __idx,
!                       _Array<_Tp> __dst, _Index __jdx)
      {
+       const _Tp* __restrict__ __p = __src.data;
+       _Tp* __restrict__ __q = __dst.data;
+       const size_t* __i = __idx.data;
+       const size_t* __j = __jdx.data;
        for (size_t __k = 0; __k < __n; ++__k)
!         __q[__j[__k]] = __p[__i[__k]];
      }
  
!   // 
!   // 5. _Array reducers.
!   // 
! 
!   // 5a. Reduce the values of an array-expression to their sum.
    // This is a naive algorithm.  It suffers from cancelling.
    // In the future try to specialize
    // for _Tp = float, double, long double using a more accurate
    // algorithm.
    //
!   template<typename _Ta>
!     inline typename _Ta::value_type
!     __valarray_sum(const _Ta&  __a)
      {
!       typedef typename _Ta::value_type _Value_type;
!       const size_t __n = __a.size();
!       _Value_type __r = _Value_type();
!       for (size_t __i = 0; __i < __n; ++__i)
!         __r = __r + __a[__i];
        return __r;
      }
  
!   // 5b. Reduce the values of an array-expression to their product.
!   template<typename _Ta>
!     inline typename _Ta::value_type
!     __valarray_product(const _Ta& __a)
!     {
!       const size_t __n = __a.size();
!       typename _Ta::value_type __r = 1;
!       for (size_t __i = 0; __i < __n; ++__i)
! 	__r = __r * __a[__i];
        return __r;
      }
  
!   // 5c. Reduce an array-expression to its minimum value.
    template<typename _Ta>
      inline typename _Ta::value_type
      __valarray_min(const _Ta& __a)
*************** namespace std
*** 393,398 ****
--- 512,518 ----
        return __r;
      }
  
+   // 5d. Reduce an array-expression to its maximum values.
    template<typename _Ta>
      inline typename _Ta::value_type
      __valarray_max(const _Ta& __a)
*************** namespace std
*** 409,533 ****
        return __r;
      }
  
!   //
!   // Helper class _Array, first layer of valarray abstraction.
!   // All operations on valarray should be forwarded to this class
!   // whenever possible. -- gdr
!   //
! 
!   template<typename _Tp>
!     struct _Array
!     {
!       explicit _Array(size_t);
!       explicit _Array(_Tp* const __restrict__);
!       explicit _Array(const valarray<_Tp>&);
!       _Array(const _Tp* __restrict__, size_t);
!       
!       _Tp* begin() const;
!       
!       _Tp* const __restrict__ _M_data;
!     };
! 
!   template<typename _Tp>
!     inline void
!     __valarray_fill (_Array<_Tp> __a, size_t __n, const _Tp& __t)
!     { std::__valarray_fill(__a._M_data, __n, __t); }
! 
!   template<typename _Tp>
!     inline void
!     __valarray_fill(_Array<_Tp> __a, size_t __n, size_t __s, const _Tp& __t)
!     { std::__valarray_fill(__a._M_data, __n, __s, __t); }
! 
!   template<typename _Tp>
!     inline void
!     __valarray_fill(_Array<_Tp> __a, _Array<size_t> __i,
! 		    size_t __n, const _Tp& __t)
!     { std::__valarray_fill(__a._M_data, __i._M_data, __n, __t); }
! 
!   // Copy a plain array __a[<__n>] into a play array __b[<>]
!   template<typename _Tp>
!     inline void
!     __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b)
!     { std::__valarray_copy(__a._M_data, __n, __b._M_data); }
! 
!   // Copy strided array __a[<__n : __s>] in plain __b[<__n>]
!   template<typename _Tp>
!     inline void
!     __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s, _Array<_Tp> __b)
!     { std::__valarray_copy(__a._M_data, __n, __s, __b._M_data); }
! 
!   // Copy a plain array  __a[<__n>] into a strided array __b[<__n : __s>]
!   template<typename _Tp>
!     inline void
!     __valarray_copy(_Array<_Tp> __a, _Array<_Tp> __b, size_t __n, size_t __s)
!     { __valarray_copy(__a._M_data, __b._M_data, __n, __s); }
! 
!   // Copy strided array __src[<__n : __s1>] into another
!   // strided array __dst[< : __s2>].  Their sizes must match.
!   template<typename _Tp>
!     inline void
!     __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s1,
!                     _Array<_Tp> __b, size_t __s2)
!     { std::__valarray_copy(__a._M_data, __n, __s1, __b._M_data, __s2); }
! 
!   // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>]
!   template<typename _Tp>
!     inline void
!     __valarray_copy(_Array<_Tp> __a, _Array<size_t> __i,
! 		    _Array<_Tp> __b, size_t __n)
!     { std::__valarray_copy(__a._M_data, __i._M_data, __b._M_data, __n); }
! 
!   // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]]
!   template<typename _Tp>
!     inline void
!     __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b,
! 		    _Array<size_t> __i)
!     { std::__valarray_copy(__a._M_data, __n, __b._M_data, __i._M_data); }
! 
!   // Copy the __n first elements of an indexed array __src[<__i>] into
!   // another indexed array __dst[<__j>].
!   template<typename _Tp>
!     inline void
!     __valarray_copy(_Array<_Tp> __src, size_t __n, _Array<size_t> __i,
!                     _Array<_Tp> __dst, _Array<size_t> __j)
!     {
!       std::__valarray_copy(__src._M_data, __n, __i._M_data,
! 		    __dst._M_data, __j._M_data);
!     }
! 
!   template<typename _Tp>
!     inline
!     _Array<_Tp>::_Array(size_t __n)
!     : _M_data(__valarray_get_storage<_Tp>(__n))
!     { std::__valarray_default_construct(_M_data, _M_data + __n); }
! 
!   template<typename _Tp>
!     inline
!     _Array<_Tp>::_Array(_Tp* const __restrict__ __p)
!     : _M_data (__p) {}
! 
!   template<typename _Tp>
!     inline
!     _Array<_Tp>::_Array(const valarray<_Tp>& __v)
!     : _M_data (__v._M_data) {}
! 
!   template<typename _Tp>
!     inline
!     _Array<_Tp>::_Array(const _Tp* __restrict__ __b, size_t __s)
!     : _M_data(__valarray_get_storage<_Tp>(__s))
!     { std::__valarray_copy_construct(__b, __s, _M_data); }
  
    template<typename _Tp>
      inline _Tp*
!     _Array<_Tp>::begin () const
!     { return _M_data; }
  
  #define _DEFINE_ARRAY_FUNCTION(_Op, _Name)				\
    template<typename _Tp>		        			\
      inline void								\
      _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, const _Tp& __t) \
      {									\
!       for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; ++__p)	\
          *__p _Op##= __t;						\
      }									\
  									\
--- 529,569 ----
        return __r;
      }
  
! //   template<typename _Tp>
! //     inline
! //     _Array<_Tp>::_Array(size_t __n)
! //     : data(__valarray_get_storage<_Tp>(__n))
! //     {
! //       _Array_default_ctor<_Tp, __is_pod<_Tp>::__value>::_S_do_it(data, __n);
! //     }
! 
! //   template<typename _Tp>
! //     inline
! //     _Array<_Tp>::_Array(_Tp* const __restrict__ __p)
! //     : data(__p) {}
! 
! //   template<typename _Tp>
! //     inline
! //     _Array<_Tp>::_Array(const valarray<_Tp>& __v)
! //     : data(__v.data) {}
! 
! //   template<typename _Tp>
! //     inline
! //     _Array<_Tp>::_Array(const _Tp* __restrict__ __b, size_t __s)
! //     : data(__valarray_get_storage<_Tp>(__s))
! //     { std::__valarray_copy_construct(__b, __s, data); }
  
    template<typename _Tp>
      inline _Tp*
!     _Array<_Tp>::begin() const
!     { return data; }
  
  #define _DEFINE_ARRAY_FUNCTION(_Op, _Name)				\
    template<typename _Tp>		        			\
      inline void								\
      _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, const _Tp& __t) \
      {									\
!       for (_Tp* __p = __a.data; __p < __a.data + __n; ++__p)	\
          *__p _Op##= __t;						\
      }									\
  									\
*************** namespace std
*** 535,542 ****
      inline void								\
      _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) \
      {									\
!       _Tp* __p = __a._M_data;						\
!       for (_Tp* __q = __b._M_data; __q < __b._M_data + __n; ++__p, ++__q) \
          *__p _Op##= *__q;						\
      }									\
  									\
--- 571,578 ----
      inline void								\
      _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) \
      {									\
!       _Tp* __p = __a.data;						\
!       for (_Tp* __q = __b.data; __q < __b.data + __n; ++__p, ++__q) \
          *__p _Op##= *__q;						\
      }									\
  									\
*************** namespace std
*** 545,551 ****
      _Array_augmented_##_Name(_Array<_Tp> __a,	        		\
                               const _Expr<_Dom, _Tp>& __e, size_t __n)	\
      {									\
!       _Tp* __p(__a._M_data);						\
        for (size_t __i = 0; __i < __n; ++__i, ++__p)                     \
          *__p _Op##= __e[__i];                                          	\
      }									\
--- 581,587 ----
      _Array_augmented_##_Name(_Array<_Tp> __a,	        		\
                               const _Expr<_Dom, _Tp>& __e, size_t __n)	\
      {									\
!       _Tp* __p(__a.data);						\
        for (size_t __i = 0; __i < __n; ++__i, ++__p)                     \
          *__p _Op##= __e[__i];                                          	\
      }									\
*************** namespace std
*** 555,562 ****
      _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, size_t __s,	\
  	                     _Array<_Tp> __b)				\
      {									\
!       _Tp* __q(__b._M_data);						\
!       for (_Tp* __p = __a._M_data; __p < __a._M_data + __s * __n;       \
  	   __p += __s, ++__q)                                           \
          *__p _Op##= *__q;						\
      }									\
--- 591,598 ----
      _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, size_t __s,	\
  	                     _Array<_Tp> __b)				\
      {									\
!       _Tp* __q(__b.data);						\
!       for (_Tp* __p = __a.data; __p < __a.data + __s * __n;       \
  	   __p += __s, ++__q)                                           \
          *__p _Op##= *__q;						\
      }									\
*************** namespace std
*** 566,573 ****
      _Array_augmented_##_Name(_Array<_Tp> __a, _Array<_Tp> __b,		\
  		             size_t __n, size_t __s)			\
      {									\
!       _Tp* __q(__b._M_data);						\
!       for (_Tp* __p = __a._M_data; __p < __a._M_data + __n;             \
  	   ++__p, __q += __s)                                           \
          *__p _Op##= *__q;						\
      }									\
--- 602,609 ----
      _Array_augmented_##_Name(_Array<_Tp> __a, _Array<_Tp> __b,		\
  		             size_t __n, size_t __s)			\
      {									\
!       _Tp* __q(__b.data);						\
!       for (_Tp* __p = __a.data; __p < __a.data + __n;             \
  	   ++__p, __q += __s)                                           \
          *__p _Op##= *__q;						\
      }									\
*************** namespace std
*** 577,583 ****
      _Array_augmented_##_Name(_Array<_Tp> __a, size_t __s,		\
                               const _Expr<_Dom, _Tp>& __e, size_t __n)	\
      {									\
!       _Tp* __p(__a._M_data);						\
        for (size_t __i = 0; __i < __n; ++__i, __p += __s)                \
          *__p _Op##= __e[__i];                                          	\
      }									\
--- 613,619 ----
      _Array_augmented_##_Name(_Array<_Tp> __a, size_t __s,		\
                               const _Expr<_Dom, _Tp>& __e, size_t __n)	\
      {									\
!       _Tp* __p(__a.data);						\
        for (size_t __i = 0; __i < __n; ++__i, __p += __s)                \
          *__p _Op##= __e[__i];                                          	\
      }									\
*************** namespace std
*** 587,596 ****
      _Array_augmented_##_Name(_Array<_Tp> __a, _Array<size_t> __i,	\
                               _Array<_Tp> __b, size_t __n)		\
      {									\
!       _Tp* __q(__b._M_data);						\
!       for (size_t* __j = __i._M_data; __j < __i._M_data + __n;          \
             ++__j, ++__q)                                                \
!         __a._M_data[*__j] _Op##= *__q;					\
      }									\
  									\
    template<typename _Tp>						\
--- 623,632 ----
      _Array_augmented_##_Name(_Array<_Tp> __a, _Array<size_t> __i,	\
                               _Array<_Tp> __b, size_t __n)		\
      {									\
!       _Tp* __q(__b.data);						\
!       for (size_t* __j = __i.data; __j < __i.data + __n;          \
             ++__j, ++__q)                                                \
!         __a.data[*__j] _Op##= *__q;					\
      }									\
  									\
    template<typename _Tp>						\
*************** namespace std
*** 598,607 ****
      _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n,		\
                               _Array<_Tp> __b, _Array<size_t> __i)	\
      {									\
!       _Tp* __p(__a._M_data);						\
!       for (size_t* __j = __i._M_data; __j<__i._M_data + __n;            \
  	   ++__j, ++__p)                                                \
!         *__p _Op##= __b._M_data[*__j];					\
      }									\
  									\
    template<typename _Tp, class _Dom>					\
--- 634,643 ----
      _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n,		\
                               _Array<_Tp> __b, _Array<size_t> __i)	\
      {									\
!       _Tp* __p(__a.data);						\
!       for (size_t* __j = __i.data; __j<__i.data + __n;            \
  	   ++__j, ++__p)                                                \
!         *__p _Op##= __b.data[*__j];					\
      }									\
  									\
    template<typename _Tp, class _Dom>					\
*************** namespace std
*** 609,617 ****
      _Array_augmented_##_Name(_Array<_Tp> __a, _Array<size_t> __i,	\
                               const _Expr<_Dom, _Tp>& __e, size_t __n)	\
      {									\
!       size_t* __j(__i._M_data);	        				\
        for (size_t __k = 0; __k<__n; ++__k, ++__j)			\
!         __a._M_data[*__j] _Op##= __e[__k];				\
      }									\
  									\
    template<typename _Tp>						\
--- 645,653 ----
      _Array_augmented_##_Name(_Array<_Tp> __a, _Array<size_t> __i,	\
                               const _Expr<_Dom, _Tp>& __e, size_t __n)	\
      {									\
!       size_t* __j(__i.data);	        				\
        for (size_t __k = 0; __k<__n; ++__k, ++__j)			\
!         __a.data[*__j] _Op##= __e[__k];				\
      }									\
  									\
    template<typename _Tp>						\
*************** namespace std
*** 619,627 ****
      _Array_augmented_##_Name(_Array<_Tp> __a, _Array<bool> __m,         \
                               _Array<_Tp> __b, size_t __n)		\
      {									\
!       bool* __ok(__m._M_data);						\
!       _Tp* __p(__a._M_data);						\
!       for (_Tp* __q = __b._M_data; __q < __b._M_data + __n;             \
  	   ++__q, ++__ok, ++__p)                                        \
          {                                                               \
            while (! *__ok)                                               \
--- 655,663 ----
      _Array_augmented_##_Name(_Array<_Tp> __a, _Array<bool> __m,         \
                               _Array<_Tp> __b, size_t __n)		\
      {									\
!       bool* __ok(__m.data);						\
!       _Tp* __p(__a.data);						\
!       for (_Tp* __q = __b.data; __q < __b.data + __n;             \
  	   ++__q, ++__ok, ++__p)                                        \
          {                                                               \
            while (! *__ok)                                               \
*************** namespace std
*** 638,646 ****
      _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n,		\
                               _Array<_Tp> __b, _Array<bool> __m)   	\
      {									\
!       bool* __ok(__m._M_data);						\
!       _Tp* __q(__b._M_data);						\
!       for (_Tp* __p = __a._M_data; __p < __a._M_data + __n;             \
  	   ++__p, ++__ok, ++__q)                                        \
          {                                                               \
            while (! *__ok)                                               \
--- 674,682 ----
      _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n,		\
                               _Array<_Tp> __b, _Array<bool> __m)   	\
      {									\
!       bool* __ok(__m.data);						\
!       _Tp* __q(__b.data);						\
!       for (_Tp* __p = __a.data; __p < __a.data + __n;             \
  	   ++__p, ++__ok, ++__q)                                        \
          {                                                               \
            while (! *__ok)                                               \
*************** namespace std
*** 657,664 ****
      _Array_augmented_##_Name(_Array<_Tp> __a, _Array<bool> __m,  	\
                               const _Expr<_Dom, _Tp>& __e, size_t __n)	\
      {									\
!       bool* __ok(__m._M_data);						\
!       _Tp* __p(__a._M_data);						\
        for (size_t __i = 0; __i < __n; ++__i, ++__ok, ++__p)             \
          {	                                           		\
            while (! *__ok)                                               \
--- 693,700 ----
      _Array_augmented_##_Name(_Array<_Tp> __a, _Array<bool> __m,  	\
                               const _Expr<_Dom, _Tp>& __e, size_t __n)	\
      {									\
!       bool* __ok(__m.data);						\
!       _Tp* __p(__a.data);						\
        for (size_t __i = 0; __i < __n; ++__i, ++__ok, ++__p)             \
          {	                                           		\
            while (! *__ok)                                               \
*** bits/valarray_array.tcc	(revision 108262)
--- bits/valarray_array.tcc	(local)
*************** namespace std
*** 41,243 ****
  {
    template<typename _Tp>
      void
!     __valarray_fill(_Array<_Tp> __a, size_t __n, _Array<bool> __m,
! 		    const _Tp& __t)
      {
!       _Tp* __p = __a._M_data;
!       bool* __ok (__m._M_data);
!       for (size_t __i=0; __i < __n; ++__i, ++__ok, ++__p)
  	{
  	  while (!*__ok)
! 	  {
! 	    ++__ok;
! 	    ++__p;
! 	  }
  	  *__p = __t;
  	}
      }
  
!   // Copy n elements of a into consecutive elements of b.  When m is
!   // false, the corresponding element of a is skipped.  m must contain
!   // at least n true elements.  a must contain at least n elements and
!   // enough elements to match up with m through the nth true element
!   // of m.  I.e.  if n is 10, m has 15 elements with 5 false followed
!   // by 10 true, a must have 15 elements.
    template<typename _Tp>
      void
!     __valarray_copy(_Array<_Tp> __a, _Array<bool> __m, _Array<_Tp> __b,
! 		    size_t __n)
!     {
!       _Tp* __p (__a._M_data);
!       bool* __ok (__m._M_data);
!       for (_Tp* __q = __b._M_data; __q < __b._M_data + __n;
! 	   ++__q, ++__ok, ++__p)
! 	{
! 	  while (! *__ok)
! 	    {
! 	      ++__ok;
! 	      ++__p;
! 	    }
! 	  *__q = *__p;
  	}
      }
  
!   // Copy n consecutive elements from a into elements of b.  Elements
!   // of b are skipped if the corresponding element of m is false.  m
!   // must contain at least n true elements.  b must have at least as
!   // many elements as the index of the nth true element of m.  I.e. if
!   // m has 15 elements with 5 false followed by 10 true, b must have
    // at least 15 elements.
    template<typename _Tp>
      void
!     __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b,
! 		    _Array<bool> __m)
      {
!       _Tp* __q (__b._M_data);
!       bool* __ok (__m._M_data);
!       for (_Tp* __p = __a._M_data; __p < __a._M_data+__n;
! 	   ++__p, ++__ok, ++__q)
! 	{
! 	  while (! *__ok)
! 	    {
! 	      ++__ok;
! 	      ++__q;
! 	    }
! 	  *__q = *__p;
  	}
      }
  
!   // Copy n elements from a into elements of b.  Elements of a are
!   // skipped if the corresponding element of m is false.  Elements of
!   // b are skipped if the corresponding element of k is false.  m and
!   // k must contain at least n true elements.  a and b must have at
!   // least as many elements as the index of the nth true element of m.
    template<typename _Tp>
      void
!     __valarray_copy(_Array<_Tp> __a, _Array<bool> __m, size_t __n,
! 		    _Array<_Tp> __b, _Array<bool> __k)
      {
!       _Tp* __p (__a._M_data);
!       _Tp* __q (__b._M_data);
!       bool* __srcok (__m._M_data);
!       bool* __dstok (__k._M_data);
        for (size_t __i = 0; __i < __n;
  	   ++__srcok, ++__p, ++__dstok, ++__q, ++__i)
  	{
! 	  while (! *__srcok)
! 	    {
! 	      ++__srcok;
! 	      ++__p;
! 	    }
! 	  while (! *__dstok) 
! 	    {
! 	      ++__dstok;
! 	      ++__q;
! 	    }
  	  *__q = *__p;
  	}
      }
  
!   // Copy n consecutive elements of e into consecutive elements of a.
!   // I.e. a[i] = e[i].
    template<typename _Tp, class _Dom>
      void
!     __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n, _Array<_Tp> __a)
      {
!       _Tp* __p (__a._M_data);
        for (size_t __i = 0; __i < __n; ++__i, ++__p)
! 	*__p = __e[__i];
      }
  
!   // Copy n consecutive elements of e into elements of a using stride
!   // s.  I.e., a[0] = e[0], a[s] = e[1], a[2*s] = e[2].
    template<typename _Tp, class _Dom>
      void
!     __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n,
! 		     _Array<_Tp> __a, size_t __s)
      {
!       _Tp* __p (__a._M_data);
        for (size_t __i = 0; __i < __n; ++__i, __p += __s)
! 	*__p = __e[__i];
      }
  
!   // Copy n consecutive elements of e into elements of a indexed by
!   // contents of i.  I.e., a[i[0]] = e[0].
    template<typename _Tp, class _Dom>
      void
!     __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n,
! 		    _Array<_Tp> __a, _Array<size_t> __i)
      {
!       size_t* __j (__i._M_data);
!       for (size_t __k = 0; __k < __n; ++__k, ++__j)
! 	__a._M_data[*__j] = __e[__k];
      }
  
!   // Copy n elements of e indexed by contents of f into elements of a
!   // indexed by contents of i.  I.e., a[i[0]] = e[f[0]].
!   template<typename _Tp>
      void
!     __valarray_copy(_Array<_Tp> __e, _Array<size_t> __f,
! 		    size_t __n, 
! 		    _Array<_Tp> __a, _Array<size_t> __i)
!     {
!       size_t* __g (__f._M_data);
!       size_t* __j (__i._M_data);
!       for (size_t __k = 0; __k < __n; ++__k, ++__j, ++__g) 
! 	__a._M_data[*__j] = __e._M_data[*__g];
!     }
! 
!   // Copy n consecutive elements of e into elements of a.  Elements of
!   // a are skipped if the corresponding element of m is false.  m must
!   // have at least n true elements and a must have at least as many
!   // elements as the index of the nth true element of m.  I.e. if m
!   // has 5 false followed by 10 true elements and n == 10, a must have
!   // at least 15 elements.
    template<typename _Tp, class _Dom>
      void
!     __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n,
! 		    _Array<_Tp> __a, _Array<bool> __m)
      {
!       bool* __ok (__m._M_data);
!       _Tp* __p (__a._M_data);
        for (size_t __i = 0; __i < __n; ++__i, ++__ok, ++__p)
  	{
! 	  while (! *__ok)
! 	    {
! 	      ++__ok;
! 	      ++__p;
! 	    }
! 	  *__p = __e[__i];
  	}
      }
  
  
    template<typename _Tp, class _Dom>
      void
!     __valarray_copy_construct(const _Expr<_Dom, _Tp>& __e, size_t __n,
! 			      _Array<_Tp> __a)
      {
!       _Tp* __p (__a._M_data);
        for (size_t __i = 0; __i < __n; ++__i, ++__p)
! 	new (__p) _Tp(__e[__i]);
      }
  
  
    template<typename _Tp>
      void
!     __valarray_copy_construct(_Array<_Tp> __a, _Array<bool> __m,
! 			      _Array<_Tp> __b, size_t __n)
      {
!       _Tp* __p (__a._M_data);
!       bool* __ok (__m._M_data);
!       for (_Tp* __q = __b._M_data; __q < __b._M_data+__n; ++__q, ++__ok, ++__p)
! 	{
! 	  while (! *__ok)
! 	    {
! 	      ++__ok;
! 	      ++__p;
! 	    }
! 	  new (__q) _Tp(*__p);
  	}
      }
  } // namespace std
--- 41,231 ----
  {
    template<typename _Tp>
      void
!     __valarray_assign(const _Tp& __t, size_t __n,
!                       _Array<_Tp> __dst, _Array<bool> __m)
      {
!       _Tp* __restrict__ __p = __dst.data;
!       const bool* __restrict__ __ok = __m.data;
!       for (size_t __i = 0; __i < __n; ++__i, ++__ok, ++__p)
  	{
  	  while (!*__ok)
!             {
!               ++__ok;
!               ++__p;
!             }
  	  *__p = __t;
  	}
      }
  
!   // Assign __n elements of __src[{__m}] to consecutive slots of __dst[<>].
!   // When a value of __m[<>] is false, the corresponding element of __src is
!   // skipped.  __m must contain at least __n true values.  __src must contain
!   // at least n elements and enough elements to match up with __m through
!   // the __nth true element of __m.  E.g., if __n is 10, __m has 15 elements
!   // with 5 false followed by 10 true, __src must have 15 elements.
    template<typename _Tp>
      void
!     __valarray_assign(_Array<_Tp> __src, _Array<bool> __m, _Array<_Tp> __dst,
!                       size_t __n)
!     {
!       const _Tp* __restrict__  __p = __src.data;
!       bool* __restrict__ __ok = __m.data;
!       _Tp* __restrict__ __q = __dst.data;
!       for (size_t __i = 0; __i < __n; ++__i, ++__ok, ++__p)
! 	{
! 	  for (; !*__ok; ++__ok) // skip to next authorised source
!             ++__p;
! 	  __q[__i] = *__p;
  	}
      }
  
!   // Assign __n consecutive elements from __src[<>] to slots in __dst[{__m}].
!   // Slots of __dst are skipped if corresponding values of __m are false.
!   // __m must contain at least __n true elements.  __dst must have at least as
!   // many elements as the index of the __nth true element of __m.  E.g., if
!   // __m has 15 elements with 5 false followed by 10 true, __dst must have
    // at least 15 elements.
    template<typename _Tp>
      void
!     __valarray_assign(_Array<_Tp> __src, size_t __n, _Array<_Tp> __dst,
!                       _Array<bool> __m)
      {
!       const _Tp* __restrict__ __p = __src.data;
!       _Tp* __restrict__ __q = __dst.data;
!       const bool* __restrict__ __ok = __m.data;
!       for (size_t __i = 0; __i < __n; ++__i, ++__ok, ++__q)
! 	{
! 	  for (; !*__ok; ++__ok) // skip to next authorized sink
!             ++__q;
! 	  *__q = __p[__i];
  	}
      }
  
!   // Assign __n values from __src[{__m}] to slots in __dst[{__k}].
!   // Slots of __src are skipped if corresponding values of __m are false.
!   // Similarly, slots of __dst are skipped if corresponding values of __k
!   // are false.  __m and __k must contain at least __n true elements.
!   // __src and __dst must have at least as many slots as the index of
!   // the __nth true element of __m.
    template<typename _Tp>
      void
!     __valarray_assign(_Array<_Tp> __src, _Array<bool> __m, size_t __n,
!                       _Array<_Tp> __dst, _Array<bool> __k)
      {
!       const _Tp* __restrict__ __p = __src.data;
!       _Tp* __restrict__ __q = __dst.data;
!       const bool* __restrict__ __srcok = __m.data;
!       const bool* __restrict__ __dstok = __k.data;
        for (size_t __i = 0; __i < __n;
  	   ++__srcok, ++__p, ++__dstok, ++__q, ++__i)
  	{
! 	  for (; !*__srcok; ++__srcok) // skip to next authorized source
!             ++__p;
! 	  for (; !*__dstok; ++__dstok) // match up with authorized sink
!             ++__q;
  	  *__q = *__p;
  	}
      }
  
!   // Assign __n consecutive elements of __src to consecutive slots of __dst.
!   // I.e. __dst[i] = __src[i].
    template<typename _Tp, class _Dom>
      void
!     __valarray_assign(const _Expr<_Dom, _Tp>& __src, size_t __n,
!                       _Array<_Tp> __dst)
      {
!       _Tp* __restrict__ __p = __dst.data;
        for (size_t __i = 0; __i < __n; ++__i, ++__p)
! 	*__p = __src[__i];
      }
  
!   // Assign __n consecutive elements of src to slots of __dst using stride
!   // __s.  E.g., __dst[0] = __src[0], __dst[s] = __src[1],
!   //             __dst[2*s] = __src[2], etc.
    template<typename _Tp, class _Dom>
      void
!     __valarray_assign(const _Expr<_Dom, _Tp>& __src, size_t __n,
!                       _Array<_Tp> __dst, size_t __s)
      {
!       _Tp* __restrict__ __p = __dst.data;
        for (size_t __i = 0; __i < __n; ++__i, __p += __s)
! 	*__p = __src[__i];
      }
  
!   // Assign __n consecutive elements of __src to slots in __dst indexed by
!   // contents of __idx.  E.g., __dst[__idx[0]] = __src[0],
!   //                           __dst[__idx[1]] = __src[1], etc.
    template<typename _Tp, class _Dom>
      void
!     __valarray_assign(const _Expr<_Dom, _Tp>& __src, size_t __n,
!                       _Array<_Tp> __dst, _Index __idx)
      {
!       const size_t* __restrict__ __i = __idx.data;
!       for (size_t __j = 0; __j < __n; ++__j)
! 	__dst.data[__i[__j]] = __src[__j];
      }
  
!   // Assign __n elements of __src indexed by contents of __msk into slots
!   // of __dst indexed by contents of __nsk.  E.g.,
!   //                  __dst[__msk[0]] = __src[__nsk[0]], etc.
!   template<typename _Tp, class _Dom>
      void
!     __valarray_assign(const _Expr<_Dom, _Tp> __src, size_t __n, _Index __msk, 
!                       _Array<_Tp> __dst, _Index __nsk)
!     {
!       _Tp* __restrict__ __q = __dst.data;
!       const size_t* __restrict__ __i = __msk.data;
!       const size_t* __restrict__ __j = __nsk.data;
!       for (size_t __k = 0; __k < __n; ++__k)
! 	__q[__j[__k]] = __src[__i[__k]];
!     }
! 
!   // Assign __n consecutive elements of __src[<>] to slots of __dst[{}__msk].
!   // Slots of __dst are skipped if the corresponding element of __msk is false.
!   // __msk must have at least __n true elements and __src must have at least
!   // as many elements as the index of the __nth true element of msk.
!   // E.g. if __msk has 5 false followed by 10 true elements and __n == 10,
!   // __src must have at least 15 elements.
    template<typename _Tp, class _Dom>
      void
!     __valarray_assign(const _Expr<_Dom, _Tp>& __src, size_t __n,
!                       _Array<_Tp> __dst, _Array<bool> __msk)
      {
!       const bool* __restrict__ __ok = __msk.data;
!       _Tp* __restrict__ __p = __dst.data;
        for (size_t __i = 0; __i < __n; ++__i, ++__ok, ++__p)
  	{
! 	  for (; !*__ok; ++__ok)
!             ++__p;
! 	  *__p = __src[__i];
  	}
      }
  
  
    template<typename _Tp, class _Dom>
      void
!     __valarray_copy_construct(const _Expr<_Dom, _Tp>& __src, size_t __n,
! 			      _Array<_Tp> __dst)
      {
!       _Tp* __restrict__ __p = __dst.data;
        for (size_t __i = 0; __i < __n; ++__i, ++__p)
! 	new (__p) _Tp(__src[__i]);
      }
  
  
    template<typename _Tp>
      void
!     __valarray_copy_construct(_Array<_Tp> __src, _Array<bool> __msk,
! 			      _Array<_Tp> __dst, size_t __n)
      {
!       const _Tp* __restrict__ __p = __src.data;
!       const bool* __restrict__ __ok = __msk.data;
!       _Tp* __restrict__ __q = __dst.data;
!       for (size_t __i = 0; __i < __n; ++__i, ++__ok, ++__p)
! 	{
! 	  for (; !*__ok; ++__ok)
!             ++__p;
! 	  new (__q + __i) _Tp(*__p);
  	}
      }
  } // namespace std
*** std/std_valarray.h	(revision 108262)
--- std/std_valarray.h	(local)
***************
*** 1,6 ****
  // The template and inlines for the -*- C++ -*- valarray class.
  
! // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004
  // Free Software Foundation, Inc.
  //
  // This file is part of the GNU ISO C++ Library.  This library is free
--- 1,6 ----
  // The template and inlines for the -*- C++ -*- valarray class.
  
! // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005
  // Free Software Foundation, Inc.
  //
  // This file is part of the GNU ISO C++ Library.  This library is free
***************
*** 44,50 ****
  #include <cmath>
  #include <cstdlib>
  #include <numeric>
- #include <algorithm>
  #include <debug/debug.h>
  
  namespace std
--- 44,49 ----
*************** namespace std
*** 512,523 ****
         */
        void resize(size_t __size, _Tp __c = _Tp());
  
      private:
        size_t _M_size;
!       _Tp* __restrict__ _M_data;
!       
!       friend class _Array<_Tp>;
      };
    
    template<typename _Tp>
      inline const _Tp&
--- 511,529 ----
         */
        void resize(size_t __size, _Tp __c = _Tp());
  
+       // Return handle on the internal data held by this valarray.
+       // This removes dependency on friendships and allows for easier
+       // extensions.
+       _Array<_Tp> __values() const;
+ 
      private:
        size_t _M_size;
!       _Array<_Tp> _M_data;
      };
+ 
+   template<typename _Tp>
+     inline _Array<_Tp>
+     valarray<_Tp>::__values() const { return _M_data; }
    
    template<typename _Tp>
      inline const _Tp&
*************** namespace std
*** 549,634 ****
  {
    template<typename _Tp>
      inline
!     valarray<_Tp>::valarray() : _M_size(0), _M_data(0) {}
  
    template<typename _Tp>
      inline 
      valarray<_Tp>::valarray(size_t __n) 
!     : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
!     { std::__valarray_default_construct(_M_data, _M_data + __n); }
  
    template<typename _Tp>
      inline
      valarray<_Tp>::valarray(const _Tp& __t, size_t __n)
!     : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
!     { std::__valarray_fill_construct(_M_data, _M_data + __n, __t); }
  
    template<typename _Tp>
      inline
      valarray<_Tp>::valarray(const _Tp* __restrict__ __p, size_t __n)
!     : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
      { 
        _GLIBCXX_DEBUG_ASSERT(__p != 0 || __n == 0);
!       std::__valarray_copy_construct(__p, __p + __n, _M_data); 
      }
  
    template<typename _Tp>
      inline
      valarray<_Tp>::valarray(const valarray<_Tp>& __v)
!     : _M_size(__v._M_size), _M_data(__valarray_get_storage<_Tp>(__v._M_size))
!     { std::__valarray_copy_construct(__v._M_data, __v._M_data + _M_size,
! 				     _M_data); }
  
    template<typename _Tp>
      inline
      valarray<_Tp>::valarray(const slice_array<_Tp>& __sa)
!     : _M_size(__sa._M_sz), _M_data(__valarray_get_storage<_Tp>(__sa._M_sz))
      {
!       std::__valarray_copy
! 	(__sa._M_array, __sa._M_sz, __sa._M_stride, _Array<_Tp>(_M_data));
      }
  
    template<typename _Tp>
      inline
      valarray<_Tp>::valarray(const gslice_array<_Tp>& __ga)
      : _M_size(__ga._M_index.size()),
!       _M_data(__valarray_get_storage<_Tp>(_M_size))
      {
!       std::__valarray_copy
! 	(__ga._M_array, _Array<size_t>(__ga._M_index),
! 	 _Array<_Tp>(_M_data), _M_size);
      }
  
    template<typename _Tp>
      inline
      valarray<_Tp>::valarray(const mask_array<_Tp>& __ma)
!     : _M_size(__ma._M_sz), _M_data(__valarray_get_storage<_Tp>(__ma._M_sz))
      {
!       std::__valarray_copy
! 	(__ma._M_array, __ma._M_mask, _Array<_Tp>(_M_data), _M_size);
      }
  
    template<typename _Tp>
      inline
      valarray<_Tp>::valarray(const indirect_array<_Tp>& __ia)
!     : _M_size(__ia._M_sz), _M_data(__valarray_get_storage<_Tp>(__ia._M_sz))
      {
!       std::__valarray_copy
! 	(__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size);
      }
  
    template<typename _Tp> template<class _Dom>
      inline
      valarray<_Tp>::valarray(const _Expr<_Dom, _Tp>& __e)
!     : _M_size(__e.size()), _M_data(__valarray_get_storage<_Tp>(_M_size))
!     { std::__valarray_copy(__e, _M_size, _Array<_Tp>(_M_data)); }
  
    template<typename _Tp>
      inline
      valarray<_Tp>::~valarray()
      {
!       std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
!       std::__valarray_release_memory(_M_data);
      }
  
    template<typename _Tp>
--- 555,638 ----
  {
    template<typename _Tp>
      inline
!     valarray<_Tp>::valarray() : _M_size(0), _M_data() {}
  
    template<typename _Tp>
      inline 
      valarray<_Tp>::valarray(size_t __n) 
!     : _M_size(__n), _M_data(__valarray_allocate<_Tp>(__n))
!     { std::__valarray_default_construct(_M_data.data, __n); }
  
    template<typename _Tp>
      inline
      valarray<_Tp>::valarray(const _Tp& __t, size_t __n)
!     : _M_size(__n), _M_data(__valarray_allocate<_Tp>(__n))
!     { std::__valarray_fill(_M_data, __n, __t); }
  
    template<typename _Tp>
      inline
      valarray<_Tp>::valarray(const _Tp* __restrict__ __p, size_t __n)
!     : _M_size(__n), _M_data(__valarray_allocate<_Tp>(__n))
      { 
        _GLIBCXX_DEBUG_ASSERT(__p != 0 || __n == 0);
!       std::__valarray_copy_construct(_Array<_Tp>(__p), __n, _M_data); 
      }
  
    template<typename _Tp>
      inline
      valarray<_Tp>::valarray(const valarray<_Tp>& __v)
!     : _M_size(__v._M_size), _M_data(__valarray_allocate<_Tp>(__v._M_size))
!     { std::__valarray_copy_construct(__v._M_data, _M_size, _M_data); }
  
    template<typename _Tp>
      inline
      valarray<_Tp>::valarray(const slice_array<_Tp>& __sa)
!     : _M_size(__sa._M_sz), _M_data(__valarray_allocate<_Tp>(__sa._M_sz))
      {
!       std::__valarray_copy_construct
! 	(__sa._M_array, __sa._M_sz, __sa._M_stride, _M_data);
      }
  
    template<typename _Tp>
      inline
      valarray<_Tp>::valarray(const gslice_array<_Tp>& __ga)
      : _M_size(__ga._M_index.size()),
!       _M_data(__valarray_allocate<_Tp>(_M_size))
      {
!       std::__valarray_copy_construct
! 	(__ga._M_array, __ga._M_index.__values(), _M_data, _M_size);
      }
  
    template<typename _Tp>
      inline
      valarray<_Tp>::valarray(const mask_array<_Tp>& __ma)
!     : _M_size(__ma._M_sz), _M_data(__valarray_allocate<_Tp>(__ma._M_sz))
      {
!       std::__valarray_copy_construct
! 	(__ma._M_array, __ma._M_mask, _M_data, _M_size);
      }
  
    template<typename _Tp>
      inline
      valarray<_Tp>::valarray(const indirect_array<_Tp>& __ia)
!     : _M_size(__ia._M_sz), _M_data(__valarray_allocate<_Tp>(__ia._M_sz))
      {
!       std::__valarray_copy_construct
! 	(__ia._M_array, __ia._M_index, _M_data, _M_size);
      }
  
    template<typename _Tp> template<class _Dom>
      inline
      valarray<_Tp>::valarray(const _Expr<_Dom, _Tp>& __e)
!     : _M_size(__e.size()), _M_data(__valarray_allocate<_Tp>(_M_size))
!     { std::__valarray_copy_construct(__e, _M_size, _M_data); }
  
    template<typename _Tp>
      inline
      valarray<_Tp>::~valarray()
      {
!       std::__valarray_destroy_elements(_M_data, _M_size);
!       std::__valarray_deallocate(_M_data);
      }
  
    template<typename _Tp>
*************** namespace std
*** 636,642 ****
      valarray<_Tp>::operator=(const valarray<_Tp>& __v)
      {
        _GLIBCXX_DEBUG_ASSERT(_M_size == __v._M_size);
!       std::__valarray_copy(__v._M_data, _M_size, _M_data);
        return *this;
      }
  
--- 640,646 ----
      valarray<_Tp>::operator=(const valarray<_Tp>& __v)
      {
        _GLIBCXX_DEBUG_ASSERT(_M_size == __v._M_size);
!       std::__valarray_assign(__v._M_data, _M_size, _M_data);
        return *this;
      }
  
*************** namespace std
*** 644,650 ****
      inline valarray<_Tp>&
      valarray<_Tp>::operator=(const _Tp& __t)
      {
!       std::__valarray_fill(_M_data, _M_size, __t);
        return *this;
      }
  
--- 648,654 ----
      inline valarray<_Tp>&
      valarray<_Tp>::operator=(const _Tp& __t)
      {
!       std::__valarray_assign(_M_data, _M_size, __t);
        return *this;
      }
  
*************** namespace std
*** 653,660 ****
      valarray<_Tp>::operator=(const slice_array<_Tp>& __sa)
      {
        _GLIBCXX_DEBUG_ASSERT(_M_size == __sa._M_sz);
!       std::__valarray_copy(__sa._M_array, __sa._M_sz,
! 			   __sa._M_stride, _Array<_Tp>(_M_data));
        return *this;
      }
  
--- 657,664 ----
      valarray<_Tp>::operator=(const slice_array<_Tp>& __sa)
      {
        _GLIBCXX_DEBUG_ASSERT(_M_size == __sa._M_sz);
!       std::__valarray_assign(__sa._M_array, __sa._M_sz,
! 			   __sa._M_stride, _M_data);
        return *this;
      }
  
*************** namespace std
*** 663,670 ****
      valarray<_Tp>::operator=(const gslice_array<_Tp>& __ga)
      {
        _GLIBCXX_DEBUG_ASSERT(_M_size == __ga._M_index.size());
!       std::__valarray_copy(__ga._M_array, _Array<size_t>(__ga._M_index),
! 			   _Array<_Tp>(_M_data), _M_size);
        return *this;
      }
  
--- 667,674 ----
      valarray<_Tp>::operator=(const gslice_array<_Tp>& __ga)
      {
        _GLIBCXX_DEBUG_ASSERT(_M_size == __ga._M_index.size());
!       std::__valarray_assign(__ga._M_array, __ga._M_index.__values(),
! 			   _M_data, _M_size);
        return *this;
      }
  
*************** namespace std
*** 673,680 ****
      valarray<_Tp>::operator=(const mask_array<_Tp>& __ma)
      {
        _GLIBCXX_DEBUG_ASSERT(_M_size == __ma._M_sz);
!       std::__valarray_copy(__ma._M_array, __ma._M_mask,
! 			   _Array<_Tp>(_M_data), _M_size);
        return *this;
      }
  
--- 677,683 ----
      valarray<_Tp>::operator=(const mask_array<_Tp>& __ma)
      {
        _GLIBCXX_DEBUG_ASSERT(_M_size == __ma._M_sz);
!       std::__valarray_assign(__ma._M_array, __ma._M_mask, _M_data, _M_size);
        return *this;
      }
  
*************** namespace std
*** 683,690 ****
      valarray<_Tp>::operator=(const indirect_array<_Tp>& __ia)
      {
        _GLIBCXX_DEBUG_ASSERT(_M_size == __ia._M_sz);
!       std::__valarray_copy(__ia._M_array, __ia._M_index,
! 			   _Array<_Tp>(_M_data), _M_size);
        return *this;
      }
  
--- 686,692 ----
      valarray<_Tp>::operator=(const indirect_array<_Tp>& __ia)
      {
        _GLIBCXX_DEBUG_ASSERT(_M_size == __ia._M_sz);
!       std::__valarray_assign(__ia._M_array, __ia._M_index, _M_data, _M_size);
        return *this;
      }
  
*************** namespace std
*** 693,699 ****
      valarray<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e)
      {
        _GLIBCXX_DEBUG_ASSERT(_M_size == __e.size());
!       std::__valarray_copy(__e, _M_size, _Array<_Tp>(_M_data));
        return *this;
      }
  
--- 695,701 ----
      valarray<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e)
      {
        _GLIBCXX_DEBUG_ASSERT(_M_size == __e.size());
!       std::__valarray_assign(__e, _M_size, _M_data);
        return *this;
      }
  
*************** namespace std
*** 702,714 ****
      valarray<_Tp>::operator[](slice __s) const
      {
        typedef _SClos<_ValArray,_Tp> _Closure;
!       return _Expr<_Closure, _Tp>(_Closure (_Array<_Tp>(_M_data), __s));
      }
  
    template<typename _Tp>
      inline slice_array<_Tp>
      valarray<_Tp>::operator[](slice __s)
!     { return slice_array<_Tp>(_Array<_Tp>(_M_data), __s); }
  
    template<typename _Tp>
      inline _Expr<_GClos<_ValArray,_Tp>, _Tp>
--- 704,716 ----
      valarray<_Tp>::operator[](slice __s) const
      {
        typedef _SClos<_ValArray,_Tp> _Closure;
!       return _Expr<_Closure, _Tp>(_Closure(_M_data, __s));
      }
  
    template<typename _Tp>
      inline slice_array<_Tp>
      valarray<_Tp>::operator[](slice __s)
!     { return slice_array<_Tp>(_M_data, __s); }
  
    template<typename _Tp>
      inline _Expr<_GClos<_ValArray,_Tp>, _Tp>
*************** namespace std
*** 716,730 ****
      {
        typedef _GClos<_ValArray,_Tp> _Closure;
        return _Expr<_Closure, _Tp>
! 	(_Closure(_Array<_Tp>(_M_data), __gs._M_index->_M_index));
      }
  
    template<typename _Tp>
      inline gslice_array<_Tp>
      valarray<_Tp>::operator[](const gslice& __gs)
      {
!       return gslice_array<_Tp>
! 	(_Array<_Tp>(_M_data), __gs._M_index->_M_index);
      }
  
    template<typename _Tp>
--- 718,731 ----
      {
        typedef _GClos<_ValArray,_Tp> _Closure;
        return _Expr<_Closure, _Tp>
! 	(_Closure(_M_data, __gs._M_index->_M_index));
      }
  
    template<typename _Tp>
      inline gslice_array<_Tp>
      valarray<_Tp>::operator[](const gslice& __gs)
      {
!       return gslice_array<_Tp>(_M_data, __gs._M_index->_M_index);
      }
  
    template<typename _Tp>
*************** namespace std
*** 735,742 ****
        size_t __e = __m.size();
        for (size_t __i=0; __i<__e; ++__i)
  	if (__m[__i]) ++__s;
!       return valarray<_Tp>(mask_array<_Tp>(_Array<_Tp>(_M_data), __s,
! 					   _Array<bool> (__m)));
      }
  
    template<typename _Tp>
--- 736,742 ----
        size_t __e = __m.size();
        for (size_t __i=0; __i<__e; ++__i)
  	if (__m[__i]) ++__s;
!       return valarray<_Tp>(mask_array<_Tp>(_M_data, __s, __m.__values()));
      }
  
    template<typename _Tp>
*************** namespace std
*** 747,753 ****
        size_t __e = __m.size();
        for (size_t __i=0; __i<__e; ++__i)
  	if (__m[__i]) ++__s;
!       return mask_array<_Tp>(_Array<_Tp>(_M_data), __s, _Array<bool>(__m));
      }
  
    template<typename _Tp>
--- 747,753 ----
        size_t __e = __m.size();
        for (size_t __i=0; __i<__e; ++__i)
  	if (__m[__i]) ++__s;
!       return mask_array<_Tp>(_M_data, __s, __m.__values());
      }
  
    template<typename _Tp>
*************** namespace std
*** 762,769 ****
      inline indirect_array<_Tp>
      valarray<_Tp>::operator[](const valarray<size_t>& __i)
      {
!       return indirect_array<_Tp>(_Array<_Tp>(_M_data), __i.size(),
! 				 _Array<size_t>(__i));
      }
  
    template<class _Tp>
--- 762,768 ----
      inline indirect_array<_Tp>
      valarray<_Tp>::operator[](const valarray<size_t>& __i)
      {
!       return indirect_array<_Tp>(_M_data, __i.size(), __i.__values());
      }
  
    template<class _Tp>
*************** namespace std
*** 776,782 ****
      valarray<_Tp>::sum() const
      {
        _GLIBCXX_DEBUG_ASSERT(_M_size > 0);
!       return std::__valarray_sum(_M_data, _M_data + _M_size);
      }
  
    template <class _Tp>
--- 775,781 ----
      valarray<_Tp>::sum() const
      {
        _GLIBCXX_DEBUG_ASSERT(_M_size > 0);
!       return std::__valarray_sum(*this);
      }
  
    template <class _Tp>
*************** namespace std
*** 790,796 ****
         else if (__n > 0)         // __n > 0: shift left
           {                 
             if (size_t(__n) > _M_size)
!              std::__valarray_default_construct(__a, __a + __n);
             else
               {
                 std::__valarray_copy_construct(_M_data + __n,
--- 789,795 ----
         else if (__n > 0)         // __n > 0: shift left
           {                 
             if (size_t(__n) > _M_size)
!              std::__valarray_default_construct(_Array<_Tp>(__a), __n);
             else
               {
                 std::__valarray_copy_construct(_M_data + __n,
*************** namespace std
*** 843,853 ****
        std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
        if (_M_size != __n)
  	{
! 	  std::__valarray_release_memory(_M_data);
  	  _M_size = __n;
! 	  _M_data = __valarray_get_storage<_Tp>(__n);
  	}
!       std::__valarray_fill_construct(_M_data, _M_data + __n, __c);
      }
      
    template<typename _Tp>
--- 842,852 ----
        std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
        if (_M_size != __n)
  	{
! 	  std::__valarray_deallocate(_M_data);
  	  _M_size = __n;
! 	  _M_data = std::__valarray_allocate<_Tp>(__n);
  	}
!       std::__valarray_fill(_M_data, __n, __c);
      }
      
    template<typename _Tp>
*************** namespace std
*** 855,861 ****
      valarray<_Tp>::min() const
      {
        _GLIBCXX_DEBUG_ASSERT(_M_size > 0);
!       return *std::min_element(_M_data, _M_data+_M_size);
      }
  
    template<typename _Tp>
--- 854,860 ----
      valarray<_Tp>::min() const
      {
        _GLIBCXX_DEBUG_ASSERT(_M_size > 0);
!       return __valarray_min(*this);
      }
  
    template<typename _Tp>
*************** namespace std
*** 863,869 ****
      valarray<_Tp>::max() const
      {
        _GLIBCXX_DEBUG_ASSERT(_M_size > 0);
!       return *std::max_element(_M_data, _M_data+_M_size);
      }
    
    template<class _Tp>
--- 862,868 ----
      valarray<_Tp>::max() const
      {
        _GLIBCXX_DEBUG_ASSERT(_M_size > 0);
!       return __valarray_max(*this);
      }
    
    template<class _Tp>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]