StringUtil: Add SplitStringIntoArray function template.
This commit is contained in:
1 parent
84b136c994
commit
97ad5ad1a1
2 files changed
+50
No files matched your search
@@ -12,6 +12,7 @@
|
|||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
|
#include <ranges>
|
||||||
#include <span>
|
#include <span>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -182,6 +183,32 @@ std::from_chars_result FromChars(std::string_view sv, std::floating_point auto&
|
|||||||
|
|
||||||
std::vector<std::string> SplitString(const std::string& str, char delim);
|
std::vector<std::string> SplitString(const std::string& str, char delim);
|
||||||
|
|
||||||
|
// Returns `nullopt` if subject does not contain exactly (Count - 1) delim.
|
||||||
|
template <std::size_t Count>
|
||||||
|
requires(Count > 1)
|
||||||
|
std::optional<std::array<std::string_view, Count>> SplitStringIntoArray(std::string_view subject,
|
||||||
|
char delim)
|
||||||
|
{
|
||||||
|
std::optional<std::array<std::string_view, Count>> result;
|
||||||
|
result.emplace();
|
||||||
|
|
||||||
|
std::size_t index = 0;
|
||||||
|
for (auto&& item : subject | std::views::split(delim))
|
||||||
|
{
|
||||||
|
// Too many delim.
|
||||||
|
if (index == Count)
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
(*result)[index++] = std::string_view{item};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Too few delim.
|
||||||
|
if (index != Count)
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// "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.
|
||||||
bool SplitPath(std::string_view full_path, std::string* path, std::string* filename,
|
bool SplitPath(std::string_view full_path, std::string* path, std::string* filename,
|
||||||
|
|||||||
@@ -259,6 +259,29 @@ TEST(StringUtil, CaseInsensitiveContains_OverlappingMatches)
|
|||||||
EXPECT_TRUE(Common::CaseInsensitiveContains("ababababa", "bABa"));
|
EXPECT_TRUE(Common::CaseInsensitiveContains("ababababa", "bABa"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(StringUtil, SplitStringIntoArray)
|
||||||
|
{
|
||||||
|
constexpr auto subject0 = "";
|
||||||
|
EXPECT_FALSE(SplitStringIntoArray<2>(subject0, '.').has_value());
|
||||||
|
|
||||||
|
constexpr auto subject1 = "hello";
|
||||||
|
EXPECT_FALSE(SplitStringIntoArray<2>(subject1, '.').has_value());
|
||||||
|
|
||||||
|
constexpr auto subject2 = "hello.world";
|
||||||
|
const auto split2 = SplitStringIntoArray<2>(subject2, '.');
|
||||||
|
EXPECT_TRUE(split2.has_value() && split2->at(1) == "world");
|
||||||
|
EXPECT_FALSE(SplitStringIntoArray<3>(subject2, '.').has_value());
|
||||||
|
|
||||||
|
constexpr auto subject3 = "hello.universe.";
|
||||||
|
EXPECT_FALSE(SplitStringIntoArray<2>(subject3, '.').has_value());
|
||||||
|
const auto split3 = SplitStringIntoArray<3>(subject3, '.');
|
||||||
|
EXPECT_TRUE(split3.has_value() && split3->at(2) == "");
|
||||||
|
EXPECT_FALSE(SplitStringIntoArray<4>(subject3, '.').has_value());
|
||||||
|
|
||||||
|
constexpr auto subject4 = "=";
|
||||||
|
EXPECT_TRUE(SplitStringIntoArray<2>(subject4, '=').has_value());
|
||||||
|
}
|
||||||
|
|
||||||
TEST(StringUtil, CharacterEncodingConversion)
|
TEST(StringUtil, CharacterEncodingConversion)
|
||||||
{
|
{
|
||||||
// wstring
|
// wstring
|
||||||
|
|||||||
Reference in new issue
Block a user