mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 22:02:49 -06:00
134 lines
5.1 KiB
C++
134 lines
5.1 KiB
C++
class WString;
|
|
|
|
class WString0 {
|
|
enum { SMALL = 23 };
|
|
|
|
wchar *ptr;
|
|
int length;
|
|
int alloc;
|
|
|
|
static Atomic voidptr[2];
|
|
|
|
bool IsRc() const { return alloc > SMALL; }
|
|
Atomic& Rc() { return *((Atomic *)ptr - 1); }
|
|
bool IsShared() { return IsRc() && Rc() > 1; }
|
|
|
|
wchar *Alloc(int& count);
|
|
void LCat(int c);
|
|
void UnShare();
|
|
|
|
friend class WStringBuffer;
|
|
friend class WString;
|
|
|
|
protected:
|
|
typedef wchar tchar;
|
|
typedef int16 bchar;
|
|
typedef WStringBuffer Buffer;
|
|
typedef WString String;
|
|
|
|
void Zero() { static wchar e[2]; length = alloc = 0; ptr = e; ASSERT(*ptr == 0); }
|
|
void Set(const wchar *s, int length);
|
|
void Set(const WString0& s);
|
|
void Free();
|
|
void Swap(WString0& b) { Upp::Swap(ptr, b.ptr); Upp::Swap(length, b.length); Upp::Swap(alloc, b.alloc); }
|
|
wchar *Insert(int pos, int count, const wchar *data);
|
|
|
|
public:
|
|
const wchar *Begin() const { return ptr; }
|
|
int operator[](int i) const { return ptr[i]; }
|
|
|
|
operator const wchar *() const { return Begin(); }
|
|
const wchar *operator~() const { return Begin(); }
|
|
|
|
void Cat(int c) { if(!IsRc() && length < alloc) { ptr[length++] = c; ptr[length] = 0; } else LCat(c); }
|
|
void Cat(const wchar *s, int length);
|
|
|
|
int GetCount() const { return length; }
|
|
int GetLength() const { return length; }
|
|
int GetAlloc() const { return alloc; }
|
|
|
|
unsigned GetHashValue() const { return memhash(ptr, length * sizeof(wchar)); }
|
|
bool IsEqual(const WString0& s) const { return memcmp(ptr, s.ptr, length * sizeof(wchar)) == 0; }
|
|
|
|
void Remove(int pos, int count);
|
|
void Insert(int pos, const wchar *s, int count);
|
|
void Clear() { Free(); Zero(); }
|
|
|
|
void Set(int pos, int ch);
|
|
void Trim(int pos);
|
|
|
|
WString0() { Zero(); }
|
|
~WString0() { Free(); }
|
|
};
|
|
|
|
class WString : public Moveable<WString, AString<WString0> > {
|
|
void Swap(WString& b) { WString0::Swap(b); }
|
|
|
|
public:
|
|
const WString& operator+=(wchar c) { Cat(c); return *this; }
|
|
const WString& operator+=(const wchar *s) { Cat(s); return *this; }
|
|
const WString& operator+=(const WString& s) { Cat(s); return *this; }
|
|
|
|
WString& operator=(const wchar *s) { WString0::Free(); WString0::Set(s, strlen__(s)); return *this; }
|
|
WString& operator=(const WString& s) { WString0::Free(); WString0::Set(s); return *this; }
|
|
WString& operator=(WStringBuffer& b) { *this = WString(b); return *this; }
|
|
WString& operator<<=(const WString& s) { WString0::Free(); WString0::Set(s, s.GetCount()); return *this; }
|
|
|
|
WString() {}
|
|
WString(const Nuller&) {}
|
|
WString(const WString& s) { WString0::Set(s); }
|
|
WString(const wchar *s) { WString0::Set(s, strlen__(s)); }
|
|
WString(const WString& s, int n) { ASSERT(n >= 0 && n <= s.GetLength()); WString0::Set(~s, n); }
|
|
WString(const wchar *s, int n) { WString0::Set(s, n); }
|
|
WString(const wchar *s, const wchar *lim) { WString0::Set(s, lim - s); }
|
|
WString(int chr, int count) { WString0::Zero(); Cat(chr, count); }
|
|
WString(WStringBuffer& b);
|
|
|
|
WString(const char *s);
|
|
WString(const char *s, int n);
|
|
WString(const char *s, const char *lim);
|
|
|
|
static WString GetVoid();
|
|
bool IsVoid() const { return alloc < 0; }
|
|
|
|
friend void Swap(WString& a, WString& b) { a.Swap(b); }
|
|
friend WString operator+(const WString& a, char b) { WString c(a); c += b; return c; }
|
|
friend WString operator+(char a, const WString& b) { WString c(a, 1); c += b; return c; }
|
|
};
|
|
|
|
class WStringBuffer : NoCopy {
|
|
wchar *begin;
|
|
wchar *end;
|
|
wchar *limit;
|
|
|
|
friend class WString;
|
|
|
|
wchar *Alloc(int len, int& alloc);
|
|
void Expand(int n, const wchar *cat = NULL, int l = 0);
|
|
void Expand();
|
|
void Zero();
|
|
void Free();
|
|
void Set(WString& s);
|
|
|
|
public:
|
|
wchar *Begin() { *end = '\0'; return begin; }
|
|
wchar *End() { *end = '\0'; return end; }
|
|
|
|
operator wchar*() { return Begin(); }
|
|
|
|
void SetLength(int l);
|
|
int GetLength() const { return end - begin; }
|
|
void Strlen() { SetLength(wstrlen(begin)); }
|
|
|
|
void Cat(int c) { if(end >= limit) Expand(); *end++ = c; }
|
|
void Cat(const wchar *s, int l);
|
|
void Cat(const wchar *s) { Cat(s, wstrlen(s)); }
|
|
|
|
int GetAlloc() const { return limit - begin; }
|
|
|
|
void operator=(WString& s) { Free(); Set(s); }
|
|
|
|
WStringBuffer() { Zero(); }
|
|
WStringBuffer(WString& s) { Set(s); }
|
|
~WStringBuffer() { Free(); }
|
|
};
|