windows-nt/Source/XPSP1/NT/net/config/inc/ncstlstr.h
2020-09-26 16:20:57 +08:00

1190 lines
29 KiB
C++

//+---------------------------------------------------------------------------
//
// 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 <stliter.h>
#include <stlxutil.h>
#include <limits.h>
#include <wchar.h>
#include "ncdebug.h"
using namespace std;
//template<class _E,
//class _Tr = char_traits<_E>,
//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_iterator, value_type, const_reference,
const_pointer, difference_type>
const_reverse_iterator;
typedef reverse_iterator<iterator, value_type, reference, pointer,
difference_type>
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_