From 286b1898466b22b84727d83bd6ae557ebf58125a Mon Sep 17 00:00:00 2001 From: jief666 Date: Mon, 8 Jan 2024 11:27:11 +0100 Subject: [PATCH] Create a copy ctor from a LString to avoid unecessary memory allocation. --- rEFIt_UEFI/cpp_foundation/XString.h | 80 ++++++------- rEFIt_UEFI/cpp_foundation/XStringAbstract.h | 122 ++++++++++++-------- 2 files changed, 113 insertions(+), 89 deletions(-) diff --git a/rEFIt_UEFI/cpp_foundation/XString.h b/rEFIt_UEFI/cpp_foundation/XString.h index f0cf56638..8b4b43a7a 100644 --- a/rEFIt_UEFI/cpp_foundation/XString.h +++ b/rEFIt_UEFI/cpp_foundation/XString.h @@ -20,7 +20,7 @@ //------------------------------------------------------------------------------------------------------------------ class XString8; -class LString8 : public LString +class LString8 : public LString { public: constexpr LString8() = delete; @@ -28,8 +28,8 @@ class LString8 : public LString LString8(const char* s) : LString(s, utf8_size_of_utf8_string(s)) {}; constexpr LString8(const char* s, size_t size) : LString(s, size) {}; #else - constexpr LString8(const char* s) : LString(s) {}; - constexpr LString8(const char* s, size_t size) : LString(s) {}; + constexpr LString8(const char* s) : LString(s) {}; + constexpr LString8(const char* s, size_t size) : LString(s) {}; #endif // no assignement, no destructor @@ -40,19 +40,19 @@ class LString8 : public LString }; -class XString8 : public XStringAbstract +class XString8 : public XStringAbstract { public: - XString8() : XStringAbstract() {}; - XString8(const XString8& S) : XStringAbstract(S) {} - XString8(const LString8& S) : XStringAbstract(S) { } + XString8() : XStringAbstract() {}; + XString8(const XString8& S) : XStringAbstract(S) {} + XString8(const LString8& S) : XStringAbstract(S) { } template // enable_if is to avoid constructing with a non-corresponding LString. To avoid memory allocation. - XString8(const OtherXStringClass& S) : XStringAbstract(S) {} + XString8(const OtherXStringClass& S) : XStringAbstract(S) {} - XString8& operator=(const XString8 &S) { this->XStringAbstract::operator=(S); return *this; } + XString8& operator=(const XString8 &S) { this->XStringAbstract::operator=(S); return *this; } - using XStringAbstract::operator =; + using XStringAbstract::operator =; const char* c_str() const { return data(); } // char* copy_str() const { return (char*)AllocateCopyPool(length()+1, m_data); } @@ -93,30 +93,30 @@ public: //------------------------------------------------------------------------------------------------------------------ class XString16; -class LString16 : public LString +class LString16 : public LString { #ifdef XSTRING_CACHING_OF_SIZE - constexpr LString16(const char16_t* s, size_t size) : LString(s, size) {}; + constexpr LString16(const char16_t* s, size_t size) : LString(s, size) {}; #else - constexpr LString16(const char16_t* s, size_t size) : LString(s) {}; + constexpr LString16(const char16_t* s, size_t size) : LString(s) {}; #endif friend constexpr LString16 operator "" _XS16 ( const char16_t* s, size_t size) { return LString16(s, size); } }; -class XString16 : public XStringAbstract +class XString16 : public XStringAbstract { public: - XString16() : XStringAbstract() {}; - XString16(const XString16& S) : XStringAbstract(S) {} - XString16(const LString16& S) : XStringAbstract(S) {} + XString16() : XStringAbstract() {}; + XString16(const XString16& S) : XStringAbstract(S) {} + XString16(const LString16& S) : XStringAbstract(S) {} template // enable_if is to avoid constructing with a non-corresponding LString. To avoid memory allocation. - XString16(const OtherXStringClass& S) : XStringAbstract(S) {} + XString16(const OtherXStringClass& S) : XStringAbstract(S) {} - XString16& operator=(const XString16 &S) { this->XStringAbstract::operator=(S); return *this; } + XString16& operator=(const XString16 &S) { this->XStringAbstract::operator=(S); return *this; } - using XStringAbstract::operator =; + using XStringAbstract::operator =; // friend LString16 operator "" _XS16 ( const char16_t* s, size_t len); }; @@ -124,37 +124,37 @@ class XString16 : public XStringAbstract //------------------------------------------------------------------------------------------------------------------ class XString32; -class LString32 : public LString +class LString32 : public LString { #ifdef XSTRING_CACHING_OF_SIZE - constexpr LString32(const char32_t* s, size_t size) : LString(s, size) {}; + constexpr LString32(const char32_t* s, size_t size) : LString(s, size) {}; #else - constexpr LString32(const char32_t* s, size_t size) : LString(s) {}; + constexpr LString32(const char32_t* s, size_t size) : LString(s) {}; #endif friend constexpr LString32 operator "" _XS32 ( const char32_t* s, size_t size) { return LString32(s, size); } }; -class XString32 : public XStringAbstract +class XString32 : public XStringAbstract { public: - XString32() : XStringAbstract() {}; - XString32(const XString32& S) : XStringAbstract(S) {} - XString32(const LString32& S) : XStringAbstract(S) {} + XString32() : XStringAbstract() {}; + XString32(const XString32& S) : XStringAbstract(S) {} + XString32(const LString32& S) : XStringAbstract(S) {} template // enable_if is to avoid constructing with a non-corresponding LString. To avoid memory allocation. - XString32(const OtherXStringClass& S) : XStringAbstract(S) {} + XString32(const OtherXStringClass& S) : XStringAbstract(S) {} - XString32& operator=(const XString32 &S) { this->XStringAbstract::operator=(S); return *this; } + XString32& operator=(const XString32 &S) { this->XStringAbstract::operator=(S); return *this; } - using XStringAbstract::operator =; + using XStringAbstract::operator =; // friend LString32 operator "" _XS32 ( const char32_t* s, size_t len); }; //------------------------------------------------------------------------------------------------------------------ class XStringW; -class LStringW : public LString +class LStringW : public LString { public: constexpr LStringW() = delete; @@ -163,8 +163,8 @@ class LStringW : public LString LStringW(const wchar_t* s) : LString(s, wchar_size_of_wchar_string(s)) {}; constexpr LStringW(const wchar_t* s, size_t size) : LString(s, size) {}; #else - constexpr LStringW(const wchar_t* s) : LString(s) {}; - constexpr LStringW(const wchar_t* s, size_t size) : LString(s) {}; + constexpr LStringW(const wchar_t* s) : LString(s) {}; + constexpr LStringW(const wchar_t* s, size_t size) : LString(s) {}; #endif friend constexpr LStringW operator "" _XSW ( const wchar_t* s, size_t size) { return LStringW(s, size); } @@ -172,20 +172,20 @@ class LStringW : public LString const wchar_t* wc_str() const { return data(); } }; -class XStringW : public XStringAbstract +class XStringW : public XStringAbstract { public: - XStringW() : XStringAbstract() {}; - XStringW(const XStringW& S) : XStringAbstract(S) {} - XStringW(const LStringW& S) : XStringAbstract(S) { } + XStringW() : XStringAbstract() {}; + XStringW(const XStringW& S) : XStringAbstract(S) {} + XStringW(const LStringW& S) : XStringAbstract(S) { } template // enable_if is to avoid constructing with a non-corresponding LString. To avoid memory allocation. - XStringW(const OtherXStringClass& S) : XStringAbstract(S) {} + XStringW(const OtherXStringClass& S) : XStringAbstract(S) {} - XStringW& operator=(const XStringW &S) { this->XStringAbstract::operator=(S); return *this; } + XStringW& operator=(const XStringW &S) { this->XStringAbstract::operator=(S); return *this; } - using XStringAbstract::operator =; + using XStringAbstract::operator =; const wchar_t* wc_str() const { return data(); } diff --git a/rEFIt_UEFI/cpp_foundation/XStringAbstract.h b/rEFIt_UEFI/cpp_foundation/XStringAbstract.h index 0410290ee..58a4ebc26 100644 --- a/rEFIt_UEFI/cpp_foundation/XStringAbstract.h +++ b/rEFIt_UEFI/cpp_foundation/XStringAbstract.h @@ -202,12 +202,13 @@ size_t XStringAbstract__rindexOf(const O* s, size_t Pos, const P* other, bool to } -template +template class __String { public: typedef T char_t; - typedef ThisXStringClass xs_t; + typedef ThisXStringClass xs_t; + typedef ThisLStringClass ls_t; protected: T *__m_data; protected: @@ -367,7 +368,7 @@ public: template size_t indexOf(const O* S, size_t Pos = 0) const { return XStringAbstract__indexOf(data(), Pos, S, false); } template - size_t indexOf(const __String& S, size_t Pos = 0) const { return indexOf(S.s(), Pos); } + size_t indexOf(const __String& S, size_t Pos = 0) const { return indexOf(S.s(), Pos); } /* IC */ size_t indexOfIC(char32_t char32Searched, size_t Pos = 0) const { @@ -377,7 +378,7 @@ public: template size_t indexOfIC(const O* S, size_t Pos = 0) const { return XStringAbstract__indexOf(data(), Pos, S, true); } template - size_t indexOfIC(const __String& S, size_t Pos = 0) const { return indexOfIC(S.s(), Pos); } + size_t indexOfIC(const __String& S, size_t Pos = 0) const { return indexOfIC(S.s(), Pos); } /* rindexOf */ @@ -389,7 +390,7 @@ public: template size_t rindexOf(const O* S, size_t Pos = MAX_XSIZE-1) const { return XStringAbstract__rindexOf(data(), Pos, S, false); } template - size_t rindexOf(const __String& S, size_t Pos = MAX_XSIZE-1) const { return rindexOf(S.s(), Pos); } + size_t rindexOf(const __String& S, size_t Pos = MAX_XSIZE-1) const { return rindexOf(S.s(), Pos); } /* IC */ size_t rindexOfIC(const char32_t char32Searched, size_t Pos = MAX_XSIZE-1) const { @@ -399,14 +400,14 @@ public: template size_t rindexOfIC(const O* S, size_t Pos = MAX_XSIZE-1) const { return XStringAbstract__rindexOf(data(), Pos, S, true); } template - size_t rindexOfIC(const __String& S, size_t Pos = MAX_XSIZE-1) const { return rindexOf(S.s(), Pos); } + size_t rindexOfIC(const __String& S, size_t Pos = MAX_XSIZE-1) const { return rindexOf(S.s(), Pos); } template - bool contains(const __String& S) const { return indexOf(S) != MAX_XSIZE; } + bool contains(const __String& S) const { return indexOf(S) != MAX_XSIZE; } template bool contains(const O* S) const { return indexOf(S) != MAX_XSIZE; } template - size_t containsIC(const __String& S) const { return indexOfIC(S) != MAX_XSIZE; } + size_t containsIC(const __String& S) const { return indexOfIC(S) != MAX_XSIZE; } template size_t containsIC(const O* S) const { return indexOfIC(S) != MAX_XSIZE; } @@ -434,11 +435,11 @@ public: return XStringAbstract__startWith(data(), other, false); } template - bool startWith(const __String& otherS) const { return XStringAbstract__startWith(data(), otherS.data(), false); } + bool startWith(const __String& otherS) const { return XStringAbstract__startWith(data(), otherS.data(), false); } template bool startWith(const O* other) const { return XStringAbstract__startWith(data(), other, false); } template - bool startWithIC(const __String& otherS) const { return XStringAbstract__startWith(data(), otherS.data(), true); } + bool startWithIC(const __String& otherS) const { return XStringAbstract__startWith(data(), otherS.data(), true); } template bool startWithIC(const O* other) const { return XStringAbstract__startWith(data(), other, true); } @@ -448,16 +449,16 @@ public: return XStringAbstract__startWithOrEqualTo(data(), other, false); } template - bool startWithOrEqualTo(const __String& otherS) const { return XStringAbstract__startWithOrEqualTo(data(), otherS.data(), false); } + bool startWithOrEqualTo(const __String& otherS) const { return XStringAbstract__startWithOrEqualTo(data(), otherS.data(), false); } template bool startWithOrEqualTo(const O* other) const { return XStringAbstract__startWithOrEqualTo(data(), other, false); } template - bool startWithOrEqualToIC(const __String& otherS) const { return XStringAbstract__startWithOrEqualTo(data(), otherS.data(), true); } + bool startWithOrEqualToIC(const __String& otherS) const { return XStringAbstract__startWithOrEqualTo(data(), otherS.data(), true); } template bool startWithOrEqualToIC(const O* other) const { return XStringAbstract__startWithOrEqualTo(data(), other, true); } template - bool endWithOrEqualToIC(const __String& otherS) const { if ( length() < otherS.length() ) return false; return XStringAbstract__rindexOf(data(), SIZE_T_MAX-1, otherS.data(), true) == length() - otherS.length(); } + bool endWithOrEqualToIC(const __String& otherS) const { if ( length() < otherS.length() ) return false; return XStringAbstract__rindexOf(data(), SIZE_T_MAX-1, otherS.data(), true) == length() - otherS.length(); } //--------------------------------------------------------------------- @@ -522,19 +523,19 @@ public: int strncmp(const O* S, size_t n) const { return XStringAbstract__ncompare(data(), S, n, false); } template - bool isEqual(const __String& S) const { return XStringAbstract__compare(data(), S.s(), false) == 0; } + bool isEqual(const __String& S) const { return XStringAbstract__compare(data(), S.s(), false) == 0; } template bool isEqual(const O* S) const { return XStringAbstract__compare(data(), S, false) == 0; } template - bool isEqualIC(const __String& S) const { return XStringAbstract__compare(data(), S.s(), true) == 0; } + bool isEqualIC(const __String& S) const { return XStringAbstract__compare(data(), S.s(), true) == 0; } template bool isEqualIC(const O* S) const { return XStringAbstract__compare(data(), S, true) == 0; } // bool SubStringEqual(size_t Pos, const T* S) const { return (memcmp(data(Pos), S, wcslen(S)) == 0); } template - bool isEqualAtIC(IntegralType pos, const __String& S) const + bool isEqualAtIC(IntegralType pos, const __String& S) const { #ifdef JIEF_DEBUG @@ -550,42 +551,42 @@ public: public: // == operator template - bool operator == (const __String& s2) const { return (*this).strcmp(s2.s()) == 0; } + bool operator == (const __String& s2) const { return (*this).strcmp(s2.s()) == 0; } // template // bool operator == (const O* s2) const { return (*this).strcmp(s2) == 0; } // template // friend bool operator == (const O* s1, ThisXStringClass& s2) { return s2.strcmp(s1) == 0; } template - bool operator != (const __String& s2) const { return !(*this == s2); } + bool operator != (const __String& s2) const { return !(*this == s2); } // template // bool operator != (const O* s2) const { return !(*this == s2); } // template // friend bool operator != (const O* s1, const ThisXStringClass& s2) { return s2.strcmp(s1) != 0; } template - bool operator < (const __String& s2) const { return (*this).strcmp(s2.s()) < 0; } + bool operator < (const __String& s2) const { return (*this).strcmp(s2.s()) < 0; } // template // bool operator < (const O* s2) const { return (*this).strcmp(s2) < 0; } // template // friend bool operator < (const O* s1, const ThisXStringClass& s2) { return s2.strcmp(s1) > 0; } template - bool operator > (const __String& s2) const { return (*this).strcmp(s2.s()) > 0; } + bool operator > (const __String& s2) const { return (*this).strcmp(s2.s()) > 0; } // template // bool operator > (const O* s2) const { return (*this).strcmp(s2) > 0; } // template // friend bool operator > (const O* s1, const ThisXStringClass& s2) { return s2.strcmp(s1) < 0; } template - bool operator <= (const __String& s2) const { return (*this).strcmp(s2.s()) <= 0; } + bool operator <= (const __String& s2) const { return (*this).strcmp(s2.s()) <= 0; } // template // bool operator <= (const O* s2) const { return (*this).strcmp(s2) <= 0; } // template // friend bool operator <= (const O* s1, const ThisXStringClass& s2) { return s2.strcmp(s1) >= 0; } template - bool operator >= (const __String& s2) const { return (*this).strcmp(s2.s()) >= 0; } + bool operator >= (const __String& s2) const { return (*this).strcmp(s2.s()) >= 0; } // template // bool operator >= (const O* s2) const { return (*this).strcmp(s2) >= 0; } // template @@ -596,8 +597,8 @@ public: //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx LString xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -template -class LString : public __String +template +class LString : public __String { public: protected: @@ -606,8 +607,9 @@ protected: constexpr LString(const T* s, size_t size) : __String(s, size) {}; constexpr LString(const LString& L) : __String(L.data(), L.size()) {}; #else - constexpr LString(const T* s) : __String(s) {}; - constexpr LString(const LString& L) : __String(L.data()) {}; + constexpr LString(const T* s) : __String(s) {}; + constexpr LString(const T* s, size_t size) : __String(s, size) {}; + constexpr LString(const LString& L) : __String(L.data()) {}; #endif constexpr LString() = delete; @@ -643,19 +645,26 @@ template auto test_pre_is_base_of(int) -> decltype(is_base_of_test_func(static_cast(nullptr))); -template< class, class = _xtools__void_t<>, class = _xtools__void_t<> > +template< class, class = _xtools__void_t<>, class = _xtools__void_t<>, class = _xtools__void_t<> > struct __string_type { typedef void type; }; template< typename T > -struct __string_type, _xtools__void_t> { typedef __String type; }; +//struct __string_type, _xtools__void_t> { typedef __String type; }; +//struct __string_type, _xtools__void_t, _xtools__void_t> { typedef __String type; }; +struct __string_type> { typedef __String type; }; #define is___String_t(x) decltype(test_pre_is_base_of::type , x>(0)) #define is___String(x) is___String_t(x)::value -template< class, class = _xtools__void_t<>, class = _xtools__void_t<> > +//template< class, class = _xtools__void_t<>, class = _xtools__void_t<> > +//struct __lstring_type { typedef void type; }; +//template< typename T > +//struct __lstring_type, _xtools__void_t> { typedef LString type; }; +template< class, class = _xtools__void_t<>, class = _xtools__void_t<>, class = _xtools__void_t<> > struct __lstring_type { typedef void type; }; template< typename T > -struct __lstring_type, _xtools__void_t> { typedef LString type; }; +struct __lstring_type, _xtools__void_t, _xtools__void_t> { typedef LString type; }; +//struct __lstring_type, _xtools__void_t, xtools__void_t> { typedef LString type; }; #define is___LString_t(x) decltype(test_pre_is_base_of< typename __lstring_type::type , x>(0)) #define is___LString(x) is___LString_t(x)::value @@ -726,13 +735,15 @@ struct _xstringarray__char_type //#define data() super::data() -template -class XStringAbstract : public __String +template +class XStringAbstract : public __String { - using super = __String; - static T nullChar; + public: + using super = __String; + using ls_t = ThisLStringClass; protected: + static T nullChar; size_t m_allocatedSize; // Must include null terminator. Real memory allocated is only m_allocatedSize (not m_allocatedSize+1) //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx @@ -790,16 +801,16 @@ public: /* default ctor */ #ifdef XSTRING_CACHING_OF_SIZE - XStringAbstract() : __String(&nullChar, 0), m_allocatedSize(0) {} + XStringAbstract() : __String(&nullChar, 0), m_allocatedSize(0) {} #else - XStringAbstract() : __String(&nullChar), m_allocatedSize(0) {} + XStringAbstract() : __String(&nullChar), m_allocatedSize(0) {} #endif /* copy ctor */ #ifdef XSTRING_CACHING_OF_SIZE - XStringAbstract(const XStringAbstract& S) : __String(&nullChar, 0), m_allocatedSize(0) + XStringAbstract(const XStringAbstract& S) : __String(&nullChar, 0), m_allocatedSize(0) #else - XStringAbstract(const XStringAbstract& S) : __String(&nullChar), m_allocatedSize(0) + XStringAbstract(const XStringAbstract& S) : __String(&nullChar), m_allocatedSize(0) #endif { *this = S; @@ -827,19 +838,19 @@ public: #else /* ctor */ template - explicit XStringAbstract(const LString& S) : __String(S.s()), m_allocatedSize(0) {} + explicit XStringAbstract(const LString& S) : __String(S.s()), m_allocatedSize(0) {} template - explicit XStringAbstract(const XStringAbstract& S) : __String(&nullChar), m_allocatedSize(0) { takeValueFrom(S); } + explicit XStringAbstract(const XStringAbstract& S) : __String(&nullChar), m_allocatedSize(0) { takeValueFrom(S); } template - explicit XStringAbstract(const LString& S) : __String(&nullChar), m_allocatedSize(0) { takeValueFrom(S); } + explicit XStringAbstract(const LString& S) : __String(&nullChar), m_allocatedSize(0) { takeValueFrom(S); } // TEMPORARILY DISABLED // template // explicit __String(const O* S) { Init(0); takeValueFrom(S); } // #endif - /* Copy Assign */ - XStringAbstract& operator=(const XStringAbstract &S) { + /* Copy Assign */ + XStringAbstract& operator=(const XStringAbstract &S) { if ( S.data() && S.m_allocatedSize == 0 ) { // S points to a litteral if ( m_allocatedSize > 0 ) { @@ -855,6 +866,19 @@ public: } return *this; } + + /* Copy Assign */ + XStringAbstract& operator=(const ls_t& S) { + if ( m_allocatedSize > 0 ) { + delete super::__m_data; + m_allocatedSize = 0; + } + super::__m_data = (T*)S.data(); // because it's a litteral, we don't copy. We need to cast, but we won't modify. + #ifdef XSTRING_CACHING_OF_SIZE + super::__m_size = S.size(); + #endif + return *this; + } /* Assign */ #ifndef _MSC_VER @@ -862,7 +886,7 @@ public: #pragma GCC diagnostic ignored "-Weffc++" #endif template - ThisXStringClass& operator =(const __String& S) { strcpy(S.s()); return *((ThisXStringClass*)this); } + ThisXStringClass& operator =(const __String& S) { strcpy(S.s()); return *((ThisXStringClass*)this); } #ifndef _MSC_VER #pragma GCC diagnostic pop #endif @@ -1057,7 +1081,7 @@ public: } /* strcat __String */ template - void strcat(const __String& other) + void strcat(const __String& other) { size_t currentSize = super::size(); // size is number of T, not in bytes size_t newSize = currentSize + utf_size_of_utf_string(data(), other.s()); // size is number of T, not in bytes @@ -1358,7 +1382,7 @@ public: /* takeValueFrom */ template - ThisXStringClass& takeValueFrom(const __String& S) { *this = S; return *((ThisXStringClass*)this); } + ThisXStringClass& takeValueFrom(const __String& S) { *this = S; return *((ThisXStringClass*)this); } template ThisXStringClass& takeValueFrom(const O* S) { strcpy(S); return *((ThisXStringClass*)this); } template @@ -1371,7 +1395,7 @@ public: /* += */ template - ThisXStringClass& operator += (const __String& S) { strcat(S.s()); return *((ThisXStringClass*)this); } + ThisXStringClass& operator += (const __String& S) { strcat(S.s()); return *((ThisXStringClass*)this); } template ThisXStringClass& operator += (O S) { strcat(S); return *((ThisXStringClass*)this); } template @@ -1380,8 +1404,8 @@ public: }; -template -T XStringAbstract::nullChar = 0; +template +T XStringAbstract::nullChar = 0; //------------------------------------------------------- + operator