diff --git a/apps/openmw_test_suite/CMakeLists.txt b/apps/openmw_test_suite/CMakeLists.txt index eb9c0be15d..6b679e8653 100644 --- a/apps/openmw_test_suite/CMakeLists.txt +++ b/apps/openmw_test_suite/CMakeLists.txt @@ -89,6 +89,7 @@ file(GLOB UNITTEST_SRC_FILES esm3/readerscache.cpp esm3/testsaveload.cpp esm3/testesmwriter.cpp + esm3/testinfoorder.cpp nifosg/testnifloader.cpp ) diff --git a/apps/openmw_test_suite/esm3/testinfoorder.cpp b/apps/openmw_test_suite/esm3/testinfoorder.cpp new file mode 100644 index 0000000000..feb48e2d0a --- /dev/null +++ b/apps/openmw_test_suite/esm3/testinfoorder.cpp @@ -0,0 +1,27 @@ +#include + +#include + +namespace ESM +{ + namespace + { + struct Value + { + RefId mId; + RefId mPrev; + + Value() = default; + Value(const Value&) = delete; + Value(Value&&) = default; + Value& operator=(const Value&) = delete; + Value& operator=(Value&&) = default; + }; + + TEST(Esm3InfoOrderTest, insertInfoShouldNotCopyValue) + { + InfoOrder order; + order.insertInfo(Value{}, false); + } + } +} diff --git a/components/esm3/infoorder.hpp b/components/esm3/infoorder.hpp index 5ca98cabd5..dcb4af4bc9 100644 --- a/components/esm3/infoorder.hpp +++ b/components/esm3/infoorder.hpp @@ -24,19 +24,12 @@ namespace ESM auto it = mInfoPositions.find(value.mId); - if (it != mInfoPositions.end()) + if (it != mInfoPositions.end() && it->second.mPosition->mPrev == value.mPrev) { - bool samePrev = it->second.mPosition->mPrev == value.mPrev; *it->second.mPosition = std::forward(value); it->second.mDeleted = deleted; - if (samePrev) - return; + return; } - else - it = mInfoPositions.emplace(value.mId, Item{ .mPosition = mOrderedInfo.end(), .mDeleted = deleted }) - .first; - - Item& item = it->second; auto before = mOrderedInfo.begin(); if (!value.mPrev.empty()) @@ -47,10 +40,22 @@ namespace ESM else before = mOrderedInfo.end(); } - if (item.mPosition == mOrderedInfo.end()) - item.mPosition = mOrderedInfo.insert(before, std::forward(value)); + + if (it == mInfoPositions.end()) + { + const RefId id = value.mId; + mInfoPositions.emplace(id, + Item{ + .mPosition = mOrderedInfo.insert(before, std::forward(value)), + .mDeleted = deleted, + }); + } else - mOrderedInfo.splice(before, mOrderedInfo, item.mPosition); + { + *it->second.mPosition = std::forward(value); + it->second.mDeleted = deleted; + mOrderedInfo.splice(before, mOrderedInfo, it->second.mPosition); + } } void removeInfo(const RefId& infoRefId)