From f669239f8de27764a0bf86962e58d70a48119b3b Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Thu, 20 Jul 2023 22:36:10 +0800 Subject: [PATCH] ... --- include/pocketpy/str.h | 118 ++++++----------------------------------- src/str.cpp | 103 +++++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+), 102 deletions(-) diff --git a/include/pocketpy/str.h b/include/pocketpy/str.h index 65d80177..eaaea76b 100644 --- a/include/pocketpy/str.h +++ b/include/pocketpy/str.h @@ -6,16 +6,7 @@ namespace pkpy { -inline int utf8len(unsigned char c, bool suppress=false){ - if((c & 0b10000000) == 0) return 1; - if((c & 0b11100000) == 0b11000000) return 2; - if((c & 0b11110000) == 0b11100000) return 3; - if((c & 0b11111000) == 0b11110000) return 4; - if((c & 0b11111100) == 0b11111000) return 5; - if((c & 0b11111110) == 0b11111100) return 6; - if(!suppress) throw std::runtime_error("invalid utf8 char: " + std::to_string(c)); - return 0; -} +int utf8len(unsigned char c, bool suppress=false); struct Str{ int size; @@ -28,59 +19,15 @@ struct Str{ bool is_inlined() const { return data == _inlined; } Str(): size(0), is_ascii(true), data(_inlined) {} + Str(int size, bool is_ascii); + Str(const std::string& s); + Str(std::string_view s); + Str(const char* s); + Str(const char* s, int len); + Str(const Str& other); + Str(Str&& other); - void _alloc(){ - if(size <= 16){ - this->data = _inlined; - }else{ - this->data = (char*)pool64.alloc(size); - } - } - - Str(int size, bool is_ascii): size(size), is_ascii(is_ascii) { - _alloc(); - } - -#define STR_INIT() \ - _alloc(); \ - for(int i=0; i other; - } + friend Str operator+(const char* p, const Str& str); + friend std::ostream& operator<<(std::ostream& os, const Str& str); + friend bool operator<(const std::string_view other, const Str& str); Str substr(int start, int len) const; Str substr(int start) const; @@ -144,7 +81,7 @@ struct Str{ }; template -inline std::string fmt(Args&&... args) { +std::string fmt(Args&&... args) { std::stringstream ss; (ss << ... << args); return ss.str(); @@ -159,10 +96,7 @@ struct StrName { std::string_view sv() const; bool empty() const { return index == 0; } - friend std::ostream& operator<<(std::ostream& os, const StrName& sn){ - return os << sn.sv(); - } - + friend std::ostream& operator<<(std::ostream& os, const StrName& sn); Str escape() const; bool operator==(const StrName& other) const noexcept { @@ -190,29 +124,9 @@ struct StrName { struct FastStrStream{ pod_vector parts; - - FastStrStream& operator<<(const Str& s){ - parts.push_back(&s); - return *this; - } - + FastStrStream& operator<<(const Str& s); bool empty() const { return parts.empty(); } - - Str str() const{ - int len = 0; - bool is_ascii = true; - for(auto& s: parts){ - len += s->length(); - is_ascii &= s->is_ascii; - } - Str result(len, is_ascii); - char* p = result.data; - for(auto& s: parts){ - memcpy(p, s->data, s->length()); - p += s->length(); - } - return result; - } + Str str() const; }; struct CString{ diff --git a/src/str.cpp b/src/str.cpp index 68357643..06602cf6 100644 --- a/src/str.cpp +++ b/src/str.cpp @@ -2,6 +2,84 @@ namespace pkpy { +int utf8len(unsigned char c, bool suppress){ + if((c & 0b10000000) == 0) return 1; + if((c & 0b11100000) == 0b11000000) return 2; + if((c & 0b11110000) == 0b11100000) return 3; + if((c & 0b11111000) == 0b11110000) return 4; + if((c & 0b11111100) == 0b11111000) return 5; + if((c & 0b11111110) == 0b11111100) return 6; + if(!suppress) throw std::runtime_error("invalid utf8 char: " + std::to_string(c)); + return 0; +} + + Str::Str(int size, bool is_ascii): size(size), is_ascii(is_ascii) { + _alloc(); + } + +#define STR_INIT() \ + _alloc(); \ + for(int i=0; i other; + } + + void Str::_alloc(){ + if(size <= 16){ + this->data = _inlined; + }else{ + this->data = (char*)pool64.alloc(size); + } + } + Str& Str::operator=(const Str& other){ if(!is_inlined()) pool64.dealloc(data); size = other.size; @@ -240,6 +318,10 @@ namespace pkpy { return _byte_index_to_unicode(size); } + std::ostream& operator<<(std::ostream& os, const StrName& sn){ + return os << sn.sv(); + } + StrName StrName::get(std::string_view s){ auto it = _interned.find(s); if(it != _interned.end()) return StrName(it->second); @@ -266,4 +348,25 @@ namespace pkpy { } std::string_view StrName::sv() const { return _r_interned[index-1].sv(); } + + FastStrStream& FastStrStream::operator<<(const Str& s){ + parts.push_back(&s); + return *this; + } + + Str FastStrStream::str() const{ + int len = 0; + bool is_ascii = true; + for(auto& s: parts){ + len += s->length(); + is_ascii &= s->is_ascii; + } + Str result(len, is_ascii); + char* p = result.data; + for(auto& s: parts){ + memcpy(p, s->data, s->length()); + p += s->length(); + } + return result; + } } // namespace pkpy \ No newline at end of file