aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/cru/common/String.hpp9
-rw-r--r--src/common/String.cpp39
-rw-r--r--test/common/StringTest.cpp14
3 files changed, 59 insertions, 3 deletions
diff --git a/include/cru/common/String.hpp b/include/cru/common/String.hpp
index 8db012cb..e7688555 100644
--- a/include/cru/common/String.hpp
+++ b/include/cru/common/String.hpp
@@ -4,6 +4,7 @@
#include "Range.hpp"
#include "StringUtil.hpp"
+#include <double-conversion/double-conversion.h>
#include <algorithm>
#include <array>
#include <charconv>
@@ -23,6 +24,9 @@ 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;
@@ -195,6 +199,8 @@ class CRU_BASE_API String {
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;
bool StartWith(StringView str) const;
@@ -225,6 +231,9 @@ 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;
+
private:
static char16_t kEmptyBuffer[1];
diff --git a/src/common/String.cpp b/src/common/String.cpp
index 9366abeb..48705d3b 100644
--- a/src/common/String.cpp
+++ b/src/common/String.cpp
@@ -2,6 +2,7 @@
#include "cru/common/Exception.hpp"
#include "cru/common/StringUtil.hpp"
+#include <cmath>
#include <gsl/gsl>
#include <algorithm>
@@ -10,6 +11,15 @@
#include <string_view>
namespace cru {
+double_conversion::StringToDoubleConverter
+ String::kDefaultStringToDoubleConverter(
+ double_conversion::StringToDoubleConverter::ALLOW_TRAILING_JUNK |
+ 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;
@@ -261,7 +271,8 @@ String& String::Trim() {
return *this;
}
-std::vector<String> String::SplitToLines(bool remove_space_line) const {
+std::vector<String> String::Split(value_type separator,
+ bool remove_space_line) const {
std::vector<String> result;
if (size_ == 0) return result;
@@ -269,7 +280,7 @@ std::vector<String> String::SplitToLines(bool remove_space_line) const {
Index line_start = 0;
Index line_end = 0;
while (line_end < size_) {
- if (buffer_[line_end] == '\n') {
+ if (buffer_[line_end] == separator) {
if (remove_space_line) {
bool add = false;
for (Index i = line_start; i < line_end; i++) {
@@ -305,6 +316,10 @@ std::vector<String> String::SplitToLines(bool remove_space_line) const {
return result;
}
+std::vector<String> String::SplitToLines(bool remove_space_line) const {
+ return Split(u'\n', remove_space_line);
+}
+
bool String::StartWith(StringView str) const {
if (str.size() > size_) return false;
return std::memcmp(str.data(), buffer_, str.size()) == 0;
@@ -419,6 +434,26 @@ int StringView::Compare(const StringView& other) const {
}
}
+float String::ParseToFloat(Index* processed_characters_count) const {
+ int pcc;
+ auto result = kDefaultStringToDoubleConverter.StringToFloat(
+ reinterpret_cast<const uc16*>(buffer_), static_cast<int>(size_), &pcc);
+ if (processed_characters_count != nullptr) {
+ *processed_characters_count = pcc;
+ }
+ return result;
+}
+
+double String::ParseToDouble(Index* processed_characters_count) const {
+ int pcc;
+ auto result = kDefaultStringToDoubleConverter.StringToDouble(
+ reinterpret_cast<const uc16*>(buffer_), static_cast<int>(size_), &pcc);
+ if (processed_characters_count != nullptr) {
+ *processed_characters_count = pcc;
+ }
+ return result;
+}
+
StringView StringView::substr(Index pos) {
Expects(pos >= 0 && pos < size_);
return StringView(ptr_ + pos, size_ - pos);
diff --git a/test/common/StringTest.cpp b/test/common/StringTest.cpp
index 7198f47b..737a93ad 100644
--- a/test/common/StringTest.cpp
+++ b/test/common/StringTest.cpp
@@ -1,5 +1,5 @@
-#include "cru/common/String.hpp"
#include "cru/common/Format.hpp"
+#include "cru/common/String.hpp"
#include <gtest/gtest.h>
@@ -69,3 +69,15 @@ TEST(String, SplitToLinesRemoveSpaceLine) {
ASSERT_EQ(lines[1], String(u"def"));
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);
+}