⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stdstring.h

📁 这是一个非常好的、可以替代mfc中的CString的字符串类。支持ansi、unicode。
💻 H
📖 第 1 页 / 共 5 页
字号:
		// checking for every possible distro here, I'll assume that unless
		// I am running with Microsoft's CRT, then vswprintf takes four
		// arguments.  If you get a compilation error here, then you can just
		// change this code to call the three-argument version.
//	#if !defined(__MWERKS__) && !defined(__SUNPRO_CC_COMPAT) && !defined(__SUNPRO_CC)
	#ifndef _MSC_VER
		return vswprintf(pW, nCount, pFmtW, vl);
	#else
		nCount;
		return vswprintf(pW, pFmtW, vl);
	#endif
	}
#else
	inline int	ssnprintf(PSTR pA, size_t nCount, PCSTR pFmtA, va_list vl)
	{ 
		return _vsnprintf(pA, nCount, pFmtA, vl);
	}
	inline int	ssnprintf(PWSTR pW, size_t nCount, PCWSTR pFmtW, va_list vl)
	{
		return _vsnwprintf(pW, nCount, pFmtW, vl);
	}
#endif


// -----------------------------------------------------------------------------
// ssload: Type safe, overloaded ::LoadString wrappers
// There is no equivalent of these in non-Win32-specific builds.  However, I'm
// thinking that with the message facet, there might eventually be one
// -----------------------------------------------------------------------------
#ifdef SS_ANSI
#else
	inline int ssload(HMODULE hInst, UINT uId, PSTR pBuf, int nMax)
	{
		return ::LoadStringA(hInst, uId, pBuf, nMax);
	}
	inline int ssload(HMODULE hInst, UINT uId, PWSTR pBuf, int nMax)
	{
		return ::LoadStringW(hInst, uId, pBuf, nMax);
	}
#endif


// -----------------------------------------------------------------------------
// sscoll/ssicoll: Collation wrappers
//		Note -- with MSVC I have reversed the arguments order here because the
//		functions appear to return the opposite of what they should
// -----------------------------------------------------------------------------
#ifdef SS_ANSI
	#ifdef SS_NOLOCALE
		inline int sscoll(PCSTR sz1, int /*nLen1*/, PCSTR sz2, int /*nLen2*/)
		{
			return strcoll(sz2, sz1);
		}
		inline int sscoll(PCWSTR sz1, int /*nLen1*/, PCWSTR sz2, int /*nLen2*/)
		{
			return wcscoll(sz2, sz1);
		}
		template<typename CT>
		inline int ssicoll(const CT* sz1, int nLen1, const CT* sz2, int nLen2)
		{
			std::basic_string<CT> str1(sz1, nLen1);
			std::basic_string<CT> str2(sz2, nLen2);

			// JMO: Note this is a complete hack. But so is SS_NOLOCALE

			sslwr((CT*)str1.data(), nLen1);
			sslwr((CT*)str2.data(), nLen2);
			
			return sscoll(str2.c_str(), str2.size(), str1.c_str(), str1.size());
		}
	#else
		template <typename CT>
		inline int sscoll(const CT* sz1, int nLen1, const CT* sz2, int nLen2)
		{
			const std::collate<CT>& coll =
				SS_USE_FACET(std::locale(), std::collate<CT>);

			return coll.compare(sz2, sz2+nLen2, sz1, sz1+nLen1);
		}
		template <typename CT>
		inline int ssicoll(const CT* sz1, int nLen1, const CT* sz2, int nLen2)
		{
			const std::locale loc;
			const std::collate<CT>& coll = SS_USE_FACET(loc, std::collate<CT>);

			// Some implementations seem to have trouble using the collate<>
			// facet typedefs so we'll just default to basic_string and hope
			// that's what the collate facet uses (which it generally should)

//			std::collate<CT>::string_type s1(sz1);
//			std::collate<CT>::string_type s2(sz2);
			std::basic_string<CT> s1(sz1);
			std::basic_string<CT> s2(sz2);

			sslwr(const_cast<CT*>(s1.c_str()), nLen1);
			sslwr(const_cast<CT*>(s2.c_str()), nLen2);
			return coll.compare(s2.c_str(), s2.c_str()+nLen2,
								s1.c_str(), s1.c_str()+nLen1);
	}
	#endif
#else
	#ifdef _MBCS
		inline int sscoll(PCSTR sz1, int /*nLen1*/, PCSTR sz2, int /*nLen2*/)
		{
			return _mbscoll((PCUSTR)sz1, (PCUSTR)sz2);
		}
		inline int ssicoll(PCSTR sz1, int /*nLen1*/, PCSTR sz2, int /*nLen2*/)
		{
			return _mbsicoll((PCUSTR)sz1, (PCUSTR)sz2);
		}
	#else
		inline int sscoll(PCSTR sz1, int /*nLen1*/, PCSTR sz2, int /*nLen2*/)
		{
			return strcoll(sz1, sz2);
		}
		inline int ssicoll(PCSTR sz1, int /*nLen1*/, PCSTR sz2, int /*nLen2*/)
		{
			return _stricoll(sz1, sz2);
		}
	#endif
	inline int sscoll(PCWSTR sz1, int /*nLen1*/, PCWSTR sz2, int /*nLen2*/)
	{
		return wcscoll(sz1, sz2);
	}
	inline int ssicoll(PCWSTR sz1, int /*nLen1*/, PCWSTR sz2, int /*nLen2*/)
	{
		return _wcsicoll(sz1, sz2);
	}
#endif


// -----------------------------------------------------------------------------
// ssfmtmsg: FormatMessage equivalents.  Needed because I added a CString facade
// Again -- no equivalent of these on non-Win32 builds but their might one day
// be one if the message facet gets implemented
// -----------------------------------------------------------------------------
#ifdef SS_ANSI
#else
	inline DWORD ssfmtmsg(DWORD dwFlags, LPCVOID pSrc, DWORD dwMsgId,
						  DWORD dwLangId, PSTR pBuf, DWORD nSize,
						  va_list* vlArgs)
	{ 
		return FormatMessageA(dwFlags, pSrc, dwMsgId, dwLangId,
							  pBuf, nSize,vlArgs);
	}
	inline DWORD ssfmtmsg(DWORD dwFlags, LPCVOID pSrc, DWORD dwMsgId,
						  DWORD dwLangId, PWSTR pBuf, DWORD nSize,
						  va_list* vlArgs)
	{
		return FormatMessageW(dwFlags, pSrc, dwMsgId, dwLangId,
							  pBuf, nSize,vlArgs);
	}
#endif
 


// FUNCTION: sscpy.  Copies up to 'nMax' characters from pSrc to pDst.
// -----------------------------------------------------------------------------
// FUNCTION:  sscpy
//		inline int sscpy(PSTR pDst, PCSTR pSrc, int nMax=-1);
//		inline int sscpy(PUSTR pDst,  PCSTR pSrc, int nMax=-1)
//		inline int sscpy(PSTR pDst, PCWSTR pSrc, int nMax=-1);
//		inline int sscpy(PWSTR pDst, PCWSTR pSrc, int nMax=-1);
//		inline int sscpy(PWSTR pDst, PCSTR pSrc, int nMax=-1);
//
// DESCRIPTION:
//		This function is very much (but not exactly) like strcpy.  These
//		overloads simplify copying one C-style string into another by allowing
//		the caller to specify two different types of strings if necessary.
//
//		The strings must NOT overlap
//
//		"Character" is expressed in terms of the destination string, not
//		the source.  If no 'nMax' argument is supplied, then the number of
//		characters copied will be sslen(pSrc).  A NULL terminator will
//		also be added so pDst must actually be big enough to hold nMax+1
//		characters.  The return value is the number of characters copied,
//		not including the NULL terminator.
//
// PARAMETERS: 
//		pSrc - the string to be copied FROM.  May be a char based string, an
//			   MBCS string (in Win32 builds) or a wide string (wchar_t).
//		pSrc - the string to be copied TO.  Also may be either MBCS or wide
//		nMax - the maximum number of characters to be copied into szDest.  Note
//			   that this is expressed in whatever a "character" means to pDst.
//			   If pDst is a wchar_t type string than this will be the maximum
//			   number of wchar_ts that my be copied.  The pDst string must be
//			   large enough to hold least nMaxChars+1 characters.
//			   If the caller supplies no argument for nMax this is a signal to
//			   the routine to copy all the characters in pSrc, regardless of
//			   how long it is.
//
// RETURN VALUE: none
// -----------------------------------------------------------------------------
template<typename CT1, typename CT2>
inline int sscpycvt(CT1* pDst, const CT2* pSrc, int nChars)
{
	StdCodeCvt(pDst, pSrc, nChars);
	pDst[SSMAX(nChars, 0)]	= '\0';
	return nChars;
}

template<typename CT1, typename CT2>
inline int sscpy(CT1* pDst, const CT2* pSrc, int nMax, int nLen)
{
	return sscpycvt(pDst, pSrc, SSMIN(nMax, nLen));
}
template<typename CT1, typename CT2>
inline int sscpy(CT1* pDst, const CT2* pSrc, int nMax)
{
	return sscpycvt(pDst, pSrc, SSMIN(nMax, sslen(pSrc)));
}
template<typename CT1, typename CT2>
inline int sscpy(CT1* pDst, const CT2* pSrc)
{
	return sscpycvt(pDst, pSrc, sslen(pSrc));
}
template<typename CT1, typename CT2>
inline int sscpy(CT1* pDst, const std::basic_string<CT2>& sSrc, int nMax)
{
	return sscpycvt(pDst, sSrc.c_str(), SSMIN(nMax, (int)sSrc.length()));
}
template<typename CT1, typename CT2>
inline int sscpy(CT1* pDst, const std::basic_string<CT2>& sSrc)
{
	return sscpycvt(pDst, sSrc.c_str(), (int)sSrc.length());
}

#ifdef SS_INC_COMDEF
	template<typename CT1>
	inline int sscpy(CT1* pDst, const _bstr_t& bs, int nMax)
	{
		return sscpycvt(pDst, static_cast<PCOLESTR>(bs), SSMIN(nMax, (int)bs.length()));
	}
	template<typename CT1>
	inline int sscpy(CT1* pDst, const _bstr_t& bs)
	{
		return sscpy(pDst, bs, bs.length());
	}
#endif


// -----------------------------------------------------------------------------
// Functional objects for changing case.  They also let you pass locales
// -----------------------------------------------------------------------------

#ifdef SS_ANSI
	#ifdef SS_NOLOCALE
		template<typename CT>
		struct SSToUpper : public std::unary_function<CT, CT>
		{
			inline CT operator()(const CT& t) const
			{
				return sstoupper(t);
			}
		};
		template<typename CT>
		struct SSToLower : public std::unary_function<CT, CT>
		{
			inline CT operator()(const CT& t) const
			{
				return sstolower(t);
			}
		};
	#else
		template<typename CT>
		struct SSToUpper : public std::binary_function<CT, std::locale, CT>
		{
			inline CT operator()(const CT& t, const std::locale& loc) const
			{
				return sstoupper<CT>(t, loc);
			}
		};
		template<typename CT>
		struct SSToLower : public std::binary_function<CT, std::locale, CT>
		{
			inline CT operator()(const CT& t, const std::locale& loc) const
			{
				return sstolower<CT>(t, loc);
			}
		};
	#endif
#endif

// This struct is used for TrimRight() and TrimLeft() function implementations.
//template<typename CT>
//struct NotSpace : public std::unary_function<CT, bool>
//{
//	const std::locale& loc;
//	inline NotSpace(const std::locale& locArg) : loc(locArg) {}
//	inline bool operator() (CT t) { return !std::isspace(t, loc); }
//};
template<typename CT>
struct NotSpace : public std::unary_function<CT, bool>
{

	// DINKUMWARE BUG:
	// Note -- using std::isspace in a COM DLL gives us access violations
	// because it causes the dynamic addition of a function to be called
	// when the library shuts down.  Unfortunately the list is maintained
	// in DLL memory but the function is in static memory.  So the COM DLL
	// goes away along with the function that was supposed to be called,
	// and then later when the DLL CRT shuts down it unloads the list and
	// tries to call the long-gone function.
	// This is DinkumWare's implementation problem.  Until then, we will
	// use good old isspace and iswspace from the CRT unless they
	// specify SS_ANSI
#if defined(SS_ANSI) && !defined(SS_NOLOCALE)
	const std::locale loc;
	NotSpace(const std::locale& locArg=std::locale()) : loc(locArg) {}
	bool operator() (CT t) const { return !std::isspace(t, loc); }
#else
	bool ssisp(char c) const { return FALSE != ::isspace((int) c); }
	bool ssisp(wchar_t c) const { return FALSE != ::iswspace((wint_t) c); }
	bool operator()(CT t) const  { return !ssisp(t); }
#endif
};




//			Now we can define the template (finally!)
// =============================================================================
// TEMPLATE: CStdStr
//		template<typename CT> class CStdStr : public std::basic_string<CT>
//
// REMARKS:
//		This template derives from basic_string<CT> and adds some MFC CString-
//		like functionality
//
//		Basically, this is my attempt to make Standard C++ library strings as
//		easy to use as the MFC CString class.
//
//		Note that although this is a template, it makes the assumption that the
//		template argument (CT, the character type) is either char or wchar_t.  
// =============================================================================

//#define CStdStr _SS	// avoid compiler warning 4786


template<typename CT>
class CStdStr : public std::basic_string<CT>
{
	// Typedefs for shorter names.  Using these names also appears to help
	// us avoid some ambiguities that otherwise arise on some platforms

	typedef typename std::basic_string<CT>		MYBASE;	 // my base class
	typedef CStdStr<CT>							MYTYPE;	 // myself
	typedef typename MYBASE::const_pointer		PCMYSTR; // PCSTR or PCWSTR 
	typedef typename MYBASE::pointer			PMYSTR;	 // PSTR or PWSTR
	typedef typename MYBASE::iterator			MYITER;  // my iterator type
	typedef typename MYBASE::const_iterator		MYCITER; // you get the idea...
	typedef typename MYBASE::reverse_iterator	MYRITER;
	typedef typename MYBASE::size_type			MYSIZE;   
	typedef typename MYBASE::value_type			MYVAL; 
	typedef typename MYBASE::allocator_type		MYALLOC;
	
public:

	// shorthand conversion from PCTSTR to string resource ID
	#define _TRES(pctstr) (LOWORD((DWORD)(pctstr)))	

	// CStdStr inline constructors
	CStdStr()
	{
	}

	CStdStr(const MYTYPE& str) : MYBASE(SSREF(str))
	{
	}

	CStdStr(const std::string& str)
	{
		ssasn(*this, SSREF(str));
	}

	CStdStr(const std::wstring& str)
	{
		ssasn(*this, SSREF(str));
	}

	CStdStr(PCMYSTR pT, MYSIZE n) : MYBASE(pT, n)
	{
	}

#ifdef SS_ALLOW_UNSIGNED_CHARS
	CStdStr(PCUSTR pU)
	{
		*this = static_cast<PCSTR>(pU);
	}
#endif

	CStdStr(PCSTR pA)
	{
	#ifdef SS_ANSI
		*this = pA;
	#else
		if ( 0 != HIWORD(pA) )
			*this = pA;
		else if ( 0 != pA && !Load(_TRES(pA)) )
			TRACE(_T("Can't load string %u\n"), _TRES(pA));
	#endif
	}

	CStdStr(PCWSTR pW)
	{
	#ifdef SS_ANSI
		*this = pW;
	#else
		if ( 0 != HIWORD(pW) )
			*this = pW;
		else if ( 0 != pW && !Load(_TRES(pW)) )
			TRACE(_T("Can't load string %u\n"), _TRES(pW));
	#endif
	}

	CStdStr(MYCITER first, MYCITER last)
		: MYBASE(first, last)
	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -