diff options
author | Kohei Yoshida <kyoshida@novell.com> | 2011-07-19 14:46:50 -0400 |
---|---|---|
committer | Kohei Yoshida <kyoshida@novell.com> | 2011-07-19 14:50:31 -0400 |
commit | d0e479962694ae7944d9d3cfa0bedda76c473e07 (patch) | |
tree | e8cfbf2d7352a3fc684eb840068ad8fce512ae28 /sc | |
parent | b2b61b8c4892a8a02ae37cd48db8fad8fa02eb32 (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.
Diffstat (limited to 'sc')
-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 5aee5b71b0a9..a39d2761c859 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; @@ -2572,25 +2570,6 @@ ScDPCollection::~ScDPCollection() maTables.clear(); } -namespace { - -/** - * Unary predicate to match DP objects by the table ID. - */ -class MatchByTable : public unary_function<ScDPObject, bool> -{ - 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()) @@ -2628,9 +2607,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, |