📄 stdstring.h
字号:
// non-standard, but often significantly faster Visual C++ way.
// =============================================================================
// If they defined SS_NO_REFCOUNT, then we must convert all assignments
#ifdef SS_NO_REFCOUNT
#define SSREF(x) (x).c_str()
#else
#define SSREF(x) (x)
#endif
// -----------------------------------------------------------------------------
// sslen: strlen/wcslen wrappers
// -----------------------------------------------------------------------------
template<typename CT> inline int sslen(const CT* pT)
{
return 0 == pT ? 0 : (int)std::basic_string<CT>::traits_type::length(pT);
// return 0 == pT ? 0 : std::char_traits<CT>::length(pT);
}
inline SS_NOTHROW int sslen(const std::string& s)
{
return static_cast<int>(s.length());
}
inline SS_NOTHROW int sslen(const std::wstring& s)
{
return static_cast<int>(s.length());
}
// -----------------------------------------------------------------------------
// sstolower/sstoupper -- convert characters to upper/lower case
// -----------------------------------------------------------------------------
template<typename CT>
inline CT sstolower(const CT& t, const std::locale& loc = std::locale())
{
return std::tolower<CT>(t, loc);
}
template<typename CT>
inline CT sstoupper(const CT& t, const std::locale& loc = std::locale())
{
return std::toupper<CT>(t, loc);
}
// -----------------------------------------------------------------------------
// ssasn: assignment functions -- assign "sSrc" to "sDst"
// -----------------------------------------------------------------------------
typedef std::string::size_type SS_SIZETYPE; // just for shorthand, really
typedef std::string::pointer SS_PTRTYPE;
typedef std::wstring::size_type SW_SIZETYPE;
typedef std::wstring::pointer SW_PTRTYPE;
inline void ssasn(std::string& sDst, const std::string& sSrc)
{
if ( sDst.c_str() != sSrc.c_str() )
{
sDst.erase();
sDst.assign(SSREF(sSrc));
}
}
inline void ssasn(std::string& sDst, PCSTR pA)
{
// Watch out for NULLs, as always.
if ( 0 == pA )
{
sDst.erase();
}
// If pA actually points to part of sDst, we must NOT erase(), but
// rather take a substring
else if ( pA >= sDst.c_str() && pA <= sDst.c_str() + sDst.size() )
{
sDst =sDst.substr(static_cast<SS_SIZETYPE>(pA-sDst.c_str()));
}
// Otherwise (most cases) apply the assignment bug fix, if applicable
// and do the assignment
else
{
Q172398(sDst);
sDst.assign(pA);
}
}
inline void ssasn(std::string& sDst, const std::wstring& sSrc)
{
if ( sSrc.empty() )
{
sDst.erase();
}
else
{
int nDst = static_cast<int>(sSrc.size());
// In MBCS builds, pad the buffer to account for the possibility of
// some 3 byte characters. Not perfect but should get most cases.
#ifdef SS_MBCS
nDst = static_cast<int>(static_cast<double>(nDst) * 1.3);
#endif
sDst.resize(nDst+1);
PCSTR szCvt = StdCodeCvt(const_cast<SS_PTRTYPE>(sDst.data()), nDst,
sSrc.c_str(), static_cast<int>(sSrc.size()));
// In MBCS builds, we don't know how long the destination string will be.
#ifdef SS_MBCS
sDst.resize(sslen(szCvt));
#else
szCvt;
sDst.resize(sSrc.size());
#endif
}
}
inline void ssasn(std::string& sDst, PCWSTR pW)
{
int nSrc = sslen(pW);
if ( nSrc > 0 )
{
int nSrc = sslen(pW);
int nDst = nSrc;
// In MBCS builds, pad the buffer to account for the possibility of
// some 3 byte characters. Not perfect but should get most cases.
#ifdef SS_MBCS
nDst = static_cast<int>(static_cast<double>(nDst) * 1.3);
#endif
sDst.resize(nDst + 1);
PCSTR szCvt = StdCodeCvt(const_cast<SS_PTRTYPE>(sDst.data()), nDst,
pW, nSrc);
// In MBCS builds, we don't know how long the destination string will be.
#ifdef SS_MBCS
sDst.resize(sslen(szCvt));
#else
sDst.resize(nDst);
szCvt;
#endif
}
else
{
sDst.erase();
}
}
inline void ssasn(std::string& sDst, const int nNull)
{
UNUSED(nNull);
ASSERT(nNull==0);
sDst.assign("");
}
inline void ssasn(std::wstring& sDst, const std::wstring& sSrc)
{
if ( sDst.c_str() != sSrc.c_str() )
{
sDst.erase();
sDst.assign(SSREF(sSrc));
}
}
inline void ssasn(std::wstring& sDst, PCWSTR pW)
{
// Watch out for NULLs, as always.
if ( 0 == pW )
{
sDst.erase();
}
// If pW actually points to part of sDst, we must NOT erase(), but
// rather take a substring
else if ( pW >= sDst.c_str() && pW <= sDst.c_str() + sDst.size() )
{
sDst = sDst.substr(static_cast<SW_SIZETYPE>(pW-sDst.c_str()));
}
// Otherwise (most cases) apply the assignment bug fix, if applicable
// and do the assignment
else
{
Q172398(sDst);
sDst.assign(pW);
}
}
#undef StrSizeType
inline void ssasn(std::wstring& sDst, const std::string& sSrc)
{
if ( sSrc.empty() )
{
sDst.erase();
}
else
{
int nSrc = static_cast<int>(sSrc.size());
int nDst = nSrc;
sDst.resize(nSrc+1);
PCWSTR szCvt = StdCodeCvt(const_cast<SW_PTRTYPE>(sDst.data()), nDst,
sSrc.c_str(), nSrc);
sDst.resize(sslen(szCvt));
}
}
inline void ssasn(std::wstring& sDst, PCSTR pA)
{
int nSrc = sslen(pA);
if ( 0 == nSrc )
{
sDst.erase();
}
else
{
int nDst = nSrc;
sDst.resize(nDst+1);
PCWSTR szCvt = StdCodeCvt(const_cast<SW_PTRTYPE>(sDst.data()), nDst, pA,
nSrc);
sDst.resize(sslen(szCvt));
}
}
inline void ssasn(std::wstring& sDst, const int nNull)
{
UNUSED(nNull);
ASSERT(nNull==0);
sDst.assign(L"");
}
// -----------------------------------------------------------------------------
// ssadd: string object concatenation -- add second argument to first
// -----------------------------------------------------------------------------
inline void ssadd(std::string& sDst, const std::wstring& sSrc)
{
int nSrc = static_cast<int>(sSrc.size());
if ( nSrc > 0 )
{
int nDst = static_cast<int>(sDst.size());
int nAdd = nSrc;
// In MBCS builds, pad the buffer to account for the possibility of
// some 3 byte characters. Not perfect but should get most cases.
#ifdef SS_MBCS
nAdd = static_cast<int>(static_cast<double>(nAdd) * 1.3);
#endif
sDst.resize(nDst+nAdd+1);
PCSTR szCvt = StdCodeCvt(const_cast<SS_PTRTYPE>(sDst.data()+nDst),
nAdd, sSrc.c_str(), nSrc);
#ifdef SS_MBCS
sDst.resize(nDst + sslen(szCvt));
#else
sDst.resize(nDst + nAdd);
szCvt;
#endif
}
}
inline void ssadd(std::string& sDst, const std::string& sSrc)
{
sDst += sSrc;
}
inline void ssadd(std::string& sDst, PCWSTR pW)
{
int nSrc = sslen(pW);
if ( nSrc > 0 )
{
int nDst = static_cast<int>(sDst.size());
int nAdd = nSrc;
#ifdef SS_MBCS
nAdd = static_cast<int>(static_cast<double>(nAdd) * 1.3);
#endif
sDst.resize(nDst + nAdd + 1);
PCSTR szCvt = StdCodeCvt(const_cast<SS_PTRTYPE>(sDst.data()+nDst),
nAdd, pW, nSrc);
#ifdef SS_MBCS
sDst.resize(nDst + sslen(szCvt));
#else
sDst.resize(nDst + nSrc);
szCvt;
#endif
}
}
inline void ssadd(std::string& sDst, PCSTR pA)
{
if ( pA )
{
// If the string being added is our internal string or a part of our
// internal string, then we must NOT do any reallocation without
// first copying that string to another object (since we're using a
// direct pointer)
if ( pA >= sDst.c_str() && pA <= sDst.c_str()+sDst.length())
{
if ( sDst.capacity() <= sDst.size()+sslen(pA) )
sDst.append(std::string(pA));
else
sDst.append(pA);
}
else
{
sDst.append(pA);
}
}
}
inline void ssadd(std::wstring& sDst, const std::wstring& sSrc)
{
sDst += sSrc;
}
inline void ssadd(std::wstring& sDst, const std::string& sSrc)
{
if ( !sSrc.empty() )
{
int nSrc = static_cast<int>(sSrc.size());
int nDst = static_cast<int>(sDst.size());
sDst.resize(nDst + nSrc + 1);
PCWSTR szCvt = StdCodeCvt(const_cast<SW_PTRTYPE>(sDst.data()+nDst),
nSrc, sSrc.c_str(), nSrc+1);
#ifdef SS_MBCS
sDst.resize(nDst + sslen(szCvt));
#else
sDst.resize(nDst + nSrc);
szCvt;
#endif
}
}
inline void ssadd(std::wstring& sDst, PCSTR pA)
{
int nSrc = sslen(pA);
if ( nSrc > 0 )
{
int nDst = static_cast<int>(sDst.size());
sDst.resize(nDst + nSrc + 1);
PCWSTR szCvt = StdCodeCvt(const_cast<SW_PTRTYPE>(sDst.data()+nDst),
nSrc, pA, nSrc+1);
#ifdef SS_MBCS
sDst.resize(nDst + sslen(szCvt));
#else
sDst.resize(nDst + nSrc);
szCvt;
#endif
}
}
inline void ssadd(std::wstring& sDst, PCWSTR pW)
{
if ( pW )
{
// If the string being added is our internal string or a part of our
// internal string, then we must NOT do any reallocation without
// first copying that string to another object (since we're using a
// direct pointer)
if ( pW >= sDst.c_str() && pW <= sDst.c_str()+sDst.length())
{
if ( sDst.capacity() <= sDst.size()+sslen(pW) )
sDst.append(std::wstring(pW));
else
sDst.append(pW);
}
else
{
sDst.append(pW);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -