diff --git a/Eigen/src/Core/DenseStorage.h b/Eigen/src/Core/DenseStorage.h index d27fb7bfb..39507ff37 100644 --- a/Eigen/src/Core/DenseStorage.h +++ b/Eigen/src/Core/DenseStorage.h @@ -198,16 +198,16 @@ template class DenseStorage(size)), m_rows(rows), m_cols(cols) + : m_data(internal::conditional_aligned_new_auto(size)), m_rows(rows), m_cols(cols) { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN } - inline ~DenseStorage() { internal::conditional_aligned_delete(m_data, m_rows*m_cols); } + inline ~DenseStorage() { internal::conditional_aligned_delete_auto(m_data, m_rows*m_cols); } inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); } inline DenseIndex rows(void) const {return m_rows;} inline DenseIndex cols(void) const {return m_cols;} inline void conservativeResize(DenseIndex size, DenseIndex rows, DenseIndex cols) { - m_data = internal::conditional_aligned_realloc_new(m_data, size, m_rows*m_cols); + m_data = internal::conditional_aligned_realloc_new_auto(m_data, size, m_rows*m_cols); m_rows = rows; m_cols = cols; } @@ -215,9 +215,9 @@ template class DenseStorage(m_data, m_rows*m_cols); + internal::conditional_aligned_delete_auto(m_data, m_rows*m_cols); if (size) - m_data = internal::conditional_aligned_new(size); + m_data = internal::conditional_aligned_new_auto(size); else m_data = 0; EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN @@ -237,24 +237,24 @@ template class DenseStorage(size)), m_cols(cols) + inline DenseStorage(DenseIndex size, DenseIndex, DenseIndex cols) : m_data(internal::conditional_aligned_new_auto(size)), m_cols(cols) { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN } - inline ~DenseStorage() { internal::conditional_aligned_delete(m_data, _Rows*m_cols); } + inline ~DenseStorage() { internal::conditional_aligned_delete_auto(m_data, _Rows*m_cols); } inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); } inline static DenseIndex rows(void) {return _Rows;} inline DenseIndex cols(void) const {return m_cols;} inline void conservativeResize(DenseIndex size, DenseIndex, DenseIndex cols) { - m_data = internal::conditional_aligned_realloc_new(m_data, size, _Rows*m_cols); + m_data = internal::conditional_aligned_realloc_new_auto(m_data, size, _Rows*m_cols); m_cols = cols; } EIGEN_STRONG_INLINE void resize(DenseIndex size, DenseIndex, DenseIndex cols) { if(size != _Rows*m_cols) { - internal::conditional_aligned_delete(m_data, _Rows*m_cols); + internal::conditional_aligned_delete_auto(m_data, _Rows*m_cols); if (size) - m_data = internal::conditional_aligned_new(size); + m_data = internal::conditional_aligned_new_auto(size); else m_data = 0; EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN @@ -273,24 +273,24 @@ template class DenseStorage(size)), m_rows(rows) + inline DenseStorage(DenseIndex size, DenseIndex rows, DenseIndex) : m_data(internal::conditional_aligned_new_auto(size)), m_rows(rows) { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN } - inline ~DenseStorage() { internal::conditional_aligned_delete(m_data, _Cols*m_rows); } + inline ~DenseStorage() { internal::conditional_aligned_delete_auto(m_data, _Cols*m_rows); } inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); } inline DenseIndex rows(void) const {return m_rows;} inline static DenseIndex cols(void) {return _Cols;} inline void conservativeResize(DenseIndex size, DenseIndex rows, DenseIndex) { - m_data = internal::conditional_aligned_realloc_new(m_data, size, m_rows*_Cols); + m_data = internal::conditional_aligned_realloc_new_auto(m_data, size, m_rows*_Cols); m_rows = rows; } EIGEN_STRONG_INLINE void resize(DenseIndex size, DenseIndex rows, DenseIndex) { if(size != m_rows*_Cols) { - internal::conditional_aligned_delete(m_data, _Cols*m_rows); + internal::conditional_aligned_delete_auto(m_data, _Cols*m_rows); if (size) - m_data = internal::conditional_aligned_new(size); + m_data = internal::conditional_aligned_new_auto(size); else m_data = 0; EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN diff --git a/Eigen/src/Core/NumTraits.h b/Eigen/src/Core/NumTraits.h index 13dae85a4..5c7762dae 100644 --- a/Eigen/src/Core/NumTraits.h +++ b/Eigen/src/Core/NumTraits.h @@ -53,6 +53,8 @@ * to by move / add / mul instructions respectively, assuming the data is already stored in CPU registers. * Stay vague here. No need to do architecture-specific stuff. * \li An enum value \a IsSigned. It is equal to \c 1 if \a T is a signed type and to 0 if \a T is unsigned. + * \li An enum value \a RequireInitialization. It is equal to \c 1 if the constructor of the numeric type \a T must + * be called, and to 0 if it is safe not to call it. Default is 0 if \a T is an arithmetic type, and 1 otherwise. * \li An epsilon() function which, unlike std::numeric_limits::epsilon(), returns a \a Real instead of a \a T. * \li A dummy_precision() function returning a weak epsilon value. It is mainly used as a default * value by the fuzzy comparison operators. @@ -65,6 +67,7 @@ template struct GenericNumTraits IsInteger = std::numeric_limits::is_integer, IsSigned = std::numeric_limits::is_signed, IsComplex = 0, + RequireInitialization = internal::is_arithmetic::value ? 0 : 1, ReadCost = 1, AddCost = 1, MulCost = 1 @@ -121,6 +124,7 @@ template struct NumTraits > typedef _Real Real; enum { IsComplex = 1, + RequireInitialization = NumTraits<_Real>::RequireInitialization, ReadCost = 2 * NumTraits<_Real>::ReadCost, AddCost = 2 * NumTraits::AddCost, MulCost = 4 * NumTraits::MulCost + 2 * NumTraits::AddCost @@ -144,6 +148,7 @@ struct NumTraits > IsComplex = NumTraits::IsComplex, IsInteger = NumTraits::IsInteger, IsSigned = NumTraits::IsSigned, + RequireInitialization = 1, ReadCost = ArrayType::SizeAtCompileTime==Dynamic ? Dynamic : ArrayType::SizeAtCompileTime * NumTraits::ReadCost, AddCost = ArrayType::SizeAtCompileTime==Dynamic ? Dynamic : ArrayType::SizeAtCompileTime * NumTraits::AddCost, MulCost = ArrayType::SizeAtCompileTime==Dynamic ? Dynamic : ArrayType::SizeAtCompileTime * NumTraits::MulCost diff --git a/Eigen/src/Core/util/Memory.h b/Eigen/src/Core/util/Memory.h index 9f95d5bc7..558486418 100644 --- a/Eigen/src/Core/util/Memory.h +++ b/Eigen/src/Core/util/Memory.h @@ -369,6 +369,30 @@ template inline T* conditional_aligned_realloc_new(T* pt return result; } + +template inline T* conditional_aligned_new_auto(size_t size) +{ + T *result = reinterpret_cast(conditional_aligned_malloc(sizeof(T)*size)); + if(NumTraits::RequireInitialization) + construct_elements_of_array(result, size); + return result; +} + +template inline T* conditional_aligned_realloc_new_auto(T* pts, size_t new_size, size_t old_size) +{ + T *result = reinterpret_cast(conditional_aligned_realloc(reinterpret_cast(pts), sizeof(T)*new_size, sizeof(T)*old_size)); + if (NumTraits::RequireInitialization && (new_size > old_size)) + construct_elements_of_array(result+old_size, new_size-old_size); + return result; +} + +template inline void conditional_aligned_delete_auto(T *ptr, size_t size) +{ + if(NumTraits::RequireInitialization) + destruct_elements_of_array(ptr, size); + conditional_aligned_free(ptr); +} + /****************************************************************************/ /** \internal Returns the index of the first element of the array that is well aligned for vectorization. diff --git a/unsupported/Eigen/MPRealSupport b/unsupported/Eigen/MPRealSupport index 37e75b2c7..6bded0c2c 100644 --- a/unsupported/Eigen/MPRealSupport +++ b/unsupported/Eigen/MPRealSupport @@ -80,6 +80,7 @@ int main() IsInteger = 0, IsSigned = 1, IsComplex = 0, + RequireInitialization = 1, ReadCost = 10, AddCost = 10, MulCost = 40