Files
hpsocket-linux/common/StringT.h
2025-04-17 20:38:35 +08:00

931 lines
22 KiB
C++

/*
* Copyright: JessMA Open Source (ldcsaa@gmail.com)
*
* Author : Bruce Liang
* Website : https://github.com/ldcsaa
* Project : https://github.com/ldcsaa/HP-Socket
* Blog : http://www.cnblogs.com/ldcsaa
* Wiki : http://www.oschina.net/p/hp-socket
* QQ Group : 44636872, 75375912
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "FuncHelper.h"
#include <stdarg.h>
#include <string.h>
#include <string>
using namespace std;
template<typename _CharT, typename _Traits = char_traits<_CharT>, typename _Alloc = allocator<_CharT>>
class CStringT : public basic_string<_CharT, _Traits, _Alloc>
{
public:
using __super = basic_string<_CharT, _Traits, _Alloc>;
using XCHAR = _CharT;
using PXSTR = _CharT*;
using PCXSTR = const _CharT*;
using traits_type = typename __super::traits_type;
using value_type = typename __super::value_type;
using allocator_type = typename __super::allocator_type;
using size_type = typename __super::size_type;
using difference_type = typename __super::difference_type;
using reference = typename __super::reference;
using const_reference = typename __super::const_reference;
using pointer = typename __super::pointer;
using const_pointer = typename __super::const_pointer;
using iterator = typename __super::iterator;
using const_iterator = typename __super::const_iterator;
using const_reverse_iterator = typename __super::const_reverse_iterator;
using reverse_iterator = typename __super::reverse_iterator;
using __super::clear;
using __super::empty;
using __super::size;
using __super::resize;
using __super::data;
using __super::c_str;
private:
constexpr static PCXSTR SPACE_CHARS = _T(" \t\r\n\f\v");
public:
void Empty() {clear();}
bool IsEmpty() const {return empty();}
int GetLength() const {return (int)size();}
const _CharT* GetString() const {return c_str();}
operator const _CharT* () const {return __super::c_str();}
_CharT* GetBuffer(int length)
{
resize((size_type)length);
return (_CharT*)data();
}
void ReleaseBuffer(int length = -1)
{
if(length == -1)
length = lstrlen(data());
resize(length);
}
void ReleaseBufferSetLength(int length)
{
ASSERT(length >=0);
ReleaseBuffer(length);
}
void Truncate(int length)
{
if(length >= GetLength())
return;
ReleaseBuffer(length);
}
int Format(const _CharT* format, ...)
{
int rs;
va_list ap;
va_start(ap, format);
rs = VASprintf(0, format, ap);
va_end(ap);
return rs;
}
int AppendFormat(const _CharT* format, ...)
{
int rs;
va_list ap;
va_start(ap, format);
rs = VASprintf(GetLength(), format, ap);
va_end(ap);
return rs;
}
int VASprintf(int offset, const _CharT* format, va_list ap)
{
va_list ap_cpy;
va_copy(ap_cpy, ap);
int count = vsnprintf(nullptr, 0, format, ap);
if(count >= 0)
{
_CharT* p = GetBuffer(count + offset);
vsnprintf(p + offset, count + 1, format, ap_cpy);
}
va_end(ap_cpy);
return count;
}
CStringT& Append(const _CharT* __s)
{
append(__s);
return *this;
}
CStringT& Append(const _CharT* __s, int __n)
{
append(__s, __n);
return *this;
}
CStringT& AppendChar(_CharT __c)
{
push_back(__c);
return *this;
}
int Compare(const _CharT* __s) const
{
return lstrcmp(c_str(), __s);
}
int CompareNoCase(const _CharT* __s) const
{
return lstricmp(c_str(), __s);
}
bool Equals(const _CharT* __s) const
{
return (Compare(__s) == 0);
}
bool EqualsNoCase(const _CharT* __s) const
{
return (CompareNoCase(__s) == 0);
}
CStringT& MakeLower()
{
size_type s = size();
_CharT* p = (_CharT*)c_str();
_CharT c;
for(size_type i = 0; i < s; i++)
{
c = p[i];
if(c >= 'A' && c <= 'Z')
p[i] = (_CharT)(c + 32);
}
return *this;
}
CStringT& MakeUpper()
{
size_type s = size();
_CharT* p = (_CharT*)c_str();
_CharT c;
for(size_type i = 0; i < s; i++)
{
c = p[i];
if(c >= 'a' && c <= 'z')
p[i] = (_CharT)(c - 32);
}
return *this;
}
CStringT Mid(int iFirst, int nCount = (int)__super::npos) const
{
return substr(iFirst, nCount);
}
CStringT Left(int nCount) const
{
return Mid(0, nCount);
}
CStringT Right(int nCount) const
{
int nLength = GetLength();
if(nCount >= nLength)
return *this;
return Mid(nLength - nCount, nCount);
}
CStringT Tokenize(PCXSTR lpszTokens, int& iStart) const
{
ASSERT(iStart >= 0);
if((lpszTokens == nullptr) || (*lpszTokens == (_CharT)0))
{
if(iStart < GetLength())
return CStringT(GetString() + iStart);
}
else
{
PCXSTR pszPlace = GetString() + iStart;
PCXSTR pszEnd = GetString() + GetLength();
if(pszPlace < pszEnd)
{
int nIncluding = lstrspn(pszPlace, lpszTokens);
if((pszPlace + nIncluding) < pszEnd)
{
pszPlace += nIncluding;
int nExcluding = lstrcspn(pszPlace, lpszTokens);
int iFrom = iStart + nIncluding;
int nUntil = nExcluding;
iStart = iFrom + nUntil + 1;
return Mid(iFrom, nUntil);
}
}
}
iStart = -1;
return CStringT();
}
CStringT& Trim()
{
return Trim(SPACE_CHARS);
}
CStringT& TrimRight()
{
return TrimRight(SPACE_CHARS);
}
CStringT& TrimLeft()
{
return TrimLeft(SPACE_CHARS);
}
CStringT& Trim(XCHAR c)
{
return(TrimRight(c).TrimLeft(c));
}
CStringT& TrimRight(XCHAR c)
{
int iLength = GetLength();
if(iLength == 0)
return *this;
PCXSTR lpszBegin = GetString();
PCXSTR lpszEnd = lpszBegin + iLength;
while(lpszEnd > lpszBegin)
{
if(*(lpszEnd - 1) != c)
break;
--lpszEnd;
}
int iNewLength = (int)(lpszEnd - lpszBegin);
if(iNewLength < iLength)
Truncate(iNewLength);
return *this;
}
CStringT& TrimLeft(XCHAR c)
{
int iLength = GetLength();
if(iLength == 0)
return *this;
PCXSTR lpszBegin = GetString();
PCXSTR lpszEnd = lpszBegin;
int iOffset = 0;
while(*lpszEnd == c)
{
++lpszEnd;
++iOffset;
if(iOffset == iLength)
break;
}
if(iOffset != 0)
{
int iNewLength = iLength - iOffset;
if(iNewLength > 0)
memcpy((PXSTR)lpszBegin, lpszEnd, (iLength - iOffset) * sizeof(XCHAR));
ReleaseBufferSetLength(iNewLength);
}
return *this;
}
CStringT& Trim(PCXSTR lpszChars)
{
return(TrimRight(lpszChars).TrimLeft(lpszChars));
}
CStringT& TrimRight(PCXSTR lpszChars)
{
ASSERT(!::IsStrEmpty(lpszChars));
if(::IsStrEmpty(lpszChars))
return *this;
int iLength = GetLength();
if(iLength == 0)
return *this;
PCXSTR lpszBegin = GetString();
PCXSTR lpszEnd = lpszBegin + iLength;
while(lpszEnd > lpszBegin)
{
if(::StrChr(lpszChars, *(lpszEnd - 1)) == nullptr)
break;
--lpszEnd;
}
int iNewLength = (int)(lpszEnd - lpszBegin);
if(iNewLength < iLength)
Truncate(iNewLength);
return *this;
}
CStringT& TrimLeft(PCXSTR lpszChars)
{
ASSERT(!::IsStrEmpty(lpszChars));
if(::IsStrEmpty(lpszChars))
return *this;
int iLength = GetLength();
if(iLength == 0)
return *this;
PCXSTR lpszBegin = GetString();
PCXSTR lpszEnd = lpszBegin;
int iOffset = 0;
while(::StrChr(lpszChars, *lpszEnd) != nullptr)
{
++lpszEnd;
++iOffset;
if(iOffset == iLength)
break;
}
if(iOffset != 0)
{
int iNewLength = iLength - iOffset;
if(iNewLength > 0)
memcpy((PXSTR)lpszBegin, lpszEnd, (iLength - iOffset) * sizeof(XCHAR));
ReleaseBufferSetLength(iNewLength);
}
return *this;
}
int Find(XCHAR c, int iStart = 0) const
{
ASSERT(iStart >= 0);
int iLength = GetLength();
if(iStart < 0 || iStart >= iLength)
return -1;
PCXSTR lpszBegin = GetString();
PCXSTR lpszFind = ::StrChr(lpszBegin + iStart, c);
return ((lpszFind == nullptr) ? -1 : (int)(lpszFind - lpszBegin));
}
int Find(PCXSTR lpszSub, int iStart = 0) const
{
ASSERT(iStart >= 0 && !::IsStrEmpty(lpszSub));
int iLength = GetLength();
if(lpszSub == nullptr || iStart < 0 || iStart > iLength)
return -1;
PCXSTR lpszBegin = GetString();
PCXSTR lpszFind = ::StrStr(lpszBegin + iStart, lpszSub);
return ((lpszFind == nullptr) ? -1 : (int)(lpszFind - lpszBegin));
}
int FindOneOf(PCXSTR lpszChars) const
{
ASSERT(!::IsStrEmpty(lpszChars));
if(lpszChars == nullptr)
return -1;
PCXSTR lpszBegin = GetString();
PCXSTR lpszFind = ::StrPBrk(lpszBegin, lpszChars);
return ((lpszFind == nullptr) ? -1 : (int)(lpszFind - lpszBegin));
}
int ReverseFind(XCHAR c) const
{
PCXSTR lpszBegin = GetString();
PCXSTR lpszFind = ::StrRChr(lpszBegin, c);
return ((lpszFind == nullptr) ? -1 : (int)(lpszFind - lpszBegin));
}
int Remove(XCHAR c)
{
int iLength = GetLength();
if(iLength == 0)
return 0;
PCXSTR lpszBegin = GetString();
PXSTR lpszCur = (PXSTR)lpszBegin;
PCXSTR lpszEnd = lpszBegin + iLength;
int iRemoved = 0;
while(lpszCur < lpszEnd)
{
if(*lpszCur == c)
++iRemoved;
else if(iRemoved > 0)
*(lpszCur - iRemoved) = *lpszCur;
++lpszCur;
}
if(iRemoved > 0)
ReleaseBufferSetLength(iLength - iRemoved);
return iRemoved;
}
XCHAR GetAt(int i) const
{
return (*this)[i];
}
void SetAt(int i, XCHAR c)
{
(*this)[i] = c;
}
XCHAR operator[](int i) const
{
ASSERT(i >= 0 && i < GetLength());
return *(GetString() + i);
}
XCHAR& operator[](int i)
{
ASSERT(i >= 0 && i < GetLength());
return *(PXSTR)(GetString() + i);
}
CStringT& Insert(int i, XCHAR c)
{
return insert((size_type)i, 1, c);
}
CStringT& Insert(int i, PCXSTR lpszChars)
{
return insert((size_type)i, lpszChars);
}
CStringT& SetString(PCXSTR lpszStr)
{
return assign(lpszStr);
}
CStringT& SetString(PCXSTR lpszStr, int iLength)
{
return assign(lpszStr, iLength);
}
friend bool operator==(const CStringT& str1, const CStringT& str2)
{
return (str1.Compare(str2) == 0);
}
friend bool operator==(const CStringT& str1, const _CharT* psz2)
{
return (str1.Compare(psz2) == 0);
}
friend bool operator==(const _CharT* psz1, const CStringT& str2)
{
return (str2.Compare(psz1) == 0);
}
friend bool operator!=(const CStringT& str1, const CStringT& str2)
{
return !(str1 == str2);
}
friend bool operator!=(const CStringT& str1, const _CharT* psz2)
{
return !(str1 == psz2);
}
friend bool operator!=(const _CharT* psz1, const CStringT& str2)
{
return !(psz1 == str2);
}
public:
CStringT() : __super() {};
explicit CStringT(const _Alloc& __a)
: __super(__a) {}
CStringT(const __super& __str)
: __super(__str) {}
CStringT(const CStringT& __str)
: __super(__str) {}
CStringT(const __super& __str, size_type __pos, size_type __n = __super::npos)
: __super(__str, __pos, __n) {}
CStringT(const __super& __str, size_type __pos, size_type __n, const _Alloc& __a)
: __super(__str, __pos, __n, __a) {}
CStringT(const _CharT* __s, size_type __n, const _Alloc& __a = _Alloc())
: __super(::SafeStr(__s), __n, __a) {}
CStringT(const _CharT* __s, const _Alloc& __a = _Alloc())
: __super(::SafeStr(__s), __a) {}
CStringT(size_type __n, _CharT __c, const _Alloc& __a = _Alloc())
: __super(__n, __c, __a) {}
#if __cplusplus >= 201103L
CStringT(__super&& __str)
: __super(__str) {}
CStringT(CStringT&& __str)
: __super(__str) {}
CStringT(initializer_list<_CharT> __l, const _Alloc& __a = _Alloc())
: __super(__l, __a) {}
#endif // C++11
template<class _InputIterator>
CStringT(_InputIterator __beg, _InputIterator __end, const _Alloc& __a = _Alloc())
: __super(__beg, __end, __a) {}
~CStringT() = default;
CStringT& operator=(const __super& __str)
{__super::operator=(__str); return *this;}
CStringT& operator=(const CStringT& __str)
{__super::operator=(__str); return *this;}
CStringT& operator=(const _CharT* __s)
{__super::operator=(::SafeStr(__s)); return *this;}
CStringT& operator=(_CharT __c)
{__super::operator=(__c); return *this;}
#if __cplusplus >= 201103L
CStringT& operator=(__super&& __str)
{__super::operator=(__str); return *this;}
CStringT& operator=(CStringT&& __str)
{__super::operator=(__str); return *this;}
CStringT& operator=(initializer_list<_CharT> __l)
{__super::operator=(__l); return *this;}
#endif // C++11
public:
CStringT& operator+=(const __super& __str)
{__super::operator+=(__str); return *this;}
CStringT& operator+=(const _CharT* __s)
{__super::operator+=(::SafeStr(__s)); return *this;}
CStringT& operator+=(_CharT __c)
{__super::operator+=(__c); return *this;}
#if __cplusplus >= 201103L
CStringT& operator+=(initializer_list<_CharT> __l)
{__super::operator+=(__l); return *this;}
#endif // C++11
CStringT& append(const __super& __str)
{__super::append(__str); return *this;}
CStringT& append(const __super& __str, size_type __pos, size_type __n)
{__super::append(__str, __pos, __n); return *this;}
CStringT& append(const _CharT* __s, size_type __n)
{__super::append(::SafeStr(__s), __n); return *this;}
CStringT& append(const _CharT* __s)
{__super::append(::SafeStr(__s)); return *this;}
CStringT& append(size_type __n, _CharT __c)
{__super::append(__n, __c); return *this;}
#if __cplusplus >= 201103L
CStringT& append(initializer_list<_CharT> __l)
{__super::append(__l); return *this;}
#endif // C++11
template<class _InputIterator>
CStringT& append(_InputIterator __first, _InputIterator __last)
{__super::append(__first, __last); return *this;}
void push_back(_CharT __c)
{__super::push_back(__c);}
CStringT& assign(const __super& __str)
{__super::assign(__str); return *this;}
#if __cplusplus >= 201103L
CStringT& assign(__super&& __str)
{__super::assign(__str); return *this;}
#endif // C++11
CStringT& assign(const __super& __str, size_type __pos, size_type __n)
{__super::assign(__str, __pos, __n); return *this;}
CStringT& assign(const _CharT* __s, size_type __n)
{__super::assign(::SafeStr(__s), __n); return *this;}
CStringT& assign(const _CharT* __s)
{__super::assign(::SafeStr(__s)); return *this;}
CStringT& assign(size_type __n, _CharT __c)
{__super::assign(__n, __c); return *this;}
template<class _InputIterator>
CStringT& assign(_InputIterator __first, _InputIterator __last)
{__super::assign(__first, __last); return *this;}
#if __cplusplus >= 201103L
CStringT& assign(initializer_list<_CharT> __l)
{__super::assign(__l); return *this;}
#endif // C++11
CStringT& insert(size_type __pos1, const __super& __str)
{__super::insert(__pos1, __str); return *this;}
CStringT& insert(size_type __pos1, const __super& __str, size_type __pos2, size_type __n)
{__super::insert(__pos1, __str, __pos2, __n); return *this;}
CStringT& insert(size_type __pos, const _CharT* __s, size_type __n)
{__super::insert(__pos, __s, __n); return *this;}
CStringT& insert(size_type __pos, const _CharT* __s)
{__super::insert(__pos, __s); return *this;}
CStringT& insert(size_type __pos, size_type __n, _CharT __c)
{__super::insert(__pos, __n, __c); return *this;}
CStringT& erase(size_type __pos = 0, size_type __n = __super::npos)
{__super::erase(__pos, __n); return *this;}
CStringT& replace(size_type __pos, size_type __n, const __super& __str)
{__super::replace(__pos, __n, __str); return *this;}
CStringT& replace(size_type __pos1, size_type __n1, const __super& __str, size_type __pos2, size_type __n2)
{__super::replace(__pos1, __n1, __str, __pos2, __n2); return *this;}
CStringT& replace(size_type __pos, size_type __n1, const _CharT* __s, size_type __n2)
{__super::replace(__pos, __n1, __s, __n2); return *this;}
CStringT& replace(size_type __pos, size_type __n1, const _CharT* __s)
{__super::replace(__pos, __n1, __s); return *this;}
CStringT& replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
{__super::replace(__pos, __n1, __n2, __c); return *this;}
CStringT& replace(iterator __i1, iterator __i2, const __super& __str)
{__super::replace(__i1, __i2, __str); return *this;}
CStringT& replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n)
{__super::replace(__i1, __i2, __s, __n); return *this;}
CStringT& replace(iterator __i1, iterator __i2, const _CharT* __s)
{__super::replace(__i1, __i2, __s); return *this;}
CStringT& replace(iterator __i1, iterator __i2, size_type __n, _CharT __c)
{__super::replace(__i1, __i2, __n, __c); return *this;}
template<class _InputIterator>
CStringT& replace(iterator __i1, iterator __i2, _InputIterator __k1, _InputIterator __k2)
{__super::replace(__i1, __i2, __k1, __k2); return *this;}
CStringT& replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2)
{__super::replace(__i1, __i2, __k1, __k2); return *this;}
CStringT& replace(iterator __i1, iterator __i2, const _CharT* __k1, const _CharT* __k2)
{__super::replace(__i1, __i2, __k1, __k2); return *this;}
CStringT& replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2)
{__super::replace(__i1, __i2, __k1, __k2); return *this;}
CStringT& replace(iterator __i1, iterator __i2, const_iterator __k1, const_iterator __k2)
{__super::replace(__i1, __i2, __k1, __k2); return *this;}
#if __cplusplus >= 201103L
CStringT& replace(iterator __i1, iterator __i2, initializer_list<_CharT> __l)
{__super::replace(__i1, __i2, __l); return *this;}
#endif // C++11
CStringT substr(size_type __pos = 0, size_type __n = __super::npos) const
{return __super::substr(__pos, __n);}
};
template<typename _CharT, typename _Traits, typename _Alloc>
CStringT<_CharT, _Traits, _Alloc>
operator+(const CStringT<_CharT, _Traits, _Alloc>& __lhs, const CStringT<_CharT, _Traits, _Alloc>& __rhs)
{
CStringT<_CharT, _Traits, _Alloc> __str(__lhs);
__str.append(__rhs);
return __str;
}
template<typename _CharT, typename _Traits, typename _Alloc>
CStringT<_CharT,_Traits,_Alloc>
operator+(const _CharT* __lhs, const CStringT<_CharT,_Traits,_Alloc>& __rhs);
template<typename _CharT, typename _Traits, typename _Alloc>
CStringT<_CharT,_Traits,_Alloc>
operator+(_CharT __lhs, const CStringT<_CharT,_Traits,_Alloc>& __rhs);
template<typename _CharT, typename _Traits, typename _Alloc>
inline CStringT<_CharT, _Traits, _Alloc>
operator+(const CStringT<_CharT, _Traits, _Alloc>& __lhs, const _CharT* __rhs)
{
CStringT<_CharT, _Traits, _Alloc> __str(__lhs);
__str.append(__rhs);
return __str;
}
template<typename _CharT, typename _Traits, typename _Alloc>
inline CStringT<_CharT, _Traits, _Alloc>
operator+(const CStringT<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs)
{
typedef CStringT<_CharT, _Traits, _Alloc> __string_type;
typedef typename __string_type::size_type __size_type;
__string_type __str(__lhs);
__str.append(__size_type(1), __rhs);
return __str;
}
#if __cplusplus >= 201103L
template<typename _CharT, typename _Traits, typename _Alloc>
inline CStringT<_CharT, _Traits, _Alloc>
operator+(CStringT<_CharT, _Traits, _Alloc>&& __lhs, const CStringT<_CharT, _Traits, _Alloc>& __rhs)
{return std::move(__lhs.append(__rhs));}
template<typename _CharT, typename _Traits, typename _Alloc>
inline CStringT<_CharT, _Traits, _Alloc>
operator+(const CStringT<_CharT, _Traits, _Alloc>& __lhs, CStringT<_CharT, _Traits, _Alloc>&& __rhs)
{return std::move(__rhs.insert(0, __lhs));}
template<typename _CharT, typename _Traits, typename _Alloc>
inline CStringT<_CharT, _Traits, _Alloc>
operator+(CStringT<_CharT, _Traits, _Alloc>&& __lhs, CStringT<_CharT, _Traits, _Alloc>&& __rhs)
{
const auto __size = __lhs.size() + __rhs.size();
const bool __cond = (__size > __lhs.capacity()
&& __size <= __rhs.capacity());
return __cond ? std::move(__rhs.insert(0, __lhs))
: std::move(__lhs.append(__rhs));
}
template<typename _CharT, typename _Traits, typename _Alloc>
inline CStringT<_CharT, _Traits, _Alloc>
operator+(const _CharT* __lhs, CStringT<_CharT, _Traits, _Alloc>&& __rhs)
{return std::move(__rhs.insert(0, __lhs));}
template<typename _CharT, typename _Traits, typename _Alloc>
inline CStringT<_CharT, _Traits, _Alloc>
operator+(_CharT __lhs, CStringT<_CharT, _Traits, _Alloc>&& __rhs)
{return std::move(__rhs.insert(0, 1, __lhs));}
template<typename _CharT, typename _Traits, typename _Alloc>
inline CStringT<_CharT, _Traits, _Alloc>
operator+(CStringT<_CharT, _Traits, _Alloc>&& __lhs, const _CharT* __rhs)
{return std::move(__lhs.append(__rhs));}
template<typename _CharT, typename _Traits, typename _Alloc>
inline CStringT<_CharT, _Traits, _Alloc>
operator+(CStringT<_CharT, _Traits, _Alloc>&& __lhs, _CharT __rhs)
{return std::move(__lhs.append(1, __rhs));}
#endif
using CStringA = CStringT<char>;
using CStringW = CStringT<wchar_t>;
using CStdStringA = string;
using CStdStringW = wstring;
#ifdef _UNICODE
using CString = CStringW;
using CStdString = CStdStringW;
#else
using CString = CStringA;
using CStdString = CStdStringA;
#endif
#define _HASH_SEED (size_t)0xdeadbeef
template<class _Kty>
inline size_t hash_value(const _Kty& _Keyval)
{
return ((size_t)_Keyval ^ _HASH_SEED);
}
template <class _InIt>
inline size_t _Hash_value(_InIt _Begin, _InIt _End)
{
size_t _Val = 2166136261U;
while(_Begin != _End)
_Val = 16777619U * _Val ^ (size_t)*_Begin++;
return (_Val);
}
template<class _Elem, class _Traits, class _Alloc>
inline size_t hash_value(const basic_string<_Elem, _Traits, _Alloc>& _Str)
{
const _Elem *_Ptr = _Str.c_str();
return (_Hash_value(_Ptr, _Ptr + _Str.size()));
}
template<class _Elem>
inline size_t hash_value(const CStringT<_Elem>& _Str)
{
const _Elem *_Ptr = _Str.c_str();
return (_Hash_value(_Ptr, _Ptr + _Str.size()));
}
inline size_t hash_value(const char *_Str)
{
return (_Hash_value(_Str, _Str + strlen(_Str)));
}
inline size_t hash_value(const wchar_t *_Str)
{
return (_Hash_value(_Str, _Str + wcslen(_Str)));
}