diff options
Diffstat (limited to 'src/corelib/tools/qmap.h')
-rw-r--r-- | src/corelib/tools/qmap.h | 35 |
1 files changed, 30 insertions, 5 deletions
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index 0215a78..bd9ba74 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -416,9 +416,29 @@ Q_INLINE_TEMPLATE typename QMapData::Node * QMap<Key, T>::node_create(QMapData *adt, QMapData::Node *aupdate[], const Key &akey, const T &avalue) { QMapData::Node *abstractNode = adt->node_create(aupdate, payload()); - Node *concreteNode = concrete(abstractNode); - new (&concreteNode->key) Key(akey); - new (&concreteNode->value) T(avalue); + QT_TRY { + Node *concreteNode = concrete(abstractNode); + new (&concreteNode->key) Key(akey); + QT_TRY { + new (&concreteNode->value) T(avalue); + } QT_CATCH(...) { + concreteNode->key.~Key(); + QT_RETHROW; + } + } QT_CATCH(...) { + adt->node_delete(aupdate, payload(), abstractNode); + QT_RETHROW; + } + + // clean up the update array for further insertions + /* + for (int i = 0; i <= d->topLevel; ++i) { + if ( aupdate[i]==reinterpret_cast<QMapData::Node *>(adt) || aupdate[i]->forward[i] != abstractNode) + break; + aupdate[i] = abstractNode; + } +*/ + return abstractNode; } @@ -704,8 +724,13 @@ Q_OUTOFLINE_TEMPLATE void QMap<Key, T>::detach_helper() QMapData::Node *cur = e->forward[0]; update[0] = x.e; while (cur != e) { - Node *concreteNode = concrete(cur); - node_create(x.d, update, concreteNode->key, concreteNode->value); + QT_TRY { + Node *concreteNode = concrete(cur); + node_create(x.d, update, concreteNode->key, concreteNode->value); + } QT_CATCH(...) { + freeData(x.d); + QT_RETHROW; + } cur = cur->forward[0]; } x.d->insertInOrder = false; |