valarray_array.h (__valarray_get_memory, [...]): New functions.
2000-07-15 Gabriel Dos Reis <gdr@codesourcery.com> * std/valarray_array.h (__valarray_get_memory, __valarray_get_storage, __valarray_release_storage): New functions. (_Array_default_ctor, _Array_init_ctor, _Array_copy_ctor, _Array_copier): New traits classes. (__valarray_default_construct): New function. Implements valarray default construction. (__valarray_fill_construct): New function. Implements valarray construction with initializer. (__valarray_copy_construct): New function. Implements valarray copy construction. (__valarray_destroy_elements): New function. (__valarray_copy, __valarray_fill): Tweak. (__valarray_sum, __valarray_product): New helper functions. (_Array<>::free_data): Remove. (_Array<>::_Array): Tweak. * std/std_valarray.h (valarray<>::product): Remove. (valarray<>::valarray): Use __valarray_get_storage. (valarray<>::shift, valarray<>::cshift, valarray<>::resize): Tweak. * std/cpp_type_traits.h: New file. * valarray.cc (multiplies<>, accumulate, valarray<>::product): Remove explicit instantiation. (__valarray_product): New function. (_Indexer::_Indexer): Use. From-SVN: r35055
This commit is contained in:
parent
557b9df529
commit
5b2ff385d5
@ -1,3 +1,34 @@
|
||||
2000-07-15 Gabriel Dos Reis <gdr@codesourcery.com>
|
||||
|
||||
* std/valarray_array.h (__valarray_get_memory,
|
||||
__valarray_get_storage, __valarray_release_storage): New
|
||||
functions.
|
||||
(_Array_default_ctor, _Array_init_ctor, _Array_copy_ctor,
|
||||
_Array_copier): New traits classes.
|
||||
(__valarray_default_construct): New function. Implements valarray
|
||||
default construction.
|
||||
(__valarray_fill_construct): New function. Implements valarray
|
||||
construction with initializer.
|
||||
(__valarray_copy_construct): New function. Implements valarray
|
||||
copy construction.
|
||||
(__valarray_destroy_elements): New function.
|
||||
(__valarray_copy, __valarray_fill): Tweak.
|
||||
(__valarray_sum, __valarray_product): New helper functions.
|
||||
(_Array<>::free_data): Remove.
|
||||
(_Array<>::_Array): Tweak.
|
||||
|
||||
* std/std_valarray.h (valarray<>::product): Remove.
|
||||
(valarray<>::valarray): Use __valarray_get_storage.
|
||||
(valarray<>::shift, valarray<>::cshift, valarray<>::resize):
|
||||
Tweak.
|
||||
|
||||
* std/cpp_type_traits.h: New file.
|
||||
|
||||
* valarray.cc (multiplies<>, accumulate, valarray<>::product):
|
||||
Remove explicit instantiation.
|
||||
(__valarray_product): New function.
|
||||
(_Indexer::_Indexer): Use.
|
||||
|
||||
2000-07-14 Jean-Francois Panisset <panisset@discreet.com>
|
||||
|
||||
* std/bastring.h (basic_string<>::clear): Add function.
|
||||
|
299
libstdc++/std/cpp_type_traits.h
Normal file
299
libstdc++/std/cpp_type_traits.h
Normal file
@ -0,0 +1,299 @@
|
||||
// The -*- C++ -*- type traits classes for internal use in libstdc++
|
||||
|
||||
// Copyright (C) 2000 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 2, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING. If not, write to the Free
|
||||
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
// USA.
|
||||
|
||||
// As a special exception, you may use this file as part of a free software
|
||||
// library without restriction. Specifically, if other files instantiate
|
||||
// templates or use macros or inline functions from this file, or you compile
|
||||
// this file and link it with other files to produce an executable, this
|
||||
// file does not by itself cause the resulting executable to be covered by
|
||||
// the GNU General Public License. This exception does not however
|
||||
// invalidate any other reasons why the executable file might be covered by
|
||||
// the GNU General Public License.
|
||||
|
||||
// Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
|
||||
|
||||
#ifndef _CPP_BITS_CPP_TYPE_TRAITS_H
|
||||
#define _CPP_BITS_CPP_TYPE_TRAITS_H 1
|
||||
|
||||
//
|
||||
// This file provides some compile-time information about various types.
|
||||
// These informations were designed, on purpose, to be constant-expressions
|
||||
// and not types as found in <stl/bits/type_traits.h>. In particular, they
|
||||
// can be used in control structures and the optimizer, hopefully, will do
|
||||
// the obvious thing.
|
||||
//
|
||||
// Why integral expressions, and not functions nor types?
|
||||
// Firstly, these compile-time information entities are used as
|
||||
// template-arguments so function return values won't work. We
|
||||
// need compile-time entities. We're left with types and iintegral constant
|
||||
// expressions.
|
||||
// Secondly, from the point of view of ease of use, type-based compile-time
|
||||
// information is -not- *that* convenient. One has to write lots of
|
||||
// overloaded functions and to hope that the compiler will select the right
|
||||
// one. As a net effect, the overall structure isn't very clear at first
|
||||
// glance.
|
||||
// Thirdly, partial ordering and overload resolution (of template functions)
|
||||
// is very costly in terms of compiler-resource. It is a Good Thing to
|
||||
// keep these resource consumption as least as possible. Please, direct
|
||||
// any comment to <dosreis@cmla.ens-cachan.fr>.
|
||||
//
|
||||
// -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06.
|
||||
//
|
||||
|
||||
extern "C++" {
|
||||
template<typename _Tp>
|
||||
struct __is_void
|
||||
{
|
||||
enum
|
||||
{
|
||||
_M_type = 0
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct __is_void<void>
|
||||
{
|
||||
enum
|
||||
{
|
||||
_M_type = 1
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
// Integer types
|
||||
//
|
||||
template<typename _Tp>
|
||||
struct __is_integer
|
||||
{
|
||||
enum
|
||||
{
|
||||
_M_type = 0
|
||||
};
|
||||
};
|
||||
|
||||
// Thirteen specializations (yes there are eleven standard integer
|
||||
// types; 'long long' and 'unsigned long long' are supported as
|
||||
// extensions)
|
||||
template<>
|
||||
struct __is_integer<bool>
|
||||
{
|
||||
enum
|
||||
{
|
||||
_M_type = 1
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct __is_integer<char>
|
||||
{
|
||||
enum
|
||||
{
|
||||
_M_type = 1
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct __is_integer<signed char>
|
||||
{
|
||||
enum
|
||||
{
|
||||
_M_type = 1
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct __is_integer<unsigned char>
|
||||
{
|
||||
enum
|
||||
{
|
||||
_M_type = 1
|
||||
};
|
||||
};
|
||||
|
||||
# if 0
|
||||
template<>
|
||||
struct __is_integer<wchar_t>
|
||||
{
|
||||
enum
|
||||
{
|
||||
_M_type = 1
|
||||
};
|
||||
};
|
||||
# endif
|
||||
|
||||
template<>
|
||||
struct __is_integer<short>
|
||||
{
|
||||
enum
|
||||
{
|
||||
_M_type = 1
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct __is_integer<unsigned short>
|
||||
{
|
||||
enum
|
||||
{
|
||||
_M_type = 1
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct __is_integer<int>
|
||||
{
|
||||
enum
|
||||
{
|
||||
_M_type = 1
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct __is_integer<unsigned int>
|
||||
{
|
||||
enum
|
||||
{
|
||||
_M_type = 1
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct __is_integer<long>
|
||||
{
|
||||
enum
|
||||
{
|
||||
_M_type = 1
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct __is_integer<unsigned long>
|
||||
{
|
||||
enum
|
||||
{
|
||||
_M_type = 1
|
||||
};
|
||||
};
|
||||
|
||||
# if 0
|
||||
template<>
|
||||
struct __is_integer<long long>
|
||||
{
|
||||
enum
|
||||
{
|
||||
_M_type = 1
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct __is_integer<unsigned long long>
|
||||
{
|
||||
enum
|
||||
{
|
||||
_M_type = 1
|
||||
};
|
||||
};
|
||||
# endif
|
||||
|
||||
//
|
||||
// Floating point types
|
||||
//
|
||||
template<typename _Tp>
|
||||
struct __is_floating
|
||||
{
|
||||
enum
|
||||
{
|
||||
_M_type = 0
|
||||
};
|
||||
};
|
||||
|
||||
// three specializations (float, double and 'long double')
|
||||
template<>
|
||||
struct __is_floating<float>
|
||||
{
|
||||
enum
|
||||
{
|
||||
_M_type = 1
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct __is_floating<double>
|
||||
{
|
||||
enum
|
||||
{
|
||||
_M_type = 1
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct __is_floating<long double>
|
||||
{
|
||||
enum
|
||||
{
|
||||
_M_type = 1
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
// An arithmetic type is an integer type or a floating point type
|
||||
//
|
||||
template<typename _Tp>
|
||||
struct __is_arithmetic
|
||||
{
|
||||
enum
|
||||
{
|
||||
_M_type = __is_integer<_Tp>::_M_type || __is_floating<_Tp>::_M_type
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
// A fundamental type is `void' or and arithmetic type
|
||||
//
|
||||
template<typename _Tp>
|
||||
struct __is_fundamental
|
||||
{
|
||||
enum
|
||||
{
|
||||
_M_type = __is_void<_Tp>::_M_type || __is_arithmetic<_Tp>::_M_type
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
// For the immediate use, the following is a good approximation
|
||||
//
|
||||
template<typename _Tp>
|
||||
struct __is_pod
|
||||
{
|
||||
enum
|
||||
{
|
||||
_M_type = __is_fundamental<_Tp>::_M_type
|
||||
};
|
||||
};
|
||||
} // extern "C++"
|
||||
|
||||
#endif //_CPP_BITS_CPP_TYPE_TRAITS_H
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -212,10 +212,7 @@ public:
|
||||
_Tp sum() const;
|
||||
_Tp min() const;
|
||||
_Tp max() const;
|
||||
|
||||
// FIXME: Extension
|
||||
_Tp product () const;
|
||||
|
||||
|
||||
valarray<_Tp> shift (int) const;
|
||||
valarray<_Tp> cshift(int) const;
|
||||
_Expr<_ValFunClos<_ValArray,_Tp>,_Tp> apply(_Tp func(_Tp)) const;
|
||||
@ -285,54 +282,69 @@ 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 (new _Tp[__n]) {}
|
||||
: _M_size (__n), _M_data(__valarray_get_storage<_Tp>(__n))
|
||||
{ __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 (new _Tp[__n])
|
||||
{ __valarray_fill (_M_data, _M_size, __t); }
|
||||
: _M_size (__n), _M_data(__valarray_get_storage<_Tp>(__n))
|
||||
{ __valarray_fill_construct(_M_data, _M_data + __n, __t); }
|
||||
|
||||
template<typename _Tp>
|
||||
inline valarray<_Tp>::valarray (const _Tp* __restrict__ __pT, size_t __n)
|
||||
: _M_size (__n), _M_data (new _Tp[__n])
|
||||
{ __valarray_copy (__pT, __n, _M_data); }
|
||||
: _M_size (__n), _M_data(__valarray_get_storage<_Tp>(__n))
|
||||
{ __valarray_copy_construct(__pT, __pT + __n, _M_data); }
|
||||
|
||||
template<typename _Tp>
|
||||
inline valarray<_Tp>::valarray (const valarray<_Tp>& __v)
|
||||
: _M_size (__v._M_size), _M_data (new _Tp[__v._M_size])
|
||||
{ __valarray_copy (__v._M_data, _M_size, _M_data); }
|
||||
: _M_size (__v._M_size), _M_data(__valarray_get_storage<_Tp>(__v._M_size))
|
||||
{ __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 (new _Tp[__sa._M_sz])
|
||||
{ __valarray_copy (__sa._M_array, __sa._M_sz, __sa._M_stride,
|
||||
_Array<_Tp>(_M_data)); }
|
||||
: _M_size (__sa._M_sz), _M_data(__valarray_get_storage<_Tp>(__sa._M_sz))
|
||||
{
|
||||
__valarray_copy_construct
|
||||
(__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 (new _Tp[_M_size])
|
||||
{ __valarray_copy (__ga._M_array, _Array<size_t>(__ga._M_index),
|
||||
_Array<_Tp>(_M_data), _M_size); }
|
||||
: _M_size (__ga._M_index.size()),
|
||||
_M_data(__valarray_get_storage<_Tp>(_M_size))
|
||||
{
|
||||
__valarray_copy_construct
|
||||
(__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 (new _Tp[__ma._M_sz])
|
||||
{ __valarray_copy (__ma._M_array, __ma._M_mask,
|
||||
_Array<_Tp>(_M_data), _M_size); }
|
||||
: _M_size (__ma._M_sz), _M_data(__valarray_get_storage<_Tp>(__ma._M_sz))
|
||||
{
|
||||
__valarray_copy_construct
|
||||
(__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 (new _Tp[__ia._M_sz])
|
||||
{ __valarray_copy (__ia._M_array, __ia._M_index,
|
||||
_Array<_Tp>(_M_data), _M_size); }
|
||||
: _M_size (__ia._M_sz), _M_data(__valarray_get_storage<_Tp>(__ia._M_size))
|
||||
{
|
||||
__valarray_copy_construct
|
||||
(__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 (new _Tp[_M_size])
|
||||
{ __valarray_copy (__e, _M_size, _Array<_Tp>(_M_data)); }
|
||||
: _M_size (__e.size ()), _M_data (__valarray_get_storage<_Tp>(_M_size))
|
||||
{ __valarray_copy_construct (__e, _M_size, _Array<_Tp>(_M_data)); }
|
||||
|
||||
template<typename _Tp>
|
||||
inline valarray<_Tp>::~valarray () { delete[] _M_data; }
|
||||
inline valarray<_Tp>::~valarray ()
|
||||
{
|
||||
__valarray_destroy_elements(_M_data, _M_data + _M_size);
|
||||
__valarray_release_storage(_M_data);
|
||||
}
|
||||
|
||||
template<typename _Tp>
|
||||
inline valarray<_Tp>&
|
||||
@ -472,14 +484,7 @@ template<class _Tp>
|
||||
inline _Tp
|
||||
valarray<_Tp>::sum () const
|
||||
{
|
||||
return accumulate (_M_data, _M_data + _M_size, _Tp ());
|
||||
}
|
||||
|
||||
template<typename _Tp>
|
||||
inline _Tp
|
||||
valarray<_Tp>::product () const
|
||||
{
|
||||
return accumulate (_M_data, _M_data+_M_size, _Tp(1), multiplies<_Tp> ());
|
||||
return __valarray_sum(_M_data, _M_data + _M_size);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
@ -488,18 +493,18 @@ valarray<_Tp>::shift (int __n) const
|
||||
{
|
||||
_Tp* const __a = static_cast<_Tp*> (alloca (sizeof(_Tp) * _M_size));
|
||||
if (! __n) // __n == 0: no shift
|
||||
__valarray_copy (_M_data, _M_size, __a);
|
||||
__valarray_copy_construct (_M_data, _M_size, __a);
|
||||
else if (__n > 0) { // __n > 0: shift left
|
||||
if (__n > _M_size)
|
||||
__valarray_fill(__a, __n, _Tp());
|
||||
__valarray_default_construct(__a, __a + __n);
|
||||
else {
|
||||
__valarray_copy (_M_data+__n, _M_size-__n, __a);
|
||||
__valarray_fill (__a+_M_size-__n, __n, _Tp());
|
||||
__valarray_copy_construct (_M_data+__n, _M_size-__n, __a);
|
||||
__valarray_default_construct (__a+_M_size-__n, __a + _M_size);
|
||||
}
|
||||
}
|
||||
else { // __n < 0: shift right
|
||||
__valarray_copy (_M_data, _M_size+__n, __a-__n);
|
||||
__valarray_fill(__a, -__n, _Tp());
|
||||
__valarray_copy_construct (_M_data, _M_data+_M_size+__n, __a-__n);
|
||||
__valarray_default_construct(__a, __a-__n);
|
||||
}
|
||||
return valarray<_Tp> (__a, _M_size);
|
||||
}
|
||||
@ -509,15 +514,17 @@ inline valarray<_Tp>
|
||||
valarray<_Tp>::cshift (int __n) const
|
||||
{
|
||||
_Tp* const __a = static_cast<_Tp*> (alloca (sizeof(_Tp) * _M_size));
|
||||
if (! __n) // __n == 0: no cshift
|
||||
__valarray_copy(_M_data, _M_size, __a);
|
||||
if (__n == 0) // __n == 0: no cshift
|
||||
__valarray_copy_construct(_M_data, _M_data + _M_size, __a);
|
||||
else if (__n > 0) { // __n > 0: cshift left
|
||||
__valarray_copy (_M_data, __n, __a + _M_size-__n);
|
||||
__valarray_copy (_M_data + __n, _M_size-__n, __a);
|
||||
__valarray_copy_construct (_M_data, _M_data + __n, __a + _M_size-__n);
|
||||
__valarray_copy_construct (_M_data + __n, _M_data + _M_size, __a);
|
||||
}
|
||||
else { // __n < 0: cshift right
|
||||
__valarray_copy (_M_data + _M_size + __n, -__n, __a);
|
||||
__valarray_copy (_M_data, _M_size + __n, __a - __n);
|
||||
__valarray_copy_construct
|
||||
(_M_data + _M_size + __n, _M_data + _M_size, __a);
|
||||
__valarray_copy_construct
|
||||
(_M_data, _M_data + _M_size + __n, __a - __n);
|
||||
}
|
||||
return valarray<_Tp> (__a, _M_size);
|
||||
}
|
||||
@ -526,12 +533,15 @@ template <class _Tp>
|
||||
inline void
|
||||
valarray<_Tp>::resize (size_t __n, _Tp __c)
|
||||
{
|
||||
if (_M_size != __n) {
|
||||
delete[] _M_data;
|
||||
_M_size = __n;
|
||||
_M_data = new _Tp[_M_size];
|
||||
}
|
||||
__valarray_fill (_M_data, _M_size, __c);
|
||||
// this is so to make valarray<valarray<T> > work
|
||||
// even though it is not required by the standard.
|
||||
__valarray_destroy_elements(_M_data, _M_data + _M_size);
|
||||
if (_M_size != __n) {
|
||||
__valarray_release_storage(_M_data);
|
||||
_M_size = __n;
|
||||
_M_data = __valarray_get_storage<_Tp>(__n);
|
||||
}
|
||||
__valarray_fill_construct (_M_data, _M_data + _M_size, __c);
|
||||
}
|
||||
|
||||
template<typename _Tp>
|
||||
|
@ -34,39 +34,205 @@
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <std/cpp_type_traits.h>
|
||||
|
||||
extern "C++" {
|
||||
|
||||
//
|
||||
// Helper functions on raw pointers
|
||||
//
|
||||
|
||||
inline void*
|
||||
__valarray_get_memory(size_t __n)
|
||||
{ return operator new(__n); }
|
||||
|
||||
// fill 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; }
|
||||
template<typename _Tp>
|
||||
inline _Tp*__restrict__
|
||||
__valarray_get_storage(size_t __n)
|
||||
{
|
||||
return static_cast<_Tp*__restrict__>
|
||||
(__valarray_get_memory(__n * sizeof(_Tp)));
|
||||
}
|
||||
|
||||
// Return memory to the system
|
||||
inline void
|
||||
__valarray_release_storage(void* __p)
|
||||
{ operator delete(__p); }
|
||||
|
||||
// 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; }
|
||||
// Turn a raw-memory into an array of _Tp filled with _Tp()
|
||||
// This is required in 'valarray<T> v(n);'
|
||||
template<typename _Tp, bool>
|
||||
struct _Array_default_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)
|
||||
{ while (__b != __e) new(__b++) _Tp(); }
|
||||
};
|
||||
|
||||
// fill indirect 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; }
|
||||
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)
|
||||
{ memset(__b, 0, (__e - __b)*sizeof(_Tp)); }
|
||||
};
|
||||
|
||||
// copy plain array __a[<__n>] in __b[<__n>]
|
||||
template<typename _Tp>
|
||||
inline void
|
||||
__valarray_copy (const _Tp* __restrict__ __a, size_t __n,
|
||||
_Tp* __restrict__ __b)
|
||||
{ memcpy (__b, __a, __n * 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);
|
||||
}
|
||||
|
||||
// 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>::_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)
|
||||
{ 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);
|
||||
}
|
||||
|
||||
// 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>::_M_type)
|
||||
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>::_M_type)
|
||||
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>::_M_type)
|
||||
while (__b != __e) { __b->~_Tp(); ++__b; }
|
||||
}
|
||||
|
||||
|
||||
// fill 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 indirect 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)
|
||||
{ memcpy (__b, __a, __n * sizeof (_Tp)); }
|
||||
};
|
||||
|
||||
template<typename _Tp>
|
||||
inline void
|
||||
__valarray_copy (const _Tp* __restrict__ __a, size_t __n,
|
||||
_Tp* __restrict__ __b)
|
||||
{
|
||||
_Array_copier<_Tp, __is_fundamental<_Tp>::_M_type>::
|
||||
_S_do_it(__a, __n, __b);
|
||||
}
|
||||
|
||||
// copy strided array __a[<__n : __s>] in plain __b[<__n>]
|
||||
template<typename _Tp>
|
||||
@ -97,6 +263,34 @@ __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; }
|
||||
|
||||
//
|
||||
// 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 = __r + *__f++;
|
||||
return __r;
|
||||
}
|
||||
|
||||
// Compute the product of all elements in range [__f, __l)
|
||||
template<typename _Tp>
|
||||
_Tp
|
||||
__valarray_product(const _Tp* __restrict__ __f,
|
||||
const _Tp* __restrict__ __l)
|
||||
{
|
||||
_Tp __r = _Tp(1);
|
||||
while (__f != __l) __r = __r * *__f++;
|
||||
return __r;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Helper class _Array, first layer of valarray abstraction.
|
||||
// All operations on valarray should be forwarded to this class
|
||||
@ -110,7 +304,6 @@ template<typename _Tp> struct _Array {
|
||||
explicit _Array (const valarray<_Tp>&);
|
||||
_Array (const _Tp* __restrict__, size_t);
|
||||
|
||||
void free_data() const;
|
||||
_Tp* begin () const;
|
||||
|
||||
_Tp* const __restrict__ _M_data;
|
||||
@ -161,7 +354,9 @@ __valarray_copy (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b,
|
||||
|
||||
template<typename _Tp>
|
||||
inline
|
||||
_Array<_Tp>::_Array (size_t __n) : _M_data (new _Tp[__n]) {}
|
||||
_Array<_Tp>::_Array (size_t __n)
|
||||
: _M_data (__valarray_get_storage<_Tp>(__n))
|
||||
{ __valarray_default_construct(_M_data, _M_data + __n); }
|
||||
|
||||
template<typename _Tp>
|
||||
inline
|
||||
@ -174,11 +369,8 @@ inline _Array<_Tp>::_Array (const valarray<_Tp>& __v)
|
||||
template<typename _Tp>
|
||||
inline
|
||||
_Array<_Tp>::_Array (const _Tp* __restrict__ __b, size_t __s)
|
||||
: _M_data (new _Tp[__s]) { __valarray_copy (__b, __s, _M_data); }
|
||||
|
||||
template<typename _Tp>
|
||||
inline void
|
||||
_Array<_Tp>::free_data() const { delete[] _M_data; }
|
||||
: _M_data (__valarray_get_storage<_Tp>(__s ))
|
||||
{ __valarray_copy_construct(__b, __s, _M_data); }
|
||||
|
||||
template<typename _Tp>
|
||||
inline _Tp*
|
||||
|
@ -1,9 +1,5 @@
|
||||
#include <std/std_valarray.h>
|
||||
|
||||
// Some Explicit Instanciations.
|
||||
template class multiplies<size_t>;
|
||||
template size_t accumulate(size_t*, size_t*, size_t, multiplies<size_t>);
|
||||
|
||||
template void
|
||||
__valarray_fill(size_t* __restrict__, size_t, const size_t&);
|
||||
|
||||
@ -15,7 +11,19 @@ template valarray<size_t>::~valarray();
|
||||
template valarray<size_t>::valarray(const valarray<size_t>&);
|
||||
template size_t valarray<size_t>::size() const;
|
||||
template size_t& valarray<size_t>::operator[](size_t);
|
||||
template size_t valarray<size_t>::product() const;
|
||||
|
||||
|
||||
inline size_t
|
||||
__valarray_product(const valarray<size_t>& __a)
|
||||
{
|
||||
// XXX: This ugly cast is necessary because
|
||||
// valarray::operator[]() const returns a VALUE!
|
||||
// Try to get the committee to correct that gross error.
|
||||
typedef const size_t* __restrict__ _Tp;
|
||||
const size_t __n = __a.size();
|
||||
valarray<size_t>& __t = const_cast<valarray<size_t>&>(__a);
|
||||
return __valarray_product(&__t[0], &__t[0] + __n);
|
||||
}
|
||||
|
||||
|
||||
void __gslice_to_index(size_t __o, const valarray<size_t>& __l,
|
||||
@ -43,7 +51,7 @@ void __gslice_to_index(size_t __o, const valarray<size_t>& __l,
|
||||
_Indexer::_Indexer(size_t __o, const valarray<size_t>& __l,
|
||||
const valarray<size_t>& __s)
|
||||
: _M_count(1), _M_start(__o), _M_size(__l), _M_stride(__s),
|
||||
_M_index(__l.size() ? __l.product() : 0)
|
||||
_M_index(__l.size() ? __valarray_product(__l) : 0)
|
||||
{ __gslice_to_index(__o, __l, __s, _M_index); }
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user