mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-25 11:26:37 +00:00 
			
		
		
		
	Merge branch 'string_to_ref_id' into 'master'
Replace std::string and std::string_view by ESM::RefId to avoid getRefIdString call See merge request OpenMW/openmw!2790
This commit is contained in:
		
						commit
						2f4eb3e299
					
				
					 25 changed files with 249 additions and 79 deletions
				
			
		|  | @ -236,7 +236,7 @@ CSMDoc::CollectionReferencesStage::CollectionReferencesStage(Document& document, | ||||||
| 
 | 
 | ||||||
| int CSMDoc::CollectionReferencesStage::setup() | int CSMDoc::CollectionReferencesStage::setup() | ||||||
| { | { | ||||||
|     mState.getSubRecords().clear(); |     mState.clearSubRecords(); | ||||||
| 
 | 
 | ||||||
|     int size = mDocument.getData().getReferences().getSize(); |     int size = mDocument.getData().getReferences().getSize(); | ||||||
| 
 | 
 | ||||||
|  | @ -260,7 +260,7 @@ void CSMDoc::CollectionReferencesStage::perform(int stage, Messages& messages) | ||||||
|             const ESM::RefId& cellId |             const ESM::RefId& cellId | ||||||
|                 = record.get().mOriginalCell.empty() ? record.get().mCell : record.get().mOriginalCell; |                 = record.get().mOriginalCell.empty() ? record.get().mCell : record.get().mOriginalCell; | ||||||
| 
 | 
 | ||||||
|             std::deque<int>& indices = mState.getSubRecords()[cellId.getRefIdString()]; |             std::deque<int>& indices = mState.getOrInsertSubRecord(cellId); | ||||||
| 
 | 
 | ||||||
|             // collect moved references at the end of the container
 |             // collect moved references at the end of the container
 | ||||||
|             const bool interior = !cellId.startsWith("#"); |             const bool interior = !cellId.startsWith("#"); | ||||||
|  | @ -360,11 +360,9 @@ void CSMDoc::WriteCellCollectionStage::perform(int stage, Messages& messages) | ||||||
|     std::deque<int> tempRefs; |     std::deque<int> tempRefs; | ||||||
|     std::deque<int> persistentRefs; |     std::deque<int> persistentRefs; | ||||||
| 
 | 
 | ||||||
|     std::map<std::string, std::deque<int>>::const_iterator references |     const std::deque<int>* references = mState.findSubRecord(cell.get().mId); | ||||||
|         = mState.getSubRecords().find(cell.get().mId.getRefIdString()); |  | ||||||
| 
 | 
 | ||||||
|     if (cell.isModified() || cell.mState == CSMWorld::RecordBase::State_Deleted |     if (cell.isModified() || cell.mState == CSMWorld::RecordBase::State_Deleted || references != nullptr) | ||||||
|         || references != mState.getSubRecords().end()) |  | ||||||
|     { |     { | ||||||
|         CSMWorld::Cell cellRecord = cell.get(); |         CSMWorld::Cell cellRecord = cell.get(); | ||||||
|         const bool interior = !cellRecord.mId.startsWith("#"); |         const bool interior = !cellRecord.mId.startsWith("#"); | ||||||
|  | @ -372,10 +370,9 @@ void CSMDoc::WriteCellCollectionStage::perform(int stage, Messages& messages) | ||||||
|         // count new references and adjust RefNumCount accordingsly
 |         // count new references and adjust RefNumCount accordingsly
 | ||||||
|         unsigned int newRefNum = cellRecord.mRefNumCounter; |         unsigned int newRefNum = cellRecord.mRefNumCounter; | ||||||
| 
 | 
 | ||||||
|         if (references != mState.getSubRecords().end()) |         if (references != nullptr) | ||||||
|         { |         { | ||||||
|             for (std::deque<int>::const_iterator iter(references->second.begin()); iter != references->second.end(); |             for (std::deque<int>::const_iterator iter(references->begin()); iter != references->end(); ++iter) | ||||||
|                  ++iter) |  | ||||||
|             { |             { | ||||||
|                 const CSMWorld::Record<CSMWorld::CellRef>& ref = mDocument.getData().getReferences().getRecord(*iter); |                 const CSMWorld::Record<CSMWorld::CellRef>& ref = mDocument.getData().getReferences().getRecord(*iter); | ||||||
| 
 | 
 | ||||||
|  | @ -421,10 +418,10 @@ void CSMDoc::WriteCellCollectionStage::perform(int stage, Messages& messages) | ||||||
|         cellRecord.save(writer, cell.mState == CSMWorld::RecordBase::State_Deleted); |         cellRecord.save(writer, cell.mState == CSMWorld::RecordBase::State_Deleted); | ||||||
| 
 | 
 | ||||||
|         // write references
 |         // write references
 | ||||||
|         if (references != mState.getSubRecords().end()) |         if (references != nullptr) | ||||||
|         { |         { | ||||||
|             writeReferences(persistentRefs, interior, newRefNum); |             writeReferences(persistentRefs, interior, newRefNum); | ||||||
|             cellRecord.saveTempMarker(writer, int(references->second.size()) - persistentRefs.size()); |             cellRecord.saveTempMarker(writer, static_cast<int>(references->size()) - persistentRefs.size()); | ||||||
|             writeReferences(tempRefs, interior, newRefNum); |             writeReferences(tempRefs, interior, newRefNum); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -68,7 +68,20 @@ bool CSMDoc::SavingState::isProjectFile() const | ||||||
|     return mProjectFile; |     return mProjectFile; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::map<std::string, std::deque<int>, Misc::StringUtils::CiComp>& CSMDoc::SavingState::getSubRecords() | const std::deque<int>* CSMDoc::SavingState::findSubRecord(const ESM::RefId& refId) const | ||||||
| { | { | ||||||
|     return mSubRecords; |     const auto it = mSubRecords.find(refId); | ||||||
|  |     if (it == mSubRecords.end()) | ||||||
|  |         return nullptr; | ||||||
|  |     return &it->second; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::deque<int>& CSMDoc::SavingState::getOrInsertSubRecord(const ESM::RefId& refId) | ||||||
|  | { | ||||||
|  |     return mSubRecords[refId]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void CSMDoc::SavingState::clearSubRecords() | ||||||
|  | { | ||||||
|  |     mSubRecords.clear(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -8,9 +8,9 @@ | ||||||
| #include <string> | #include <string> | ||||||
| 
 | 
 | ||||||
| #include <components/esm3/esmwriter.hpp> | #include <components/esm3/esmwriter.hpp> | ||||||
| 
 |  | ||||||
| #include <components/misc/algorithm.hpp> | #include <components/misc/algorithm.hpp> | ||||||
| #include <components/to_utf8/to_utf8.hpp> | #include <components/to_utf8/to_utf8.hpp> | ||||||
|  | 
 | ||||||
| namespace CSMDoc | namespace CSMDoc | ||||||
| { | { | ||||||
|     class Operation; |     class Operation; | ||||||
|  | @ -26,7 +26,7 @@ namespace CSMDoc | ||||||
|         ESM::ESMWriter mWriter; |         ESM::ESMWriter mWriter; | ||||||
|         std::filesystem::path mProjectPath; |         std::filesystem::path mProjectPath; | ||||||
|         bool mProjectFile; |         bool mProjectFile; | ||||||
|         std::map<std::string, std::deque<int>, Misc::StringUtils::CiComp> mSubRecords; // record ID, list of subrecords
 |         std::map<ESM::RefId, std::deque<int>> mSubRecords; // record ID, list of subrecords
 | ||||||
| 
 | 
 | ||||||
|     public: |     public: | ||||||
|         SavingState(Operation& operation, std::filesystem::path projectPath, ToUTF8::FromType encoding); |         SavingState(Operation& operation, std::filesystem::path projectPath, ToUTF8::FromType encoding); | ||||||
|  | @ -47,7 +47,11 @@ namespace CSMDoc | ||||||
|         bool isProjectFile() const; |         bool isProjectFile() const; | ||||||
|         ///< Currently saving project file? (instead of content file)
 |         ///< Currently saving project file? (instead of content file)
 | ||||||
| 
 | 
 | ||||||
|         std::map<std::string, std::deque<int>, Misc::StringUtils::CiComp>& getSubRecords(); |         const std::deque<int>* findSubRecord(const ESM::RefId& refId) const; | ||||||
|  | 
 | ||||||
|  |         std::deque<int>& getOrInsertSubRecord(const ESM::RefId& refId); | ||||||
|  | 
 | ||||||
|  |         void clearSubRecords(); | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -15,7 +15,6 @@ | ||||||
| 
 | 
 | ||||||
| #include <components/esm3/cellref.hpp> | #include <components/esm3/cellref.hpp> | ||||||
| #include <components/esm3/esmreader.hpp> | #include <components/esm3/esmreader.hpp> | ||||||
| #include <components/misc/strings/lower.hpp> |  | ||||||
| 
 | 
 | ||||||
| #include "mergestate.hpp" | #include "mergestate.hpp" | ||||||
| 
 | 
 | ||||||
|  | @ -117,7 +116,7 @@ void CSMTools::MergeReferencesStage::perform(int stage, CSMDoc::Messages& messag | ||||||
| 
 | 
 | ||||||
|         ref.mOriginalCell = ref.mCell; |         ref.mOriginalCell = ref.mCell; | ||||||
| 
 | 
 | ||||||
|         ref.mRefNum.mIndex = mIndex[Misc::StringUtils::lowerCase(ref.mCell.getRefIdString())]++; |         ref.mRefNum.mIndex = mIndex[ref.mCell]++; | ||||||
|         ref.mRefNum.mContentFile = 0; |         ref.mRefNum.mContentFile = 0; | ||||||
|         ref.mNew = false; |         ref.mNew = false; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -113,7 +113,7 @@ namespace CSMTools | ||||||
|     class MergeReferencesStage : public CSMDoc::Stage |     class MergeReferencesStage : public CSMDoc::Stage | ||||||
|     { |     { | ||||||
|         MergeState& mState; |         MergeState& mState; | ||||||
|         std::map<std::string, int> mIndex; |         std::map<ESM::RefId, int> mIndex; | ||||||
| 
 | 
 | ||||||
|     public: |     public: | ||||||
|         MergeReferencesStage(MergeState& state); |         MergeReferencesStage(MergeState& state); | ||||||
|  |  | ||||||
|  | @ -136,7 +136,7 @@ namespace CSMWorld | ||||||
|         return SceneUtil::getActorSkeleton(firstPerson, mFemale, beast, werewolf); |         return SceneUtil::getActorSkeleton(firstPerson, mFemale, beast, werewolf); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     std::string_view ActorAdapter::ActorData::getPart(ESM::PartReferenceType index) const |     ESM::RefId ActorAdapter::ActorData::getPart(ESM::PartReferenceType index) const | ||||||
|     { |     { | ||||||
|         auto it = mParts.find(index); |         auto it = mParts.find(index); | ||||||
|         if (it == mParts.end()) |         if (it == mParts.end()) | ||||||
|  | @ -146,12 +146,11 @@ namespace CSMWorld | ||||||
|                 if (mFemale) |                 if (mFemale) | ||||||
|                 { |                 { | ||||||
|                     // Note: we should use male parts for females as fallback
 |                     // Note: we should use male parts for females as fallback
 | ||||||
|                     const std::string& femalePart = mRaceData->getFemalePart(index).getRefIdString(); |                     if (const ESM::RefId femalePart = mRaceData->getFemalePart(index); !femalePart.empty()) | ||||||
|                     if (!femalePart.empty()) |  | ||||||
|                         return femalePart; |                         return femalePart; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 return mRaceData->getMalePart(index).getRefIdString(); |                 return mRaceData->getMalePart(index); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             return {}; |             return {}; | ||||||
|  | @ -174,7 +173,7 @@ namespace CSMWorld | ||||||
|                 return; |                 return; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         mParts[index] = std::make_pair(partId.getRefIdString(), priority); |         mParts[index] = std::make_pair(partId, priority); | ||||||
|         addOtherDependency(partId); |         addOtherDependency(partId); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -35,7 +35,7 @@ namespace CSMWorld | ||||||
|         Q_OBJECT |         Q_OBJECT | ||||||
|     public: |     public: | ||||||
|         /// A list indexed by ESM::PartReferenceType
 |         /// A list indexed by ESM::PartReferenceType
 | ||||||
|         using ActorPartList = std::map<ESM::PartReferenceType, std::pair<std::string, int>>; |         using ActorPartList = std::map<ESM::PartReferenceType, std::pair<ESM::RefId, int>>; | ||||||
|         /// A list indexed by ESM::BodyPart::MeshPart
 |         /// A list indexed by ESM::BodyPart::MeshPart
 | ||||||
|         using RacePartList = std::array<ESM::RefId, ESM::BodyPart::MP_Count>; |         using RacePartList = std::array<ESM::RefId, ESM::BodyPart::MP_Count>; | ||||||
|         /// Tracks unique strings
 |         /// Tracks unique strings
 | ||||||
|  | @ -95,7 +95,7 @@ namespace CSMWorld | ||||||
|             /// Returns the skeleton the actor should use for attaching parts to
 |             /// Returns the skeleton the actor should use for attaching parts to
 | ||||||
|             std::string getSkeleton() const; |             std::string getSkeleton() const; | ||||||
|             /// Retrieves the associated actor part
 |             /// Retrieves the associated actor part
 | ||||||
|             std::string_view getPart(ESM::PartReferenceType index) const; |             ESM::RefId getPart(ESM::PartReferenceType index) const; | ||||||
|             /// Checks if the actor has a data dependency
 |             /// Checks if the actor has a data dependency
 | ||||||
|             bool hasDependency(const ESM::RefId& id) const; |             bool hasDependency(const ESM::RefId& id) const; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -6,6 +6,7 @@ | ||||||
| 
 | 
 | ||||||
| #include <osg/Vec3d> | #include <osg/Vec3d> | ||||||
| 
 | 
 | ||||||
|  | #include <components/esm/refid.hpp> | ||||||
| #include <components/esm3/loadland.hpp> | #include <components/esm3/loadland.hpp> | ||||||
| #include <components/misc/constants.hpp> | #include <components/misc/constants.hpp> | ||||||
| 
 | 
 | ||||||
|  | @ -59,6 +60,11 @@ bool CSMWorld::CellCoordinates::isExteriorCell(const std::string& id) | ||||||
|     return (!id.empty() && id[0] == '#'); |     return (!id.empty() && id[0] == '#'); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool CSMWorld::CellCoordinates::isExteriorCell(const ESM::RefId& id) | ||||||
|  | { | ||||||
|  |     return id.startsWith("#"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| std::pair<CSMWorld::CellCoordinates, bool> CSMWorld::CellCoordinates::fromId(const std::string& id) | std::pair<CSMWorld::CellCoordinates, bool> CSMWorld::CellCoordinates::fromId(const std::string& id) | ||||||
| { | { | ||||||
|     // no worldspace for now, needs to be changed for 1.1
 |     // no worldspace for now, needs to be changed for 1.1
 | ||||||
|  |  | ||||||
|  | @ -12,6 +12,11 @@ namespace osg | ||||||
|     class Vec3d; |     class Vec3d; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | namespace ESM | ||||||
|  | { | ||||||
|  |     class RefId; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| namespace CSMWorld | namespace CSMWorld | ||||||
| { | { | ||||||
|     class CellCoordinates |     class CellCoordinates | ||||||
|  | @ -41,6 +46,8 @@ namespace CSMWorld | ||||||
| 
 | 
 | ||||||
|         static bool isExteriorCell(const std::string& id); |         static bool isExteriorCell(const std::string& id); | ||||||
| 
 | 
 | ||||||
|  |         static bool isExteriorCell(const ESM::RefId& id); | ||||||
|  | 
 | ||||||
|         /// \return first: CellCoordinates (or 0, 0 if cell does not have coordinates),
 |         /// \return first: CellCoordinates (or 0, 0 if cell does not have coordinates),
 | ||||||
|         /// second: is cell paged?
 |         /// second: is cell paged?
 | ||||||
|         ///
 |         ///
 | ||||||
|  |  | ||||||
|  | @ -91,10 +91,10 @@ namespace CSMWorld | ||||||
|         ///
 |         ///
 | ||||||
|         /// \return Success?
 |         /// \return Success?
 | ||||||
| 
 | 
 | ||||||
|         int cloneRecordImp(const std::string& origin, const std::string& dest, UniversalId::Type type); |         int cloneRecordImp(const ESM::RefId& origin, const ESM::RefId& dest, UniversalId::Type type); | ||||||
|         ///< Returns the index of the clone.
 |         ///< Returns the index of the clone.
 | ||||||
| 
 | 
 | ||||||
|         int touchRecordImp(const std::string& id); |         int touchRecordImp(const ESM::RefId& id); | ||||||
|         ///< Returns the index of the record on success, -1 on failure.
 |         ///< Returns the index of the record on success, -1 on failure.
 | ||||||
| 
 | 
 | ||||||
|     public: |     public: | ||||||
|  | @ -227,29 +227,28 @@ namespace CSMWorld | ||||||
| 
 | 
 | ||||||
|     template <typename ESXRecordT> |     template <typename ESXRecordT> | ||||||
|     int Collection<ESXRecordT>::cloneRecordImp( |     int Collection<ESXRecordT>::cloneRecordImp( | ||||||
|         const std::string& origin, const std::string& destination, UniversalId::Type type) |         const ESM::RefId& origin, const ESM::RefId& destination, UniversalId::Type type) | ||||||
|     { |     { | ||||||
|         auto copy = std::make_unique<Record<ESXRecordT>>(); |         auto copy = std::make_unique<Record<ESXRecordT>>(); | ||||||
|         copy->mModified = getRecord(ESM::RefId::stringRefId(origin)).get(); |         copy->mModified = getRecord(origin).get(); | ||||||
|         copy->mState = RecordBase::State_ModifiedOnly; |         copy->mState = RecordBase::State_ModifiedOnly; | ||||||
|         setRecordId(ESM::RefId::stringRefId(destination), copy->get()); |         setRecordId(destination, copy->get()); | ||||||
| 
 | 
 | ||||||
|         if (type == UniversalId::Type_Reference) |         if (type == UniversalId::Type_Reference) | ||||||
|         { |         { | ||||||
|             CSMWorld::CellRef* ptr = (CSMWorld::CellRef*)©->mModified; |             CSMWorld::CellRef* ptr = (CSMWorld::CellRef*)©->mModified; | ||||||
|             ptr->mRefNum.mIndex = 0; |             ptr->mRefNum.mIndex = 0; | ||||||
|         } |         } | ||||||
|         ESM::RefId destinationRefId = ESM::RefId::stringRefId(destination); |         const int index = getAppendIndex(destination, type); | ||||||
|         int index = getAppendIndex(destinationRefId, type); |         insertRecord(std::move(copy), getAppendIndex(destination, type)); | ||||||
|         insertRecord(std::move(copy), getAppendIndex(destinationRefId, type)); |  | ||||||
| 
 | 
 | ||||||
|         return index; |         return index; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     template <typename ESXRecordT> |     template <typename ESXRecordT> | ||||||
|     int Collection<ESXRecordT>::touchRecordImp(const std::string& id) |     int Collection<ESXRecordT>::touchRecordImp(const ESM::RefId& id) | ||||||
|     { |     { | ||||||
|         int index = getIndex(ESM::RefId::stringRefId(id)); |         const int index = getIndex(id); | ||||||
|         Record<ESXRecordT>& record = *mRecords.at(index); |         Record<ESXRecordT>& record = *mRecords.at(index); | ||||||
|         if (record.isDeleted()) |         if (record.isDeleted()) | ||||||
|         { |         { | ||||||
|  | @ -269,27 +268,27 @@ namespace CSMWorld | ||||||
|     void Collection<ESXRecordT>::cloneRecord( |     void Collection<ESXRecordT>::cloneRecord( | ||||||
|         const ESM::RefId& origin, const ESM::RefId& destination, const UniversalId::Type type) |         const ESM::RefId& origin, const ESM::RefId& destination, const UniversalId::Type type) | ||||||
|     { |     { | ||||||
|         cloneRecordImp(origin.getRefIdString(), destination.getRefIdString(), type); |         cloneRecordImp(origin, destination, type); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     template <> |     template <> | ||||||
|     inline void Collection<Land>::cloneRecord( |     inline void Collection<Land>::cloneRecord( | ||||||
|         const ESM::RefId& origin, const ESM::RefId& destination, const UniversalId::Type type) |         const ESM::RefId& origin, const ESM::RefId& destination, const UniversalId::Type type) | ||||||
|     { |     { | ||||||
|         int index = cloneRecordImp(origin.getRefIdString(), destination.getRefIdString(), type); |         const int index = cloneRecordImp(origin, destination, type); | ||||||
|         mRecords.at(index)->get().setPlugin(0); |         mRecords.at(index)->get().setPlugin(0); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     template <typename ESXRecordT> |     template <typename ESXRecordT> | ||||||
|     bool Collection<ESXRecordT>::touchRecord(const ESM::RefId& id) |     bool Collection<ESXRecordT>::touchRecord(const ESM::RefId& id) | ||||||
|     { |     { | ||||||
|         return touchRecordImp(id.getRefIdString()) != -1; |         return touchRecordImp(id) != -1; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     template <> |     template <> | ||||||
|     inline bool Collection<Land>::touchRecord(const ESM::RefId& id) |     inline bool Collection<Land>::touchRecord(const ESM::RefId& id) | ||||||
|     { |     { | ||||||
|         int index = touchRecordImp(id.getRefIdString()); |         const int index = touchRecordImp(id); | ||||||
|         if (index >= 0) |         if (index >= 0) | ||||||
|         { |         { | ||||||
|             mRecords.at(index)->get().setPlugin(0); |             mRecords.at(index)->get().setPlugin(0); | ||||||
|  |  | ||||||
|  | @ -113,11 +113,7 @@ void CSMWorld::CommandDispatcher::setEditLock(bool locked) | ||||||
| void CSMWorld::CommandDispatcher::setSelection(const std::vector<std::string>& selection) | void CSMWorld::CommandDispatcher::setSelection(const std::vector<std::string>& selection) | ||||||
| { | { | ||||||
|     mSelection = selection; |     mSelection = selection; | ||||||
|     for (auto& sel : mSelection) |     std::sort(mSelection.begin(), mSelection.end(), Misc::StringUtils::CiComp{}); | ||||||
|     { |  | ||||||
|         Misc::StringUtils::lowerCaseInPlace(sel); |  | ||||||
|     } |  | ||||||
|     std::sort(mSelection.begin(), mSelection.end()); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void CSMWorld::CommandDispatcher::setExtendedTypes(const std::vector<UniversalId>& types) | void CSMWorld::CommandDispatcher::setExtendedTypes(const std::vector<UniversalId>& types) | ||||||
|  | @ -290,8 +286,7 @@ void CSMWorld::CommandDispatcher::executeExtendedDelete() | ||||||
|                 if (record.mState == RecordBase::State_Deleted) |                 if (record.mState == RecordBase::State_Deleted) | ||||||
|                     continue; |                     continue; | ||||||
| 
 | 
 | ||||||
|                 if (!std::binary_search(mSelection.begin(), mSelection.end(), |                 if (!std::binary_search(mSelection.begin(), mSelection.end(), record.get().mCell)) | ||||||
|                         Misc::StringUtils::lowerCase(record.get().mCell.getRefIdString()))) |  | ||||||
|                     continue; |                     continue; | ||||||
| 
 | 
 | ||||||
|                 macro.push(new CSMWorld::DeleteCommand(model, record.get().mId.getRefIdString())); |                 macro.push(new CSMWorld::DeleteCommand(model, record.get().mId.getRefIdString())); | ||||||
|  | @ -321,8 +316,7 @@ void CSMWorld::CommandDispatcher::executeExtendedRevert() | ||||||
|             { |             { | ||||||
|                 const Record<CellRef>& record = collection.getRecord(i); |                 const Record<CellRef>& record = collection.getRecord(i); | ||||||
| 
 | 
 | ||||||
|                 if (!std::binary_search(mSelection.begin(), mSelection.end(), |                 if (!std::binary_search(mSelection.begin(), mSelection.end(), record.get().mCell)) | ||||||
|                         Misc::StringUtils::lowerCase(record.get().mCell.getRefIdString()))) |  | ||||||
|                     continue; |                     continue; | ||||||
| 
 | 
 | ||||||
|                 macro.push(new CSMWorld::RevertCommand(model, record.get().mId.getRefIdString())); |                 macro.push(new CSMWorld::RevertCommand(model, record.get().mId.getRefIdString())); | ||||||
|  |  | ||||||
|  | @ -1209,9 +1209,8 @@ bool CSMWorld::Data::continueLoading(CSMDoc::Messages& messages) | ||||||
|                 messages.add(id, "Logic error: cell index out of bounds", "", CSMDoc::Message::Severity_Error); |                 messages.add(id, "Logic error: cell index out of bounds", "", CSMDoc::Message::Severity_Error); | ||||||
|                 index = mCells.getSize() - 1; |                 index = mCells.getSize() - 1; | ||||||
|             } |             } | ||||||
|             const std::string cellId = mCells.getId(index).getRefIdString(); |  | ||||||
| 
 | 
 | ||||||
|             mRefs.load(*mReader, index, mBase, mRefLoadCache[cellId], messages); |             mRefs.load(*mReader, index, mBase, mRefLoadCache[mCells.getId(index)], messages); | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -123,7 +123,7 @@ namespace CSMWorld | ||||||
|         const ESM::Dialogue* mDialogue; // last loaded dialogue
 |         const ESM::Dialogue* mDialogue; // last loaded dialogue
 | ||||||
|         bool mBase; |         bool mBase; | ||||||
|         bool mProject; |         bool mProject; | ||||||
|         std::map<std::string, std::map<unsigned int, unsigned int>, Misc::StringUtils::CiComp> mRefLoadCache; |         std::map<ESM::RefId, std::map<unsigned int, unsigned int>> mRefLoadCache; | ||||||
|         int mReaderIndex; |         int mReaderIndex; | ||||||
| 
 | 
 | ||||||
|         bool mFsStrict; |         bool mFsStrict; | ||||||
|  |  | ||||||
|  | @ -85,7 +85,7 @@ std::pair<char, bool> CSMWorld::ScriptContext::getMemberType(const std::string& | ||||||
|     if (index == -1) |     if (index == -1) | ||||||
|         return std::make_pair(' ', false); |         return std::make_pair(' ', false); | ||||||
| 
 | 
 | ||||||
|     std::map<std::string, Compiler::Locals>::iterator iter = mLocals.find(id2.getRefIdString()); |     auto iter = mLocals.find(id2); | ||||||
| 
 | 
 | ||||||
|     if (iter == mLocals.end()) |     if (iter == mLocals.end()) | ||||||
|     { |     { | ||||||
|  | @ -97,7 +97,7 @@ std::pair<char, bool> CSMWorld::ScriptContext::getMemberType(const std::string& | ||||||
|         Compiler::Scanner scanner(errorHandler, stream, getExtensions()); |         Compiler::Scanner scanner(errorHandler, stream, getExtensions()); | ||||||
|         scanner.scan(parser); |         scanner.scan(parser); | ||||||
| 
 | 
 | ||||||
|         iter = mLocals.insert(std::make_pair(id2.getRefIdString(), locals)).first; |         iter = mLocals.emplace(id2, std::move(locals)).first; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return std::make_pair(iter->second.getType(Misc::StringUtils::lowerCase(name)), reference); |     return std::make_pair(iter->second.getType(Misc::StringUtils::lowerCase(name)), reference); | ||||||
|  | @ -131,7 +131,7 @@ void CSMWorld::ScriptContext::clear() | ||||||
| 
 | 
 | ||||||
| bool CSMWorld::ScriptContext::clearLocals(const std::string& script) | bool CSMWorld::ScriptContext::clearLocals(const std::string& script) | ||||||
| { | { | ||||||
|     std::map<std::string, Compiler::Locals>::iterator iter = mLocals.find(script); |     const auto iter = mLocals.find(script); | ||||||
| 
 | 
 | ||||||
|     if (iter != mLocals.end()) |     if (iter != mLocals.end()) | ||||||
|     { |     { | ||||||
|  |  | ||||||
|  | @ -19,7 +19,7 @@ namespace CSMWorld | ||||||
|         const Data& mData; |         const Data& mData; | ||||||
|         mutable std::vector<ESM::RefId> mIds; |         mutable std::vector<ESM::RefId> mIds; | ||||||
|         mutable bool mIdsUpdated; |         mutable bool mIdsUpdated; | ||||||
|         mutable std::map<std::string, Compiler::Locals, Misc::StringUtils::CiComp> mLocals; |         mutable std::map<ESM::RefId, Compiler::Locals, std::less<>> mLocals; | ||||||
| 
 | 
 | ||||||
|     public: |     public: | ||||||
|         ScriptContext(const Data& data); |         ScriptContext(const Data& data); | ||||||
|  |  | ||||||
|  | @ -104,9 +104,8 @@ namespace CSVRender | ||||||
|     { |     { | ||||||
|         for (int i = 0; i < ESM::PRT_Count; ++i) |         for (int i = 0; i < ESM::PRT_Count; ++i) | ||||||
|         { |         { | ||||||
|             auto type = (ESM::PartReferenceType)i; |             const auto type = static_cast<ESM::PartReferenceType>(i); | ||||||
|             const std::string_view partId = mActorData->getPart(type); |             attachBodyPart(type, getBodyPartMesh(mActorData->getPart(type))); | ||||||
|             attachBodyPart(type, getBodyPartMesh(partId)); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -124,11 +123,11 @@ namespace CSVRender | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     std::string Actor::getBodyPartMesh(std::string_view bodyPartId) |     std::string Actor::getBodyPartMesh(const ESM::RefId& bodyPartId) | ||||||
|     { |     { | ||||||
|         const auto& bodyParts = mData.getBodyParts(); |         const auto& bodyParts = mData.getBodyParts(); | ||||||
| 
 | 
 | ||||||
|         const int index = bodyParts.searchId(ESM::RefId::stringRefId(bodyPartId)); |         const int index = bodyParts.searchId(bodyPartId); | ||||||
|         if (index != -1 && !bodyParts.getRecord(index).isDeleted()) |         if (index != -1 && !bodyParts.getRecord(index).isDeleted()) | ||||||
|             return MeshPrefix + bodyParts.getRecord(index).get().mModel; |             return MeshPrefix + bodyParts.getRecord(index).get().mModel; | ||||||
|         else |         else | ||||||
|  |  | ||||||
|  | @ -51,7 +51,7 @@ namespace CSVRender | ||||||
|         void loadBodyParts(); |         void loadBodyParts(); | ||||||
|         void attachBodyPart(ESM::PartReferenceType, const std::string& mesh); |         void attachBodyPart(ESM::PartReferenceType, const std::string& mesh); | ||||||
| 
 | 
 | ||||||
|         std::string getBodyPartMesh(std::string_view bodyPartId); |         std::string getBodyPartMesh(const ESM::RefId& bodyPartId); | ||||||
| 
 | 
 | ||||||
|         static const std::string MeshPrefix; |         static const std::string MeshPrefix; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -737,7 +737,7 @@ void CSVRender::Object::apply(CSMWorld::CommandMacro& commands) | ||||||
|         // Do cell check first so positions can be compared
 |         // Do cell check first so positions can be compared
 | ||||||
|         const CSMWorld::CellRef& ref = collection.getRecord(recordIndex).get(); |         const CSMWorld::CellRef& ref = collection.getRecord(recordIndex).get(); | ||||||
| 
 | 
 | ||||||
|         if (CSMWorld::CellCoordinates::isExteriorCell(ref.mCell.getRefIdString())) |         if (CSMWorld::CellCoordinates::isExteriorCell(ref.mCell)) | ||||||
|         { |         { | ||||||
|             // Find cell index at new position
 |             // Find cell index at new position
 | ||||||
|             std::pair<int, int> cellIndex |             std::pair<int, int> cellIndex | ||||||
|  |  | ||||||
|  | @ -37,7 +37,7 @@ namespace MWWorld | ||||||
| 
 | 
 | ||||||
|         for (const ESM::Global& esmGlobal : globals) |         for (const ESM::Global& esmGlobal : globals) | ||||||
|         { |         { | ||||||
|             mVariables.emplace(esmGlobal.mId.getRefIdString(), esmGlobal); |             mVariables.emplace(esmGlobal.mId, esmGlobal); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -98,8 +98,7 @@ namespace MWWorld | ||||||
|             // Deleted globals can't appear there, so isDeleted will be ignored here.
 |             // Deleted globals can't appear there, so isDeleted will be ignored here.
 | ||||||
|             global.load(reader, isDeleted); |             global.load(reader, isDeleted); | ||||||
| 
 | 
 | ||||||
|             Collection::iterator iter = mVariables.find(global.mId.getRefIdString()); |             if (const auto iter = mVariables.find(global.mId); iter != mVariables.end()) | ||||||
|             if (iter != mVariables.end()) |  | ||||||
|                 iter->second = global; |                 iter->second = global; | ||||||
| 
 | 
 | ||||||
|             return true; |             return true; | ||||||
|  |  | ||||||
|  | @ -2,8 +2,8 @@ | ||||||
| #define GAME_MWWORLD_GLOBALS_H | #define GAME_MWWORLD_GLOBALS_H | ||||||
| 
 | 
 | ||||||
| #include <cstdint> | #include <cstdint> | ||||||
|  | #include <map> | ||||||
| #include <string> | #include <string> | ||||||
| #include <unordered_map> |  | ||||||
| #include <vector> | #include <vector> | ||||||
| 
 | 
 | ||||||
| #include <components/esm3/loadglob.hpp> | #include <components/esm3/loadglob.hpp> | ||||||
|  | @ -29,8 +29,7 @@ namespace MWWorld | ||||||
|     class Globals |     class Globals | ||||||
|     { |     { | ||||||
|     private: |     private: | ||||||
|         using Collection |         using Collection = std::map<ESM::RefId, ESM::Global, std::less<>>; | ||||||
|             = std::unordered_map<std::string, ESM::Global, Misc::StringUtils::CiHash, Misc::StringUtils::CiEqual>; |  | ||||||
| 
 | 
 | ||||||
|         Collection mVariables; // type, value
 |         Collection mVariables; // type, value
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -23,6 +23,7 @@ file(GLOB UNITTEST_SRC_FILES | ||||||
| 
 | 
 | ||||||
|     esm/test_fixed_string.cpp |     esm/test_fixed_string.cpp | ||||||
|     esm/variant.cpp |     esm/variant.cpp | ||||||
|  |     esm/testrefid.cpp | ||||||
| 
 | 
 | ||||||
|     lua/test_lua.cpp |     lua/test_lua.cpp | ||||||
|     lua/test_scriptscontainer.cpp |     lua/test_scriptscontainer.cpp | ||||||
|  |  | ||||||
							
								
								
									
										148
									
								
								apps/openmw_test_suite/esm/testrefid.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								apps/openmw_test_suite/esm/testrefid.cpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,148 @@ | ||||||
|  | #include <components/esm/refid.hpp> | ||||||
|  | 
 | ||||||
|  | #include <gtest/gtest.h> | ||||||
|  | 
 | ||||||
|  | #include <functional> | ||||||
|  | #include <map> | ||||||
|  | #include <string> | ||||||
|  | 
 | ||||||
|  | namespace ESM | ||||||
|  | { | ||||||
|  |     namespace | ||||||
|  |     { | ||||||
|  |         using namespace ::testing; | ||||||
|  | 
 | ||||||
|  |         TEST(ESMRefIdTest, defaultConstructedIsEmpty) | ||||||
|  |         { | ||||||
|  |             const RefId refId; | ||||||
|  |             EXPECT_TRUE(refId.empty()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         TEST(ESMRefIdTest, stringRefIdIsNotEmpty) | ||||||
|  |         { | ||||||
|  |             const RefId refId = RefId::stringRefId("ref_id"); | ||||||
|  |             EXPECT_FALSE(refId.empty()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         TEST(ESMRefIdTest, formIdRefIdIsNotEmpty) | ||||||
|  |         { | ||||||
|  |             const RefId refId = RefId::formIdRefId(42); | ||||||
|  |             EXPECT_FALSE(refId.empty()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         TEST(ESMRefIdTest, defaultConstructedIsEqualToItself) | ||||||
|  |         { | ||||||
|  |             const RefId refId; | ||||||
|  |             EXPECT_EQ(refId, refId); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         TEST(ESMRefIdTest, defaultConstructedIsEqualToDefaultConstructed) | ||||||
|  |         { | ||||||
|  |             const RefId a; | ||||||
|  |             const RefId b; | ||||||
|  |             EXPECT_EQ(a, b); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         TEST(ESMRefIdTest, defaultConstructedIsNotEqualToDebugStringRefId) | ||||||
|  |         { | ||||||
|  |             const RefId a; | ||||||
|  |             const RefId b = RefId::stringRefId("b"); | ||||||
|  |             EXPECT_NE(a, b); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         TEST(ESMRefIdTest, defaultConstructedIsNotEqualToFormIdRefId) | ||||||
|  |         { | ||||||
|  |             const RefId a; | ||||||
|  |             const RefId b = RefId::formIdRefId(42); | ||||||
|  |             EXPECT_NE(a, b); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         TEST(ESMRefIdTest, defaultConstructedIsNotEqualToDebugStringLiteral) | ||||||
|  |         { | ||||||
|  |             const RefId a; | ||||||
|  |             EXPECT_NE(a, "foo"); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         TEST(ESMRefIdTest, stringRefIdIsEqualToTheSameStringLiteralValue) | ||||||
|  |         { | ||||||
|  |             const RefId refId = RefId::stringRefId("ref_id"); | ||||||
|  |             EXPECT_EQ(refId, "ref_id"); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         TEST(ESMRefIdTest, stringRefIdIsCaseInsensitiveEqualToTheSameStringLiteralValue) | ||||||
|  |         { | ||||||
|  |             const RefId refId = RefId::stringRefId("ref_id"); | ||||||
|  |             EXPECT_EQ(refId, "REF_ID"); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         TEST(ESMRefIdTest, stringRefIdIsEqualToTheSameStringRefId) | ||||||
|  |         { | ||||||
|  |             const RefId a = RefId::stringRefId("ref_id"); | ||||||
|  |             const RefId b = RefId::stringRefId("ref_id"); | ||||||
|  |             EXPECT_EQ(a, b); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         TEST(ESMRefIdTest, stringRefIdIsCaseInsensitiveEqualToTheSameStringRefId) | ||||||
|  |         { | ||||||
|  |             const RefId lower = RefId::stringRefId("ref_id"); | ||||||
|  |             const RefId upper = RefId::stringRefId("REF_ID"); | ||||||
|  |             EXPECT_EQ(lower, upper); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         TEST(ESMRefIdTest, stringRefIdIsEqualToItself) | ||||||
|  |         { | ||||||
|  |             const RefId refId = RefId::stringRefId("ref_id"); | ||||||
|  |             EXPECT_EQ(refId, refId); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         TEST(ESMRefIdTest, stringRefIdIsCaseInsensitiveLessByContent) | ||||||
|  |         { | ||||||
|  |             const RefId a = RefId::stringRefId("a"); | ||||||
|  |             const RefId b = RefId::stringRefId("B"); | ||||||
|  |             EXPECT_LT(a, b); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         TEST(ESMRefIdTest, stringRefIdHasCaseInsensitiveHash) | ||||||
|  |         { | ||||||
|  |             const RefId lower = RefId::stringRefId("a"); | ||||||
|  |             const RefId upper = RefId::stringRefId("A"); | ||||||
|  |             const std::hash<RefId> hash; | ||||||
|  |             EXPECT_EQ(hash(lower), hash(upper)); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         TEST(ESMRefIdTest, hasCaseInsensitiveEqualityWithStringView) | ||||||
|  |         { | ||||||
|  |             const RefId a = RefId::stringRefId("a"); | ||||||
|  |             const std::string_view b = "A"; | ||||||
|  |             EXPECT_EQ(a, b); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         TEST(ESMRefIdTest, hasCaseInsensitiveLessWithStringView) | ||||||
|  |         { | ||||||
|  |             const RefId a = RefId::stringRefId("a"); | ||||||
|  |             const std::string_view b = "B"; | ||||||
|  |             EXPECT_LT(a, b); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         TEST(ESMRefIdTest, hasCaseInsensitiveStrongOrderWithStringView) | ||||||
|  |         { | ||||||
|  |             const RefId a = RefId::stringRefId("a"); | ||||||
|  |             const std::string_view b = "B"; | ||||||
|  |             const RefId c = RefId::stringRefId("c"); | ||||||
|  |             EXPECT_LT(a, b); | ||||||
|  |             EXPECT_LT(b, c); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         TEST(ESMRefIdTest, canBeUsedAsMapKeyWithLookupByStringView) | ||||||
|  |         { | ||||||
|  |             const std::map<ESM::RefId, int, std::less<>> map({ { ESM::RefId::stringRefId("a"), 42 } }); | ||||||
|  |             EXPECT_EQ(map.count("A"), 1); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         TEST(ESMRefIdTest, canBeUsedAsLookupKeyForMapWithStringKey) | ||||||
|  |         { | ||||||
|  |             const std::map<std::string, int, std::less<>> map({ { "a", 42 } }); | ||||||
|  |             EXPECT_EQ(map.count(ESM::RefId::stringRefId("A")), 1); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -144,7 +144,7 @@ namespace | ||||||
|     class TestInterpreterContext : public Interpreter::Context |     class TestInterpreterContext : public Interpreter::Context | ||||||
|     { |     { | ||||||
|         LocalVariables mLocals; |         LocalVariables mLocals; | ||||||
|         std::map<std::string, GlobalVariables, Misc::StringUtils::CiComp> mMembers; |         std::map<ESM::RefId, GlobalVariables> mMembers; | ||||||
| 
 | 
 | ||||||
|     public: |     public: | ||||||
|         const ESM::RefId& getTarget() const override { return ESM::RefId::sEmpty; } |         const ESM::RefId& getTarget() const override { return ESM::RefId::sEmpty; } | ||||||
|  | @ -209,7 +209,7 @@ namespace | ||||||
| 
 | 
 | ||||||
|         int getMemberShort(const ESM::RefId& id, std::string_view name, bool global) const override |         int getMemberShort(const ESM::RefId& id, std::string_view name, bool global) const override | ||||||
|         { |         { | ||||||
|             auto it = mMembers.find(id.getRefIdString()); |             auto it = mMembers.find(id); | ||||||
|             if (it != mMembers.end()) |             if (it != mMembers.end()) | ||||||
|                 return it->second.getShort(name); |                 return it->second.getShort(name); | ||||||
|             return {}; |             return {}; | ||||||
|  | @ -217,7 +217,7 @@ namespace | ||||||
| 
 | 
 | ||||||
|         int getMemberLong(const ESM::RefId& id, std::string_view name, bool global) const override |         int getMemberLong(const ESM::RefId& id, std::string_view name, bool global) const override | ||||||
|         { |         { | ||||||
|             auto it = mMembers.find(id.getRefIdString()); |             auto it = mMembers.find(id); | ||||||
|             if (it != mMembers.end()) |             if (it != mMembers.end()) | ||||||
|                 return it->second.getLong(name); |                 return it->second.getLong(name); | ||||||
|             return {}; |             return {}; | ||||||
|  | @ -225,7 +225,7 @@ namespace | ||||||
| 
 | 
 | ||||||
|         float getMemberFloat(const ESM::RefId& id, std::string_view name, bool global) const override |         float getMemberFloat(const ESM::RefId& id, std::string_view name, bool global) const override | ||||||
|         { |         { | ||||||
|             auto it = mMembers.find(id.getRefIdString()); |             auto it = mMembers.find(id); | ||||||
|             if (it != mMembers.end()) |             if (it != mMembers.end()) | ||||||
|                 return it->second.getFloat(name); |                 return it->second.getFloat(name); | ||||||
|             return {}; |             return {}; | ||||||
|  | @ -233,17 +233,17 @@ namespace | ||||||
| 
 | 
 | ||||||
|         void setMemberShort(const ESM::RefId& id, std::string_view name, int value, bool global) override |         void setMemberShort(const ESM::RefId& id, std::string_view name, int value, bool global) override | ||||||
|         { |         { | ||||||
|             mMembers[id.getRefIdString()].setShort(name, value); |             mMembers[id].setShort(name, value); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         void setMemberLong(const ESM::RefId& id, std::string_view name, int value, bool global) override |         void setMemberLong(const ESM::RefId& id, std::string_view name, int value, bool global) override | ||||||
|         { |         { | ||||||
|             mMembers[id.getRefIdString()].setLong(name, value); |             mMembers[id].setLong(name, value); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         void setMemberFloat(const ESM::RefId& id, std::string_view name, float value, bool global) override |         void setMemberFloat(const ESM::RefId& id, std::string_view name, float value, bool global) override | ||||||
|         { |         { | ||||||
|             mMembers[id.getRefIdString()].setFloat(name, value); |             mMembers[id].setFloat(name, value); | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -16,9 +16,14 @@ namespace ESM | ||||||
|         return Misc::StringUtils::ciLess(mId, rhs.mId); |         return Misc::StringUtils::ciLess(mId, rhs.mId); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     bool RefId::operator<(std::string_view rhs) const |     bool operator<(const RefId& lhs, std::string_view rhs) | ||||||
|     { |     { | ||||||
|         return Misc::StringUtils::ciLess(mId, rhs); |         return Misc::StringUtils::ciLess(lhs.mId, rhs); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     bool operator<(std::string_view lhs, const RefId& rhs) | ||||||
|  |     { | ||||||
|  |         return Misc::StringUtils::ciLess(lhs, rhs.mId); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     std::ostream& operator<<(std::ostream& os, const RefId& refId) |     std::ostream& operator<<(std::ostream& os, const RefId& refId) | ||||||
|  |  | ||||||
|  | @ -39,7 +39,9 @@ namespace ESM | ||||||
| 
 | 
 | ||||||
|         bool operator<(const RefId& rhs) const; |         bool operator<(const RefId& rhs) const; | ||||||
| 
 | 
 | ||||||
|         bool operator<(std::string_view rhs) const; |         friend bool operator<(const RefId& lhs, std::string_view rhs); | ||||||
|  | 
 | ||||||
|  |         friend bool operator<(std::string_view lhs, const RefId& rhs); | ||||||
| 
 | 
 | ||||||
|         friend std::ostream& operator<<(std::ostream& os, const RefId& dt); |         friend std::ostream& operator<<(std::ostream& os, const RefId& dt); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue