From 23e7e3c165bb2631f9d8eb298f86da862e91cefa Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sun, 6 Dec 2015 15:14:05 +1100 Subject: [PATCH] Use std::unique_ptr to store records in collections, RefidCollection and RefIdData. - std::move support required (C++11) - MSVC 2013 or later should be fine --- apps/opencs/model/doc/document.cpp | 25 +++-- apps/opencs/model/doc/savingstages.cpp | 12 +- apps/opencs/model/tools/mergestages.cpp | 21 ++-- apps/opencs/model/tools/mergestages.hpp | 4 +- apps/opencs/model/world/collection.hpp | 105 +++++++++--------- apps/opencs/model/world/collectionbase.hpp | 5 +- apps/opencs/model/world/commands.cpp | 14 +-- apps/opencs/model/world/commands.hpp | 5 +- apps/opencs/model/world/data.cpp | 7 +- apps/opencs/model/world/idcollection.hpp | 33 +++--- apps/opencs/model/world/idtable.cpp | 7 +- apps/opencs/model/world/idtable.hpp | 3 +- apps/opencs/model/world/infocollection.cpp | 45 ++++---- apps/opencs/model/world/infocollection.hpp | 2 +- .../opencs/model/world/nestedidcollection.hpp | 32 +++--- .../model/world/nestedinfocollection.cpp | 32 +++--- apps/opencs/model/world/record.hpp | 18 +-- apps/opencs/model/world/refcollection.cpp | 23 ++-- apps/opencs/model/world/refidcollection.cpp | 15 +-- apps/opencs/model/world/refidcollection.hpp | 4 +- apps/opencs/model/world/refiddata.cpp | 12 +- apps/opencs/model/world/refiddata.hpp | 53 +++++---- 22 files changed, 248 insertions(+), 229 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 18dc9af4a..766503643 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2,6 +2,7 @@ #include #include +#include #include @@ -2091,10 +2092,10 @@ void CSMDoc::Document::addOptionalGmst (const ESM::GameSetting& gmst) { if (getData().getGmsts().searchId (gmst.mId)==-1) { - CSMWorld::Record record; - record.mBase = gmst; - record.mState = CSMWorld::RecordBase::State_BaseOnly; - getData().getGmsts().appendRecord (record); + std::unique_ptr > record(new CSMWorld::Record); + record->mBase = gmst; + record->mState = CSMWorld::RecordBase::State_BaseOnly; + getData().getGmsts().appendRecord (std::move(record)); } } @@ -2102,10 +2103,10 @@ void CSMDoc::Document::addOptionalGlobal (const ESM::Global& global) { if (getData().getGlobals().searchId (global.mId)==-1) { - CSMWorld::Record record; - record.mBase = global; - record.mState = CSMWorld::RecordBase::State_BaseOnly; - getData().getGlobals().appendRecord (record); + std::unique_ptr > record(new CSMWorld::Record); + record->mBase = global; + record->mState = CSMWorld::RecordBase::State_BaseOnly; + getData().getGlobals().appendRecord (std::move(record)); } } @@ -2113,10 +2114,10 @@ void CSMDoc::Document::addOptionalMagicEffect (const ESM::MagicEffect& magicEffe { if (getData().getMagicEffects().searchId (magicEffect.mId)==-1) { - CSMWorld::Record record; - record.mBase = magicEffect; - record.mState = CSMWorld::RecordBase::State_BaseOnly; - getData().getMagicEffects().appendRecord (record); + std::unique_ptr > record(new CSMWorld::Record); + record->mBase = magicEffect; + record->mState = CSMWorld::RecordBase::State_BaseOnly; + getData().getMagicEffects().appendRecord (std::move(record)); } } diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp index db38c4779..e18f2311f 100644 --- a/apps/opencs/model/doc/savingstages.cpp +++ b/apps/opencs/model/doc/savingstages.cpp @@ -118,7 +118,7 @@ void CSMDoc::WriteDialogueCollectionStage::perform (int stage, Messages& message for (CSMWorld::InfoCollection::RecordConstIterator iter (range.first); iter!=range.second; ++iter) { - if (iter->isModified() || iter->mState == CSMWorld::RecordBase::State_Deleted) + if ((*iter)->isModified() || (*iter)->mState == CSMWorld::RecordBase::State_Deleted) { infoModified = true; break; @@ -144,9 +144,9 @@ void CSMDoc::WriteDialogueCollectionStage::perform (int stage, Messages& message // write modified selected info records for (CSMWorld::InfoCollection::RecordConstIterator iter (range.first); iter!=range.second; ++iter) { - if (iter->isModified() || iter->mState == CSMWorld::RecordBase::State_Deleted) + if ((*iter)->isModified() || (*iter)->mState == CSMWorld::RecordBase::State_Deleted) { - ESM::DialInfo info = iter->get(); + ESM::DialInfo info = (*iter)->get(); info.mId = info.mId.substr (info.mId.find_last_of ('#')+1); info.mPrev = ""; @@ -155,7 +155,7 @@ void CSMDoc::WriteDialogueCollectionStage::perform (int stage, Messages& message CSMWorld::InfoCollection::RecordConstIterator prev = iter; --prev; - info.mPrev = prev->get().mId.substr (prev->get().mId.find_last_of ('#')+1); + info.mPrev = (*prev)->get().mId.substr ((*prev)->get().mId.find_last_of ('#')+1); } CSMWorld::InfoCollection::RecordConstIterator next = iter; @@ -164,11 +164,11 @@ void CSMDoc::WriteDialogueCollectionStage::perform (int stage, Messages& message info.mNext = ""; if (next!=range.second) { - info.mNext = next->get().mId.substr (next->get().mId.find_last_of ('#')+1); + info.mNext = (*next)->get().mId.substr ((*next)->get().mId.find_last_of ('#')+1); } writer.startRecord (info.sRecordId); - info.save (writer, iter->mState == CSMWorld::RecordBase::State_Deleted); + info.save (writer, (*iter)->mState == CSMWorld::RecordBase::State_Deleted); writer.endRecord (info.sRecordId); } } diff --git a/apps/opencs/model/tools/mergestages.cpp b/apps/opencs/model/tools/mergestages.cpp index d936be593..105a722d0 100644 --- a/apps/opencs/model/tools/mergestages.cpp +++ b/apps/opencs/model/tools/mergestages.cpp @@ -100,10 +100,9 @@ void CSMTools::MergeReferencesStage::perform (int stage, CSMDoc::Messages& messa ref.mRefNum.mIndex = mIndex[Misc::StringUtils::lowerCase (ref.mCell)]++; ref.mRefNum.mContentFile = 0; - CSMWorld::Record newRecord ( - CSMWorld::RecordBase::State_ModifiedOnly, 0, &ref); - - mState.mTarget->getData().getReferences().appendRecord (newRecord); + mState.mTarget->getData().getReferences().appendRecord ( + std::make_unique >( + CSMWorld::Record(CSMWorld::RecordBase::State_ModifiedOnly, 0, &ref))); } } @@ -189,10 +188,9 @@ void CSMTools::MergeLandTexturesStage::perform (int stage, CSMDoc::Messages& mes texture.mIndex = mNext->second-1; texture.mId = stream2.str(); - CSMWorld::Record newRecord ( - CSMWorld::RecordBase::State_ModifiedOnly, 0, &texture); - - mState.mTarget->getData().getLandTextures().appendRecord (newRecord); + mState.mTarget->getData().getLandTextures().appendRecord ( + std::make_unique >( + CSMWorld::Record(CSMWorld::RecordBase::State_ModifiedOnly, 0, &texture))); found = true; } @@ -250,9 +248,8 @@ void CSMTools::MergeLandStage::perform (int stage, CSMDoc::Messages& messages) } } - CSMWorld::Record newRecord ( - CSMWorld::RecordBase::State_ModifiedOnly, 0, &newLand); - - mState.mTarget->getData().getLand().appendRecord (newRecord); + mState.mTarget->getData().getLand().appendRecord ( + std::make_unique >( + CSMWorld::Record(CSMWorld::RecordBase::State_ModifiedOnly, 0, &newLand))); } } diff --git a/apps/opencs/model/tools/mergestages.hpp b/apps/opencs/model/tools/mergestages.hpp index f88f5be9f..cfb7852dc 100644 --- a/apps/opencs/model/tools/mergestages.hpp +++ b/apps/opencs/model/tools/mergestages.hpp @@ -3,6 +3,7 @@ #include #include +#include #include @@ -82,7 +83,8 @@ namespace CSMTools const CSMWorld::Record& record = source.getRecord (stage); if (!record.isDeleted()) - target.appendRecord (CSMWorld::Record (CSMWorld::RecordBase::State_ModifiedOnly, 0, &record.get())); + target.appendRecord (std::make_unique >( + CSMWorld::Record(CSMWorld::RecordBase::State_ModifiedOnly, 0, &record.get()))); } class MergeRefIdsStage : public CSMDoc::Stage diff --git a/apps/opencs/model/world/collection.hpp b/apps/opencs/model/world/collection.hpp index a13673461..475a26263 100644 --- a/apps/opencs/model/world/collection.hpp +++ b/apps/opencs/model/world/collection.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include @@ -49,7 +50,7 @@ namespace CSMWorld private: - std::vector > mRecords; + std::vector > > mRecords; std::map mIndex; std::vector *> mColumns; @@ -61,7 +62,7 @@ namespace CSMWorld const std::map& getIdMap() const; - const std::vector >& getRecords() const; + const std::vector > >& getRecords() const; bool reorderRowsImp (int baseIndex, const std::vector& newOrder); ///< Reorder the rows [baseIndex, baseIndex+newOrder.size()) according to the indices @@ -112,12 +113,12 @@ namespace CSMWorld ////< Search record with \a id. /// \return index of record (if found) or -1 (not found) - virtual void replace (int index, const RecordBase& record); + virtual void replace (int index, std::unique_ptr record); ///< If the record type does not match, an exception is thrown. /// /// \attention \a record must not change the ID. - virtual void appendRecord (const RecordBase& record, + virtual void appendRecord (std::unique_ptr record, UniversalId::Type type = UniversalId::Type_None); ///< If the record type does not match, an exception is thrown. ///< \param type Will be ignored, unless the collection supports multiple record types @@ -135,7 +136,7 @@ namespace CSMWorld /// /// \param listDeleted include deleted record in the list - virtual void insertRecord (const RecordBase& record, int index, + virtual void insertRecord (std::unique_ptr record, int index, UniversalId::Type type = UniversalId::Type_None); ///< Insert record before index. /// @@ -152,7 +153,7 @@ namespace CSMWorld void addColumn (Column *column); - void setRecord (int index, const Record& record); + void setRecord (int index, std::unique_ptr > record); ///< \attention This function must not change the ID. NestableColumn *getNestableColumn (int column) const; @@ -165,7 +166,7 @@ namespace CSMWorld } template - const std::vector >& Collection::getRecords() const + const std::vector > >& Collection::getRecords() const { return mRecords; } @@ -185,15 +186,15 @@ namespace CSMWorld return false; // reorder records - std::vector > buffer (size); + std::vector > > buffer (size); for (int i=0; isetModified (buffer[newOrder[i]]->get()); } - std::copy (buffer.begin(), buffer.end(), mRecords.begin()+baseIndex); + std::move (buffer.begin(), buffer.end(), mRecords.begin()+baseIndex); // adjust index for (std::map::iterator iter (mIndex.begin()); iter!=mIndex.end(); @@ -210,12 +211,12 @@ namespace CSMWorld const std::string& destination, const UniversalId::Type type) { - Record copy; - copy.mModified = getRecord(origin).get(); - copy.mState = RecordBase::State_ModifiedOnly; - copy.get().mId = destination; + std::unique_ptr > copy(new Record); + copy->mModified = getRecord(origin).get(); + copy->mState = RecordBase::State_ModifiedOnly; + copy->get().mId = destination; - insertRecord(copy, getAppendIndex(destination, type)); + insertRecord(std::move(copy), getAppendIndex(destination, type)); } template @@ -238,15 +239,15 @@ namespace CSMWorld if (iter==mIndex.end()) { - Record record2; - record2.mState = Record::State_ModifiedOnly; - record2.mModified = record; + std::unique_ptr > record2(new Record); + record2->mState = Record::State_ModifiedOnly; + record2->mModified = record; - insertRecord (record2, getAppendIndex (id)); + insertRecord (std::move(record2), getAppendIndex (id)); } else { - mRecords[iter->second].setModified (record); + mRecords[iter->second]->setModified (record); } } @@ -259,7 +260,7 @@ namespace CSMWorld template std::string Collection::getId (int index) const { - return IdAccessorT().getId (mRecords.at (index).get()); + return IdAccessorT().getId (mRecords.at (index)->get()); } template @@ -282,13 +283,13 @@ namespace CSMWorld template QVariant Collection::getData (int index, int column) const { - return mColumns.at (column)->get (mRecords.at (index)); + return mColumns.at (column)->get (*mRecords.at (index)); } template void Collection::setData (int index, int column, const QVariant& data) { - return mColumns.at (column)->set (mRecords.at (index), data); + return mColumns.at (column)->set (*mRecords.at (index), data); } template @@ -315,8 +316,8 @@ namespace CSMWorld template void Collection::merge() { - for (typename std::vector >::iterator iter (mRecords.begin()); iter!=mRecords.end(); ++iter) - iter->merge(); + for (typename std::vector > >::iterator iter (mRecords.begin()); iter!=mRecords.end(); ++iter) + (*iter)->merge(); purge(); } @@ -328,7 +329,7 @@ namespace CSMWorld while (i (mRecords.size())) { - if (mRecords[i].isErased()) + if (mRecords[i]->isErased()) removeRows (i, 1); else ++i; @@ -369,11 +370,11 @@ namespace CSMWorld IdAccessorT().getId (record) = id; record.blank(); - Record record2; - record2.mState = Record::State_ModifiedOnly; - record2.mModified = record; + std::unique_ptr > record2(new Record); + record2->mState = Record::State_ModifiedOnly; + record2->mModified = record; - insertRecord (record2, getAppendIndex (id, type), type); + insertRecord (std::move(record2), getAppendIndex (id, type), type); } template @@ -390,18 +391,19 @@ namespace CSMWorld } template - void Collection::replace (int index, const RecordBase& record) + void Collection::replace (int index, std::unique_ptr record) { - mRecords.at (index) = dynamic_cast&> (record); + std::unique_ptr > tmp(static_cast*>(record.release())); + mRecords.at (index) = std::move(tmp); } template - void Collection::appendRecord (const RecordBase& record, + void Collection::appendRecord (std::unique_ptr record, UniversalId::Type type) { - insertRecord (record, - getAppendIndex (IdAccessorT().getId ( - dynamic_cast&> (record).get()), type), type); + int index = + getAppendIndex(IdAccessorT().getId(static_cast*>(record.get())->get()), type); + insertRecord (std::move(record), index, type); } template @@ -419,8 +421,8 @@ namespace CSMWorld for (typename std::map::const_iterator iter = mIndex.begin(); iter!=mIndex.end(); ++iter) { - if (listDeleted || !mRecords[iter->second].isDeleted()) - ids.push_back (IdAccessorT().getId (mRecords[iter->second].get())); + if (listDeleted || !mRecords[iter->second]->isDeleted()) + ids.push_back (IdAccessorT().getId (mRecords[iter->second]->get())); } return ids; @@ -430,29 +432,30 @@ namespace CSMWorld const Record& Collection::getRecord (const std::string& id) const { int index = getIndex (id); - return mRecords.at (index); + return *mRecords.at (index); } template const Record& Collection::getRecord (int index) const { - return mRecords.at (index); + return *mRecords.at (index); } template - void Collection::insertRecord (const RecordBase& record, int index, + void Collection::insertRecord (std::unique_ptr record, int index, UniversalId::Type type) { int size = static_cast(mRecords.size()); if (index < 0 || index > size) throw std::runtime_error ("index out of range"); - const Record& record2 = dynamic_cast&> (record); + std::unique_ptr > record2(static_cast*>(record.release())); + std::string lowerId = Misc::StringUtils::lowerCase(IdAccessorT().getId(record2->get())); if (index == size) - mRecords.push_back (record2); + mRecords.push_back (std::move(record2)); else - mRecords.insert (mRecords.begin()+index, record2); + mRecords.insert (mRecords.begin()+index, std::move(record2)); if (index < size-1) { @@ -463,18 +466,18 @@ namespace CSMWorld } } - mIndex.insert (std::make_pair (Misc::StringUtils::lowerCase (IdAccessorT().getId ( - record2.get())), index)); + mIndex.insert (std::make_pair (lowerId, index)); } template - void Collection::setRecord (int index, const Record& record) + void Collection::setRecord (int index, + std::unique_ptr > record) { - if (Misc::StringUtils::lowerCase (IdAccessorT().getId (mRecords.at (index).get()))!= - Misc::StringUtils::lowerCase (IdAccessorT().getId (record.get()))) + if (Misc::StringUtils::lowerCase (IdAccessorT().getId (mRecords.at (index)->get())) != + Misc::StringUtils::lowerCase (IdAccessorT().getId (record->get()))) throw std::runtime_error ("attempt to change the ID of a record"); - mRecords.at (index) = record; + mRecords.at (index) = std::move(record); } template diff --git a/apps/opencs/model/world/collectionbase.hpp b/apps/opencs/model/world/collectionbase.hpp index ef826e31c..fa0399e49 100644 --- a/apps/opencs/model/world/collectionbase.hpp +++ b/apps/opencs/model/world/collectionbase.hpp @@ -3,6 +3,7 @@ #include #include +#include #include "universalid.hpp" #include "columns.hpp" @@ -64,13 +65,13 @@ namespace CSMWorld ////< Search record with \a id. /// \return index of record (if found) or -1 (not found) - virtual void replace (int index, const RecordBase& record) = 0; + virtual void replace (int index, std::unique_ptr record) = 0; ///< If the record type does not match, an exception is thrown. /// /// \attention \a record must not change the ID. ///< \param type Will be ignored, unless the collection supports multiple record types - virtual void appendRecord (const RecordBase& record, + virtual void appendRecord (std::unique_ptr record, UniversalId::Type type = UniversalId::Type_None) = 0; ///< If the record type does not match, an exception is thrown. diff --git a/apps/opencs/model/world/commands.cpp b/apps/opencs/model/world/commands.cpp index d510cd103..0f6681ba1 100644 --- a/apps/opencs/model/world/commands.cpp +++ b/apps/opencs/model/world/commands.cpp @@ -124,16 +124,15 @@ void CSMWorld::CreateCommand::undo() } CSMWorld::RevertCommand::RevertCommand (IdTable& model, const std::string& id, QUndoCommand* parent) -: QUndoCommand (parent), mModel (model), mId (id), mOld (0) + : QUndoCommand (parent), mModel (model), mId (id) { setText (("Revert record " + id).c_str()); - mOld = model.getRecord (id).clone(); + mOld = std::move(model.getRecord (id).clone()); } CSMWorld::RevertCommand::~RevertCommand() { - delete mOld; } void CSMWorld::RevertCommand::redo() @@ -155,21 +154,20 @@ void CSMWorld::RevertCommand::redo() void CSMWorld::RevertCommand::undo() { - mModel.setRecord (mId, *mOld); + mModel.setRecord (mId, std::move(mOld)); } CSMWorld::DeleteCommand::DeleteCommand (IdTable& model, const std::string& id, CSMWorld::UniversalId::Type type, QUndoCommand* parent) -: QUndoCommand (parent), mModel (model), mId (id), mOld (0), mType(type) +: QUndoCommand (parent), mModel (model), mId (id), mType(type) { setText (("Delete record " + id).c_str()); - mOld = model.getRecord (id).clone(); + mOld = std::move(model.getRecord (id).clone()); } CSMWorld::DeleteCommand::~DeleteCommand() { - delete mOld; } void CSMWorld::DeleteCommand::redo() @@ -191,7 +189,7 @@ void CSMWorld::DeleteCommand::redo() void CSMWorld::DeleteCommand::undo() { - mModel.setRecord (mId, *mOld, mType); + mModel.setRecord (mId, std::move(mOld), mType); } diff --git a/apps/opencs/model/world/commands.hpp b/apps/opencs/model/world/commands.hpp index 05f21017c..5cfad5856 100644 --- a/apps/opencs/model/world/commands.hpp +++ b/apps/opencs/model/world/commands.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -97,7 +98,7 @@ namespace CSMWorld { IdTable& mModel; std::string mId; - RecordBase *mOld; + std::unique_ptr mOld; // not implemented RevertCommand (const RevertCommand&); @@ -118,7 +119,7 @@ namespace CSMWorld { IdTable& mModel; std::string mId; - RecordBase *mOld; + std::unique_ptr mOld; UniversalId::Type mType; // not implemented diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 9f92935dc..0e35c4141 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -861,8 +861,8 @@ const CSMWorld::MetaData& CSMWorld::Data::getMetaData() const void CSMWorld::Data::setMetaData (const MetaData& metaData) { - Record record (RecordBase::State_ModifiedOnly, 0, &metaData); - mMetaData.setRecord (0, record); + mMetaData.setRecord (0, std::make_unique >( + Record(RecordBase::State_ModifiedOnly, 0, &metaData))); } const CSMWorld::NpcAutoCalc& CSMWorld::Data::getNpcAutoCalc() const @@ -920,7 +920,8 @@ int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base metaData.mId = "sys::meta"; metaData.load (*mReader); - mMetaData.setRecord (0, Record (RecordBase::State_ModifiedOnly, 0, &metaData)); + mMetaData.setRecord (0, std::make_unique >( + Record (RecordBase::State_ModifiedOnly, 0, &metaData))); } return mReader->getRecordCount(); diff --git a/apps/opencs/model/world/idcollection.hpp b/apps/opencs/model/world/idcollection.hpp index ea6eefb88..5a7d2410d 100644 --- a/apps/opencs/model/world/idcollection.hpp +++ b/apps/opencs/model/world/idcollection.hpp @@ -66,9 +66,9 @@ namespace CSMWorld return -1; } - Record baseRecord = this->getRecord (index); - baseRecord.mState = RecordBase::State_Deleted; - this->setRecord (index, baseRecord); + std::unique_ptr > baseRecord(new Record(this->getRecord(index))); + baseRecord->mState = RecordBase::State_Deleted; + this->setRecord(index, std::move(baseRecord)); return index; } @@ -79,30 +79,31 @@ namespace CSMWorld int IdCollection::load (const ESXRecordT& record, bool base, int index) { - if (index==-2) + if (index==-2) // index unknown index = this->searchId (IdAccessorT().getId (record)); if (index==-1) { // new record - Record record2; - record2.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly; - (base ? record2.mBase : record2.mModified) = record; + std::unique_ptr > record2(new Record); + record2->mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly; + (base ? record2->mBase : record2->mModified) = record; index = this->getSize(); - this->appendRecord (record2); + this->appendRecord(std::move(record2)); } else { // old record - Record record2 = Collection::getRecord (index); + std::unique_ptr > record2( + new Record(Collection::getRecord(index))); if (base) - record2.mBase = record; + record2->mBase = record; else - record2.setModified (record); + record2->setModified(record); - this->setRecord (index, record2); + this->setRecord(index, std::move(record2)); } return index; @@ -116,7 +117,7 @@ namespace CSMWorld if (index==-1) return false; - Record record = Collection::getRecord (index); + const Record& record = Collection::getRecord (index); if (record.isDeleted()) return false; @@ -127,8 +128,10 @@ namespace CSMWorld } else { - record.mState = RecordBase::State_Deleted; - this->setRecord (index, record); + std::unique_ptr > record2( + new Record(Collection::getRecord(index))); + record2->mState = RecordBase::State_Deleted; + this->setRecord(index, std::move(record2)); } return true; diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index e6acf77de..ec666b3df 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -166,7 +166,8 @@ QModelIndex CSMWorld::IdTable::getModelIndex (const std::string& id, int column) return index(mIdCollection->getIndex (id), column); } -void CSMWorld::IdTable::setRecord (const std::string& id, const RecordBase& record, CSMWorld::UniversalId::Type type) +void CSMWorld::IdTable::setRecord (const std::string& id, + std::unique_ptr record, CSMWorld::UniversalId::Type type) { int index = mIdCollection->searchId (id); @@ -176,13 +177,13 @@ void CSMWorld::IdTable::setRecord (const std::string& id, const RecordBase& reco beginInsertRows (QModelIndex(), index2, index2); - mIdCollection->appendRecord (record, type); + mIdCollection->appendRecord (std::move(record), type); endInsertRows(); } else { - mIdCollection->replace (index, record); + mIdCollection->replace (index, std::move(record)); emit dataChanged (CSMWorld::IdTable::index (index, 0), CSMWorld::IdTable::index (index, mIdCollection->getColumns()-1)); } diff --git a/apps/opencs/model/world/idtable.hpp b/apps/opencs/model/world/idtable.hpp index 9ecba0214..7219e5a48 100644 --- a/apps/opencs/model/world/idtable.hpp +++ b/apps/opencs/model/world/idtable.hpp @@ -2,6 +2,7 @@ #define CSM_WOLRD_IDTABLE_H #include +#include #include "idtablebase.hpp" #include "universalid.hpp" @@ -59,7 +60,7 @@ namespace CSMWorld virtual QModelIndex getModelIndex (const std::string& id, int column) const; - void setRecord (const std::string& id, const RecordBase& record, + void setRecord (const std::string& id, std::unique_ptr record, UniversalId::Type type = UniversalId::Type_None); ///< Add record or overwrite existing recrod. diff --git a/apps/opencs/model/world/infocollection.cpp b/apps/opencs/model/world/infocollection.cpp index 083d07da0..c331a2d73 100644 --- a/apps/opencs/model/world/infocollection.cpp +++ b/apps/opencs/model/world/infocollection.cpp @@ -15,25 +15,25 @@ void CSMWorld::InfoCollection::load (const Info& record, bool base) if (index==-1) { // new record - Record record2; - record2.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly; - (base ? record2.mBase : record2.mModified) = record; + std::unique_ptr > record2(new Record); + record2->mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly; + (base ? record2->mBase : record2->mModified) = record; int index2 = -1; - std::string topic = Misc::StringUtils::lowerCase (record2.get().mTopicId); + std::string topic = Misc::StringUtils::lowerCase (record2->get().mTopicId); - if (!record2.get().mPrev.empty()) + if (!record2->get().mPrev.empty()) { - index2 = getInfoIndex (record2.get().mPrev, topic); + index2 = getInfoIndex (record2->get().mPrev, topic); if (index2!=-1) ++index2; } - if (index2==-1 && !record2.get().mNext.empty()) + if (index2==-1 && !record2->get().mNext.empty()) { - index2 = getInfoIndex (record2.get().mNext, topic); + index2 = getInfoIndex (record2->get().mNext, topic); } if (index2==-1) @@ -43,19 +43,19 @@ void CSMWorld::InfoCollection::load (const Info& record, bool base) index2 = std::distance (getRecords().begin(), range.second); } - insertRecord (record2, index2); + insertRecord (std::move(record2), index2); } else { // old record - Record record2 = getRecord (index); + std::unique_ptr > record2(new Record(getRecord(index))); if (base) - record2.mBase = record; + record2->mBase = record; else - record2.setModified (record); + record2->setModified (record); - setRecord (index, record2); + setRecord (index, std::move(record2)); } } @@ -66,7 +66,7 @@ int CSMWorld::InfoCollection::getInfoIndex (const std::string& id, const std::st std::pair range = getTopicRange (topic); for (; range.first!=range.second; ++range.first) - if (Misc::StringUtils::ciEqual(range.first->get().mId, fullId)) + if (Misc::StringUtils::ciEqual((*range.first).get()->get().mId, fullId)) return std::distance (getRecords().begin(), range.first); return -1; @@ -128,9 +128,9 @@ void CSMWorld::InfoCollection::load (ESM::ESMReader& reader, bool base, const ES } else { - Record record = getRecord (index); - record.mState = RecordBase::State_Deleted; - setRecord (index, record); + std::unique_ptr > record(new Record(getRecord(index))); + record->mState = RecordBase::State_Deleted; + setRecord (index, std::move(record)); } } else @@ -171,7 +171,7 @@ CSMWorld::InfoCollection::Range CSMWorld::InfoCollection::getTopicRange (const s while (begin != getRecords().begin()) { - if (!Misc::StringUtils::ciEqual(begin->get().mTopicId, topic2)) + if (!Misc::StringUtils::ciEqual((*begin)->get().mTopicId, topic2)) { // we've gone one too far, go back ++begin; @@ -184,7 +184,7 @@ CSMWorld::InfoCollection::Range CSMWorld::InfoCollection::getTopicRange (const s RecordConstIterator end = begin; for (; end!=getRecords().end(); ++end) - if (!Misc::StringUtils::ciEqual(end->get().mTopicId, topic2)) + if (!Misc::StringUtils::ciEqual((*end)->get().mTopicId, topic2)) break; return Range (begin, end); @@ -199,7 +199,7 @@ void CSMWorld::InfoCollection::removeDialogueInfos(const std::string& dialogueId std::map::const_iterator end = getIdMap().end(); for (; current != end; ++current) { - Record record = getRecord(current->second); + const Record& record = getRecord(current->second); if (Misc::StringUtils::ciEqual(dialogueId, record.get().mTopicId)) { @@ -209,8 +209,9 @@ void CSMWorld::InfoCollection::removeDialogueInfos(const std::string& dialogueId } else { - record.mState = RecordBase::State_Deleted; - setRecord(current->second, record); + std::unique_ptr > record2(new Record(record)); + record2->mState = RecordBase::State_Deleted; + setRecord(current->second, std::move(record2)); } } else diff --git a/apps/opencs/model/world/infocollection.hpp b/apps/opencs/model/world/infocollection.hpp index e5a5575c7..da389763c 100644 --- a/apps/opencs/model/world/infocollection.hpp +++ b/apps/opencs/model/world/infocollection.hpp @@ -15,7 +15,7 @@ namespace CSMWorld { public: - typedef std::vector >::const_iterator RecordConstIterator; + typedef std::vector > >::const_iterator RecordConstIterator; typedef std::pair Range; private: diff --git a/apps/opencs/model/world/nestedidcollection.hpp b/apps/opencs/model/world/nestedidcollection.hpp index 56b112365..08ed70d42 100644 --- a/apps/opencs/model/world/nestedidcollection.hpp +++ b/apps/opencs/model/world/nestedidcollection.hpp @@ -90,23 +90,23 @@ namespace CSMWorld template void NestedIdCollection::addNestedRow(int row, int column, int position) { - Record record; - record.assign(Collection::getRecord(row)); + std::unique_ptr > record(new Record); + record->assign(Collection::getRecord(row)); - getAdapter(Collection::getColumn(column)).addRow(record, position); + getAdapter(Collection::getColumn(column)).addRow(*record, position); - Collection::setRecord(row, record); + Collection::setRecord(row, std::move(record)); } template void NestedIdCollection::removeNestedRows(int row, int column, int subRow) { - Record record; - record.assign(Collection::getRecord(row)); + std::unique_ptr > record(new Record); + record->assign(Collection::getRecord(row)); - getAdapter(Collection::getColumn(column)).removeRow(record, subRow); + getAdapter(Collection::getColumn(column)).removeRow(*record, subRow); - Collection::setRecord(row, record); + Collection::setRecord(row, std::move(record)); } template @@ -121,13 +121,13 @@ namespace CSMWorld void NestedIdCollection::setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn) { - Record record; - record.assign(Collection::getRecord(row)); + std::unique_ptr > record(new Record); + record->assign(Collection::getRecord(row)); getAdapter(Collection::getColumn(column)).setData( - record, data, subRow, subColumn); + *record, data, subRow, subColumn); - Collection::setRecord(row, record); + Collection::setRecord(row, std::move(record)); } template @@ -142,13 +142,13 @@ namespace CSMWorld void NestedIdCollection::setNestedTable(int row, int column, const CSMWorld::NestedTableWrapperBase& nestedTable) { - Record record; - record.assign(Collection::getRecord(row)); + std::unique_ptr > record(new Record); + record->assign(Collection::getRecord(row)); getAdapter(Collection::getColumn(column)).setTable( - record, nestedTable); + *record, nestedTable); - Collection::setRecord(row, record); + Collection::setRecord(row, std::move(record)); } template diff --git a/apps/opencs/model/world/nestedinfocollection.cpp b/apps/opencs/model/world/nestedinfocollection.cpp index 4abaaf9c0..d404bb9a6 100644 --- a/apps/opencs/model/world/nestedinfocollection.cpp +++ b/apps/opencs/model/world/nestedinfocollection.cpp @@ -35,22 +35,22 @@ namespace CSMWorld void NestedInfoCollection::addNestedRow(int row, int column, int position) { - Record record; - record.assign(Collection >::getRecord(row)); + std::unique_ptr > record(new Record); + record->assign(Collection >::getRecord(row)); - getAdapter(Collection >::getColumn(column)).addRow(record, position); + getAdapter(Collection >::getColumn(column)).addRow(*record, position); - Collection >::setRecord(row, record); + Collection >::setRecord(row, std::move(record)); } void NestedInfoCollection::removeNestedRows(int row, int column, int subRow) { - Record record; - record.assign(Collection >::getRecord(row)); + std::unique_ptr > record(new Record); + record->assign(Collection >::getRecord(row)); - getAdapter(Collection >::getColumn(column)).removeRow(record, subRow); + getAdapter(Collection >::getColumn(column)).removeRow(*record, subRow); - Collection >::setRecord(row, record); + Collection >::setRecord(row, std::move(record)); } QVariant NestedInfoCollection::getNestedData (int row, @@ -63,13 +63,13 @@ namespace CSMWorld void NestedInfoCollection::setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn) { - Record record; - record.assign(Collection >::getRecord(row)); + std::unique_ptr > record(new Record); + record->assign(Collection >::getRecord(row)); getAdapter(Collection >::getColumn(column)).setData( - record, data, subRow, subColumn); + *record, data, subRow, subColumn); - Collection >::setRecord(row, record); + Collection >::setRecord(row, std::move(record)); } CSMWorld::NestedTableWrapperBase* NestedInfoCollection::nestedTable(int row, @@ -82,13 +82,13 @@ namespace CSMWorld void NestedInfoCollection::setNestedTable(int row, int column, const CSMWorld::NestedTableWrapperBase& nestedTable) { - Record record; - record.assign(Collection >::getRecord(row)); + std::unique_ptr > record(new Record); + record->assign(Collection >::getRecord(row)); getAdapter(Collection >::getColumn(column)).setTable( - record, nestedTable); + *record, nestedTable); - Collection >::setRecord(row, record); + Collection >::setRecord(row, std::move(record)); } int NestedInfoCollection::getNestedRowsCount(int row, int column) const diff --git a/apps/opencs/model/world/record.hpp b/apps/opencs/model/world/record.hpp index 3362f9f96..91e4c3c42 100644 --- a/apps/opencs/model/world/record.hpp +++ b/apps/opencs/model/world/record.hpp @@ -1,6 +1,7 @@ #ifndef CSM_WOLRD_RECORD_H #define CSM_WOLRD_RECORD_H +#include #include namespace CSMWorld @@ -20,9 +21,9 @@ namespace CSMWorld virtual ~RecordBase(); - virtual RecordBase *clone() const = 0; + virtual std::unique_ptr clone() const = 0; - virtual RecordBase *modifiedCopy() const = 0; + virtual std::unique_ptr modifiedCopy() const = 0; virtual void assign (const RecordBase& record) = 0; ///< Will throw an exception if the types don't match. @@ -45,9 +46,9 @@ namespace CSMWorld Record(State state, const ESXRecordT *base = 0, const ESXRecordT *modified = 0); - virtual RecordBase *clone() const; + virtual std::unique_ptr clone() const; - virtual RecordBase *modifiedCopy() const; + virtual std::unique_ptr modifiedCopy() const; virtual void assign (const RecordBase& record); @@ -85,15 +86,16 @@ namespace CSMWorld } template - RecordBase *Record::modifiedCopy() const + std::unique_ptr Record::modifiedCopy() const { - return new Record (State_ModifiedOnly, 0, &(this->get())); + return std::make_unique >( + Record(State_ModifiedOnly, 0, &(this->get()))); } template - RecordBase *Record::clone() const + std::unique_ptr Record::clone() const { - return new Record (*this); + return std::make_unique >(Record(*this)); } template diff --git a/apps/opencs/model/world/refcollection.cpp b/apps/opencs/model/world/refcollection.cpp index 3f3688fb7..2568a5120 100644 --- a/apps/opencs/model/world/refcollection.cpp +++ b/apps/opencs/model/world/refcollection.cpp @@ -92,8 +92,6 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool int index = getIndex (iter->second); - Record record = getRecord (index); - if (base) { removeRows (index, 1); @@ -101,8 +99,9 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool } else { - record.mState = RecordBase::State_Deleted; - setRecord (index, record); + std::unique_ptr > record2(new Record(getRecord(index))); + record2->mState = RecordBase::State_Deleted; + setRecord(index, std::move(record2)); } continue; @@ -113,11 +112,11 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool // new reference ref.mId = getNewId(); - Record record; - record.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly; - (base ? record.mBase : record.mModified) = ref; + std::unique_ptr > record(new Record); + record->mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly; + (base ? record->mBase : record->mModified) = ref; - appendRecord (record); + appendRecord(std::move(record)); cache.insert (std::make_pair (ref.mRefNum, ref.mId)); } @@ -128,11 +127,11 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool int index = getIndex (ref.mId); - Record record = getRecord (index); - record.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_Modified; - (base ? record.mBase : record.mModified) = ref; + std::unique_ptr > record(new Record(getRecord(index))); + record->mState = base ? RecordBase::State_BaseOnly : RecordBase::State_Modified; + (base ? record->mBase : record->mModified) = ref; - setRecord (index, record); + setRecord(index, std::move(record)); } } } diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 9560539b2..7737e62c0 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -810,30 +810,31 @@ int CSMWorld::RefIdCollection::searchId (const std::string& id) const return mData.localToGlobalIndex (localIndex); } -void CSMWorld::RefIdCollection::replace (int index, const RecordBase& record) +void CSMWorld::RefIdCollection::replace (int index, std::unique_ptr record) { - mData.getRecord (mData.globalToLocalIndex (index)).assign (record); + mData.getRecord (mData.globalToLocalIndex (index)).assign (*record.release()); } void CSMWorld::RefIdCollection::cloneRecord(const std::string& origin, const std::string& destination, const CSMWorld::UniversalId::Type type) { - std::auto_ptr newRecord(mData.getRecord(mData.searchId(origin)).modifiedCopy()); + std::unique_ptr newRecord = + std::move(mData.getRecord(mData.searchId(origin)).modifiedCopy()); mAdapters.find(type)->second->setId(*newRecord, destination); - mData.insertRecord(*newRecord, type, destination); + mData.insertRecord(std::move(newRecord), type, destination); } -void CSMWorld::RefIdCollection::appendRecord (const RecordBase& record, +void CSMWorld::RefIdCollection::appendRecord (std::unique_ptr record, UniversalId::Type type) { - std::string id = findAdapter (type).getId (record); + std::string id = findAdapter (type).getId (*record.get()); int index = mData.getAppendIndex (type); mData.appendRecord (type, id, false); - mData.getRecord (mData.globalToLocalIndex (index)).assign (record); + mData.getRecord (mData.globalToLocalIndex (index)).assign (*record.release()); } const CSMWorld::RecordBase& CSMWorld::RefIdCollection::getRecord (const std::string& id) const diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index 4db39348e..f749e7df7 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -89,12 +89,12 @@ namespace CSMWorld ////< Search record with \a id. /// \return index of record (if found) or -1 (not found) - virtual void replace (int index, const RecordBase& record); + virtual void replace (int index, std::unique_ptr record); ///< If the record type does not match, an exception is thrown. /// /// \attention \a record must not change the ID. - virtual void appendRecord (const RecordBase& record, UniversalId::Type type); + virtual void appendRecord (std::unique_ptr record, UniversalId::Type type); ///< If the record type does not match, an exception is thrown. /// ///< \param type Will be ignored, unless the collection supports multiple record types diff --git a/apps/opencs/model/world/refiddata.cpp b/apps/opencs/model/world/refiddata.cpp index 2d8c9ac10..298a62021 100644 --- a/apps/opencs/model/world/refiddata.cpp +++ b/apps/opencs/model/world/refiddata.cpp @@ -367,7 +367,7 @@ const CSMWorld::RefIdDataContainer< ESM::Static >& CSMWorld::RefIdData::getStati return mStatics; } -void CSMWorld::RefIdData::insertRecord (CSMWorld::RecordBase& record, CSMWorld::UniversalId::Type type, const std::string& id) +void CSMWorld::RefIdData::insertRecord (std::unique_ptr record, CSMWorld::UniversalId::Type type, const std::string& id) { std::map::iterator iter = mRecordContainers.find (type); @@ -375,7 +375,7 @@ void CSMWorld::RefIdData::insertRecord (CSMWorld::RecordBase& record, CSMWorld:: if (iter==mRecordContainers.end()) throw std::logic_error ("invalid local index type"); - iter->second->insertRecord(record); + iter->second->insertRecord(std::move(record)); mIndex.insert (std::make_pair (Misc::StringUtils::lowerCase (id), LocalIndex (iter->second->getSize()-1, type))); @@ -387,9 +387,7 @@ void CSMWorld::RefIdData::copyTo (int index, RefIdData& target) const RefIdDataContainerBase *source = mRecordContainers.find (localIndex.second)->second; - std::string id = source->getId (localIndex.first); - - std::auto_ptr newRecord (source->getRecord (localIndex.first).modifiedCopy()); - - target.insertRecord (*newRecord, localIndex.second, id); + target.insertRecord(source->getRecord(localIndex.first).modifiedCopy(), + localIndex.second, + source->getId(localIndex.first)); } diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index 59cad6a66..4a0900e6d 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -49,7 +50,7 @@ namespace CSMWorld virtual void appendRecord (const std::string& id, bool base) = 0; - virtual void insertRecord (RecordBase& record) = 0; + virtual void insertRecord (std::unique_ptr record) = 0; virtual int load (ESM::ESMReader& reader, bool base) = 0; ///< \return index of a loaded record or -1 if no record was loaded @@ -64,7 +65,7 @@ namespace CSMWorld template struct RefIdDataContainer : public RefIdDataContainerBase { - std::vector > mContainer; + std::vector > > mContainer; virtual int getSize() const; @@ -74,7 +75,7 @@ namespace CSMWorld virtual void appendRecord (const std::string& id, bool base); - virtual void insertRecord (RecordBase& record); + virtual void insertRecord (std::unique_ptr record); virtual int load (ESM::ESMReader& reader, bool base); ///< \return index of a loaded record or -1 if no record was loaded @@ -87,10 +88,18 @@ namespace CSMWorld }; template - void RefIdDataContainer::insertRecord(RecordBase& record) + void RefIdDataContainer::insertRecord(std::unique_ptr record) { - Record& newRecord = dynamic_cast& >(record); - mContainer.push_back(newRecord); + Record *tmp = dynamic_cast*>(record.get()); + if(tmp != nullptr) + { + record.release(); + std::unique_ptr > newRecord; + newRecord.reset(tmp); + mContainer.push_back(std::move(newRecord)); + } + else + throw std::runtime_error ("invalid record for RefIdDataContainer"); } template @@ -102,27 +111,27 @@ namespace CSMWorld template const RecordBase& RefIdDataContainer::getRecord (int index) const { - return mContainer.at (index); + return *mContainer.at (index); } template RecordBase& RefIdDataContainer::getRecord (int index) { - return mContainer.at (index); + return *mContainer.at (index); } template void RefIdDataContainer::appendRecord (const std::string& id, bool base) { - Record record; + std::unique_ptr > record(new Record); - record.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly; + record->mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly; - record.mBase.mId = id; - record.mModified.mId = id; - (base ? record.mBase : record.mModified).blank(); + record->mBase.mId = id; + record->mModified.mId = id; + (base ? record->mBase : record->mModified).blank(); - mContainer.push_back (record); + mContainer.push_back (std::move(record)); } template @@ -137,7 +146,7 @@ namespace CSMWorld int numRecords = static_cast(mContainer.size()); for (; index < numRecords; ++index) { - if (Misc::StringUtils::ciEqual(mContainer[index].get().mId, record.mId)) + if (Misc::StringUtils::ciEqual(mContainer[index]->get().mId, record.mId)) { break; } @@ -155,7 +164,7 @@ namespace CSMWorld // Flag the record as Deleted even for a base content file. // RefIdData is responsible for its erasure. - mContainer[index].mState = RecordBase::State_Deleted; + mContainer[index]->mState = RecordBase::State_Deleted; } else { @@ -164,16 +173,16 @@ namespace CSMWorld appendRecord(record.mId, base); if (base) { - mContainer.back().mBase = record; + mContainer.back()->mBase = record; } else { - mContainer.back().mModified = record; + mContainer.back()->mModified = record; } } else if (!base) { - mContainer[index].setModified(record); + mContainer[index]->setModified(record); } } @@ -192,13 +201,13 @@ namespace CSMWorld template std::string RefIdDataContainer::getId (int index) const { - return mContainer.at (index).get().mId; + return mContainer.at (index)->get().mId; } template void RefIdDataContainer::save (int index, ESM::ESMWriter& writer) const { - Record record = mContainer.at(index); + const Record& record = *mContainer.at(index); if (record.isModified() || record.mState == RecordBase::State_Deleted) { @@ -260,7 +269,7 @@ namespace CSMWorld void erase (int index, int count); - void insertRecord (CSMWorld::RecordBase& record, CSMWorld::UniversalId::Type type, + void insertRecord (std::unique_ptr record, CSMWorld::UniversalId::Type type, const std::string& id); const RecordBase& getRecord (const LocalIndex& index) const;