summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kyoshida@novell.com>2011-07-19 14:46:50 -0400
committerKohei Yoshida <kyoshida@novell.com>2011-07-19 14:50:31 -0400
commit8da78944e7c4fcae9ae40bea7162898d20db6329 (patch)
tree67f0efa86a8803d02043c818d7180b253e45f24b
parent0290076c7043ab3b9dfde2fd6219334f5a0e987d (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.
-rw-r--r--sc/source/core/data/dpobject.cxx33
1 files changed, 9 insertions, 24 deletions
diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx
index f0b498c9b..bea58b806 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,