diff options
author | Yuqian Yang <crupest@crupest.life> | 2025-10-17 09:46:56 +0800 |
---|---|---|
committer | Yuqian Yang <crupest@crupest.life> | 2025-10-17 09:46:56 +0800 |
commit | 9e4419826b3e23c63567591701a2834a837da98e (patch) | |
tree | 763838a83850f5cb07cff43915aa6be3a689bef0 | |
parent | a6b5b8b879a9a587ec0ad605722d5d6428d5e68c (diff) | |
download | cru-9e4419826b3e23c63567591701a2834a837da98e.tar.gz cru-9e4419826b3e23c63567591701a2834a837da98e.tar.bz2 cru-9e4419826b3e23c63567591701a2834a837da98e.zip |
Toml remove String.
-rw-r--r-- | include/cru/base/StringUtil.h | 42 | ||||
-rw-r--r-- | include/cru/toml/TomlDocument.h | 21 | ||||
-rw-r--r-- | include/cru/toml/TomlParser.h | 4 | ||||
-rw-r--r-- | src/base/StringUtil.cpp | 38 | ||||
-rw-r--r-- | src/base/log/Logger.cpp | 2 | ||||
-rw-r--r-- | src/toml/TomlDocument.cpp | 16 | ||||
-rw-r--r-- | src/toml/TomlParser.cpp | 23 | ||||
-rw-r--r-- | test/base/StringUtilTest.cpp | 2 | ||||
-rw-r--r-- | test/toml/ParserTest.cpp | 14 |
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"); } |