summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Kellermann <max@musicpd.org>2021-07-16 08:20:18 +0200
committerMax Kellermann <max@musicpd.org>2021-07-16 08:30:34 +0200
commit809a18913a179c1581cea463daaac3cbdae2231f (patch)
treed7989375e71732781f728626cd18a15fa99dfbc2
parent5eab2d96f499ba0dce3df1800e566c7b52b3d05f (diff)
fs/Traits: add overload GetParent(string_view)
-rw-r--r--src/fs/Traits.cxx28
-rw-r--r--src/fs/Traits.hxx31
2 files changed, 59 insertions, 0 deletions
diff --git a/src/fs/Traits.cxx b/src/fs/Traits.cxx
index f3598fdc1..35d7fa1fd 100644
--- a/src/fs/Traits.cxx
+++ b/src/fs/Traits.cxx
@@ -85,6 +85,22 @@ GetParentPathImpl(typename Traits::const_pointer p) noexcept
}
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
RelativePathImpl(typename Traits::string_view base,
typename Traits::const_pointer other) noexcept
@@ -166,6 +182,12 @@ PathTraitsFS::GetParent(PathTraitsFS::const_pointer p) noexcept
return GetParentPathImpl<PathTraitsFS>(p);
}
+PathTraitsFS::string_view
+PathTraitsFS::GetParent(string_view p) noexcept
+{
+ return GetParentPathImpl<PathTraitsFS>(p);
+}
+
PathTraitsFS::const_pointer
PathTraitsFS::Relative(string_view base, const_pointer other) noexcept
{
@@ -210,6 +232,12 @@ PathTraitsUTF8::GetParent(const_pointer p) noexcept
return GetParentPathImpl<PathTraitsUTF8>(p);
}
+PathTraitsUTF8::string_view
+PathTraitsUTF8::GetParent(string_view p) noexcept
+{
+ return GetParentPathImpl<PathTraitsUTF8>(p);
+}
+
PathTraitsUTF8::const_pointer
PathTraitsUTF8::Relative(string_view base, const_pointer other) noexcept
{
diff --git a/src/fs/Traits.hxx b/src/fs/Traits.hxx
index 9f22e2f7a..a5495a29f 100644
--- a/src/fs/Traits.hxx
+++ b/src/fs/Traits.hxx
@@ -88,6 +88,18 @@ struct PathTraitsFS {
#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
static const_pointer GetFilenameSuffix(const_pointer filename) noexcept {
const_pointer dot = StringFindLast(filename, '.');
@@ -106,6 +118,10 @@ struct PathTraitsFS {
static constexpr bool IsDrive(const_pointer p) noexcept {
return IsAlphaASCII(p[0]) && p[1] == ':';
}
+
+ static constexpr bool IsDrive(string_view p) noexcept {
+ return p.size() >= 2 && IsAlphaASCII(p[0]) && p[1] == ':';
+ }
#endif
gcc_pure gcc_nonnull_all
@@ -153,6 +169,9 @@ struct PathTraitsFS {
gcc_pure gcc_nonnull_all
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
* object, not including the directory separator. Returns an
@@ -212,6 +231,11 @@ struct PathTraitsUTF8 {
return std::strrchr(p, SEPARATOR);
}
+ [[gnu::pure]]
+ static const_pointer FindLastSeparator(string_view p) noexcept {
+ return StringFindLast(p.data(), SEPARATOR, p.size());
+ }
+
gcc_pure
static const_pointer GetFilenameSuffix(const_pointer filename) noexcept {
const_pointer dot = StringFindLast(filename, '.');
@@ -230,6 +254,10 @@ struct PathTraitsUTF8 {
static constexpr bool IsDrive(const_pointer p) noexcept {
return IsAlphaASCII(p[0]) && p[1] == ':';
}
+
+ static constexpr bool IsDrive(string_view p) noexcept {
+ return p.size() >= 2 && IsAlphaASCII(p[0]) && p[1] == ':';
+ }
#endif
gcc_pure gcc_nonnull_all
@@ -277,6 +305,9 @@ struct PathTraitsUTF8 {
gcc_pure gcc_nonnull_all
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
* object, not including the directory separator. Returns an