aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2022-01-20 22:25:16 +0800
committercrupest <crupest@outlook.com>2022-01-20 22:25:16 +0800
commitb68d2027fe7505c14899db9fa1496b5ace09e25f (patch)
tree8361112fdf5a245794070ae8d58279c4b91cc54b
parent3c3a08a02a0f8fc56dc2da3374f025d4fdaf62c5 (diff)
downloadcru-b68d2027fe7505c14899db9fa1496b5ace09e25f.tar.gz
cru-b68d2027fe7505c14899db9fa1496b5ace09e25f.tar.bz2
cru-b68d2027fe7505c14899db9fa1496b5ace09e25f.zip
...
-rw-r--r--include/cru/common/Format.hpp3
-rw-r--r--include/cru/common/String.hpp68
-rw-r--r--include/cru/common/StringUtil.hpp36
-rw-r--r--include/cru/xml/XmlNode.hpp1
-rw-r--r--src/common/String.cpp304
-rw-r--r--src/common/StringUtil.cpp28
-rw-r--r--src/ui/mapper/PointMapper.cpp4
-rw-r--r--test/common/StringTest.cpp41
-rw-r--r--test/common/StringUtilTest.cpp17
9 files changed, 276 insertions, 226 deletions
diff --git a/include/cru/common/Format.hpp b/include/cru/common/Format.hpp
index c2fd2e09..1ad71262 100644
--- a/include/cru/common/Format.hpp
+++ b/include/cru/common/Format.hpp
@@ -2,7 +2,8 @@
#include "Exception.hpp"
#include "String.hpp"
-#include "cru/common/Base.hpp"
+
+#include <charconv>
namespace cru {
inline String ToString(bool value) {
diff --git a/include/cru/common/String.hpp b/include/cru/common/String.hpp
index dac81e8d..1d660623 100644
--- a/include/cru/common/String.hpp
+++ b/include/cru/common/String.hpp
@@ -5,18 +5,10 @@
#include "StringUtil.hpp"
#include <double-conversion/double-conversion.h>
-#include <algorithm>
-#include <array>
-#include <charconv>
#include <initializer_list>
#include <iterator>
-#include <limits>
-#include <stdexcept>
#include <string>
#include <string_view>
-#include <system_error>
-#include <tuple>
-#include <type_traits>
#include <vector>
namespace cru {
@@ -24,9 +16,6 @@ class StringView;
class CRU_BASE_API String {
public:
- static double_conversion::StringToDoubleConverter
- kDefaultStringToDoubleConverter;
-
using value_type = char16_t;
using size_type = Index;
using difference_type = Index;
@@ -181,24 +170,21 @@ class CRU_BASE_API String {
return String(this->buffer_ + start, size);
}
- public:
String& operator+=(value_type value) {
this->append(value);
return *this;
}
String& operator+=(StringView other);
+ public:
operator std::u16string_view() const {
return std::u16string_view(data(), size());
}
+ StringView View() const;
+
public:
Index Find(value_type value, Index start = 0) const;
-
- String& TrimStart();
- String& TrimEnd();
- String& Trim();
-
std::vector<String> Split(value_type separator,
bool remove_space_line = false) const;
std::vector<String> SplitToLines(bool remove_space_line = false) const;
@@ -206,6 +192,10 @@ class CRU_BASE_API String {
bool StartWith(StringView str) const;
bool EndWith(StringView str) const;
+ String& TrimStart();
+ String& TrimEnd();
+ String& Trim();
+
public:
void AppendCodePoint(CodePoint code_point);
@@ -218,6 +208,11 @@ class CRU_BASE_API String {
Range RangeFromCodeUnitToCodePoint(Range code_unit_range) const;
Range RangeFromCodePointToCodeUnit(Range code_point_range) const;
+ float ParseToFloat(Index* processed_characters_count = nullptr) const;
+ double ParseToDouble(Index* processed_characters_count = nullptr) const;
+ std::vector<float> ParseToFloatList(value_type separator = u' ') const;
+ std::vector<double> ParseToDoubleList(value_type separator = u' ') const;
+
#ifdef CRU_PLATFORM_WINDOWS
const wchar_t* WinCStr() const {
return reinterpret_cast<const wchar_t*>(c_str());
@@ -231,11 +226,6 @@ class CRU_BASE_API String {
int Compare(const String& other) const;
- float ParseToFloat(Index* processed_characters_count = nullptr) const;
- double ParseToDouble(Index* processed_characters_count = nullptr) const;
- std::vector<float> ParseToFloatList(value_type separator = u' ');
- std::vector<double> ParseToDoubleList(value_type separator = u' ');
-
private:
static char16_t kEmptyBuffer[1];
@@ -247,6 +237,9 @@ class CRU_BASE_API String {
class CRU_BASE_API StringView {
public:
+ static double_conversion::StringToDoubleConverter
+ kDefaultStringToDoubleConverter;
+
using value_type = char16_t;
using size_type = Index;
using difference_type = Index;
@@ -307,16 +300,39 @@ class CRU_BASE_API StringView {
StringView substr(Index pos);
StringView substr(Index pos, Index size);
- int Compare(const StringView& other) const;
-
- String ToString() const { return String(ptr_, size_); }
-
value_type operator[](Index index) const { return ptr_[index]; }
operator std::u16string_view() const {
return std::u16string_view(data(), size());
}
+ public:
+ int Compare(const StringView& other) const;
+
+ String ToString() const { return String(ptr_, size_); }
+
+ Utf16CodePointIterator CodePointIterator() const {
+ return Utf16CodePointIterator(ptr_, size_);
+ }
+
+ Index Find(value_type value, Index start = 0) const;
+ std::vector<String> Split(value_type separator,
+ bool remove_space_line = false) const;
+ std::vector<String> SplitToLines(bool remove_space_line = false) const;
+
+ bool StartWith(StringView str) const;
+ bool EndWith(StringView str) const;
+
+ Index IndexFromCodeUnitToCodePoint(Index code_unit_index) const;
+ Index IndexFromCodePointToCodeUnit(Index code_point_index) const;
+ Range RangeFromCodeUnitToCodePoint(Range code_unit_range) const;
+ Range RangeFromCodePointToCodeUnit(Range code_point_range) const;
+
+ float ParseToFloat(Index* processed_characters_count = nullptr) const;
+ double ParseToDouble(Index* processed_characters_count = nullptr) const;
+ std::vector<float> ParseToFloatList(value_type separator = u' ') const;
+ std::vector<double> ParseToDoubleList(value_type separator = u' ') const;
+
std::string ToUtf8() const;
private:
diff --git a/include/cru/common/StringUtil.hpp b/include/cru/common/StringUtil.hpp
index 2d53fc2b..c840960d 100644
--- a/include/cru/common/StringUtil.hpp
+++ b/include/cru/common/StringUtil.hpp
@@ -2,9 +2,6 @@
#include "Base.hpp"
#include <functional>
-#include <stdexcept>
-#include <string>
-#include <string_view>
namespace cru {
using CodePoint = std::int32_t;
@@ -118,9 +115,6 @@ using Utf8CodePointIterator = CodePointIterator<char, &Utf8NextCodePoint>;
using Utf16CodePointIterator = CodePointIterator<char16_t, &Utf16NextCodePoint>;
-void CRU_BASE_API Utf8EncodeCodePointAppend(CodePoint code_point,
- std::string& str);
-
namespace details {
template <typename UInt, int number_of_bit, typename ReturnType>
inline std::enable_if_t<std::is_unsigned_v<UInt>, ReturnType> ExtractBits(
@@ -129,18 +123,18 @@ inline std::enable_if_t<std::is_unsigned_v<UInt>, ReturnType> ExtractBits(
}
} // namespace details
-template <typename TAppend>
-bool Utf8EncodeCodePointAppendWithFunc(CodePoint code_point, TAppend&& append) {
- auto write_continue_byte = [&append](std::uint8_t byte6) {
- append((1u << 7) + (((1u << 6) - 1) & byte6));
+template <typename TStr>
+bool Utf8EncodeCodePointAppend(CodePoint code_point, TStr& str) {
+ auto write_continue_byte = [&str](std::uint8_t byte6) {
+ str.push_back((1u << 7) + (((1u << 6) - 1) & byte6));
};
if (code_point >= 0 && code_point <= 0x007F) {
- append(static_cast<char>(code_point));
+ str.push_back(static_cast<char>(code_point));
return true;
} else if (code_point >= 0x0080 && code_point <= 0x07FF) {
std::uint32_t unsigned_code_point = code_point;
- append(
+ str.push_back(
static_cast<char>(details::ExtractBits<std::uint32_t, 5, std::uint8_t>(
(unsigned_code_point >> 6)) +
0b11000000));
@@ -149,7 +143,7 @@ bool Utf8EncodeCodePointAppendWithFunc(CodePoint code_point, TAppend&& append) {
return true;
} else if (code_point >= 0x0800 && code_point <= 0xFFFF) {
std::uint32_t unsigned_code_point = code_point;
- append(
+ str.push_back(
static_cast<char>(details::ExtractBits<std::uint32_t, 4, std::uint8_t>(
(unsigned_code_point >> (6 * 2))) +
0b11100000));
@@ -160,7 +154,7 @@ bool Utf8EncodeCodePointAppendWithFunc(CodePoint code_point, TAppend&& append) {
return true;
} else if (code_point >= 0x10000 && code_point <= 0x10FFFF) {
std::uint32_t unsigned_code_point = code_point;
- append(
+ str.push_back(
static_cast<char>(details::ExtractBits<std::uint32_t, 3, std::uint8_t>(
(unsigned_code_point >> (6 * 3))) +
0b11110000));
@@ -176,19 +170,18 @@ bool Utf8EncodeCodePointAppendWithFunc(CodePoint code_point, TAppend&& append) {
}
}
-template <typename TAppend>
-bool Utf16EncodeCodePointAppendWithFunc(CodePoint code_point,
- TAppend&& append) {
+template <typename TStr>
+bool Utf16EncodeCodePointAppend(CodePoint code_point, TStr& str) {
if ((code_point >= 0 && code_point <= 0xD7FF) ||
(code_point >= 0xE000 && code_point <= 0xFFFF)) {
- append(static_cast<char16_t>(code_point));
+ str.push_back(static_cast<char16_t>(code_point));
return true;
} else if (code_point >= 0x10000 && code_point <= 0x10FFFF) {
std::uint32_t u = code_point - 0x10000;
- append(static_cast<char16_t>(
+ str.push_back(static_cast<char16_t>(
details::ExtractBits<std::uint32_t, 10, std::uint32_t>(u >> 10) +
0xD800u));
- append(static_cast<char16_t>(
+ str.push_back(static_cast<char16_t>(
details::ExtractBits<std::uint32_t, 10, std::uint32_t>(u) + 0xDC00u));
return true;
} else {
@@ -196,9 +189,6 @@ bool Utf16EncodeCodePointAppendWithFunc(CodePoint code_point,
}
}
-std::string CRU_BASE_API ToUtf8(const char16_t* ptr, Index size);
-std::u16string CRU_BASE_API ToUtf16(const char* s, Index size);
-
// If given s is not a valid utf16 string, return value is UD.
bool CRU_BASE_API Utf16IsValidInsertPosition(const char16_t* ptr, Index size,
Index position);
diff --git a/include/cru/xml/XmlNode.hpp b/include/cru/xml/XmlNode.hpp
index 0972037a..71753410 100644
--- a/include/cru/xml/XmlNode.hpp
+++ b/include/cru/xml/XmlNode.hpp
@@ -5,6 +5,7 @@
#include "cru/common/String.hpp"
#include <algorithm>
+#include <optional>
#include <unordered_map>
#include <vector>
diff --git a/src/common/String.cpp b/src/common/String.cpp
index 3721eed3..24fb4071 100644
--- a/src/common/String.cpp
+++ b/src/common/String.cpp
@@ -11,14 +11,6 @@
#include <string_view>
namespace cru {
-double_conversion::StringToDoubleConverter
- String::kDefaultStringToDoubleConverter(
- double_conversion::StringToDoubleConverter::ALLOW_LEADING_SPACES |
- double_conversion::StringToDoubleConverter::ALLOW_TRAILING_SPACES |
- double_conversion::StringToDoubleConverter::
- ALLOW_CASE_INSENSIBILITY,
- 0.0, NAN, "infinity", "nan");
-
template <typename C>
Index GetStrSize(const C* str) {
Index i = 0;
@@ -29,11 +21,16 @@ Index GetStrSize(const C* str) {
}
String String::FromUtf8(const char* str) {
- return FromUtf16(cru::ToUtf16(str, GetStrSize(str)));
+ return FromUtf8(str, GetStrSize(str));
}
String String::FromUtf8(const char* str, Index size) {
- return FromUtf16(cru::ToUtf16(str, size));
+ String result;
+ Utf8CodePointIterator iter(str, size);
+ for (auto cp : iter) {
+ Utf16EncodeCodePointAppend(cp, result);
+ }
+ return result;
}
char16_t String::kEmptyBuffer[1] = {0};
@@ -190,6 +187,7 @@ String::iterator String::insert(const_iterator pos, const_iterator str,
}
Index index = pos - cbegin();
+
Index new_size = size_ + size;
if (new_size > capacity_) {
auto new_capacity = capacity_;
@@ -229,15 +227,32 @@ String::iterator String::erase(const_iterator start, const_iterator end) {
return s;
}
+String& String::operator+=(StringView other) {
+ append(other);
+ return *this;
+}
+
+StringView String::View() const { return *this; }
+
Index String::Find(value_type value, Index start) const {
- Expects(start >= 0 && start <= size_);
+ return View().Find(value, start);
+}
- for (Index i = start; i < size_; ++i) {
- if (buffer_[i] == value) return i;
- }
- return -1;
+std::vector<String> String::Split(value_type separator,
+ bool remove_space_line) const {
+ return View().Split(separator, remove_space_line);
}
+std::vector<String> String::SplitToLines(bool remove_space_line) const {
+ return View().SplitToLines(remove_space_line);
+}
+
+bool String::StartWith(StringView str) const { return View().StartWith(str); }
+
+bool String::EndWith(StringView str) const { return View().EndWith(str); }
+
+std::string String::ToUtf8() const { return View().ToUtf8(); }
+
String& String::TrimStart() {
if (size_ == 0) return *this;
@@ -270,8 +285,132 @@ String& String::Trim() {
return *this;
}
-std::vector<String> String::Split(value_type separator,
- bool remove_space_line) const {
+void String::AppendCodePoint(CodePoint code_point) {
+ if (Utf16EncodeCodePointAppend(code_point, *this)) {
+ throw TextEncodeException(u"Code point out of range.");
+ }
+}
+
+Index String::IndexFromCodeUnitToCodePoint(Index code_unit_index) const {
+ return View().IndexFromCodeUnitToCodePoint(code_unit_index);
+}
+
+Index String::IndexFromCodePointToCodeUnit(Index code_point_index) const {
+ return View().IndexFromCodePointToCodeUnit(code_point_index);
+}
+
+Range String::RangeFromCodeUnitToCodePoint(Range code_unit_range) const {
+ return View().RangeFromCodeUnitToCodePoint(code_unit_range);
+}
+
+Range String::RangeFromCodePointToCodeUnit(Range code_point_range) const {
+ return View().RangeFromCodePointToCodeUnit(code_point_range);
+}
+
+float String::ParseToFloat(Index* processed_characters_count) const {
+ return View().ParseToFloat(processed_characters_count);
+}
+
+double String::ParseToDouble(Index* processed_characters_count) const {
+ return View().ParseToDouble(processed_characters_count);
+}
+
+std::vector<float> String::ParseToFloatList(value_type separator) const {
+ return View().ParseToFloatList(separator);
+}
+
+std::vector<double> String::ParseToDoubleList(value_type separator) const {
+ return View().ParseToDoubleList(separator);
+}
+
+namespace {
+inline int Compare(char16_t left, char16_t right) {
+ if (left < right) return -1;
+ if (left > right) return 1;
+ return 0;
+}
+} // namespace
+
+int String::Compare(const String& other) const {
+ const_iterator i1 = cbegin();
+ const_iterator i2 = other.cbegin();
+
+ const_iterator end1 = cend();
+ const_iterator end2 = other.cend();
+
+ while (i1 != end1 && i2 != end2) {
+ int r = cru::Compare(*i1, *i2);
+ if (r != 0) return r;
+ i1++;
+ i2++;
+ }
+
+ if (i1 == end1) {
+ if (i2 == end2) {
+ return 0;
+ } else {
+ return -1;
+ }
+ } else {
+ return 1;
+ }
+}
+
+double_conversion::StringToDoubleConverter
+ StringView::kDefaultStringToDoubleConverter(
+ double_conversion::StringToDoubleConverter::ALLOW_LEADING_SPACES |
+ double_conversion::StringToDoubleConverter::ALLOW_TRAILING_SPACES |
+ double_conversion::StringToDoubleConverter::
+ ALLOW_CASE_INSENSIBILITY,
+ 0.0, NAN, "infinity", "nan");
+
+int StringView::Compare(const StringView& other) const {
+ const_iterator i1 = cbegin();
+ const_iterator i2 = other.cbegin();
+
+ const_iterator end1 = cend();
+ const_iterator end2 = other.cend();
+
+ while (i1 != end1 && i2 != end2) {
+ int r = cru::Compare(*i1, *i2);
+ if (r != 0) return r;
+ i1++;
+ i2++;
+ }
+
+ if (i1 == end1) {
+ if (i2 == end2) {
+ return 0;
+ } else {
+ return -1;
+ }
+ } else {
+ return 1;
+ }
+}
+
+StringView StringView::substr(Index pos) {
+ Expects(pos >= 0 && pos < size_);
+ return StringView(ptr_ + pos, size_ - pos);
+}
+
+StringView StringView::substr(Index pos, Index size) {
+ Expects(pos >= 0 && pos < size_);
+
+ return StringView(ptr_ + pos, std::min(size, size_ - pos));
+}
+
+Index StringView::Find(value_type value, Index start) const {
+ Expects(start >= 0 && start <= size_);
+
+ for (Index i = start; i < size_; ++i) {
+ if (ptr_[i] == value) return i;
+ }
+ return -1;
+}
+
+std::vector<String> StringView::Split(value_type separator,
+ bool remove_space_line) const {
std::vector<String> result;
if (size_ == 0) return result;
@@ -279,11 +418,11 @@ std::vector<String> String::Split(value_type separator,
Index line_start = 0;
Index line_end = 0;
while (line_end < size_) {
- if (buffer_[line_end] == separator) {
+ if (ptr_[line_end] == separator) {
if (remove_space_line) {
bool add = false;
for (Index i = line_start; i < line_end; i++) {
- if (!IsWhitespace(buffer_[i])) {
+ if (!IsWhitespace(ptr_[i])) {
add = true;
break;
}
@@ -302,7 +441,7 @@ std::vector<String> String::Split(value_type separator,
if (remove_space_line) {
bool add = false;
for (Index i = line_start; i < size_; i++) {
- if (!IsWhitespace(buffer_[i])) {
+ if (!IsWhitespace(ptr_[i])) {
add = true;
break;
}
@@ -315,30 +454,21 @@ std::vector<String> String::Split(value_type separator,
return result;
}
-std::vector<String> String::SplitToLines(bool remove_space_line) const {
+std::vector<String> StringView::SplitToLines(bool remove_space_line) const {
return Split(u'\n', remove_space_line);
}
-bool String::StartWith(StringView str) const {
+bool StringView::StartWith(StringView str) const {
if (str.size() > size_) return false;
- return std::memcmp(str.data(), buffer_, str.size()) == 0;
+ return std::memcmp(str.data(), ptr_, str.size()) == 0;
}
-bool String::EndWith(StringView str) const {
+bool StringView::EndWith(StringView str) const {
if (str.size() > size_) return false;
- return std::memcmp(str.data(), buffer_ + size_ - str.size(), str.size()) == 0;
+ return std::memcmp(str.data(), ptr_ + size_ - str.size(), str.size()) == 0;
}
-std::string String::ToUtf8() const { return cru::ToUtf8(buffer_, size_); }
-
-void String::AppendCodePoint(CodePoint code_point) {
- if (!Utf16EncodeCodePointAppendWithFunc(
- code_point, [this](char16_t c) { this->push_back(c); })) {
- throw TextEncodeException(u"Code point out of range.");
- }
-}
-
-Index String::IndexFromCodeUnitToCodePoint(Index code_unit_index) const {
+Index StringView::IndexFromCodeUnitToCodePoint(Index code_unit_index) const {
auto iter = CodePointIterator();
Index result = 0;
while (iter.GetPosition() < code_unit_index && !iter.IsPastEnd()) {
@@ -348,7 +478,7 @@ Index String::IndexFromCodeUnitToCodePoint(Index code_unit_index) const {
return result;
}
-Index String::IndexFromCodePointToCodeUnit(Index code_point_index) const {
+Index StringView::IndexFromCodePointToCodeUnit(Index code_point_index) const {
auto iter = CodePointIterator();
Index cpi = 0;
while (cpi < code_point_index && !iter.IsPastEnd()) {
@@ -358,106 +488,51 @@ Index String::IndexFromCodePointToCodeUnit(Index code_point_index) const {
return iter.GetPosition();
}
-Range String::RangeFromCodeUnitToCodePoint(Range code_unit_range) const {
+Range StringView::RangeFromCodeUnitToCodePoint(Range code_unit_range) const {
return Range::FromTwoSides(
IndexFromCodeUnitToCodePoint(code_unit_range.GetStart()),
IndexFromCodeUnitToCodePoint(code_unit_range.GetEnd()));
}
-Range String::RangeFromCodePointToCodeUnit(Range code_point_range) const {
+Range StringView::RangeFromCodePointToCodeUnit(Range code_point_range) const {
return Range::FromTwoSides(
IndexFromCodePointToCodeUnit(code_point_range.GetStart()),
IndexFromCodePointToCodeUnit(code_point_range.GetEnd()));
}
-String& String::operator+=(StringView other) {
- append(other);
- return *this;
-}
-
-namespace {
-inline int Compare(char16_t left, char16_t right) {
- if (left < right) return -1;
- if (left > right) return 1;
- return 0;
-}
-} // namespace
-
-int String::Compare(const String& other) const {
- const_iterator i1 = cbegin();
- const_iterator i2 = other.cbegin();
-
- const_iterator end1 = cend();
- const_iterator end2 = other.cend();
-
- while (i1 != end1 && i2 != end2) {
- int r = cru::Compare(*i1, *i2);
- if (r != 0) return r;
- i1++;
- i2++;
- }
-
- if (i1 == end1) {
- if (i2 == end2) {
- return 0;
- } else {
- return -1;
- }
- } else {
- return 1;
- }
-}
-
-int StringView::Compare(const StringView& other) const {
- const_iterator i1 = cbegin();
- const_iterator i2 = other.cbegin();
-
- const_iterator end1 = cend();
- const_iterator end2 = other.cend();
-
- while (i1 != end1 && i2 != end2) {
- int r = cru::Compare(*i1, *i2);
- if (r != 0) return r;
- i1++;
- i2++;
- }
-
- if (i1 == end1) {
- if (i2 == end2) {
- return 0;
- } else {
- return -1;
- }
- } else {
- return 1;
+std::string StringView::ToUtf8() const {
+ std::string result;
+ for (auto cp : CodePointIterator()) {
+ Utf8EncodeCodePointAppend(cp, result);
}
+ return result;
}
-float String::ParseToFloat(Index* processed_characters_count) const {
+float StringView::ParseToFloat(Index* processed_characters_count) const {
int pcc;
auto result = kDefaultStringToDoubleConverter.StringToFloat(
- reinterpret_cast<const uc16*>(buffer_), static_cast<int>(size_), &pcc);
+ reinterpret_cast<const uc16*>(ptr_), static_cast<int>(size_), &pcc);
if (processed_characters_count != nullptr) {
*processed_characters_count = pcc;
}
return result;
}
-double String::ParseToDouble(Index* processed_characters_count) const {
+double StringView::ParseToDouble(Index* processed_characters_count) const {
int pcc;
auto result = kDefaultStringToDoubleConverter.StringToDouble(
- reinterpret_cast<const uc16*>(buffer_), static_cast<int>(size_), &pcc);
+ reinterpret_cast<const uc16*>(ptr_), static_cast<int>(size_), &pcc);
if (processed_characters_count != nullptr) {
*processed_characters_count = pcc;
}
return result;
}
-std::vector<float> String::ParseToFloatList(value_type separator) {
+std::vector<float> StringView::ParseToFloatList(value_type separator) const {
std::vector<float> result;
- auto list = Split(separator);
+ auto list = Split(separator, true);
for (auto& item : list) {
- auto value = ParseToFloat();
+ auto value = item.ParseToFloat();
if (std::isnan(value)) {
throw Exception(u"Invalid double value.");
}
@@ -466,11 +541,11 @@ std::vector<float> String::ParseToFloatList(value_type separator) {
return result;
}
-std::vector<double> String::ParseToDoubleList(value_type separator) {
+std::vector<double> StringView::ParseToDoubleList(value_type separator) const {
std::vector<double> result;
- auto list = Split(separator);
+ auto list = Split(separator, true);
for (auto& item : list) {
- auto value = ParseToDouble();
+ auto value = item.ParseToDouble();
if (std::isnan(value)) {
throw Exception(u"Invalid double value.");
}
@@ -479,19 +554,6 @@ std::vector<double> String::ParseToDoubleList(value_type separator) {
return result;
}
-StringView StringView::substr(Index pos) {
- Expects(pos >= 0 && pos < size_);
- return StringView(ptr_ + pos, size_ - pos);
-}
-
-StringView StringView::substr(Index pos, Index size) {
- Expects(pos >= 0 && pos < size_);
-
- return StringView(ptr_ + pos, std::min(size, size_ - pos));
-}
-
-std::string StringView::ToUtf8() const { return cru::ToUtf8(ptr_, size_); }
-
String ToLower(StringView s) {
String result;
for (auto c : s) result.push_back(ToLower(c));
diff --git a/src/common/StringUtil.cpp b/src/common/StringUtil.cpp
index 1f5f6150..2bec815d 100644
--- a/src/common/StringUtil.cpp
+++ b/src/common/StringUtil.cpp
@@ -149,34 +149,6 @@ CodePoint Utf16PreviousCodePoint(const char16_t* ptr, Index size, Index current,
return result;
}
-void Utf8EncodeCodePointAppend(CodePoint code_point, std::string& str) {
- if (!Utf8EncodeCodePointAppendWithFunc(code_point,
- [&str](char c) { str.push_back(c); }))
- throw TextEncodeException(u"Code point out of range.");
-}
-
-void Utf16EncodeCodePointAppend(CodePoint code_point, std::u16string& str) {
- if (!Utf16EncodeCodePointAppendWithFunc(
- code_point, [&str](char16_t c) { str.push_back(c); }))
- throw TextEncodeException(u"Code point out of range.");
-}
-
-std::string ToUtf8(const char16_t* ptr, Index size) {
- std::string result;
- for (CodePoint cp : Utf16CodePointIterator(ptr, size)) {
- Utf8EncodeCodePointAppend(cp, result);
- }
- return result;
-}
-
-std::u16string ToUtf16(const char* ptr, Index size) {
- std::u16string result;
- for (CodePoint cp : Utf8CodePointIterator(ptr, size)) {
- Utf16EncodeCodePointAppend(cp, result);
- }
- return result;
-}
-
bool Utf16IsValidInsertPosition(const char16_t* ptr, Index size,
Index position) {
if (position < 0) return false;
diff --git a/src/ui/mapper/PointMapper.cpp b/src/ui/mapper/PointMapper.cpp
index abd586a4..59a7b187 100644
--- a/src/ui/mapper/PointMapper.cpp
+++ b/src/ui/mapper/PointMapper.cpp
@@ -1,3 +1,5 @@
#include "cru/ui/mapper/PointMapper.hpp"
-namespace cru::ui::mapper {}
+namespace cru::ui::mapper {
+
+}
diff --git a/test/common/StringTest.cpp b/test/common/StringTest.cpp
index 737a93ad..0a60e729 100644
--- a/test/common/StringTest.cpp
+++ b/test/common/StringTest.cpp
@@ -70,14 +70,35 @@ TEST(String, SplitToLinesRemoveSpaceLine) {
ASSERT_EQ(lines[2], String(u"ghi"));
}
-TEST(String, ParseToFloat) {
- using cru::String;
- ASSERT_EQ(String(u"3.14159").ParseToDouble(), 3.14159);
- ASSERT_EQ(String(u" 3.14159").ParseToDouble(), 3.14159);
- ASSERT_EQ(String(u" 3.14159 ").ParseToDouble(), 3.14159);
-
- cru::Index processed_char_count = 0;
- ASSERT_EQ(String(u" 3.14159 garbege").ParseToDouble(&processed_char_count),
- 3.14159);
- ASSERT_EQ(processed_char_count, 9);
+TEST(StringView, ToUtf8) {
+ using cru::StringView;
+ StringView utf16_text = u"aπ你🤣!";
+ std::string_view utf8_text = "aπ你🤣!";
+
+ ASSERT_EQ(utf16_text.ToUtf8(), utf8_text);
+}
+
+TEST(String, FromUtf8) {
+ std::u16string_view utf16_text = u"aπ你🤣!";
+ std::string_view utf8_text = "aπ你🤣!";
+
+ ASSERT_EQ(cru::String::FromUtf8(utf8_text), utf16_text);
+}
+
+TEST(StringView, ParseToDouble) {
+ using cru::StringView;
+ ASSERT_EQ(StringView(u"3.14159").ParseToDouble(), 3.14159);
+ ASSERT_EQ(StringView(u" 3.14159").ParseToDouble(), 3.14159);
+ ASSERT_EQ(StringView(u" 3.14159 ").ParseToDouble(), 3.14159);
+}
+
+TEST(String, ParseToDoubleList) {
+ using cru::StringView;
+
+ auto list = StringView(u" 1.23 2.34 3.45 ").ParseToDoubleList();
+
+ ASSERT_EQ(list.size(), 3);
+ ASSERT_EQ(list[0], 1.23);
+ ASSERT_EQ(list[1], 2.34);
+ ASSERT_EQ(list[2], 3.45);
}
diff --git a/test/common/StringUtilTest.cpp b/test/common/StringUtilTest.cpp
index 5e1753b8..0fc63685 100644
--- a/test/common/StringUtilTest.cpp
+++ b/test/common/StringUtilTest.cpp
@@ -1,3 +1,4 @@
+#include "cru/common/String.hpp"
#include "cru/common/StringUtil.hpp"
#include <gtest/gtest.h>
@@ -91,22 +92,6 @@ TEST(StringUtil, Utf16CodePointIterator) {
ASSERT_EQ(code_points, expected_code_points);
}
-TEST(StringUtil, ToUtf8) {
- using cru::ToUtf8;
- std::u16string_view utf16_text = u"aπ你🤣!";
- std::string_view utf8_text = "aπ你🤣!";
-
- ASSERT_EQ(ToUtf8(utf16_text.data(), utf16_text.size()), utf8_text);
-}
-
-TEST(StringUtil, ToUtf16) {
- using cru::ToUtf16;
- std::u16string_view utf16_text = u"aπ你🤣!";
- std::string_view utf8_text = "aπ你🤣!";
-
- ASSERT_EQ(ToUtf16(utf8_text.data(), utf8_text.size()), utf16_text);
-}
-
// TEST(WinString, IndexUtf8ToUtf16) {
// using cru::platform::win::IndexUtf8ToUtf16;
// std::string_view utf8_string = "aπ你🤣!";