From e5b3502b03bdbdbecbd2e8b328e0f874499b452b Mon Sep 17 00:00:00 2001 From: crupest Date: Wed, 15 Sep 2021 21:54:06 +0800 Subject: ... --- include/cru/common/String.hpp | 61 +++++++++++++++++++++++-------------------- src/common/String.cpp | 32 +++++++++++++++++++---- 2 files changed, 59 insertions(+), 34 deletions(-) diff --git a/include/cru/common/String.hpp b/include/cru/common/String.hpp index ed3deb4c..f407cb60 100644 --- a/include/cru/common/String.hpp +++ b/include/cru/common/String.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -21,20 +22,36 @@ class StringView; class CRU_BASE_API String { public: + using value_type = std::uint16_t; + using size_type = Index; + using difference_type = Index; + using reference = std::uint16_t&; + using const_reference = const std::uint16_t&; + using pointer = std::uint16_t*; + using const_pointer = const std::uint16_t*; + using iterator = std::uint16_t*; + using const_iterator = const std::uint16_t*; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + public: + static String FromUtf8(const char* str); + static String FromUtf8(const char* str, Index size); static String FromUtf8(std::string_view str) { return FromUtf8(str.data(), str.size()); } - static String FromUtf8(const char* str, Index size); - static String FromUtf16(const std::uint16_t* str) { return String(str); } - static String FromUtf16(const std::uint16_t* str, Index size) { - return String(str, size); + static String FromUtf16(const char16_t* str) { + return String(reinterpret_cast(str)); } - - static String FromUtf16(const char16_t* str) { return String(str); } static String FromUtf16(const char16_t* str, Index size) { - return String(str, size); + return String(reinterpret_cast(str), size); } + static String FromUtf16(std::u16string_view str) { + return FromUtf16(str.data(), str.size()); + } + + static inline String From(StringView str); // Never use this if you don't know what this mean! static String FromBuffer(std::uint16_t* buffer, Index size, Index capacity) { @@ -48,31 +65,15 @@ class CRU_BASE_API String { } #endif - public: - using value_type = std::uint16_t; - using size_type = Index; - using difference_type = Index; - using reference = std::uint16_t&; - using const_reference = const std::uint16_t&; - using pointer = std::uint16_t*; - using const_pointer = const std::uint16_t*; - using iterator = std::uint16_t*; - using const_iterator = const std::uint16_t*; - using reverse_iterator = std::reverse_iterator; - using const_reverse_iterator = std::reverse_iterator; - public: String() = default; - explicit String(const std::uint16_t* str); - String(const std::uint16_t* str, Index size); - - explicit String(const char16_t* str); - String(const char16_t* str, Index size); - String(const std::u16string_view& str) : String(str.data(), str.size()) {} + explicit String(const_pointer str); + String(const_pointer str, size_type size); template - constexpr String(const char16_t (&str)[size]) : String(str, size) {} + String(const char16_t (&str)[size]) + : String(reinterpret_cast(str), size) {} template String(Iter start, Iter end) { @@ -81,8 +82,7 @@ class CRU_BASE_API String { } } - String(const std::initializer_list& l) - : String(l.begin(), l.end()) {} + String(std::initializer_list l) : String(l.begin(), l.end()) {} #ifdef CRU_PLATFORM_WINDOWS String(const wchar_t* str); @@ -112,6 +112,7 @@ class CRU_BASE_API String { void resize(Index new_size); void reserve(Index new_capacity); + void shrink_to_fit(); std::uint16_t& front() { return this->operator[](0); } const std::uint16_t& front() const { return this->operator[](0); } @@ -369,6 +370,8 @@ inline String::iterator String::insert(const_iterator pos, StringView str) { inline void String::append(StringView str) { this->append(str.data(), str.size()); } + +inline String String::From(StringView str) { return str.ToString(); } } // namespace cru template <> diff --git a/src/common/String.cpp b/src/common/String.cpp index 3d3e4a3c..092ba406 100644 --- a/src/common/String.cpp +++ b/src/common/String.cpp @@ -9,8 +9,12 @@ #include namespace cru { +String String::FromUtf8(const char* str) { + return FromUtf16(cru::ToUtf16(std::string_view(str))); +} + String String::FromUtf8(const char* str, Index size) { - return String{cru::ToUtf16(std::string_view(str, size))}; + return FromUtf16(cru::ToUtf16(std::string_view(str, size))); } std::uint16_t String::kEmptyBuffer[1] = {0}; @@ -25,6 +29,7 @@ Index GetStrSize(const C* str) { } String::String(const std::uint16_t* str) : String(str, GetStrSize(str)) {} + String::String(const std::uint16_t* str, Index size) { this->buffer_ = new std::uint16_t[size + 1]; std::memcpy(this->buffer_, str, size * sizeof(char16_t)); @@ -33,10 +38,6 @@ String::String(const std::uint16_t* str, Index size) { this->capacity_ = size; } -String::String(const char16_t* str) : String(str, GetStrSize(str)) {} -String::String(const char16_t* str, Index size) - : String(reinterpret_cast(str), size) {} - #ifdef CRU_PLATFORM_WINDOWS String::String(const wchar_t* str) : String(str, GetStrSize(str)) {} String::String(const wchar_t* str, Index size) @@ -125,7 +126,24 @@ void String::resize(Index new_size) { } } +void String::shrink_to_fit() { + if (capacity_ == size_) return; + if (size_ == 0) { + delete[] buffer_; + buffer_ = kEmptyBuffer; + size_ = 0; + capacity_ = 0; + } else { + auto new_buffer = new value_type[size_ + 1]; + std::memcpy(new_buffer, buffer_, sizeof(value_type) * size_); + delete[] buffer_; + buffer_ = new_buffer; + capacity_ = size_; + } +} + void String::reserve(Index new_capacity) { + Expects(new_capacity >= 0); if (new_capacity <= this->capacity_) return; if (new_capacity > 0) { std::uint16_t* new_buffer = new std::uint16_t[new_capacity + 1]; @@ -141,6 +159,8 @@ void String::reserve(Index new_capacity) { String::iterator String::insert(const_iterator pos, const std::uint16_t* str, Index size) { + Expects(pos >= cbegin() && pos <= cend()); + std::vector backup_buffer; if (str >= buffer_ && str < buffer_ + size_) { backup_buffer.resize(size); @@ -174,6 +194,8 @@ String::iterator String::insert(const_iterator pos, const std::uint16_t* str, } String::iterator String::erase(const_iterator start, const_iterator end) { + Expects(buffer_ <= start && start <= end && end <= buffer_ + size_); + Index new_size = size_ - (end - start); auto s = const_cast(start); -- cgit v1.2.3