aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2014-10-09 23:35:49 +0200
committerGravatar Gael Guennebaud <g.gael@free.fr>2014-10-09 23:35:49 +0200
commit349c2c9235ce93b50bd8e38be3e876ee73442ccc (patch)
treec230ce845ee892009c3e008c82eb6f125b5c61a6 /Eigen
parent48d537f59fd3c7efd954bb99581dac83fd1c0f16 (diff)
bug #367: fix double copies in atWithInsertion, and add respective unit-test
Diffstat (limited to 'Eigen')
-rw-r--r--Eigen/src/SparseCore/CompressedStorage.h27
1 files changed, 23 insertions, 4 deletions
diff --git a/Eigen/src/SparseCore/CompressedStorage.h b/Eigen/src/SparseCore/CompressedStorage.h
index 4f3695773..f408dd3a6 100644
--- a/Eigen/src/SparseCore/CompressedStorage.h
+++ b/Eigen/src/SparseCore/CompressedStorage.h
@@ -172,12 +172,31 @@ class CompressedStorage
size_t id = searchLowerIndex(0,m_size,key);
if (id>=m_size || m_indices[id]!=key)
{
- resize(m_size+1,1);
- for (size_t j=m_size-1; j>id; --j)
+ if (m_allocatedSize<m_size+1)
{
- m_indices[j] = m_indices[j-1];
- m_values[j] = m_values[j-1];
+ m_allocatedSize = 2*(m_size+1);
+ internal::scoped_array<Scalar> newValues(m_allocatedSize);
+ internal::scoped_array<Index> newIndices(m_allocatedSize);
+
+ // copy first chunk
+ internal::smart_copy(m_values, m_values +id, newValues.ptr());
+ internal::smart_copy(m_indices, m_indices+id, newIndices.ptr());
+
+ // copy the rest
+ if(m_size>id)
+ {
+ internal::smart_copy(m_values +id, m_values +m_size, newValues.ptr() +id+1);
+ internal::smart_copy(m_indices+id, m_indices+m_size, newIndices.ptr()+id+1);
+ }
+ std::swap(m_values,newValues.ptr());
+ std::swap(m_indices,newIndices.ptr());
}
+ else if(m_size>id)
+ {
+ internal::smart_memmove(m_values +id, m_values +m_size, m_values +id+1);
+ internal::smart_memmove(m_indices+id, m_indices+m_size, m_indices+id+1);
+ }
+ m_size++;
m_indices[id] = key;
m_values[id] = defaultValue;
}