123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600 |
- #pragma once
- #include <string>
- #include <locale>
- #include <functional>
- #include "String.StringView.hpp"
- #ifdef DSTRING_EXPORTS
- #define WSTRING_API _declspec(dllexport)
- #else
- #define WSTRING_API _declspec(dllimport)
- #endif
- #ifdef _DSTRING_STATIC_
- #undef WSTRING_API
- #define WSTRING_API
- #endif
- #ifndef DSTRING_EXPORTS
- #ifdef _WIN64
- #ifdef _DEBUG
- #pragma comment (lib, "ECOM.Utility.DString64D.lib")
- #else
- #pragma comment (lib, "ECOM.Utility.DString64.lib")
- #endif
- #else // X86
- #endif
- #endif // DSTRING_EXPORTS
- #ifndef _OLEAUTO_H_
- typedef LPWSTR BSTR;// must (semantically) match typedef in oleauto.h
- #endif
- namespace ECOM::Utility::String
- {
- class DString;
- // using size_type = unsigned int; // 用 unsigned int 比较好, 但是会造成很多编译警告
- using size_type = int;
- //-----------------------------------------------------------------------------
- // WStringData
- //-----------------------------------------------------------------------------
- namespace
- {
- struct WStringData
- {
- long nRefs; // reference count
- size_type nDataLength; // 字符数, length of data (including terminator)
- size_type nAllocLength; // length of allocation
- // wchar_t data[nAllocLength]
- wchar_t * data () // wchar_t* to managed data
- {
- return (wchar_t *) (this + 1);
- }
- };
- }
- //-----------------------------------------------------------------------------
- // WString
- //-----------------------------------------------------------------------------
- class WSTRING_API WString
- {
- public:
- using value_type = WString;
- public:
- WString ();
- WString (const wchar_t * lpsz) = delete;
- WString (const wchar_t * lpsz, int nCount);
- WString (const BSTR bstr) = delete;
- explicit WString (const DString & From);
- explicit WString (const DStringView & From);
- WString (const std::wstring & Src);
- WString (const WString & Src);
- WString (WString && Src);
- public:
- ~WString ();
- public:
- // 返回的是字符数, 而不是真正的长度 ! 真正的长度要乘以 2
- size_type GetLength () const;
- size_type GetByteLength () const { return GetLength () << 1; }
- size_type GetAllocLength () const { return GetData ()->nAllocLength; }
- size_type size () const { return GetLength (); }
- public:
- bool empty () const { return IsEmpty (); }
- bool IsEmpty () const { return GetLength () <= 0; }
- void Clear ();
- void Release ();
- public:
- wchar_t GetAt (int nIndex) const
- {
- return m_pchData [nIndex];
- }
- wchar_t operator [] (int nIndex) const { return GetAt (nIndex); }
- void SetAt (int nIndex, wchar_t ch);
- int Count (wchar_t ch) const;
- int Count (const WStringView & Sub) const;
- protected:
- size_t _Hash () const;
- public:
- WString & operator = (const wchar_t *) = delete;
- WString & operator = (const WString & S);
- WString & operator = (const DString & S);
- WString & operator = (wchar_t ch);
- WString & operator = (const DStringView & S);
- WString & operator = (const WStringView & S) { return Assign (S); }
- WString & operator = (WString && S);
- WString & operator = (const std::wstring & S) { AssignCopy (static_cast <int> (S.size ()), S.c_str ()); return *this; }
- WString & operator = (std::initializer_list <WStringView> lst)
- {
- return Assign (lst);
- }
- public:
- // string concatenation
- WString & Append (const WString & S)
- {
- ConcatInPlace (S.GetData ()->nDataLength, S.m_pchData);
- return *this;
- }
- WString & Append (const DString & S)
- {
- return Append (WString (S));
- }
- WString & Append (wchar_t ch)
- {
- ConcatInPlace (1, &ch);
- return *this;
- }
- WString & Append (const DStringView & S);
- WString & Append (const WStringView & S);
- WString & Append (const std::wstring_view & S);
- WString & Append (const std::wstring & S)
- {
- ConcatInPlace (static_cast <int> (S.length ()), S.c_str ());
- return *this;
- }
- WString & Append (const char *) = delete; // 改用 L"..."_sv 代替
- WString & Append (const wchar_t *) = delete; // 改用 L"..."_sv 代替
- WString & operator += (const WString & S) { return Append (S); }
- WString & operator += (wchar_t ch) { return Append (ch); }
- WString & operator += (const DStringView S) { return Append (S); }
- WString & operator += (const WStringView S) { return Append (S); }
- WString & operator += (const DString & S) { return Append (S); }
- // WString & operator += (const std::wstring & S) { return Append (S); }
- WString & operator += (std::initializer_list <WStringView> lst) { return Append (lst); }
- // WString & operator += (const char *) = delete; // 改用 L"..."_sv 代替
- // WString & operator += (const wchar_t *) = delete; // 改用 L"..."_sv 代替
- WString & operator << (const DString & S) { return Append (WString (S)); }
- WString & operator << (const DStringView & S) { return Append (S); }
- WString & operator << (const WStringView & S) { return Append (S); }
- WString & operator << (const WString & S) { return Append (S); }
- WString & operator << (wchar_t ch) { return Append (ch); }
- WString & operator << (short v) { return Append (From (v)); }
- WString & operator << (int v) { return Append (From (v)); }
- WString & operator << (long v) { return Append (From (v)); }
- WString & operator << (UINT16 v) { return Append (From (v)); }
- WString & operator << (UINT32 v) { return Append (From (v)); }
- WString & operator << (unsigned long v) { return Append (From (v)); }
- // WString & operator << (const std::wstring & S) { return Append (S); }
- WString & operator << (std::initializer_list <WStringView> lst) { return Append (lst); }
- //< WString & operator << (const char *) = delete; // 改用 L"..."_sv 代替
- // WString & operator << (const wchar_t *) = delete; // 改用 L"..."_sv 代替
- // 不废除了, 某些强制赋值还是需要的.
- // 如果不做提前声明, 编译时发生 C2678: 无法找到匹配的运算符
- // 2023-11-14
- //>
- public:
- // string comparison
- int Compare (const wchar_t * lpsz) const;
- int CompareNoCase (const wchar_t * lpsz) const;
- int Compare (const WStringView & With) const;
- int Compare (const WString & With) const;
- //< 增加命名空间后, std::map <DString, ...> 就需要如下内置比较函数
- bool operator == (const WString & with) const { return Compare (with) == 0; }
- bool operator != (const WString & with) const { return Compare (with) != 0; }
- bool operator < (const WString & with) const { return Compare (with) < 0; }
- bool operator > (const WString & with) const { return Compare (with) > 0; }
- bool operator <= (const WString & with) const { return Compare (with) <= 0; }
- bool operator >= (const WString & with) const { return Compare (with) >= 0; }
- public:
- WString Mid (int nFirst, int nCount) const;
- WString Mid (int nFirst) const;
- WString Left (int nCount) const;
- WString Right (int nCount) const;
- public:
- void MakeUpper ();
- void MakeLower ();
- void MakeReverse ();
- public:
- int TrimLeft ();
- int TrimRight ();
- void TrimRight (wchar_t chTarget);
- void TrimRight (const WStringView & szTargets);
- void TrimLeft (wchar_t chTarget);
- void TrimLeft (const WStringView & szTargets);
- WString Trim () const { WString copy = *this; copy.TrimRight (); copy.TrimLeft (); return copy; }
- public:
- // 用指定的字符填充左边/右边/中间, 直到总长度达到指定值为止
- void JustLeft (int ToLength, wchar_t ch = ' ');
- void JustRight (int ToLength, wchar_t ch = ' ');
- void JustCenter (int ToLength, wchar_t ch = ' ');
- public:
- int Replace (wchar_t chOld, wchar_t chNew);
- int Replace (const WString & Old, const WStringView & New);
- int Replace (const WStringView & Old, const WStringView & New);
- int Remove (const WStringView & Sub);
- int Remove (wchar_t chRemove);
- int RemoveSpace ();
- int RemovePunctuation ();
- int RemoveControl ();
- // 用谓词函数来判断单个字符是否应该删除, 如果返回 true 就删除
- int Remove (std::function <bool (int)> pred);
- int NCRemove (const WStringView & lpszSub);
- int NCRemove (wchar_t chRemove);
- void Repeat (wchar_t ch, int n);
- void Repeat (const WStringView & S, int n);
- public:
- // Pred 返回 true, 表明找到, 否则下一个字符
- using tPred = std::function <bool (wchar_t ch)>;
- public:
- int Find (wchar_t ch, int nStart = 0) const;
- int Find (tPred && pred, int nStart = 0) const;
- int Find (const WStringView & Sub, int nStart = 0) const;
- int Find (const WString & Sub, int nStart = 0) const;
- // find at right
- int ReverseFind (wchar_t ch, int nStart = 0) const;
- int ReverseFind (const WStringView & Sub, int nStart = 0) const;
- bool StartWith (const WStringView & Sub, int iStart = 0) const;
- bool EndWith (const WStringView & Sub, int iStart = 0) const;
- bool StartWith (const WString & Sub, int iStart = 0) const { return StartWith (Sub.To <WStringView> (), iStart); }
- bool EndWith (const WString & Sub, int iStart = 0) const { return EndWith (Sub.To <WStringView> (), iStart); }
- bool StartWith (wchar_t ch, int iStart = 0) const;
- bool EndWith (wchar_t ch, int iStart = 0) const;
- int NCFind (wchar_t ch) const;
- int NCFind (const WStringView & Sub) const;
- public:
- using tvCallback = std::function <void (CV_WString & sub)>;
- // 如果回调返回 true, 则继续, 否则停止
- using tbCallback = std::function <bool (int Index, CV_WString & sub)>;
- int Split (wchar_t ch , tvCallback && onFound, int start = 0) const;
- int Split (tPred && pred, tvCallback && onFound, int start = 0) const;
- int SplitIf (wchar_t ch , tbCallback && onFound, int start = 0) const;
- int SplitIf (tPred && pred, tbCallback && onFound, int start = 0) const;
- // 分割成列表
- auto SplitTo (wchar_t ch , int start = 0) const -> std::list <WString>;
- auto SplitTo (tPred && pred, int start = 0) const -> std::list <WString>;
- // 分割成数组, 最多 Max 个
- auto SplitMax (int Max, wchar_t ch , int start = 0) const -> std::vector <WString>;
- auto SplitMax (int Max, tPred && pred, int start = 0) const -> std::vector <WString>;
- // 返回指定 Index 的某一个, 如果找不到: 当 Index=0 时返回本串, 否则返回空串
- auto SplitOne (int atIndex, wchar_t ch , int start = 0) const ->WString;
- auto SplitOne (int atIndex, tPred && pred, int start = 0) const ->WString;
- // Cast
- public:
- operator const wchar_t * () const { return m_pchData; }
- const wchar_t * constBuffer () const { return m_pchData; }
- wchar_t * data () const { return m_pchData; }
- const wchar_t * c_str () const { return m_pchData; }
- DString ToDString () const;
- DString ToDString (UINT CodePage) const;
- DString ToDString (const char * LocName) const;
- DString ToDString (const _locale_t Loc) const;
- // explicit operator const DString () const { return ToDString (); }
- operator const DString () const = delete;
- operator bool () const = delete;
- // 用于自动判别类型
- public:
- template <typename T> bool Is () const { return false; }
- template <> bool Is <WString> () const { return true; }
- template <> bool Is <DString> () const { return false; }
- public:
- static WString From (const int i);
- static WString From (const long i);
- static WString From (const unsigned int u);
- static WString From (const unsigned long u);
- static WString From (const __int64 i);
- static WString From (const unsigned __int64 u);
- static WString From (const double d);
- static WString From (const std::wstring_view & Src);
- static WString From (CV_WString & Src) { return WString (Src); }
- static WString From (const WString & Src) { return WString (Src); }
- static WString From (const char * Src) { return FromCodePage (Src, CP_ACP); }
- static WString From (const wchar_t * lpsz) { return (CV_WString) lpsz; }
- static WString FromCodePage (const DString & from, UINT CodePage);
- static WString FromCodePage (const std::string & from, UINT CodePage);
- static WString FromCodePage (const std::string_view & from, UINT CodePage);
- static WString FromCodePage (const char * from, UINT CodePage);
- static WString FromCodePage (const char * from, int len, UINT CodePage);
- static WString FromLocale (const DString & from, const char * LocName);
- static WString FromLocale (const char * from, const char * LocName);
- static WString FromLocale (const char * from, int len, const char * LocName);
- static WString FromLocale (const DString & from, const _locale_t Loc);
- static WString FromLocale (const char * from, const _locale_t Loc);
- static WString FromLocale (const char * from, int len, const _locale_t Loc);
-
- // repeat a single character
- static WString FromRepeat (wchar_t ch, int nRepeat);
- protected:
- void FormatV (const wchar_t * lpszFormat, va_list argList);
- void AppendFormatV (const wchar_t * lpszFormat, va_list argList);
- protected:
- // 对于字符串,代码中很容易忘记 L 前缀, 导致传入的是 char *, 而期望的是 wchar_t *
- // 比如, 正确的写法是: Format ("%s", L"abcd"); 但是很容易写成 Format ("%s", "abcd");
- // 为了避免出现这种 BUG, 把这几个函数改成 protected
- static WString FromFormat (const wchar_t * szFormat, ...);
- void Format (const wchar_t * lpszFormat, ...);
- void AppendFormat (const wchar_t * lpszFormat, ...);
- public:
- // get pointer to modifiable buffer at least as long as nMinBufLength
- wchar_t * GetBuffer (int nMinBufLength);
- // release buffer, setting length to nNewLength (or to first nul if -1)
- void ReleaseBuffer (int nNewLength = -1);
- // get pointer to modifiable buffer exactly as long as nNewLength
- wchar_t * GetBufferSetLength (int nNewLength);
- void Reserve (int nMinBufLength) { GetBuffer (nMinBufLength); }
- void reserve (int nMinBufLength) { GetBuffer (nMinBufLength); }
- public:
- double Double () const { return _wtof (m_pchData); }
- int Int () const { int i = _wtoi (m_pchData); if (i) return i; return wcstol (m_pchData, NULL, 16); }
- long Long () const { long l = _wtol (m_pchData); if (l) return l; return wcstol (m_pchData, NULL, 16); }
- wchar_t Char () const { return m_pchData[0]; }
- bool Bool () const;
- __int64 Int64 () const { __int64 i = _wtoi64 (m_pchData); if (i) return i; return _wcstoi64 (m_pchData, NULL, 16); }
- template <typename T> T To () const = delete;
- template <> int To () const { return Int (); }
- template <> double To () const { return Double (); }
- template <> float To () const { return (float) Double (); }
- template <> long To () const { return Long (); }
- template <> bool To () const { return Bool (); }
- template <> __int64 To () const { return Int64 (); }
- template <> unsigned int To () const { return Int (); }
- template <> unsigned __int64 To () const { return Int64 (); }
- template <> unsigned long To () const { return Long (); }
- template <> WString To () const { return *this; }
- // template <> DString To () const { return this->ToDString (); }
- template <> std::wstring To () const { return std::wstring { m_pchData, static_cast <std::string::size_type> (GetLength ()) }; }
- template <> std::wstring_view To () const { return std::wstring_view { m_pchData, static_cast <std::wstring_view::size_type> (GetLength ()) }; }
- public: // 与 StringView 的转换,构造,赋值等
- WString (const WStringView & Src);
- // WString (const std::wstring_view & Src);
- // 从 DStringView 显式 生成 WString, 需要程序员指定, 以明示: 这种构造是有代价的
- static WString From (const StringView & Src);
- operator WStringView () const noexcept;
- operator std::wstring_view () const noexcept;
- template <> WStringView To () const;
- template <> const WStringView To () const;
- WString & Assign (const WStringView & _Right);
- WString & Assign (const std::wstring_view & _Right);
- WString & Append (std::initializer_list <WStringView> lst);
- WString & Append (std::initializer_list <std::wstring_view> lst);
- WString & Append (std::initializer_list <const wchar_t *> lst);
- WString & Assign (std::initializer_list <std::wstring_view> lst);
- WString & Assign (std::initializer_list <WStringView> lst);
- WString & Assign (std::initializer_list <const wchar_t *> lst);
- // 万一编译器警告: 调用不明确, 就用模板函数显式告诉编译器
- template <typename T> static WString From (std::initializer_list <T> lst) { WString rc; rc.Assign (lst); return rc; }
- static WString From (std::initializer_list <WStringView> lst) { WString rc; rc.Assign (lst); return rc; }
- static WString From (std::initializer_list <std::wstring_view> lst) { WString rc; rc.Assign (lst); return rc; }
- static WString From (std::initializer_list <const wchar_t *> lst) { WString rc; rc.Assign (lst); return rc; }
- protected:
- static int __cdecl GetFormattedLength (const wchar_t * pszFormat, va_list argList);
- static int __cdecl VFormat (wchar_t * lpzBuffer, const wchar_t * pszFormat, va_list argList);
- public:
- // release memory allocated to but unused by string
- void FreeExtra ();
- protected:
- wchar_t * m_pchData; // pointer to ref counted string data
- WStringData * GetData() const
- {
- return ((WStringData *) m_pchData)-1;
- }
- bool IsNil () const; // 用来判断 m_pchData 是否等于 WStringPchNil
- void Init ();
- void AllocCopy (WString& dest, int nCopyLen, int nCopyIndex, int nExtraLen) const;
- void AllocBuffer (int Len);
- void AssignCopy (int Len, const wchar_t * S);
- void ConcatCopy (int L1, const wchar_t * S1, int L2, const wchar_t * S2);
- void ConcatInPlace (int Len, const wchar_t * S);
- void CopyBeforeWrite ();
- void AllocBeforeWrite (int nLen);
- // 拷贝赋值
- WString & Assign (const WString & Src);
- void MoveAssign (WString & Src);
- void MoveAssign (WString && Src);
- static void Release (WStringData * pData);
- static void FreeData (WStringData * pData);
- };
- }
- namespace eSTR = ECOM::Utility::String;
- WSTRING_API eSTR::WString operator + (const eSTR::WString & S1, const eSTR::DString & S2);
- WSTRING_API eSTR::WString operator + (const eSTR::DString & S1, const eSTR::WString & S2);
- WSTRING_API eSTR::WString operator + (const eSTR::WString & S1, const eSTR::WString & S2);
- WSTRING_API eSTR::WString operator + (const eSTR::WString & S, wchar_t ch);
- WSTRING_API eSTR::WString operator + (const eSTR::WString & S1, const eSTR::WStringView & S2);
- WSTRING_API eSTR::WString operator + (const eSTR::WStringView & S1, const eSTR::WString & S2);
- WSTRING_API eSTR::WString operator + (const eSTR::WStringView & S1, wchar_t ch);
- WSTRING_API eSTR::WString operator + (wchar_t ch, const eSTR::WString & S);
- WSTRING_API eSTR::WString operator + (const eSTR::WString & S1, const std::wstring_view & S2);
- WSTRING_API eSTR::WString operator + (const std::wstring_view & S1, const eSTR::WString & S2);
- WSTRING_API eSTR::WString operator + (const std::wstring_view & S1, wchar_t ch);
- WSTRING_API eSTR::WString operator + (const eSTR::WString & S1, const std::wstring & S2);
- WSTRING_API eSTR::WString operator + (const std::wstring & S1, const eSTR::WString & S2);
- WSTRING_API eSTR::WString operator + (const eSTR::WStringView & S1, const eSTR::WStringView & S2);
- // Compare helpers
- WSTRING_API inline bool operator == (const eSTR::WString & s1, const eSTR::WStringView s2) { return s1.Compare (s2) == 0; }
- WSTRING_API inline bool operator != (const eSTR::WString & s1, const eSTR::WStringView s2) { return s1.Compare (s2) != 0; }
- WSTRING_API inline bool operator < (const eSTR::WString & s1, const eSTR::WStringView s2) { return s1.Compare (s2) < 0; }
- WSTRING_API inline bool operator > (const eSTR::WString & s1, const eSTR::WStringView s2) { return s1.Compare (s2) > 0; }
- WSTRING_API inline bool operator <= (const eSTR::WString & s1, const eSTR::WStringView s2) { return s1.Compare (s2) <= 0; }
- WSTRING_API inline bool operator >= (const eSTR::WString & s1, const eSTR::WStringView s2) { return s1.Compare (s2) >= 0; }
- #if 1
- inline bool operator == (const eSTR::WString & s1, const wchar_t * s2) = delete;
- inline bool operator != (const eSTR::WString & s1, const wchar_t * s2) = delete;
- inline bool operator < (const eSTR::WString & s1, const wchar_t * s2) = delete;
- inline bool operator > (const eSTR::WString & s1, const wchar_t * s2) = delete;
- inline bool operator <= (const eSTR::WString & s1, const wchar_t * s2) = delete;
- inline bool operator >= (const eSTR::WString & s1, const wchar_t * s2) = delete;
- #else
- WSTRING_API inline bool operator == (const eSTR::WString & s1, const wchar_t * s2) { return s1.Compare (s2) == 0; }
- WSTRING_API inline bool operator != (const eSTR::WString & s1, const wchar_t * s2) { return s1.Compare (s2) != 0; }
- WSTRING_API inline bool operator < (const eSTR::WString & s1, const wchar_t * s2) { return s1.Compare (s2) < 0; }
- WSTRING_API inline bool operator > (const eSTR::WString & s1, const wchar_t * s2) { return s1.Compare (s2) > 0; }
- WSTRING_API inline bool operator <= (const eSTR::WString & s1, const wchar_t * s2) { return s1.Compare (s2) <= 0; }
- WSTRING_API inline bool operator >= (const eSTR::WString & s1, const wchar_t * s2) { return s1.Compare (s2) >= 0; }
- #endif
- WSTRING_API inline bool operator == (const eSTR::WStringView & s1, const eSTR::WString & s2) { return s2.Compare (s1) == 0; }
- WSTRING_API inline bool operator != (const eSTR::WStringView & s1, const eSTR::WString & s2) { return s2.Compare (s1) != 0; }
- WSTRING_API inline bool operator < (const eSTR::WStringView & s1, const eSTR::WString & s2) { return s2.Compare (s1) > 0; }
- WSTRING_API inline bool operator > (const eSTR::WStringView & s1, const eSTR::WString & s2) { return s2.Compare (s1) < 0; }
- WSTRING_API inline bool operator <= (const eSTR::WStringView & s1, const eSTR::WString & s2) { return s2.Compare (s1) >= 0; }
- WSTRING_API inline bool operator >= (const eSTR::WStringView & s1, const eSTR::WString & s2) { return s2.Compare (s1) <= 0; }
- #if 1
- inline bool operator == (const wchar_t * s1, const eSTR::WString & s2) = delete;
- inline bool operator != (const wchar_t * s1, const eSTR::WString & s2) = delete;
- inline bool operator < (const wchar_t * s1, const eSTR::WString & s2) = delete;
- inline bool operator > (const wchar_t * s1, const eSTR::WString & s2) = delete;
- inline bool operator <= (const wchar_t * s1, const eSTR::WString & s2) = delete;
- inline bool operator >= (const wchar_t * s1, const eSTR::WString & s2) = delete;
- #else
- WSTRING_API inline bool operator == (const wchar_t * s1, const eSTR::WString & s2) { return s2.Compare (s1) == 0; }
- WSTRING_API inline bool operator != (const wchar_t * s1, const eSTR::WString & s2) { return s2.Compare (s1) != 0; }
- WSTRING_API inline bool operator < (const wchar_t * s1, const eSTR::WString & s2) { return s2.Compare (s1) > 0; }
- WSTRING_API inline bool operator > (const wchar_t * s1, const eSTR::WString & s2) { return s2.Compare (s1) < 0; }
- WSTRING_API inline bool operator <= (const wchar_t * s1, const eSTR::WString & s2) { return s2.Compare (s1) >= 0; }
- WSTRING_API inline bool operator >= (const wchar_t * s1, const eSTR::WString & s2) { return s2.Compare (s1) <= 0; }
- #endif
- template <>
- struct std::hash <eSTR::WString>
- {
- size_t operator() (const wchar_t * pc) const noexcept
- {
- auto len = wcslen (pc);
- return std::_Hash_array_representation (pc, len);
- }
- size_t operator() (const eSTR::WString & from) const noexcept
- {
- auto pc = from.constBuffer ();
- auto len = from.GetLength ();
- return std::_Hash_array_representation (pc, len);
- }
- };
- #include "Hash.String.hpp"
- //< 针对 WString 的 Hash. 目的是避免编译器的错误: 重载函数调用不明确
- namespace ECOM::Utility
- {
- inline constexpr size_t Hash (const String::WString & SV)
- {
- return (Hash (SV.To <String::WStringView> ()));
- }
- }
|