Add type for normalized VFS path and use for VFS::Manager file map key

This will reduce the number of path normalizations while more places will use
this type. In some cases it also will reduce number of temporary allocations for
new strings.

For now make conversion from and to std::string_view implicit to allow gradual
migration to this type.
ini_importer_tests
elsid 12 months ago
parent a2147d70cc
commit 35d9b18b4c
No known key found for this signature in database
GPG Key ID: 4DE04C198CBA7625

@ -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); }

@ -8,7 +8,12 @@ namespace VFS
{
class File;
using FileMap = std::map<std::string, File*, std::less<>>;
namespace Path
{
class Normalized;
}
using FileMap = std::map<Path::Normalized, File*, std::less<>>;
}
#endif

@ -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) };

@ -4,6 +4,7 @@
#include <components/misc/strings/lower.hpp>
#include <algorithm>
#include <ostream>
#include <string>
#include <string_view>
@ -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 <class T>
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 <class T>
friend bool operator<(const Normalized& lhs, const T& rhs)
{
return lhs.mValue < rhs;
}
template <class T>
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

@ -4,6 +4,7 @@
#include <string>
#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++()
{

Loading…
Cancel
Save