diff --git a/apps/openmw_test_suite/testing_util.hpp b/apps/openmw_test_suite/testing_util.hpp index aa76f7f944..b819848a8f 100644 --- a/apps/openmw_test_suite/testing_util.hpp +++ b/apps/openmw_test_suite/testing_util.hpp @@ -61,7 +61,7 @@ namespace TestingOpenMW void listResources(VFS::FileMap& out) override { for (const auto& [key, value] : mFiles) - out.emplace(VFS::Path::normalizeFilename(key), value); + out.emplace(key, value); } bool contains(std::string_view file) const override { return mFiles.contains(file); } diff --git a/components/vfs/filemap.hpp b/components/vfs/filemap.hpp index 808153fc05..1b7d390d88 100644 --- a/components/vfs/filemap.hpp +++ b/components/vfs/filemap.hpp @@ -8,7 +8,12 @@ namespace VFS { class File; - using FileMap = std::map>; + namespace Path + { + class Normalized; + } + + using FileMap = std::map>; } #endif diff --git a/components/vfs/manager.cpp b/components/vfs/manager.cpp index 5315f17252..d312ce9d84 100644 --- a/components/vfs/manager.cpp +++ b/components/vfs/manager.cpp @@ -83,7 +83,7 @@ namespace VFS return { mIndex.begin(), mIndex.end() }; std::string normalized = Path::normalizeFilename(path); const auto it = mIndex.lower_bound(normalized); - if (it == mIndex.end() || !it->first.starts_with(normalized)) + if (it == mIndex.end() || !it->first.view().starts_with(normalized)) return { it, it }; ++normalized.back(); return { it, mIndex.lower_bound(normalized) }; diff --git a/components/vfs/pathutil.hpp b/components/vfs/pathutil.hpp index 724b406f1d..9bcc263842 100644 --- a/components/vfs/pathutil.hpp +++ b/components/vfs/pathutil.hpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -51,6 +52,73 @@ namespace VFS::Path bool operator()(std::string_view left, std::string_view right) const { return pathLess(left, right); } }; + + class Normalized + { + public: + Normalized() = default; + + Normalized(std::string_view value) + : mValue(normalizeFilename(value)) + { + } + + Normalized(const char* value) + : Normalized(std::string_view(value)) + { + } + + Normalized(const std::string& value) + : Normalized(std::string_view(value)) + { + } + + explicit Normalized(std::string&& value) + : mValue(std::move(value)) + { + normalizeFilenameInPlace(mValue); + } + + const std::string& value() const& { return mValue; } + + std::string value() && { return std::move(mValue); } + + std::string_view view() const { return mValue; } + + operator std::string_view() const { return mValue; } + + operator const std::string&() const { return mValue; } + + friend bool operator==(const Normalized& lhs, const Normalized& rhs) = default; + + template + friend bool operator==(const Normalized& lhs, const T& rhs) + { + return lhs.mValue == rhs; + } + + friend bool operator<(const Normalized& lhs, const Normalized& rhs) { return lhs.mValue < rhs.mValue; } + + template + friend bool operator<(const Normalized& lhs, const T& rhs) + { + return lhs.mValue < rhs; + } + + template + friend bool operator<(const T& lhs, const Normalized& rhs) + { + return lhs < rhs.mValue; + } + + friend std::ostream& operator<<(std::ostream& stream, const Normalized& value) + { + return stream << value.mValue; + } + + private: + std::string mValue; + }; } #endif diff --git a/components/vfs/recursivedirectoryiterator.hpp b/components/vfs/recursivedirectoryiterator.hpp index 82f8e594fd..39fb26e873 100644 --- a/components/vfs/recursivedirectoryiterator.hpp +++ b/components/vfs/recursivedirectoryiterator.hpp @@ -4,6 +4,7 @@ #include #include "filemap.hpp" +#include "pathutil.hpp" namespace VFS { @@ -15,9 +16,9 @@ namespace VFS { } - const std::string& operator*() const { return mIt->first; } + const std::string& operator*() const { return mIt->first.value(); } - const std::string* operator->() const { return &mIt->first; } + const std::string* operator->() const { return &mIt->first.value(); } RecursiveDirectoryIterator& operator++() {