StringT.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930
  1. /*
  2. * Copyright: JessMA Open Source (ldcsaa@gmail.com)
  3. *
  4. * Author : Bruce Liang
  5. * Website : https://github.com/ldcsaa
  6. * Project : https://github.com/ldcsaa/HP-Socket
  7. * Blog : http://www.cnblogs.com/ldcsaa
  8. * Wiki : http://www.oschina.net/p/hp-socket
  9. * QQ Group : 44636872, 75375912
  10. *
  11. * Licensed under the Apache License, Version 2.0 (the "License");
  12. * you may not use this file except in compliance with the License.
  13. * You may obtain a copy of the License at
  14. *
  15. * http://www.apache.org/licenses/LICENSE-2.0
  16. *
  17. * Unless required by applicable law or agreed to in writing, software
  18. * distributed under the License is distributed on an "AS IS" BASIS,
  19. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  20. * See the License for the specific language governing permissions and
  21. * limitations under the License.
  22. */
  23. #pragma once
  24. #include "FuncHelper.h"
  25. #include <stdarg.h>
  26. #include <string.h>
  27. #include <string>
  28. using namespace std;
  29. template<typename _CharT, typename _Traits = char_traits<_CharT>, typename _Alloc = allocator<_CharT>>
  30. class CStringT : public basic_string<_CharT, _Traits, _Alloc>
  31. {
  32. public:
  33. using __super = basic_string<_CharT, _Traits, _Alloc>;
  34. using XCHAR = _CharT;
  35. using PXSTR = _CharT*;
  36. using PCXSTR = const _CharT*;
  37. using traits_type = typename __super::traits_type;
  38. using value_type = typename __super::value_type;
  39. using allocator_type = typename __super::allocator_type;
  40. using size_type = typename __super::size_type;
  41. using difference_type = typename __super::difference_type;
  42. using reference = typename __super::reference;
  43. using const_reference = typename __super::const_reference;
  44. using pointer = typename __super::pointer;
  45. using const_pointer = typename __super::const_pointer;
  46. using iterator = typename __super::iterator;
  47. using const_iterator = typename __super::const_iterator;
  48. using const_reverse_iterator = typename __super::const_reverse_iterator;
  49. using reverse_iterator = typename __super::reverse_iterator;
  50. using __super::clear;
  51. using __super::empty;
  52. using __super::size;
  53. using __super::resize;
  54. using __super::data;
  55. using __super::c_str;
  56. private:
  57. constexpr static PCXSTR SPACE_CHARS = _T(" \t\r\n\f\v");
  58. public:
  59. void Empty() {clear();}
  60. bool IsEmpty() const {return empty();}
  61. int GetLength() const {return (int)size();}
  62. const _CharT* GetString() const {return c_str();}
  63. operator const _CharT* () const {return __super::c_str();}
  64. _CharT* GetBuffer(int length)
  65. {
  66. resize((size_type)length);
  67. return (_CharT*)data();
  68. }
  69. void ReleaseBuffer(int length = -1)
  70. {
  71. if(length == -1)
  72. length = lstrlen(data());
  73. resize(length);
  74. }
  75. void ReleaseBufferSetLength(int length)
  76. {
  77. ASSERT(length >=0);
  78. ReleaseBuffer(length);
  79. }
  80. void Truncate(int length)
  81. {
  82. if(length >= GetLength())
  83. return;
  84. ReleaseBuffer(length);
  85. }
  86. int Format(const _CharT* format, ...)
  87. {
  88. int rs;
  89. va_list ap;
  90. va_start(ap, format);
  91. rs = VASprintf(0, format, ap);
  92. va_end(ap);
  93. return rs;
  94. }
  95. int AppendFormat(const _CharT* format, ...)
  96. {
  97. int rs;
  98. va_list ap;
  99. va_start(ap, format);
  100. rs = VASprintf(GetLength(), format, ap);
  101. va_end(ap);
  102. return rs;
  103. }
  104. int VASprintf(int offset, const _CharT* format, va_list ap)
  105. {
  106. va_list ap_cpy;
  107. va_copy(ap_cpy, ap);
  108. int count = vsnprintf(nullptr, 0, format, ap);
  109. if(count >= 0)
  110. {
  111. _CharT* p = GetBuffer(count + offset);
  112. vsnprintf(p + offset, count + 1, format, ap_cpy);
  113. }
  114. va_end(ap_cpy);
  115. return count;
  116. }
  117. CStringT& Append(const _CharT* __s)
  118. {
  119. append(__s);
  120. return *this;
  121. }
  122. CStringT& Append(const _CharT* __s, int __n)
  123. {
  124. append(__s, __n);
  125. return *this;
  126. }
  127. CStringT& AppendChar(_CharT __c)
  128. {
  129. push_back(__c);
  130. return *this;
  131. }
  132. int Compare(const _CharT* __s) const
  133. {
  134. return lstrcmp(c_str(), __s);
  135. }
  136. int CompareNoCase(const _CharT* __s) const
  137. {
  138. return lstricmp(c_str(), __s);
  139. }
  140. bool Equals(const _CharT* __s) const
  141. {
  142. return (Compare(__s) == 0);
  143. }
  144. bool EqualsNoCase(const _CharT* __s) const
  145. {
  146. return (CompareNoCase(__s) == 0);
  147. }
  148. CStringT& MakeLower()
  149. {
  150. size_type s = size();
  151. _CharT* p = (_CharT*)c_str();
  152. _CharT c;
  153. for(size_type i = 0; i < s; i++)
  154. {
  155. c = p[i];
  156. if(c >= 'A' && c <= 'Z')
  157. p[i] = (_CharT)(c + 32);
  158. }
  159. return *this;
  160. }
  161. CStringT& MakeUpper()
  162. {
  163. size_type s = size();
  164. _CharT* p = (_CharT*)c_str();
  165. _CharT c;
  166. for(size_type i = 0; i < s; i++)
  167. {
  168. c = p[i];
  169. if(c >= 'a' && c <= 'z')
  170. p[i] = (_CharT)(c - 32);
  171. }
  172. return *this;
  173. }
  174. CStringT Mid(int iFirst, int nCount = (int)__super::npos) const
  175. {
  176. return substr(iFirst, nCount);
  177. }
  178. CStringT Left(int nCount) const
  179. {
  180. return Mid(0, nCount);
  181. }
  182. CStringT Right(int nCount) const
  183. {
  184. int nLength = GetLength();
  185. if(nCount >= nLength)
  186. return *this;
  187. return Mid(nLength - nCount, nCount);
  188. }
  189. CStringT Tokenize(PCXSTR lpszTokens, int& iStart) const
  190. {
  191. ASSERT(iStart >= 0);
  192. if((lpszTokens == nullptr) || (*lpszTokens == (_CharT)0))
  193. {
  194. if(iStart < GetLength())
  195. return CStringT(GetString() + iStart);
  196. }
  197. else
  198. {
  199. PCXSTR pszPlace = GetString() + iStart;
  200. PCXSTR pszEnd = GetString() + GetLength();
  201. if(pszPlace < pszEnd)
  202. {
  203. int nIncluding = lstrspn(pszPlace, lpszTokens);
  204. if((pszPlace + nIncluding) < pszEnd)
  205. {
  206. pszPlace += nIncluding;
  207. int nExcluding = lstrcspn(pszPlace, lpszTokens);
  208. int iFrom = iStart + nIncluding;
  209. int nUntil = nExcluding;
  210. iStart = iFrom + nUntil + 1;
  211. return Mid(iFrom, nUntil);
  212. }
  213. }
  214. }
  215. iStart = -1;
  216. return CStringT();
  217. }
  218. CStringT& Trim()
  219. {
  220. return Trim(SPACE_CHARS);
  221. }
  222. CStringT& TrimRight()
  223. {
  224. return TrimRight(SPACE_CHARS);
  225. }
  226. CStringT& TrimLeft()
  227. {
  228. return TrimLeft(SPACE_CHARS);
  229. }
  230. CStringT& Trim(XCHAR c)
  231. {
  232. return(TrimRight(c).TrimLeft(c));
  233. }
  234. CStringT& TrimRight(XCHAR c)
  235. {
  236. int iLength = GetLength();
  237. if(iLength == 0)
  238. return *this;
  239. PCXSTR lpszBegin = GetString();
  240. PCXSTR lpszEnd = lpszBegin + iLength;
  241. while(lpszEnd > lpszBegin)
  242. {
  243. if(*(lpszEnd - 1) != c)
  244. break;
  245. --lpszEnd;
  246. }
  247. int iNewLength = (int)(lpszEnd - lpszBegin);
  248. if(iNewLength < iLength)
  249. Truncate(iNewLength);
  250. return *this;
  251. }
  252. CStringT& TrimLeft(XCHAR c)
  253. {
  254. int iLength = GetLength();
  255. if(iLength == 0)
  256. return *this;
  257. PCXSTR lpszBegin = GetString();
  258. PCXSTR lpszEnd = lpszBegin;
  259. int iOffset = 0;
  260. while(*lpszEnd == c)
  261. {
  262. ++lpszEnd;
  263. ++iOffset;
  264. if(iOffset == iLength)
  265. break;
  266. }
  267. if(iOffset != 0)
  268. {
  269. int iNewLength = iLength - iOffset;
  270. if(iNewLength > 0)
  271. memcpy((PXSTR)lpszBegin, lpszEnd, (iLength - iOffset) * sizeof(XCHAR));
  272. ReleaseBufferSetLength(iNewLength);
  273. }
  274. return *this;
  275. }
  276. CStringT& Trim(PCXSTR lpszChars)
  277. {
  278. return(TrimRight(lpszChars).TrimLeft(lpszChars));
  279. }
  280. CStringT& TrimRight(PCXSTR lpszChars)
  281. {
  282. ASSERT(!::IsStrEmpty(lpszChars));
  283. if(::IsStrEmpty(lpszChars))
  284. return *this;
  285. int iLength = GetLength();
  286. if(iLength == 0)
  287. return *this;
  288. PCXSTR lpszBegin = GetString();
  289. PCXSTR lpszEnd = lpszBegin + iLength;
  290. while(lpszEnd > lpszBegin)
  291. {
  292. if(::StrChr(lpszChars, *(lpszEnd - 1)) == nullptr)
  293. break;
  294. --lpszEnd;
  295. }
  296. int iNewLength = (int)(lpszEnd - lpszBegin);
  297. if(iNewLength < iLength)
  298. Truncate(iNewLength);
  299. return *this;
  300. }
  301. CStringT& TrimLeft(PCXSTR lpszChars)
  302. {
  303. ASSERT(!::IsStrEmpty(lpszChars));
  304. if(::IsStrEmpty(lpszChars))
  305. return *this;
  306. int iLength = GetLength();
  307. if(iLength == 0)
  308. return *this;
  309. PCXSTR lpszBegin = GetString();
  310. PCXSTR lpszEnd = lpszBegin;
  311. int iOffset = 0;
  312. while(::StrChr(lpszChars, *lpszEnd) != nullptr)
  313. {
  314. ++lpszEnd;
  315. ++iOffset;
  316. if(iOffset == iLength)
  317. break;
  318. }
  319. if(iOffset != 0)
  320. {
  321. int iNewLength = iLength - iOffset;
  322. if(iNewLength > 0)
  323. memcpy((PXSTR)lpszBegin, lpszEnd, (iLength - iOffset) * sizeof(XCHAR));
  324. ReleaseBufferSetLength(iNewLength);
  325. }
  326. return *this;
  327. }
  328. int Find(XCHAR c, int iStart = 0) const
  329. {
  330. ASSERT(iStart >= 0);
  331. int iLength = GetLength();
  332. if(iStart < 0 || iStart >= iLength)
  333. return -1;
  334. PCXSTR lpszBegin = GetString();
  335. PCXSTR lpszFind = ::StrChr(lpszBegin + iStart, c);
  336. return ((lpszFind == nullptr) ? -1 : (int)(lpszFind - lpszBegin));
  337. }
  338. int Find(PCXSTR lpszSub, int iStart = 0) const
  339. {
  340. ASSERT(iStart >= 0 && !::IsStrEmpty(lpszSub));
  341. int iLength = GetLength();
  342. if(lpszSub == nullptr || iStart < 0 || iStart > iLength)
  343. return -1;
  344. PCXSTR lpszBegin = GetString();
  345. PCXSTR lpszFind = ::StrStr(lpszBegin + iStart, lpszSub);
  346. return ((lpszFind == nullptr) ? -1 : (int)(lpszFind - lpszBegin));
  347. }
  348. int FindOneOf(PCXSTR lpszChars) const
  349. {
  350. ASSERT(!::IsStrEmpty(lpszChars));
  351. if(lpszChars == nullptr)
  352. return -1;
  353. PCXSTR lpszBegin = GetString();
  354. PCXSTR lpszFind = ::StrPBrk(lpszBegin, lpszChars);
  355. return ((lpszFind == nullptr) ? -1 : (int)(lpszFind - lpszBegin));
  356. }
  357. int ReverseFind(XCHAR c) const
  358. {
  359. PCXSTR lpszBegin = GetString();
  360. PCXSTR lpszFind = ::StrRChr(lpszBegin, c);
  361. return ((lpszFind == nullptr) ? -1 : (int)(lpszFind - lpszBegin));
  362. }
  363. int Remove(XCHAR c)
  364. {
  365. int iLength = GetLength();
  366. if(iLength == 0)
  367. return 0;
  368. PCXSTR lpszBegin = GetString();
  369. PXSTR lpszCur = (PXSTR)lpszBegin;
  370. PCXSTR lpszEnd = lpszBegin + iLength;
  371. int iRemoved = 0;
  372. while(lpszCur < lpszEnd)
  373. {
  374. if(*lpszCur == c)
  375. ++iRemoved;
  376. else if(iRemoved > 0)
  377. *(lpszCur - iRemoved) = *lpszCur;
  378. ++lpszCur;
  379. }
  380. if(iRemoved > 0)
  381. ReleaseBufferSetLength(iLength - iRemoved);
  382. return iRemoved;
  383. }
  384. XCHAR GetAt(int i) const
  385. {
  386. return (*this)[i];
  387. }
  388. void SetAt(int i, XCHAR c)
  389. {
  390. (*this)[i] = c;
  391. }
  392. XCHAR operator[](int i) const
  393. {
  394. ASSERT(i >= 0 && i < GetLength());
  395. return *(GetString() + i);
  396. }
  397. XCHAR& operator[](int i)
  398. {
  399. ASSERT(i >= 0 && i < GetLength());
  400. return *(PXSTR)(GetString() + i);
  401. }
  402. CStringT& Insert(int i, XCHAR c)
  403. {
  404. return insert((size_type)i, 1, c);
  405. }
  406. CStringT& Insert(int i, PCXSTR lpszChars)
  407. {
  408. return insert((size_type)i, lpszChars);
  409. }
  410. CStringT& SetString(PCXSTR lpszStr)
  411. {
  412. return assign(lpszStr);
  413. }
  414. CStringT& SetString(PCXSTR lpszStr, int iLength)
  415. {
  416. return assign(lpszStr, iLength);
  417. }
  418. friend bool operator==(const CStringT& str1, const CStringT& str2)
  419. {
  420. return (str1.Compare(str2) == 0);
  421. }
  422. friend bool operator==(const CStringT& str1, const _CharT* psz2)
  423. {
  424. return (str1.Compare(psz2) == 0);
  425. }
  426. friend bool operator==(const _CharT* psz1, const CStringT& str2)
  427. {
  428. return (str2.Compare(psz1) == 0);
  429. }
  430. friend bool operator!=(const CStringT& str1, const CStringT& str2)
  431. {
  432. return !(str1 == str2);
  433. }
  434. friend bool operator!=(const CStringT& str1, const _CharT* psz2)
  435. {
  436. return !(str1 == psz2);
  437. }
  438. friend bool operator!=(const _CharT* psz1, const CStringT& str2)
  439. {
  440. return !(psz1 == str2);
  441. }
  442. public:
  443. CStringT() : __super() {};
  444. explicit CStringT(const _Alloc& __a)
  445. : __super(__a) {}
  446. CStringT(const __super& __str)
  447. : __super(__str) {}
  448. CStringT(const CStringT& __str)
  449. : __super(__str) {}
  450. CStringT(const __super& __str, size_type __pos, size_type __n = __super::npos)
  451. : __super(__str, __pos, __n) {}
  452. CStringT(const __super& __str, size_type __pos, size_type __n, const _Alloc& __a)
  453. : __super(__str, __pos, __n, __a) {}
  454. CStringT(const _CharT* __s, size_type __n, const _Alloc& __a = _Alloc())
  455. : __super(::SafeStr(__s), __n, __a) {}
  456. CStringT(const _CharT* __s, const _Alloc& __a = _Alloc())
  457. : __super(::SafeStr(__s), __a) {}
  458. CStringT(size_type __n, _CharT __c, const _Alloc& __a = _Alloc())
  459. : __super(__n, __c, __a) {}
  460. #if __cplusplus >= 201103L
  461. CStringT(__super&& __str)
  462. : __super(__str) {}
  463. CStringT(CStringT&& __str)
  464. : __super(__str) {}
  465. CStringT(initializer_list<_CharT> __l, const _Alloc& __a = _Alloc())
  466. : __super(__l, __a) {}
  467. #endif // C++11
  468. template<class _InputIterator>
  469. CStringT(_InputIterator __beg, _InputIterator __end, const _Alloc& __a = _Alloc())
  470. : __super(__beg, __end, __a) {}
  471. ~CStringT() = default;
  472. CStringT& operator=(const __super& __str)
  473. {__super::operator=(__str); return *this;}
  474. CStringT& operator=(const CStringT& __str)
  475. {__super::operator=(__str); return *this;}
  476. CStringT& operator=(const _CharT* __s)
  477. {__super::operator=(::SafeStr(__s)); return *this;}
  478. CStringT& operator=(_CharT __c)
  479. {__super::operator=(__c); return *this;}
  480. #if __cplusplus >= 201103L
  481. CStringT& operator=(__super&& __str)
  482. {__super::operator=(__str); return *this;}
  483. CStringT& operator=(CStringT&& __str)
  484. {__super::operator=(__str); return *this;}
  485. CStringT& operator=(initializer_list<_CharT> __l)
  486. {__super::operator=(__l); return *this;}
  487. #endif // C++11
  488. public:
  489. CStringT& operator+=(const __super& __str)
  490. {__super::operator+=(__str); return *this;}
  491. CStringT& operator+=(const _CharT* __s)
  492. {__super::operator+=(::SafeStr(__s)); return *this;}
  493. CStringT& operator+=(_CharT __c)
  494. {__super::operator+=(__c); return *this;}
  495. #if __cplusplus >= 201103L
  496. CStringT& operator+=(initializer_list<_CharT> __l)
  497. {__super::operator+=(__l); return *this;}
  498. #endif // C++11
  499. CStringT& append(const __super& __str)
  500. {__super::append(__str); return *this;}
  501. CStringT& append(const __super& __str, size_type __pos, size_type __n)
  502. {__super::append(__str, __pos, __n); return *this;}
  503. CStringT& append(const _CharT* __s, size_type __n)
  504. {__super::append(::SafeStr(__s), __n); return *this;}
  505. CStringT& append(const _CharT* __s)
  506. {__super::append(::SafeStr(__s)); return *this;}
  507. CStringT& append(size_type __n, _CharT __c)
  508. {__super::append(__n, __c); return *this;}
  509. #if __cplusplus >= 201103L
  510. CStringT& append(initializer_list<_CharT> __l)
  511. {__super::append(__l); return *this;}
  512. #endif // C++11
  513. template<class _InputIterator>
  514. CStringT& append(_InputIterator __first, _InputIterator __last)
  515. {__super::append(__first, __last); return *this;}
  516. void push_back(_CharT __c)
  517. {__super::push_back(__c);}
  518. CStringT& assign(const __super& __str)
  519. {__super::assign(__str); return *this;}
  520. #if __cplusplus >= 201103L
  521. CStringT& assign(__super&& __str)
  522. {__super::assign(__str); return *this;}
  523. #endif // C++11
  524. CStringT& assign(const __super& __str, size_type __pos, size_type __n)
  525. {__super::assign(__str, __pos, __n); return *this;}
  526. CStringT& assign(const _CharT* __s, size_type __n)
  527. {__super::assign(::SafeStr(__s), __n); return *this;}
  528. CStringT& assign(const _CharT* __s)
  529. {__super::assign(::SafeStr(__s)); return *this;}
  530. CStringT& assign(size_type __n, _CharT __c)
  531. {__super::assign(__n, __c); return *this;}
  532. template<class _InputIterator>
  533. CStringT& assign(_InputIterator __first, _InputIterator __last)
  534. {__super::assign(__first, __last); return *this;}
  535. #if __cplusplus >= 201103L
  536. CStringT& assign(initializer_list<_CharT> __l)
  537. {__super::assign(__l); return *this;}
  538. #endif // C++11
  539. CStringT& insert(size_type __pos1, const __super& __str)
  540. {__super::insert(__pos1, __str); return *this;}
  541. CStringT& insert(size_type __pos1, const __super& __str, size_type __pos2, size_type __n)
  542. {__super::insert(__pos1, __str, __pos2, __n); return *this;}
  543. CStringT& insert(size_type __pos, const _CharT* __s, size_type __n)
  544. {__super::insert(__pos, __s, __n); return *this;}
  545. CStringT& insert(size_type __pos, const _CharT* __s)
  546. {__super::insert(__pos, __s); return *this;}
  547. CStringT& insert(size_type __pos, size_type __n, _CharT __c)
  548. {__super::insert(__pos, __n, __c); return *this;}
  549. CStringT& erase(size_type __pos = 0, size_type __n = __super::npos)
  550. {__super::erase(__pos, __n); return *this;}
  551. CStringT& replace(size_type __pos, size_type __n, const __super& __str)
  552. {__super::replace(__pos, __n, __str); return *this;}
  553. CStringT& replace(size_type __pos1, size_type __n1, const __super& __str, size_type __pos2, size_type __n2)
  554. {__super::replace(__pos1, __n1, __str, __pos2, __n2); return *this;}
  555. CStringT& replace(size_type __pos, size_type __n1, const _CharT* __s, size_type __n2)
  556. {__super::replace(__pos, __n1, __s, __n2); return *this;}
  557. CStringT& replace(size_type __pos, size_type __n1, const _CharT* __s)
  558. {__super::replace(__pos, __n1, __s); return *this;}
  559. CStringT& replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
  560. {__super::replace(__pos, __n1, __n2, __c); return *this;}
  561. CStringT& replace(iterator __i1, iterator __i2, const __super& __str)
  562. {__super::replace(__i1, __i2, __str); return *this;}
  563. CStringT& replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n)
  564. {__super::replace(__i1, __i2, __s, __n); return *this;}
  565. CStringT& replace(iterator __i1, iterator __i2, const _CharT* __s)
  566. {__super::replace(__i1, __i2, __s); return *this;}
  567. CStringT& replace(iterator __i1, iterator __i2, size_type __n, _CharT __c)
  568. {__super::replace(__i1, __i2, __n, __c); return *this;}
  569. template<class _InputIterator>
  570. CStringT& replace(iterator __i1, iterator __i2, _InputIterator __k1, _InputIterator __k2)
  571. {__super::replace(__i1, __i2, __k1, __k2); return *this;}
  572. CStringT& replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2)
  573. {__super::replace(__i1, __i2, __k1, __k2); return *this;}
  574. CStringT& replace(iterator __i1, iterator __i2, const _CharT* __k1, const _CharT* __k2)
  575. {__super::replace(__i1, __i2, __k1, __k2); return *this;}
  576. CStringT& replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2)
  577. {__super::replace(__i1, __i2, __k1, __k2); return *this;}
  578. CStringT& replace(iterator __i1, iterator __i2, const_iterator __k1, const_iterator __k2)
  579. {__super::replace(__i1, __i2, __k1, __k2); return *this;}
  580. #if __cplusplus >= 201103L
  581. CStringT& replace(iterator __i1, iterator __i2, initializer_list<_CharT> __l)
  582. {__super::replace(__i1, __i2, __l); return *this;}
  583. #endif // C++11
  584. CStringT substr(size_type __pos = 0, size_type __n = __super::npos) const
  585. {return __super::substr(__pos, __n);}
  586. };
  587. template<typename _CharT, typename _Traits, typename _Alloc>
  588. CStringT<_CharT, _Traits, _Alloc>
  589. operator+(const CStringT<_CharT, _Traits, _Alloc>& __lhs, const CStringT<_CharT, _Traits, _Alloc>& __rhs)
  590. {
  591. CStringT<_CharT, _Traits, _Alloc> __str(__lhs);
  592. __str.append(__rhs);
  593. return __str;
  594. }
  595. template<typename _CharT, typename _Traits, typename _Alloc>
  596. CStringT<_CharT,_Traits,_Alloc>
  597. operator+(const _CharT* __lhs, const CStringT<_CharT,_Traits,_Alloc>& __rhs);
  598. template<typename _CharT, typename _Traits, typename _Alloc>
  599. CStringT<_CharT,_Traits,_Alloc>
  600. operator+(_CharT __lhs, const CStringT<_CharT,_Traits,_Alloc>& __rhs);
  601. template<typename _CharT, typename _Traits, typename _Alloc>
  602. inline CStringT<_CharT, _Traits, _Alloc>
  603. operator+(const CStringT<_CharT, _Traits, _Alloc>& __lhs, const _CharT* __rhs)
  604. {
  605. CStringT<_CharT, _Traits, _Alloc> __str(__lhs);
  606. __str.append(__rhs);
  607. return __str;
  608. }
  609. template<typename _CharT, typename _Traits, typename _Alloc>
  610. inline CStringT<_CharT, _Traits, _Alloc>
  611. operator+(const CStringT<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs)
  612. {
  613. typedef CStringT<_CharT, _Traits, _Alloc> __string_type;
  614. typedef typename __string_type::size_type __size_type;
  615. __string_type __str(__lhs);
  616. __str.append(__size_type(1), __rhs);
  617. return __str;
  618. }
  619. #if __cplusplus >= 201103L
  620. template<typename _CharT, typename _Traits, typename _Alloc>
  621. inline CStringT<_CharT, _Traits, _Alloc>
  622. operator+(CStringT<_CharT, _Traits, _Alloc>&& __lhs, const CStringT<_CharT, _Traits, _Alloc>& __rhs)
  623. {return std::move(__lhs.append(__rhs));}
  624. template<typename _CharT, typename _Traits, typename _Alloc>
  625. inline CStringT<_CharT, _Traits, _Alloc>
  626. operator+(const CStringT<_CharT, _Traits, _Alloc>& __lhs, CStringT<_CharT, _Traits, _Alloc>&& __rhs)
  627. {return std::move(__rhs.insert(0, __lhs));}
  628. template<typename _CharT, typename _Traits, typename _Alloc>
  629. inline CStringT<_CharT, _Traits, _Alloc>
  630. operator+(CStringT<_CharT, _Traits, _Alloc>&& __lhs, CStringT<_CharT, _Traits, _Alloc>&& __rhs)
  631. {
  632. const auto __size = __lhs.size() + __rhs.size();
  633. const bool __cond = (__size > __lhs.capacity()
  634. && __size <= __rhs.capacity());
  635. return __cond ? std::move(__rhs.insert(0, __lhs))
  636. : std::move(__lhs.append(__rhs));
  637. }
  638. template<typename _CharT, typename _Traits, typename _Alloc>
  639. inline CStringT<_CharT, _Traits, _Alloc>
  640. operator+(const _CharT* __lhs, CStringT<_CharT, _Traits, _Alloc>&& __rhs)
  641. {return std::move(__rhs.insert(0, __lhs));}
  642. template<typename _CharT, typename _Traits, typename _Alloc>
  643. inline CStringT<_CharT, _Traits, _Alloc>
  644. operator+(_CharT __lhs, CStringT<_CharT, _Traits, _Alloc>&& __rhs)
  645. {return std::move(__rhs.insert(0, 1, __lhs));}
  646. template<typename _CharT, typename _Traits, typename _Alloc>
  647. inline CStringT<_CharT, _Traits, _Alloc>
  648. operator+(CStringT<_CharT, _Traits, _Alloc>&& __lhs, const _CharT* __rhs)
  649. {return std::move(__lhs.append(__rhs));}
  650. template<typename _CharT, typename _Traits, typename _Alloc>
  651. inline CStringT<_CharT, _Traits, _Alloc>
  652. operator+(CStringT<_CharT, _Traits, _Alloc>&& __lhs, _CharT __rhs)
  653. {return std::move(__lhs.append(1, __rhs));}
  654. #endif
  655. using CStringA = CStringT<char>;
  656. using CStringW = CStringT<wchar_t>;
  657. using CStdStringA = string;
  658. using CStdStringW = wstring;
  659. #ifdef _UNICODE
  660. using CString = CStringW;
  661. using CStdString = CStdStringW;
  662. #else
  663. using CString = CStringA;
  664. using CStdString = CStdStringA;
  665. #endif
  666. #define _HASH_SEED (size_t)0xdeadbeef
  667. template<class _Kty>
  668. inline size_t hash_value(const _Kty& _Keyval)
  669. {
  670. return ((size_t)_Keyval ^ _HASH_SEED);
  671. }
  672. template <class _InIt>
  673. inline size_t _Hash_value(_InIt _Begin, _InIt _End)
  674. {
  675. size_t _Val = 2166136261U;
  676. while(_Begin != _End)
  677. _Val = 16777619U * _Val ^ (size_t)*_Begin++;
  678. return (_Val);
  679. }
  680. template<class _Elem, class _Traits, class _Alloc>
  681. inline size_t hash_value(const basic_string<_Elem, _Traits, _Alloc>& _Str)
  682. {
  683. const _Elem *_Ptr = _Str.c_str();
  684. return (_Hash_value(_Ptr, _Ptr + _Str.size()));
  685. }
  686. template<class _Elem>
  687. inline size_t hash_value(const CStringT<_Elem>& _Str)
  688. {
  689. const _Elem *_Ptr = _Str.c_str();
  690. return (_Hash_value(_Ptr, _Ptr + _Str.size()));
  691. }
  692. inline size_t hash_value(const char *_Str)
  693. {
  694. return (_Hash_value(_Str, _Str + strlen(_Str)));
  695. }
  696. inline size_t hash_value(const wchar_t *_Str)
  697. {
  698. return (_Hash_value(_Str, _Str + wcslen(_Str)));
  699. }