103 |
// finally spotting a silly little error in StdCodeCvt that |
// finally spotting a silly little error in StdCodeCvt that |
104 |
// has been causing me (and users of CStdString) problems for |
// has been causing me (and users of CStdString) problems for |
105 |
// years in some relatively rare conversions. I had reversed |
// years in some relatively rare conversions. I had reversed |
106 |
// two length arguments. |
// two length arguments. |
107 |
// |
// |
108 |
// 2003-NOV-24 - Thanks to a bunch of people for helping me clean up many |
// 2003-NOV-24 - Thanks to a bunch of people for helping me clean up many |
109 |
// compiler warnings (and yes, even a couple of actual compiler |
// compiler warnings (and yes, even a couple of actual compiler |
167 |
// |
// |
168 |
// 2001-OCT-29 - Added a minor range checking fix for the Mid function to |
// 2001-OCT-29 - Added a minor range checking fix for the Mid function to |
169 |
// make it as forgiving as CString's version is. Thanks to |
// make it as forgiving as CString's version is. Thanks to |
170 |
// Igor Kholodov for noticing this. |
// Igor Kholodov for noticing this. |
171 |
// - Added a specialization of std::swap for CStdString. Thanks |
// - Added a specialization of std::swap for CStdString. Thanks |
172 |
// to Mike Crusader for suggesting this! It's commented out |
// to Mike Crusader for suggesting this! It's commented out |
173 |
// because you're not supposed to inject your own code into the |
// because you're not supposed to inject your own code into the |
245 |
// - Some of the Q172398 fixes were not checking for assignment- |
// - Some of the Q172398 fixes were not checking for assignment- |
246 |
// to-self. Fixed. Thanks to Baptiste Lepilleur. |
// to-self. Fixed. Thanks to Baptiste Lepilleur. |
247 |
// |
// |
248 |
// 1999-AUG-20 - Improved Load() function to be more efficient by using |
// 1999-AUG-20 - Improved Load() function to be more efficient by using |
249 |
// SizeOfResource(). Thanks to Rich Zuris for this. |
// SizeOfResource(). Thanks to Rich Zuris for this. |
250 |
// - Corrected resource ID constructor, again thanks to Rich. |
// - Corrected resource ID constructor, again thanks to Rich. |
251 |
// - Fixed a bug that occurred with UNICODE characters above |
// - Fixed a bug that occurred with UNICODE characters above |
252 |
// the first 255 ANSI ones. Thanks to Craig Watson. |
// the first 255 ANSI ones. Thanks to Craig Watson. |
253 |
// - Added missing overloads of TrimLeft() and TrimRight(). |
// - Added missing overloads of TrimLeft() and TrimRight(). |
254 |
// Thanks to Karim Ratib for pointing them out |
// Thanks to Karim Ratib for pointing them out |
255 |
// |
// |
274 |
// - Changed operators << and >> (for MFC CArchive) to serialize |
// - Changed operators << and >> (for MFC CArchive) to serialize |
275 |
// EXACTLY as CString's do. So now you can send a CString out |
// EXACTLY as CString's do. So now you can send a CString out |
276 |
// to a CArchive and later read it in as a CStdString. I have |
// to a CArchive and later read it in as a CStdString. I have |
277 |
// no idea why you would want to do this but you can. |
// no idea why you would want to do this but you can. |
278 |
// |
// |
279 |
// 1999-JUN-21 - Changed the CStdString class into the CStdStr template. |
// 1999-JUN-21 - Changed the CStdString class into the CStdStr template. |
280 |
// - Fixed FormatV() to correctly decrement the loop counter. |
// - Fixed FormatV() to correctly decrement the loop counter. |
284 |
// using to _alloca(). |
// using to _alloca(). |
285 |
// - Updated the text conversion macros to properly use code |
// - Updated the text conversion macros to properly use code |
286 |
// pages and to fit in better in MFC/ATL builds. In other |
// pages and to fit in better in MFC/ATL builds. In other |
287 |
// words, I copied Microsoft's conversion stuff again. |
// words, I copied Microsoft's conversion stuff again. |
288 |
// - Added equivalents of CString::GetBuffer, GetBufferSetLength |
// - Added equivalents of CString::GetBuffer, GetBufferSetLength |
289 |
// - new sscpy() replacement of CStdString::CopyString() |
// - new sscpy() replacement of CStdString::CopyString() |
290 |
// - a Trim() function that combines TrimRight() and TrimLeft(). |
// - a Trim() function that combines TrimRight() and TrimLeft(). |
298 |
// 1999-FEB-03 - Fixed a bug in a rarely-used overload of operator+() that |
// 1999-FEB-03 - Fixed a bug in a rarely-used overload of operator+() that |
299 |
// caused infinite recursion and stack overflow |
// caused infinite recursion and stack overflow |
300 |
// - Added member functions to simplify the process of |
// - Added member functions to simplify the process of |
301 |
// persisting CStdStrings to/from DCOM IStream interfaces |
// persisting CStdStrings to/from DCOM IStream interfaces |
302 |
// - Added functional objects (e.g. StdStringLessNoCase) that |
// - Added functional objects (e.g. StdStringLessNoCase) that |
303 |
// allow CStdStrings to be used as keys STL map objects with |
// allow CStdStrings to be used as keys STL map objects with |
304 |
// case-insensitive comparison |
// case-insensitive comparison |
305 |
// - Added array indexing operators (i.e. operator[]). I |
// - Added array indexing operators (i.e. operator[]). I |
306 |
// originally assumed that these were unnecessary and would be |
// originally assumed that these were unnecessary and would be |
307 |
// inherited from basic_string. However, without them, Visual |
// inherited from basic_string. However, without them, Visual |
308 |
// C++ complains about ambiguous overloads when you try to use |
// C++ complains about ambiguous overloads when you try to use |
309 |
// them. Thanks to Julian Selman to pointing this out. |
// them. Thanks to Julian Selman to pointing this out. |
310 |
// |
// |
311 |
// 1998-FEB-?? - Added overloads of assign() function to completely account |
// 1998-FEB-?? - Added overloads of assign() function to completely account |
312 |
// for Q172398 bug. Thanks to "Pete the Plumber" for this |
// for Q172398 bug. Thanks to "Pete the Plumber" for this |
316 |
// COPYRIGHT: |
// COPYRIGHT: |
317 |
// 2002 Joseph M. O'Leary. This code is 100% free. Use it anywhere you |
// 2002 Joseph M. O'Leary. This code is 100% free. Use it anywhere you |
318 |
// want. Rewrite it, restructure it, whatever. If you can write software |
// want. Rewrite it, restructure it, whatever. If you can write software |
319 |
// that makes money off of it, good for you. I kinda like capitalism. |
// that makes money off of it, good for you. I kinda like capitalism. |
320 |
// Please don't blame me if it causes your $30 billion dollar satellite |
// Please don't blame me if it causes your $30 billion dollar satellite |
321 |
// explode in orbit. If you redistribute it in any form, I'd appreciate it |
// explode in orbit. If you redistribute it in any form, I'd appreciate it |
322 |
// if you would leave this notice here. |
// if you would leave this notice here. |
411 |
// out of the MFC world and you don't want to rewrite all your calls to |
// out of the MFC world and you don't want to rewrite all your calls to |
412 |
// Format(), then you can define this flag and it will no longer crash. |
// Format(), then you can define this flag and it will no longer crash. |
413 |
// |
// |
414 |
// Note however that this ONLY works for Format(), not sprintf, fprintf, |
// Note however that this ONLY works for Format(), not sprintf, fprintf, |
415 |
// etc. If you pass a CStdString object to one of those functions, your |
// etc. If you pass a CStdString object to one of those functions, your |
416 |
// program will crash. Not much I can do to get around this, short of |
// program will crash. Not much I can do to get around this, short of |
417 |
// writing substitutes for those functions as well. |
// writing substitutes for those functions as well. |
461 |
// standard library functions to do it's work. It will NOT attempt to use |
// standard library functions to do it's work. It will NOT attempt to use |
462 |
// any Win32 of Visual C++ specific functions -- even if they are |
// any Win32 of Visual C++ specific functions -- even if they are |
463 |
// available. You may define this flag yourself to prevent any Win32 |
// available. You may define this flag yourself to prevent any Win32 |
464 |
// of VC++ specific functions from being called. |
// of VC++ specific functions from being called. |
465 |
|
|
466 |
// If we're not on Win32, we MUST use an ANSI build |
// If we're not on Win32, we MUST use an ANSI build |
467 |
|
|
508 |
|
|
509 |
// Compiler Error regarding _UNICODE and UNICODE |
// Compiler Error regarding _UNICODE and UNICODE |
510 |
// ----------------------------------------------- |
// ----------------------------------------------- |
511 |
// Microsoft header files are screwy. Sometimes they depend on a preprocessor |
// Microsoft header files are screwy. Sometimes they depend on a preprocessor |
512 |
// flag named "_UNICODE". Other times they check "UNICODE" (note the lack of |
// flag named "_UNICODE". Other times they check "UNICODE" (note the lack of |
513 |
// leading underscore in the second version". In several places, they silently |
// leading underscore in the second version". In several places, they silently |
514 |
// "synchronize" these two flags this by defining one of the other was defined. |
// "synchronize" these two flags this by defining one of the other was defined. |
515 |
// In older version of this header, I used to try to do the same thing. |
// In older version of this header, I used to try to do the same thing. |
516 |
// |
// |
517 |
// However experience has taught me that this is a bad idea. You get weird |
// However experience has taught me that this is a bad idea. You get weird |
518 |
// compiler errors that seem to indicate things like LPWSTR and LPTSTR not being |
// compiler errors that seem to indicate things like LPWSTR and LPTSTR not being |
535 |
#ifdef _MSC_VER |
#ifdef _MSC_VER |
536 |
#if defined (_UNICODE) && !defined (UNICODE) |
#if defined (_UNICODE) && !defined (UNICODE) |
537 |
#error UNICODE defined but not UNICODE |
#error UNICODE defined but not UNICODE |
538 |
// #define UNICODE // no longer silently fix this |
// #define UNICODE // no longer silently fix this |
539 |
#endif |
#endif |
540 |
#if defined (UNICODE) && !defined (_UNICODE) |
#if defined (UNICODE) && !defined (_UNICODE) |
541 |
#error Warning, UNICODE defined but not _UNICODE |
#error Warning, UNICODE defined but not _UNICODE |
542 |
// #define _UNICODE // no longer silently fix this |
// #define _UNICODE // no longer silently fix this |
543 |
#endif |
#endif |
544 |
#endif |
#endif |
545 |
|
|
546 |
|
|
547 |
// ----------------------------------------------------------------------------- |
// ----------------------------------------------------------------------------- |
548 |
// MIN and MAX. The Standard C++ template versions go by so many names (at |
// MIN and MAX. The Standard C++ template versions go by so many names (at |
549 |
// at least in the MS implementation) that you never know what's available |
// at least in the MS implementation) that you never know what's available |
550 |
// ----------------------------------------------------------------------------- |
// ----------------------------------------------------------------------------- |
551 |
template < class Type > |
template < class Type > |
552 |
inline const Type & SSMIN(const Type & arg1, const Type & arg2) |
inline const Type & SSMIN(const Type & arg1, const Type & arg2) |
553 |
{ |
{ |
554 |
return arg2 < arg1 ? arg2 : arg1; |
return arg2 < arg1 ? arg2 : arg1; |
555 |
} |
} |
556 |
template < class Type > |
template < class Type > |
557 |
inline const Type & SSMAX(const Type & arg1, const Type & arg2) |
inline const Type & SSMAX(const Type & arg1, const Type & arg2) |
558 |
{ |
{ |
559 |
return arg2 > arg1 ? arg2 : arg1; |
return arg2 > arg1 ? arg2 : arg1; |
560 |
} |
} |
564 |
|
|
565 |
#if !defined(W32BASE_H) |
#if !defined(W32BASE_H) |
566 |
|
|
567 |
// If they want us to use only standard C++ stuff (no Win32 stuff) |
// If they want us to use only standard C++ stuff (no Win32 stuff) |
568 |
|
|
569 |
#ifdef SS_ANSI |
#ifdef SS_ANSI |
570 |
|
|
571 |
// On Win32 we have TCHAR.H so just include it. This is NOT violating |
// On Win32 we have TCHAR.H so just include it. This is NOT violating |
572 |
// the spirit of SS_ANSI as we are not calling any Win32 functions here. |
// the spirit of SS_ANSI as we are not calling any Win32 functions here. |
573 |
|
|
574 |
#ifdef SS_WIN32 |
#ifdef SS_WIN32 |
575 |
|
|
579 |
#define STRICT |
#define STRICT |
580 |
#endif |
#endif |
581 |
|
|
582 |
// ... but on non-Win32 platforms, we must #define the types we need. |
// ... but on non-Win32 platforms, we must #define the types we need. |
583 |
|
|
584 |
#else |
#else |
585 |
|
|
597 |
#endif // #ifndef _WIN32 |
#endif // #ifndef _WIN32 |
598 |
|
|
599 |
|
|
600 |
// Make sure ASSERT and verify are defined using only ANSI stuff |
// Make sure ASSERT and verify are defined using only ANSI stuff |
601 |
|
|
602 |
#ifndef ASSERT |
#ifndef ASSERT |
603 |
#include <assert.h> |
#include <assert.h> |
619 |
#define STRICT |
#define STRICT |
620 |
#endif |
#endif |
621 |
|
|
622 |
// Make sure ASSERT and verify are defined |
// Make sure ASSERT and verify are defined |
623 |
|
|
624 |
#ifndef ASSERT |
#ifndef ASSERT |
625 |
#include <crtdbg.h> |
#include <crtdbg.h> |
727 |
|
|
728 |
#ifndef SS_USE_FACET |
#ifndef SS_USE_FACET |
729 |
|
|
730 |
// STLPort #defines a macro (__STL_NO_EXPLICIT_FUNCTION_TMPL_ARGS) for |
// STLPort #defines a macro (__STL_NO_EXPLICIT_FUNCTION_TMPL_ARGS) for |
731 |
// all MSVC builds, erroneously in my opinion. It causes problems for |
// all MSVC builds, erroneously in my opinion. It causes problems for |
732 |
// my SS_ANSI builds. In my code, I always comment out that line. You'll |
// my SS_ANSI builds. In my code, I always comment out that line. You'll |
733 |
// find it in \stlport\config\stl_msvc.h |
// find it in \stlport\config\stl_msvc.h |
734 |
|
|
735 |
#if defined(__SGI_STL_PORT) && (__SGI_STL_PORT >= 0x400 ) |
#if defined(__SGI_STL_PORT) && (__SGI_STL_PORT >= 0x400 ) |
736 |
|
|
745 |
|
|
746 |
#define SS_USE_FACET(loc, fac) std::_USE(loc, fac) |
#define SS_USE_FACET(loc, fac) std::_USE(loc, fac) |
747 |
|
|
748 |
// ...and |
// ...and |
749 |
#elif defined(_RWSTD_NO_TEMPLATE_ON_RETURN_TYPE) |
#elif defined(_RWSTD_NO_TEMPLATE_ON_RETURN_TYPE) |
750 |
|
|
751 |
#define SS_USE_FACET(loc, fac) std::use_facet(loc, (fac*)0) |
#define SS_USE_FACET(loc, fac) std::use_facet(loc, (fac*)0) |
765 |
#include <wchar.h> // Added to Std Library with Amendment #1. |
#include <wchar.h> // Added to Std Library with Amendment #1. |
766 |
|
|
767 |
// First define the conversion helper functions. We define these regardless of |
// First define the conversion helper functions. We define these regardless of |
768 |
// any preprocessor macro settings since their names won't collide. |
// any preprocessor macro settings since their names won't collide. |
769 |
|
|
770 |
// Not sure if we need all these headers. I believe ANSI says we do. |
// Not sure if we need all these headers. I believe ANSI says we do. |
771 |
|
|
803 |
SSCodeCvt::result res = SSCodeCvt::ok; |
SSCodeCvt::result res = SSCodeCvt::ok; |
804 |
const SSCodeCvt & conv = SS_USE_FACET(loc, SSCodeCvt); |
const SSCodeCvt & conv = SS_USE_FACET(loc, SSCodeCvt); |
805 |
SSCodeCvt::state_type st = { |
SSCodeCvt::state_type st = { |
806 |
0}; |
0}; |
807 |
res = conv.in(st, |
res = conv.in(st, |
808 |
pSrcA, pSrcA + nSrc, pNextSrcA, |
pSrcA, pSrcA + nSrc, pNextSrcA, |
809 |
pDstW, pDstW + nDst, pNextDstW); |
pDstW, pDstW + nDst, pNextDstW); |
842 |
SSCodeCvt::result res = SSCodeCvt::ok; |
SSCodeCvt::result res = SSCodeCvt::ok; |
843 |
const SSCodeCvt & conv = SS_USE_FACET(loc, SSCodeCvt); |
const SSCodeCvt & conv = SS_USE_FACET(loc, SSCodeCvt); |
844 |
SSCodeCvt::state_type st = { |
SSCodeCvt::state_type st = { |
845 |
0}; |
0}; |
846 |
res = conv.out(st, |
res = conv.out(st, |
847 |
pSrcW, pSrcW + nSrc, pNextSrcW, |
pSrcW, pSrcW + nSrc, pNextSrcW, |
848 |
pDstA, pDstA + nDst, pNextDstA); |
pDstA, pDstA + nDst, pNextDstA); |
869 |
|
|
870 |
/* |
/* |
871 |
#else // ...or are we doing things assuming win32 and Visual C++? |
#else // ...or are we doing things assuming win32 and Visual C++? |
872 |
|
|
873 |
inline PWSTR StdCodeCvt(PWSTR pDstW, int nDst, PCSTR pSrcA, int nSrc, UINT acp=CP_ACP) |
inline PWSTR StdCodeCvt(PWSTR pDstW, int nDst, PCSTR pSrcA, int nSrc, UINT acp=CP_ACP) |
874 |
{ |
{ |
875 |
ASSERT(0 != pSrcA); |
ASSERT(0 != pSrcA); |
882 |
{ |
{ |
883 |
return StdCodeCvt(pDstW, nDst, (PCSTR)pSrcA, nSrc, acp); |
return StdCodeCvt(pDstW, nDst, (PCSTR)pSrcA, nSrc, acp); |
884 |
} |
} |
885 |
|
|
886 |
inline PSTR StdCodeCvt(PSTR pDstA, nDst PCWSTR pSrcW, int nSrc, UINT acp=CP_ACP) |
inline PSTR StdCodeCvt(PSTR pDstA, nDst PCWSTR pSrcW, int nSrc, UINT acp=CP_ACP) |
887 |
{ |
{ |
888 |
ASSERT(0 != pDstA); |
ASSERT(0 != pDstA); |
895 |
{ |
{ |
896 |
return (PUSTR)StdCodeCvt((PSTR)pDstA, nDst, pSrcW, nSrc, acp); |
return (PUSTR)StdCodeCvt((PSTR)pDstA, nDst, pSrcW, nSrc, acp); |
897 |
} |
} |
898 |
|
|
899 |
#endif |
#endif |
900 |
*/ |
*/ |
901 |
|
|
902 |
// Unicode/MBCS conversion macros are only available on implementations of |
// Unicode/MBCS conversion macros are only available on implementations of |
903 |
// the "C" library that have the non-standard _alloca function. As far as I |
// the "C" library that have the non-standard _alloca function. As far as I |
904 |
// know that's only Microsoft's though I've heard that the function exists |
// know that's only Microsoft's though I've heard that the function exists |
905 |
// elsewhere. |
// elsewhere. |
906 |
|
|
907 |
#if defined(SS_ALLOCA) && !defined SS_NO_CONVERSION |
#if defined(SS_ALLOCA) && !defined SS_NO_CONVERSION |
908 |
|
|
909 |
#include <malloc.h> // needed for _alloca |
#include <malloc.h> // needed for _alloca |
910 |
|
|
911 |
// Define our conversion macros to look exactly like Microsoft's to |
// Define our conversion macros to look exactly like Microsoft's to |
912 |
// facilitate using this stuff both with and without MFC/ATL |
// facilitate using this stuff both with and without MFC/ATL |
913 |
|
|
914 |
#ifdef _CONVERSION_USES_THREAD_LOCALE |
#ifdef _CONVERSION_USES_THREAD_LOCALE |
915 |
|
|
959 |
#define SSA2T SSA2W |
#define SSA2T SSA2W |
960 |
#define SST2CA SSW2CA |
#define SST2CA SSW2CA |
961 |
#define SSA2CT SSA2CW |
#define SSA2CT SSA2CW |
962 |
// (Did you get a compiler error here about not being able to convert |
// (Did you get a compiler error here about not being able to convert |
963 |
// PTSTR into PWSTR? Then your _UNICODE and UNICODE flags are messed |
// PTSTR into PWSTR? Then your _UNICODE and UNICODE flags are messed |
964 |
// up. Best bet: #define BOTH macros before including any MS headers.) |
// up. Best bet: #define BOTH macros before including any MS headers.) |
965 |
inline PWSTR SST2W(PTSTR p) |
inline PWSTR SST2W(PTSTR p) |
966 |
{ |
{ |
967 |
return p; |
return p; |
1002 |
#endif // #ifdef UNICODE |
#endif // #ifdef UNICODE |
1003 |
|
|
1004 |
#if defined(UNICODE) |
#if defined(UNICODE) |
1005 |
// in these cases the default (TCHAR) is the same as OLECHAR |
// in these cases the default (TCHAR) is the same as OLECHAR |
1006 |
inline PCOLESTR SST2COLE(PCTSTR p) |
inline PCOLESTR SST2COLE(PCTSTR p) |
1007 |
{ |
{ |
1008 |
return p; |
return p; |
1020 |
return p; |
return p; |
1021 |
} |
} |
1022 |
#elif defined(OLE2ANSI) |
#elif defined(OLE2ANSI) |
1023 |
// in these cases the default (TCHAR) is the same as OLECHAR |
// in these cases the default (TCHAR) is the same as OLECHAR |
1024 |
inline PCOLESTR SST2COLE(PCTSTR p) |
inline PCOLESTR SST2COLE(PCTSTR p) |
1025 |
{ |
{ |
1026 |
return p; |
return p; |
1038 |
return p; |
return p; |
1039 |
} |
} |
1040 |
#else |
#else |
1041 |
//CharNextW doesn't work on Win95 so we use this |
//CharNextW doesn't work on Win95 so we use this |
1042 |
#define SST2COLE(pa) SSA2CW((pa)) |
#define SST2COLE(pa) SSA2CW((pa)) |
1043 |
#define SST2OLE(pa) SSA2W((pa)) |
#define SST2OLE(pa) SSA2W((pa)) |
1044 |
#define SSOLE2CT(po) SSW2CA((po)) |
#define SSOLE2CT(po) SSW2CA((po)) |
1089 |
} |
} |
1090 |
#endif |
#endif |
1091 |
|
|
1092 |
// Above we've defined macros that look like MS' but all have |
// Above we've defined macros that look like MS' but all have |
1093 |
// an 'SS' prefix. Now we need the real macros. We'll either |
// an 'SS' prefix. Now we need the real macros. We'll either |
1094 |
// get them from the macros above or from MFC/ATL. |
// get them from the macros above or from MFC/ATL. |
1095 |
|
|
1096 |
#if defined (USES_CONVERSION) |
#if defined (USES_CONVERSION) |
1097 |
|
|
1151 |
if (nChars > 0) { |
if (nChars > 0) { |
1152 |
pDst[0] = '\0'; |
pDst[0] = '\0'; |
1153 |
std::basic_string < char >::traits_type::copy(pDst, pSrc, nChars); |
std::basic_string < char >::traits_type::copy(pDst, pSrc, nChars); |
1154 |
// std::char_traits<char>::copy(pDst, pSrc, nChars); |
// std::char_traits<char>::copy(pDst, pSrc, nChars); |
1155 |
pDst[nChars] = '\0'; |
pDst[nChars] = '\0'; |
1156 |
} |
} |
1157 |
|
|
1173 |
if (nChars > 0) { |
if (nChars > 0) { |
1174 |
pDst[0] = '\0'; |
pDst[0] = '\0'; |
1175 |
std::basic_string < wchar_t >::traits_type::copy(pDst, pSrc, nChars); |
std::basic_string < wchar_t >::traits_type::copy(pDst, pSrc, nChars); |
1176 |
// std::char_traits<wchar_t>::copy(pDst, pSrc, nChars); |
// std::char_traits<wchar_t>::copy(pDst, pSrc, nChars); |
1177 |
pDst[nChars] = '\0'; |
pDst[nChars] = '\0'; |
1178 |
} |
} |
1179 |
|
|
1210 |
// Therefore, to keep the CStdStr declaration simple, we have these inline |
// Therefore, to keep the CStdStr declaration simple, we have these inline |
1211 |
// functions. The template calls them often. Since they are inline (and NOT |
// functions. The template calls them often. Since they are inline (and NOT |
1212 |
// exported when this is built as a DLL), they will probably be resolved away |
// exported when this is built as a DLL), they will probably be resolved away |
1213 |
// to nothing. |
// to nothing. |
1214 |
// |
// |
1215 |
// Without these functions, the CStdStr<> template would probably have to broken |
// Without these functions, the CStdStr<> template would probably have to broken |
1216 |
// out into two, almost identical classes. Either that or it would be a huge, |
// out into two, almost identical classes. Either that or it would be a huge, |
1217 |
// convoluted mess, with tons of "if" statements all over the place checking the |
// convoluted mess, with tons of "if" statements all over the place checking the |
1218 |
// size of template parameter CT. |
// size of template parameter CT. |
1219 |
// |
// |
1220 |
// In several cases, you will see two versions of each function. One version is |
// In several cases, you will see two versions of each function. One version is |
1221 |
// the more portable, standard way of doing things, while the other is the |
// the more portable, standard way of doing things, while the other is the |
1222 |
// non-standard, but often significantly faster Visual C++ way. |
// non-standard, but often significantly faster Visual C++ way. |
1233 |
// ----------------------------------------------------------------------------- |
// ----------------------------------------------------------------------------- |
1234 |
// sslen: strlen/wcslen wrappers |
// sslen: strlen/wcslen wrappers |
1235 |
// ----------------------------------------------------------------------------- |
// ----------------------------------------------------------------------------- |
1236 |
template < typename CT > inline int sslen(const CT * pT) |
template < typename CT > |
1237 |
|
inline int sslen(const CT * pT) |
1238 |
{ |
{ |
1239 |
return 0 == pT ? 0 : (int) std::basic_string < |
return 0 == pT ? 0 : (int) std::basic_string < |
1240 |
CT >::traits_type::length(pT); |
CT >::traits_type::length(pT); |
1241 |
// return 0 == pT ? 0 : std::char_traits<CT>::length(pT); |
// return 0 == pT ? 0 : std::char_traits<CT>::length(pT); |
1242 |
} |
} |
1243 |
inline SS_NOTHROW int sslen(const std::string & s) |
inline SS_NOTHROW int sslen(const std::string & s) |
1244 |
{ |
{ |
1253 |
// sstolower/sstoupper -- convert characters to upper/lower case |
// sstolower/sstoupper -- convert characters to upper/lower case |
1254 |
// ----------------------------------------------------------------------------- |
// ----------------------------------------------------------------------------- |
1255 |
template < typename CT > |
template < typename CT > |
1256 |
inline CT sstolower(const CT & t, const std::locale & loc = std::locale()) |
inline CT sstolower(const CT & t, const std::locale & loc = std::locale()) |
1257 |
{ |
{ |
1258 |
return std::tolower < CT > (t, loc); |
return std::tolower < CT > (t, loc); |
1259 |
} |
} |
1260 |
|
|
1261 |
template < typename CT > |
template < typename CT > |
1262 |
inline CT sstoupper(const CT & t, const std::locale & loc = std::locale()) |
inline CT sstoupper(const CT & t, const std::locale & loc = std::locale()) |
1263 |
{ |
{ |
1264 |
return std::toupper < CT > (t, loc); |
return std::toupper < CT > (t, loc); |
1265 |
} |
} |
1306 |
{ |
{ |
1307 |
if (sSrc.empty()) { |
if (sSrc.empty()) { |
1308 |
sDst.erase(); |
sDst.erase(); |
1309 |
} |
} else { |
|
else { |
|
1310 |
int nDst = static_cast < int >(sSrc.size()); |
int nDst = static_cast < int >(sSrc.size()); |
1311 |
|
|
1312 |
// In MBCS builds, pad the buffer to account for the possibility of |
// In MBCS builds, pad the buffer to account for the possibility of |
1313 |
// some 3 byte characters. Not perfect but should get most cases. |
// some 3 byte characters. Not perfect but should get most cases. |
1314 |
|
|
1315 |
#ifdef SS_MBCS |
#ifdef SS_MBCS |
1316 |
|
|
1317 |
nDst = static_cast < int >(static_cast < double >(nDst) * 1.3); |
nDst = static_cast < int >(static_cast < double >(nDst) * 1.3); |
1318 |
#endif |
#endif |
1319 |
|
|
1325 |
// In MBCS builds, we don't know how long the destination string will be. |
// In MBCS builds, we don't know how long the destination string will be. |
1326 |
|
|
1327 |
#ifdef SS_MBCS |
#ifdef SS_MBCS |
1328 |
|
|
1329 |
sDst.resize(sslen(szCvt)); |
sDst.resize(sslen(szCvt)); |
1330 |
#else |
#else |
1331 |
|
|
1332 |
szCvt; |
szCvt; |
1333 |
sDst.resize(sSrc.size()); |
sDst.resize(sSrc.size()); |
1334 |
#endif |
#endif |
1335 |
|
|
1336 |
} |
} |
1337 |
} |
} |
1338 |
inline void ssasn(std::string & sDst, PCWSTR pW) |
inline void ssasn(std::string & sDst, PCWSTR pW) |
1346 |
// some 3 byte characters. Not perfect but should get most cases. |
// some 3 byte characters. Not perfect but should get most cases. |
1347 |
|
|
1348 |
#ifdef SS_MBCS |
#ifdef SS_MBCS |
1349 |
|
|
1350 |
nDst = static_cast < int >(static_cast < double >(nDst) * 1.3); |
nDst = static_cast < int >(static_cast < double >(nDst) * 1.3); |
1351 |
#endif |
#endif |
1352 |
|
|
1358 |
// In MBCS builds, we don't know how long the destination string will be. |
// In MBCS builds, we don't know how long the destination string will be. |
1359 |
|
|
1360 |
#ifdef SS_MBCS |
#ifdef SS_MBCS |
1361 |
|
|
1362 |
sDst.resize(sslen(szCvt)); |
sDst.resize(sslen(szCvt)); |
1363 |
#else |
#else |
1364 |
|
|
1365 |
sDst.resize(nDst); |
sDst.resize(nDst); |
1366 |
szCvt; |
szCvt; |
1367 |
#endif |
#endif |
1368 |
} |
|
1369 |
else { |
} else { |
1370 |
sDst.erase(); |
sDst.erase(); |
1371 |
} |
} |
1372 |
} |
} |
1412 |
{ |
{ |
1413 |
if (sSrc.empty()) { |
if (sSrc.empty()) { |
1414 |
sDst.erase(); |
sDst.erase(); |
1415 |
} |
} else { |
|
else { |
|
1416 |
int nSrc = static_cast < int >(sSrc.size()); |
int nSrc = static_cast < int >(sSrc.size()); |
1417 |
int nDst = nSrc; |
int nDst = nSrc; |
1418 |
|
|
1430 |
|
|
1431 |
if (0 == nSrc) { |
if (0 == nSrc) { |
1432 |
sDst.erase(); |
sDst.erase(); |
1433 |
} |
} else { |
|
else { |
|
1434 |
int nDst = nSrc; |
int nDst = nSrc; |
1435 |
sDst.resize(nDst + 1); |
sDst.resize(nDst + 1); |
1436 |
PCWSTR szCvt = |
PCWSTR szCvt = |
1463 |
// some 3 byte characters. Not perfect but should get most cases. |
// some 3 byte characters. Not perfect but should get most cases. |
1464 |
|
|
1465 |
#ifdef SS_MBCS |
#ifdef SS_MBCS |
1466 |
|
|
1467 |
nAdd = static_cast < int >(static_cast < double >(nAdd) * 1.3); |
nAdd = static_cast < int >(static_cast < double >(nAdd) * 1.3); |
1468 |
#endif |
#endif |
1469 |
|
|
1473 |
nAdd, sSrc.c_str(), nSrc); |
nAdd, sSrc.c_str(), nSrc); |
1474 |
|
|
1475 |
#ifdef SS_MBCS |
#ifdef SS_MBCS |
1476 |
|
|
1477 |
sDst.resize(nDst + sslen(szCvt)); |
sDst.resize(nDst + sslen(szCvt)); |
1478 |
#else |
#else |
1479 |
|
|
1480 |
sDst.resize(nDst + nAdd); |
sDst.resize(nDst + nAdd); |
1481 |
szCvt; |
szCvt; |
1482 |
#endif |
#endif |
1483 |
|
|
1484 |
} |
} |
1485 |
} |
} |
1486 |
inline void ssadd(std::string & sDst, const std::string & sSrc) |
inline void ssadd(std::string & sDst, const std::string & sSrc) |
1495 |
int nAdd = nSrc; |
int nAdd = nSrc; |
1496 |
|
|
1497 |
#ifdef SS_MBCS |
#ifdef SS_MBCS |
1498 |
|
|
1499 |
nAdd = static_cast < int >(static_cast < double >(nAdd) * 1.3); |
nAdd = static_cast < int >(static_cast < double >(nAdd) * 1.3); |
1500 |
#endif |
#endif |
1501 |
|
|
1505 |
nAdd, pW, nSrc); |
nAdd, pW, nSrc); |
1506 |
|
|
1507 |
#ifdef SS_MBCS |
#ifdef SS_MBCS |
1508 |
|
|
1509 |
sDst.resize(nDst + sslen(szCvt)); |
sDst.resize(nDst + sslen(szCvt)); |
1510 |
#else |
#else |
1511 |
|
|
1512 |
sDst.resize(nDst + nSrc); |
sDst.resize(nDst + nSrc); |
1513 |
szCvt; |
szCvt; |
1514 |
#endif |
#endif |
1515 |
|
|
1516 |
} |
} |
1517 |
} |
} |
1518 |
inline void ssadd(std::string & sDst, PCSTR pA) |
inline void ssadd(std::string & sDst, PCSTR pA) |
1528 |
sDst.append(std::string(pA)); |
sDst.append(std::string(pA)); |
1529 |
else |
else |
1530 |
sDst.append(pA); |
sDst.append(pA); |
1531 |
} |
} else { |
|
else { |
|
1532 |
sDst.append(pA); |
sDst.append(pA); |
1533 |
} |
} |
1534 |
} |
} |
1549 |
nSrc, sSrc.c_str(), nSrc + 1); |
nSrc, sSrc.c_str(), nSrc + 1); |
1550 |
|
|
1551 |
#ifdef SS_MBCS |
#ifdef SS_MBCS |
1552 |
|
|
1553 |
sDst.resize(nDst + sslen(szCvt)); |
sDst.resize(nDst + sslen(szCvt)); |
1554 |
#else |
#else |
1555 |
|
|
1556 |
sDst.resize(nDst + nSrc); |
sDst.resize(nDst + nSrc); |
1557 |
szCvt; |
szCvt; |
1558 |
#endif |
#endif |
1559 |
|
|
1560 |
} |
} |
1561 |
} |
} |
1562 |
inline void ssadd(std::wstring & sDst, PCSTR pA) |
inline void ssadd(std::wstring & sDst, PCSTR pA) |
1572 |
nSrc, pA, nSrc + 1); |
nSrc, pA, nSrc + 1); |
1573 |
|
|
1574 |
#ifdef SS_MBCS |
#ifdef SS_MBCS |
1575 |
|
|
1576 |
sDst.resize(nDst + sslen(szCvt)); |
sDst.resize(nDst + sslen(szCvt)); |
1577 |
#else |
#else |
1578 |
|
|
1579 |
sDst.resize(nDst + nSrc); |
sDst.resize(nDst + nSrc); |
1580 |
szCvt; |
szCvt; |
1581 |
#endif |
#endif |
1582 |
|
|
1583 |
} |
} |
1584 |
} |
} |
1585 |
inline void ssadd(std::wstring & sDst, PCWSTR pW) |
inline void ssadd(std::wstring & sDst, PCWSTR pW) |
1595 |
sDst.append(std::wstring(pW)); |
sDst.append(std::wstring(pW)); |
1596 |
else |
else |
1597 |
sDst.append(pW); |
sDst.append(pW); |
1598 |
} |
} else { |
|
else { |
|
1599 |
sDst.append(pW); |
sDst.append(pW); |
1600 |
} |
} |
1601 |
} |
} |
1605 |
// ----------------------------------------------------------------------------- |
// ----------------------------------------------------------------------------- |
1606 |
// sscmp: comparison (case sensitive, not affected by locale) |
// sscmp: comparison (case sensitive, not affected by locale) |
1607 |
// ----------------------------------------------------------------------------- |
// ----------------------------------------------------------------------------- |
1608 |
template < typename CT > inline int sscmp(const CT * pA1, const CT * pA2) |
template < typename CT > |
1609 |
|
inline int sscmp(const CT * pA1, const CT * pA2) |
1610 |
{ |
{ |
1611 |
CT f; |
CT f; |
1612 |
CT l; |
CT l; |
1622 |
// ----------------------------------------------------------------------------- |
// ----------------------------------------------------------------------------- |
1623 |
// ssicmp: comparison (case INsensitive, not affected by locale) |
// ssicmp: comparison (case INsensitive, not affected by locale) |
1624 |
// ----------------------------------------------------------------------------- |
// ----------------------------------------------------------------------------- |
1625 |
template < typename CT > inline int ssicmp(const CT * pA1, const CT * pA2) |
template < typename CT > |
1626 |
|
inline int ssicmp(const CT * pA1, const CT * pA2) |
1627 |
{ |
{ |
1628 |
// Using the "C" locale = "not affected by locale" |
// Using the "C" locale = "not affected by locale" |
1629 |
|
|
1645 |
// ----------------------------------------------------------------------------- |
// ----------------------------------------------------------------------------- |
1646 |
|
|
1647 |
template < typename CT > |
template < typename CT > |
1648 |
inline void sslwr(CT * pT, size_t nLen, const std::locale & loc = |
inline void sslwr(CT * pT, size_t nLen, const std::locale & loc = |
1649 |
std::locale()) |
std::locale()) |
1650 |
{ |
{ |
1651 |
SS_USE_FACET(loc, std::ctype < CT >).tolower(pT, pT + nLen); |
SS_USE_FACET(loc, std::ctype < CT >).tolower(pT, pT + nLen); |
1652 |
} |
} |
1653 |
template < typename CT > |
template < typename CT > |
1654 |
inline void ssupr(CT * pT, size_t nLen, const std::locale & loc = |
inline void ssupr(CT * pT, size_t nLen, const std::locale & loc = |
1655 |
std::locale()) |
std::locale()) |
1656 |
{ |
{ |
1657 |
SS_USE_FACET(loc, std::ctype < CT >).toupper(pT, pT + nLen); |
SS_USE_FACET(loc, std::ctype < CT >).toupper(pT, pT + nLen); |
1662 |
// builds we can't use _vsnprintf/_vsnwsprintf because they're MS extensions. |
// builds we can't use _vsnprintf/_vsnwsprintf because they're MS extensions. |
1663 |
// |
// |
1664 |
// ----------------------------------------------------------------------------- |
// ----------------------------------------------------------------------------- |
1665 |
// Borland's headers put some ANSI "C" functions in the 'std' namespace. |
// Borland's headers put some ANSI "C" functions in the 'std' namespace. |
1666 |
// Promote them to the global namespace so we can use them here. |
// Promote them to the global namespace so we can use them here. |
1667 |
|
|
1668 |
#if defined(__BORLANDC__) |
#if defined(__BORLANDC__) |
1670 |
using std::vswprintf; |
using std::vswprintf; |
1671 |
#endif |
#endif |
1672 |
|
|
1673 |
// GNU is supposed to have vsnprintf and vsnwprintf. But only the newer |
// GNU is supposed to have vsnprintf and vsnwprintf. But only the newer |
1674 |
// distributions do. |
// distributions do. |
1675 |
|
|
1676 |
#if defined(__GNUC__) |
#if defined(__GNUC__) |
1677 |
|
|
1684 |
return vswprintf(pW, nCount, pFmtW, vl); |
return vswprintf(pW, nCount, pFmtW, vl); |
1685 |
} |
} |
1686 |
|
|
1687 |
// Microsofties can use |
// Microsofties can use |
1688 |
#elif defined(_MSC_VER) && !defined(SS_ANSI) |
#elif defined(_MSC_VER) && !defined(SS_ANSI) |
1689 |
|
|
1690 |
inline int ssnprintf(PSTR pA, size_t nCount, PCSTR pFmtA, va_list vl) |
inline int ssnprintf(PSTR pA, size_t nCount, PCSTR pFmtA, va_list vl) |
1698 |
|
|
1699 |
#elif !defined (SS_DANGEROUS_FORMAT) |
#elif !defined (SS_DANGEROUS_FORMAT) |
1700 |
|
|
1701 |
// GOT COMPILER PROBLEMS HERE? |
// GOT COMPILER PROBLEMS HERE? |
1702 |
// --------------------------- |
// --------------------------- |
1703 |
// Does your compiler choke on one or more of the following 2 functions? It |
// Does your compiler choke on one or more of the following 2 functions? It |
1704 |
// probably means that you don't have have either vsnprintf or vsnwprintf in |
// probably means that you don't have have either vsnprintf or vsnwprintf in |
1705 |
// your version of the CRT. This is understandable since neither is an ANSI |
// your version of the CRT. This is understandable since neither is an ANSI |
1706 |
// "C" function. However it still leaves you in a dilemma. In order to make |
// "C" function. However it still leaves you in a dilemma. In order to make |
1707 |
// this code build, you're going to have to to use some non-length-checked |
// this code build, you're going to have to to use some non-length-checked |
1708 |
// formatting functions that every CRT has: vsprintf and vswprintf. |
// formatting functions that every CRT has: vsprintf and vswprintf. |
1709 |
// |
// |
1710 |
// This is very dangerous. With the proper erroneous (or malicious) code, it |
// This is very dangerous. With the proper erroneous (or malicious) code, it |
1711 |
// can lead to buffer overlows and crashing your PC. Use at your own risk |
// can lead to buffer overlows and crashing your PC. Use at your own risk |
1712 |
// In order to use them, just #define SS_DANGEROUS_FORMAT at the top of |
// In order to use them, just #define SS_DANGEROUS_FORMAT at the top of |
1713 |
// this file. |
// this file. |
1714 |
// |
// |
1715 |
// Even THEN you might not be all the way home due to some non-conforming |
// Even THEN you might not be all the way home due to some non-conforming |
1716 |
// distributions. More on this in the comments below. |
// distributions. More on this in the comments below. |
1717 |
|
|
1718 |
inline int ssnprintf(PSTR pA, size_t nCount, PCSTR pFmtA, va_list vl) |
inline int ssnprintf(PSTR pA, size_t nCount, PCSTR pFmtA, va_list vl) |
1719 |
{ |
{ |
1734 |
inline int ssvsprintf(PWSTR pW, size_t nCount, PCWSTR pFmtW, va_list vl) |
inline int ssvsprintf(PWSTR pW, size_t nCount, PCWSTR pFmtW, va_list vl) |
1735 |
{ |
{ |
1736 |
// JMO: Some distributions of the "C" have a version of vswprintf that |
// JMO: Some distributions of the "C" have a version of vswprintf that |
1737 |
// takes 3 arguments (e.g. Microsoft, Borland, GNU). Others have a |
// takes 3 arguments (e.g. Microsoft, Borland, GNU). Others have a |
1738 |
// version which takes 4 arguments (an extra "count" argument in the |
// version which takes 4 arguments (an extra "count" argument in the |
1739 |
// second position. The best stab I can take at this so far is that if |
// second position. The best stab I can take at this so far is that if |
1740 |
// you are NOT running with MS, Borland, or GNU, then I'll assume you |
// you are NOT running with MS, Borland, or GNU, then I'll assume you |
1750 |
// |
// |
1751 |
// Thanks to Ronny Schulz for the SGI-specific checks here. |
// Thanks to Ronny Schulz for the SGI-specific checks here. |
1752 |
|
|
1753 |
// #if !defined(__MWERKS__) && !defined(__SUNPRO_CC_COMPAT) && !defined(__SUNPRO_CC) |
// #if !defined(__MWERKS__) && !defined(__SUNPRO_CC_COMPAT) && !defined(__SUNPRO_CC) |
1754 |
#if !defined(_MSC_VER) \ |
#if !defined(_MSC_VER) \ |
1755 |
&& !defined (__BORLANDC__) \ |
&& !defined (__BORLANDC__) \ |
1756 |
&& !defined(__GNUC__) \ |
&& !defined(__GNUC__) \ |
1763 |
|
|
1764 |
#elif defined(__sgi) |
#elif defined(__sgi) |
1765 |
|
|
1766 |
nCount; |
nCount; |
1767 |
return vsprintf((char *) pW, (char *) pFmtW, vl); |
return vsprintf((char *) pW, (char *) pFmtW, vl); |
1768 |
|
|
1769 |
#else |
#else |
1770 |
|
|
1771 |
nCount; |
nCount; |
1772 |
return vswprintf(pW, pFmtW, vl); |
return vswprintf(pW, pFmtW, vl); |
1773 |
|
|
1774 |
#endif |
#endif |
1775 |
|
|
1802 |
// functions appear to return the opposite of what they should |
// functions appear to return the opposite of what they should |
1803 |
// ----------------------------------------------------------------------------- |
// ----------------------------------------------------------------------------- |
1804 |
template < typename CT > |
template < typename CT > |
1805 |
inline int sscoll(const CT * sz1, int nLen1, const CT * sz2, int nLen2) |
inline int sscoll(const CT * sz1, int nLen1, const CT * sz2, int nLen2) |
1806 |
{ |
{ |
1807 |
const std::collate < CT > &coll = |
const std::collate < CT > &coll = |
1808 |
SS_USE_FACET(std::locale(), std::collate < CT >); |
SS_USE_FACET(std::locale(), std::collate < CT >); |
1810 |
return coll.compare(sz2, sz2 + nLen2, sz1, sz1 + nLen1); |
return coll.compare(sz2, sz2 + nLen2, sz1, sz1 + nLen1); |
1811 |
} |
} |
1812 |
template < typename CT > |
template < typename CT > |
1813 |
inline int ssicoll(const CT * sz1, int nLen1, const CT * sz2, int nLen2) |
inline int ssicoll(const CT * sz1, int nLen1, const CT * sz2, int nLen2) |
1814 |
{ |
{ |
1815 |
const std::locale loc; |
const std::locale loc; |
1816 |
const std::collate < CT > &coll = SS_USE_FACET(loc, std::collate < CT >); |
const std::collate < CT > &coll = SS_USE_FACET(loc, std::collate < CT >); |
1819 |
// facet typedefs so we'll just default to basic_string and hope |
// facet typedefs so we'll just default to basic_string and hope |
1820 |
// that's what the collate facet uses (which it generally should) |
// that's what the collate facet uses (which it generally should) |
1821 |
|
|
1822 |
// std::collate<CT>::string_type s1(sz1); |
// std::collate<CT>::string_type s1(sz1); |
1823 |
// std::collate<CT>::string_type s2(sz2); |
// std::collate<CT>::string_type s2(sz2); |
1824 |
const std::basic_string < CT > sEmpty; |
const std::basic_string < CT > sEmpty; |
1825 |
std::basic_string < CT > s1(sz1 ? sz1 : sEmpty.c_str()); |
std::basic_string < CT > s1(sz1 ? sz1 : sEmpty.c_str()); |
1826 |
std::basic_string < CT > s2(sz2 ? sz2 : sEmpty.c_str()); |
std::basic_string < CT > s2(sz2 ? sz2 : sEmpty.c_str()); |
1881 |
// characters. The return value is the number of characters copied, |
// characters. The return value is the number of characters copied, |
1882 |
// not including the NULL terminator. |
// not including the NULL terminator. |
1883 |
// |
// |
1884 |
// PARAMETERS: |
// PARAMETERS: |
1885 |
// pSrc - the string to be copied FROM. May be a char based string, an |
// pSrc - the string to be copied FROM. May be a char based string, an |
1886 |
// MBCS string (in Win32 builds) or a wide string (wchar_t). |
// MBCS string (in Win32 builds) or a wide string (wchar_t). |
1887 |
// pSrc - the string to be copied TO. Also may be either MBCS or wide |
// pSrc - the string to be copied TO. Also may be either MBCS or wide |
1897 |
// RETURN VALUE: none |
// RETURN VALUE: none |
1898 |
// ----------------------------------------------------------------------------- |
// ----------------------------------------------------------------------------- |
1899 |
template < typename CT1, typename CT2 > |
template < typename CT1, typename CT2 > |
1900 |
inline int sscpycvt(CT1 * pDst, const CT2 * pSrc, int nMax) |
inline int sscpycvt(CT1 * pDst, const CT2 * pSrc, int nMax) |
1901 |
{ |
{ |
1902 |
// Note -- we assume pDst is big enough to hold pSrc. If not, we're in |
// Note -- we assume pDst is big enough to hold pSrc. If not, we're in |
1903 |
// big trouble. No bounds checking. Caveat emptor. |
// big trouble. No bounds checking. Caveat emptor. |
1943 |
} |
} |
1944 |
|
|
1945 |
template < typename CT1, typename CT2 > |
template < typename CT1, typename CT2 > |
1946 |
inline int sscpy(CT1 * pDst, const CT2 * pSrc, int nMax, int nLen) |
inline int sscpy(CT1 * pDst, const CT2 * pSrc, int nMax, int nLen) |
1947 |
{ |
{ |
1948 |
return sscpycvt(pDst, pSrc, SSMIN(nMax, nLen)); |
return sscpycvt(pDst, pSrc, SSMIN(nMax, nLen)); |
1949 |
} |
} |
1950 |
template < typename CT1, typename CT2 > |
template < typename CT1, typename CT2 > |
1951 |
inline int sscpy(CT1 * pDst, const CT2 * pSrc, int nMax) |
inline int sscpy(CT1 * pDst, const CT2 * pSrc, int nMax) |
1952 |
{ |
{ |
1953 |
return sscpycvt(pDst, pSrc, SSMIN(nMax, sslen(pSrc))); |
return sscpycvt(pDst, pSrc, SSMIN(nMax, sslen(pSrc))); |
1954 |
} |
} |
1955 |
template < typename CT1, typename CT2 > |
template < typename CT1, typename CT2 > |
1956 |
inline int sscpy(CT1 * pDst, const CT2 * pSrc) |
inline int sscpy(CT1 * pDst, const CT2 * pSrc) |
1957 |
{ |
{ |
1958 |
return sscpycvt(pDst, pSrc, sslen(pSrc)); |
return sscpycvt(pDst, pSrc, sslen(pSrc)); |
1959 |
} |
} |
1960 |
template < typename CT1, typename CT2 > |
template < typename CT1, typename CT2 > |
1961 |
inline int sscpy(CT1 * pDst, const std::basic_string < CT2 > &sSrc, |
inline int sscpy(CT1 * pDst, const std::basic_string < CT2 > &sSrc, |
1962 |
int nMax) |
int nMax) |
1963 |
{ |
{ |
1964 |
return sscpycvt(pDst, sSrc.c_str(), SSMIN(nMax, (int) sSrc.length())); |
return sscpycvt(pDst, sSrc.c_str(), SSMIN(nMax, (int) sSrc.length())); |
1965 |
} |
} |
1966 |
template < typename CT1, typename CT2 > |
template < typename CT1, typename CT2 > |
1967 |
inline int sscpy(CT1 * pDst, const std::basic_string < CT2 > &sSrc) |
inline int sscpy(CT1 * pDst, const std::basic_string < CT2 > &sSrc) |
1968 |
{ |
{ |
1969 |
return sscpycvt(pDst, sSrc.c_str(), (int) sSrc.length()); |
return sscpycvt(pDst, sSrc.c_str(), (int) sSrc.length()); |
1970 |
} |
} |
1971 |
|
|
1972 |
#ifdef SS_INC_COMDEF |
#ifdef SS_INC_COMDEF |
1973 |
template < typename CT1 > |
template < typename CT1 > |
1974 |
inline int sscpy(CT1 * pDst, const _bstr_t & bs, int nMax) |
inline int sscpy(CT1 * pDst, const _bstr_t & bs, int nMax) |
1975 |
{ |
{ |
1976 |
return sscpycvt(pDst, static_cast < PCOLESTR > (bs), |
return sscpycvt(pDst, static_cast < PCOLESTR > (bs), |
1977 |
SSMIN(nMax, static_cast < int >(bs.length()))); |
SSMIN(nMax, static_cast < int >(bs.length()))); |
1978 |
} |
} |
1979 |
template < typename CT1 > inline int sscpy(CT1 * pDst, const _bstr_t & bs) |
template < typename CT1 > |
1980 |
|
inline int sscpy(CT1 * pDst, const _bstr_t & bs) |
1981 |
{ |
{ |
1982 |
return sscpy(pDst, bs, static_cast < int >(bs.length())); |
return sscpy(pDst, bs, static_cast < int >(bs.length())); |
1983 |
} |
} |
1989 |
// ----------------------------------------------------------------------------- |
// ----------------------------------------------------------------------------- |
1990 |
|
|
1991 |
template < typename CT > |
template < typename CT > |
1992 |
struct SSToUpper:public std::binary_function < CT, std::locale, CT > |
struct SSToUpper:public std::binary_function < CT, std::locale, CT > |
1993 |
{ |
{ |
1994 |
inline CT operator() (const CT & t, const std::locale & loc) const |
inline CT operator() (const CT & t, const std::locale & loc) const |
1995 |
{ |
{ |
1997 |
} |
} |
1998 |
}; |
}; |
1999 |
template < typename CT > |
template < typename CT > |
2000 |
struct SSToLower:public std::binary_function < CT, std::locale, CT > |
struct SSToLower:public std::binary_function < CT, std::locale, CT > |
2001 |
{ |
{ |
2002 |
inline CT operator() (const CT & t, const std::locale & loc) const |
inline CT operator() (const CT & t, const std::locale & loc) const |
2003 |
{ |
{ |
2014 |
// inline bool operator() (CT t) { return !std::isspace(t, loc); } |
// inline bool operator() (CT t) { return !std::isspace(t, loc); } |
2015 |
//}; |
//}; |
2016 |
template < typename CT > |
template < typename CT > |
2017 |
struct NotSpace:public std::unary_function < CT, bool > |
struct NotSpace:public std::unary_function < CT, bool > |
2018 |
{ |
{ |
2019 |
// DINKUMWARE BUG: |
// DINKUMWARE BUG: |
2020 |
// Note -- using std::isspace in a COM DLL gives us access violations |
// Note -- using std::isspace in a COM DLL gives us access violations |
2029 |
// iswspace() from the CRT unless they specify SS_ANSI |
// iswspace() from the CRT unless they specify SS_ANSI |
2030 |
|
|
2031 |
const std::locale loc; |
const std::locale loc; |
2032 |
NotSpace(const std::locale & locArg = std::locale()):loc(locArg) { |
NotSpace(const std::locale & locArg = std::locale()):loc(locArg) |
2033 |
} |
{} |
2034 |
bool operator() (CT t) const |
bool operator() (CT t) const |
2035 |
{ |
{ |
2036 |
return !std::isspace(t, loc); |
return !std::isspace(t, loc); |
2053 |
// easy to use as the MFC CString class. |
// easy to use as the MFC CString class. |
2054 |
// |
// |
2055 |
// Note that although this is a template, it makes the assumption that the |
// Note that although this is a template, it makes the assumption that the |
2056 |
// template argument (CT, the character type) is either char or wchar_t. |
// template argument (CT, the character type) is either char or wchar_t. |
2057 |
// ============================================================================= |
// ============================================================================= |
2058 |
|
|
2059 |
//#define CStdStr _SS // avoid compiler warning 4786 |
//#define CStdStr _SS // avoid compiler warning 4786 |
2062 |
// PCSTR FmtArg(const std::string& arg) { return arg.c_str(); } |
// PCSTR FmtArg(const std::string& arg) { return arg.c_str(); } |
2063 |
// PCWSTR FmtArg(const std::wstring& arg) { return arg.c_str(); } |
// PCWSTR FmtArg(const std::wstring& arg) { return arg.c_str(); } |
2064 |
|
|
2065 |
template < typename ARG > struct FmtArg |
template < typename ARG > |
2066 |
|
struct FmtArg |
2067 |
{ |
{ |
2068 |
explicit FmtArg(const ARG & arg):a_(arg) |
explicit FmtArg(const ARG & arg):a_(arg) |
2069 |
{ |
{} |
|
} |
|
2070 |
const ARG & operator() () const |
const ARG & operator() () const |
2071 |
{ |
{ |
2072 |
return a_; |
return a_; |
2073 |
} |
} |
2074 |
const ARG & a_; |
const ARG & a_; |
2075 |
private: |
private: |
2076 |
FmtArg & operator=(const FmtArg &) |
FmtArg & operator=(const FmtArg &) |
2077 |
{ |
{ |
2078 |
return *this; |
return *this; |
2079 |
} |
} |
2080 |
}; |
}; |
2081 |
|
|
2082 |
template < typename CT > class CStdStr:public std::basic_string < CT > { |
template < typename CT > |
2083 |
// Typedefs for shorter names. Using these names also appears to help |
class CStdStr:public std::basic_string < CT > |
2084 |
// us avoid some ambiguities that otherwise arise on some platforms |
{ |
2085 |
|
// Typedefs for shorter names. Using these names also appears to help |
2086 |
|
// us avoid some ambiguities that otherwise arise on some platforms |
2087 |
|
|
2088 |
#define MYBASE std::basic_string<CT> // my base class |
#define MYBASE std::basic_string<CT> // my base class |
2089 |
//typedef typename std::basic_string<CT> MYBASE; // my base class |
//typedef typename std::basic_string<CT> MYBASE; // my base class |
2090 |
typedef CStdStr < CT > MYTYPE; // myself |
typedef CStdStr < CT > MYTYPE; // myself |
2091 |
typedef typename MYBASE::const_pointer PCMYSTR; // PCSTR or PCWSTR |
typedef typename MYBASE::const_pointer PCMYSTR; // PCSTR or PCWSTR |
2092 |
typedef typename MYBASE::pointer PMYSTR; // PSTR or PWSTR |
typedef typename MYBASE::pointer PMYSTR; // PSTR or PWSTR |
2093 |
typedef typename MYBASE::iterator MYITER; // my iterator type |
typedef typename MYBASE::iterator MYITER; // my iterator type |
2094 |
typedef typename MYBASE::const_iterator MYCITER; // you get the idea... |
typedef typename MYBASE::const_iterator MYCITER; // you get the idea... |
2095 |
typedef typename MYBASE::reverse_iterator MYRITER; |
typedef typename MYBASE::reverse_iterator MYRITER; |
2096 |
typedef typename MYBASE::size_type MYSIZE; |
typedef typename MYBASE::size_type MYSIZE; |
2097 |
typedef typename MYBASE::value_type MYVAL; |
typedef typename MYBASE::value_type MYVAL; |
2098 |
typedef typename MYBASE::allocator_type MYALLOC; |
typedef typename MYBASE::allocator_type MYALLOC; |
2099 |
|
|
2100 |
public: |
public: |
2101 |
// shorthand conversion from PCTSTR to string resource ID |
// shorthand conversion from PCTSTR to string resource ID |
2102 |
#define SSRES(pctstr) LOWORD(reinterpret_cast<unsigned long>(pctstr)) |
#define SSRES(pctstr) LOWORD(reinterpret_cast<unsigned long>(pctstr)) |
2103 |
|
|
2104 |
bool TryLoad(const void *pT) |
bool TryLoad(const void *pT) |
2105 |
{ |
{ |
2106 |
bool bLoaded = false; |
bool bLoaded = false; |
2107 |
|
|
2108 |
#if defined(SS_WIN32) && !defined(SS_ANSI) |
#if defined(SS_WIN32) && !defined(SS_ANSI) |
2109 |
if ((pT != NULL) && SS_IS_INTRESOURCE(pT)) { |
|
2110 |
UINT nId = LOWORD(reinterpret_cast < unsigned long >(pT)); |
if ((pT != NULL) && SS_IS_INTRESOURCE(pT)) { |
2111 |
if (!LoadString(nId)) { |
UINT nId = LOWORD(reinterpret_cast < unsigned long >(pT)); |
2112 |
TRACE(_T("Can't load string %u\n"), SSRES(pT)); |
if (!LoadString(nId)) { |
2113 |
|
TRACE(_T("Can't load string %u\n"), SSRES(pT)); |
2114 |
|
} |
2115 |
|
bLoaded = true; |
2116 |
} |
} |
|
bLoaded = true; |
|
|
} |
|
2117 |
#endif |
#endif |
2118 |
|
|
2119 |
return bLoaded; |
return bLoaded; |
2120 |
} |
} |
2121 |
|
|
2122 |
|
|
2123 |
// CStdStr inline constructors |
// CStdStr inline constructors |
2124 |
CStdStr() { |
CStdStr() |
2125 |
} |
{} |
2126 |
|
|
2127 |
CStdStr(const MYTYPE & str):MYBASE(SSREF(str)) { |
CStdStr(const MYTYPE & str):MYBASE(SSREF(str)) |
2128 |
} |
{} |
2129 |
|
|
2130 |
CStdStr(const std::string & str) |
CStdStr(const std::string & str) |
2131 |
{ |
{ |
2132 |
ssasn(*this, SSREF(str)); |
ssasn(*this, SSREF(str)); |
2133 |
} |
} |
2134 |
|
|
2135 |
CStdStr(const std::wstring & str) |
CStdStr(const std::wstring & str) |
2136 |
{ |
{ |
2137 |
ssasn(*this, SSREF(str)); |
ssasn(*this, SSREF(str)); |
2138 |
} |
} |
2139 |
|
|
2140 |
CStdStr(PCMYSTR pT, MYSIZE n):MYBASE(pT, n) { |
CStdStr(PCMYSTR pT, MYSIZE n):MYBASE(pT, n) |
2141 |
} |
{} |
2142 |
|
|
2143 |
#ifdef SS_UNSIGNED |
#ifdef SS_UNSIGNED |
2144 |
CStdStr(PCUSTR pU) { |
|
2145 |
*this = reinterpret_cast < PCSTR > (pU); |
CStdStr(PCUSTR pU) |
2146 |
} |
{ |
2147 |
|
*this = reinterpret_cast < PCSTR > (pU); |
2148 |
|
} |
2149 |
#endif |
#endif |
2150 |
|
|
2151 |
CStdStr(PCSTR pA) { |
CStdStr(PCSTR pA) |
2152 |
|
{ |
2153 |
#ifdef SS_ANSI |
#ifdef SS_ANSI |
|
*this = pA; |
|
|
#else |
|
|
if (!TryLoad(pA)) |
|
2154 |
*this = pA; |
*this = pA; |
2155 |
|
#else |
2156 |
|
|
2157 |
|
if (!TryLoad(pA)) |
2158 |
|
*this = pA; |
2159 |
#endif |
#endif |
|
} |
|
2160 |
|
|
2161 |
CStdStr(PCWSTR pW) { |
} |
2162 |
|
|
2163 |
|
CStdStr(PCWSTR pW) |
2164 |
|
{ |
2165 |
#ifdef SS_ANSI |
#ifdef SS_ANSI |
|
*this = pW; |
|
|
#else |
|
|
if (!TryLoad(pW)) |
|
2166 |
*this = pW; |
*this = pW; |
2167 |
|
#else |
2168 |
|
|
2169 |
|
if (!TryLoad(pW)) |
2170 |
|
*this = pW; |
2171 |
#endif |
#endif |
|
} |
|
2172 |
|
|
2173 |
CStdStr(MYCITER first, MYCITER last) |
} |
|
: MYBASE(first, last) { |
|
|
} |
|
2174 |
|
|
2175 |
CStdStr(MYSIZE nSize, MYVAL ch, const MYALLOC & al = MYALLOC()) |
CStdStr(MYCITER first, MYCITER last) |
2176 |
: MYBASE(nSize, ch, al) { |
: MYBASE(first, last) |
2177 |
} |
{} |
2178 |
|
|
2179 |
|
CStdStr(MYSIZE nSize, MYVAL ch, const MYALLOC & al = MYALLOC()) |
2180 |
|
: MYBASE(nSize, ch, al) |
2181 |
|
{} |
2182 |
|
|
2183 |
#ifdef SS_INC_COMDEF |
#ifdef SS_INC_COMDEF |
2184 |
CStdStr(const _bstr_t & bstr) |
|
2185 |
{ |
CStdStr(const _bstr_t & bstr) |
2186 |
if (bstr.length() > 0) |
{ |
2187 |
this->append(static_cast < PCMYSTR > (bstr), bstr.length()); |
if (bstr.length() > 0) |
2188 |
} |
this->append(static_cast < PCMYSTR > (bstr), bstr.length()); |
2189 |
|
} |
2190 |
#endif |
#endif |
2191 |
|
|
2192 |
// CStdStr inline assignment operators -- the ssasn function now takes care |
// CStdStr inline assignment operators -- the ssasn function now takes care |
2193 |
// of fixing the MSVC assignment bug (see knowledge base article Q172398). |
// of fixing the MSVC assignment bug (see knowledge base article Q172398). |
2194 |
MYTYPE & operator=(const MYTYPE & str) |
MYTYPE & operator=(const MYTYPE & str) |
2195 |
{ |
{ |
2196 |
ssasn(*this, str); |
ssasn(*this, str); |
2197 |
return *this; |
return *this; |
2198 |
} |
} |
2199 |
|
|
2200 |
MYTYPE & operator=(const std::string & str) { |
MYTYPE & operator=(const std::string & str) |
2201 |
ssasn(*this, str); |
{ |
2202 |
return *this; |
ssasn(*this, str); |
2203 |
} |
return *this; |
2204 |
|
} |
2205 |
|
|
2206 |
MYTYPE & operator=(const std::wstring & str) { |
MYTYPE & operator=(const std::wstring & str) |
2207 |
ssasn(*this, str); |
{ |
2208 |
return *this; |
ssasn(*this, str); |
2209 |
} |
return *this; |
2210 |
|
} |
2211 |
|
|
2212 |
MYTYPE & operator=(PCSTR pA) { |
MYTYPE & operator=(PCSTR pA) |
2213 |
ssasn(*this, pA); |
{ |
2214 |
return *this; |
ssasn(*this, pA); |
2215 |
} |
return *this; |
2216 |
|
} |
2217 |
|
|
2218 |
MYTYPE & operator=(PCWSTR pW) { |
MYTYPE & operator=(PCWSTR pW) |
2219 |
ssasn(*this, pW); |
{ |
2220 |
return *this; |
ssasn(*this, pW); |
2221 |
} |
return *this; |
2222 |
|
} |
2223 |
|
|
2224 |
#ifdef SS_UNSIGNED |
#ifdef SS_UNSIGNED |
2225 |
MYTYPE & operator=(PCUSTR pU) { |
MYTYPE & operator=(PCUSTR pU) |
2226 |
ssasn(*this, reinterpret_cast < PCSTR > (pU)); |
{ |
2227 |
return *this; |
ssasn(*this, reinterpret_cast < PCSTR > (pU)); |
2228 |
} |
return *this; |
2229 |
|
} |
2230 |
#endif |
#endif |
2231 |
|
|
2232 |
MYTYPE & operator=(CT t) { |
MYTYPE & operator=(CT t) |
2233 |
Q172398(*this); |
{ |
2234 |
this->assign(1, t); |
Q172398(*this); |
2235 |
return *this; |
this->assign(1, t); |
|
} |
|
|
|
|
|
#ifdef SS_INC_COMDEF |
|
|
MYTYPE & operator=(const _bstr_t & bstr) { |
|
|
if (bstr.length() > 0) { |
|
|
this->assign(static_cast < PCMYSTR > (bstr), bstr.length()); |
|
2236 |
return *this; |
return *this; |
2237 |
} |
} |
2238 |
else { |
|
2239 |
this->erase(); |
#ifdef SS_INC_COMDEF |
2240 |
return *this; |
MYTYPE & operator=(const _bstr_t & bstr) |
2241 |
|
{ |
2242 |
|
if (bstr.length() > 0) { |
2243 |
|
this->assign(static_cast < PCMYSTR > (bstr), bstr.length()); |
2244 |
|
return *this; |
2245 |
|
} else { |
2246 |
|
this->erase(); |
2247 |
|
return *this; |
2248 |
|
} |
2249 |
} |
} |
|
} |
|
2250 |
#endif |
#endif |
2251 |
|
|
2252 |
|
|
2253 |
// Overloads also needed to fix the MSVC assignment bug (KB: Q172398) |
// Overloads also needed to fix the MSVC assignment bug (KB: Q172398) |
2254 |
// *** Thanks to Pete The Plumber for catching this one *** |
// *** Thanks to Pete The Plumber for catching this one *** |
2255 |
// They also are compiled if you have explicitly turned off refcounting |
// They also are compiled if you have explicitly turned off refcounting |
2256 |
#if ( defined(_MSC_VER) && ( _MSC_VER < 1200 ) ) || defined(SS_NO_REFCOUNT) |
#if ( defined(_MSC_VER) && ( _MSC_VER < 1200 ) ) || defined(SS_NO_REFCOUNT) |
2257 |
|
|
2258 |
MYTYPE & assign(const MYTYPE & str) { |
MYTYPE & assign(const MYTYPE & str) |
2259 |
Q172398(*this); |
{ |
2260 |
sscpy(GetBuffer(str.size() + 1), SSREF(str)); |
Q172398(*this); |
2261 |
this->ReleaseBuffer(str.size()); |
sscpy(GetBuffer(str.size() + 1), SSREF(str)); |
2262 |
return *this; |
this->ReleaseBuffer(str.size()); |
2263 |
} |
return *this; |
2264 |
|
} |
|
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ähne for catching this bug |
|
|
|
|
|
nChars = SSMIN(nChars, str.length() - nStart); |
|
|
MYTYPE strTemp(str.c_str() + nStart, nChars); |
|
|
Q172398(*this); |
|
|
this->assign(strTemp); |
|
|
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ähne for catching this bug |
|
|
|
|
|
nChars = SSMIN(nChars, str.length() - nStart); |
|
2265 |
|
|
2266 |
// Watch out for assignment to self |
MYTYPE & assign(const MYTYPE & str, MYSIZE nStart, MYSIZE nChars) |
2267 |
|
{ |
2268 |
|
// This overload of basic_string::assign is supposed to assign up to |
2269 |
|
// <nChars> or the NULL terminator, whichever comes first. Since we |
2270 |
|
// are about to call a less forgiving overload (in which <nChars> |
2271 |
|
// must be a valid length), we must adjust the length here to a safe |
2272 |
|
// value. Thanks to Ullrich Pollähne for catching this bug |
2273 |
|
|
2274 |
if (this == &str) { |
nChars = SSMIN(nChars, str.length() - nStart); |
2275 |
MYTYPE strTemp(str.c_str() + nStart, nChars); |
MYTYPE strTemp(str.c_str() + nStart, nChars); |
|
static_cast < MYBASE * >(this)->assign(strTemp); |
|
|
} |
|
|
else { |
|
2276 |
Q172398(*this); |
Q172398(*this); |
2277 |
static_cast < MYBASE * >(this)->assign(str.c_str() + nStart, |
this->assign(strTemp); |
2278 |
nChars); |
return *this; |
2279 |
} |
} |
|
return *this; |
|
|
} |
|
2280 |
|
|
2281 |
MYTYPE & assign(const CT * pC, MYSIZE nChars) { |
MYTYPE & assign(const MYBASE & str) |
2282 |
// Q172398 only fix -- erase before assigning, but not if we're |
{ |
2283 |
// assigning from our own buffer |
ssasn(*this, str); |
2284 |
|
return *this; |
2285 |
|
} |
2286 |
|
|
2287 |
#if defined ( _MSC_VER ) && ( _MSC_VER < 1200 ) |
MYTYPE & assign(const MYBASE & str, MYSIZE nStart, MYSIZE nChars) |
2288 |
if (!this->empty() && |
{ |
2289 |
(pC < this->data() || pC > this->data() + this->capacity())) { |
// This overload of basic_string::assign is supposed to assign up to |
2290 |
this->erase(); |
// <nChars> or the NULL terminator, whichever comes first. Since we |
2291 |
|
// are about to call a less forgiving overload (in which <nChars> |
2292 |
|
// must be a valid length), we must adjust the length here to a safe |
2293 |
|
// value. Thanks to Ullrich Pollähne for catching this bug |
2294 |
|
|
2295 |
|
nChars = SSMIN(nChars, str.length() - nStart); |
2296 |
|
|
2297 |
|
// Watch out for assignment to self |
2298 |
|
|
2299 |
|
if (this == &str) { |
2300 |
|
MYTYPE strTemp(str.c_str() + nStart, nChars); |
2301 |
|
static_cast < MYBASE * >(this)->assign(strTemp); |
2302 |
|
} else { |
2303 |
|
Q172398(*this); |
2304 |
|
static_cast < MYBASE * >(this)->assign(str.c_str() + nStart, |
2305 |
|
nChars); |
2306 |
|
} |
2307 |
|
return *this; |
2308 |
} |
} |
2309 |
|
|
2310 |
|
MYTYPE & assign(const CT * pC, MYSIZE nChars) |
2311 |
|
{ |
2312 |
|
// Q172398 only fix -- erase before assigning, but not if we're |
2313 |
|
// assigning from our own buffer |
2314 |
|
|
2315 |
|
#if defined ( _MSC_VER ) && ( _MSC_VER < 1200 ) |
2316 |
|
if (!this->empty() && |
2317 |
|
(pC < this->data() || pC > this->data() + this->capacity())) { |
2318 |
|
this->erase(); |
2319 |
|
} |
2320 |
#endif |
#endif |
2321 |
Q172398(*this); |
Q172398(*this); |
2322 |
static_cast < MYBASE * >(this)->assign(pC, nChars); |
static_cast < MYBASE * >(this)->assign(pC, nChars); |
2323 |
return *this; |
return *this; |
2324 |
} |
} |
2325 |
|
|
2326 |
MYTYPE & assign(MYSIZE nChars, MYVAL val) { |
MYTYPE & assign(MYSIZE nChars, MYVAL val) |
2327 |
Q172398(*this); |
{ |
2328 |
static_cast < MYBASE * >(this)->assign(nChars, val); |
Q172398(*this); |
2329 |
return *this; |
static_cast < MYBASE * >(this)->assign(nChars, val); |
2330 |
} |
return *this; |
2331 |
|
} |
2332 |
|
|
2333 |
MYTYPE & assign(const CT * pT) { |
MYTYPE & assign(const CT * pT) |
2334 |
return this->assign(pT, MYBASE::traits_type::length(pT)); |
{ |
2335 |
} |
return this->assign(pT, MYBASE::traits_type::length(pT)); |
2336 |
|
} |
2337 |
|
|
2338 |
MYTYPE & assign(MYCITER iterFirst, MYCITER iterLast) { |
MYTYPE & assign(MYCITER iterFirst, MYCITER iterLast) |
2339 |
|
{ |
2340 |
#if defined ( _MSC_VER ) && ( _MSC_VER < 1200 ) |
#if defined ( _MSC_VER ) && ( _MSC_VER < 1200 ) |
2341 |
// Q172398 fix. don't call erase() if we're assigning from ourself |
// Q172398 fix. don't call erase() if we're assigning from ourself |
2342 |
if (iterFirst < this->begin() || |
if (iterFirst < this->begin() || |
2343 |
iterFirst > this->begin() + this->size()) { |
iterFirst > this->begin() + this->size()) { |
2344 |
this->erase() |
this->erase() |
2345 |
} |
} |
2346 |
#endif |
#endif |
2347 |
this->replace(this->begin(), this->end(), iterFirst, iterLast); |
this->replace(this->begin(), this->end(), iterFirst, iterLast); |
2348 |
return *this; |
return *this; |
2349 |
} |
} |
2350 |
#endif |
#endif |
2351 |
|
|
2352 |
|
|
2353 |
// ------------------------------------------------------------------------- |
// ------------------------------------------------------------------------- |
2354 |
// CStdStr inline concatenation. |
// CStdStr inline concatenation. |
2355 |
// ------------------------------------------------------------------------- |
// ------------------------------------------------------------------------- |
2356 |
MYTYPE & operator+=(const MYTYPE & str) { |
MYTYPE & operator+=(const MYTYPE & str) |
2357 |
ssadd(*this, str); |
{ |
2358 |
return *this; |
ssadd(*this, str); |
2359 |
} |
return *this; |
2360 |
|
} |
2361 |
|
|
2362 |
MYTYPE & operator+=(const std::string & str) { |
MYTYPE & operator+=(const std::string & str) |
2363 |
ssadd(*this, str); |
{ |
2364 |
return *this; |
ssadd(*this, str); |
2365 |
} |
return *this; |
2366 |
|
} |
2367 |
|
|
2368 |
MYTYPE & operator+=(const std::wstring & str) { |
MYTYPE & operator+=(const std::wstring & str) |
2369 |
ssadd(*this, str); |
{ |
2370 |
return *this; |
ssadd(*this, str); |
2371 |
} |
return *this; |
2372 |
|
} |
2373 |
|
|
2374 |
MYTYPE & operator+=(PCSTR pA) { |
MYTYPE & operator+=(PCSTR pA) |
2375 |
ssadd(*this, pA); |
{ |
2376 |
return *this; |
ssadd(*this, pA); |
2377 |
} |
return *this; |
2378 |
|
} |
2379 |
|
|
2380 |
MYTYPE & operator+=(PCWSTR pW) { |
MYTYPE & operator+=(PCWSTR pW) |
2381 |
ssadd(*this, pW); |
{ |
2382 |
return *this; |
ssadd(*this, pW); |
2383 |
} |
return *this; |
2384 |
|
} |
2385 |
|
|
2386 |
MYTYPE & operator+=(CT t) { |
MYTYPE & operator+=(CT t) |
2387 |
this->append(1, t); |
{ |
2388 |
return *this; |
this->append(1, t); |
2389 |
} |
return *this; |
2390 |
|
} |
2391 |
#ifdef SS_INC_COMDEF // if we have _bstr_t, define a += for it too. |
#ifdef SS_INC_COMDEF // if we have _bstr_t, define a += for it too. |
2392 |
MYTYPE & operator+=(const _bstr_t & bstr) { |
MYTYPE & operator+=(const _bstr_t & bstr) |
2393 |
return this->operator+=(static_cast < PCMYSTR > (bstr)); |
{ |
2394 |
} |
return this->operator+=(static_cast < PCMYSTR > (bstr)); |
2395 |
|
} |
2396 |
#endif |
#endif |
2397 |
|
|
2398 |
|
|
2399 |
// ------------------------------------------------------------------------- |
// ------------------------------------------------------------------------- |
2400 |
// Case changing functions |
// Case changing functions |
2401 |
// ------------------------------------------------------------------------- |
// ------------------------------------------------------------------------- |
|
|
|
|
MYTYPE & ToUpper(const std::locale & loc = std::locale()) { |
|
|
// Note -- if there are any MBCS character sets in which the lowercase |
|
|
// form a character takes up a different number of bytes than the |
|
|
// uppercase form, this would probably not work... |
|
|
|
|
|
std::transform(this->begin(), |
|
|
this->end(), |
|
|
this->begin(), std::bind2nd(SSToUpper < CT > (), loc)); |
|
|
|
|
|
// ...but if it were, this would probably work better. Also, this way |
|
|
// seems to be a bit faster when anything other then the "C" locale is |
|
|
// used... |
|
|
|
|
|
// if ( !empty() ) |
|
|
// { |
|
|
// ssupr(this->GetBuf(), this->size(), loc); |
|
|
// this->RelBuf(); |
|
|
// } |
|
2402 |
|
|
2403 |
return *this; |
MYTYPE & ToUpper(const std::locale & loc = std::locale()) |
2404 |
} |
{ |
2405 |
|
// Note -- if there are any MBCS character sets in which the lowercase |
2406 |
|
// form a character takes up a different number of bytes than the |
2407 |
|
// uppercase form, this would probably not work... |
2408 |
|
|
2409 |
|
std::transform(this->begin(), |
2410 |
|
this->end(), |
2411 |
|
this->begin(), std::bind2nd(SSToUpper < CT > (), loc)); |
2412 |
|
|
2413 |
|
// ...but if it were, this would probably work better. Also, this way |
2414 |
|
// seems to be a bit faster when anything other then the "C" locale is |
2415 |
|
// used... |
2416 |
|
|
2417 |
|
// if ( !empty() ) |
2418 |
|
// { |
2419 |
|
// ssupr(this->GetBuf(), this->size(), loc); |
2420 |
|
// this->RelBuf(); |
2421 |
|
// } |
2422 |
|
|
2423 |
MYTYPE & ToLower(const std::locale & loc = std::locale()) { |
return *this; |
2424 |
// Note -- if there are any MBCS character sets in which the lowercase |
} |
|
// form a character takes up a different number of bytes than the |
|
|
// uppercase form, this would probably not work... |
|
|
|
|
|
std::transform(this->begin(), |
|
|
this->end(), |
|
|
this->begin(), std::bind2nd(SSToLower < CT > (), loc)); |
|
|
|
|
|
// ...but if it were, this would probably work better. Also, this way |
|
|
// seems to be a bit faster when anything other then the "C" locale is |
|
|
// used... |
|
|
|
|
|
// if ( !empty() ) |
|
|
// { |
|
|
// sslwr(this->GetBuf(), this->size(), loc); |
|
|
// this->RelBuf(); |
|
|
// } |
|
|
return *this; |
|
|
} |
|
2425 |
|
|
2426 |
|
MYTYPE & ToLower(const std::locale & loc = std::locale()) |
2427 |
|
{ |
2428 |
|
// Note -- if there are any MBCS character sets in which the lowercase |
2429 |
|
// form a character takes up a different number of bytes than the |
2430 |
|
// uppercase form, this would probably not work... |
2431 |
|
|
2432 |
|
std::transform(this->begin(), |
2433 |
|
this->end(), |
2434 |
|
this->begin(), std::bind2nd(SSToLower < CT > (), loc)); |
2435 |
|
|
2436 |
|
// ...but if it were, this would probably work better. Also, this way |
2437 |
|
// seems to be a bit faster when anything other then the "C" locale is |
2438 |
|
// used... |
2439 |
|
|
2440 |
|
// if ( !empty() ) |
2441 |
|
// { |
2442 |
|
// sslwr(this->GetBuf(), this->size(), loc); |
2443 |
|
// this->RelBuf(); |
2444 |
|
// } |
2445 |
|
return *this; |
2446 |
|
} |
2447 |
|
|
|
MYTYPE & Normalize() { |
|
|
return Trim().ToLower(); |
|
|
} |
|
2448 |
|
|
2449 |
|
MYTYPE & Normalize() |
2450 |
|
{ |
2451 |
|
return Trim().ToLower(); |
2452 |
|
} |
2453 |
|
|
|
// ------------------------------------------------------------------------- |
|
|
// 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. |
|
|
// In VC 7 and later, of course, the ref-counting stuff is gone. |
|
|
// ------------------------------------------------------------------------- |
|
|
|
|
|
CT *GetBuf(int nMinLen = -1) { |
|
|
if (static_cast < int >(this->size()) < nMinLen) |
|
|
this->resize(static_cast < MYSIZE > (nMinLen)); |
|
2454 |
|
|
2455 |
return this->empty()? const_cast < |
// ------------------------------------------------------------------------- |
2456 |
CT * >(this->data()) : &(this->at(0)); |
// CStdStr -- Direct access to character buffer. In the MS' implementation, |
2457 |
} |
// the at() function that we use here also calls _Freeze() providing us some |
2458 |
|
// protection from multithreading problems associated with ref-counting. |
2459 |
|
// In VC 7 and later, of course, the ref-counting stuff is gone. |
2460 |
|
// ------------------------------------------------------------------------- |
2461 |
|
|
2462 |
CT *SetBuf(int nLen) |
CT *GetBuf(int nMinLen = -1) |
2463 |
{ |
{ |
2464 |
nLen = (nLen > 0 ? nLen : 0); |
if (static_cast < int >(this->size()) |
2465 |
if (this->capacity() < 1 && nLen == 0) |
< nMinLen) |
2466 |
this->resize(1); |
this->resize(static_cast < MYSIZE > (nMinLen)); |
2467 |
|
|
2468 |
this->resize(static_cast < MYSIZE > (nLen)); |
return this->empty()? const_cast < |
2469 |
return const_cast < CT * >(this->data()); |
CT * >(this->data()) : &(this->at(0)); |
2470 |
} |
} |
|
void RelBuf(int nNewLen = -1) { |
|
|
this->resize(static_cast < MYSIZE > (nNewLen > -1 ? nNewLen : |
|
|
sslen(this->c_str()))); |
|
|
} |
|
2471 |
|
|
2472 |
void BufferRel() |
CT *SetBuf(int nLen) |
2473 |
{ |
{ |
2474 |
RelBuf(); |
nLen = (nLen > 0 ? nLen : 0); |
2475 |
} // backwards compatability |
if (this->capacity() < 1 && nLen == 0) |
2476 |
CT *Buffer() |
this->resize(1); |
|
{ |
|
|
return GetBuf(); |
|
|
} // backwards compatability |
|
|
CT *BufferSet(int nLen) |
|
|
{ |
|
|
return SetBuf(nLen); |
|
|
} // backwards compatability |
|
2477 |
|
|
2478 |
bool Equals(const CT * pT, bool bUseCase = false) const |
this->resize(static_cast < MYSIZE > (nLen)); |
2479 |
{ |
return const_cast < CT * >(this->data()); |
2480 |
return 0 == |
} |
2481 |
(bUseCase ? this->compare(pT) : ssicmp(this->c_str(), pT)); |
void RelBuf(int nNewLen = -1) |
2482 |
} |
{ |
2483 |
|
this->resize(static_cast < MYSIZE > (nNewLen > -1 ? nNewLen : |
2484 |
|
sslen(this->c_str()))); |
2485 |
|
} |
2486 |
|
|
2487 |
// ------------------------------------------------------------------------- |
void BufferRel() |
2488 |
// FUNCTION: CStdStr::Load |
{ |
2489 |
// REMARKS: |
RelBuf(); |
2490 |
// Loads string from resource specified by nID |
} // backwards compatability |
2491 |
// |
CT *Buffer() |
2492 |
// PARAMETERS: |
{ |
2493 |
// nID - resource Identifier. Purely a Win32 thing in this case |
return GetBuf(); |
2494 |
// |
} // backwards compatability |
2495 |
// RETURN VALUE: |
CT *BufferSet(int nLen) |
2496 |
// true if successful, false otherwise |
{ |
2497 |
// ------------------------------------------------------------------------- |
return SetBuf(nLen); |
2498 |
|
} // backwards compatability |
2499 |
|
|
2500 |
#ifndef SS_ANSI |
bool Equals(const CT * pT, bool bUseCase = false) const |
2501 |
|
{ |
2502 |
|
return 0 == |
2503 |
|
(bUseCase ? this->compare(pT) : ssicmp(this->c_str(), pT)); |
2504 |
|
} |
2505 |
|
|
2506 |
bool Load(UINT nId, HMODULE hModule = NULL) { |
// ------------------------------------------------------------------------- |
2507 |
bool bLoaded = false; // set to true of we succeed. |
// FUNCTION: CStdStr::Load |
2508 |
|
// REMARKS: |
2509 |
|
// Loads string from resource specified by nID |
2510 |
|
// |
2511 |
|
// PARAMETERS: |
2512 |
|
// nID - resource Identifier. Purely a Win32 thing in this case |
2513 |
|
// |
2514 |
|
// RETURN VALUE: |
2515 |
|
// true if successful, false otherwise |
2516 |
|
// ------------------------------------------------------------------------- |
2517 |
|
|
2518 |
#ifdef _MFC_VER // When in Rome (or MFC land)... |
#ifndef SS_ANSI |
2519 |
|
|
2520 |
// If they gave a resource handle, use it. Note - this is archaic |
bool Load(UINT nId, HMODULE hModule = NULL) |
2521 |
// and not really what I would recommend. But then again, in MFC |
{ |
2522 |
// land, you ought to be using CString for resources anyway since |
bool bLoaded = false; // set to true of we succeed. |
|
// it walks the resource chain for you. |
|
2523 |
|
|
2524 |
HMODULE hModuleOld = NULL; |
#ifdef _MFC_VER // When in Rome (or MFC land)... |
2525 |
|
|
2526 |
if (NULL != hModule) { |
// If they gave a resource handle, use it. Note - this is archaic |
2527 |
hModuleOld = AfxGetResourceHandle(); |
// and not really what I would recommend. But then again, in MFC |
2528 |
AfxSetResourceHandle(hModule); |
// land, you ought to be using CString for resources anyway since |
2529 |
} |
// it walks the resource chain for you. |
2530 |
|
|
2531 |
|
HMODULE hModuleOld = NULL; |
2532 |
|
|
2533 |
|
if (NULL != hModule) { |
2534 |
|
hModuleOld = AfxGetResourceHandle(); |
2535 |
|
AfxSetResourceHandle(hModule); |
2536 |
|
} |
2537 |
|
|
2538 |
// ...load the string |
// ...load the string |
2539 |
|
|
2540 |
CString strRes; |
CString strRes; |
2541 |
bLoaded = FALSE != strRes.LoadString(nId); |
bLoaded = FALSE != strRes.LoadString(nId); |
2542 |
|
|
2543 |
// ...and if we set the resource handle, restore it. |
// ...and if we set the resource handle, restore it. |
2544 |
|
|
2545 |
if (NULL != hModuleOld) |
if (NULL != hModuleOld) |
2546 |
AfxSetResourceHandle(hModule); |
AfxSetResourceHandle(hModule); |
2547 |
|
|
2548 |
if (bLoaded) |
if (bLoaded) |
2549 |
*this = strRes; |
*this = strRes; |
2550 |
|
|
2551 |
#else // otherwise make our own hackneyed version of CString's Load |
#else // otherwise make our own hackneyed version of CString's Load |
2552 |
|
|
2553 |
// Get the resource name and module handle |
// Get the resource name and module handle |
2554 |
|
|
2555 |
if (NULL == hModule) |
if (NULL == hModule) |
2556 |
hModule = GetResourceHandle(); |
hModule = GetResourceHandle(); |
2557 |
|
|
2558 |
PCTSTR szName = MAKEINTRESOURCE((nId >> 4) + 1); // lifted |
PCTSTR szName = MAKEINTRESOURCE((nId >> 4) + 1); // lifted |
2559 |
DWORD dwSize = 0; |
DWORD dwSize = 0; |
2560 |
|
|
2561 |
// No sense continuing if we can't find the resource |
// No sense continuing if we can't find the resource |
2562 |
|
|
2563 |
HRSRC hrsrc =::FindResource(hModule, szName, RT_STRING); |
HRSRC hrsrc =::FindResource(hModule, szName, RT_STRING); |
2564 |
|
|
2565 |
if (NULL == hrsrc) { |
if (NULL == hrsrc) { |
2566 |
TRACE(_T("Cannot find resource %d: 0x%X"), nId,::GetLastError()); |
TRACE(_T("Cannot find resource %d: 0x%X"), nId,::GetLastError()); |
2567 |
} |
} else if (0 == (dwSize =::SizeofResource(hModule, hrsrc) / sizeof(CT))) { |
2568 |
else if (0 == (dwSize =::SizeofResource(hModule, hrsrc) / sizeof(CT))) { |
TRACE(_T("Cant get size of resource %d 0x%X\n"), nId, |
2569 |
TRACE(_T("Cant get size of resource %d 0x%X\n"), nId, |
GetLastError()); |
2570 |
GetLastError()); |
} else { |
2571 |
} |
bLoaded = 0 != ssload(hModule, nId, GetBuf(dwSize), dwSize); |
2572 |
else { |
ReleaseBuffer(); |
2573 |
bLoaded = 0 != ssload(hModule, nId, GetBuf(dwSize), dwSize); |
} |
|
ReleaseBuffer(); |
|
|
} |
|
2574 |
|
|
2575 |
#endif // #ifdef _MFC_VER |
#endif // #ifdef _MFC_VER |
2576 |
|
|
2577 |
if (!bLoaded) |
if (!bLoaded) |
2578 |
TRACE(_T("String not loaded 0x%X\n"),::GetLastError()); |
TRACE(_T("String not loaded 0x%X\n"),::GetLastError()); |
2579 |
|
|
2580 |
return bLoaded; |
return bLoaded; |
2581 |
} |
} |
2582 |
|
|
2583 |
#endif // #ifdef SS_ANSI |
#endif // #ifdef SS_ANSI |
2584 |
|
|
2585 |
// ------------------------------------------------------------------------- |
// ------------------------------------------------------------------------- |
2586 |
// FUNCTION: CStdStr::Format |
// FUNCTION: CStdStr::Format |
2587 |
// void _cdecl Formst(CStdStringA& PCSTR szFormat, ...) |
// void _cdecl Formst(CStdStringA& PCSTR szFormat, ...) |
2588 |
// void _cdecl Format(PCSTR szFormat); |
// void _cdecl Format(PCSTR szFormat); |
2589 |
// |
// |
2590 |
// DESCRIPTION: |
// DESCRIPTION: |
2591 |
// This function does sprintf/wsprintf style formatting on CStdStringA |
// This function does sprintf/wsprintf style formatting on CStdStringA |
2592 |
// objects. It looks a lot like MFC's CString::Format. Some people |
// objects. It looks a lot like MFC's CString::Format. Some people |
2593 |
// might even call this identical. Fortunately, these people are now |
// might even call this identical. Fortunately, these people are now |
2594 |
// dead... heh heh. |
// dead... heh heh. |
2595 |
// |
// |
2596 |
// PARAMETERS: |
// PARAMETERS: |
2597 |
// nId - ID of string resource holding the format string |
// nId - ID of string resource holding the format string |
2598 |
// szFormat - a PCSTR holding the format specifiers |
// szFormat - a PCSTR holding the format specifiers |
2599 |
// argList - a va_list holding the arguments for the format specifiers. |
// argList - a va_list holding the arguments for the format specifiers. |
2600 |
// |
// |
2601 |
// RETURN VALUE: None. |
// RETURN VALUE: None. |
2602 |
// ------------------------------------------------------------------------- |
// ------------------------------------------------------------------------- |
2603 |
// formatting (using wsprintf style formatting) |
// formatting (using wsprintf style formatting) |
2604 |
|
|
2605 |
// If they want a Format() function that safely handles string objects |
// If they want a Format() function that safely handles string objects |
2606 |
// without casting |
// without casting |
2607 |
|
|
2608 |
#ifdef SS_SAFE_FORMAT |
#ifdef SS_SAFE_FORMAT |
2609 |
|
|
2610 |
// Question: Joe, you wacky coder you, why do you have so many overloads |
// Question: Joe, you wacky coder you, why do you have so many overloads |
2611 |
// of the Format() function |
// of the Format() function |
2612 |
// Answer: One reason only - CString compatability. In short, by making |
// Answer: One reason only - CString compatability. In short, by making |
2613 |
// the Format() function a template this way, I can do strong typing |
// the Format() function a template this way, I can do strong typing |
2614 |
// and allow people to pass CStdString arguments as fillers for |
// and allow people to pass CStdString arguments as fillers for |
2615 |
// "%s" format specifiers without crashing their program! The downside |
// "%s" format specifiers without crashing their program! The downside |
2616 |
// is that I need to overload on the number of arguments. If you are |
// is that I need to overload on the number of arguments. If you are |
2617 |
// passing more arguments than I have listed below in any of my |
// passing more arguments than I have listed below in any of my |
2618 |
// overloads, just add another one. |
// overloads, just add another one. |
2619 |
// |
// |
2620 |
// Yes, yes, this is really ugly. In essence what I am doing here is |
// Yes, yes, this is really ugly. In essence what I am doing here is |
2621 |
// protecting people from a bad (and incorrect) programming practice |
// protecting people from a bad (and incorrect) programming practice |
2622 |
// that they should not be doing anyway. I am protecting them from |
// that they should not be doing anyway. I am protecting them from |
2623 |
// themselves. Why am I doing this? Well, if you had any idea the |
// themselves. Why am I doing this? Well, if you had any idea the |
2624 |
// number of times I've been emailed by people about this |
// number of times I've been emailed by people about this |
2625 |
// "incompatability" in my code, you wouldn't ask. |
// "incompatability" in my code, you wouldn't ask. |
2626 |
|
|
2627 |
void Fmt(const CT * szFmt, ...) |
void Fmt(const CT * szFmt, ...) |
2628 |
{ |
{ |
2629 |
va_list argList; |
va_list argList; |
2630 |
va_start(argList, szFmt); |
va_start(argList, szFmt); |
2631 |
FormatV(szFmt, argList); |
FormatV(szFmt, argList); |
2632 |
va_end(argList); |
va_end(argList); |
2633 |
} |
} |
2634 |
|
|
2635 |
#ifndef SS_ANSI |
#ifndef SS_ANSI |
2636 |
|
|
2637 |
void Format(UINT nId) |
void Format(UINT nId) |
2638 |
{ |
{ |
2639 |
MYTYPE strFmt; |
MYTYPE strFmt; |
2640 |
if (strFmt.Load(nId)) |
if (strFmt.Load(nId)) |
2641 |
this->swap(strFmt); |
this->swap(strFmt); |
2642 |
} |
} |
2643 |
template < class A1 > void Format(UINT nId, const A1 & v) |
template < class A1 > |
2644 |
{ |
void Format(UINT nId, const A1 & v) |
2645 |
MYTYPE strFmt; |
{ |
2646 |
if (strFmt.Load(nId)) |
MYTYPE strFmt; |
2647 |
Fmt(strFmt, FmtArg < A1 > (v) ()); |
if (strFmt.Load(nId)) |
2648 |
} |
Fmt(strFmt, FmtArg < A1 > (v) ()); |
2649 |
template < class A1, class A2 > |
} |
2650 |
|
template < class A1, class A2 > |
2651 |
void Format(UINT nId, const A1 & v1, const A2 & v2) |
void Format(UINT nId, const A1 & v1, const A2 & v2) |
2652 |
{ |
{ |
2653 |
MYTYPE strFmt; |
MYTYPE strFmt; |
2654 |
if (strFmt.Load(nId)) |
if (strFmt.Load(nId)) |
2655 |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) ()); |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) ()); |
2656 |
} |
} |
2657 |
template < class A1, class A2, class A3 > |
template < class A1, class A2, class A3 > |
2658 |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3) |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3) |
2659 |
{ |
{ |
2660 |
MYTYPE strFmt; |
MYTYPE strFmt; |
2661 |
if (strFmt.Load(nId)) { |
if (strFmt.Load(nId)) { |
2662 |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
2663 |
FmtArg < A3 > (v3) ()); |
FmtArg < A3 > (v3) ()); |
2664 |
|
} |
2665 |
} |
} |
2666 |
} |
template < class A1, class A2, class A3, class A4 > |
|
template < class A1, class A2, class A3, class A4 > |
|
2667 |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3, |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3, |
2668 |
const A4 & v4) |
const A4 & v4) |
2669 |
{ |
{ |
2670 |
MYTYPE strFmt; |
MYTYPE strFmt; |
2671 |
if (strFmt.Load(nId)) { |
if (strFmt.Load(nId)) { |
2672 |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
2673 |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) ()); |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) ()); |
2674 |
|
} |
2675 |
} |
} |
2676 |
} |
template < class A1, class A2, class A3, class A4, class A5 > |
|
template < class A1, class A2, class A3, class A4, class A5 > |
|
2677 |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3, |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3, |
2678 |
const A4 & v4, const A5 & v5) |
const A4 & v4, const A5 & v5) |
2679 |
{ |
{ |
2680 |
MYTYPE strFmt; |
MYTYPE strFmt; |
2681 |
if (strFmt.Load(nId)) { |
if (strFmt.Load(nId)) { |
2682 |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
2683 |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
2684 |
FmtArg < A5 > (v5) ()); |
FmtArg < A5 > (v5) ()); |
2685 |
|
} |
2686 |
} |
} |
2687 |
} |
template < class A1, class A2, class A3, class A4, class A5, class A6 > |
|
template < class A1, class A2, class A3, class A4, class A5, class A6 > |
|
2688 |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3, |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3, |
2689 |
const A4 & v4, const A5 & v5, const A6 & v6) |
const A4 & v4, const A5 & v5, const A6 & v6) |
2690 |
{ |
{ |
2691 |
MYTYPE strFmt; |
MYTYPE strFmt; |
2692 |
if (strFmt.Load(nId)) { |
if (strFmt.Load(nId)) { |
2693 |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
2694 |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
2695 |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) ()); |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) ()); |
2696 |
|
} |
2697 |
} |
} |
2698 |
} |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
|
template < class A1, class A2, class A3, class A4, class A5, class A6, |
|
2699 |
class A7 > |
class A7 > |
2700 |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3, |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3, |
2701 |
const A4 & v4, const A5 & v5, const A6 & v6, |
const A4 & v4, const A5 & v5, const A6 & v6, |
2702 |
const A7 & v7) |
const A7 & v7) |
2703 |
{ |
{ |
2704 |
MYTYPE strFmt; |
MYTYPE strFmt; |
2705 |
if (strFmt.Load(nId)) { |
if (strFmt.Load(nId)) { |
2706 |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
2707 |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
2708 |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
2709 |
FmtArg < A7 > (v7) ()); |
FmtArg < A7 > (v7) ()); |
2710 |
|
} |
2711 |
} |
} |
2712 |
} |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
|
template < class A1, class A2, class A3, class A4, class A5, class A6, |
|
2713 |
class A7, class A8 > |
class A7, class A8 > |
2714 |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3, |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3, |
2715 |
const A4 & v4, const A5 & v5, const A6 & v6, |
const A4 & v4, const A5 & v5, const A6 & v6, |
2716 |
const A7 & v7, const A8 & v8) |
const A7 & v7, const A8 & v8) |
2717 |
{ |
{ |
2718 |
MYTYPE strFmt; |
MYTYPE strFmt; |
2719 |
if (strFmt.Load(nId)) { |
if (strFmt.Load(nId)) { |
2720 |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
2721 |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
2722 |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
2723 |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) ()); |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) ()); |
2724 |
|
} |
2725 |
} |
} |
2726 |
} |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
|
template < class A1, class A2, class A3, class A4, class A5, class A6, |
|
2727 |
class A7, class A8, class A9 > |
class A7, class A8, class A9 > |
2728 |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3, |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3, |
2729 |
const A4 & v4, const A5 & v5, const A6 & v6, |
const A4 & v4, const A5 & v5, const A6 & v6, |
2730 |
const A7 & v7, const A8 & v8, const A9 & v9) |
const A7 & v7, const A8 & v8, const A9 & v9) |
2731 |
{ |
{ |
2732 |
MYTYPE strFmt; |
MYTYPE strFmt; |
2733 |
if (strFmt.Load(nId)) { |
if (strFmt.Load(nId)) { |
2734 |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
2735 |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
2736 |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
2737 |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
2738 |
FmtArg < A9 > (v9) ()); |
FmtArg < A9 > (v9) ()); |
2739 |
|
} |
2740 |
} |
} |
2741 |
} |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
|
template < class A1, class A2, class A3, class A4, class A5, class A6, |
|
2742 |
class A7, class A8, class A9, class A10 > |
class A7, class A8, class A9, class A10 > |
2743 |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3, |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3, |
2744 |
const A4 & v4, const A5 & v5, const A6 & v6, |
const A4 & v4, const A5 & v5, const A6 & v6, |
2745 |
const A7 & v7, const A8 & v8, const A9 & v9, |
const A7 & v7, const A8 & v8, const A9 & v9, |
2746 |
const A10 & v10) |
const A10 & v10) |
2747 |
{ |
{ |
2748 |
MYTYPE strFmt; |
MYTYPE strFmt; |
2749 |
if (strFmt.Load(nId)) { |
if (strFmt.Load(nId)) { |
2750 |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
2751 |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
2752 |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
2753 |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
2754 |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) ()); |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) ()); |
2755 |
|
} |
2756 |
} |
} |
2757 |
} |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
|
template < class A1, class A2, class A3, class A4, class A5, class A6, |
|
2758 |
class A7, class A8, class A9, class A10, class A11 > |
class A7, class A8, class A9, class A10, class A11 > |
2759 |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3, |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3, |
2760 |
const A4 & v4, const A5 & v5, const A6 & v6, |
const A4 & v4, const A5 & v5, const A6 & v6, |
2761 |
const A7 & v7, const A8 & v8, const A9 & v9, |
const A7 & v7, const A8 & v8, const A9 & v9, |
2762 |
const A10 & v10, const A11 & v11) |
const A10 & v10, const A11 & v11) |
2763 |
{ |
{ |
2764 |
MYTYPE strFmt; |
MYTYPE strFmt; |
2765 |
if (strFmt.Load(nId)) { |
if (strFmt.Load(nId)) { |
2766 |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
2767 |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
2768 |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
2769 |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
2770 |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) (), |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) (), |
2771 |
FmtArg < A11 > (v11) ()); |
FmtArg < A11 > (v11) ()); |
2772 |
|
} |
2773 |
} |
} |
2774 |
} |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
|
template < class A1, class A2, class A3, class A4, class A5, class A6, |
|
2775 |
class A7, class A8, class A9, class A10, class A11, class A12 > |
class A7, class A8, class A9, class A10, class A11, class A12 > |
2776 |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3, |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3, |
2777 |
const A4 & v4, const A5 & v5, const A6 & v6, |
const A4 & v4, const A5 & v5, const A6 & v6, |
2778 |
const A7 & v7, const A8 & v8, const A9 & v9, |
const A7 & v7, const A8 & v8, const A9 & v9, |
2779 |
const A10 & v10, const A11 & v11, const A12 & v12) |
const A10 & v10, const A11 & v11, const A12 & v12) |
2780 |
{ |
{ |
2781 |
MYTYPE strFmt; |
MYTYPE strFmt; |
2782 |
if (strFmt.Load(nId)) { |
if (strFmt.Load(nId)) { |
2783 |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
2784 |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
2785 |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
2786 |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
2787 |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) (), |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) (), |
2788 |
FmtArg < A11 > (v11) (), FmtArg < A12 > (v12) ()); |
FmtArg < A11 > (v11) (), FmtArg < A12 > (v12) ()); |
2789 |
|
} |
2790 |
} |
} |
2791 |
} |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
|
template < class A1, class A2, class A3, class A4, class A5, class A6, |
|
2792 |
class A7, class A8, class A9, class A10, class A11, class A12, |
class A7, class A8, class A9, class A10, class A11, class A12, |
2793 |
class A13 > |
class A13 > |
2794 |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3, |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3, |
2796 |
const A7 & v7, const A8 & v8, const A9 & v9, |
const A7 & v7, const A8 & v8, const A9 & v9, |
2797 |
const A10 & v10, const A11 & v11, const A12 & v12, |
const A10 & v10, const A11 & v11, const A12 & v12, |
2798 |
const A13 & v13) |
const A13 & v13) |
2799 |
{ |
{ |
2800 |
MYTYPE strFmt; |
MYTYPE strFmt; |
2801 |
if (strFmt.Load(nId)) { |
if (strFmt.Load(nId)) { |
2802 |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
2803 |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
2804 |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
2805 |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
2806 |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) (), |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) (), |
2807 |
FmtArg < A11 > (v11) (), FmtArg < A12 > (v12) (), |
FmtArg < A11 > (v11) (), FmtArg < A12 > (v12) (), |
2808 |
FmtArg < A13 > (v13) ()); |
FmtArg < A13 > (v13) ()); |
2809 |
|
} |
2810 |
} |
} |
2811 |
} |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
|
template < class A1, class A2, class A3, class A4, class A5, class A6, |
|
2812 |
class A7, class A8, class A9, class A10, class A11, class A12, |
class A7, class A8, class A9, class A10, class A11, class A12, |
2813 |
class A13, class A14 > |
class A13, class A14 > |
2814 |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3, |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3, |
2816 |
const A7 & v7, const A8 & v8, const A9 & v9, |
const A7 & v7, const A8 & v8, const A9 & v9, |
2817 |
const A10 & v10, const A11 & v11, const A12 & v12, |
const A10 & v10, const A11 & v11, const A12 & v12, |
2818 |
const A13 & v13, const A14 & v14) |
const A13 & v13, const A14 & v14) |
2819 |
{ |
{ |
2820 |
MYTYPE strFmt; |
MYTYPE strFmt; |
2821 |
if (strFmt.Load(nId)) { |
if (strFmt.Load(nId)) { |
2822 |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
2823 |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
2824 |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
2825 |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
2826 |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) (), |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) (), |
2827 |
FmtArg < A11 > (v11) (), FmtArg < A12 > (v12) (), |
FmtArg < A11 > (v11) (), FmtArg < A12 > (v12) (), |
2828 |
FmtArg < A13 > (v13) (), FmtArg < A14 > (v14) ()); |
FmtArg < A13 > (v13) (), FmtArg < A14 > (v14) ()); |
2829 |
|
} |
2830 |
} |
} |
2831 |
} |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
|
template < class A1, class A2, class A3, class A4, class A5, class A6, |
|
2832 |
class A7, class A8, class A9, class A10, class A11, class A12, |
class A7, class A8, class A9, class A10, class A11, class A12, |
2833 |
class A13, class A14, class A15 > |
class A13, class A14, class A15 > |
2834 |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3, |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3, |
2836 |
const A7 & v7, const A8 & v8, const A9 & v9, |
const A7 & v7, const A8 & v8, const A9 & v9, |
2837 |
const A10 & v10, const A11 & v11, const A12 & v12, |
const A10 & v10, const A11 & v11, const A12 & v12, |
2838 |
const A13 & v13, const A14 & v14, const A15 & v15) |
const A13 & v13, const A14 & v14, const A15 & v15) |
2839 |
{ |
{ |
2840 |
MYTYPE strFmt; |
MYTYPE strFmt; |
2841 |
if (strFmt.Load(nId)) { |
if (strFmt.Load(nId)) { |
2842 |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
2843 |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
2844 |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
2845 |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
2846 |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) (), |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) (), |
2847 |
FmtArg < A11 > (v11) (), FmtArg < A12 > (v12) (), |
FmtArg < A11 > (v11) (), FmtArg < A12 > (v12) (), |
2848 |
FmtArg < A13 > (v13) (), FmtArg < A14 > (v14) (), |
FmtArg < A13 > (v13) (), FmtArg < A14 > (v14) (), |
2849 |
FmtArg < A15 > (v15) ()); |
FmtArg < A15 > (v15) ()); |
2850 |
|
} |
2851 |
} |
} |
2852 |
} |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
|
template < class A1, class A2, class A3, class A4, class A5, class A6, |
|
2853 |
class A7, class A8, class A9, class A10, class A11, class A12, |
class A7, class A8, class A9, class A10, class A11, class A12, |
2854 |
class A13, class A14, class A15, class A16 > |
class A13, class A14, class A15, class A16 > |
2855 |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3, |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3, |
2858 |
const A10 & v10, const A11 & v11, const A12 & v12, |
const A10 & v10, const A11 & v11, const A12 & v12, |
2859 |
const A13 & v13, const A14 & v14, const A15 & v15, |
const A13 & v13, const A14 & v14, const A15 & v15, |
2860 |
const A16 & v16) |
const A16 & v16) |
2861 |
{ |
{ |
2862 |
MYTYPE strFmt; |
MYTYPE strFmt; |
2863 |
if (strFmt.Load(nId)) { |
if (strFmt.Load(nId)) { |
2864 |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
2865 |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
2866 |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
2867 |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
2868 |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) (), |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) (), |
2869 |
FmtArg < A11 > (v11) (), FmtArg < A12 > (v12) (), |
FmtArg < A11 > (v11) (), FmtArg < A12 > (v12) (), |
2870 |
FmtArg < A13 > (v13) (), FmtArg < A14 > (v14) (), |
FmtArg < A13 > (v13) (), FmtArg < A14 > (v14) (), |
2871 |
FmtArg < A15 > (v15) (), FmtArg < A16 > (v16) ()); |
FmtArg < A15 > (v15) (), FmtArg < A16 > (v16) ()); |
2872 |
|
} |
2873 |
} |
} |
2874 |
} |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
|
template < class A1, class A2, class A3, class A4, class A5, class A6, |
|
2875 |
class A7, class A8, class A9, class A10, class A11, class A12, |
class A7, class A8, class A9, class A10, class A11, class A12, |
2876 |
class A13, class A14, class A15, class A16, class A17 > |
class A13, class A14, class A15, class A16, class A17 > |
2877 |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3, |
void Format(UINT nId, const A1 & v1, const A2 & v2, const A3 & v3, |
2880 |
const A10 & v10, const A11 & v11, const A12 & v12, |
const A10 & v10, const A11 & v11, const A12 & v12, |
2881 |
const A13 & v13, const A14 & v14, const A15 & v15, |
const A13 & v13, const A14 & v14, const A15 & v15, |
2882 |
const A16 & v16, const A17 & v17) |
const A16 & v16, const A17 & v17) |
2883 |
{ |
{ |
2884 |
MYTYPE strFmt; |
MYTYPE strFmt; |
2885 |
if (strFmt.Load(nId)) { |
if (strFmt.Load(nId)) { |
2886 |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(strFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
2887 |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
2888 |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
2889 |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
2890 |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) (), |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) (), |
2891 |
FmtArg < A11 > (v11) (), FmtArg < A12 > (v12) (), |
FmtArg < A11 > (v11) (), FmtArg < A12 > (v12) (), |
2892 |
FmtArg < A13 > (v13) (), FmtArg < A14 > (v14) (), |
FmtArg < A13 > (v13) (), FmtArg < A14 > (v14) (), |
2893 |
FmtArg < A15 > (v15) (), FmtArg < A16 > (v16) (), |
FmtArg < A15 > (v15) (), FmtArg < A16 > (v16) (), |
2894 |
FmtArg < A17 > (v17) ()); |
FmtArg < A17 > (v17) ()); |
2895 |
|
} |
2896 |
} |
} |
|
} |
|
2897 |
|
|
2898 |
#endif // #ifndef SS_ANSI |
#endif // #ifndef SS_ANSI |
2899 |
|
|
2900 |
// ...now the other overload of Format: the one that takes a string literal |
// ...now the other overload of Format: the one that takes a string literal |
2901 |
|
|
2902 |
void Format(const CT * szFmt) |
void Format(const CT * szFmt) |
2903 |
{ |
{ |
2904 |
*this = szFmt; |
*this = szFmt; |
2905 |
} |
} |
2906 |
template < class A1 > void Format(const CT * szFmt, const A1 & v) |
template < class A1 > |
2907 |
{ |
void Format(const CT * szFmt, const A1 & v) |
2908 |
Fmt(szFmt, FmtArg < A1 > (v) ()); |
{ |
2909 |
} |
Fmt(szFmt, FmtArg < A1 > (v) ()); |
2910 |
template < class A1, class A2 > |
} |
2911 |
|
template < class A1, class A2 > |
2912 |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2) |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2) |
2913 |
{ |
{ |
2914 |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) ()); |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) ()); |
2915 |
} |
} |
2916 |
template < class A1, class A2, class A3 > |
template < class A1, class A2, class A3 > |
2917 |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
2918 |
const A3 & v3) |
const A3 & v3) |
2919 |
{ |
{ |
2920 |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
2921 |
FmtArg < A3 > (v3) ()); |
FmtArg < A3 > (v3) ()); |
2922 |
} |
} |
2923 |
template < class A1, class A2, class A3, class A4 > |
template < class A1, class A2, class A3, class A4 > |
2924 |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
2925 |
const A3 & v3, const A4 & v4) |
const A3 & v3, const A4 & v4) |
2926 |
{ |
{ |
2927 |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
2928 |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) ()); |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) ()); |
2929 |
} |
} |
2930 |
template < class A1, class A2, class A3, class A4, class A5 > |
template < class A1, class A2, class A3, class A4, class A5 > |
2931 |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
2932 |
const A3 & v3, const A4 & v4, const A5 & v5) |
const A3 & v3, const A4 & v4, const A5 & v5) |
2933 |
{ |
{ |
2934 |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
2935 |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
2936 |
FmtArg < A5 > (v5) ()); |
FmtArg < A5 > (v5) ()); |
2937 |
} |
} |
2938 |
template < class A1, class A2, class A3, class A4, class A5, class A6 > |
template < class A1, class A2, class A3, class A4, class A5, class A6 > |
2939 |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
2940 |
const A3 & v3, const A4 & v4, const A5 & v5, |
const A3 & v3, const A4 & v4, const A5 & v5, |
2941 |
const A6 & v6) |
const A6 & v6) |
2942 |
{ |
{ |
2943 |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
2944 |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
2945 |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) ()); |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) ()); |
2946 |
} |
} |
2947 |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
2948 |
class A7 > |
class A7 > |
2949 |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
2950 |
const A3 & v3, const A4 & v4, const A5 & v5, |
const A3 & v3, const A4 & v4, const A5 & v5, |
2951 |
const A6 & v6, const A7 & v7) |
const A6 & v6, const A7 & v7) |
2952 |
{ |
{ |
2953 |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
2954 |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
2955 |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
2956 |
FmtArg < A7 > (v7) ()); |
FmtArg < A7 > (v7) ()); |
2957 |
} |
} |
2958 |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
2959 |
class A7, class A8 > |
class A7, class A8 > |
2960 |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
2961 |
const A3 & v3, const A4 & v4, const A5 & v5, |
const A3 & v3, const A4 & v4, const A5 & v5, |
2962 |
const A6 & v6, const A7 & v7, const A8 & v8) |
const A6 & v6, const A7 & v7, const A8 & v8) |
2963 |
{ |
{ |
2964 |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
2965 |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
2966 |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
2967 |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) ()); |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) ()); |
2968 |
} |
} |
2969 |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
2970 |
class A7, class A8, class A9 > |
class A7, class A8, class A9 > |
2971 |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
2972 |
const A3 & v3, const A4 & v4, const A5 & v5, |
const A3 & v3, const A4 & v4, const A5 & v5, |
2973 |
const A6 & v6, const A7 & v7, const A8 & v8, |
const A6 & v6, const A7 & v7, const A8 & v8, |
2974 |
const A9 & v9) |
const A9 & v9) |
2975 |
{ |
{ |
2976 |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
2977 |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
2978 |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
2979 |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
2980 |
FmtArg < A9 > (v9) ()); |
FmtArg < A9 > (v9) ()); |
2981 |
} |
} |
2982 |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
2983 |
class A7, class A8, class A9, class A10 > |
class A7, class A8, class A9, class A10 > |
2984 |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
2985 |
const A3 & v3, const A4 & v4, const A5 & v5, |
const A3 & v3, const A4 & v4, const A5 & v5, |
2986 |
const A6 & v6, const A7 & v7, const A8 & v8, |
const A6 & v6, const A7 & v7, const A8 & v8, |
2987 |
const A9 & v9, const A10 & v10) |
const A9 & v9, const A10 & v10) |
2988 |
{ |
{ |
2989 |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
2990 |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
2991 |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
2992 |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
2993 |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) ()); |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) ()); |
2994 |
} |
} |
2995 |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
2996 |
class A7, class A8, class A9, class A10, class A11 > |
class A7, class A8, class A9, class A10, class A11 > |
2997 |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
2998 |
const A3 & v3, const A4 & v4, const A5 & v5, |
const A3 & v3, const A4 & v4, const A5 & v5, |
2999 |
const A6 & v6, const A7 & v7, const A8 & v8, |
const A6 & v6, const A7 & v7, const A8 & v8, |
3000 |
const A9 & v9, const A10 & v10, const A11 & v11) |
const A9 & v9, const A10 & v10, const A11 & v11) |
3001 |
{ |
{ |
3002 |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
3003 |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
3004 |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
3005 |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
3006 |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) (), |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) (), |
3007 |
FmtArg < A11 > (v11) ()); |
FmtArg < A11 > (v11) ()); |
3008 |
} |
} |
3009 |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
3010 |
class A7, class A8, class A9, class A10, class A11, class A12 > |
class A7, class A8, class A9, class A10, class A11, class A12 > |
3011 |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
3012 |
const A3 & v3, const A4 & v4, const A5 & v5, |
const A3 & v3, const A4 & v4, const A5 & v5, |
3013 |
const A6 & v6, const A7 & v7, const A8 & v8, |
const A6 & v6, const A7 & v7, const A8 & v8, |
3014 |
const A9 & v9, const A10 & v10, const A11 & v11, |
const A9 & v9, const A10 & v10, const A11 & v11, |
3015 |
const A12 & v12) |
const A12 & v12) |
3016 |
{ |
{ |
3017 |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
3018 |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
3019 |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
3020 |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
3021 |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) (), |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) (), |
3022 |
FmtArg < A11 > (v11) (), FmtArg < A12 > (v12) ()); |
FmtArg < A11 > (v11) (), FmtArg < A12 > (v12) ()); |
3023 |
} |
} |
3024 |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
3025 |
class A7, class A8, class A9, class A10, class A11, class A12, |
class A7, class A8, class A9, class A10, class A11, class A12, |
3026 |
class A13 > |
class A13 > |
3027 |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
3029 |
const A6 & v6, const A7 & v7, const A8 & v8, |
const A6 & v6, const A7 & v7, const A8 & v8, |
3030 |
const A9 & v9, const A10 & v10, const A11 & v11, |
const A9 & v9, const A10 & v10, const A11 & v11, |
3031 |
const A12 & v12, const A13 & v13) |
const A12 & v12, const A13 & v13) |
3032 |
{ |
{ |
3033 |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
3034 |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
3035 |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
3036 |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
3037 |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) (), |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) (), |
3038 |
FmtArg < A11 > (v11) (), FmtArg < A12 > (v12) (), |
FmtArg < A11 > (v11) (), FmtArg < A12 > (v12) (), |
3039 |
FmtArg < A13 > (v13) ()); |
FmtArg < A13 > (v13) ()); |
3040 |
} |
} |
3041 |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
3042 |
class A7, class A8, class A9, class A10, class A11, class A12, |
class A7, class A8, class A9, class A10, class A11, class A12, |
3043 |
class A13, class A14 > |
class A13, class A14 > |
3044 |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
3046 |
const A6 & v6, const A7 & v7, const A8 & v8, |
const A6 & v6, const A7 & v7, const A8 & v8, |
3047 |
const A9 & v9, const A10 & v10, const A11 & v11, |
const A9 & v9, const A10 & v10, const A11 & v11, |
3048 |
const A12 & v12, const A13 & v13, const A14 & v14) |
const A12 & v12, const A13 & v13, const A14 & v14) |
3049 |
{ |
{ |
3050 |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
3051 |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
3052 |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
3053 |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
3054 |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) (), |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) (), |
3055 |
FmtArg < A11 > (v11) (), FmtArg < A12 > (v12) (), |
FmtArg < A11 > (v11) (), FmtArg < A12 > (v12) (), |
3056 |
FmtArg < A13 > (v13) (), FmtArg < A14 > (v14) ()); |
FmtArg < A13 > (v13) (), FmtArg < A14 > (v14) ()); |
3057 |
} |
} |
3058 |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
3059 |
class A7, class A8, class A9, class A10, class A11, class A12, |
class A7, class A8, class A9, class A10, class A11, class A12, |
3060 |
class A13, class A14, class A15 > |
class A13, class A14, class A15 > |
3061 |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
3064 |
const A9 & v9, const A10 & v10, const A11 & v11, |
const A9 & v9, const A10 & v10, const A11 & v11, |
3065 |
const A12 & v12, const A13 & v13, const A14 & v14, |
const A12 & v12, const A13 & v13, const A14 & v14, |
3066 |
const A15 & v15) |
const A15 & v15) |
3067 |
{ |
{ |
3068 |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
3069 |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
3070 |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
3071 |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
3072 |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) (), |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) (), |
3073 |
FmtArg < A11 > (v11) (), FmtArg < A12 > (v12) (), |
FmtArg < A11 > (v11) (), FmtArg < A12 > (v12) (), |
3074 |
FmtArg < A13 > (v13) (), FmtArg < A14 > (v14) (), |
FmtArg < A13 > (v13) (), FmtArg < A14 > (v14) (), |
3075 |
FmtArg < A15 > (v15) ()); |
FmtArg < A15 > (v15) ()); |
3076 |
} |
} |
3077 |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
3078 |
class A7, class A8, class A9, class A10, class A11, class A12, |
class A7, class A8, class A9, class A10, class A11, class A12, |
3079 |
class A13, class A14, class A15, class A16 > |
class A13, class A14, class A15, class A16 > |
3080 |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
3083 |
const A9 & v9, const A10 & v10, const A11 & v11, |
const A9 & v9, const A10 & v10, const A11 & v11, |
3084 |
const A12 & v12, const A13 & v13, const A14 & v14, |
const A12 & v12, const A13 & v13, const A14 & v14, |
3085 |
const A15 & v15, const A16 & v16) |
const A15 & v15, const A16 & v16) |
3086 |
{ |
{ |
3087 |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
3088 |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
3089 |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
3090 |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
3091 |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) (), |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) (), |
3092 |
FmtArg < A11 > (v11) (), FmtArg < A12 > (v12) (), |
FmtArg < A11 > (v11) (), FmtArg < A12 > (v12) (), |
3093 |
FmtArg < A13 > (v13) (), FmtArg < A14 > (v14) (), |
FmtArg < A13 > (v13) (), FmtArg < A14 > (v14) (), |
3094 |
FmtArg < A15 > (v15) (), FmtArg < A16 > (v16) ()); |
FmtArg < A15 > (v15) (), FmtArg < A16 > (v16) ()); |
3095 |
} |
} |
3096 |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
template < class A1, class A2, class A3, class A4, class A5, class A6, |
3097 |
class A7, class A8, class A9, class A10, class A11, class A12, |
class A7, class A8, class A9, class A10, class A11, class A12, |
3098 |
class A13, class A14, class A15, class A16, class A17 > |
class A13, class A14, class A15, class A16, class A17 > |
3099 |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
void Format(const CT * szFmt, const A1 & v1, const A2 & v2, |
3102 |
const A9 & v9, const A10 & v10, const A11 & v11, |
const A9 & v9, const A10 & v10, const A11 & v11, |
3103 |
const A12 & v12, const A13 & v13, const A14 & v14, |
const A12 & v12, const A13 & v13, const A14 & v14, |
3104 |
const A15 & v15, const A16 & v16, const A17 & v17) |
const A15 & v15, const A16 & v16, const A17 & v17) |
3105 |
{ |
{ |
3106 |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
Fmt(szFmt, FmtArg < A1 > (v1) (), FmtArg < A2 > (v2) (), |
3107 |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
FmtArg < A3 > (v3) (), FmtArg < A4 > (v4) (), |
3108 |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
FmtArg < A5 > (v5) (), FmtArg < A6 > (v6) (), |
3109 |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
FmtArg < A7 > (v7) (), FmtArg < A8 > (v8) (), |
3110 |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) (), |
FmtArg < A9 > (v9) (), FmtArg < A10 > (v10) (), |
3111 |
FmtArg < A11 > (v11) (), FmtArg < A12 > (v12) (), |
FmtArg < A11 > (v11) (), FmtArg < A12 > (v12) (), |
3112 |
FmtArg < A13 > (v13) (), FmtArg < A14 > (v14) (), |
FmtArg < A13 > (v13) (), FmtArg < A14 > (v14) (), |
3113 |
FmtArg < A15 > (v15) (), FmtArg < A16 > (v16) (), |
FmtArg < A15 > (v15) (), FmtArg < A16 > (v16) (), |
3114 |
FmtArg < A17 > (v17) ()); |
FmtArg < A17 > (v17) ()); |
3115 |
} |
} |
3116 |
|
|
3117 |
#else // #ifdef SS_SAFE_FORMAT |
#else // #ifdef SS_SAFE_FORMAT |
3118 |
|
|
3119 |
|
|
3120 |
#ifndef SS_ANSI |
#ifndef SS_ANSI |
3121 |
|
|
3122 |
void Format(UINT nId, ...) |
void Format(UINT nId, ...) |
3123 |
{ |
{ |
3124 |
va_list argList; |
va_list argList; |
3125 |
va_start(argList, nId); |
va_start(argList, nId); |
3126 |
|
|
3127 |
MYTYPE strFmt; |
MYTYPE strFmt; |
3128 |
if (strFmt.Load(nId)) |
if (strFmt.Load(nId)) |
3129 |
FormatV(strFmt, argList); |
FormatV(strFmt, argList); |
3130 |
|
|
3131 |
va_end(argList); |
va_end(argList); |
3132 |
} |
} |
3133 |
|
|
3134 |
#endif // #ifdef SS_ANSI |
#endif // #ifdef SS_ANSI |
3135 |
|
|
3136 |
void Format(const CT * szFmt, ...) |
void Format(const CT * szFmt, ...) |
3137 |
{ |
{ |
3138 |
va_list argList; |
va_list argList; |
3139 |
va_start(argList, szFmt); |
va_start(argList, szFmt); |
3140 |
FormatV(szFmt, argList); |
FormatV(szFmt, argList); |
3141 |
va_end(argList); |
va_end(argList); |
3142 |
} |
} |
3143 |
|
|
3144 |
#endif // #ifdef SS_SAFE_FORMAT |
#endif // #ifdef SS_SAFE_FORMAT |
3145 |
|
|
3146 |
void AppendFormat(const CT * szFmt, ...) |
void AppendFormat(const CT * szFmt, ...) |
3147 |
{ |
{ |
3148 |
va_list argList; |
va_list argList; |
3149 |
va_start(argList, szFmt); |
va_start(argList, szFmt); |
3150 |
AppendFormatV(szFmt, argList); |
AppendFormatV(szFmt, argList); |
3151 |
va_end(argList); |
va_end(argList); |
3152 |
} |
} |
3153 |
|
|
3154 |
#define MAX_FMT_TRIES 5 // #of times we try |
#define MAX_FMT_TRIES 5 // #of times we try |
3155 |
#define FMT_BLOCK_SIZE 2048 // # of bytes to increment per try |
#define FMT_BLOCK_SIZE 2048 // # of bytes to increment per try |
3157 |
#define BUFSIZE_2ND 512 |
#define BUFSIZE_2ND 512 |
3158 |
#define STD_BUF_SIZE 1024 |
#define STD_BUF_SIZE 1024 |
3159 |
|
|
3160 |
// an efficient way to add formatted characters to the string. You may only |
// an efficient way to add formatted characters to the string. You may only |
3161 |
// add up to STD_BUF_SIZE characters at a time, though |
// add up to STD_BUF_SIZE characters at a time, though |
3162 |
void AppendFormatV(const CT * szFmt, va_list argList) |
void AppendFormatV(const CT * szFmt, va_list argList) |
3163 |
{ |
{ |
3164 |
CT szBuf[STD_BUF_SIZE]; |
CT szBuf[STD_BUF_SIZE]; |
3165 |
#ifdef SS_ANSI |
#ifdef SS_ANSI |
3166 |
int nLen = ssvsprintf(szBuf, STD_BUF_SIZE - 1, szFmt, argList); |
|
3167 |
|
int nLen = ssvsprintf(szBuf, STD_BUF_SIZE - 1, szFmt, argList); |
3168 |
#else |
#else |
3169 |
int nLen = ssnprintf(szBuf, STD_BUF_SIZE - 1, szFmt, argList); |
|
3170 |
|
int nLen = ssnprintf(szBuf, STD_BUF_SIZE - 1, szFmt, argList); |
3171 |
#endif |
#endif |
|
if (0 < nLen) |
|
|
this->append(szBuf, nLen); |
|
|
} |
|
3172 |
|
|
3173 |
// ------------------------------------------------------------------------- |
if (0 < nLen) |
3174 |
// FUNCTION: FormatV |
this->append(szBuf, nLen); |
3175 |
// void FormatV(PCSTR szFormat, va_list, argList); |
} |
|
// |
|
|
// DESCRIPTION: |
|
|
// This function formats the string with sprintf style format-specs. |
|
|
// It makes a general guess at required buffer size and then tries |
|
|
// successively larger buffers until it finds one big enough or a |
|
|
// threshold (MAX_FMT_TRIES) is exceeded. |
|
|
// |
|
|
// PARAMETERS: |
|
|
// szFormat - a PCSTR holding the format of the output |
|
|
// argList - a Microsoft specific va_list for variable argument lists |
|
|
// |
|
|
// RETURN VALUE: |
|
|
// ------------------------------------------------------------------------- |
|
3176 |
|
|
3177 |
void FormatV(const CT * szFormat, va_list argList) |
// ------------------------------------------------------------------------- |
3178 |
{ |
// FUNCTION: FormatV |
3179 |
|
// void FormatV(PCSTR szFormat, va_list, argList); |
3180 |
|
// |
3181 |
|
// DESCRIPTION: |
3182 |
|
// This function formats the string with sprintf style format-specs. |
3183 |
|
// It makes a general guess at required buffer size and then tries |
3184 |
|
// successively larger buffers until it finds one big enough or a |
3185 |
|
// threshold (MAX_FMT_TRIES) is exceeded. |
3186 |
|
// |
3187 |
|
// PARAMETERS: |
3188 |
|
// szFormat - a PCSTR holding the format of the output |
3189 |
|
// argList - a Microsoft specific va_list for variable argument lists |
3190 |
|
// |
3191 |
|
// RETURN VALUE: |
3192 |
|
// ------------------------------------------------------------------------- |
3193 |
|
|
3194 |
|
void FormatV(const CT * szFormat, va_list argList) |
3195 |
|
{ |
3196 |
#ifdef SS_ANSI |
#ifdef SS_ANSI |
3197 |
|
|
3198 |
int nLen = sslen(szFormat) + STD_BUF_SIZE; |
int nLen = sslen(szFormat) + STD_BUF_SIZE; |
3199 |
ssvsprintf(GetBuffer(nLen), nLen - 1, szFormat, argList); |
ssvsprintf(GetBuffer(nLen), nLen - 1, szFormat, argList); |
3200 |
ReleaseBuffer(); |
ReleaseBuffer(); |
3201 |
|
|
3202 |
#else |
#else |
3203 |
|
|
3204 |
CT *pBuf = NULL; |
CT *pBuf = NULL; |
3205 |
int nChars = 1; |
int nChars = 1; |
3206 |
int nUsed = 0; |
int nUsed = 0; |
3207 |
size_type nActual = 0; |
size_type nActual = 0; |
3208 |
int nTry = 0; |
int nTry = 0; |
3209 |
|
|
3210 |
do { |
do { |
3211 |
// Grow more than linearly (e.g. 512, 1536, 3072, etc) |
// Grow more than linearly (e.g. 512, 1536, 3072, etc) |
3212 |
|
|
3213 |
nChars += ((nTry + 1) * FMT_BLOCK_SIZE); |
nChars += ((nTry + 1) * FMT_BLOCK_SIZE); |
3214 |
pBuf = reinterpret_cast < CT * >(_alloca(sizeof(CT) * nChars)); |
pBuf = reinterpret_cast < CT * >(_alloca(sizeof(CT) * nChars)); |
3215 |
nUsed = ssnprintf(pBuf, nChars - 1, szFormat, argList); |
nUsed = ssnprintf(pBuf, nChars - 1, szFormat, argList); |
3216 |
|
|
3217 |
// Ensure proper NULL termination. |
// Ensure proper NULL termination. |
3218 |
|
|
3219 |
nActual = nUsed == -1 ? nChars - 1 : SSMIN(nUsed, nChars - 1); |
nActual = nUsed == -1 ? nChars - 1 : SSMIN(nUsed, nChars - 1); |
3220 |
pBuf[nActual] = '\0'; |
pBuf[nActual] = '\0'; |
3221 |
|
|
3222 |
|
|
3223 |
} while (nUsed < 0 && nTry++ < MAX_FMT_TRIES); |
} while (nUsed < 0 && nTry++ < MAX_FMT_TRIES); |
3224 |
|
|
3225 |
// assign whatever we managed to format |
// assign whatever we managed to format |
3226 |
|
|
3227 |
this->assign(pBuf, nActual); |
this->assign(pBuf, nActual); |
3228 |
|
|
3229 |
#endif |
#endif |
|
} |
|
3230 |
|
|
3231 |
// ------------------------------------------------------------------------- |
} |
3232 |
// CString Facade Functions: |
|
3233 |
// |
// ------------------------------------------------------------------------- |
3234 |
// The following methods are intended to allow you to use this class as a |
// CString Facade Functions: |
3235 |
// near drop-in replacement for CString. |
// |
3236 |
// ------------------------------------------------------------------------- |
// The following methods are intended to allow you to use this class as a |
3237 |
|
// near drop-in replacement for CString. |
3238 |
|
// ------------------------------------------------------------------------- |
3239 |
#ifdef SS_WIN32 |
#ifdef SS_WIN32 |
3240 |
BSTR AllocSysString() const |
BSTR AllocSysString() const |
3241 |
{ |
{ |
3242 |
ostring os; |
ostring os; |
3243 |
ssasn(os, *this); |
ssasn(os, *this); |
3244 |
return::SysAllocString(os.c_str()); |
return::SysAllocString(os.c_str()); |
3245 |
} |
} |
3246 |
#endif |
#endif |
3247 |
|
|
3248 |
int Collate(PCMYSTR szThat) const |
int Collate(PCMYSTR szThat) const |
3249 |
{ |
{ |
3250 |
return sscoll(this->c_str(), this->length(), szThat, sslen(szThat)); |
return sscoll(this->c_str(), this->length(), szThat, sslen(szThat)); |
3251 |
} |
} |
3252 |
|
|
3253 |
int CollateNoCase(PCMYSTR szThat) const |
int CollateNoCase(PCMYSTR szThat) const |
3254 |
{ |
{ |
3255 |
return ssicoll(this->c_str(), this->length(), szThat, sslen(szThat)); |
return ssicoll(this->c_str(), this->length(), szThat, sslen(szThat)); |
3256 |
} |
} |
3257 |
|
|
3258 |
int Compare(PCMYSTR szThat) const |
int Compare(PCMYSTR szThat) const |
3259 |
{ |
{ |
3260 |
return this->compare(szThat); |
return this->compare(szThat); |
3261 |
} |
} |
3262 |
|
|
3263 |
int CompareNoCase(PCMYSTR szThat) const |
int CompareNoCase(PCMYSTR szThat) const |
3264 |
{ |
{ |
3265 |
return ssicmp(this->c_str(), szThat); |
return ssicmp(this->c_str(), szThat); |
3266 |
} |
} |
3267 |
|
|
3268 |
int Delete(int nIdx, int nCount = 1) { |
int Delete(int nIdx, int nCount = 1) |
3269 |
if (nIdx < 0) |
{ |
3270 |
nIdx = 0; |
if (nIdx < 0) |
3271 |
|
nIdx = 0; |
|
if (nIdx < this->GetLength()) |
|
|
this->erase(static_cast < MYSIZE > (nIdx), |
|
|
static_cast < MYSIZE > (nCount)); |
|
3272 |
|
|
3273 |
return GetLength(); |
if (nIdx < this->GetLength()) |
3274 |
} |
this->erase(static_cast < MYSIZE > (nIdx), |
3275 |
|
static_cast < MYSIZE > (nCount)); |
3276 |
|
|
3277 |
void Empty() |
return GetLength(); |
3278 |
{ |
} |
|
this->erase(); |
|
|
} |
|
3279 |
|
|
3280 |
int Find(CT ch) const |
void Empty() |
3281 |
{ |
{ |
3282 |
MYSIZE nIdx = this->find_first_of(ch); |
this->erase(); |
3283 |
return static_cast < int >(MYBASE::npos == nIdx ? -1 : nIdx); |
} |
|
} |
|
3284 |
|
|
3285 |
int Find(PCMYSTR szSub) const |
int Find(CT ch) const |
3286 |
{ |
{ |
3287 |
MYSIZE nIdx = this->find(szSub); |
MYSIZE nIdx = this->find_first_of(ch); |
3288 |
return static_cast < int >(MYBASE::npos == nIdx ? -1 : nIdx); |
return static_cast < int >(MYBASE::npos == nIdx ? -1 : nIdx); |
3289 |
} |
} |
3290 |
|
|
3291 |
int Find(CT ch, int nStart) const |
int Find(PCMYSTR szSub) const |
3292 |
{ |
{ |
3293 |
// CString::Find docs say add 1 to nStart when it's not zero |
MYSIZE nIdx = this->find(szSub); |
3294 |
// CString::Find code doesn't do that however. We'll stick |
return static_cast < int >(MYBASE::npos == nIdx ? -1 : nIdx); |
3295 |
// with what the code does |
} |
|
|
|
|
MYSIZE nIdx = |
|
|
this->find_first_of(ch, static_cast < MYSIZE > (nStart)); |
|
|
return static_cast < int >(MYBASE::npos == nIdx ? -1 : nIdx); |
|
|
} |
|
3296 |
|
|
3297 |
int Find(PCMYSTR szSub, int nStart) const |
int Find(CT ch, int nStart) const |
3298 |
{ |
{ |
3299 |
// CString::Find docs say add 1 to nStart when it's not zero |
// CString::Find docs say add 1 to nStart when it's not zero |
3300 |
// CString::Find code doesn't do that however. We'll stick |
// CString::Find code doesn't do that however. We'll stick |
3301 |
// with what the code does |
// with what the code does |
3302 |
|
|
3303 |
MYSIZE nIdx = this->find(szSub, static_cast < MYSIZE > (nStart)); |
MYSIZE nIdx = |
3304 |
return static_cast < int >(MYBASE::npos == nIdx ? -1 : nIdx); |
this->find_first_of(ch, static_cast < MYSIZE > (nStart)); |
3305 |
} |
return static_cast < int >(MYBASE::npos == nIdx ? -1 : nIdx); |
3306 |
|
} |
3307 |
|
|
3308 |
int FindOneOf(PCMYSTR szCharSet) const |
int Find(PCMYSTR szSub, int nStart) const |
3309 |
{ |
{ |
3310 |
MYSIZE nIdx = this->find_first_of(szCharSet); |
// CString::Find docs say add 1 to nStart when it's not zero |
3311 |
return static_cast < int >(MYBASE::npos == nIdx ? -1 : nIdx); |
// CString::Find code doesn't do that however. We'll stick |
3312 |
} |
// with what the code does |
3313 |
|
|
3314 |
|
MYSIZE nIdx = this->find(szSub, static_cast < MYSIZE > (nStart)); |
3315 |
|
return static_cast < int >(MYBASE::npos == nIdx ? -1 : nIdx); |
3316 |
|
} |
3317 |
|
|
3318 |
|
int FindOneOf(PCMYSTR szCharSet) const |
3319 |
|
{ |
3320 |
|
MYSIZE nIdx = this->find_first_of(szCharSet); |
3321 |
|
return static_cast < int >(MYBASE::npos == nIdx ? -1 : nIdx); |
3322 |
|
} |
3323 |
|
|
3324 |
#ifndef SS_ANSI |
#ifndef SS_ANSI |
3325 |
void FormatMessage(PCMYSTR szFormat, ...) throw(std::exception) |
void FormatMessage(PCMYSTR szFormat, ...) throw(std::exception) |
3326 |
{ |
{ |
3327 |
va_list argList; |
va_list argList; |
3328 |
va_start(argList, szFormat); |
va_start(argList, szFormat); |
3329 |
PMYSTR szTemp; |
PMYSTR szTemp; |
3330 |
if (ssfmtmsg |
if (ssfmtmsg |
3331 |
(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, |
(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, |
3332 |
szFormat, 0, 0, reinterpret_cast < PMYSTR > (&szTemp), 0, |
szFormat, 0, 0, reinterpret_cast < PMYSTR > (&szTemp), 0, |
3333 |
&argList) == 0 || szTemp == 0) { |
&argList) == 0 || szTemp == 0) { |
3334 |
throw std::runtime_error("out of memory"); |
throw std::runtime_error("out of memory"); |
3335 |
} |
} |
3336 |
*this = szTemp; |
*this = szTemp; |
3337 |
LocalFree(szTemp); |
LocalFree(szTemp); |
3338 |
va_end(argList); |
va_end(argList); |
3339 |
} |
} |
3340 |
|
|
3341 |
void FormatMessage(UINT nFormatId, ...) throw(std::exception) |
void FormatMessage(UINT nFormatId, ...) throw(std::exception) |
3342 |
{ |
{ |
3343 |
MYTYPE sFormat; |
MYTYPE sFormat; |
3344 |
VERIFY(sFormat.LoadString(nFormatId)); |
VERIFY(sFormat.LoadString(nFormatId)); |
3345 |
va_list argList; |
va_list argList; |
3346 |
va_start(argList, nFormatId); |
va_start(argList, nFormatId); |
3347 |
PMYSTR szTemp; |
PMYSTR szTemp; |
3348 |
if (ssfmtmsg |
if (ssfmtmsg |
3349 |
(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, |
(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, |
3350 |
sFormat, 0, 0, reinterpret_cast < PMYSTR > (&szTemp), 0, |
sFormat, 0, 0, reinterpret_cast < PMYSTR > (&szTemp), 0, |
3351 |
&argList) == 0 || szTemp == 0) { |
&argList) == 0 || szTemp == 0) { |
3352 |
throw std::runtime_error("out of memory"); |
throw std::runtime_error("out of memory"); |
3353 |
} |
} |
3354 |
*this = szTemp; |
*this = szTemp; |
3355 |
LocalFree(szTemp); |
LocalFree(szTemp); |
3356 |
va_end(argList); |
va_end(argList); |
3357 |
} |
} |
3358 |
#endif |
#endif |
3359 |
|
|
3360 |
// GetAllocLength -- an MSVC7 function but it costs us nothing to add it. |
// GetAllocLength -- an MSVC7 function but it costs us nothing to add it. |
3361 |
|
|
3362 |
int GetAllocLength() |
int GetAllocLength() |
3363 |
{ |
{ |
3364 |
return static_cast < int >(this->capacity()); |
return static_cast < int >(this->capacity()); |
3365 |
} |
} |
3366 |
|
|
3367 |
// ------------------------------------------------------------------------- |
// ------------------------------------------------------------------------- |
3368 |
// GetXXXX -- Direct access to character buffer |
// GetXXXX -- Direct access to character buffer |
3369 |
// ------------------------------------------------------------------------- |
// ------------------------------------------------------------------------- |
3370 |
CT GetAt(int nIdx) const |
CT GetAt(int nIdx) const |
3371 |
{ |
{ |
3372 |
return this->at(static_cast < MYSIZE > (nIdx)); |
return this->at(static_cast < MYSIZE > (nIdx)); |
3373 |
} |
} |
3374 |
|
|
3375 |
CT *GetBuffer(int nMinLen = -1) { |
CT *GetBuffer(int nMinLen = -1) |
3376 |
return GetBuf(nMinLen); |
{ |
3377 |
} |
return GetBuf(nMinLen); |
3378 |
|
} |
3379 |
|
|
3380 |
CT *GetBufferSetLength(int nLen) |
CT *GetBufferSetLength(int nLen) |
3381 |
{ |
{ |
3382 |
return BufferSet(nLen); |
return BufferSet(nLen); |
3383 |
} |
} |
3384 |
|
|
3385 |
// GetLength() -- MFC docs say this is the # of BYTES but |
// GetLength() -- MFC docs say this is the # of BYTES but |
3386 |
// in truth it is the number of CHARACTERs (chars or wchar_ts) |
// in truth it is the number of CHARACTERs (chars or wchar_ts) |
3387 |
int GetLength() const |
int GetLength() const |
3388 |
{ |
{ |
3389 |
return static_cast < int >(this->length()); |
return static_cast < int >(this->length()); |
3390 |
} |
} |
3391 |
|
|
3392 |
int Insert(int nIdx, CT ch) |
int Insert(int nIdx, CT ch) |
3393 |
{ |
{ |
3394 |
if (static_cast < MYSIZE > (nIdx) > this->size() - 1) |
if (static_cast < MYSIZE > (nIdx) > |
3395 |
this->append(1, ch); |
this->size() - 1) |
3396 |
else |
this->append(1, ch); |
3397 |
this->insert(static_cast < MYSIZE > (nIdx), 1, ch); |
else |
3398 |
|
this->insert(static_cast < MYSIZE > (nIdx), 1, ch); |
3399 |
|
|
3400 |
return GetLength(); |
return GetLength(); |
3401 |
} |
} |
3402 |
int Insert(int nIdx, PCMYSTR sz) |
int Insert(int nIdx, PCMYSTR sz) |
3403 |
{ |
{ |
3404 |
if (static_cast < MYSIZE > (nIdx) >= this->size()) |
if (static_cast < MYSIZE > (nIdx) > |
3405 |
this->append(sz, static_cast < MYSIZE > (sslen(sz))); |
= this->size()) |
3406 |
else |
this->append(sz, static_cast < MYSIZE > (sslen(sz))); |
3407 |
this->insert(static_cast < MYSIZE > (nIdx), sz); |
else |
3408 |
|
this->insert(static_cast < MYSIZE > (nIdx), sz); |
3409 |
|
|
3410 |
return GetLength(); |
return GetLength(); |
3411 |
} |
} |
3412 |
|
|
3413 |
bool IsEmpty() const |
bool IsEmpty() const |
3414 |
{ |
{ |
3415 |
return this->empty(); |
return this->empty(); |
3416 |
} |
} |
3417 |
|
|
3418 |
MYTYPE Left(int nCount) const |
MYTYPE Left(int nCount) const |
3419 |
{ |
{ |
3420 |
// Range check the count. |
// Range check the count. |
3421 |
|
|
3422 |
nCount = SSMAX(0, SSMIN(nCount, static_cast < int >(this->size()))); |
nCount = SSMAX(0, SSMIN(nCount, static_cast < int >(this->size()))); |
3423 |
return this->substr(0, static_cast < MYSIZE > (nCount)); |
return this->substr(0, static_cast < MYSIZE > (nCount)); |
3424 |
} |
} |
3425 |
|
|
3426 |
#ifndef SS_ANSI |
#ifndef SS_ANSI |
3427 |
bool LoadString(UINT nId) |
bool LoadString(UINT nId) |
3428 |
{ |
{ |
3429 |
return this->Load(nId); |
return this->Load(nId); |
3430 |
} |
} |
3431 |
#endif |
#endif |
3432 |
|
|
3433 |
void MakeLower() |
void MakeLower() |
3434 |
{ |
{ |
3435 |
ToLower(); |
ToLower(); |
3436 |
} |
} |
|
|
|
|
void MakeReverse() |
|
|
{ |
|
|
std::reverse(this->begin(), this->end()); |
|
|
} |
|
|
|
|
|
void MakeUpper() |
|
|
{ |
|
|
ToUpper(); |
|
|
} |
|
3437 |
|
|
3438 |
MYTYPE Mid(int nFirst) const |
void MakeReverse() |
3439 |
{ |
{ |
3440 |
return Mid(nFirst, this->GetLength() - nFirst); |
std::reverse(this->begin(), this->end()); |
3441 |
} |
} |
3442 |
|
|
3443 |
MYTYPE Mid(int nFirst, int nCount) const |
void MakeUpper() |
3444 |
{ |
{ |
3445 |
// CString does range checking here. Since we're trying to emulate it, |
ToUpper(); |
3446 |
// we must check too. |
} |
3447 |
|
|
3448 |
if (nFirst < 0) |
MYTYPE Mid(int nFirst) const |
3449 |
nFirst = 0; |
{ |
3450 |
if (nCount < 0) |
return Mid(nFirst, this->GetLength() - nFirst); |
3451 |
nCount = 0; |
} |
3452 |
|
|
3453 |
int nSize = static_cast < int >(this->size()); |
MYTYPE Mid(int nFirst, int nCount) const |
3454 |
|
{ |
3455 |
|
// CString does range checking here. Since we're trying to emulate it, |
3456 |
|
// we must check too. |
3457 |
|
|
3458 |
if (nFirst + nCount > nSize) |
if (nFirst < 0) |
3459 |
nCount = nSize - nFirst; |
nFirst = 0; |
3460 |
|
if (nCount < 0) |
3461 |
|
nCount = 0; |
3462 |
|
|
3463 |
if (nFirst > nSize) |
int nSize = static_cast < int >(this->size()); |
|
return MYTYPE(); |
|
3464 |
|
|
3465 |
ASSERT(nFirst >= 0); |
if (nFirst + nCount > nSize) |
3466 |
ASSERT(nFirst + nCount <= nSize); |
nCount = nSize - nFirst; |
3467 |
|
|
3468 |
return this->substr(static_cast < MYSIZE > (nFirst), |
if (nFirst > nSize) |
3469 |
static_cast < MYSIZE > (nCount)); |
return MYTYPE(); |
|
} |
|
3470 |
|
|
3471 |
void ReleaseBuffer(int nNewLen = -1) { |
ASSERT(nFirst >= 0); |
3472 |
RelBuf(nNewLen); |
ASSERT(nFirst + nCount <= nSize); |
|
} |
|
3473 |
|
|
3474 |
int Remove(CT ch) |
return this->substr(static_cast < MYSIZE > (nFirst), |
3475 |
{ |
static_cast < MYSIZE > (nCount)); |
|
MYSIZE nIdx = 0; |
|
|
int nRemoved = 0; |
|
|
while ((nIdx = this->find_first_of(ch)) != MYBASE::npos) { |
|
|
this->erase(nIdx, 1); |
|
|
nRemoved++; |
|
3476 |
} |
} |
|
return nRemoved; |
|
|
} |
|
3477 |
|
|
3478 |
int Replace(CT chOld, CT chNew) |
void ReleaseBuffer(int nNewLen = -1) |
3479 |
{ |
{ |
3480 |
int nReplaced = 0; |
RelBuf(nNewLen); |
3481 |
|
} |
3482 |
|
|
3483 |
for (MYITER iter = this->begin(); iter != this->end(); iter++) { |
int Remove(CT ch) |
3484 |
if (*iter == chOld) { |
{ |
3485 |
*iter = chNew; |
MYSIZE nIdx = 0; |
3486 |
nReplaced++; |
int nRemoved = 0; |
3487 |
|
while ((nIdx = this->find_first_of(ch)) != MYBASE::npos) { |
3488 |
|
this->erase(nIdx, 1); |
3489 |
|
nRemoved++; |
3490 |
} |
} |
3491 |
|
return nRemoved; |
3492 |
} |
} |
3493 |
|
|
3494 |
return nReplaced; |
int Replace(CT chOld, CT chNew) |
3495 |
} |
{ |
3496 |
|
int nReplaced = 0; |
3497 |
|
|
3498 |
int Replace(PCMYSTR szOld, PCMYSTR szNew) |
for (MYITER iter = this->begin(); iter != this->end(); iter++) { |
3499 |
{ |
if (*iter == chOld) { |
3500 |
int nReplaced = 0; |
*iter = chNew; |
3501 |
MYSIZE nIdx = 0; |
nReplaced++; |
|
MYSIZE nOldLen = sslen(szOld); |
|
|
|
|
|
if (0 != nOldLen) { |
|
|
// If the replacement string is longer than the one it replaces, this |
|
|
// string is going to have to grow in size, Figure out how much |
|
|
// and grow it all the way now, rather than incrementally |
|
|
|
|
|
MYSIZE nNewLen = sslen(szNew); |
|
|
if (nNewLen > nOldLen) { |
|
|
int nFound = 0; |
|
|
while (nIdx < this->length() && |
|
|
(nIdx = this->find(szOld, nIdx)) != MYBASE::npos) { |
|
|
nFound++; |
|
|
nIdx += nOldLen; |
|
3502 |
} |
} |
|
this->reserve(this->size() + nFound * (nNewLen - nOldLen)); |
|
3503 |
} |
} |
3504 |
|
|
3505 |
|
return nReplaced; |
3506 |
|
} |
3507 |
|
|
3508 |
static const CT ch = CT(0); |
int Replace(PCMYSTR szOld, PCMYSTR szNew) |
3509 |
PCMYSTR szRealNew = szNew == 0 ? &ch : szNew; |
{ |
3510 |
nIdx = 0; |
int nReplaced = 0; |
3511 |
|
MYSIZE nIdx = 0; |
3512 |
while (nIdx < this->length() && |
MYSIZE nOldLen = sslen(szOld); |
3513 |
(nIdx = this->find(szOld, nIdx)) != MYBASE::npos) { |
|
3514 |
this->replace(this->begin() + nIdx, |
if (0 != nOldLen) { |
3515 |
this->begin() + nIdx + nOldLen, szRealNew); |
// If the replacement string is longer than the one it replaces, this |
3516 |
|
// string is going to have to grow in size, Figure out how much |
3517 |
|
// and grow it all the way now, rather than incrementally |
3518 |
|
|
3519 |
|
MYSIZE nNewLen = sslen(szNew); |
3520 |
|
if (nNewLen > nOldLen) { |
3521 |
|
int nFound = 0; |
3522 |
|
while (nIdx < this->length() && |
3523 |
|
(nIdx = this->find(szOld, nIdx)) != MYBASE::npos) { |
3524 |
|
nFound++; |
3525 |
|
nIdx += nOldLen; |
3526 |
|
} |
3527 |
|
this->reserve(this->size() + nFound * (nNewLen - nOldLen)); |
3528 |
|
} |
3529 |
|
|
3530 |
|
|
3531 |
|
static const CT ch = CT(0); |
3532 |
|
PCMYSTR szRealNew = szNew == 0 ? &ch : szNew; |
3533 |
|
nIdx = 0; |
3534 |
|
|
3535 |
nReplaced++; |
while (nIdx < this->length() && |
3536 |
nIdx += nNewLen; |
(nIdx = this->find(szOld, nIdx)) != MYBASE::npos) { |
3537 |
|
this->replace(this->begin() + nIdx, |
3538 |
|
this->begin() + nIdx + nOldLen, szRealNew); |
3539 |
|
|
3540 |
|
nReplaced++; |
3541 |
|
nIdx += nNewLen; |
3542 |
|
} |
3543 |
} |
} |
|
} |
|
3544 |
|
|
3545 |
return nReplaced; |
return nReplaced; |
3546 |
} |
} |
3547 |
|
|
3548 |
int ReverseFind(CT ch) const |
int ReverseFind(CT ch) const |
3549 |
{ |
{ |
3550 |
MYSIZE nIdx = this->find_last_of(ch); |
MYSIZE nIdx = this->find_last_of(ch); |
3551 |
return static_cast < int >(MYBASE::npos == nIdx ? -1 : nIdx); |
return static_cast < int >(MYBASE::npos == nIdx ? -1 : nIdx); |
3552 |
} |
} |
3553 |
|
|
3554 |
// ReverseFind overload that's not in CString but might be useful |
// ReverseFind overload that's not in CString but might be useful |
3555 |
int ReverseFind(PCMYSTR szFind, MYSIZE pos = MYBASE::npos) const |
int ReverseFind(PCMYSTR szFind, MYSIZE pos = MYBASE::npos) const |
3556 |
{ |
{ |
3557 |
MYSIZE nIdx = this->rfind(0 == szFind ? MYTYPE() : szFind, pos); |
MYSIZE nIdx = this->rfind(0 == szFind ? MYTYPE() : szFind, pos); |
3558 |
return static_cast < int >(MYBASE::npos == nIdx ? -1 : nIdx); |
return static_cast < int >(MYBASE::npos == nIdx ? -1 : nIdx); |
3559 |
} |
} |
3560 |
|
|
3561 |
MYTYPE Right(int nCount) const |
MYTYPE Right(int nCount) const |
3562 |
{ |
{ |
3563 |
// Range check the count. |
// Range check the count. |
3564 |
|
|
3565 |
nCount = SSMAX(0, SSMIN(nCount, static_cast < int >(this->size()))); |
nCount = SSMAX(0, SSMIN(nCount, static_cast < int >(this->size()))); |
3566 |
return this->substr(this->size() - static_cast < MYSIZE > (nCount)); |
return this->substr(this->size() - static_cast < MYSIZE > (nCount)); |
3567 |
} |
} |
3568 |
|
|
3569 |
void SetAt(int nIndex, CT ch) |
void SetAt(int nIndex, CT ch) |
3570 |
{ |
{ |
3571 |
ASSERT(this->size() > static_cast < MYSIZE > (nIndex)); |
ASSERT(this->size() > static_cast < MYSIZE > (nIndex)); |
3572 |
this->at(static_cast < MYSIZE > (nIndex)) = ch; |
this->at(static_cast < MYSIZE > (nIndex)) = ch; |
3573 |
} |
} |
3574 |
|
|
3575 |
#ifndef SS_ANSI |
#ifndef SS_ANSI |
3576 |
BSTR SetSysString(BSTR * pbstr) const |
BSTR SetSysString(BSTR * pbstr) const |
3577 |
{ |
{ |
3578 |
ostring os; |
ostring os; |
3579 |
ssasn(os, *this); |
ssasn(os, *this); |
3580 |
if (!::SysReAllocStringLen(pbstr, os.c_str(), os.length())) |
if (!::SysReAllocStringLen(pbstr, os.c_str(), os.length())) |
3581 |
throw std::runtime_error("out of memory"); |
throw std::runtime_error("out of memory"); |
3582 |
|
|
3583 |
ASSERT(*pbstr != 0); |
ASSERT(*pbstr != 0); |
3584 |
return *pbstr; |
return *pbstr; |
3585 |
} |
} |
3586 |
#endif |
#endif |
3587 |
|
|
3588 |
MYTYPE SpanExcluding(PCMYSTR szCharSet) const |
MYTYPE SpanExcluding(PCMYSTR szCharSet) const |
3589 |
{ |
{ |
3590 |
MYSIZE pos = this->find_first_of(szCharSet); |
MYSIZE pos = this->find_first_of(szCharSet); |
3591 |
return pos == MYBASE::npos ? *this : Left(pos); |
return pos == MYBASE::npos ? *this : Left(pos); |
3592 |
} |
} |
3593 |
|
|
3594 |
MYTYPE SpanIncluding(PCMYSTR szCharSet) const |
MYTYPE SpanIncluding(PCMYSTR szCharSet) const |
3595 |
{ |
{ |
3596 |
MYSIZE pos = this->find_first_not_of(szCharSet); |
MYSIZE pos = this->find_first_not_of(szCharSet); |
3597 |
return pos == MYBASE::npos ? *this : Left(pos); |
return pos == MYBASE::npos ? *this : Left(pos); |
3598 |
} |
} |
3599 |
|
|
3600 |
#if defined SS_WIN32 && !defined(UNICODE) && !defined(SS_ANSI) |
#if defined SS_WIN32 && !defined(UNICODE) && !defined(SS_ANSI) |
3601 |
|
|
3602 |
// CString's OemToAnsi and AnsiToOem functions are available only in |
// CString's OemToAnsi and AnsiToOem functions are available only in |
3603 |
// Unicode builds. However since we're a template we also need a |
// Unicode builds. However since we're a template we also need a |
3604 |
// runtime check of CT and a reinterpret_cast to account for the fact |
// runtime check of CT and a reinterpret_cast to account for the fact |
3605 |
// that CStdStringW gets instantiated even in non-Unicode builds. |
// that CStdStringW gets instantiated even in non-Unicode builds. |
3606 |
|
|
3607 |
void AnsiToOem() |
void AnsiToOem() |
3608 |
{ |
{ |
3609 |
if (sizeof(CT) == sizeof(char) && !empty()) { |
if (sizeof(CT) == sizeof(char) && !empty()) { |
3610 |
::CharToOem(reinterpret_cast < PCSTR > (this->c_str()), |
::CharToOem(reinterpret_cast < PCSTR > (this->c_str()), |
3611 |
reinterpret_cast < PSTR > (GetBuf())); |
reinterpret_cast < PSTR > (GetBuf())); |
3612 |
} |
} else { |
3613 |
else { |
ASSERT(false); |
3614 |
ASSERT(false); |
} |
3615 |
} |
} |
|
} |
|
3616 |
|
|
3617 |
void OemToAnsi() |
void OemToAnsi() |
3618 |
{ |
{ |
3619 |
if (sizeof(CT) == sizeof(char) && !empty()) { |
if (sizeof(CT) == sizeof(char) && !empty()) { |
3620 |
::OemToChar(reinterpret_cast < PCSTR > (this->c_str()), |
::OemToChar(reinterpret_cast < PCSTR > (this->c_str()), |
3621 |
reinterpret_cast < PSTR > (GetBuf())); |
reinterpret_cast < PSTR > (GetBuf())); |
3622 |
} |
} else { |
3623 |
else { |
ASSERT(false); |
3624 |
ASSERT(false); |
} |
3625 |
} |
} |
|
} |
|
3626 |
|
|
3627 |
#endif |
#endif |
3628 |
|
|
3629 |
|
|
3630 |
// ------------------------------------------------------------------------- |
// ------------------------------------------------------------------------- |
3631 |
// Trim and its variants |
// Trim and its variants |
3632 |
// ------------------------------------------------------------------------- |
// ------------------------------------------------------------------------- |
3633 |
MYTYPE & Trim() { |
MYTYPE & Trim() |
3634 |
return TrimLeft().TrimRight(); |
{ |
3635 |
} |
return TrimLeft().TrimRight(); |
3636 |
|
} |
3637 |
|
|
3638 |
MYTYPE & TrimLeft() { |
MYTYPE & TrimLeft() |
3639 |
this->erase(this->begin(), |
{ |
3640 |
std::find_if(this->begin(), this->end(), |
this->erase(this->begin(), |
3641 |
NotSpace < CT > ())); |
std::find_if(this->begin(), this->end(), |
3642 |
|
NotSpace < CT > ())); |
3643 |
|
|
3644 |
return *this; |
return *this; |
3645 |
} |
} |
3646 |
|
|
3647 |
MYTYPE & TrimLeft(CT tTrim) { |
MYTYPE & TrimLeft(CT tTrim) |
3648 |
this->erase(0, this->find_first_not_of(tTrim)); |
{ |
3649 |
return *this; |
this->erase(0, this->find_first_not_of(tTrim)); |
3650 |
} |
return *this; |
3651 |
|
} |
3652 |
|
|
3653 |
MYTYPE & TrimLeft(PCMYSTR szTrimChars) { |
MYTYPE & TrimLeft(PCMYSTR szTrimChars) |
3654 |
this->erase(0, this->find_first_not_of(szTrimChars)); |
{ |
3655 |
return *this; |
this->erase(0, this->find_first_not_of(szTrimChars)); |
3656 |
} |
return *this; |
3657 |
|
} |
3658 |
|
|
3659 |
MYTYPE & TrimRight() { |
MYTYPE & TrimRight() |
3660 |
// NOTE: When comparing reverse_iterators here (MYRITER), I avoid using |
{ |
3661 |
// operator!=. This is because namespace rel_ops also has a template |
// NOTE: When comparing reverse_iterators here (MYRITER), I avoid using |
3662 |
// operator!= which conflicts with the global operator!= already defined |
// operator!=. This is because namespace rel_ops also has a template |
3663 |
// for reverse_iterator in the header <utility>. |
// operator!= which conflicts with the global operator!= already defined |
3664 |
// Thanks to John James for alerting me to this. |
// for reverse_iterator in the header <utility>. |
3665 |
|
// Thanks to John James for alerting me to this. |
3666 |
MYRITER it = |
|
3667 |
std::find_if(this->rbegin(), this->rend(), NotSpace < CT > ()); |
MYRITER it = |
3668 |
if (!(this->rend() == it)) |
std::find_if(this->rbegin(), this->rend(), NotSpace < CT > ()); |
3669 |
this->erase(this->rend() - it); |
if (!(this->rend() == it)) |
3670 |
|
this->erase(this->rend() - it); |
3671 |
|
|
3672 |
this->erase(!(it == this->rend())? this->find_last_of(*it) + 1 : 0); |
this->erase(!(it == this->rend())? this->find_last_of(*it) + 1 : 0); |
3673 |
return *this; |
return *this; |
3674 |
} |
} |
3675 |
|
|
3676 |
MYTYPE & TrimRight(CT tTrim) { |
MYTYPE & TrimRight(CT tTrim) |
3677 |
MYSIZE nIdx = this->find_last_not_of(tTrim); |
{ |
3678 |
this->erase(MYBASE::npos == nIdx ? 0 : ++nIdx); |
MYSIZE nIdx = this->find_last_not_of(tTrim); |
3679 |
return *this; |
this->erase(MYBASE::npos == nIdx ? 0 : ++nIdx); |
3680 |
} |
return *this; |
3681 |
|
} |
3682 |
|
|
3683 |
MYTYPE & TrimRight(PCMYSTR szTrimChars) { |
MYTYPE & TrimRight(PCMYSTR szTrimChars) |
3684 |
MYSIZE nIdx = this->find_last_not_of(szTrimChars); |
{ |
3685 |
this->erase(MYBASE::npos == nIdx ? 0 : ++nIdx); |
MYSIZE nIdx = this->find_last_not_of(szTrimChars); |
3686 |
return *this; |
this->erase(MYBASE::npos == nIdx ? 0 : ++nIdx); |
3687 |
} |
return *this; |
3688 |
|
} |
3689 |
|
|
3690 |
void FreeExtra() |
void FreeExtra() |
3691 |
{ |
{ |
3692 |
MYTYPE mt; |
MYTYPE mt; |
3693 |
this->swap(mt); |
this->swap(mt); |
3694 |
if (!mt.empty()) |
if (!mt.empty()) |
3695 |
this->assign(mt.c_str(), mt.size()); |
this->assign(mt.c_str(), mt.size()); |
3696 |
} |
} |
3697 |
|
|
3698 |
// I have intentionally not implemented the following CString |
// I have intentionally not implemented the following CString |
3699 |
// functions. You cannot make them work without taking advantage |
// functions. You cannot make them work without taking advantage |
3700 |
// of implementation specific behavior. However if you absolutely |
// of implementation specific behavior. However if you absolutely |
3701 |
// MUST have them, uncomment out these lines for "sort-of-like" |
// MUST have them, uncomment out these lines for "sort-of-like" |
3702 |
// their behavior. You're on your own. |
// their behavior. You're on your own. |
|
|
|
|
// CT* LockBuffer() { return GetBuf(); }// won't really lock |
|
|
// void UnlockBuffer(); { } // why have UnlockBuffer w/o LockBuffer? |
|
|
|
|
|
// Array-indexing operators. Required because we defined an implicit cast |
|
|
// to operator const CT* (Thanks to Julian Selman for pointing this out) |
|
|
|
|
|
CT & operator[](int nIdx) { |
|
|
return static_cast < MYBASE * >(this)->operator[](static_cast < |
|
|
MYSIZE > (nIdx)); |
|
|
} |
|
3703 |
|
|
3704 |
const CT & operator[] (int nIdx) const |
// CT* LockBuffer() { return GetBuf(); }// won't really lock |
3705 |
{ |
// void UnlockBuffer(); { } // why have UnlockBuffer w/o LockBuffer? |
|
return static_cast < const MYBASE *>(this)->operator[] (static_cast < |
|
|
MYSIZE > |
|
|
(nIdx)); |
|
|
} |
|
3706 |
|
|
3707 |
CT & operator[] (unsigned int nIdx) |
// Array-indexing operators. Required because we defined an implicit cast |
3708 |
{ |
// to operator const CT* (Thanks to Julian Selman for pointing this out) |
|
return static_cast < MYBASE * >(this)->operator[](static_cast < |
|
|
MYSIZE > (nIdx)); |
|
|
} |
|
3709 |
|
|
3710 |
const CT & operator[] (unsigned int nIdx) const |
CT & operator[](int nIdx) |
3711 |
{ |
{ |
3712 |
return static_cast < const MYBASE *>(this)->operator[] (static_cast < |
return static_cast < MYBASE * >(this)->operator[](static_cast < |
3713 |
MYSIZE > |
MYSIZE > (nIdx)); |
3714 |
(nIdx)); |
} |
3715 |
} |
|
3716 |
|
const CT & operator[] (int nIdx) const |
3717 |
|
{ |
3718 |
|
return static_cast < const MYBASE *>(this)->operator[] (static_cast < |
3719 |
|
MYSIZE > |
3720 |
|
(nIdx)); |
3721 |
|
} |
3722 |
|
|
3723 |
|
CT & operator[] (unsigned int nIdx) |
3724 |
|
{ |
3725 |
|
return static_cast < MYBASE * >(this)->operator[](static_cast < |
3726 |
|
MYSIZE > (nIdx)); |
3727 |
|
} |
3728 |
|
|
3729 |
|
const CT & operator[] (unsigned int nIdx) const |
3730 |
|
{ |
3731 |
|
return static_cast < const MYBASE *>(this)->operator[] (static_cast < |
3732 |
|
MYSIZE > |
3733 |
|
(nIdx)); |
3734 |
|
} |
3735 |
|
|
3736 |
#ifndef SS_NO_IMPLICIT_CAST |
#ifndef SS_NO_IMPLICIT_CAST |
3737 |
operator const CT *() const |
operator const CT *() const |
3738 |
{ |
{ |
3739 |
return this->c_str(); |
return this->c_str(); |
3740 |
} |
} |
3741 |
#endif |
#endif |
3742 |
|
|
3743 |
// IStream related functions. Useful in IPersistStream implementations |
// IStream related functions. Useful in IPersistStream implementations |
3744 |
|
|
3745 |
#ifdef SS_INC_COMDEF |
#ifdef SS_INC_COMDEF |
3746 |
|
|
3747 |
// struct SSSHDR - useful for non Std C++ persistence schemes. |
// struct SSSHDR - useful for non Std C++ persistence schemes. |
3748 |
typedef struct SSSHDR |
typedef struct SSSHDR |
3749 |
{ |
{ |
3750 |
BYTE byCtrl; |
BYTE byCtrl; |
3751 |
ULONG nChars; |
ULONG nChars; |
3752 |
} SSSHDR; // as in "Standard String Stream Header" |
} |
3753 |
|
SSSHDR; // as in "Standard String Stream Header" |
3754 |
|
|
3755 |
#define SSSO_UNICODE 0x01 // the string is a wide string |
#define SSSO_UNICODE 0x01 // the string is a wide string |
3756 |
#define SSSO_COMPRESS 0x02 // the string is compressed |
#define SSSO_COMPRESS 0x02 // the string is compressed |
3757 |
|
|
3758 |
// ------------------------------------------------------------------------- |
// ------------------------------------------------------------------------- |
3759 |
// FUNCTION: StreamSize |
// FUNCTION: StreamSize |
3760 |
// REMARKS: |
// REMARKS: |
3761 |
// Returns how many bytes it will take to StreamSave() this CStdString |
// Returns how many bytes it will take to StreamSave() this CStdString |
3762 |
// object to an IStream. |
// object to an IStream. |
3763 |
// ------------------------------------------------------------------------- |
// ------------------------------------------------------------------------- |
3764 |
ULONG StreamSize() const |
ULONG StreamSize() const |
|
{ |
|
|
// Control header plus string |
|
|
ASSERT(this->size() * sizeof(CT) < 0xffffffffUL - sizeof(SSSHDR)); |
|
|
return (this->size() * sizeof(CT)) + sizeof(SSSHDR); |
|
|
} |
|
|
|
|
|
// ------------------------------------------------------------------------- |
|
|
// FUNCTION: StreamSave |
|
|
// REMARKS: |
|
|
// Saves this CStdString object to a COM IStream. |
|
|
// ------------------------------------------------------------------------- |
|
|
HRESULT StreamSave(IStream * pStream) const |
|
|
{ |
|
|
ASSERT(this->size() * sizeof(CT) < 0xffffffffUL - sizeof(SSSHDR)); |
|
|
HRESULT hr = E_FAIL; |
|
|
ASSERT(pStream != 0); |
|
|
SSSHDR hdr; |
|
|
hdr.byCtrl = sizeof(CT) == 2 ? SSSO_UNICODE : 0; |
|
|
hdr.nChars = this->size(); |
|
|
|
|
|
|
|
|
if (FAILED(hr = pStream->Write(&hdr, sizeof(SSSHDR), 0))) { |
|
|
TRACE(_T("StreamSave: Cannot write control header, ERR=0x%X\n"), |
|
|
hr); |
|
|
} |
|
|
else if (empty()) |
|
3765 |
{ |
{ |
3766 |
; // nothing to write |
// Control header plus string |
3767 |
} |
ASSERT(this->size() * sizeof(CT) < 0xffffffffUL - sizeof(SSSHDR)); |
3768 |
else if (FAILED(hr = pStream->Write(this->c_str(), |
return (this->size() * sizeof(CT)) + sizeof(SSSHDR); |
|
this->size() * sizeof(CT), 0))) { |
|
|
TRACE(_T("StreamSave: Cannot write string to stream 0x%X\n"), hr); |
|
3769 |
} |
} |
3770 |
|
|
3771 |
return hr; |
// ------------------------------------------------------------------------- |
3772 |
} |
// FUNCTION: StreamSave |
3773 |
|
// REMARKS: |
3774 |
|
// Saves this CStdString object to a COM IStream. |
3775 |
|
// ------------------------------------------------------------------------- |
3776 |
|
HRESULT StreamSave(IStream * pStream) const |
3777 |
|
{ |
3778 |
|
ASSERT(this->size() * sizeof(CT) < 0xffffffffUL - sizeof(SSSHDR)); |
3779 |
|
HRESULT hr = E_FAIL; |
3780 |
|
ASSERT(pStream != 0); |
3781 |
|
SSSHDR hdr; |
3782 |
|
hdr.byCtrl = sizeof(CT) == 2 ? SSSO_UNICODE : 0; |
3783 |
|
hdr.nChars = this->size(); |
3784 |
|
|
3785 |
|
|
3786 |
|
if (FAILED(hr = pStream->Write(&hdr, sizeof(SSSHDR), 0))) { |
3787 |
|
TRACE(_T("StreamSave: Cannot write control header, ERR=0x%X\n"), |
3788 |
|
hr); |
3789 |
|
} else if (empty()) { |
3790 |
|
; // nothing to write |
3791 |
|
} else if (FAILED(hr = pStream->Write(this->c_str(), |
3792 |
|
this->size() * sizeof(CT), 0))) { |
3793 |
|
TRACE(_T("StreamSave: Cannot write string to stream 0x%X\n"), hr); |
3794 |
|
} |
3795 |
|
|
3796 |
|
return hr; |
3797 |
|
} |
3798 |
|
|
3799 |
// ------------------------------------------------------------------------- |
|
3800 |
// FUNCTION: StreamLoad |
// ------------------------------------------------------------------------- |
3801 |
// REMARKS: |
// FUNCTION: StreamLoad |
3802 |
// This method loads the object from an IStream. |
// REMARKS: |
3803 |
// ------------------------------------------------------------------------- |
// This method loads the object from an IStream. |
3804 |
HRESULT StreamLoad(IStream * pStream) |
// ------------------------------------------------------------------------- |
3805 |
{ |
HRESULT StreamLoad(IStream * pStream) |
3806 |
ASSERT(pStream != 0); |
{ |
3807 |
SSSHDR hdr; |
ASSERT(pStream != 0); |
3808 |
HRESULT hr = E_FAIL; |
SSSHDR hdr; |
3809 |
|
HRESULT hr = E_FAIL; |
3810 |
if (FAILED(hr = pStream->Read(&hdr, sizeof(SSSHDR), 0))) { |
|
3811 |
TRACE(_T("StreamLoad: Cant read control header, ERR=0x%X\n"), hr); |
if (FAILED(hr = pStream->Read(&hdr, sizeof(SSSHDR), 0))) { |
3812 |
} |
TRACE(_T("StreamLoad: Cant read control header, ERR=0x%X\n"), hr); |
3813 |
else if (hdr.nChars > 0) { |
} else if (hdr.nChars > 0) { |
3814 |
ULONG nRead = 0; |
ULONG nRead = 0; |
3815 |
PMYSTR pMyBuf = BufferSet(hdr.nChars); |
PMYSTR pMyBuf = BufferSet(hdr.nChars); |
3816 |
|
|
3817 |
// If our character size matches the character size of the string |
// If our character size matches the character size of the string |
3818 |
// we're trying to read, then we can read it directly into our |
// we're trying to read, then we can read it directly into our |
3819 |
// buffer. Otherwise, we have to read into an intermediate buffer |
// buffer. Otherwise, we have to read into an intermediate buffer |
3820 |
// and convert. |
// and convert. |
3821 |
|
|
3822 |
if ((hdr.byCtrl & SSSO_UNICODE) != 0) { |
if ((hdr.byCtrl & SSSO_UNICODE) != 0) { |
3823 |
ULONG nBytes = hdr.nChars * sizeof(wchar_t); |
ULONG nBytes = hdr.nChars * sizeof(wchar_t); |
3824 |
if (sizeof(CT) == sizeof(wchar_t)) { |
if (sizeof(CT) == sizeof(wchar_t)) { |
3825 |
if (FAILED(hr = pStream->Read(pMyBuf, nBytes, &nRead))) |
if (FAILED(hr = pStream->Read(pMyBuf, nBytes, &nRead))) |
3826 |
TRACE(_T("StreamLoad: Cannot read string: 0x%X\n"), |
TRACE(_T("StreamLoad: Cannot read string: 0x%X\n"), |
3827 |
hr); |
hr); |
3828 |
} |
} else { |
3829 |
else { |
PWSTR pBufW = |
3830 |
PWSTR pBufW = |
reinterpret_cast < PWSTR > (_alloca((nBytes) + 1)); |
3831 |
reinterpret_cast < PWSTR > (_alloca((nBytes) + 1)); |
if (FAILED(hr = pStream->Read(pBufW, nBytes, &nRead))) |
3832 |
if (FAILED(hr = pStream->Read(pBufW, nBytes, &nRead))) |
TRACE(_T("StreamLoad: Cannot read string: 0x%X\n"), |
3833 |
TRACE(_T("StreamLoad: Cannot read string: 0x%X\n"), |
hr); |
3834 |
hr); |
else |
3835 |
else |
sscpy(pMyBuf, pBufW, hdr.nChars); |
3836 |
sscpy(pMyBuf, pBufW, hdr.nChars); |
} |
3837 |
} |
} else { |
3838 |
} |
ULONG nBytes = hdr.nChars * sizeof(char); |
3839 |
else { |
if (sizeof(CT) == sizeof(char)) { |
3840 |
ULONG nBytes = hdr.nChars * sizeof(char); |
if (FAILED(hr = pStream->Read(pMyBuf, nBytes, &nRead))) |
3841 |
if (sizeof(CT) == sizeof(char)) { |
TRACE(_T("StreamLoad: Cannot read string: 0x%X\n"), |
3842 |
if (FAILED(hr = pStream->Read(pMyBuf, nBytes, &nRead))) |
hr); |
3843 |
TRACE(_T("StreamLoad: Cannot read string: 0x%X\n"), |
} else { |
3844 |
hr); |
PSTR pBufA = reinterpret_cast < PSTR > (_alloca(nBytes)); |
3845 |
} |
if (FAILED(hr = pStream->Read(pBufA, hdr.nChars, &nRead))) |
3846 |
else { |
TRACE(_T("StreamLoad: Cannot read string: 0x%X\n"), |
3847 |
PSTR pBufA = reinterpret_cast < PSTR > (_alloca(nBytes)); |
hr); |
3848 |
if (FAILED(hr = pStream->Read(pBufA, hdr.nChars, &nRead))) |
else |
3849 |
TRACE(_T("StreamLoad: Cannot read string: 0x%X\n"), |
sscpy(pMyBuf, pBufA, hdr.nChars); |
3850 |
hr); |
} |
|
else |
|
|
sscpy(pMyBuf, pBufA, hdr.nChars); |
|
3851 |
} |
} |
3852 |
|
} else { |
3853 |
|
this->erase(); |
3854 |
} |
} |
3855 |
|
return hr; |
3856 |
} |
} |
|
else { |
|
|
this->erase(); |
|
|
} |
|
|
return hr; |
|
|
} |
|
3857 |
#endif // #ifdef SS_INC_COMDEF |
#endif // #ifdef SS_INC_COMDEF |
3858 |
|
|
3859 |
#ifndef SS_ANSI |
#ifndef SS_ANSI |
3860 |
|
|
3861 |
// SetResourceHandle/GetResourceHandle. In MFC builds, these map directly |
// SetResourceHandle/GetResourceHandle. In MFC builds, these map directly |
3862 |
// to AfxSetResourceHandle and AfxGetResourceHandle. In non-MFC builds they |
// to AfxSetResourceHandle and AfxGetResourceHandle. In non-MFC builds they |
3863 |
// point to a single static HINST so that those who call the member |
// point to a single static HINST so that those who call the member |
3864 |
// functions that take resource IDs can provide an alternate HINST of a DLL |
// functions that take resource IDs can provide an alternate HINST of a DLL |
3865 |
// to search. This is not exactly the list of HMODULES that MFC provides |
// to search. This is not exactly the list of HMODULES that MFC provides |
3866 |
// but it's better than nothing. |
// but it's better than nothing. |
3867 |
|
|
3868 |
#ifdef _MFC_VER |
#ifdef _MFC_VER |
3869 |
static void SetResourceHandle(HMODULE hNew) |
static void SetResourceHandle(HMODULE hNew) |
3870 |
{ |
{ |
3871 |
AfxSetResourceHandle(hNew); |
AfxSetResourceHandle(hNew); |
3872 |
} |
} |
3873 |
static HMODULE GetResourceHandle() |
static HMODULE GetResourceHandle() |
3874 |
{ |
{ |
3875 |
return AfxGetResourceHandle(); |
return AfxGetResourceHandle(); |
3876 |
} |
} |
3877 |
#else |
#else |
3878 |
static void SetResourceHandle(HMODULE hNew) |
static void SetResourceHandle(HMODULE hNew) |
3879 |
{ |
{ |
3880 |
SSResourceHandle() = hNew; |
SSResourceHandle() = hNew; |
3881 |
} |
} |
3882 |
static HMODULE GetResourceHandle() |
static HMODULE GetResourceHandle() |
3883 |
{ |
{ |
3884 |
return SSResourceHandle(); |
return SSResourceHandle(); |
3885 |
} |
} |
3886 |
#endif |
#endif |
3887 |
|
|
3888 |
#endif |
#endif |
3905 |
// SSDLLEXP (nothing, just #define it) extern |
// SSDLLEXP (nothing, just #define it) extern |
3906 |
// SSDLLSPEC __declspec(dllexport) __declspec(dllimport) |
// SSDLLSPEC __declspec(dllexport) __declspec(dllimport) |
3907 |
// |
// |
3908 |
// Note that these macros must be available to ALL clients who want to |
// Note that these macros must be available to ALL clients who want to |
3909 |
// link to the DLL and use the class. If they |
// link to the DLL and use the class. If they |
3910 |
// |
// |
3911 |
// A word of advice: Don't bother. |
// A word of advice: Don't bother. |
3912 |
// |
// |
4057 |
|
|
4058 |
#ifdef SS_SAFE_FORMAT |
#ifdef SS_SAFE_FORMAT |
4059 |
|
|
4060 |
template <> struct FmtArg <CStdStringA > |
template <> |
4061 |
|
struct FmtArg <CStdStringA > |
4062 |
{ |
{ |
4063 |
explicit FmtArg(const CStdStringA & arg):a_(arg) |
explicit FmtArg(const CStdStringA & arg):a_(arg) |
4064 |
{ |
{} |
|
} |
|
4065 |
PCSTR operator() () const |
PCSTR operator() () const |
4066 |
{ |
{ |
4067 |
return a_.c_str(); |
return a_.c_str(); |
4068 |
} |
} |
4069 |
const CStdStringA & a_; |
const CStdStringA & a_; |
4070 |
private: |
private: |
4071 |
FmtArg < CStdStringA > &operator=(const FmtArg < CStdStringA > &) |
FmtArg < CStdStringA > &operator=(const FmtArg < CStdStringA > &) |
4072 |
{ |
{ |
4073 |
return *this; |
return *this; |
4074 |
} |
} |
4075 |
}; |
}; |
4076 |
template <> struct FmtArg <CStdStringW > |
template <> |
4077 |
|
struct FmtArg <CStdStringW > |
4078 |
{ |
{ |
4079 |
explicit FmtArg(const CStdStringW & arg):a_(arg) |
explicit FmtArg(const CStdStringW & arg):a_(arg) |
4080 |
{ |
{} |
|
} |
|
4081 |
PCWSTR operator() () const |
PCWSTR operator() () const |
4082 |
{ |
{ |
4083 |
return a_.c_str(); |
return a_.c_str(); |
4084 |
} |
} |
4085 |
const CStdStringW & a_; |
const CStdStringW & a_; |
4086 |
private: |
private: |
4087 |
FmtArg < CStdStringW > &operator=(const FmtArg < CStdStringW > &) |
FmtArg < CStdStringW > &operator=(const FmtArg < CStdStringW > &) |
4088 |
{ |
{ |
4089 |
return *this; |
return *this; |
4090 |
} |
} |
4091 |
}; |
}; |
4092 |
|
|
4093 |
template <> struct FmtArg <std::string > |
template <> |
4094 |
|
struct FmtArg <std::string > |
4095 |
{ |
{ |
4096 |
explicit FmtArg(const std::string & arg):a_(arg) |
explicit FmtArg(const std::string & arg):a_(arg) |
4097 |
{ |
{} |
|
} |
|
4098 |
PCSTR operator() () const |
PCSTR operator() () const |
4099 |
{ |
{ |
4100 |
return a_.c_str(); |
return a_.c_str(); |
4101 |
} |
} |
4102 |
const std::string & a_; |
const std::string & a_; |
4103 |
private: |
private: |
4104 |
FmtArg < std::string > &operator=(const FmtArg < std::string > &) |
FmtArg < std::string > &operator=(const FmtArg < std::string > &) |
4105 |
{ |
{ |
4106 |
return *this; |
return *this; |
4107 |
} |
} |
4108 |
}; |
}; |
4109 |
template <> struct FmtArg <std::wstring > |
template <> |
4110 |
|
struct FmtArg <std::wstring > |
4111 |
{ |
{ |
4112 |
explicit FmtArg(const std::wstring & arg):a_(arg) |
explicit FmtArg(const std::wstring & arg):a_(arg) |
4113 |
{ |
{} |
|
} |
|
4114 |
PCWSTR operator() () const |
PCWSTR operator() () const |
4115 |
{ |
{ |
4116 |
return a_.c_str(); |
return a_.c_str(); |
4117 |
} |
} |
4118 |
const std::wstring & a_; |
const std::wstring & a_; |
4119 |
private: |
private: |
4120 |
FmtArg < std::wstring > &operator=(const FmtArg < std::wstring > &) |
FmtArg < std::wstring > &operator=(const FmtArg < std::wstring > &) |
4121 |
{ |
{ |
4122 |
return *this; |
return *this; |
4125 |
#endif // #ifdef SS_SAFEFORMAT |
#endif // #ifdef SS_SAFEFORMAT |
4126 |
|
|
4127 |
#ifndef SS_ANSI |
#ifndef SS_ANSI |
4128 |
// SSResourceHandle: our MFC-like resource handle |
// SSResourceHandle: our MFC-like resource handle |
4129 |
inline HMODULE & SSResourceHandle() |
inline HMODULE & SSResourceHandle() |
4130 |
{ |
{ |
4131 |
static HMODULE hModuleSS = GetModuleHandle(0); |
static HMODULE hModuleSS = GetModuleHandle(0); |
4234 |
|
|
4235 |
|
|
4236 |
#if defined(SS_WIN32) && !defined (SS_ANSI) |
#if defined(SS_WIN32) && !defined (SS_ANSI) |
4237 |
// ------------------------------------------------------------------------- |
// ------------------------------------------------------------------------- |
4238 |
// FUNCTION: WUSysMessage |
// FUNCTION: WUSysMessage |
4239 |
// CStdStringA WUSysMessageA(DWORD dwError, DWORD dwLangId=SS_DEFLANGID); |
// CStdStringA WUSysMessageA(DWORD dwError, DWORD dwLangId=SS_DEFLANGID); |
4240 |
// CStdStringW WUSysMessageW(DWORD dwError, DWORD dwLangId=SS_DEFLANGID); |
// CStdStringW WUSysMessageW(DWORD dwError, DWORD dwLangId=SS_DEFLANGID); |
4241 |
// |
// |
4242 |
// DESCRIPTION: |
// DESCRIPTION: |
4243 |
// This function simplifies the process of obtaining a string equivalent |
// This function simplifies the process of obtaining a string equivalent |
4244 |
// of a system error code returned from GetLastError(). You simply |
// of a system error code returned from GetLastError(). You simply |
4245 |
// supply the value returned by GetLastError() to this function and the |
// supply the value returned by GetLastError() to this function and the |
4246 |
// corresponding system string is returned in the form of a CStdStringA. |
// corresponding system string is returned in the form of a CStdStringA. |
4247 |
// |
// |
4248 |
// PARAMETERS: |
// PARAMETERS: |
4249 |
// dwError - a DWORD value representing the error code to be translated |
// dwError - a DWORD value representing the error code to be translated |
4250 |
// dwLangId - the language id to use. defaults to english. |
// dwLangId - the language id to use. defaults to english. |
4251 |
// |
// |
4252 |
// RETURN VALUE: |
// RETURN VALUE: |
4253 |
// a CStdStringA equivalent of the error code. Currently, this function |
// a CStdStringA equivalent of the error code. Currently, this function |
4254 |
// only returns either English of the system default language strings. |
// only returns either English of the system default language strings. |
4255 |
// ------------------------------------------------------------------------- |
// ------------------------------------------------------------------------- |
4256 |
#define SS_DEFLANGID MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT) |
#define SS_DEFLANGID MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT) |
4257 |
inline CStdStringA WUSysMessageA(DWORD dwError, DWORD dwLangId = SS_DEFLANGID) |
inline CStdStringA WUSysMessageA(DWORD dwError, DWORD dwLangId = SS_DEFLANGID) |
4258 |
{ |
{ |
4279 |
// Define TCHAR based friendly names for some of these functions |
// Define TCHAR based friendly names for some of these functions |
4280 |
|
|
4281 |
#ifdef UNICODE |
#ifdef UNICODE |
4282 |
//#define CStdString CStdStringW |
//#define CStdString CStdStringW |
4283 |
typedef CStdStringW CStdString; |
typedef CStdStringW CStdString; |
4284 |
#define WUSysMessage WUSysMessageW |
#define WUSysMessage WUSysMessageW |
4285 |
#define WUFormat WUFormatW |
#define WUFormat WUFormatW |
4286 |
#else |
#else |
4287 |
//#define CStdString CStdStringA |
//#define CStdString CStdStringA |
4288 |
typedef CStdStringA CStdString; |
typedef CStdStringA CStdString; |
4289 |
#define WUSysMessage WUSysMessageA |
#define WUSysMessage WUSysMessageA |
4290 |
#define WUFormat WUFormatA |
#define WUFormat WUFormatA |
4326 |
#endif |
#endif |
4327 |
|
|
4328 |
struct StdStringLessNoCaseW:std::binary_function < CStdStringW, CStdStringW, |
struct StdStringLessNoCaseW:std::binary_function < CStdStringW, CStdStringW, |
4329 |
bool > |
bool > |
4330 |
{ |
{ |
4331 |
inline |
inline |
4332 |
bool operator() (const CStdStringW & sLeft, |
bool operator() (const CStdStringW & sLeft, |
4333 |
const CStdStringW & sRight) const |
const CStdStringW & sRight) const |
4334 |
{ |
{ |
4335 |
return ssicmp(sLeft.c_str(), sRight.c_str()) < 0; |
return ssicmp(sLeft.c_str(), sRight.c_str()) < 0; |
4336 |
} |
} |
4337 |
}; |
}; |
4338 |
struct StdStringEqualsNoCaseW:std::binary_function < CStdStringW, CStdStringW, |
struct StdStringEqualsNoCaseW:std::binary_function < CStdStringW, CStdStringW, |
4339 |
bool > |
bool > |
4340 |
{ |
{ |
4341 |
inline |
inline |
4342 |
bool operator() (const CStdStringW & sLeft, |
bool operator() (const CStdStringW & sLeft, |
4343 |
const CStdStringW & sRight) const |
const CStdStringW & sRight) const |
4344 |
{ |
{ |
4345 |
return ssicmp(sLeft.c_str(), sRight.c_str()) == 0; |
return ssicmp(sLeft.c_str(), sRight.c_str()) == 0; |
4346 |
} |
} |
4347 |
}; |
}; |
4348 |
struct StdStringLessNoCaseA:std::binary_function < CStdStringA, CStdStringA, |
struct StdStringLessNoCaseA:std::binary_function < CStdStringA, CStdStringA, |
4349 |
bool > |
bool > |
4350 |
{ |
{ |
4351 |
inline |
inline |
4352 |
bool operator() (const CStdStringA & sLeft, |
bool operator() (const CStdStringA & sLeft, |
4353 |
const CStdStringA & sRight) const |
const CStdStringA & sRight) const |
4354 |
{ |
{ |
4355 |
return ssicmp(sLeft.c_str(), sRight.c_str()) < 0; |
return ssicmp(sLeft.c_str(), sRight.c_str()) < 0; |
4356 |
} |
} |
4357 |
}; |
}; |
4358 |
struct StdStringEqualsNoCaseA:std::binary_function < CStdStringA, CStdStringA, |
struct StdStringEqualsNoCaseA:std::binary_function < CStdStringA, CStdStringA, |
4359 |
bool > |
bool > |
4360 |
{ |
{ |
4361 |
inline |
inline |
4362 |
bool operator() (const CStdStringA & sLeft, |
bool operator() (const CStdStringA & sLeft, |
4363 |
const CStdStringA & sRight) const |
const CStdStringA & sRight) const |
4364 |
{ |
{ |
4365 |
return ssicmp(sLeft.c_str(), sRight.c_str()) == 0; |
return ssicmp(sLeft.c_str(), sRight.c_str()) == 0; |
4366 |
} |
} |
4374 |
#endif |
#endif |
4375 |
|
|
4376 |
|
|
4377 |
// These std::swap specializations come courtesy of Mike Crusader. |
// These std::swap specializations come courtesy of Mike Crusader. |
4378 |
|
|
4379 |
//namespace std |
//namespace std |
4380 |
//{ |
//{ |