#pragma once
#include <string>
template<class T>
void SwapFun(T& left, T& right)
{
T temp = left;
left = right;
right = temp;
}
class CShString
{
public:
CShString(char* pStr)
:m_iLen(strlen(pStr))
, m_iMaxSize(CalcuMax(m_iLen))
, px(new char[m_iMaxSize])
, pn(new int(1))
{
memcpy(px, pStr, m_iLen + 1);
}
CShString(char* pStr, int iLength)
:m_iLen(iLength)
, m_iMaxSize(CalcuMax(iLength))
, px(new char[m_iMaxSize])
, pn(new int(1))
{
ASSERT(iLength == strlen(pStr));
memcpy(px, pStr, m_iLen);
px[m_iLen] = '\0';
}
CShString(const CShString& strOther)
: px (strOther.px), pn(strOther.pn);
{
++*pn;
}
CShString& Assign(const CShString& other)
{
Swap(CShString(other.Data(), other.GetLength()));
return *this;
}
CShString& Assign(const char* pStr)
{
Swap(CShString(pStr));
return *this;
}
CShString& Assign(const char* pStr, int ilength)
{
Swap(CShString(pStr, ilength));
return *this;
}
CShString& Append(const CShString& other)
{
int nSize = GetLength() + other.GetLength() + 1;
char* pStr = new char[nSize];
memcpy(pStr, Data(), GetLength());
memcpy(pStr + GetLength(), other,Data(), other.GetLength() + 1);
ResetAs(pStr, nSize);
}
CShString& Append(const char* pOther)
{
int nLen = strlen(pOther);
int nSize = GetLength() + nLen + 1;
char* pStr = new char[nSize];
memcpy(pStr, Data(), GetLength());
memcpy(pStr + GetLength(), pOther, nLen + 1);
ResetAs(pStr, nSize);
}
CShString& Append(const char* pStr, int ilength)
{
int nSize = GetLength() + ilength + 1;
char* pStr = new char[nSize];
memcpy(pStr, Data(), GetLength());
memcpy(pStr + GetLength(), pStr, ilength + 1);
ResetAs(pStr, nSize);
}
~CShString(void)
{
if (--*pn == 0)
{
delete pn;
delete px;
}
}
const char* Data() const
{
return px;
}
int GetLength()
{
return m_iLen;
}
private:
void ResetAs(char* pStr, int iSize)
{
if (--*pn == 0)
{
delete pn;
delete px;
}
m_iMaxSize = CalcuMax(iSize);
m_iLen = iSize - 1;
px = pStr;
pn = new int(1);
}
void Swap(CShString& other)
{
SwapFun(m_iLen, other.m_iLen);
SwapFun(m_iMaxSize, other.m_iMaxSize);
SwapFun(px, other.px);
SwapFun(pn, other.pn);
}
static int CalcuMax(int iLen)
{
int i = 0;
while (INIT_MAX_LEN + (i++) * DELTA_LEN < iLen + 1){}
return INIT_MAX_LEN + (i - 1) * DELTA_LEN;
}
static const int INIT_MAX_LEN = 100;
static const int DELTA_LEN = 20;
int m_iLen;
int m_iMaxSize;
char* px;
int* pn;
};