Commit 809a1891 authored by Max Kellermann's avatar Max Kellermann

fs/Traits: add overload GetParent(string_view)

parent 5eab2d96
...@@ -85,6 +85,22 @@ GetParentPathImpl(typename Traits::const_pointer p) noexcept ...@@ -85,6 +85,22 @@ GetParentPathImpl(typename Traits::const_pointer p) noexcept
} }
template<typename Traits> template<typename Traits>
typename Traits::string_view
GetParentPathImpl(typename Traits::string_view p) noexcept
{
auto sep = Traits::FindLastSeparator(p);
if (sep == nullptr)
return Traits::CURRENT_DIRECTORY;
if (sep == p.data())
return p.substr(0, 1);
#ifdef _WIN32
if (Traits::IsDrive(p) && sep == p.data() + 2)
return p.substr(0, 3);
#endif
return p.substr(0, sep - p.data());
}
template<typename Traits>
typename Traits::const_pointer typename Traits::const_pointer
RelativePathImpl(typename Traits::string_view base, RelativePathImpl(typename Traits::string_view base,
typename Traits::const_pointer other) noexcept typename Traits::const_pointer other) noexcept
...@@ -166,6 +182,12 @@ PathTraitsFS::GetParent(PathTraitsFS::const_pointer p) noexcept ...@@ -166,6 +182,12 @@ PathTraitsFS::GetParent(PathTraitsFS::const_pointer p) noexcept
return GetParentPathImpl<PathTraitsFS>(p); return GetParentPathImpl<PathTraitsFS>(p);
} }
PathTraitsFS::string_view
PathTraitsFS::GetParent(string_view p) noexcept
{
return GetParentPathImpl<PathTraitsFS>(p);
}
PathTraitsFS::const_pointer PathTraitsFS::const_pointer
PathTraitsFS::Relative(string_view base, const_pointer other) noexcept PathTraitsFS::Relative(string_view base, const_pointer other) noexcept
{ {
...@@ -210,6 +232,12 @@ PathTraitsUTF8::GetParent(const_pointer p) noexcept ...@@ -210,6 +232,12 @@ PathTraitsUTF8::GetParent(const_pointer p) noexcept
return GetParentPathImpl<PathTraitsUTF8>(p); return GetParentPathImpl<PathTraitsUTF8>(p);
} }
PathTraitsUTF8::string_view
PathTraitsUTF8::GetParent(string_view p) noexcept
{
return GetParentPathImpl<PathTraitsUTF8>(p);
}
PathTraitsUTF8::const_pointer PathTraitsUTF8::const_pointer
PathTraitsUTF8::Relative(string_view base, const_pointer other) noexcept PathTraitsUTF8::Relative(string_view base, const_pointer other) noexcept
{ {
......
...@@ -88,6 +88,18 @@ struct PathTraitsFS { ...@@ -88,6 +88,18 @@ struct PathTraitsFS {
#endif #endif
} }
[[gnu::pure]]
static const_pointer FindLastSeparator(string_view p) noexcept {
#ifdef _WIN32
const_pointer pos = p.data() + p.size();
while (p.data() != pos && !IsSeparator(*pos))
--pos;
return IsSeparator(*pos) ? pos : nullptr;
#else
return StringFindLast(p.data(), SEPARATOR, p.size());
#endif
}
gcc_pure gcc_pure
static const_pointer GetFilenameSuffix(const_pointer filename) noexcept { static const_pointer GetFilenameSuffix(const_pointer filename) noexcept {
const_pointer dot = StringFindLast(filename, '.'); const_pointer dot = StringFindLast(filename, '.');
...@@ -106,6 +118,10 @@ struct PathTraitsFS { ...@@ -106,6 +118,10 @@ struct PathTraitsFS {
static constexpr bool IsDrive(const_pointer p) noexcept { static constexpr bool IsDrive(const_pointer p) noexcept {
return IsAlphaASCII(p[0]) && p[1] == ':'; return IsAlphaASCII(p[0]) && p[1] == ':';
} }
static constexpr bool IsDrive(string_view p) noexcept {
return p.size() >= 2 && IsAlphaASCII(p[0]) && p[1] == ':';
}
#endif #endif
gcc_pure gcc_nonnull_all gcc_pure gcc_nonnull_all
...@@ -153,6 +169,9 @@ struct PathTraitsFS { ...@@ -153,6 +169,9 @@ struct PathTraitsFS {
gcc_pure gcc_nonnull_all gcc_pure gcc_nonnull_all
static string_view GetParent(const_pointer p) noexcept; static string_view GetParent(const_pointer p) noexcept;
[[gnu::pure]]
static string_view GetParent(string_view p) noexcept;
/** /**
* Determine the relative part of the given path to this * Determine the relative part of the given path to this
* object, not including the directory separator. Returns an * object, not including the directory separator. Returns an
...@@ -212,6 +231,11 @@ struct PathTraitsUTF8 { ...@@ -212,6 +231,11 @@ struct PathTraitsUTF8 {
return std::strrchr(p, SEPARATOR); return std::strrchr(p, SEPARATOR);
} }
[[gnu::pure]]
static const_pointer FindLastSeparator(string_view p) noexcept {
return StringFindLast(p.data(), SEPARATOR, p.size());
}
gcc_pure gcc_pure
static const_pointer GetFilenameSuffix(const_pointer filename) noexcept { static const_pointer GetFilenameSuffix(const_pointer filename) noexcept {
const_pointer dot = StringFindLast(filename, '.'); const_pointer dot = StringFindLast(filename, '.');
...@@ -230,6 +254,10 @@ struct PathTraitsUTF8 { ...@@ -230,6 +254,10 @@ struct PathTraitsUTF8 {
static constexpr bool IsDrive(const_pointer p) noexcept { static constexpr bool IsDrive(const_pointer p) noexcept {
return IsAlphaASCII(p[0]) && p[1] == ':'; return IsAlphaASCII(p[0]) && p[1] == ':';
} }
static constexpr bool IsDrive(string_view p) noexcept {
return p.size() >= 2 && IsAlphaASCII(p[0]) && p[1] == ':';
}
#endif #endif
gcc_pure gcc_nonnull_all gcc_pure gcc_nonnull_all
...@@ -277,6 +305,9 @@ struct PathTraitsUTF8 { ...@@ -277,6 +305,9 @@ struct PathTraitsUTF8 {
gcc_pure gcc_nonnull_all gcc_pure gcc_nonnull_all
static string_view GetParent(const_pointer p) noexcept; static string_view GetParent(const_pointer p) noexcept;
[[gnu::pure]]
static string_view GetParent(string_view p) noexcept;
/** /**
* Determine the relative part of the given path to this * Determine the relative part of the given path to this
* object, not including the directory separator. Returns an * object, not including the directory separator. Returns an
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment