aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2022-01-08 17:35:10 +0800
committercrupest <crupest@outlook.com>2022-01-08 17:35:10 +0800
commitc38f1f7c273e85c0a6d197cb27424c9ca69e234d (patch)
treee87685469d9b442966b97f11a48d0bc48ffaf074
parent431cbdbe7d3ae8c45458dcf914717b0365ecd99a (diff)
downloadcru-c38f1f7c273e85c0a6d197cb27424c9ca69e234d.tar.gz
cru-c38f1f7c273e85c0a6d197cb27424c9ca69e234d.tar.bz2
cru-c38f1f7c273e85c0a6d197cb27424c9ca69e234d.zip
...
-rw-r--r--include/cru/common/String.hpp6
-rw-r--r--src/common/String.cpp78
-rw-r--r--test/common/StringTest.cpp37
3 files changed, 120 insertions, 1 deletions
diff --git a/include/cru/common/String.hpp b/include/cru/common/String.hpp
index bd079243..86e0a134 100644
--- a/include/cru/common/String.hpp
+++ b/include/cru/common/String.hpp
@@ -181,7 +181,13 @@ class CRU_BASE_API String {
}
public:
+ Index Find(value_type value, Index start = 0) const;
+
+ String& TrimStart();
String& TrimEnd();
+ String& Trim();
+
+ std::vector<String> SplitToLines(bool remove_space_line = false) const;
public:
void AppendCodePoint(CodePoint code_point);
diff --git a/src/common/String.cpp b/src/common/String.cpp
index 8d674369..ade2a72d 100644
--- a/src/common/String.cpp
+++ b/src/common/String.cpp
@@ -113,6 +113,8 @@ String::~String() {
String::String(from_buffer_tag, pointer buffer, Index size, Index capacity)
: buffer_(buffer), size_(size), capacity_(capacity) {}
+void String::clear() { resize(0); }
+
void String::resize(Index new_size) {
Expects(new_size >= 0);
@@ -211,6 +213,32 @@ String::iterator String::erase(const_iterator start, const_iterator end) {
return s;
}
+Index String::Find(value_type value, Index start) const {
+ Expects(start >= 0 && start <= size_);
+
+ for (Index i = start; i < size_; ++i) {
+ if (buffer_[i] == value) return i;
+ }
+ return -1;
+}
+
+String& String::TrimStart() {
+ if (size_ == 0) return *this;
+
+ auto start = begin();
+ while (start != end() && IsWhitespace(*start)) {
+ ++start;
+ }
+
+ if (start == end()) {
+ clear();
+ } else {
+ erase(begin(), start);
+ }
+
+ return *this;
+}
+
String& String::TrimEnd() {
if (size_ == 0) return *this;
while (size_ > 0 && IsWhitespace(buffer_[size_ - 1])) {
@@ -220,6 +248,56 @@ String& String::TrimEnd() {
return *this;
}
+String& String::Trim() {
+ TrimStart();
+ TrimEnd();
+ return *this;
+}
+
+std::vector<String> String::SplitToLines(bool remove_space_line) const {
+ std::vector<String> result;
+
+ if (size_ == 0) return result;
+
+ Index line_start = 0;
+ Index line_end = 0;
+ while (line_end < size_) {
+ if (buffer_[line_end] == '\n') {
+ if (remove_space_line) {
+ bool add = false;
+ for (Index i = line_start; i < line_end; i++) {
+ if (!IsWhitespace(buffer_[i])) {
+ add = true;
+ break;
+ }
+ }
+ if (add) result.emplace_back(begin() + line_start, begin() + line_end);
+ } else {
+ result.emplace_back(begin() + line_start, begin() + line_end);
+ }
+ line_start = line_end + 1;
+ line_end = line_start;
+ } else {
+ line_end++;
+ }
+ }
+
+ if (remove_space_line) {
+ bool add = false;
+ for (Index i = line_start; i < size_; i++) {
+ if (!IsWhitespace(buffer_[i])) {
+ add = true;
+ break;
+ }
+ }
+ if (add) result.emplace_back(begin() + line_start, begin() + size_);
+ } else {
+ result.emplace_back(begin() + line_start, begin() + size_);
+ }
+
+ return result;
+}
+
std::string String::ToUtf8() const { return cru::ToUtf8(buffer_, size_); }
void String::AppendCodePoint(CodePoint code_point) {
diff --git a/test/common/StringTest.cpp b/test/common/StringTest.cpp
index 53ed359f..f11f9197 100644
--- a/test/common/StringTest.cpp
+++ b/test/common/StringTest.cpp
@@ -19,7 +19,6 @@ TEST(String, IndexConvert) {
ASSERT_EQ(s.IndexFromCodeUnitToCodePoint(1), 1);
ASSERT_EQ(s.IndexFromCodeUnitToCodePoint(3), 3);
ASSERT_EQ(s.IndexFromCodeUnitToCodePoint(3), 3);
-
}
TEST(String, Format) {
@@ -28,3 +27,39 @@ TEST(String, Format) {
ASSERT_EQ(Format(u"{} + {} = {}", 123, 321, 444), String(u"123 + 321 = 444"));
}
+
+TEST(String, SplitToLines) {
+ using cru::String;
+
+ String s(u"abc\ndef\nghi");
+ auto lines = s.SplitToLines();
+ ASSERT_EQ(lines.size(), 3);
+ ASSERT_EQ(lines[0], String(u"abc"));
+ ASSERT_EQ(lines[1], String(u"def"));
+ ASSERT_EQ(lines[2], String(u"ghi"));
+}
+
+TEST(String, SplitToLinesWithEmptyLine) {
+ using cru::String;
+
+ String s(u"abc\n \ndef\n\nghi\n");
+ auto lines = s.SplitToLines();
+ ASSERT_EQ(lines.size(), 6);
+ ASSERT_EQ(lines[0], String(u"abc"));
+ ASSERT_EQ(lines[1], String(u" "));
+ ASSERT_EQ(lines[2], String(u"def"));
+ ASSERT_EQ(lines[3], String(u""));
+ ASSERT_EQ(lines[4], String(u"ghi"));
+ ASSERT_EQ(lines[5], String(u""));
+}
+
+TEST(String, SplitToLinesRemoveSpaceLine) {
+ using cru::String;
+
+ String s(u"abc\n \ndef\n\nghi\n");
+ auto lines = s.SplitToLines(true);
+ ASSERT_EQ(lines.size(), 3);
+ ASSERT_EQ(lines[0], String(u"abc"));
+ ASSERT_EQ(lines[1], String(u"def"));
+ ASSERT_EQ(lines[2], String(u"ghi"));
+}