summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Rosdahl <joel@rosdahl.net>2023-02-25 14:27:32 +0100
committerJoel Rosdahl <joel@rosdahl.net>2023-03-04 10:10:20 +0100
commit9b7830450268893bdb23872d5fcfa89b8d014f5e (patch)
treeff9e93691405d14852572c6a52eca544673abac3
parent66c9c76151497638f1be2bb05ccc2d58d075fc2d (diff)
downloadccache-9b7830450268893bdb23872d5fcfa89b8d014f5e.tar.gz
enhance: Add util::split_once(std::string&&, char)
-rw-r--r--src/util/string.cpp17
-rw-r--r--src/util/string.hpp4
-rw-r--r--unittest/test_util_string.cpp54
3 files changed, 66 insertions, 9 deletions
diff --git a/src/util/string.cpp b/src/util/string.cpp
index 4ad3decd..c33bd9f5 100644
--- a/src/util/string.cpp
+++ b/src/util/string.cpp
@@ -278,6 +278,23 @@ replace_first(const std::string_view string,
}
std::pair<std::string_view, std::optional<std::string_view>>
+split_once(const char* string, const char split_char)
+{
+ return split_once(std::string_view(string), split_char);
+}
+
+std::pair<std::string, std::optional<std::string>>
+split_once(std::string&& string, const char split_char)
+{
+ const auto [left, right] = split_once(std::string_view(string), split_char);
+ if (right) {
+ return std::make_pair(std::string(left), std::string(*right));
+ } else {
+ return std::make_pair(std::string(left), std::nullopt);
+ }
+}
+
+std::pair<std::string_view, std::optional<std::string_view>>
split_once(const std::string_view string, const char split_char)
{
const size_t sep_pos = string.find(split_char);
diff --git a/src/util/string.hpp b/src/util/string.hpp
index 7df40aad..3b23fa4e 100644
--- a/src/util/string.hpp
+++ b/src/util/string.hpp
@@ -117,6 +117,10 @@ std::string replace_first(std::string_view string,
// Split `string` into two parts using `split_char` as the delimiter. The second
// part will be `nullopt` if there is no `split_char` in `string.`
std::pair<std::string_view, std::optional<std::string_view>>
+split_once(const char* string, char split_char);
+std::pair<std::string, std::optional<std::string>>
+split_once(std::string&& string, char split_char);
+std::pair<std::string_view, std::optional<std::string_view>>
split_once(std::string_view string, char split_char);
// Return true if `prefix` is a prefix of `string`.
diff --git a/unittest/test_util_string.cpp b/unittest/test_util_string.cpp
index 12746d08..e2fb2334 100644
--- a/unittest/test_util_string.cpp
+++ b/unittest/test_util_string.cpp
@@ -24,6 +24,13 @@
#include <vector>
static bool
+operator==(std::pair<std::string, std::optional<std::string>> left,
+ std::pair<std::string, std::optional<std::string>> right)
+{
+ return left.first == right.first && left.second == right.second;
+}
+
+static bool
operator==(std::pair<std::string_view, std::optional<std::string_view>> left,
std::pair<std::string_view, std::optional<std::string_view>> right)
{
@@ -314,15 +321,44 @@ TEST_CASE("util::split_once")
using std::nullopt;
using util::split_once;
- CHECK(split_once("", '=') == make_pair("", nullopt));
- CHECK(split_once("a", '=') == make_pair("a", nullopt));
- CHECK(split_once("=a", '=') == make_pair("", "a"));
- CHECK(split_once("a=", '=') == make_pair("a", ""));
- CHECK(split_once("a==", '=') == make_pair("a", "="));
- CHECK(split_once("a=b", '=') == make_pair("a", "b"));
- CHECK(split_once("a=b=", '=') == make_pair("a", "b="));
- CHECK(split_once("a=b=c", '=') == make_pair("a", "b=c"));
- CHECK(split_once("x y", ' ') == make_pair("x", "y"));
+ SUBCASE("const char*")
+ {
+ CHECK(split_once("", '=') == make_pair("", nullopt));
+ CHECK(split_once("a", '=') == make_pair("a", nullopt));
+ CHECK(split_once("=a", '=') == make_pair("", "a"));
+ CHECK(split_once("a=", '=') == make_pair("a", ""));
+ CHECK(split_once("a==", '=') == make_pair("a", "="));
+ CHECK(split_once("a=b", '=') == make_pair("a", "b"));
+ CHECK(split_once("a=b=", '=') == make_pair("a", "b="));
+ CHECK(split_once("a=b=c", '=') == make_pair("a", "b=c"));
+ CHECK(split_once("x y", ' ') == make_pair("x", "y"));
+ }
+
+ SUBCASE("std::string&&")
+ {
+ CHECK(split_once(std::string(""), '=') == make_pair("", nullopt));
+ CHECK(split_once(std::string("a"), '=') == make_pair("a", nullopt));
+ CHECK(split_once(std::string("=a"), '=') == make_pair("", "a"));
+ CHECK(split_once(std::string("a="), '=') == make_pair("a", ""));
+ CHECK(split_once(std::string("a=="), '=') == make_pair("a", "="));
+ CHECK(split_once(std::string("a=b"), '=') == make_pair("a", "b"));
+ CHECK(split_once(std::string("a=b="), '=') == make_pair("a", "b="));
+ CHECK(split_once(std::string("a=b=c"), '=') == make_pair("a", "b=c"));
+ CHECK(split_once(std::string("x y"), ' ') == make_pair("x", "y"));
+ }
+
+ SUBCASE("std::string_view")
+ {
+ CHECK(split_once(std::string_view(""), '=') == make_pair("", nullopt));
+ CHECK(split_once(std::string_view("a"), '=') == make_pair("a", nullopt));
+ CHECK(split_once(std::string_view("=a"), '=') == make_pair("", "a"));
+ CHECK(split_once(std::string_view("a="), '=') == make_pair("a", ""));
+ CHECK(split_once(std::string_view("a=="), '=') == make_pair("a", "="));
+ CHECK(split_once(std::string_view("a=b"), '=') == make_pair("a", "b"));
+ CHECK(split_once(std::string_view("a=b="), '=') == make_pair("a", "b="));
+ CHECK(split_once(std::string_view("a=b=c"), '=') == make_pair("a", "b=c"));
+ CHECK(split_once(std::string_view("x y"), ' ') == make_pair("x", "y"));
+ }
}
TEST_CASE("util::starts_with")