From 6d3dee1b66ce77b82f2d4e1c052f78c8c9ccdc5d Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Thu, 9 Jun 2011 19:04:06 +0200 Subject: [PATCH] introduce a smart_copy internal function and fix sparse matrices with non POD scalar type --- Eigen/src/Core/util/Memory.h | 23 ++++++++++++++++++++++- Eigen/src/Sparse/CompressedStorage.h | 4 ++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/Eigen/src/Core/util/Memory.h b/Eigen/src/Core/util/Memory.h index 8e4eccd95..f9bafab57 100644 --- a/Eigen/src/Core/util/Memory.h +++ b/Eigen/src/Core/util/Memory.h @@ -462,6 +462,27 @@ inline static Index first_aligned(const Scalar* array, Index size) } } + +// std::copy is much slower than std::copy, so let's introduce a smart_copy which +// use memcpy on trivial types, i.e., on types that does not require an initialization ctor. +template struct smart_copy_helper; + +template void smart_copy(const T* start, const T* end, T* target) +{ + smart_copy_helper::RequireInitialization>::run(start, end, target); +} + +template struct smart_copy_helper { + inline static void run(const T* start, const T* end, T* target) + { memcpy(target, start, std::ptrdiff_t(end)-std::ptrdiff_t(start)); } +}; + +template struct smart_copy_helper { + inline static void run(const T* start, const T* end, T* target) + { std::copy(start, end, target); } +}; + + } // end namespace internal /***************************************************************************** @@ -517,7 +538,7 @@ template class aligned_stack_memory_handler * if SIZE is smaller than EIGEN_STACK_ALLOCATION_LIMIT, and if stack allocation is supported by the platform * (currently, this is Linux and Visual Studio only). Otherwise the memory is allocated on the heap. * The allocated buffer is automatically deleted when exiting the scope of this declaration. - * If BUFFER is non nul, then the declared variable is simply an alias for BUFFER, and no allocation/deletion occurs. + * If BUFFER is non null, then the declared variable is simply an alias for BUFFER, and no allocation/deletion occurs. * Here is an example: * \code * { diff --git a/Eigen/src/Sparse/CompressedStorage.h b/Eigen/src/Sparse/CompressedStorage.h index 1c36a2632..b5c6def17 100644 --- a/Eigen/src/Sparse/CompressedStorage.h +++ b/Eigen/src/Sparse/CompressedStorage.h @@ -218,8 +218,8 @@ class CompressedStorage Index* newIndices = new Index[size]; size_t copySize = std::min(size, m_size); // copy - memcpy(newValues, m_values, copySize * sizeof(Scalar)); - memcpy(newIndices, m_indices, copySize * sizeof(Index)); + internal::smart_copy(m_values, m_values+copySize, newValues); + internal::smart_copy(m_indices, m_indices+copySize, newIndices); // delete old stuff delete[] m_values; delete[] m_indices;