String.WString.hpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. #pragma once
  2. #include <string>
  3. #include <locale>
  4. #include <functional>
  5. #include "String.StringView.hpp"
  6. #ifdef DSTRING_EXPORTS
  7. #define WSTRING_API _declspec(dllexport)
  8. #else
  9. #define WSTRING_API _declspec(dllimport)
  10. #endif
  11. #ifdef _DSTRING_STATIC_
  12. #undef WSTRING_API
  13. #define WSTRING_API
  14. #endif
  15. #ifndef DSTRING_EXPORTS
  16. #ifdef _WIN64
  17. #ifdef _DEBUG
  18. #pragma comment (lib, "ECOM.Utility.DString64D.lib")
  19. #else
  20. #pragma comment (lib, "ECOM.Utility.DString64.lib")
  21. #endif
  22. #else // X86
  23. #endif
  24. #endif // DSTRING_EXPORTS
  25. #ifndef _OLEAUTO_H_
  26. typedef LPWSTR BSTR;// must (semantically) match typedef in oleauto.h
  27. #endif
  28. namespace ECOM::Utility::String
  29. {
  30. class DString;
  31. // using size_type = unsigned int; // 用 unsigned int 比较好, 但是会造成很多编译警告
  32. using size_type = int;
  33. //-----------------------------------------------------------------------------
  34. // WStringData
  35. //-----------------------------------------------------------------------------
  36. namespace
  37. {
  38. struct WStringData
  39. {
  40. long nRefs; // reference count
  41. size_type nDataLength; // 字符数, length of data (including terminator)
  42. size_type nAllocLength; // length of allocation
  43. // wchar_t data[nAllocLength]
  44. wchar_t * data () // wchar_t* to managed data
  45. {
  46. return (wchar_t *) (this + 1);
  47. }
  48. };
  49. }
  50. //-----------------------------------------------------------------------------
  51. // WString
  52. //-----------------------------------------------------------------------------
  53. class WSTRING_API WString
  54. {
  55. public:
  56. using value_type = WString;
  57. public:
  58. WString ();
  59. WString (const wchar_t * lpsz) = delete;
  60. WString (const wchar_t * lpsz, int nCount);
  61. WString (const BSTR bstr) = delete;
  62. explicit WString (const DString & From);
  63. explicit WString (const DStringView & From);
  64. WString (const std::wstring & Src);
  65. WString (const WString & Src);
  66. WString (WString && Src);
  67. public:
  68. ~WString ();
  69. public:
  70. // 返回的是字符数, 而不是真正的长度 ! 真正的长度要乘以 2
  71. size_type GetLength () const;
  72. size_type GetByteLength () const { return GetLength () << 1; }
  73. size_type GetAllocLength () const { return GetData ()->nAllocLength; }
  74. size_type size () const { return GetLength (); }
  75. public:
  76. bool empty () const { return IsEmpty (); }
  77. bool IsEmpty () const { return GetLength () <= 0; }
  78. void Clear ();
  79. void Release ();
  80. public:
  81. wchar_t GetAt (int nIndex) const
  82. {
  83. return m_pchData [nIndex];
  84. }
  85. wchar_t operator [] (int nIndex) const { return GetAt (nIndex); }
  86. void SetAt (int nIndex, wchar_t ch);
  87. int Count (wchar_t ch) const;
  88. int Count (const WStringView & Sub) const;
  89. protected:
  90. size_t _Hash () const;
  91. public:
  92. WString & operator = (const wchar_t *) = delete;
  93. WString & operator = (const WString & S);
  94. WString & operator = (const DString & S);
  95. WString & operator = (wchar_t ch);
  96. WString & operator = (const DStringView & S);
  97. WString & operator = (const WStringView & S) { return Assign (S); }
  98. WString & operator = (WString && S);
  99. WString & operator = (const std::wstring & S) { AssignCopy (static_cast <int> (S.size ()), S.c_str ()); return *this; }
  100. WString & operator = (std::initializer_list <WStringView> lst)
  101. {
  102. return Assign (lst);
  103. }
  104. public:
  105. // string concatenation
  106. WString & Append (const WString & S)
  107. {
  108. ConcatInPlace (S.GetData ()->nDataLength, S.m_pchData);
  109. return *this;
  110. }
  111. WString & Append (const DString & S)
  112. {
  113. return Append (WString (S));
  114. }
  115. WString & Append (wchar_t ch)
  116. {
  117. ConcatInPlace (1, &ch);
  118. return *this;
  119. }
  120. WString & Append (const DStringView & S);
  121. WString & Append (const WStringView & S);
  122. WString & Append (const std::wstring_view & S);
  123. WString & Append (const std::wstring & S)
  124. {
  125. ConcatInPlace (static_cast <int> (S.length ()), S.c_str ());
  126. return *this;
  127. }
  128. WString & Append (const char *) = delete; // 改用 L"..."_sv 代替
  129. WString & Append (const wchar_t *) = delete; // 改用 L"..."_sv 代替
  130. WString & operator += (const WString & S) { return Append (S); }
  131. WString & operator += (wchar_t ch) { return Append (ch); }
  132. WString & operator += (const DStringView S) { return Append (S); }
  133. WString & operator += (const WStringView S) { return Append (S); }
  134. WString & operator += (const DString & S) { return Append (S); }
  135. // WString & operator += (const std::wstring & S) { return Append (S); }
  136. WString & operator += (std::initializer_list <WStringView> lst) { return Append (lst); }
  137. // WString & operator += (const char *) = delete; // 改用 L"..."_sv 代替
  138. // WString & operator += (const wchar_t *) = delete; // 改用 L"..."_sv 代替
  139. WString & operator << (const DString & S) { return Append (WString (S)); }
  140. WString & operator << (const DStringView & S) { return Append (S); }
  141. WString & operator << (const WStringView & S) { return Append (S); }
  142. WString & operator << (const WString & S) { return Append (S); }
  143. WString & operator << (wchar_t ch) { return Append (ch); }
  144. WString & operator << (short v) { return Append (From (v)); }
  145. WString & operator << (int v) { return Append (From (v)); }
  146. WString & operator << (long v) { return Append (From (v)); }
  147. WString & operator << (UINT16 v) { return Append (From (v)); }
  148. WString & operator << (UINT32 v) { return Append (From (v)); }
  149. WString & operator << (unsigned long v) { return Append (From (v)); }
  150. // WString & operator << (const std::wstring & S) { return Append (S); }
  151. WString & operator << (std::initializer_list <WStringView> lst) { return Append (lst); }
  152. //< WString & operator << (const char *) = delete; // 改用 L"..."_sv 代替
  153. // WString & operator << (const wchar_t *) = delete; // 改用 L"..."_sv 代替
  154. // 不废除了, 某些强制赋值还是需要的.
  155. // 如果不做提前声明, 编译时发生 C2678: 无法找到匹配的运算符
  156. // 2023-11-14
  157. //>
  158. public:
  159. // string comparison
  160. int Compare (const wchar_t * lpsz) const;
  161. int CompareNoCase (const wchar_t * lpsz) const;
  162. int Compare (const WStringView & With) const;
  163. int Compare (const WString & With) const;
  164. //< 增加命名空间后, std::map <DString, ...> 就需要如下内置比较函数
  165. bool operator == (const WString & with) const { return Compare (with) == 0; }
  166. bool operator != (const WString & with) const { return Compare (with) != 0; }
  167. bool operator < (const WString & with) const { return Compare (with) < 0; }
  168. bool operator > (const WString & with) const { return Compare (with) > 0; }
  169. bool operator <= (const WString & with) const { return Compare (with) <= 0; }
  170. bool operator >= (const WString & with) const { return Compare (with) >= 0; }
  171. public:
  172. WString Mid (int nFirst, int nCount) const;
  173. WString Mid (int nFirst) const;
  174. WString Left (int nCount) const;
  175. WString Right (int nCount) const;
  176. public:
  177. void MakeUpper ();
  178. void MakeLower ();
  179. void MakeReverse ();
  180. public:
  181. int TrimLeft ();
  182. int TrimRight ();
  183. void TrimRight (wchar_t chTarget);
  184. void TrimRight (const WStringView & szTargets);
  185. void TrimLeft (wchar_t chTarget);
  186. void TrimLeft (const WStringView & szTargets);
  187. WString Trim () const { WString copy = *this; copy.TrimRight (); copy.TrimLeft (); return copy; }
  188. public:
  189. // 用指定的字符填充左边/右边/中间, 直到总长度达到指定值为止
  190. void JustLeft (int ToLength, wchar_t ch = ' ');
  191. void JustRight (int ToLength, wchar_t ch = ' ');
  192. void JustCenter (int ToLength, wchar_t ch = ' ');
  193. public:
  194. int Replace (wchar_t chOld, wchar_t chNew);
  195. int Replace (const WString & Old, const WStringView & New);
  196. int Replace (const WStringView & Old, const WStringView & New);
  197. int Remove (const WStringView & Sub);
  198. int Remove (wchar_t chRemove);
  199. int RemoveSpace ();
  200. int RemovePunctuation ();
  201. int RemoveControl ();
  202. // 用谓词函数来判断单个字符是否应该删除, 如果返回 true 就删除
  203. int Remove (std::function <bool (int)> pred);
  204. int NCRemove (const WStringView & lpszSub);
  205. int NCRemove (wchar_t chRemove);
  206. void Repeat (wchar_t ch, int n);
  207. void Repeat (const WStringView & S, int n);
  208. public:
  209. // Pred 返回 true, 表明找到, 否则下一个字符
  210. using tPred = std::function <bool (wchar_t ch)>;
  211. public:
  212. int Find (wchar_t ch, int nStart = 0) const;
  213. int Find (tPred && pred, int nStart = 0) const;
  214. int Find (const WStringView & Sub, int nStart = 0) const;
  215. int Find (const WString & Sub, int nStart = 0) const;
  216. // find at right
  217. int ReverseFind (wchar_t ch, int nStart = 0) const;
  218. int ReverseFind (const WStringView & Sub, int nStart = 0) const;
  219. bool StartWith (const WStringView & Sub, int iStart = 0) const;
  220. bool EndWith (const WStringView & Sub, int iStart = 0) const;
  221. bool StartWith (const WString & Sub, int iStart = 0) const { return StartWith (Sub.To <WStringView> (), iStart); }
  222. bool EndWith (const WString & Sub, int iStart = 0) const { return EndWith (Sub.To <WStringView> (), iStart); }
  223. bool StartWith (wchar_t ch, int iStart = 0) const;
  224. bool EndWith (wchar_t ch, int iStart = 0) const;
  225. int NCFind (wchar_t ch) const;
  226. int NCFind (const WStringView & Sub) const;
  227. public:
  228. using tvCallback = std::function <void (CV_WString & sub)>;
  229. // 如果回调返回 true, 则继续, 否则停止
  230. using tbCallback = std::function <bool (int Index, CV_WString & sub)>;
  231. int Split (wchar_t ch , tvCallback && onFound, int start = 0) const;
  232. int Split (tPred && pred, tvCallback && onFound, int start = 0) const;
  233. int SplitIf (wchar_t ch , tbCallback && onFound, int start = 0) const;
  234. int SplitIf (tPred && pred, tbCallback && onFound, int start = 0) const;
  235. // 分割成列表
  236. auto SplitTo (wchar_t ch , int start = 0) const -> std::list <WString>;
  237. auto SplitTo (tPred && pred, int start = 0) const -> std::list <WString>;
  238. // 分割成数组, 最多 Max 个
  239. auto SplitMax (int Max, wchar_t ch , int start = 0) const -> std::vector <WString>;
  240. auto SplitMax (int Max, tPred && pred, int start = 0) const -> std::vector <WString>;
  241. // 返回指定 Index 的某一个, 如果找不到: 当 Index=0 时返回本串, 否则返回空串
  242. auto SplitOne (int atIndex, wchar_t ch , int start = 0) const ->WString;
  243. auto SplitOne (int atIndex, tPred && pred, int start = 0) const ->WString;
  244. // Cast
  245. public:
  246. operator const wchar_t * () const { return m_pchData; }
  247. const wchar_t * constBuffer () const { return m_pchData; }
  248. wchar_t * data () const { return m_pchData; }
  249. const wchar_t * c_str () const { return m_pchData; }
  250. DString ToDString () const;
  251. DString ToDString (UINT CodePage) const;
  252. DString ToDString (const char * LocName) const;
  253. DString ToDString (const _locale_t Loc) const;
  254. // explicit operator const DString () const { return ToDString (); }
  255. operator const DString () const = delete;
  256. operator bool () const = delete;
  257. // 用于自动判别类型
  258. public:
  259. template <typename T> bool Is () const { return false; }
  260. template <> bool Is <WString> () const { return true; }
  261. template <> bool Is <DString> () const { return false; }
  262. public:
  263. static WString From (const int i);
  264. static WString From (const long i);
  265. static WString From (const unsigned int u);
  266. static WString From (const unsigned long u);
  267. static WString From (const __int64 i);
  268. static WString From (const unsigned __int64 u);
  269. static WString From (const double d);
  270. static WString From (const std::wstring_view & Src);
  271. static WString From (CV_WString & Src) { return WString (Src); }
  272. static WString From (const WString & Src) { return WString (Src); }
  273. static WString From (const char * Src) { return FromCodePage (Src, CP_ACP); }
  274. static WString From (const wchar_t * lpsz) { return (CV_WString) lpsz; }
  275. static WString FromCodePage (const DString & from, UINT CodePage);
  276. static WString FromCodePage (const std::string & from, UINT CodePage);
  277. static WString FromCodePage (const std::string_view & from, UINT CodePage);
  278. static WString FromCodePage (const char * from, UINT CodePage);
  279. static WString FromCodePage (const char * from, int len, UINT CodePage);
  280. static WString FromLocale (const DString & from, const char * LocName);
  281. static WString FromLocale (const char * from, const char * LocName);
  282. static WString FromLocale (const char * from, int len, const char * LocName);
  283. static WString FromLocale (const DString & from, const _locale_t Loc);
  284. static WString FromLocale (const char * from, const _locale_t Loc);
  285. static WString FromLocale (const char * from, int len, const _locale_t Loc);
  286. // repeat a single character
  287. static WString FromRepeat (wchar_t ch, int nRepeat);
  288. protected:
  289. void FormatV (const wchar_t * lpszFormat, va_list argList);
  290. void AppendFormatV (const wchar_t * lpszFormat, va_list argList);
  291. protected:
  292. // 对于字符串,代码中很容易忘记 L 前缀, 导致传入的是 char *, 而期望的是 wchar_t *
  293. // 比如, 正确的写法是: Format ("%s", L"abcd"); 但是很容易写成 Format ("%s", "abcd");
  294. // 为了避免出现这种 BUG, 把这几个函数改成 protected
  295. static WString FromFormat (const wchar_t * szFormat, ...);
  296. void Format (const wchar_t * lpszFormat, ...);
  297. void AppendFormat (const wchar_t * lpszFormat, ...);
  298. public:
  299. // get pointer to modifiable buffer at least as long as nMinBufLength
  300. wchar_t * GetBuffer (int nMinBufLength);
  301. // release buffer, setting length to nNewLength (or to first nul if -1)
  302. void ReleaseBuffer (int nNewLength = -1);
  303. // get pointer to modifiable buffer exactly as long as nNewLength
  304. wchar_t * GetBufferSetLength (int nNewLength);
  305. void Reserve (int nMinBufLength) { GetBuffer (nMinBufLength); }
  306. void reserve (int nMinBufLength) { GetBuffer (nMinBufLength); }
  307. public:
  308. double Double () const { return _wtof (m_pchData); }
  309. int Int () const { int i = _wtoi (m_pchData); if (i) return i; return wcstol (m_pchData, NULL, 16); }
  310. long Long () const { long l = _wtol (m_pchData); if (l) return l; return wcstol (m_pchData, NULL, 16); }
  311. wchar_t Char () const { return m_pchData[0]; }
  312. bool Bool () const;
  313. __int64 Int64 () const { __int64 i = _wtoi64 (m_pchData); if (i) return i; return _wcstoi64 (m_pchData, NULL, 16); }
  314. template <typename T> T To () const = delete;
  315. template <> int To () const { return Int (); }
  316. template <> double To () const { return Double (); }
  317. template <> float To () const { return (float) Double (); }
  318. template <> long To () const { return Long (); }
  319. template <> bool To () const { return Bool (); }
  320. template <> __int64 To () const { return Int64 (); }
  321. template <> unsigned int To () const { return Int (); }
  322. template <> unsigned __int64 To () const { return Int64 (); }
  323. template <> unsigned long To () const { return Long (); }
  324. template <> WString To () const { return *this; }
  325. // template <> DString To () const { return this->ToDString (); }
  326. template <> std::wstring To () const { return std::wstring { m_pchData, static_cast <std::string::size_type> (GetLength ()) }; }
  327. template <> std::wstring_view To () const { return std::wstring_view { m_pchData, static_cast <std::wstring_view::size_type> (GetLength ()) }; }
  328. public: // 与 StringView 的转换,构造,赋值等
  329. WString (const WStringView & Src);
  330. // WString (const std::wstring_view & Src);
  331. // 从 DStringView 显式 生成 WString, 需要程序员指定, 以明示: 这种构造是有代价的
  332. static WString From (const StringView & Src);
  333. operator WStringView () const noexcept;
  334. operator std::wstring_view () const noexcept;
  335. template <> WStringView To () const;
  336. template <> const WStringView To () const;
  337. WString & Assign (const WStringView & _Right);
  338. WString & Assign (const std::wstring_view & _Right);
  339. WString & Append (std::initializer_list <WStringView> lst);
  340. WString & Append (std::initializer_list <std::wstring_view> lst);
  341. WString & Append (std::initializer_list <const wchar_t *> lst);
  342. WString & Assign (std::initializer_list <std::wstring_view> lst);
  343. WString & Assign (std::initializer_list <WStringView> lst);
  344. WString & Assign (std::initializer_list <const wchar_t *> lst);
  345. // 万一编译器警告: 调用不明确, 就用模板函数显式告诉编译器
  346. template <typename T> static WString From (std::initializer_list <T> lst) { WString rc; rc.Assign (lst); return rc; }
  347. static WString From (std::initializer_list <WStringView> lst) { WString rc; rc.Assign (lst); return rc; }
  348. static WString From (std::initializer_list <std::wstring_view> lst) { WString rc; rc.Assign (lst); return rc; }
  349. static WString From (std::initializer_list <const wchar_t *> lst) { WString rc; rc.Assign (lst); return rc; }
  350. protected:
  351. static int __cdecl GetFormattedLength (const wchar_t * pszFormat, va_list argList);
  352. static int __cdecl VFormat (wchar_t * lpzBuffer, const wchar_t * pszFormat, va_list argList);
  353. public:
  354. // release memory allocated to but unused by string
  355. void FreeExtra ();
  356. protected:
  357. wchar_t * m_pchData; // pointer to ref counted string data
  358. WStringData * GetData() const
  359. {
  360. return ((WStringData *) m_pchData)-1;
  361. }
  362. bool IsNil () const; // 用来判断 m_pchData 是否等于 WStringPchNil
  363. void Init ();
  364. void AllocCopy (WString& dest, int nCopyLen, int nCopyIndex, int nExtraLen) const;
  365. void AllocBuffer (int Len);
  366. void AssignCopy (int Len, const wchar_t * S);
  367. void ConcatCopy (int L1, const wchar_t * S1, int L2, const wchar_t * S2);
  368. void ConcatInPlace (int Len, const wchar_t * S);
  369. void CopyBeforeWrite ();
  370. void AllocBeforeWrite (int nLen);
  371. // 拷贝赋值
  372. WString & Assign (const WString & Src);
  373. void MoveAssign (WString & Src);
  374. void MoveAssign (WString && Src);
  375. static void Release (WStringData * pData);
  376. static void FreeData (WStringData * pData);
  377. };
  378. }
  379. namespace eSTR = ECOM::Utility::String;
  380. WSTRING_API eSTR::WString operator + (const eSTR::WString & S1, const eSTR::DString & S2);
  381. WSTRING_API eSTR::WString operator + (const eSTR::DString & S1, const eSTR::WString & S2);
  382. WSTRING_API eSTR::WString operator + (const eSTR::WString & S1, const eSTR::WString & S2);
  383. WSTRING_API eSTR::WString operator + (const eSTR::WString & S, wchar_t ch);
  384. WSTRING_API eSTR::WString operator + (const eSTR::WString & S1, const eSTR::WStringView & S2);
  385. WSTRING_API eSTR::WString operator + (const eSTR::WStringView & S1, const eSTR::WString & S2);
  386. WSTRING_API eSTR::WString operator + (const eSTR::WStringView & S1, wchar_t ch);
  387. WSTRING_API eSTR::WString operator + (wchar_t ch, const eSTR::WString & S);
  388. WSTRING_API eSTR::WString operator + (const eSTR::WString & S1, const std::wstring_view & S2);
  389. WSTRING_API eSTR::WString operator + (const std::wstring_view & S1, const eSTR::WString & S2);
  390. WSTRING_API eSTR::WString operator + (const std::wstring_view & S1, wchar_t ch);
  391. WSTRING_API eSTR::WString operator + (const eSTR::WString & S1, const std::wstring & S2);
  392. WSTRING_API eSTR::WString operator + (const std::wstring & S1, const eSTR::WString & S2);
  393. WSTRING_API eSTR::WString operator + (const eSTR::WStringView & S1, const eSTR::WStringView & S2);
  394. // Compare helpers
  395. WSTRING_API inline bool operator == (const eSTR::WString & s1, const eSTR::WStringView s2) { return s1.Compare (s2) == 0; }
  396. WSTRING_API inline bool operator != (const eSTR::WString & s1, const eSTR::WStringView s2) { return s1.Compare (s2) != 0; }
  397. WSTRING_API inline bool operator < (const eSTR::WString & s1, const eSTR::WStringView s2) { return s1.Compare (s2) < 0; }
  398. WSTRING_API inline bool operator > (const eSTR::WString & s1, const eSTR::WStringView s2) { return s1.Compare (s2) > 0; }
  399. WSTRING_API inline bool operator <= (const eSTR::WString & s1, const eSTR::WStringView s2) { return s1.Compare (s2) <= 0; }
  400. WSTRING_API inline bool operator >= (const eSTR::WString & s1, const eSTR::WStringView s2) { return s1.Compare (s2) >= 0; }
  401. #if 1
  402. inline bool operator == (const eSTR::WString & s1, const wchar_t * s2) = delete;
  403. inline bool operator != (const eSTR::WString & s1, const wchar_t * s2) = delete;
  404. inline bool operator < (const eSTR::WString & s1, const wchar_t * s2) = delete;
  405. inline bool operator > (const eSTR::WString & s1, const wchar_t * s2) = delete;
  406. inline bool operator <= (const eSTR::WString & s1, const wchar_t * s2) = delete;
  407. inline bool operator >= (const eSTR::WString & s1, const wchar_t * s2) = delete;
  408. #else
  409. WSTRING_API inline bool operator == (const eSTR::WString & s1, const wchar_t * s2) { return s1.Compare (s2) == 0; }
  410. WSTRING_API inline bool operator != (const eSTR::WString & s1, const wchar_t * s2) { return s1.Compare (s2) != 0; }
  411. WSTRING_API inline bool operator < (const eSTR::WString & s1, const wchar_t * s2) { return s1.Compare (s2) < 0; }
  412. WSTRING_API inline bool operator > (const eSTR::WString & s1, const wchar_t * s2) { return s1.Compare (s2) > 0; }
  413. WSTRING_API inline bool operator <= (const eSTR::WString & s1, const wchar_t * s2) { return s1.Compare (s2) <= 0; }
  414. WSTRING_API inline bool operator >= (const eSTR::WString & s1, const wchar_t * s2) { return s1.Compare (s2) >= 0; }
  415. #endif
  416. WSTRING_API inline bool operator == (const eSTR::WStringView & s1, const eSTR::WString & s2) { return s2.Compare (s1) == 0; }
  417. WSTRING_API inline bool operator != (const eSTR::WStringView & s1, const eSTR::WString & s2) { return s2.Compare (s1) != 0; }
  418. WSTRING_API inline bool operator < (const eSTR::WStringView & s1, const eSTR::WString & s2) { return s2.Compare (s1) > 0; }
  419. WSTRING_API inline bool operator > (const eSTR::WStringView & s1, const eSTR::WString & s2) { return s2.Compare (s1) < 0; }
  420. WSTRING_API inline bool operator <= (const eSTR::WStringView & s1, const eSTR::WString & s2) { return s2.Compare (s1) >= 0; }
  421. WSTRING_API inline bool operator >= (const eSTR::WStringView & s1, const eSTR::WString & s2) { return s2.Compare (s1) <= 0; }
  422. #if 1
  423. inline bool operator == (const wchar_t * s1, const eSTR::WString & s2) = delete;
  424. inline bool operator != (const wchar_t * s1, const eSTR::WString & s2) = delete;
  425. inline bool operator < (const wchar_t * s1, const eSTR::WString & s2) = delete;
  426. inline bool operator > (const wchar_t * s1, const eSTR::WString & s2) = delete;
  427. inline bool operator <= (const wchar_t * s1, const eSTR::WString & s2) = delete;
  428. inline bool operator >= (const wchar_t * s1, const eSTR::WString & s2) = delete;
  429. #else
  430. WSTRING_API inline bool operator == (const wchar_t * s1, const eSTR::WString & s2) { return s2.Compare (s1) == 0; }
  431. WSTRING_API inline bool operator != (const wchar_t * s1, const eSTR::WString & s2) { return s2.Compare (s1) != 0; }
  432. WSTRING_API inline bool operator < (const wchar_t * s1, const eSTR::WString & s2) { return s2.Compare (s1) > 0; }
  433. WSTRING_API inline bool operator > (const wchar_t * s1, const eSTR::WString & s2) { return s2.Compare (s1) < 0; }
  434. WSTRING_API inline bool operator <= (const wchar_t * s1, const eSTR::WString & s2) { return s2.Compare (s1) >= 0; }
  435. WSTRING_API inline bool operator >= (const wchar_t * s1, const eSTR::WString & s2) { return s2.Compare (s1) <= 0; }
  436. #endif
  437. template <>
  438. struct std::hash <eSTR::WString>
  439. {
  440. size_t operator() (const wchar_t * pc) const noexcept
  441. {
  442. auto len = wcslen (pc);
  443. return std::_Hash_array_representation (pc, len);
  444. }
  445. size_t operator() (const eSTR::WString & from) const noexcept
  446. {
  447. auto pc = from.constBuffer ();
  448. auto len = from.GetLength ();
  449. return std::_Hash_array_representation (pc, len);
  450. }
  451. };
  452. #include "Hash.String.hpp"
  453. //< 针对 WString 的 Hash. 目的是避免编译器的错误: 重载函数调用不明确
  454. namespace ECOM::Utility
  455. {
  456. inline constexpr size_t Hash (const String::WString & SV)
  457. {
  458. return (Hash (SV.To <String::WStringView> ()));
  459. }
  460. }