Professional Documents
Culture Documents
#define _VALARRAY_ARRAY_H 1
#include <bits/c++config.h>
#include <bits/cpp_type_traits.h>
#include <cstdlib>
#include <cstring>
#include <new>
namespace std
{
//
// Helper functions on raw pointers
//
template<typename _Tp>
inline _Tp*__restrict__
__valarray_get_storage(size_t __n)
{
return static_cast<_Tp*__restrict__>
(std::__valarray_get_memory(__n * sizeof(_Tp)));
}
template<typename _Tp>
struct _Array_default_ctor<_Tp, true>
{
// 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>::_M_type>::
_S_do_it(__b, __e);
}
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>::_M_type>::
_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>::_M_type>::
_S_do_it(__b, __e, __o);
}
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)); }
};
//
// 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;
}
template<typename _Ta>
inline typename _Ta::value_type
__valarray_max(const _Ta& __a)
{
size_t __s = __a.size();
typedef typename _Ta::value_type _Value_type;
_Value_type __r = __s == 0 ? _Value_type() : __a[0];
for (size_t __i = 1; __i < __s; ++__i)
{
_Value_type __t = __a[__i];
if (__t > __r)
__r = __t;
}
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);
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); }
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_ARRAY_FUNCTION(+, __plus)
_DEFINE_ARRAY_FUNCTION(-, __minus)
_DEFINE_ARRAY_FUNCTION(*, __multiplies)
_DEFINE_ARRAY_FUNCTION(/, __divides)
_DEFINE_ARRAY_FUNCTION(%, __modulus)
_DEFINE_ARRAY_FUNCTION(^, __bitwise_xor)
_DEFINE_ARRAY_FUNCTION(|, __bitwise_or)
_DEFINE_ARRAY_FUNCTION(&, __bitwise_and)
_DEFINE_ARRAY_FUNCTION(<<, __shift_left)
_DEFINE_ARRAY_FUNCTION(>>, __shift_right)
#undef _DEFINE_VALARRAY_FUNCTION
} // namespace std
#ifndef _GLIBCXX_EXPORT_TEMPLATE
# include <bits/valarray_array.tcc>
#endif
#endif /* _ARRAY_H */