diff options
author | Kohei Yoshida <kyoshida@novell.com> | 2011-07-19 14:46:50 -0400 |
---|---|---|
committer | David Tardon <dtardon@redhat.com> | 2011-07-20 06:50:16 +0200 |
commit | c82f49c06b32f0da90e53df50bb24789fffe3c9a (patch) | |
tree | e455ee5906e9e3a531a1706d11a92de69de3f9f1 | |
parent | d688aee70f87acbfe273b814d21b5dba343fc9d9 (diff) |
fdo#39236: Prevent double-deletes during removal of pivot tables.
In short, don't use erase remove(_if) idiom to remove objects from
boost ptr containers which would cause double deletes because of
the way remove-like algorithms work. STL's remove-like algorithms
create duplicates of the elements instead of re-ordering them by
design, and this obviously doesn't work well with containers
containing pointers.
Signed-off-by: David Tardon <dtardon@redhat.com>
-rw-r--r-- | sc/source/core/data/dpobject.cxx | 33 |
1 files changed, 9 insertions, 24 deletions
diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index 442676340..3aa7477cd 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -83,8 +83,6 @@ using namespace com::sun::star; using ::std::vector; -using ::std::unary_function; -using ::std::remove_if; using ::boost::shared_ptr; using ::com::sun::star::uno::Sequence; using ::com::sun::star::uno::Reference; @@ -2556,25 +2554,6 @@ ScDPCollection::~ScDPCollection() maTables.clear(); } -namespace { - -/** - * Unary predicate to match DP objects by the table ID. - */ -class MatchByTable : public unary_function<bool, ScDPObject> -{ - SCTAB mnTab; -public: - MatchByTable(SCTAB nTab) : mnTab(nTab) {} - - bool operator() (const ScDPObject& rObj) const - { - return rObj.GetOutRange().aStart.Tab() == mnTab; - } -}; - -} - bool ScDPCollection::ClearCache(ScDPObject* pDPObj) { if (pDPObj->IsSheetData()) @@ -2612,9 +2591,15 @@ bool ScDPCollection::ClearCache(ScDPObject* pDPObj) void ScDPCollection::DeleteOnTab( SCTAB nTab ) { - maTables.erase( - remove_if(maTables.begin(), maTables.end(), MatchByTable(nTab)), - maTables.end()); + TablesType aNewTables; + while (!maTables.empty()) + { + TablesType::auto_type xDP = maTables.pop_back(); + if (xDP->GetOutRange().aStart.Tab() != nTab) + // Not on this sheet. Keep it. + aNewTables.push_back(xDP.release()); + } + maTables.swap(aNewTables); } void ScDPCollection::UpdateReference( UpdateRefMode eUpdateRefMode, |