//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1997. // // File: N C S T L S T R . H // // Contents: STL string class renamed so as to remove our dependance // from msvcp50.dll. // // Notes: // // Author: shaunco 12 Apr 1998 // //---------------------------------------------------------------------------- #pragma once #ifndef _NCSTLSTR_H_ #define _NCSTLSTR_H_ #include #include #include #include #include "ncdebug.h" using namespace std; //template, //class _A = allocator<_E> > struct wchar_traits { typedef wchar_t _E; typedef _E char_type; // for overloads typedef wint_t int_type; typedef mbstate_t state_type; static void __cdecl assign(_E& _X, const _E& _Y) { _X = _Y; } static bool __cdecl eq(const _E& _X, const _E& _Y) { return (_X == _Y); } static bool __cdecl lt(const _E& _X, const _E& _Y) { return (_X < _Y); } static int __cdecl compare(const _E *_U, const _E *_V, size_t _N) { return (wmemcmp(_U, _V, _N)); } static size_t __cdecl length(const _E *_U) { return (wcslen(_U)); } static _E *__cdecl copy(_E *_U, const _E *_V, size_t _N) { return (wmemcpy(_U, _V, _N)); } static const _E * __cdecl find(const _E *_U, size_t _N, const _E& _C) { return ((const _E *)wmemchr(_U, _C, _N)); } static _E * __cdecl move(_E *_U, const _E *_V, size_t _N) { return (wmemmove(_U, _V, _N)); } static _E * __cdecl assign(_E *_U, size_t _N, const _E& _C) { return (wmemset(_U, _C, _N)); } static _E __cdecl to_char_type(const int_type& _C) { return (_C); } static int_type __cdecl to_int_type(const _E& _C) { return (_C); } static bool __cdecl eq_int_type(const int_type& _X, const int_type& _Y) { return (_X == _Y); } static int_type __cdecl eof() { return (WEOF); } static int_type __cdecl not_eof(const int_type& _C) { return (_C != eof() ? _C : !eof()); } }; class CWideString { public: typedef CWideString _Myt; typedef wchar_traits _Tr; typedef _Tr::_E _E; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef _E* pointer; typedef const _E* const_pointer; typedef _E& reference; typedef const _E& const_reference; typedef _E value_type; typedef pointer iterator; typedef const_pointer const_iterator; typedef reverse_iterator const_reverse_iterator; typedef reverse_iterator reverse_iterator; typedef const_iterator _It; explicit CWideString() { _Tidy(); } CWideString(const _Myt& _X) { _Tidy(), assign(_X, 0, npos); } CWideString(const _Myt& _X, size_type _P, size_type _M) { _Tidy(), assign(_X, _P, _M); } CWideString(const _E *_S, size_type _N) { _Tidy(), assign(_S, _N); } CWideString(const _E *_S) { _Tidy(), assign(_S); } CWideString(size_type _N, _E _C) { _Tidy(), assign(_N, _C); } CWideString(_It _F, _It _L) { _Tidy(); assign(_F, _L); } ~CWideString() { _Tidy(true); } enum _Mref { _FROZEN = USHRT_MAX }; enum _Npos { // -1 is not arbitrary. It is chosen because it works in math // operations. npos is treated as size_type and is inolved in // arithmetic. // npos = -1 }; _Myt& operator=(const _Myt& _X) { return (assign(_X)); } _Myt& operator=(const _E *_S) { return (assign(_S)); } _Myt& operator=(_E _C) { return (assign(1, _C)); } _Myt& operator+=(const _Myt& _X) { return (append(_X)); } _Myt& operator+=(const _E *_S) { return (append(_S)); } _Myt& operator+=(_E _C) { return (append(1, _C)); } _Myt& append(const _Myt& _X) { return (append(_X, 0, npos)); } _Myt& append(const _Myt& _X, size_type _P, size_type _M) { AssertH (_X.size() >= _P); //if (_X.size() < _P) // _Xran(); size_type _N = _X.size() - _P; if (_N < _M) _M = _N; AssertH ((_Len + _M < npos)); //if (npos - _Len <= _M) // _Xlen(); if (0 < _M && _Grow(_N = _Len + _M)) { _Tr::copy(_Ptr + _Len, &_X.c_str()[_P], _M); _Eos(_N); } return (*this); } _Myt& append(const _E *_S, size_type _M) { AssertH ((_Len + _M < npos)); //if (npos - _Len <= _M) // _Xlen(); size_type _N; if (0 < _M && _Grow(_N = _Len + _M)) { _Tr::copy(_Ptr + _Len, _S, _M); _Eos(_N); } return (*this); } _Myt& append(const _E *_S) { return (append(_S, _Tr::length(_S))); } _Myt& append(size_type _M, _E _C) { AssertH ((_Len + _M < npos)); //if (npos - _Len <= _M) // _Xlen(); size_type _N; if (0 < _M && _Grow(_N = _Len + _M)) { _Tr::assign(_Ptr + _Len, _M, _C); _Eos(_N); } return (*this); } _Myt& append(_It _F, _It _L) { return (replace(end(), end(), _F, _L)); } _Myt& assign(const _Myt& _X) { return (assign(_X, 0, npos)); } _Myt& assign(const _Myt& _X, size_type _P, size_type _M) { AssertH (_X.size() >= _P); //if (_X.size() < _P) // _Xran(); size_type _N = _X.size() - _P; if (_M < _N) _N = _M; if (this == &_X) { erase((size_type)(_P + _N)), erase(0, _P); } else if (0 < _N && _N == _X.size() && _Refcnt(_X.c_str()) < _FROZEN - 1) { _Tidy(true); _Ptr = (_E *)_X.c_str(); _Len = _X.size(); _Res = _X.capacity(); ++_Refcnt(_Ptr); } else if (_Grow(_N, true)) { _Tr::copy(_Ptr, &_X.c_str()[_P], _N); _Eos(_N); } return (*this); } _Myt& assign(const _E *_S, size_type _N) { if (_Grow(_N)) { _Tr::copy(_Ptr, _S, _N); _Eos(_N); } return (*this); } _Myt& assign(const _E *_S) { return (assign(_S, _Tr::length(_S))); } _Myt& assignSafe(const _E *_S) { return (_S) ? assign(_S, _Tr::length(_S)) : erase(); } _Myt& assign(size_type _N, _E _C) { AssertH (npos != _N); //if (_N == npos) // _Xlen(); if (_Grow(_N)) { _Tr::assign(_Ptr, _N, _C); _Eos(_N); } return (*this); } _Myt& assign(_It _F, _It _L) { return (replace(begin(), end(), _F, _L)); } _Myt& insert(size_type _P0, const _Myt& _X) { return (insert(_P0, _X, 0, npos)); } _Myt& insert(size_type _P0, const _Myt& _X, size_type _P, size_type _M) { AssertH ((_Len >= _P0) && (_X.size() >= _P)); //if (_Len < _P0 || _X.size() < _P) // _Xran(); size_type _N = _X.size() - _P; if (_N < _M) _M = _N; AssertH ((_Len + _M < npos)); //if (npos - _Len <= _M) // _Xlen(); if (0 < _M && _Grow(_N = _Len + _M)) { _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0, _Len - _P0); _Tr::copy(_Ptr + _P0, &_X.c_str()[_P], _M); _Eos(_N); } return (*this); } _Myt& insert(size_type _P0, const _E *_S, size_type _M) { AssertH (_Len >= _P0); //if (_Len < _P0) // _Xran(); AssertH ((_Len + _M < npos)); //if (npos - _Len <= _M) // _Xlen(); size_type _N; if (0 < _M && _Grow(_N = _Len + _M)) { _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0, _Len - _P0); _Tr::copy(_Ptr + _P0, _S, _M); _Eos(_N); } return (*this); } _Myt& insert(size_type _P0, const _E *_S) { return (insert(_P0, _S, _Tr::length(_S))); } _Myt& insert(size_type _P0, size_type _M, _E _C) { AssertH (_Len >= _P0); //if (_Len < _P0) // _Xran(); AssertH ((_Len + _M < npos)); //if (npos - _Len <= _M) // _Xlen(); size_type _N; if (0 < _M && _Grow(_N = _Len + _M)) { _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0, _Len - _P0); _Tr::assign(_Ptr + _P0, _M, _C); _Eos(_N); } return (*this); } iterator insert(iterator _P, _E _C) { size_type _P0 = _Pdif(_P, begin()); insert(_P0, 1, _C); return (begin() + _P0); } void insert(iterator _P, size_type _M, _E _C) { size_type _P0 = _Pdif(_P, begin()); insert(_P0, _M, _C); } void insert(iterator _P, _It _F, _It _L) { replace(_P, _P, _F, _L); } _Myt& erase(size_type _P0 = 0, size_type _M = npos) { AssertH (_Len >= _P0); //if (_Len < _P0) // _Xran(); _Split(); if (_Len - _P0 < _M) _M = _Len - _P0; if (0 < _M) { _Tr::move(_Ptr + _P0, _Ptr + _P0 + _M, _Len - _P0 - _M); size_type _N = _Len - _M; if (_Grow(_N)) _Eos(_N); } return (*this); } iterator erase(iterator _P) { size_t _M = _Pdif(_P, begin()); erase(_M, 1); return (_Psum(_Ptr, _M)); } iterator erase(iterator _F, iterator _L) { size_t _M = _Pdif(_F, begin()); erase(_M, _Pdif(_L, _F)); return (_Psum(_Ptr, _M)); } _Myt& replace(size_type _P0, size_type _N0, const _Myt& _X) { return (replace(_P0, _N0, _X, 0, npos)); } _Myt& replace(size_type _P0, size_type _N0, const _Myt& _X, size_type _P, size_type _M) { AssertH ((_Len >= _P0) && (_X.size() >= _P)); //if (_Len < _P0 || _X.size() < _P) // _Xran(); if (_Len - _P0 < _N0) _N0 = _Len - _P0; size_type _N = _X.size() - _P; if (_N < _M) _M = _N; AssertH (npos - _M > _Len - _N0); //if (npos - _M <= _Len - _N0) // _Xlen(); _Split(); size_type _Nm = _Len - _N0 - _P0; if (_M < _N0) _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0 + _N0, _Nm); if ((0 < _M || 0 < _N0) && _Grow(_N = _Len + _M - _N0)) { if (_N0 < _M) _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0 + _N0, _Nm); _Tr::copy(_Ptr + _P0, &_X.c_str()[_P], _M); _Eos(_N); } return (*this); } _Myt& replace(size_type _P0, size_type _N0, const _E *_S, size_type _M) { AssertH (_Len >= _P0); //if (_Len < _P0) // _Xran(); if (_Len - _P0 < _N0) _N0 = _Len - _P0; AssertH (npos - _M > _Len - _N0); //if (npos - _M <= _Len - _N0) // _Xlen(); _Split(); size_type _Nm = _Len - _N0 - _P0; if (_M < _N0) _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0 + _N0, _Nm); size_type _N; if ((0 < _M || 0 < _N0) && _Grow(_N = _Len + _M - _N0)) { if (_N0 < _M) _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0 + _N0, _Nm); _Tr::copy(_Ptr + _P0, _S, _M); _Eos(_N); } return (*this); } _Myt& replace(size_type _P0, size_type _N0, const _E *_S) { return (replace(_P0, _N0, _S, _Tr::length(_S))); } _Myt& replace(size_type _P0, size_type _N0, size_type _M, _E _C) { AssertH (_Len >= _P0); //if (_Len < _P0) // _Xran(); if (_Len - _P0 < _N0) _N0 = _Len - _P0; AssertH (npos - _M > _Len - _N0); //if (npos - _M <= _Len - _N0) // _Xlen(); _Split(); size_type _Nm = _Len - _N0 - _P0; if (_M < _N0) _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0 + _N0, _Nm); size_type _N; if ((0 < _M || 0 < _N0) && _Grow(_N = _Len + _M - _N0)) { if (_N0 < _M) _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0 + _N0, _Nm); _Tr::assign(_Ptr + _P0, _M, _C); _Eos(_N); } return (*this); } _Myt& replace(iterator _F, iterator _L, const _Myt& _X) { return (replace(_Pdif(_F, begin()), _Pdif(_L, _F), _X)); } _Myt& replace(iterator _F, iterator _L, const _E *_S, size_type _M) { return (replace(_Pdif(_F, begin()), _Pdif(_L, _F), _S, _M)); } _Myt& replace(iterator _F, iterator _L, const _E *_S) { return (replace(_Pdif(_F, begin()), _Pdif(_L, _F), _S)); } _Myt& replace(iterator _F, iterator _L, size_type _M, _E _C) { return (replace(_Pdif(_F, begin()), _Pdif(_L, _F), _M, _C)); } _Myt& replace(iterator _F1, iterator _L1, _It _F2, _It _L2) { size_type _P0 = _Pdif(_F1, begin()); size_type _M = 0; _Distance(_F2, _L2, _M); replace(_P0, _Pdif(_L1, _F1), _M, _E(0)); for (_F1 = begin() + _P0; 0 < _M; ++_F1, ++_F2, --_M) *_F1 = *_F2; return (*this); } iterator begin() { _Freeze(); return (_Ptr); } const_iterator begin() const { return (_Ptr); } iterator end() { _Freeze(); return ((iterator)_Psum(_Ptr, _Len)); } const_iterator end() const { return ((const_iterator)_Psum(_Ptr, _Len)); } reverse_iterator rbegin() { return (reverse_iterator(end())); } const_reverse_iterator rbegin() const { return (const_reverse_iterator(end())); } reverse_iterator rend() { return (reverse_iterator(begin())); } const_reverse_iterator rend() const { return (const_reverse_iterator(begin())); } reference at(size_type _P0) { AssertH (_Len > _P0); //if (_Len <= _P0) // _Xran(); _Freeze(); return (_Ptr[_P0]); } const_reference at(size_type _P0) const { AssertH (_Len > _P0); //if (_Len <= _P0) // _Xran(); return (_Ptr[_P0]); } reference operator[](size_type _P0) { if (_Len < _P0 || _Ptr == 0) return ((reference)*_Nullstr()); _Freeze(); return (_Ptr[_P0]); } const_reference operator[](size_type _P0) const { if (_Ptr == 0) return (*_Nullstr()); else return (_Ptr[_P0]); } const _E *c_str() const { return (_Ptr == 0 ? _Nullstr() : _Ptr); } const _E *data() const { return (c_str()); } size_type length() const { return (_Len); } size_type size() const { return (_Len); } void resize(size_type _N, _E _C) { _N <= _Len ? erase(_N) : append(_N - _Len, _C); } void resize(size_type _N) { _N <= _Len ? erase(_N) : append(_N - _Len, _E(0)); } size_type capacity() const { return (_Res); } void reserve(size_type _N = 0) { if (_Res < _N) _Grow(_N); } bool empty() const { return (_Len == 0); } size_type copy(_E *_S, size_type _N, size_type _P0 = 0) const { AssertH (_Len >= _P0); //if (_Len < _P0) // _Xran(); if (_Len - _P0 < _N) _N = _Len - _P0; if (0 < _N) _Tr::copy(_S, _Ptr + _P0, _N); return (_N); } void swap(_Myt& _X) { std::swap(_Ptr, _X._Ptr); std::swap(_Len, _X._Len); std::swap(_Res, _X._Res); } void swap(_Myt& _X, _Myt& _Y) { _X.swap(_Y); } size_type find(const _Myt& _X, size_type _P = 0) const { return (find(_X.c_str(), _P, _X.size())); } size_type find(const _E *_S, size_type _P, size_type _N) const { if (_N == 0 && _P <= _Len) return (_P); size_type _Nm; if (_P < _Len && _N <= (_Nm = _Len - _P)) { const _E *_U, *_V; for (_Nm -= _N - 1, _V = _Ptr + _P; (_U = _Tr::find(_V, _Nm, *_S)) != 0; _Nm -= (size_type)(_U - _V + 1), _V = _U + 1) if (_Tr::compare(_U, _S, _N) == 0) return (_U - _Ptr); } return (npos); } size_type find(const _E *_S, size_type _P = 0) const { return (find(_S, _P, _Tr::length(_S))); } size_type find(_E _C, size_type _P = 0) const { return (find((const _E *)&_C, _P, 1)); } size_type rfind(const _Myt& _X, size_type _P = npos) const { return (rfind(_X.c_str(), _P, _X.size())); } size_type rfind(const _E *_S, size_type _P, size_type _N) const { if (_N == 0) return (_P < _Len ? _P : _Len); if (_N <= _Len) for (const _E *_U = _Ptr + + (_P < _Len - _N ? _P : _Len - _N); ; --_U) if (_Tr::eq(*_U, *_S) && _Tr::compare(_U, _S, _N) == 0) return (_U - _Ptr); else if (_U == _Ptr) break; return (npos); } size_type rfind(const _E *_S, size_type _P = npos) const { return (rfind(_S, _P, _Tr::length(_S))); } size_type rfind(_E _C, size_type _P = npos) const { return (rfind((const _E *)&_C, _P, 1)); } size_type find_first_of(const _Myt& _X, size_type _P = 0) const { return (find_first_of(_X.c_str(), _P, _X.size())); } size_type find_first_of(const _E *_S, size_type _P, size_type _N) const { if (0 < _N && _P < _Len) { const _E *const _V = _Ptr + _Len; for (const _E *_U = _Ptr + _P; _U < _V; ++_U) if (_Tr::find(_S, _N, *_U) != 0) return (_U - _Ptr); } return (npos); } size_type find_first_of(const _E *_S, size_type _P = 0) const { return (find_first_of(_S, _P, _Tr::length(_S))); } size_type find_first_of(_E _C, size_type _P = 0) const { return (find((const _E *)&_C, _P, 1)); } size_type find_last_of(const _Myt& _X, size_type _P = npos) const { return (find_last_of(_X.c_str(), _P, _X.size())); } size_type find_last_of(const _E *_S, size_type _P, size_type _N) const { if (0 < _N && 0 < _Len) for (const _E *_U = _Ptr + (_P < _Len ? _P : _Len - 1); ; --_U) if (_Tr::find(_S, _N, *_U) != 0) return (_U - _Ptr); else if (_U == _Ptr) break; return (npos); } size_type find_last_of(const _E *_S, size_type _P = npos) const { return (find_last_of(_S, _P, _Tr::length(_S))); } size_type find_last_of(_E _C, size_type _P = npos) const { return (rfind((const _E *)&_C, _P, 1)); } size_type find_first_not_of(const _Myt& _X, size_type _P = 0) const { return (find_first_not_of(_X.c_str(), _P, _X.size())); } size_type find_first_not_of(const _E *_S, size_type _P, size_type _N) const { if (_P < _Len) { const _E *const _V = _Ptr + _Len; for (const _E *_U = _Ptr + _P; _U < _V; ++_U) if (_Tr::find(_S, _N, *_U) == 0) return (_U - _Ptr); } return (npos); } size_type find_first_not_of(const _E *_S, size_type _P = 0) const { return (find_first_not_of(_S, _P, _Tr::length(_S))); } size_type find_first_not_of(_E _C, size_type _P = 0) const { return (find_first_not_of((const _E *)&_C, _P, 1)); } size_type find_last_not_of(const _Myt& _X, size_type _P = npos) const { return (find_last_not_of(_X.c_str(), _P, _X.size())); } size_type find_last_not_of(const _E *_S, size_type _P, size_type _N) const { if (0 < _Len) for (const _E *_U = _Ptr + (_P < _Len ? _P : _Len - 1); ; --_U) if (_Tr::find(_S, _N, *_U) == 0) return (_U - _Ptr); else if (_U == _Ptr) break; return (npos); } size_type find_last_not_of(const _E *_S, size_type _P = npos) const { return (find_last_not_of(_S, _P, _Tr::length(_S))); } size_type find_last_not_of(_E _C, size_type _P = npos) const { return (find_last_not_of((const _E *)&_C, _P, 1)); } _Myt substr(size_type _P = 0, size_type _M = npos) const { return (_Myt(*this, _P, _M)); } int compare(const _Myt& _X) const { return (compare(0, _Len, _X.c_str(), _X.size())); } int compare(size_type _P0, size_type _N0, const _Myt& _X) const { return (compare(_P0, _N0, _X, 0, npos)); } int compare(size_type _P0, size_type _N0, const _Myt& _X, size_type _P, size_type _M) const { AssertH (_X.size() >= _P); //if (_X.size() < _P) // _Xran(); if (_X._Len - _P < _M) _M = _X._Len - _P; return (compare(_P0, _N0, _X.c_str() + _P, _M)); } int compare(const _E *_S) const { return (compare(0, _Len, _S, _Tr::length(_S))); } int compare(size_type _P0, size_type _N0, const _E *_S) const { return (compare(_P0, _N0, _S, _Tr::length(_S))); } int compare(size_type _P0, size_type _N0, const _E *_S, size_type _M) const { AssertH (_Len >= _P0); //if (_Len < _P0) // _Xran(); if (_Len - _P0 < _N0) _N0 = _Len - _P0; size_type _Ans = _Tr::compare(_Psum(_Ptr, _P0), _S, _N0 < _M ? _N0 : _M); return (_Ans != 0 ? _Ans : _N0 < _M ? -1 : _N0 == _M ? 0 : +1); } private: enum { // the number of characters that, when multiplied by sizeof(_E) will // still fit within the range of size_type. (We allocate two extra // characters -- one for the refcount, the other for the terminator.) // _MAX_SIZE = (((unsigned int)(-1)) / sizeof(_E)) - 2, // _MIN_SIZE seems to be an allocation granularity (in characters). // Allocation requests are bit ORed with _MIN_SIZE. // _MIN_SIZE = 7, //_MIN_SIZE = sizeof (_E) <= 32 ? 31 : 7 }; void _Copy(size_type _N) { //AssertSzH (_Len <= _N, "Can't allocate less than we need to copy"); size_type _Ns = _N | _MIN_SIZE; if (_MAX_SIZE < _Ns) _Ns = _N; size_type _NewLen = (_Ns < _Len) ? _Ns : _Len; _E *_S = (_E*) MemAllocRaiseException ((_Ns + 2) * sizeof(_E)); //_TRY_BEGIN //_S = allocator.allocate(_Ns + 2, (void *)0); //_CATCH_ALL //_Ns = _N; //_S = allocator.allocate(_Ns + 2, (void *)0); //_CATCH_END if (_Len) { _Tr::copy(_S + 1, _Ptr, _NewLen); } _Tidy(true); _Ptr = _S + 1; _Refcnt(_Ptr) = 0; _Res = _Ns; _Eos(_NewLen); } void _Eos(size_type _N) { _Tr::assign(_Ptr[_Len = _N], _E(0)); } void _Freeze() { if (_Ptr != 0 && _Refcnt(_Ptr) != 0 && _Refcnt(_Ptr) != _FROZEN) _Grow(_Len); if (_Ptr != 0) _Refcnt(_Ptr) = _FROZEN; } bool _Grow(size_type _N, bool _Trim = false) { AssertH (_N < _MAX_SIZE); //if (_MAX_SIZE < _N) // _Xlen(); if (_Ptr != 0 && _Refcnt(_Ptr) != 0 && _Refcnt(_Ptr) != _FROZEN) { if (_N == 0) { --_Refcnt(_Ptr), _Tidy(); return (false); } else { _Copy(_N); return (true); } } else if (_N == 0) { if (_Trim) { _Tidy(true); } else if (_Ptr != 0) { _Eos(0); } return (false); } else { if (_Trim && (_N > _Res || _Res > _MIN_SIZE)) { _Tidy(true); _Copy(_N); } else if (!_Trim && (_N > _Res)) { _Copy(_N); } return (true); } } static const _E * __cdecl _Nullstr() { static const _E _C = _E(0); return (&_C); } static size_type _Pdif(const_pointer _P2, const_pointer _P1) { return (_P2 == 0 ? 0 : _P2 - _P1); } static const_pointer _Psum(const_pointer _P, size_type _N) { return (_P == 0 ? 0 : _P + _N); } static pointer _Psum(pointer _P, size_type _N) { return (_P == 0 ? 0 : _P + _N); } unsigned short& _Refcnt(const _E *_U) { return (((unsigned short *)_U)[-1]); } void _Split() { if (_Ptr != 0 && _Refcnt(_Ptr) != 0 && _Refcnt(_Ptr) != _FROZEN) { _E *_Temp = _Ptr; _Tidy(true); assign(_Temp); } } void _Tidy(bool _Built = false) { if (!_Built || _Ptr == 0) { ; } else if (_Refcnt(_Ptr) == 0 || _Refcnt(_Ptr) == _FROZEN) { MemFree(_Ptr - 1); //allocator.deallocate(_Ptr - 1, _Res + 2); } else { --_Refcnt(_Ptr); } _Ptr = 0, _Len = 0, _Res = 0; } _E *_Ptr; size_type _Len, _Res; }; inline CWideString __cdecl operator+( const CWideString& _L, const CWideString& _R) {return (CWideString(_L) += _R); } inline CWideString __cdecl operator+( const CWideString::_E *_L, const CWideString& _R) {return (CWideString(_L) += _R); } inline CWideString __cdecl operator+( const CWideString::_E _L, const CWideString& _R) {return (CWideString(1, _L) += _R); } inline CWideString __cdecl operator+( const CWideString& _L, const CWideString::_E *_R) {return (CWideString(_L) += _R); } inline CWideString __cdecl operator+( const CWideString& _L, const CWideString::_E _R) {return (CWideString(_L) += _R); } inline bool __cdecl operator==( const CWideString& _L, const CWideString& _R) {return (_L.compare(_R) == 0); } inline bool __cdecl operator==( const CWideString::_E * _L, const CWideString& _R) {return (_R.compare(_L) == 0); } inline bool __cdecl operator==( const CWideString& _L, const CWideString::_E *_R) {return (_L.compare(_R) == 0); } inline bool __cdecl operator!=( const CWideString& _L, const CWideString& _R) {return (!(_L == _R)); } inline bool __cdecl operator!=( const CWideString::_E *_L, const CWideString& _R) {return (!(_L == _R)); } inline bool __cdecl operator!=( const CWideString& _L, const CWideString::_E *_R) {return (!(_L == _R)); } inline bool __cdecl operator<( const CWideString& _L, const CWideString& _R) {return (_L.compare(_R) < 0); } inline bool __cdecl operator<( const CWideString::_E * _L, const CWideString& _R) {return (_R.compare(_L) > 0); } inline bool __cdecl operator<( const CWideString& _L, const CWideString::_E *_R) {return (_L.compare(_R) < 0); } inline bool __cdecl operator>( const CWideString& _L, const CWideString& _R) {return (_R < _L); } inline bool __cdecl operator>( const CWideString::_E * _L, const CWideString& _R) {return (_R < _L); } inline bool __cdecl operator>( const CWideString& _L, const CWideString::_E *_R) {return (_R < _L); } inline bool __cdecl operator<=( const CWideString& _L, const CWideString& _R) {return (!(_R < _L)); } inline bool __cdecl operator<=( const CWideString::_E * _L, const CWideString& _R) {return (!(_R < _L)); } inline bool __cdecl operator<=( const CWideString& _L, const CWideString::_E *_R) {return (!(_R < _L)); } inline bool __cdecl operator>=( const CWideString& _L, const CWideString& _R) {return (!(_L < _R)); } inline bool __cdecl operator>=( const CWideString::_E * _L, const CWideString& _R) {return (!(_L < _R)); } inline bool __cdecl operator>=( const CWideString& _L, const CWideString::_E *_R) {return (!(_L < _R)); } #endif // _NCSTLSTR_H_