Create a copy ctor from a LString to avoid unecessary memory allocation.

This commit is contained in:
jief666 2024-01-08 11:27:11 +01:00
parent 2d2b942ef4
commit 286b189846
2 changed files with 113 additions and 89 deletions

View File

@ -20,7 +20,7 @@
//------------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------------
class XString8; class XString8;
class LString8 : public LString<char, XString8> class LString8 : public LString<char, XString8, LString8>
{ {
public: public:
constexpr LString8() = delete; constexpr LString8() = delete;
@ -28,8 +28,8 @@ class LString8 : public LString<char, XString8>
LString8(const char* s) : LString<char, XString8>(s, utf8_size_of_utf8_string(s)) {}; LString8(const char* s) : LString<char, XString8>(s, utf8_size_of_utf8_string(s)) {};
constexpr LString8(const char* s, size_t size) : LString<char, XString8>(s, size) {}; constexpr LString8(const char* s, size_t size) : LString<char, XString8>(s, size) {};
#else #else
constexpr LString8(const char* s) : LString<char, XString8>(s) {}; constexpr LString8(const char* s) : LString<char, XString8, LString8>(s) {};
constexpr LString8(const char* s, size_t size) : LString<char, XString8>(s) {}; constexpr LString8(const char* s, size_t size) : LString<char, XString8, LString8>(s) {};
#endif #endif
// no assignement, no destructor // no assignement, no destructor
@ -40,19 +40,19 @@ class LString8 : public LString<char, XString8>
}; };
class XString8 : public XStringAbstract<char, XString8> class XString8 : public XStringAbstract<char, XString8, LString8>
{ {
public: public:
XString8() : XStringAbstract<char, XString8>() {}; XString8() : XStringAbstract<char, XString8, LString8>() {};
XString8(const XString8& S) : XStringAbstract<char, XString8>(S) {} XString8(const XString8& S) : XStringAbstract<char, XString8, LString8>(S) {}
XString8(const LString8& S) : XStringAbstract<char, XString8>(S) { } XString8(const LString8& S) : XStringAbstract<char, XString8, LString8>(S) { }
template<class OtherXStringClass, enable_if( is___String(OtherXStringClass) && !is___LString(OtherXStringClass))> // enable_if is to avoid constructing with a non-corresponding LString. To avoid memory allocation. template<class OtherXStringClass, enable_if( is___String(OtherXStringClass) && !is___LString(OtherXStringClass))> // enable_if is to avoid constructing with a non-corresponding LString. To avoid memory allocation.
XString8(const OtherXStringClass& S) : XStringAbstract<char, XString8>(S) {} XString8(const OtherXStringClass& S) : XStringAbstract<char, XString8, LString8>(S) {}
XString8& operator=(const XString8 &S) { this->XStringAbstract<char, XString8>::operator=(S); return *this; } XString8& operator=(const XString8 &S) { this->XStringAbstract<char, XString8, LString8>::operator=(S); return *this; }
using XStringAbstract<char, XString8>::operator =; using XStringAbstract<char, XString8, LString8>::operator =;
const char* c_str() const { return data(); } const char* c_str() const { return data(); }
// char* copy_str() const { return (char*)AllocateCopyPool(length()+1, m_data); } // char* copy_str() const { return (char*)AllocateCopyPool(length()+1, m_data); }
@ -93,30 +93,30 @@ public:
//------------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------------
class XString16; class XString16;
class LString16 : public LString<char16_t, XString16> class LString16 : public LString<char16_t, XString16, LString16>
{ {
#ifdef XSTRING_CACHING_OF_SIZE #ifdef XSTRING_CACHING_OF_SIZE
constexpr LString16(const char16_t* s, size_t size) : LString<char16_t, XString16>(s, size) {}; constexpr LString16(const char16_t* s, size_t size) : LString<char16_t, XString16, LString16>(s, size) {};
#else #else
constexpr LString16(const char16_t* s, size_t size) : LString<char16_t, XString16>(s) {}; constexpr LString16(const char16_t* s, size_t size) : LString<char16_t, XString16, LString16>(s) {};
#endif #endif
friend constexpr LString16 operator "" _XS16 ( const char16_t* s, size_t size) { return LString16(s, size); } friend constexpr LString16 operator "" _XS16 ( const char16_t* s, size_t size) { return LString16(s, size); }
}; };
class XString16 : public XStringAbstract<char16_t, XString16> class XString16 : public XStringAbstract<char16_t, XString16, LString16>
{ {
public: public:
XString16() : XStringAbstract<char16_t, XString16>() {}; XString16() : XStringAbstract<char16_t, XString16, LString16>() {};
XString16(const XString16& S) : XStringAbstract<char16_t, XString16>(S) {} XString16(const XString16& S) : XStringAbstract<char16_t, XString16, LString16>(S) {}
XString16(const LString16& S) : XStringAbstract<char16_t, XString16>(S) {} XString16(const LString16& S) : XStringAbstract<char16_t, XString16, LString16>(S) {}
template<class OtherXStringClass, enable_if( is___String(OtherXStringClass) && !is___LString(OtherXStringClass))> // enable_if is to avoid constructing with a non-corresponding LString. To avoid memory allocation. template<class OtherXStringClass, enable_if( is___String(OtherXStringClass) && !is___LString(OtherXStringClass))> // enable_if is to avoid constructing with a non-corresponding LString. To avoid memory allocation.
XString16(const OtherXStringClass& S) : XStringAbstract<char16_t, XString16>(S) {} XString16(const OtherXStringClass& S) : XStringAbstract<char16_t, XString16, LString16>(S) {}
XString16& operator=(const XString16 &S) { this->XStringAbstract<char16_t, XString16>::operator=(S); return *this; } XString16& operator=(const XString16 &S) { this->XStringAbstract<char16_t, XString16, LString16>::operator=(S); return *this; }
using XStringAbstract<char16_t, XString16>::operator =; using XStringAbstract<char16_t, XString16, LString16>::operator =;
// friend LString16 operator "" _XS16 ( const char16_t* s, size_t len); // friend LString16 operator "" _XS16 ( const char16_t* s, size_t len);
}; };
@ -124,37 +124,37 @@ class XString16 : public XStringAbstract<char16_t, XString16>
//------------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------------
class XString32; class XString32;
class LString32 : public LString<char32_t, XString32> class LString32 : public LString<char32_t, XString32 ,LString32>
{ {
#ifdef XSTRING_CACHING_OF_SIZE #ifdef XSTRING_CACHING_OF_SIZE
constexpr LString32(const char32_t* s, size_t size) : LString<char32_t, XString32>(s, size) {}; constexpr LString32(const char32_t* s, size_t size) : LString<char32_t, XString32 ,LString32>(s, size) {};
#else #else
constexpr LString32(const char32_t* s, size_t size) : LString<char32_t, XString32>(s) {}; constexpr LString32(const char32_t* s, size_t size) : LString<char32_t, XString32 ,LString32>(s) {};
#endif #endif
friend constexpr LString32 operator "" _XS32 ( const char32_t* s, size_t size) { return LString32(s, size); } friend constexpr LString32 operator "" _XS32 ( const char32_t* s, size_t size) { return LString32(s, size); }
}; };
class XString32 : public XStringAbstract<char32_t, XString32> class XString32 : public XStringAbstract<char32_t, XString32, LString32>
{ {
public: public:
XString32() : XStringAbstract<char32_t, XString32>() {}; XString32() : XStringAbstract<char32_t, XString32 ,LString32>() {};
XString32(const XString32& S) : XStringAbstract<char32_t, XString32>(S) {} XString32(const XString32& S) : XStringAbstract<char32_t, XString32 ,LString32>(S) {}
XString32(const LString32& S) : XStringAbstract<char32_t, XString32>(S) {} XString32(const LString32& S) : XStringAbstract<char32_t, XString32 ,LString32>(S) {}
template<class OtherXStringClass, enable_if( is___String(OtherXStringClass) && !is___LString(OtherXStringClass))> // enable_if is to avoid constructing with a non-corresponding LString. To avoid memory allocation. template<class OtherXStringClass, enable_if( is___String(OtherXStringClass) && !is___LString(OtherXStringClass))> // enable_if is to avoid constructing with a non-corresponding LString. To avoid memory allocation.
XString32(const OtherXStringClass& S) : XStringAbstract<char32_t, XString32>(S) {} XString32(const OtherXStringClass& S) : XStringAbstract<char32_t, XString32, LString32>(S) {}
XString32& operator=(const XString32 &S) { this->XStringAbstract<char32_t, XString32>::operator=(S); return *this; } XString32& operator=(const XString32 &S) { this->XStringAbstract<char32_t, XString32 ,LString32>::operator=(S); return *this; }
using XStringAbstract<char32_t, XString32>::operator =; using XStringAbstract<char32_t, XString32 ,LString32>::operator =;
// friend LString32 operator "" _XS32 ( const char32_t* s, size_t len); // friend LString32 operator "" _XS32 ( const char32_t* s, size_t len);
}; };
//------------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------------
class XStringW; class XStringW;
class LStringW : public LString<wchar_t, XStringW> class LStringW : public LString<wchar_t, XStringW, LStringW>
{ {
public: public:
constexpr LStringW() = delete; constexpr LStringW() = delete;
@ -163,8 +163,8 @@ class LStringW : public LString<wchar_t, XStringW>
LStringW(const wchar_t* s) : LString<wchar_t, XStringW>(s, wchar_size_of_wchar_string(s)) {}; LStringW(const wchar_t* s) : LString<wchar_t, XStringW>(s, wchar_size_of_wchar_string(s)) {};
constexpr LStringW(const wchar_t* s, size_t size) : LString<wchar_t, XStringW>(s, size) {}; constexpr LStringW(const wchar_t* s, size_t size) : LString<wchar_t, XStringW>(s, size) {};
#else #else
constexpr LStringW(const wchar_t* s) : LString<wchar_t, XStringW>(s) {}; constexpr LStringW(const wchar_t* s) : LString<wchar_t, XStringW, LStringW>(s) {};
constexpr LStringW(const wchar_t* s, size_t size) : LString<wchar_t, XStringW>(s) {}; constexpr LStringW(const wchar_t* s, size_t size) : LString<wchar_t, XStringW, LStringW>(s) {};
#endif #endif
friend constexpr LStringW operator "" _XSW ( const wchar_t* s, size_t size) { return LStringW(s, size); } friend constexpr LStringW operator "" _XSW ( const wchar_t* s, size_t size) { return LStringW(s, size); }
@ -172,20 +172,20 @@ class LStringW : public LString<wchar_t, XStringW>
const wchar_t* wc_str() const { return data(); } const wchar_t* wc_str() const { return data(); }
}; };
class XStringW : public XStringAbstract<wchar_t, XStringW> class XStringW : public XStringAbstract<wchar_t, XStringW, LStringW>
{ {
public: public:
XStringW() : XStringAbstract<wchar_t, XStringW>() {}; XStringW() : XStringAbstract<wchar_t, XStringW, LStringW>() {};
XStringW(const XStringW& S) : XStringAbstract<wchar_t, XStringW>(S) {} XStringW(const XStringW& S) : XStringAbstract<wchar_t, XStringW, LStringW>(S) {}
XStringW(const LStringW& S) : XStringAbstract<wchar_t, XStringW>(S) { } XStringW(const LStringW& S) : XStringAbstract<wchar_t, XStringW, LStringW>(S) { }
template<class OtherXStringClass, enable_if( is___String(OtherXStringClass) && !is___LString(OtherXStringClass))> // enable_if is to avoid constructing with a non-corresponding LString. To avoid memory allocation. template<class OtherXStringClass, enable_if( is___String(OtherXStringClass) && !is___LString(OtherXStringClass))> // enable_if is to avoid constructing with a non-corresponding LString. To avoid memory allocation.
XStringW(const OtherXStringClass& S) : XStringAbstract<wchar_t, XStringW>(S) {} XStringW(const OtherXStringClass& S) : XStringAbstract<wchar_t, XStringW, LStringW>(S) {}
XStringW& operator=(const XStringW &S) { this->XStringAbstract<wchar_t, XStringW>::operator=(S); return *this; } XStringW& operator=(const XStringW &S) { this->XStringAbstract<wchar_t, XStringW, LStringW>::operator=(S); return *this; }
using XStringAbstract<wchar_t, XStringW>::operator =; using XStringAbstract<wchar_t, XStringW, LStringW>::operator =;
const wchar_t* wc_str() const { return data(); } const wchar_t* wc_str() const { return data(); }

View File

@ -202,12 +202,13 @@ size_t XStringAbstract__rindexOf(const O* s, size_t Pos, const P* other, bool to
} }
template<class T, class ThisXStringClass> template<class T, class ThisXStringClass, class ThisLStringClass>
class __String class __String
{ {
public: public:
typedef T char_t; typedef T char_t;
typedef ThisXStringClass xs_t; typedef ThisXStringClass xs_t;
typedef ThisLStringClass ls_t;
protected: protected:
T *__m_data; T *__m_data;
protected: protected:
@ -367,7 +368,7 @@ public:
template<typename O> template<typename O>
size_t indexOf(const O* S, size_t Pos = 0) const { return XStringAbstract__indexOf(data(), Pos, S, false); } size_t indexOf(const O* S, size_t Pos = 0) const { return XStringAbstract__indexOf(data(), Pos, S, false); }
template<typename O, class OtherXStringClass> template<typename O, class OtherXStringClass>
size_t indexOf(const __String<O, OtherXStringClass>& S, size_t Pos = 0) const { return indexOf(S.s(), Pos); } size_t indexOf(const __String<O, OtherXStringClass, typename OtherXStringClass::ls_t>& S, size_t Pos = 0) const { return indexOf(S.s(), Pos); }
/* IC */ /* IC */
size_t indexOfIC(char32_t char32Searched, size_t Pos = 0) const size_t indexOfIC(char32_t char32Searched, size_t Pos = 0) const
{ {
@ -377,7 +378,7 @@ public:
template<typename O> template<typename O>
size_t indexOfIC(const O* S, size_t Pos = 0) const { return XStringAbstract__indexOf(data(), Pos, S, true); } size_t indexOfIC(const O* S, size_t Pos = 0) const { return XStringAbstract__indexOf(data(), Pos, S, true); }
template<typename O, class OtherXStringClass> template<typename O, class OtherXStringClass>
size_t indexOfIC(const __String<O, OtherXStringClass>& S, size_t Pos = 0) const { return indexOfIC(S.s(), Pos); } size_t indexOfIC(const __String<O, OtherXStringClass, typename OtherXStringClass::ls_t>& S, size_t Pos = 0) const { return indexOfIC(S.s(), Pos); }
/* rindexOf */ /* rindexOf */
@ -389,7 +390,7 @@ public:
template<typename O> template<typename O>
size_t rindexOf(const O* S, size_t Pos = MAX_XSIZE-1) const { return XStringAbstract__rindexOf(data(), Pos, S, false); } size_t rindexOf(const O* S, size_t Pos = MAX_XSIZE-1) const { return XStringAbstract__rindexOf(data(), Pos, S, false); }
template<typename O, class OtherXStringClass> template<typename O, class OtherXStringClass>
size_t rindexOf(const __String<O, OtherXStringClass>& S, size_t Pos = MAX_XSIZE-1) const { return rindexOf(S.s(), Pos); } size_t rindexOf(const __String<O, OtherXStringClass, typename OtherXStringClass::ls_t>& S, size_t Pos = MAX_XSIZE-1) const { return rindexOf(S.s(), Pos); }
/* IC */ /* IC */
size_t rindexOfIC(const char32_t char32Searched, size_t Pos = MAX_XSIZE-1) const size_t rindexOfIC(const char32_t char32Searched, size_t Pos = MAX_XSIZE-1) const
{ {
@ -399,14 +400,14 @@ public:
template<typename O> template<typename O>
size_t rindexOfIC(const O* S, size_t Pos = MAX_XSIZE-1) const { return XStringAbstract__rindexOf(data(), Pos, S, true); } size_t rindexOfIC(const O* S, size_t Pos = MAX_XSIZE-1) const { return XStringAbstract__rindexOf(data(), Pos, S, true); }
template<typename O, class OtherXStringClass> template<typename O, class OtherXStringClass>
size_t rindexOfIC(const __String<O, OtherXStringClass>& S, size_t Pos = MAX_XSIZE-1) const { return rindexOf(S.s(), Pos); } size_t rindexOfIC(const __String<O, OtherXStringClass, typename OtherXStringClass::ls_t>& S, size_t Pos = MAX_XSIZE-1) const { return rindexOf(S.s(), Pos); }
template<typename O, class OtherXStringClass> template<typename O, class OtherXStringClass>
bool contains(const __String<O, OtherXStringClass>& S) const { return indexOf(S) != MAX_XSIZE; } bool contains(const __String<O, OtherXStringClass, typename OtherXStringClass::ls_t>& S) const { return indexOf(S) != MAX_XSIZE; }
template<typename O> template<typename O>
bool contains(const O* S) const { return indexOf(S) != MAX_XSIZE; } bool contains(const O* S) const { return indexOf(S) != MAX_XSIZE; }
template<typename O, class OtherXStringClass> template<typename O, class OtherXStringClass>
size_t containsIC(const __String<O, OtherXStringClass>& S) const { return indexOfIC(S) != MAX_XSIZE; } size_t containsIC(const __String<O, OtherXStringClass, typename OtherXStringClass::ls_t>& S) const { return indexOfIC(S) != MAX_XSIZE; }
template<typename O> template<typename O>
size_t containsIC(const O* S) const { return indexOfIC(S) != MAX_XSIZE; } size_t containsIC(const O* S) const { return indexOfIC(S) != MAX_XSIZE; }
@ -434,11 +435,11 @@ public:
return XStringAbstract__startWith(data(), other, false); return XStringAbstract__startWith(data(), other, false);
} }
template<typename O, class OtherXStringClass> template<typename O, class OtherXStringClass>
bool startWith(const __String<O, OtherXStringClass>& otherS) const { return XStringAbstract__startWith(data(), otherS.data(), false); } bool startWith(const __String<O, OtherXStringClass, typename OtherXStringClass::ls_t>& otherS) const { return XStringAbstract__startWith(data(), otherS.data(), false); }
template<typename O> template<typename O>
bool startWith(const O* other) const { return XStringAbstract__startWith(data(), other, false); } bool startWith(const O* other) const { return XStringAbstract__startWith(data(), other, false); }
template<typename O, class OtherXStringClass> template<typename O, class OtherXStringClass>
bool startWithIC(const __String<O, OtherXStringClass>& otherS) const { return XStringAbstract__startWith(data(), otherS.data(), true); } bool startWithIC(const __String<O, OtherXStringClass, typename OtherXStringClass::ls_t>& otherS) const { return XStringAbstract__startWith(data(), otherS.data(), true); }
template<typename O> template<typename O>
bool startWithIC(const O* other) const { return XStringAbstract__startWith(data(), other, true); } bool startWithIC(const O* other) const { return XStringAbstract__startWith(data(), other, true); }
@ -448,16 +449,16 @@ public:
return XStringAbstract__startWithOrEqualTo(data(), other, false); return XStringAbstract__startWithOrEqualTo(data(), other, false);
} }
template<typename O, class OtherXStringClass> template<typename O, class OtherXStringClass>
bool startWithOrEqualTo(const __String<O, OtherXStringClass>& otherS) const { return XStringAbstract__startWithOrEqualTo(data(), otherS.data(), false); } bool startWithOrEqualTo(const __String<O, OtherXStringClass, typename OtherXStringClass::ls_t>& otherS) const { return XStringAbstract__startWithOrEqualTo(data(), otherS.data(), false); }
template<typename O> template<typename O>
bool startWithOrEqualTo(const O* other) const { return XStringAbstract__startWithOrEqualTo(data(), other, false); } bool startWithOrEqualTo(const O* other) const { return XStringAbstract__startWithOrEqualTo(data(), other, false); }
template<typename O, class OtherXStringClass> template<typename O, class OtherXStringClass>
bool startWithOrEqualToIC(const __String<O, OtherXStringClass>& otherS) const { return XStringAbstract__startWithOrEqualTo(data(), otherS.data(), true); } bool startWithOrEqualToIC(const __String<O, OtherXStringClass, typename OtherXStringClass::ls_t>& otherS) const { return XStringAbstract__startWithOrEqualTo(data(), otherS.data(), true); }
template<typename O> template<typename O>
bool startWithOrEqualToIC(const O* other) const { return XStringAbstract__startWithOrEqualTo(data(), other, true); } bool startWithOrEqualToIC(const O* other) const { return XStringAbstract__startWithOrEqualTo(data(), other, true); }
template<typename O, class OtherXStringClass> template<typename O, class OtherXStringClass>
bool endWithOrEqualToIC(const __String<O, OtherXStringClass>& 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<O, OtherXStringClass, typename OtherXStringClass::ls_t>& 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); } int strncmp(const O* S, size_t n) const { return XStringAbstract__ncompare(data(), S, n, false); }
template<typename O, class OtherXStringClass> template<typename O, class OtherXStringClass>
bool isEqual(const __String<O, OtherXStringClass>& S) const { return XStringAbstract__compare(data(), S.s(), false) == 0; } bool isEqual(const __String<O, OtherXStringClass, typename OtherXStringClass::ls_t>& S) const { return XStringAbstract__compare(data(), S.s(), false) == 0; }
template<typename O> template<typename O>
bool isEqual(const O* S) const { return XStringAbstract__compare(data(), S, false) == 0; } bool isEqual(const O* S) const { return XStringAbstract__compare(data(), S, false) == 0; }
template<typename O, class OtherXStringClass> template<typename O, class OtherXStringClass>
bool isEqualIC(const __String<O, OtherXStringClass>& S) const { return XStringAbstract__compare(data(), S.s(), true) == 0; } bool isEqualIC(const __String<O, OtherXStringClass, typename OtherXStringClass::ls_t>& S) const { return XStringAbstract__compare(data(), S.s(), true) == 0; }
template<typename O> template<typename O>
bool isEqualIC(const O* S) const { return XStringAbstract__compare(data(), S, true) == 0; } 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); } // bool SubStringEqual(size_t Pos, const T* S) const { return (memcmp(data(Pos), S, wcslen(S)) == 0); }
template<typename IntegralType, typename O, class OtherXStringClass> template<typename IntegralType, typename O, class OtherXStringClass>
bool isEqualAtIC(IntegralType pos, const __String<O, OtherXStringClass>& S) const bool isEqualAtIC(IntegralType pos, const __String<O, OtherXStringClass, typename OtherXStringClass::ls_t>& S) const
{ {
#ifdef JIEF_DEBUG #ifdef JIEF_DEBUG
@ -550,42 +551,42 @@ public:
public: public:
// == operator // == operator
template<typename O, class OtherXStringClass> template<typename O, class OtherXStringClass>
bool operator == (const __String<O, OtherXStringClass>& s2) const { return (*this).strcmp(s2.s()) == 0; } bool operator == (const __String<O, OtherXStringClass, typename OtherXStringClass::ls_t>& s2) const { return (*this).strcmp(s2.s()) == 0; }
// template<typename O> // template<typename O>
// bool operator == (const O* s2) const { return (*this).strcmp(s2) == 0; } // bool operator == (const O* s2) const { return (*this).strcmp(s2) == 0; }
// template<typename O> // template<typename O>
// friend bool operator == (const O* s1, ThisXStringClass& s2) { return s2.strcmp(s1) == 0; } // friend bool operator == (const O* s1, ThisXStringClass& s2) { return s2.strcmp(s1) == 0; }
template<typename O, class OtherXStringClass> template<typename O, class OtherXStringClass>
bool operator != (const __String<O, OtherXStringClass>& s2) const { return !(*this == s2); } bool operator != (const __String<O, OtherXStringClass, typename OtherXStringClass::ls_t>& s2) const { return !(*this == s2); }
// template<typename O> // template<typename O>
// bool operator != (const O* s2) const { return !(*this == s2); } // bool operator != (const O* s2) const { return !(*this == s2); }
// template<typename O> // template<typename O>
// friend bool operator != (const O* s1, const ThisXStringClass& s2) { return s2.strcmp(s1) != 0; } // friend bool operator != (const O* s1, const ThisXStringClass& s2) { return s2.strcmp(s1) != 0; }
template<typename O, class OtherXStringClass> template<typename O, class OtherXStringClass>
bool operator < (const __String<O, OtherXStringClass>& s2) const { return (*this).strcmp(s2.s()) < 0; } bool operator < (const __String<O, OtherXStringClass, typename OtherXStringClass::ls_t>& s2) const { return (*this).strcmp(s2.s()) < 0; }
// template<typename O> // template<typename O>
// bool operator < (const O* s2) const { return (*this).strcmp(s2) < 0; } // bool operator < (const O* s2) const { return (*this).strcmp(s2) < 0; }
// template<typename O> // template<typename O>
// friend bool operator < (const O* s1, const ThisXStringClass& s2) { return s2.strcmp(s1) > 0; } // friend bool operator < (const O* s1, const ThisXStringClass& s2) { return s2.strcmp(s1) > 0; }
template<typename O, class OtherXStringClass> template<typename O, class OtherXStringClass>
bool operator > (const __String<O, OtherXStringClass>& s2) const { return (*this).strcmp(s2.s()) > 0; } bool operator > (const __String<O, OtherXStringClass, typename OtherXStringClass::ls_t>& s2) const { return (*this).strcmp(s2.s()) > 0; }
// template<typename O> // template<typename O>
// bool operator > (const O* s2) const { return (*this).strcmp(s2) > 0; } // bool operator > (const O* s2) const { return (*this).strcmp(s2) > 0; }
// template<typename O> // template<typename O>
// friend bool operator > (const O* s1, const ThisXStringClass& s2) { return s2.strcmp(s1) < 0; } // friend bool operator > (const O* s1, const ThisXStringClass& s2) { return s2.strcmp(s1) < 0; }
template<typename O, class OtherXStringClass> template<typename O, class OtherXStringClass>
bool operator <= (const __String<O, OtherXStringClass>& s2) const { return (*this).strcmp(s2.s()) <= 0; } bool operator <= (const __String<O, OtherXStringClass, typename OtherXStringClass::ls_t>& s2) const { return (*this).strcmp(s2.s()) <= 0; }
// template<typename O> // template<typename O>
// bool operator <= (const O* s2) const { return (*this).strcmp(s2) <= 0; } // bool operator <= (const O* s2) const { return (*this).strcmp(s2) <= 0; }
// template<typename O> // template<typename O>
// friend bool operator <= (const O* s1, const ThisXStringClass& s2) { return s2.strcmp(s1) >= 0; } // friend bool operator <= (const O* s1, const ThisXStringClass& s2) { return s2.strcmp(s1) >= 0; }
template<typename O, class OtherXStringClass> template<typename O, class OtherXStringClass>
bool operator >= (const __String<O, OtherXStringClass>& s2) const { return (*this).strcmp(s2.s()) >= 0; } bool operator >= (const __String<O, OtherXStringClass, typename OtherXStringClass::ls_t>& s2) const { return (*this).strcmp(s2.s()) >= 0; }
// template<typename O> // template<typename O>
// bool operator >= (const O* s2) const { return (*this).strcmp(s2) >= 0; } // bool operator >= (const O* s2) const { return (*this).strcmp(s2) >= 0; }
// template<typename O> // template<typename O>
@ -596,8 +597,8 @@ public:
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx LString xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx LString xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
template<class T, class ThisXStringClass> template<class T, class ThisXStringClass, class ThisLStringClass>
class LString : public __String<T, ThisXStringClass> class LString : public __String<T, ThisXStringClass, ThisLStringClass>
{ {
public: public:
protected: protected:
@ -606,8 +607,9 @@ protected:
constexpr LString(const T* s, size_t size) : __String<T, ThisXStringClass>(s, size) {}; constexpr LString(const T* s, size_t size) : __String<T, ThisXStringClass>(s, size) {};
constexpr LString(const LString& L) : __String<T, ThisXStringClass>(L.data(), L.size()) {}; constexpr LString(const LString& L) : __String<T, ThisXStringClass>(L.data(), L.size()) {};
#else #else
constexpr LString(const T* s) : __String<T, ThisXStringClass>(s) {}; constexpr LString(const T* s) : __String<T, ThisXStringClass, ThisLStringClass>(s) {};
constexpr LString(const LString& L) : __String<T, ThisXStringClass>(L.data()) {}; constexpr LString(const T* s, size_t size) : __String<T, ThisXStringClass, ThisLStringClass>(s, size) {};
constexpr LString(const LString& L) : __String<T, ThisXStringClass, ThisLStringClass>(L.data()) {};
#endif #endif
constexpr LString() = delete; constexpr LString() = delete;
@ -643,19 +645,26 @@ template <typename B, typename D>
auto test_pre_is_base_of(int) -> decltype(is_base_of_test_func<B>(static_cast<D*>(nullptr))); auto test_pre_is_base_of(int) -> decltype(is_base_of_test_func<B>(static_cast<D*>(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; }; struct __string_type { typedef void type; };
template< typename T > template< typename T >
struct __string_type<T, _xtools__void_t<typename T::xs_t>, _xtools__void_t<typename T::char_t>> { typedef __String<typename T::char_t, typename T::xs_t> type; }; //struct __string_type<T, _xtools__void_t<typename T::xs_t>, _xtools__void_t<typename T::char_t>> { typedef __String<typename T::char_t, typename T::xs_t> type; };
//struct __string_type<T, _xtools__void_t<typename T::char_t>, _xtools__void_t<typename T::xs_t>, _xtools__void_t<typename T::ls_t>> { typedef __String<typename T::char_t, typename T::xs_t, typename T::ls_t> type; };
struct __string_type<T, _xtools__void_t<typename T::char_t>> { typedef __String<typename T::char_t, typename T::xs_t, typename T::ls_t> type; };
#define is___String_t(x) decltype(test_pre_is_base_of<typename __string_type<x>::type , x>(0)) #define is___String_t(x) decltype(test_pre_is_base_of<typename __string_type<x>::type , x>(0))
#define is___String(x) is___String_t(x)::value #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<T, _xtools__void_t<typename T::xs_t>, _xtools__void_t<typename T::char_t>> { typedef LString<typename T::char_t, typename T::xs_t> type; };
template< class, class = _xtools__void_t<>, class = _xtools__void_t<>, class = _xtools__void_t<> >
struct __lstring_type { typedef void type; }; struct __lstring_type { typedef void type; };
template< typename T > template< typename T >
struct __lstring_type<T, _xtools__void_t<typename T::xs_t>, _xtools__void_t<typename T::char_t>> { typedef LString<typename T::char_t, typename T::xs_t> type; }; struct __lstring_type<T, _xtools__void_t<typename T::xs_t>, _xtools__void_t<typename T::char_t>, _xtools__void_t<typename T::ls_t>> { typedef LString<typename T::char_t, typename T::xs_t, typename T::ls_t> type; };
//struct __lstring_type<T, _xtools__void_t<typename T::char_t>, _xtools__void_t<typename T::xs_t>, xtools__void_t<typename T::ls_t>> { typedef LString<typename T::char_t, typename T::xs_t, typename T::ls_t> type; };
#define is___LString_t(x) decltype(test_pre_is_base_of< typename __lstring_type<x>::type , x>(0)) #define is___LString_t(x) decltype(test_pre_is_base_of< typename __lstring_type<x>::type , x>(0))
#define is___LString(x) is___LString_t(x)::value #define is___LString(x) is___LString_t(x)::value
@ -726,13 +735,15 @@ struct _xstringarray__char_type<T, enable_if_t(is___LString(T))>
//#define data() super::data() //#define data() super::data()
template<class T, class ThisXStringClass> template<class T, class ThisXStringClass, class ThisLStringClass>
class XStringAbstract : public __String<T, ThisXStringClass> class XStringAbstract : public __String<T, ThisXStringClass, ThisLStringClass>
{ {
using super = __String<T, ThisXStringClass>; public:
static T nullChar; using super = __String<T, ThisXStringClass, ThisLStringClass>;
using ls_t = ThisLStringClass;
protected: protected:
static T nullChar;
size_t m_allocatedSize; // Must include null terminator. Real memory allocated is only m_allocatedSize (not m_allocatedSize+1) size_t m_allocatedSize; // Must include null terminator. Real memory allocated is only m_allocatedSize (not m_allocatedSize+1)
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
@ -790,16 +801,16 @@ public:
/* default ctor */ /* default ctor */
#ifdef XSTRING_CACHING_OF_SIZE #ifdef XSTRING_CACHING_OF_SIZE
XStringAbstract() : __String<T, ThisXStringClass>(&nullChar, 0), m_allocatedSize(0) {} XStringAbstract() : __String<T, ThisXStringClass, ThisLStringClass>(&nullChar, 0), m_allocatedSize(0) {}
#else #else
XStringAbstract() : __String<T, ThisXStringClass>(&nullChar), m_allocatedSize(0) {} XStringAbstract() : __String<T, ThisXStringClass, ThisLStringClass>(&nullChar), m_allocatedSize(0) {}
#endif #endif
/* copy ctor */ /* copy ctor */
#ifdef XSTRING_CACHING_OF_SIZE #ifdef XSTRING_CACHING_OF_SIZE
XStringAbstract(const XStringAbstract& S) : __String<T, ThisXStringClass>(&nullChar, 0), m_allocatedSize(0) XStringAbstract(const XStringAbstract& S) : __String<T, ThisXStringClass, ThisLStringClass>(&nullChar, 0), m_allocatedSize(0)
#else #else
XStringAbstract(const XStringAbstract& S) : __String<T, ThisXStringClass>(&nullChar), m_allocatedSize(0) XStringAbstract(const XStringAbstract& S) : __String<T, ThisXStringClass, ThisLStringClass>(&nullChar), m_allocatedSize(0)
#endif #endif
{ {
*this = S; *this = S;
@ -827,19 +838,19 @@ public:
#else #else
/* ctor */ /* ctor */
template<class OtherLStringClass> template<class OtherLStringClass>
explicit XStringAbstract(const LString<T, OtherLStringClass>& S) : __String<T, ThisXStringClass>(S.s()), m_allocatedSize(0) {} explicit XStringAbstract(const LString<T, OtherLStringClass, typename OtherLStringClass::ls_t>& S) : __String<T, ThisXStringClass, typename ThisXStringClass::ls_t>(S.s()), m_allocatedSize(0) {}
template<typename O, class OtherXStringClass> template<typename O, class OtherXStringClass>
explicit XStringAbstract<T, ThisXStringClass>(const XStringAbstract<O, OtherXStringClass>& S) : __String<T, ThisXStringClass>(&nullChar), m_allocatedSize(0) { takeValueFrom(S); } explicit XStringAbstract<T, ThisXStringClass, ThisLStringClass>(const XStringAbstract<O, OtherXStringClass, typename OtherXStringClass::ls_t>& S) : __String<T, ThisXStringClass, ThisLStringClass>(&nullChar), m_allocatedSize(0) { takeValueFrom(S); }
template<typename O, class OtherXStringClass> template<typename O, class OtherXStringClass>
explicit XStringAbstract<T, ThisXStringClass>(const LString<O, OtherXStringClass>& S) : __String<T, ThisXStringClass>(&nullChar), m_allocatedSize(0) { takeValueFrom(S); } explicit XStringAbstract<T, ThisXStringClass, ThisLStringClass>(const LString<O, OtherXStringClass, typename OtherXStringClass::ls_t>& S) : __String<T, ThisXStringClass, typename ThisXStringClass::ls_t>(&nullChar), m_allocatedSize(0) { takeValueFrom(S); }
// TEMPORARILY DISABLED // TEMPORARILY DISABLED
// template<typename O> // template<typename O>
// explicit __String<T, ThisXStringClass>(const O* S) { Init(0); takeValueFrom(S); } // explicit __String<T, ThisXStringClass>(const O* S) { Init(0); takeValueFrom(S); }
// //
#endif #endif
/* Copy Assign */ /* Copy Assign */
XStringAbstract& operator=(const XStringAbstract &S) { XStringAbstract& operator=(const XStringAbstract &S) {
if ( S.data() && S.m_allocatedSize == 0 ) { if ( S.data() && S.m_allocatedSize == 0 ) {
// S points to a litteral // S points to a litteral
if ( m_allocatedSize > 0 ) { if ( m_allocatedSize > 0 ) {
@ -855,6 +866,19 @@ public:
} }
return *this; 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 */ /* Assign */
#ifndef _MSC_VER #ifndef _MSC_VER
@ -862,7 +886,7 @@ public:
#pragma GCC diagnostic ignored "-Weffc++" #pragma GCC diagnostic ignored "-Weffc++"
#endif #endif
template<typename O, class OtherXStringClass> template<typename O, class OtherXStringClass>
ThisXStringClass& operator =(const __String<O, OtherXStringClass>& S) { strcpy(S.s()); return *((ThisXStringClass*)this); } ThisXStringClass& operator =(const __String<O, OtherXStringClass, typename OtherXStringClass::ls_t>& S) { strcpy(S.s()); return *((ThisXStringClass*)this); }
#ifndef _MSC_VER #ifndef _MSC_VER
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
@ -1057,7 +1081,7 @@ public:
} }
/* strcat __String */ /* strcat __String */
template<typename OtherCharType, class OtherXStringClass> template<typename OtherCharType, class OtherXStringClass>
void strcat(const __String<OtherCharType, OtherXStringClass>& other) void strcat(const __String<OtherCharType, OtherXStringClass, typename OtherXStringClass::ls_t>& other)
{ {
size_t currentSize = super::size(); // size is number of T, not in bytes 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 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 */ /* takeValueFrom */
template<typename O, class OtherXStringClass> template<typename O, class OtherXStringClass>
ThisXStringClass& takeValueFrom(const __String<O, OtherXStringClass>& S) { *this = S; return *((ThisXStringClass*)this); } ThisXStringClass& takeValueFrom(const __String<O, OtherXStringClass, typename OtherXStringClass::ls_t>& S) { *this = S; return *((ThisXStringClass*)this); }
template<typename O> template<typename O>
ThisXStringClass& takeValueFrom(const O* S) { strcpy(S); return *((ThisXStringClass*)this); } ThisXStringClass& takeValueFrom(const O* S) { strcpy(S); return *((ThisXStringClass*)this); }
template<typename O, enable_if(is_char(O))> template<typename O, enable_if(is_char(O))>
@ -1371,7 +1395,7 @@ public:
/* += */ /* += */
template<typename O, class OtherXStringClass> template<typename O, class OtherXStringClass>
ThisXStringClass& operator += (const __String<O, OtherXStringClass>& S) { strcat(S.s()); return *((ThisXStringClass*)this); } ThisXStringClass& operator += (const __String<O, OtherXStringClass, typename OtherXStringClass::ls_t>& S) { strcat(S.s()); return *((ThisXStringClass*)this); }
template<typename O, enable_if(is_char(O))> template<typename O, enable_if(is_char(O))>
ThisXStringClass& operator += (O S) { strcat(S); return *((ThisXStringClass*)this); } ThisXStringClass& operator += (O S) { strcat(S); return *((ThisXStringClass*)this); }
template<typename O> template<typename O>
@ -1380,8 +1404,8 @@ public:
}; };
template<class T, class ThisXStringClass> template<class T, class ThisXStringClass, class ThisLStringClass>
T XStringAbstract<T, ThisXStringClass>::nullChar = 0; T XStringAbstract<T, ThisXStringClass, ThisLStringClass>::nullChar = 0;
//------------------------------------------------------- + operator //------------------------------------------------------- + operator