This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
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>