aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuqian Yang <crupest@crupest.life>2025-10-17 09:46:56 +0800
committerYuqian Yang <crupest@crupest.life>2025-10-17 09:46:56 +0800
commit9e4419826b3e23c63567591701a2834a837da98e (patch)
tree763838a83850f5cb07cff43915aa6be3a689bef0
parenta6b5b8b879a9a587ec0ad605722d5d6428d5e68c (diff)
downloadcru-9e4419826b3e23c63567591701a2834a837da98e.tar.gz
cru-9e4419826b3e23c63567591701a2834a837da98e.tar.bz2
cru-9e4419826b3e23c63567591701a2834a837da98e.zip
Toml remove String.
-rw-r--r--include/cru/base/StringUtil.h42
-rw-r--r--include/cru/toml/TomlDocument.h21
-rw-r--r--include/cru/toml/TomlParser.h4
-rw-r--r--src/base/StringUtil.cpp38
-rw-r--r--src/base/log/Logger.cpp2
-rw-r--r--src/toml/TomlDocument.cpp16
-rw-r--r--src/toml/TomlParser.cpp23
-rw-r--r--test/base/StringUtilTest.cpp2
-rw-r--r--test/toml/ParserTest.cpp14
9 files changed, 85 insertions, 77 deletions
diff --git a/include/cru/base/StringUtil.h b/include/cru/base/StringUtil.h
index f2373444..d79c0c23 100644
--- a/include/cru/base/StringUtil.h
+++ b/include/cru/base/StringUtil.h
@@ -5,6 +5,7 @@
#include <compare>
#include <functional>
#include <stdexcept>
+#include <string>
#include <string_view>
#include <type_traits>
#include <vector>
@@ -16,7 +17,7 @@ std::weak_ordering CaseInsensitiveCompare(std::string_view left,
std::string TrimBegin(std::string_view str);
std::string TrimEnd(std::string_view str);
std::string Trim(std::string_view str);
-} // namespace string
+bool IsSpace(std::string_view str);
namespace details {
struct SplitOptionsTag {};
@@ -24,43 +25,12 @@ struct SplitOptionsTag {};
using SplitOption = Bitmask<details::SplitOptionsTag>;
struct SplitOptions {
static constexpr SplitOption RemoveEmpty = SplitOption::FromOffset(1);
+ static constexpr SplitOption RemoveSpace = SplitOption::FromOffset(2);
};
-template <typename TString>
-std::vector<TString> Split(const TString& str, const TString& sep,
- SplitOption options = {}) {
- using size_type = typename TString::size_type;
-
- if (sep.empty()) throw std::invalid_argument("Sep can't be empty.");
- if (str.empty()) return {};
-
- size_type current_pos = 0;
- std::vector<TString> result;
-
- while (current_pos != TString::npos) {
- if (current_pos == str.size()) {
- if (!options.Has(SplitOptions::RemoveEmpty)) {
- result.push_back({});
- }
- break;
- }
-
- auto next_pos = str.find(sep, current_pos);
- auto sub = str.substr(current_pos, next_pos - current_pos);
- if (!(options.Has(SplitOptions::RemoveEmpty) && sub.empty())) {
- result.push_back(sub);
- }
- current_pos =
- next_pos == TString::npos ? TString::npos : next_pos + sep.size();
- }
-
- return result;
-}
-
-inline std::vector<std::string> Split(const char* str, const std::string& sep,
- SplitOption options = {}) {
- return Split<std::string>(std::string(str), sep, options);
-}
+std::vector<std::string> Split(std::string_view str, std::string_view sep,
+ SplitOption options = {});
+} // namespace string
using CodePoint = std::int32_t;
constexpr CodePoint k_invalid_code_point = -1;
diff --git a/include/cru/toml/TomlDocument.h b/include/cru/toml/TomlDocument.h
index d072d384..4cd3ab3e 100644
--- a/include/cru/toml/TomlDocument.h
+++ b/include/cru/toml/TomlDocument.h
@@ -3,7 +3,6 @@
#include "Base.h"
#include "cru/base/Base.h"
-#include "cru/base/String.h"
#include <optional>
#include <unordered_map>
@@ -16,9 +15,9 @@ class CRU_TOML_API TomlSection {
CRU_DEFAULT_MOVE(TomlSection)
public:
- std::optional<String> GetValue(const String& key) const;
- void SetValue(const String& key, String value);
- void DeleteValue(const String& key);
+ std::optional<std::string> GetValue(const std::string& key) const;
+ void SetValue(const std::string& key, std::string value);
+ void DeleteValue(const std::string& key);
auto begin() { return values_.begin(); }
auto end() { return values_.end(); }
@@ -28,7 +27,7 @@ class CRU_TOML_API TomlSection {
auto cend() const { return values_.cend(); }
private:
- std::unordered_map<String, String> values_;
+ std::unordered_map<std::string, std::string> values_;
};
class CRU_TOML_API TomlDocument {
@@ -38,11 +37,11 @@ class CRU_TOML_API TomlDocument {
CRU_DEFAULT_MOVE(TomlDocument)
public:
- TomlSection* GetSection(const String& name);
- TomlSection* GetSectionOrCreate(const String& name);
- const TomlSection* GetSection(const String& name) const;
- void SetSection(const String& name, TomlSection section);
- void DeleteSection(const String& name);
+ TomlSection* GetSection(const std::string& name);
+ TomlSection* GetSectionOrCreate(const std::string& name);
+ const TomlSection* GetSection(const std::string& name) const;
+ void SetSection(const std::string& name, TomlSection section);
+ void DeleteSection(const std::string& name);
auto begin() { return sections_.begin(); }
auto end() { return sections_.end(); }
@@ -52,6 +51,6 @@ class CRU_TOML_API TomlDocument {
auto cend() const { return sections_.cend(); }
private:
- std::unordered_map<String, TomlSection> sections_;
+ std::unordered_map<std::string, TomlSection> sections_;
};
} // namespace cru::toml
diff --git a/include/cru/toml/TomlParser.h b/include/cru/toml/TomlParser.h
index 76c270c3..b6532931 100644
--- a/include/cru/toml/TomlParser.h
+++ b/include/cru/toml/TomlParser.h
@@ -14,7 +14,7 @@ class CRU_TOML_API TomlParsingException : public Exception {
class CRU_TOML_API TomlParser {
public:
- explicit TomlParser(String input);
+ explicit TomlParser(std::string input);
CRU_DELETE_COPY(TomlParser)
CRU_DELETE_MOVE(TomlParser)
@@ -29,7 +29,7 @@ class CRU_TOML_API TomlParser {
void DoParse(TomlDocument& document);
private:
- String input_;
+ std::string input_;
std::optional<TomlDocument> cache_;
};
diff --git a/src/base/StringUtil.cpp b/src/base/StringUtil.cpp
index bbd201cd..42aea114 100644
--- a/src/base/StringUtil.cpp
+++ b/src/base/StringUtil.cpp
@@ -5,6 +5,7 @@
#include <algorithm>
#include <cctype>
#include <compare>
+#include <string_view>
namespace cru {
namespace string {
@@ -40,6 +41,43 @@ std::string Trim(std::string_view str) {
[](char c) { return !std::isspace(c); });
return std::string(iter1, str.cend() - (iter2 - str.crbegin()));
}
+
+bool IsSpace(std::string_view str) {
+ return std::ranges::all_of(str, [](char c) { return std::isspace(c); });
+}
+
+std::vector<std::string> Split(std::string_view str, std::string_view sep,
+ SplitOption options) {
+ using size_type = std::string_view::size_type;
+
+ if (sep.empty()) throw std::invalid_argument("Sep can't be empty.");
+ if (str.empty()) return {};
+
+ size_type current_pos = 0;
+ std::vector<std::string> result;
+
+ while (current_pos != std::string_view::npos) {
+ if (current_pos == str.size()) {
+ if (!options.Has(SplitOptions::RemoveEmpty)) {
+ result.push_back({});
+ }
+ break;
+ }
+
+ auto next_pos = str.find(sep, current_pos);
+ auto sub = str.substr(current_pos, next_pos == std::string_view::npos
+ ? std::string_view::npos
+ : next_pos - current_pos);
+ if (!(options.Has(SplitOptions::RemoveEmpty) && sub.empty() ||
+ options.Has(SplitOptions::RemoveSpace) && IsSpace(sub))) {
+ result.push_back(std::string(sub));
+ }
+ current_pos = next_pos == std::string_view::npos ? std::string_view::npos
+ : next_pos + sep.size();
+ }
+
+ return result;
+}
} // namespace string
using details::ExtractBits;
diff --git a/src/base/log/Logger.cpp b/src/base/log/Logger.cpp
index 4d3d72ba..2c0f3f07 100644
--- a/src/base/log/Logger.cpp
+++ b/src/base/log/Logger.cpp
@@ -96,7 +96,7 @@ void Logger::RemoveDebugTag(const std::string &tag) {
void Logger::LoadDebugTagFromEnv(const char *env_var, std::string sep) {
auto env = std::getenv(env_var);
if (env != nullptr) {
- for (auto tag : Split(std::string(env), sep)) {
+ for (auto tag : cru::string::Split(std::string(env), sep)) {
AddDebugTag(std::move(tag));
}
}
diff --git a/src/toml/TomlDocument.cpp b/src/toml/TomlDocument.cpp
index e9351538..af9e2ac8 100644
--- a/src/toml/TomlDocument.cpp
+++ b/src/toml/TomlDocument.cpp
@@ -1,7 +1,7 @@
#include "cru/toml/TomlDocument.h"
namespace cru::toml {
-std::optional<String> TomlSection::GetValue(const String& key) const {
+std::optional<std::string> TomlSection::GetValue(const std::string& key) const {
auto it = values_.find(key);
if (it == values_.end()) {
return std::nullopt;
@@ -9,13 +9,13 @@ std::optional<String> TomlSection::GetValue(const String& key) const {
return it->second;
}
-void TomlSection::SetValue(const String& key, String value) {
+void TomlSection::SetValue(const std::string& key, std::string value) {
values_[key] = std::move(value);
}
-void TomlSection::DeleteValue(const String& key) { values_.erase(key); }
+void TomlSection::DeleteValue(const std::string& key) { values_.erase(key); }
-TomlSection* TomlDocument::GetSection(const String& name) {
+TomlSection* TomlDocument::GetSection(const std::string& name) {
auto it = sections_.find(name);
if (it == sections_.end()) {
return nullptr;
@@ -23,7 +23,7 @@ TomlSection* TomlDocument::GetSection(const String& name) {
return &it->second;
}
-const TomlSection* TomlDocument::GetSection(const String& name) const {
+const TomlSection* TomlDocument::GetSection(const std::string& name) const {
auto it = sections_.find(name);
if (it == sections_.end()) {
return nullptr;
@@ -31,7 +31,7 @@ const TomlSection* TomlDocument::GetSection(const String& name) const {
return &it->second;
}
-TomlSection* TomlDocument::GetSectionOrCreate(const String& name) {
+TomlSection* TomlDocument::GetSectionOrCreate(const std::string& name) {
auto it = sections_.find(name);
if (it == sections_.end()) {
sections_[name] = TomlSection();
@@ -40,10 +40,10 @@ TomlSection* TomlDocument::GetSectionOrCreate(const String& name) {
return &it->second;
}
-void TomlDocument::SetSection(const String& name, TomlSection section) {
+void TomlDocument::SetSection(const std::string& name, TomlSection section) {
sections_[name] = std::move(section);
}
-void TomlDocument::DeleteSection(const String& name) { sections_.erase(name); }
+void TomlDocument::DeleteSection(const std::string& name) { sections_.erase(name); }
} // namespace cru::toml
diff --git a/src/toml/TomlParser.cpp b/src/toml/TomlParser.cpp
index 14442c3c..1aea5b73 100644
--- a/src/toml/TomlParser.cpp
+++ b/src/toml/TomlParser.cpp
@@ -1,8 +1,9 @@
#include "cru/toml/TomlParser.h"
+#include "cru/base/StringUtil.h"
#include "cru/toml/TomlDocument.h"
namespace cru::toml {
-TomlParser::TomlParser(String input) : input_(std::move(input)) {}
+TomlParser::TomlParser(std::string input) : input_(std::move(input)) {}
TomlParser::~TomlParser() = default;
@@ -17,25 +18,25 @@ TomlDocument TomlParser::Parse() {
}
void TomlParser::DoParse(TomlDocument& document) {
- std::vector<String> lines = input_.SplitToLines(true);
+ std::vector<std::string> lines = cru::string::Split(input_, "\n", cru::string::SplitOptions::RemoveSpace);
- String current_section_name;
+ std::string current_section_name;
for (auto& line : lines) {
- line.Trim();
- if (line.StartWith(u"[") && line.EndWith(u"]")) {
+ line = cru::string::Trim(line);
+ if (line.starts_with("[") && line.ends_with("]")) {
current_section_name = line.substr(1, line.size() - 2);
- } else if (line.StartWith(u"#")) {
+ } else if (line.starts_with("#")) {
// Ignore comments.
} else {
- auto equal_index = line.Find(u'=');
+ auto equal_index = line.find('=');
- if (equal_index == -1) {
- throw TomlParsingException("Invalid TOML line: " + line.ToUtf8());
+ if (equal_index == std::string::npos) {
+ throw TomlParsingException("Invalid TOML line: " + line);
}
- auto key = line.substr(0, equal_index).Trim();
- auto value = line.substr(equal_index + 1).Trim();
+ auto key = cru::string::Trim(line.substr(0, equal_index));
+ auto value = cru::string::Trim(line.substr(equal_index + 1));
document.GetSectionOrCreate(current_section_name)->SetValue(key, value);
}
diff --git a/test/base/StringUtilTest.cpp b/test/base/StringUtilTest.cpp
index 6b826d74..3ce4cff1 100644
--- a/test/base/StringUtilTest.cpp
+++ b/test/base/StringUtilTest.cpp
@@ -7,7 +7,7 @@ using cru::Index;
using cru::k_invalid_code_point;
TEST_CASE("StringUtil Split", "[string]") {
- using cru::Split;
+ using cru::string::Split;
REQUIRE(Split("abc", "b") == std::vector<std::string>{"a", "c"});
REQUIRE(Split("abcd", "bc") == std::vector<std::string>{"a", "d"});
REQUIRE(Split("abcdbcd", "bc") == std::vector<std::string>{"a", "d", "d"});
diff --git a/test/toml/ParserTest.cpp b/test/toml/ParserTest.cpp
index b35b932a..4a4ba212 100644
--- a/test/toml/ParserTest.cpp
+++ b/test/toml/ParserTest.cpp
@@ -7,7 +7,7 @@ using namespace cru::toml;
TEST_CASE("CruTomlParserTest Simple", "[toml]") {
TomlParser parser(
- uR"(
+ R"(
a1 = v1
a2 = v2
# comment
@@ -22,10 +22,10 @@ a5 = v5
a6 = v6
)");
auto document = parser.Parse();
- REQUIRE(document.GetSection(u"")->GetValue(u"a1") == u"v1");
- REQUIRE(document.GetSection(u"")->GetValue(u"a2") == u"v2");
- REQUIRE(document.GetSection(u"s1")->GetValue(u"a3") == u"v3");
- REQUIRE(document.GetSection(u"s1")->GetValue(u"a4") == u"v4");
- REQUIRE(document.GetSection(u"s2")->GetValue(u"a5") == u"v5");
- REQUIRE(document.GetSection(u"s2")->GetValue(u"a6") == u"v6");
+ REQUIRE(document.GetSection("")->GetValue("a1") == "v1");
+ REQUIRE(document.GetSection("")->GetValue("a2") == "v2");
+ REQUIRE(document.GetSection("s1")->GetValue("a3") == "v3");
+ REQUIRE(document.GetSection("s1")->GetValue("a4") == "v4");
+ REQUIRE(document.GetSection("s2")->GetValue("a5") == "v5");
+ REQUIRE(document.GetSection("s2")->GetValue("a6") == "v6");
}