📄 stdstring.h
字号:
// =============================================================================
// FILE: StdString.h
// AUTHOR: Joe O'Leary (with outside help noted in comments)
// REMARKS:
// This header file declares the CStdStr template. This template derives
// the Standard C++ Library basic_string<> template and add to it the
// the following conveniences:
// - The full MFC CString set of functions (including implicit cast)
// - writing to/reading from COM IStream interfaces
// - Functional objects for use in STL algorithms
//
// From this template, we intstantiate two classes: CStdStringA and
// CStdStringW. The name "CStdString" is just a #define of one of these,
// based upone the _UNICODE macro setting
//
// This header also declares our own version of the MFC/ATL UNICODE-MBCS
// conversion macros. Our version looks exactly like the Microsoft's to
// facilitate portability.
//
// NOTE:
// If you you use this in an MFC or ATL build, you should include either
// afx.h or atlbase.h first, as appropriate.
//
// PEOPLE WHO HAVE CONTRIBUTED TO THIS CLASS:
//
// Several people have helped me iron out problems and othewise improve
// this class. OK, this is a long list but in my own defense, this code
// has undergone two major rewrites. Many of the improvements became
// necessary after I rewrote the code as a template. Others helped me
// improve the CString facade.
//
// Anyway, these people are (in chronological order):
//
// - Pete the Plumber (???)
// - Julian Selman
// - Chris (of Melbsys)
// - Dave Plummer
// - John C Sipos
// - Chris Sells
// - Nigel Nunn
// - Fan Xia
// - Matthew Williams
// - Carl Engman
// - Mark Zeren
// - Craig Watson
// - Rich Zuris
// - Karim Ratib
// - Chris Conti
// - Baptiste Lepilleur
// - Greg Pickles
// - Jim Cline
// - Jeff Kohn
// - Todd Heckel
// - Ullrich Poll鋒ne
// - Joe Vitaterna
// - Joe Woodbury
// - Aaron (no last name)
// - Joldakowski (???)
// - Scott Hathaway
// - Eric Nitzche
// - Pablo Presedo
// - Farrokh Nejadlotfi
// - Jason Mills
// - Igor Kholodov
// - Mike Crusader
// - John James
// - Wang Haifeng
// - Tim Dowty
// - Arnt Witteveen
// - Glen Maynard
// - Paul DeMarco
//
// REVISION HISTORY
// 2002-OCT-21 - Many thanks to Paul DeMarco who was invaluable in helping me
// get this code working with Borland's free compiler as well
// as the Dev-C++ compiler (available free at SourceForge).
//
// 2002-SEP-13 - Thanks to Glen Maynard who helped me get rid of some loud
// but harmless warnings that were showing up on g++. Glen
// also pointed out that some pre-declarations of FmtArg<>
// specializations were unnecessary (and no good on G++)
//
// 2002-JUN-26 - Thanks to Arnt Witteveen for pointing out that I was using
// static_cast<> in a place in which I should have been using
// reinterpret_cast<> (the ctor for unsigned char strings).
// That's what happens when I don't unit-test properly!
// Arnt also noticed that CString was silently correcting the
// 'nCount' argument to Left() and Right() where CStdString was
// not (and crashing if it was bad). That is also now fixed!
//
// 2002-FEB-25 - Thanks to Tim Dowty for pointing out (and giving me the fix
// for) a conversion problem with non-ASCII MBCS characters.
// CStdString is now used in my favorite commercial MP3 player!
//
// 2001-DEC-06 - Thanks to Wang Haifeng for spotting a problem in one of the
// assignment operators (for _bstr_t) that would cause compiler
// errors when refcounting protection was turned off.
//
// 2001-NOV-27 - Remove calls to operator!= which involve reverse_iterators
// due to a conflict with the rel_ops operator!=. Thanks to
// John James for pointing this out.
//
// 2001-OCT-29 - Added a minor range checking fix for the Mid function to
// make it as forgiving as CString's version is. Thanks to
// Igor Kholodov for noticing this.
// - Added a specialization of std::swap for CStdString. Thanks
// to Mike Crusader for suggesting this! It's commented out
// because you're not supposed to inject your own code into the
// 'std' namespace. But if you don't care about that, it's
// there if you want it
// - Thanks to Jason Mills for catching a case where CString was
// more forgiving in the Delete() function than I was.
//
// 2001-JUN-06 - I was violating the Standard name lookup rules stated
// in [14.6.2(3)]. None of the compilers I've tried so
// far apparently caught this but HP-UX aCC 3.30 did. The
// fix was to add 'this->' prefixes in many places.
// Thanks to Farrokh Nejadlotfi for this!
//
// 2001-APR-27 - StreamLoad was calculating the number of BYTES in one
// case, not characters. Thanks to Pablo Presedo for this.
//
// 2001-FEB-23 - Replace() had a bug which caused infinite loops if the
// source string was empty. Fixed thanks to Eric Nitzsche.
//
// 2001-FEB-23 - Scott Hathaway was a huge help in providing me with the
// ability to build CStdString on Sun Unix systems. He
// sent me detailed build reports about what works and what
// does not. If CStdString compiles on your Unix box, you
// can thank Scott for it.
//
// 2000-DEC-29 - Joldakowski noticed one overload of Insert failed to do a
// range check as CString's does. Now fixed -- thanks!
//
// 2000-NOV-07 - Aaron pointed out that I was calling static member
// functions of char_traits via a temporary. This was not
// technically wrong, but it was unnecessary and caused
// problems for poor old buggy VC5. Thanks Aaron!
//
// 2000-JUL-11 - Joe Woodbury noted that the CString::Find docs don't match
// what the CString::Find code really ends up doing. I was
// trying to match the docs. Now I match the CString code
// - Joe also caught me truncating strings for GetBuffer() calls
// when the supplied length was less than the current length.
//
// 2000-MAY-25 - Better support for STLPORT's Standard library distribution
// - Got rid of the NSP macro - it interfered with Koenig lookup
// - Thanks to Joe Woodbury for catching a TrimLeft() bug that
// I introduced in January. Empty strings were not getting
// trimmed
//
// 2000-APR-17 - Thanks to Joe Vitaterna for pointing out that ReverseFind
// is supposed to be a const function.
//
// 2000-MAR-07 - Thanks to Ullrich Poll鋒ne for catching a range bug in one
// of the overloads of assign.
//
// 2000-FEB-01 - You can now use CStdString on the Mac with CodeWarrior!
// Thanks to Todd Heckel for helping out with this.
//
// 2000-JAN-23 - Thanks to Jim Cline for pointing out how I could make the
// Trim() function more efficient.
// - Thanks to Jeff Kohn for prompting me to find and fix a typo
// in one of the addition operators that takes _bstr_t.
// - Got rid of the .CPP file - you only need StdString.h now!
//
// 1999-DEC-22 - Thanks to Greg Pickles for helping me identify a problem
// with my implementation of CStdString::FormatV in which
// resulting string might not be properly NULL terminated.
//
// 1999-DEC-06 - Chris Conti pointed yet another basic_string<> assignment
// bug that MS has not fixed. CStdString did nothing to fix
// it either but it does now! The bug was: create a string
// longer than 31 characters, get a pointer to it (via c_str())
// and then assign that pointer to the original string object.
// The resulting string would be empty. Not with CStdString!
//
// 1999-OCT-06 - BufferSet was erasing the string even when it was merely
// supposed to shrink it. Fixed. Thanks to Chris Conti.
// - Some of the Q172398 fixes were not checking for assignment-
// to-self. Fixed. Thanks to Baptiste Lepilleur.
//
// 1999-AUG-20 - Improved Load() function to be more efficient by using
// SizeOfResource(). Thanks to Rich Zuris for this.
// - Corrected resource ID constructor, again thanks to Rich.
// - Fixed a bug that occurred with UNICODE characters above
// the first 255 ANSI ones. Thanks to Craig Watson.
// - Added missing overloads of TrimLeft() and TrimRight().
// Thanks to Karim Ratib for pointing them out
//
// 1999-JUL-21 - Made all calls to GetBuf() with no args check length first.
//
// 1999-JUL-10 - Improved MFC/ATL independence of conversion macros
// - Added SS_NO_REFCOUNT macro to allow you to disable any
// reference-counting your basic_string<> impl. may do.
// - Improved ReleaseBuffer() to be as forgiving as CString.
// Thanks for Fan Xia for helping me find this and to
// Matthew Williams for pointing it out directly.
//
// 1999-JUL-06 - Thanks to Nigel Nunn for catching a very sneaky bug in
// ToLower/ToUpper. They should call GetBuf() instead of
// data() in order to ensure the changed string buffer is not
// reference-counted (in those implementations that refcount).
//
// 1999-JUL-01 - Added a true CString facade. Now you can use CStdString as
// a drop-in replacement for CString. If you find this useful,
// you can thank Chris Sells for finally convincing me to give
// in and implement it.
// - Changed operators << and >> (for MFC CArchive) to serialize
// EXACTLY as CString's do. So now you can send a CString out
// to a CArchive and later read it in as a CStdString. I have
// no idea why you would want to do this but you can.
//
// 1999-JUN-21 - Changed the CStdString class into the CStdStr template.
// - Fixed FormatV() to correctly decrement the loop counter.
// This was harmless bug but a bug nevertheless. Thanks to
// Chris (of Melbsys) for pointing it out
// - Changed Format() to try a normal stack-based array before
// using to _alloca().
// - Updated the text conversion macros to properly use code
// pages and to fit in better in MFC/ATL builds. In other
// words, I copied Microsoft's conversion stuff again.
// - Added equivalents of CString::GetBuffer, GetBufferSetLength
// - new sscpy() replacement of CStdString::CopyString()
// - a Trim() function that combines TrimRight() and TrimLeft().
//
// 1999-MAR-13 - Corrected the "NotSpace" functional object to use _istpace()
// instead of _isspace() Thanks to Dave Plummer for this.
//
// 1999-FEB-26 - Removed errant line (left over from testing) that #defined
// _MFC_VER. Thanks to John C Sipos for noticing this.
//
// 1999-FEB-03 - Fixed a bug in a rarely-used overload of operator+() that
// caused infinite recursion and stack overflow
// - Added member functions to simplify the process of
// persisting CStdStrings to/from DCOM IStream interfaces
// - Added functional objects (e.g. StdStringLessNoCase) that
// allow CStdStrings to be used as keys STL map objects with
// case-insensitive comparison
// - Added array indexing operators (i.e. operator[]). I
// originally assumed that these were unnecessary and would be
// inherited from basic_string. However, without them, Visual
// C++ complains about ambiguous overloads when you try to use
// them. Thanks to Julian Selman to pointing this out.
//
// 1998-FEB-?? - Added overloads of assign() function to completely account
// for Q172398 bug. Thanks to "Pete the Plumber" for this
//
// 1998-FEB-?? - Initial submission
//
// COPYRIGHT:
// 2002 Joseph M. O'Leary. This code is 100% free. Use it anywhere you
// want. Rewrite it, restructure it, whatever. If you can write software
// that makes money off of it, good for you. I kinda like capitalism.
// Please don't blame me if it causes your $30 billion dollar satellite
// explode in orbit. If you redistribute it in any form, I'd appreciate it
// if you would leave this notice here.
//
// If you find any bugs, please let me know:
//
// jmoleary@earthlink.net
// http://www.joeo.net/
//
// The latest version of this code is available at the following link:
// http://www.joeo.net/code/StdString.zip
// =============================================================================
// Avoid multiple inclusion the VC++ way,
// Turn off browser references
// Turn off unavoidable compiler warnings
#if defined(_MSC_VER) && (_MSC_VER > 1100)
#pragma once
#pragma component(browser, off, references, "CStdString")
#pragma warning (disable : 4290) // C++ Exception Specification ignored
#pragma warning (disable : 4127) // Conditional expression is constant
#pragma warning (disable : 4097) // typedef name used as synonym for class name
#endif
// Borland warnings to turn off
#ifdef __BORLANDC__
#pragma option push -w-inl
// #pragma warn -inl // Turn off inline function warnings
#endif
#ifndef STDSTRING_H
#define STDSTRING_H
// MACRO: SS_NO_LOCALE
// -------------------
// This macro prevents the CStdString code from using the <locale> header
// of the Standard C++ Library. It is a hack plain and simple and was
// added to get around some problems that people using older versions of
// g++ were having. The proper solution is to upgrade your version of g++
// to 3.0 or later, but if you simply cannot do that and your compiler is
// having trouble with the header <locale>, then this macro MIGHT help you.
// You're on your own. I do not recommend using this except as a last
// resort. Eventually I'm going to get rid of it.
//#define SS_NO_LOCALE
// MACRO: SS_UNSIGNED
// ------------------
// This macro causes the addition of a constructor and assignment operator
// which take unsigned characters. CString has such functions and in order
// to provide maximum CString-compatability, this code needs them as well.
// In practice you will likely never need these functions...
//#define SS_UNSIGNED
// MACRO: SS_SAFE_FORMAT
// ---------------------
// This macro provides limited compatability with a questionable CString
// "feature". You can define it in order to avoid a common problem that
// people encounter when switching from CString to CStdString.
//
// To illustrate the problem -- With CString, you can do this:
//
// CString sName("Joe");
// CString sTmp;
// sTmp.Format("My name is %s", sName); // WORKS!
//
// However if you were to try this with CStdString, your program would
// crash.
//
// CStdString sName("Joe");
// CStdString sTmp;
// sTmp.Format("My name is %s", sName); // CRASHES!
//
// You must explicitly call c_str() or cast the object to the proper type
//
// sTmp.Format("My name is %s", sName.c_str()); // WORKS!
// sTmp.Format("My name is %s", static_cast<PCSTR>(sName));// WORKS!
// sTmp.Format("My name is %s", (PCSTR)sName);// WORKS!
//
// This is because it is illegal to pass anything but a POD type as a
// variadic argument to a variadic function (i.e. as one of the "..."
// arguments). The type const char* is a POD type. The type CStdString
// is not. Of course, neither is the type CString, but CString lets you do
// it anyway due to the way they laid out the class in binary. I have no
// control over this in CStdString since I derive from whatever
// implementation of basic_string is available.
//
// However if you have legacy code (which does this) that you want to take
// out of the MFC world and you don't want to rewrite all your calls to
// Format(), then you can define this flag and it will no longer crash.
//
// Note however that this ONLY works for Format(), not sprintf, fprintf,
// etc. If you pass a CStdString object to one of those functions, your
// program will crash. Not much I can do to get around this, short of
// writing substitutes for those functions as well.
#define SS_SAFE_FORMAT // use new template style Format() function
// MACRO: SS_NO_IMPLICIT_CAST
// --------------------------
// Some people don't like the implicit cast to const char* (or rather to
// const CT*) that CStdString (and MFC's CString) provide. That was the
// whole reason I created this class in the first place, but hey, whatever
// bakes your cake. Just #define this macro to get rid of the the implicit
// cast.
//#define SS_NO_IMPLICIT_CAST // gets rid of operator const CT*()
// MACRO: SS_NO_REFCOUNT
// ---------------------
// turns off reference counting at the assignment level. Only needed
// for the version of basic_string<> that comes with Visual C++ versions
// 6.0 or earlier, and only then in some heavily multithreaded scenarios.
// Uncomment it if you feel you need it.
//#define SS_NO_REFCOUNT
// MACRO: SS_WIN32
// ---------------
// When this flag is set, we are building code for the Win32 platform and
// may use Win32 specific functions (such as LoadString). This gives us
// a couple of nice extras for the code.
//
// Obviously, Microsoft's is not the only compiler available for Win32 out
// there. So I can't just check to see if _MSC_VER is defined to detect
// if I'm building on Win32. So for now, if you use MS Visual C++ or
// Borland's compiler, I turn this on. Otherwise you may turn it on
// yourself, if you prefer
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WIN32)
#define SS_WIN32
#endif
// MACRO: SS_ANSI
// --------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -