From 9b7830450268893bdb23872d5fcfa89b8d014f5e Mon Sep 17 00:00:00 2001 From: Joel Rosdahl Date: Sat, 25 Feb 2023 14:27:32 +0100 Subject: enhance: Add util::split_once(std::string&&, char) --- src/util/string.cpp | 17 ++++++++++++++ src/util/string.hpp | 4 ++++ unittest/test_util_string.cpp | 54 +++++++++++++++++++++++++++++++++++-------- 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 @@ -277,6 +277,23 @@ replace_first(const std::string_view string, return result; } +std::pair> +split_once(const char* string, const char split_char) +{ + return split_once(std::string_view(string), split_char); +} + +std::pair> +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> split_once(const std::string_view string, const char 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> +split_once(const char* string, char split_char); +std::pair> +split_once(std::string&& string, char split_char); +std::pair> 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 @@ -23,6 +23,13 @@ #include // https://github.com/doctest/doctest/issues/618 #include +static bool +operator==(std::pair> left, + std::pair> right) +{ + return left.first == right.first && left.second == right.second; +} + static bool operator==(std::pair> left, std::pair> 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") -- cgit v1.2.1