📄 stdstring.h
字号:
}
CStdStr(MYSIZE nSize, MYVAL ch, const MYALLOC& al=MYALLOC())
: MYBASE(nSize, ch, al)
{
}
#ifdef SS_INC_COMDEF
CStdStr(const _bstr_t& bstr)
{
if ( bstr.length() > 0 )
this->append(static_cast<PCMYSTR>(bstr), bstr.length());
}
#endif
// CStdStr inline assignment operators -- the ssasn function now takes care
// of fixing the MSVC assignment bug (see knowledge base article Q172398).
MYTYPE& operator=(const MYTYPE& str)
{
ssasn(*this, str);
return *this;
}
MYTYPE& operator=(const std::string& str)
{
ssasn(*this, str);
return *this;
}
MYTYPE& operator=(const std::wstring& str)
{
ssasn(*this, str);
return *this;
}
MYTYPE& operator=(PCSTR pA)
{
ssasn(*this, pA);
return *this;
}
MYTYPE& operator=(PCWSTR pW)
{
ssasn(*this, pW);
return *this;
}
#ifdef SS_ALLOW_UNSIGNED_CHARS
MYTYPE& operator=(PCUSTR pU)
{
ssasn(*this, static_cast<PCSTR>(pU)):
return *this;
}
#endif
MYTYPE& operator=(CT t)
{
Q172398(*this);
this->assign(1, t);
return *this;
}
#ifdef SS_INC_COMDEF
MYTYPE& operator=(const _bstr_t& bstr)
{
if ( bstr.length() > 0 )
{
this->assign(static_cast<PCMYSTR>(bstr), bstr.length());
return *this;
}
else
{
this->erase();
return *this;
}
}
#endif
// Overloads also needed to fix the MSVC assignment bug (KB: Q172398)
// *** Thanks to Pete The Plumber for catching this one ***
// They also are compiled if you have explicitly turned off refcounting
#if ( defined(_MSC_VER) && ( _MSC_VER < 1200 ) ) || defined(SS_NO_REFCOUNT)
MYTYPE& assign(const MYTYPE& str)
{
ssasn(*this, str);
return *this;
}
MYTYPE& assign(const MYTYPE& str, MYSIZE nStart, MYSIZE nChars)
{
// This overload of basic_string::assign is supposed to assign up to
// <nChars> or the NULL terminator, whichever comes first. Since we
// are about to call a less forgiving overload (in which <nChars>
// must be a valid length), we must adjust the length here to a safe
// value. Thanks to Ullrich Poll鋒ne for catching this bug
nChars = SSMIN(nChars, str.length() - nStart);
// Watch out for assignment to self
if ( this == &str )
{
MYTYPE strTemp(str.c_str()+nStart, nChars);
MYBASE::assign(strTemp);
}
else
{
Q172398(*this);
MYBASE::assign(str.c_str()+nStart, nChars);
}
return *this;
}
MYTYPE& assign(const MYBASE& str)
{
ssasn(*this, str);
return *this;
}
MYTYPE& assign(const MYBASE& str, MYSIZE nStart, MYSIZE nChars)
{
// This overload of basic_string::assign is supposed to assign up to
// <nChars> or the NULL terminator, whichever comes first. Since we
// are about to call a less forgiving overload (in which <nChars>
// must be a valid length), we must adjust the length here to a safe
// value. Thanks to Ullrich Poll鋒ne for catching this bug
nChars = SSMIN(nChars, str.length() - nStart);
// Watch out for assignment to self
if ( this == &str ) // watch out for assignment to self
{
MYTYPE strTemp(str.c_str() + nStart, nChars);
MYBASE::assign(strTemp);
}
else
{
Q172398(*this);
MYBASE::assign(str.c_str()+nStart, nChars);
}
return *this;
}
MYTYPE& assign(const CT* pC, MYSIZE nChars)
{
// Q172398 only fix -- erase before assigning, but not if we're
// assigning from our own buffer
#if defined ( _MSC_VER ) && ( _MSC_VER < 1200 )
if ( !this->empty() &&
( pC < this->data() || pC > this->data() + this->capacity() ) )
{
this->erase();
}
#endif
Q172398(*this);
MYBASE::assign(pC, nChars);
return *this;
}
MYTYPE& assign(MYSIZE nChars, MYVAL val)
{
Q172398(*this);
MYBASE::assign(nChars, val);
return *this;
}
MYTYPE& assign(const CT* pT)
{
return this->assign(pT, MYBASE::traits_type::length(pT));
}
MYTYPE& assign(MYCITER iterFirst, MYCITER iterLast)
{
#if defined ( _MSC_VER ) && ( _MSC_VER < 1200 )
// Q172398 fix. don't call erase() if we're assigning from ourself
if ( iterFirst < this->begin() || iterFirst > this->begin() + this->size() )
this->erase()
#endif
this->replace(this->begin(), this->end(), iterFirst, iterLast);
return *this;
}
#endif
// -------------------------------------------------------------------------
// CStdStr inline concatenation.
// -------------------------------------------------------------------------
MYTYPE& operator+=(const MYTYPE& str)
{
ssadd(*this, str);
return *this;
}
MYTYPE& operator+=(const std::string& str)
{
ssadd(*this, str);
return *this;
}
MYTYPE& operator+=(const std::wstring& str)
{
ssadd(*this, str);
return *this;
}
MYTYPE& operator+=(PCSTR pA)
{
ssadd(*this, pA);
return *this;
}
MYTYPE& operator+=(PCWSTR pW)
{
ssadd(*this, pW);
return *this;
}
MYTYPE& operator+=(CT t)
{
this->append(1, t);
return *this;
}
#ifdef SS_INC_COMDEF // if we have _bstr_t, define a += for it too.
MYTYPE& operator+=(const _bstr_t& bstr)
{
return this->operator+=(static_cast<PCMYSTR>(bstr));
}
#endif
// addition operators -- global friend functions.
friend MYTYPE operator+(const MYTYPE& str1, const MYTYPE& str2);
friend MYTYPE operator+(const MYTYPE& str, CT t);
friend MYTYPE operator+(const MYTYPE& str, PCSTR sz);
friend MYTYPE operator+(const MYTYPE& str, PCWSTR sz);
friend MYTYPE operator+(PCSTR pA, const MYTYPE& str);
friend MYTYPE operator+(PCWSTR pW, const MYTYPE& str);
#ifdef SS_INC_COMDEF
friend MYTYPE operator+(const _bstr_t& bstr, const MYTYPE& str);
friend MYTYPE operator+(const MYTYPE& str, const _bstr_t& bstr);
#endif
// -------------------------------------------------------------------------
// Case changing functions
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
MYTYPE& ToUpper()
{
// Strictly speaking, this would be about the most portable way
// std::transform(begin(),
// end(),
// begin(),
// std::bind2nd(SSToUpper<CT>(), std::locale()));
// But practically speaking, this works faster
if ( !empty() )
ssupr(GetBuf(), this->size());
return *this;
}
MYTYPE& ToLower()
{
// Strictly speaking, this would be about the most portable way
// std::transform(begin(),
// end(),
// begin(),
// std::bind2nd(SSToLower<CT>(), std::locale()));
// But practically speaking, this works faster
if ( !empty() )
sslwr(GetBuf(), this->size());
return *this;
}
MYTYPE& Normalize()
{
return Trim().ToLower();
}
// -------------------------------------------------------------------------
// CStdStr -- Direct access to character buffer. In the MS' implementation,
// the at() function that we use here also calls _Freeze() providing us some
// protection from multithreading problems associated with ref-counting.
// -------------------------------------------------------------------------
CT* GetBuf(int nMinLen=-1)
{
if ( static_cast<int>(size()) < nMinLen )
this->resize(static_cast<MYSIZE>(nMinLen));
return this->empty() ? const_cast<CT*>(this->data()) : &(this->at(0));
}
CT* SetBuf(int nLen)
{
nLen = ( nLen > 0 ? nLen : 0 );
if ( this->capacity() < 1 && nLen == 0 )
this->resize(1);
this->resize(static_cast<MYSIZE>(nLen));
return const_cast<CT*>(this->data());
}
void RelBuf(int nNewLen=-1)
{
this->resize(static_cast<MYSIZE>(nNewLen > -1 ? nNewLen : sslen(this->c_str())));
}
void BufferRel() { RelBuf(); } // backwards compatability
CT* Buffer() { return GetBuf(); } // backwards compatability
CT* BufferSet(int nLen) { return SetBuf(nLen);}// backwards compatability
bool Equals(const CT* pT, bool bUseCase=false) const
{ // get copy, THEN compare (thread safe)
return bUseCase ? this->compare(pT) == 0 : ssicmp(MYTYPE(*this).c_str(), pT) == 0;
}
// -------------------------------------------------------------------------
// FUNCTION: CStdStr::Load
// REMARKS:
// Loads string from resource specified by nID
//
// PARAMETERS:
// nID - resource Identifier. Purely a Win32 thing in this case
//
// RETURN VALUE:
// true if successful, false otherwise
// -------------------------------------------------------------------------
#ifndef SS_ANSI
bool Load(UINT nId, HMODULE hModule=NULL)
{
bool bLoaded = false; // set to true of we succeed.
#ifdef _MFC_VER // When in Rome...
CString strRes;
bLoaded = FALSE != strRes.LoadString(nId);
if ( bLoaded )
*this = strRes;
#else
// Get the resource name and module handle
if ( NULL == hModule )
hModule = GetResourceHandle();
PCTSTR szName = MAKEINTRESOURCE((nId>>4)+1); // lifted
DWORD dwSize = 0;
// No sense continuing if we can't find the resource
HRSRC hrsrc = ::FindResource(hModule, szName, RT_STRING);
if ( NULL == hrsrc )
{
TRACE(_T("Cannot find resource %d: 0x%X"), nId, ::GetLastError());
}
else if ( 0 == (dwSize = ::SizeofResource(hModule, hrsrc) / sizeof(CT)))
{
TRACE(_T("Cant get size of resource %d 0x%X\n"),nId,GetLastError());
}
else
{
bLoaded = 0 != ssload(hModule, nId, GetBuf(dwSize), dwSize);
ReleaseBuffer();
}
#endif
if ( !bLoaded )
TRACE(_T("String not loaded 0x%X\n"), ::GetLastError());
return bLoaded;
}
#endif
// -------------------------------------------------------------------------
// FUNCTION: CStdStr::Format
// void _cdecl Formst(CStdStringA& PCSTR szFormat, ...)
// void _cdecl Format(PCSTR szFormat);
//
// DESCRIPTION:
// This function does sprintf/wsprintf style formatting on CStdStringA
// objects. It looks a lot like MFC's CString::Format. Some people
// might even call this identical. Fortunately, these people are now
// dead.
//
// PARAMETERS:
// nId - ID of string resource holding the format string
// szFormat - a PCSTR holding the format specifiers
// argList - a va_list holding the arguments for the format specifiers.
//
// RETURN VALUE: None.
// -------------------------------------------------------------------------
// formatting (using wsprintf style formatting)
#ifndef SS_ANSI
void Format(UINT nId, ...)
{
va_list argList;
va_start(argList, nId);
va_start(argList, nId);
MYT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -