StringUtil: Modernize SplitString and add unit tests

This commit is contained in:
Sepalani 2025-01-05 00:04:28 +04:00
parent 05cad38abc
commit 9f33bfc58e
3 changed files with 42 additions and 8 deletions

View File

@ -16,6 +16,7 @@
#include <iterator> #include <iterator>
#include <limits.h> #include <limits.h>
#include <locale> #include <locale>
#include <ranges>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <type_traits> #include <type_traits>
@ -356,16 +357,17 @@ std::string PathToFileName(std::string_view path)
return file_name + extension; return file_name + extension;
} }
std::vector<std::string> SplitString(const std::string& str, const char delim) std::vector<std::string> SplitString(std::string_view sv, const char delim)
{ {
std::istringstream iss(str); if (sv.empty())
std::vector<std::string> output(1); return {std::string()};
while (std::getline(iss, *output.rbegin(), delim)) const std::ranges::split_view string_views(sv, delim);
output.push_back(""); std::ranges::transform_view strings(string_views,
[](auto&& r) { return std::string(r.data(), r.size()); });
output.pop_back(); // TODO: Use C++23 std::from_range
return output; return {strings.begin(), strings.end()};
} }
std::string TabsToSpaces(int tab_size, std::string str) std::string TabsToSpaces(int tab_size, std::string str)

View File

@ -199,7 +199,7 @@ std::from_chars_result FromChars(std::string_view sv, T& value,
std::string TabsToSpaces(int tab_size, std::string str); std::string TabsToSpaces(int tab_size, std::string str);
std::vector<std::string> SplitString(const std::string& str, char delim); std::vector<std::string> SplitString(std::string_view sv, char delim);
// "C:/Windows/winhelp.exe" to "C:/Windows/", "winhelp", ".exe" // "C:/Windows/winhelp.exe" to "C:/Windows/", "winhelp", ".exe"
// This requires forward slashes to be used for the path separators, even on Windows. // This requires forward slashes to be used for the path separators, even on Windows.

View File

@ -192,3 +192,35 @@ TEST(StringUtil, SplitPathBackslashesNotRecognizedAsSeparators)
} }
// TODO: add `SplitPath` test coverage for paths containing Windows drives, e.g., "C:". // TODO: add `SplitPath` test coverage for paths containing Windows drives, e.g., "C:".
TEST(StringUtil, SplitString)
{
using V = std::vector<std::string>;
const char d = ',';
EXPECT_EQ(SplitString("", d), V({""}));
EXPECT_EQ(SplitString("a", d), V({"a"}));
EXPECT_EQ(SplitString("ab", d), V({"ab"}));
EXPECT_EQ(SplitString(",", d), V({"", ""}));
EXPECT_EQ(SplitString("a,", d), V({"a", ""}));
EXPECT_EQ(SplitString(",b", d), V({"", "b"}));
EXPECT_EQ(SplitString("a,b", d), V({"a", "b"}));
EXPECT_EQ(SplitString("ab,", d), V({"ab", ""}));
EXPECT_EQ(SplitString(",ab", d), V({"", "ab"}));
EXPECT_EQ(SplitString("ab,,", d), V({"ab", "", ""}));
EXPECT_EQ(SplitString(",ab,", d), V({"", "ab", ""}));
EXPECT_EQ(SplitString(",,ab", d), V({"", "", "ab"}));
EXPECT_EQ(SplitString("a,,", d), V({"a", "", ""}));
EXPECT_EQ(SplitString("a,b,", d), V({"a", "b", ""}));
EXPECT_EQ(SplitString("a,,c", d), V({"a", "", "c"}));
EXPECT_EQ(SplitString(",b,", d), V({"", "b", ""}));
EXPECT_EQ(SplitString(",b,c", d), V({"", "b", "c"}));
EXPECT_EQ(SplitString(",,c", d), V({"", "", "c"}));
EXPECT_EQ(SplitString(",,", d), V({"", "", ""}));
EXPECT_EQ(SplitString("abc", d), V({"abc"}));
EXPECT_EQ(SplitString("a,bc", d), V({"a", "bc"}));
EXPECT_EQ(SplitString("ab,c", d), V({"ab", "c"}));
EXPECT_EQ(SplitString("abc,", d), V({"abc", ""}));
EXPECT_EQ(SplitString(",abc", d), V({"", "abc"}));
EXPECT_EQ(SplitString("abc,,", d), V({"abc", "", ""}));
EXPECT_EQ(SplitString(",,abc", d), V({"", "", "abc"}));
}