Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1189 lines
29 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: N C S T L S T R . H
  7. //
  8. // Contents: STL string class renamed so as to remove our dependance
  9. // from msvcp50.dll.
  10. //
  11. // Notes:
  12. //
  13. // Author: shaunco 12 Apr 1998
  14. //
  15. //----------------------------------------------------------------------------
  16. #pragma once
  17. #ifndef _NCSTLSTR_H_
  18. #define _NCSTLSTR_H_
  19. #include <stliter.h>
  20. #include <stlxutil.h>
  21. #include <limits.h>
  22. #include <wchar.h>
  23. #include "ncdebug.h"
  24. using namespace std;
  25. //template<class _E,
  26. //class _Tr = char_traits<_E>,
  27. //class _A = allocator<_E> >
  28. struct wchar_traits
  29. {
  30. typedef wchar_t _E;
  31. typedef _E char_type; // for overloads
  32. typedef wint_t int_type;
  33. typedef mbstate_t state_type;
  34. static void __cdecl assign(_E& _X, const _E& _Y)
  35. {
  36. _X = _Y;
  37. }
  38. static bool __cdecl eq(const _E& _X, const _E& _Y)
  39. {
  40. return (_X == _Y);
  41. }
  42. static bool __cdecl lt(const _E& _X, const _E& _Y)
  43. {
  44. return (_X < _Y);
  45. }
  46. static int __cdecl compare(const _E *_U, const _E *_V, size_t _N)
  47. {
  48. return (wmemcmp(_U, _V, _N));
  49. }
  50. static size_t __cdecl length(const _E *_U)
  51. {
  52. return (wcslen(_U));
  53. }
  54. static _E *__cdecl copy(_E *_U, const _E *_V, size_t _N)
  55. {
  56. return (wmemcpy(_U, _V, _N));
  57. }
  58. static const _E * __cdecl find(const _E *_U, size_t _N,
  59. const _E& _C)
  60. {
  61. return ((const _E *)wmemchr(_U, _C, _N));
  62. }
  63. static _E * __cdecl move(_E *_U, const _E *_V, size_t _N)
  64. {
  65. return (wmemmove(_U, _V, _N));
  66. }
  67. static _E * __cdecl assign(_E *_U, size_t _N, const _E& _C)
  68. {
  69. return (wmemset(_U, _C, _N));
  70. }
  71. static _E __cdecl to_char_type(const int_type& _C)
  72. {
  73. return (_C);
  74. }
  75. static int_type __cdecl to_int_type(const _E& _C)
  76. {
  77. return (_C);
  78. }
  79. static bool __cdecl eq_int_type(const int_type& _X,
  80. const int_type& _Y)
  81. {
  82. return (_X == _Y);
  83. }
  84. static int_type __cdecl eof()
  85. {
  86. return (WEOF);
  87. }
  88. static int_type __cdecl not_eof(const int_type& _C)
  89. {
  90. return (_C != eof() ? _C : !eof());
  91. }
  92. };
  93. class CWideString
  94. {
  95. public:
  96. typedef CWideString _Myt;
  97. typedef wchar_traits _Tr;
  98. typedef _Tr::_E _E;
  99. typedef size_t size_type;
  100. typedef ptrdiff_t difference_type;
  101. typedef _E* pointer;
  102. typedef const _E* const_pointer;
  103. typedef _E& reference;
  104. typedef const _E& const_reference;
  105. typedef _E value_type;
  106. typedef pointer iterator;
  107. typedef const_pointer const_iterator;
  108. typedef reverse_iterator<const_iterator, value_type, const_reference,
  109. const_pointer, difference_type>
  110. const_reverse_iterator;
  111. typedef reverse_iterator<iterator, value_type, reference, pointer,
  112. difference_type>
  113. reverse_iterator;
  114. typedef const_iterator _It;
  115. explicit CWideString()
  116. {
  117. _Tidy();
  118. }
  119. CWideString(const _Myt& _X)
  120. {
  121. _Tidy(), assign(_X, 0, npos);
  122. }
  123. CWideString(const _Myt& _X, size_type _P, size_type _M)
  124. {
  125. _Tidy(), assign(_X, _P, _M);
  126. }
  127. CWideString(const _E *_S, size_type _N)
  128. {
  129. _Tidy(), assign(_S, _N);
  130. }
  131. CWideString(const _E *_S)
  132. {
  133. _Tidy(), assign(_S);
  134. }
  135. CWideString(size_type _N, _E _C)
  136. {
  137. _Tidy(), assign(_N, _C);
  138. }
  139. CWideString(_It _F, _It _L)
  140. {
  141. _Tidy(); assign(_F, _L);
  142. }
  143. ~CWideString()
  144. {
  145. _Tidy(true);
  146. }
  147. enum _Mref
  148. {
  149. _FROZEN = USHRT_MAX
  150. };
  151. enum _Npos
  152. {
  153. // -1 is not arbitrary. It is chosen because it works in math
  154. // operations. npos is treated as size_type and is inolved in
  155. // arithmetic.
  156. //
  157. npos = -1
  158. };
  159. _Myt& operator=(const _Myt& _X)
  160. {
  161. return (assign(_X));
  162. }
  163. _Myt& operator=(const _E *_S)
  164. {
  165. return (assign(_S));
  166. }
  167. _Myt& operator=(_E _C)
  168. {
  169. return (assign(1, _C));
  170. }
  171. _Myt& operator+=(const _Myt& _X)
  172. {
  173. return (append(_X));
  174. }
  175. _Myt& operator+=(const _E *_S)
  176. {
  177. return (append(_S));
  178. }
  179. _Myt& operator+=(_E _C)
  180. {
  181. return (append(1, _C));
  182. }
  183. _Myt& append(const _Myt& _X)
  184. {
  185. return (append(_X, 0, npos));
  186. }
  187. _Myt& append(const _Myt& _X, size_type _P, size_type _M)
  188. {
  189. AssertH (_X.size() >= _P);
  190. //if (_X.size() < _P)
  191. // _Xran();
  192. size_type _N = _X.size() - _P;
  193. if (_N < _M)
  194. _M = _N;
  195. AssertH ((_Len + _M < npos));
  196. //if (npos - _Len <= _M)
  197. // _Xlen();
  198. if (0 < _M && _Grow(_N = _Len + _M))
  199. {
  200. _Tr::copy(_Ptr + _Len, &_X.c_str()[_P], _M);
  201. _Eos(_N);
  202. }
  203. return (*this);
  204. }
  205. _Myt& append(const _E *_S, size_type _M)
  206. {
  207. AssertH ((_Len + _M < npos));
  208. //if (npos - _Len <= _M)
  209. // _Xlen();
  210. size_type _N;
  211. if (0 < _M && _Grow(_N = _Len + _M))
  212. {
  213. _Tr::copy(_Ptr + _Len, _S, _M);
  214. _Eos(_N);
  215. }
  216. return (*this);
  217. }
  218. _Myt& append(const _E *_S)
  219. {
  220. return (append(_S, _Tr::length(_S)));
  221. }
  222. _Myt& append(size_type _M, _E _C)
  223. {
  224. AssertH ((_Len + _M < npos));
  225. //if (npos - _Len <= _M)
  226. // _Xlen();
  227. size_type _N;
  228. if (0 < _M && _Grow(_N = _Len + _M))
  229. {
  230. _Tr::assign(_Ptr + _Len, _M, _C);
  231. _Eos(_N);
  232. }
  233. return (*this);
  234. }
  235. _Myt& append(_It _F, _It _L)
  236. {
  237. return (replace(end(), end(), _F, _L));
  238. }
  239. _Myt& assign(const _Myt& _X)
  240. {
  241. return (assign(_X, 0, npos));
  242. }
  243. _Myt& assign(const _Myt& _X, size_type _P, size_type _M)
  244. {
  245. AssertH (_X.size() >= _P);
  246. //if (_X.size() < _P)
  247. // _Xran();
  248. size_type _N = _X.size() - _P;
  249. if (_M < _N)
  250. _N = _M;
  251. if (this == &_X)
  252. {
  253. erase((size_type)(_P + _N)), erase(0, _P);
  254. }
  255. else if (0 < _N && _N == _X.size()
  256. && _Refcnt(_X.c_str()) < _FROZEN - 1)
  257. {
  258. _Tidy(true);
  259. _Ptr = (_E *)_X.c_str();
  260. _Len = _X.size();
  261. _Res = _X.capacity();
  262. ++_Refcnt(_Ptr);
  263. }
  264. else if (_Grow(_N, true))
  265. {
  266. _Tr::copy(_Ptr, &_X.c_str()[_P], _N);
  267. _Eos(_N);
  268. }
  269. return (*this);
  270. }
  271. _Myt& assign(const _E *_S, size_type _N)
  272. {
  273. if (_Grow(_N))
  274. {
  275. _Tr::copy(_Ptr, _S, _N);
  276. _Eos(_N);
  277. }
  278. return (*this);
  279. }
  280. _Myt& assign(const _E *_S)
  281. {
  282. return (assign(_S, _Tr::length(_S)));
  283. }
  284. _Myt& assignSafe(const _E *_S)
  285. {
  286. return (_S) ? assign(_S, _Tr::length(_S)) : erase();
  287. }
  288. _Myt& assign(size_type _N, _E _C)
  289. {
  290. AssertH (npos != _N);
  291. //if (_N == npos)
  292. // _Xlen();
  293. if (_Grow(_N))
  294. {
  295. _Tr::assign(_Ptr, _N, _C);
  296. _Eos(_N);
  297. }
  298. return (*this);
  299. }
  300. _Myt& assign(_It _F, _It _L)
  301. {
  302. return (replace(begin(), end(), _F, _L));
  303. }
  304. _Myt& insert(size_type _P0, const _Myt& _X)
  305. {
  306. return (insert(_P0, _X, 0, npos));
  307. }
  308. _Myt& insert(size_type _P0, const _Myt& _X, size_type _P, size_type _M)
  309. {
  310. AssertH ((_Len >= _P0) && (_X.size() >= _P));
  311. //if (_Len < _P0 || _X.size() < _P)
  312. // _Xran();
  313. size_type _N = _X.size() - _P;
  314. if (_N < _M)
  315. _M = _N;
  316. AssertH ((_Len + _M < npos));
  317. //if (npos - _Len <= _M)
  318. // _Xlen();
  319. if (0 < _M && _Grow(_N = _Len + _M))
  320. {
  321. _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0, _Len - _P0);
  322. _Tr::copy(_Ptr + _P0, &_X.c_str()[_P], _M);
  323. _Eos(_N);
  324. }
  325. return (*this);
  326. }
  327. _Myt& insert(size_type _P0, const _E *_S, size_type _M)
  328. {
  329. AssertH (_Len >= _P0);
  330. //if (_Len < _P0)
  331. // _Xran();
  332. AssertH ((_Len + _M < npos));
  333. //if (npos - _Len <= _M)
  334. // _Xlen();
  335. size_type _N;
  336. if (0 < _M && _Grow(_N = _Len + _M))
  337. {
  338. _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0, _Len - _P0);
  339. _Tr::copy(_Ptr + _P0, _S, _M);
  340. _Eos(_N);
  341. }
  342. return (*this);
  343. }
  344. _Myt& insert(size_type _P0, const _E *_S)
  345. {
  346. return (insert(_P0, _S, _Tr::length(_S)));
  347. }
  348. _Myt& insert(size_type _P0, size_type _M, _E _C)
  349. {
  350. AssertH (_Len >= _P0);
  351. //if (_Len < _P0)
  352. // _Xran();
  353. AssertH ((_Len + _M < npos));
  354. //if (npos - _Len <= _M)
  355. // _Xlen();
  356. size_type _N;
  357. if (0 < _M && _Grow(_N = _Len + _M))
  358. {
  359. _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0, _Len - _P0);
  360. _Tr::assign(_Ptr + _P0, _M, _C);
  361. _Eos(_N);
  362. }
  363. return (*this);
  364. }
  365. iterator insert(iterator _P, _E _C)
  366. {
  367. size_type _P0 = _Pdif(_P, begin());
  368. insert(_P0, 1, _C);
  369. return (begin() + _P0);
  370. }
  371. void insert(iterator _P, size_type _M, _E _C)
  372. {
  373. size_type _P0 = _Pdif(_P, begin());
  374. insert(_P0, _M, _C);
  375. }
  376. void insert(iterator _P, _It _F, _It _L)
  377. {
  378. replace(_P, _P, _F, _L);
  379. }
  380. _Myt& erase(size_type _P0 = 0, size_type _M = npos)
  381. {
  382. AssertH (_Len >= _P0);
  383. //if (_Len < _P0)
  384. // _Xran();
  385. _Split();
  386. if (_Len - _P0 < _M)
  387. _M = _Len - _P0;
  388. if (0 < _M)
  389. {
  390. _Tr::move(_Ptr + _P0, _Ptr + _P0 + _M,
  391. _Len - _P0 - _M);
  392. size_type _N = _Len - _M;
  393. if (_Grow(_N))
  394. _Eos(_N);
  395. }
  396. return (*this);
  397. }
  398. iterator erase(iterator _P)
  399. {
  400. size_t _M = _Pdif(_P, begin());
  401. erase(_M, 1);
  402. return (_Psum(_Ptr, _M));
  403. }
  404. iterator erase(iterator _F, iterator _L)
  405. {
  406. size_t _M = _Pdif(_F, begin());
  407. erase(_M, _Pdif(_L, _F));
  408. return (_Psum(_Ptr, _M));
  409. }
  410. _Myt& replace(size_type _P0, size_type _N0, const _Myt& _X)
  411. {
  412. return (replace(_P0, _N0, _X, 0, npos));
  413. }
  414. _Myt& replace(size_type _P0, size_type _N0, const _Myt& _X,
  415. size_type _P, size_type _M)
  416. {
  417. AssertH ((_Len >= _P0) && (_X.size() >= _P));
  418. //if (_Len < _P0 || _X.size() < _P)
  419. // _Xran();
  420. if (_Len - _P0 < _N0)
  421. _N0 = _Len - _P0;
  422. size_type _N = _X.size() - _P;
  423. if (_N < _M)
  424. _M = _N;
  425. AssertH (npos - _M > _Len - _N0);
  426. //if (npos - _M <= _Len - _N0)
  427. // _Xlen();
  428. _Split();
  429. size_type _Nm = _Len - _N0 - _P0;
  430. if (_M < _N0)
  431. _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0 + _N0, _Nm);
  432. if ((0 < _M || 0 < _N0) && _Grow(_N = _Len + _M - _N0))
  433. {
  434. if (_N0 < _M)
  435. _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0 + _N0, _Nm);
  436. _Tr::copy(_Ptr + _P0, &_X.c_str()[_P], _M);
  437. _Eos(_N);
  438. }
  439. return (*this);
  440. }
  441. _Myt& replace(size_type _P0, size_type _N0, const _E *_S,
  442. size_type _M)
  443. {
  444. AssertH (_Len >= _P0);
  445. //if (_Len < _P0)
  446. // _Xran();
  447. if (_Len - _P0 < _N0)
  448. _N0 = _Len - _P0;
  449. AssertH (npos - _M > _Len - _N0);
  450. //if (npos - _M <= _Len - _N0)
  451. // _Xlen();
  452. _Split();
  453. size_type _Nm = _Len - _N0 - _P0;
  454. if (_M < _N0)
  455. _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0 + _N0, _Nm);
  456. size_type _N;
  457. if ((0 < _M || 0 < _N0) && _Grow(_N = _Len + _M - _N0))
  458. {
  459. if (_N0 < _M)
  460. _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0 + _N0, _Nm);
  461. _Tr::copy(_Ptr + _P0, _S, _M);
  462. _Eos(_N);
  463. }
  464. return (*this);
  465. }
  466. _Myt& replace(size_type _P0, size_type _N0, const _E *_S)
  467. {
  468. return (replace(_P0, _N0, _S, _Tr::length(_S)));
  469. }
  470. _Myt& replace(size_type _P0, size_type _N0,
  471. size_type _M, _E _C)
  472. {
  473. AssertH (_Len >= _P0);
  474. //if (_Len < _P0)
  475. // _Xran();
  476. if (_Len - _P0 < _N0)
  477. _N0 = _Len - _P0;
  478. AssertH (npos - _M > _Len - _N0);
  479. //if (npos - _M <= _Len - _N0)
  480. // _Xlen();
  481. _Split();
  482. size_type _Nm = _Len - _N0 - _P0;
  483. if (_M < _N0)
  484. _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0 + _N0, _Nm);
  485. size_type _N;
  486. if ((0 < _M || 0 < _N0) && _Grow(_N = _Len + _M - _N0))
  487. {
  488. if (_N0 < _M)
  489. _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0 + _N0,
  490. _Nm);
  491. _Tr::assign(_Ptr + _P0, _M, _C);
  492. _Eos(_N);
  493. }
  494. return (*this);
  495. }
  496. _Myt& replace(iterator _F, iterator _L, const _Myt& _X)
  497. {
  498. return (replace(_Pdif(_F, begin()), _Pdif(_L, _F), _X));
  499. }
  500. _Myt& replace(iterator _F, iterator _L, const _E *_S,
  501. size_type _M)
  502. {
  503. return (replace(_Pdif(_F, begin()), _Pdif(_L, _F), _S, _M));
  504. }
  505. _Myt& replace(iterator _F, iterator _L, const _E *_S)
  506. {
  507. return (replace(_Pdif(_F, begin()), _Pdif(_L, _F), _S));
  508. }
  509. _Myt& replace(iterator _F, iterator _L, size_type _M, _E _C)
  510. {
  511. return (replace(_Pdif(_F, begin()), _Pdif(_L, _F), _M, _C));
  512. }
  513. _Myt& replace(iterator _F1, iterator _L1,
  514. _It _F2, _It _L2)
  515. {
  516. size_type _P0 = _Pdif(_F1, begin());
  517. size_type _M = 0;
  518. _Distance(_F2, _L2, _M);
  519. replace(_P0, _Pdif(_L1, _F1), _M, _E(0));
  520. for (_F1 = begin() + _P0; 0 < _M; ++_F1, ++_F2, --_M)
  521. *_F1 = *_F2;
  522. return (*this);
  523. }
  524. iterator begin()
  525. {
  526. _Freeze();
  527. return (_Ptr);
  528. }
  529. const_iterator begin() const
  530. {
  531. return (_Ptr);
  532. }
  533. iterator end()
  534. {
  535. _Freeze();
  536. return ((iterator)_Psum(_Ptr, _Len));
  537. }
  538. const_iterator end() const
  539. {
  540. return ((const_iterator)_Psum(_Ptr, _Len));
  541. }
  542. reverse_iterator rbegin()
  543. {
  544. return (reverse_iterator(end()));
  545. }
  546. const_reverse_iterator rbegin() const
  547. {
  548. return (const_reverse_iterator(end()));
  549. }
  550. reverse_iterator rend()
  551. {
  552. return (reverse_iterator(begin()));
  553. }
  554. const_reverse_iterator rend() const
  555. {
  556. return (const_reverse_iterator(begin()));
  557. }
  558. reference at(size_type _P0)
  559. {
  560. AssertH (_Len > _P0);
  561. //if (_Len <= _P0)
  562. // _Xran();
  563. _Freeze();
  564. return (_Ptr[_P0]);
  565. }
  566. const_reference at(size_type _P0) const
  567. {
  568. AssertH (_Len > _P0);
  569. //if (_Len <= _P0)
  570. // _Xran();
  571. return (_Ptr[_P0]);
  572. }
  573. reference operator[](size_type _P0)
  574. {
  575. if (_Len < _P0 || _Ptr == 0)
  576. return ((reference)*_Nullstr());
  577. _Freeze();
  578. return (_Ptr[_P0]);
  579. }
  580. const_reference operator[](size_type _P0) const
  581. {
  582. if (_Ptr == 0)
  583. return (*_Nullstr());
  584. else
  585. return (_Ptr[_P0]);
  586. }
  587. const _E *c_str() const
  588. {
  589. return (_Ptr == 0 ? _Nullstr() : _Ptr);
  590. }
  591. const _E *data() const
  592. {
  593. return (c_str());
  594. }
  595. size_type length() const
  596. {
  597. return (_Len);
  598. }
  599. size_type size() const
  600. {
  601. return (_Len);
  602. }
  603. void resize(size_type _N, _E _C)
  604. {
  605. _N <= _Len ? erase(_N) : append(_N - _Len, _C);
  606. }
  607. void resize(size_type _N)
  608. {
  609. _N <= _Len ? erase(_N) : append(_N - _Len, _E(0));
  610. }
  611. size_type capacity() const
  612. {
  613. return (_Res);
  614. }
  615. void reserve(size_type _N = 0)
  616. {
  617. if (_Res < _N)
  618. _Grow(_N);
  619. }
  620. bool empty() const
  621. {
  622. return (_Len == 0);
  623. }
  624. size_type copy(_E *_S, size_type _N, size_type _P0 = 0) const
  625. {
  626. AssertH (_Len >= _P0);
  627. //if (_Len < _P0)
  628. // _Xran();
  629. if (_Len - _P0 < _N)
  630. _N = _Len - _P0;
  631. if (0 < _N)
  632. _Tr::copy(_S, _Ptr + _P0, _N);
  633. return (_N);
  634. }
  635. void swap(_Myt& _X)
  636. {
  637. std::swap(_Ptr, _X._Ptr);
  638. std::swap(_Len, _X._Len);
  639. std::swap(_Res, _X._Res);
  640. }
  641. void swap(_Myt& _X, _Myt& _Y)
  642. {
  643. _X.swap(_Y);
  644. }
  645. size_type find(const _Myt& _X, size_type _P = 0) const
  646. {
  647. return (find(_X.c_str(), _P, _X.size()));
  648. }
  649. size_type find(const _E *_S, size_type _P,
  650. size_type _N) const
  651. {
  652. if (_N == 0 && _P <= _Len)
  653. return (_P);
  654. size_type _Nm;
  655. if (_P < _Len && _N <= (_Nm = _Len - _P))
  656. {
  657. const _E *_U, *_V;
  658. for (_Nm -= _N - 1, _V = _Ptr + _P;
  659. (_U = _Tr::find(_V, _Nm, *_S)) != 0;
  660. _Nm -= (size_type)(_U - _V + 1), _V = _U + 1)
  661. if (_Tr::compare(_U, _S, _N) == 0)
  662. return (_U - _Ptr);
  663. }
  664. return (npos);
  665. }
  666. size_type find(const _E *_S, size_type _P = 0) const
  667. {
  668. return (find(_S, _P, _Tr::length(_S)));
  669. }
  670. size_type find(_E _C, size_type _P = 0) const
  671. {
  672. return (find((const _E *)&_C, _P, 1));
  673. }
  674. size_type rfind(const _Myt& _X, size_type _P = npos) const
  675. {
  676. return (rfind(_X.c_str(), _P, _X.size()));
  677. }
  678. size_type rfind(const _E *_S, size_type _P,
  679. size_type _N) const
  680. {
  681. if (_N == 0)
  682. return (_P < _Len ? _P : _Len);
  683. if (_N <= _Len)
  684. for (const _E *_U = _Ptr +
  685. + (_P < _Len - _N ? _P : _Len - _N); ; --_U)
  686. if (_Tr::eq(*_U, *_S)
  687. && _Tr::compare(_U, _S, _N) == 0)
  688. return (_U - _Ptr);
  689. else if (_U == _Ptr)
  690. break;
  691. return (npos);
  692. }
  693. size_type rfind(const _E *_S, size_type _P = npos) const
  694. {
  695. return (rfind(_S, _P, _Tr::length(_S)));
  696. }
  697. size_type rfind(_E _C, size_type _P = npos) const
  698. {
  699. return (rfind((const _E *)&_C, _P, 1));
  700. }
  701. size_type find_first_of(const _Myt& _X,
  702. size_type _P = 0) const
  703. {
  704. return (find_first_of(_X.c_str(), _P, _X.size()));
  705. }
  706. size_type find_first_of(const _E *_S, size_type _P,
  707. size_type _N) const
  708. {
  709. if (0 < _N && _P < _Len)
  710. {
  711. const _E *const _V = _Ptr + _Len;
  712. for (const _E *_U = _Ptr + _P; _U < _V; ++_U)
  713. if (_Tr::find(_S, _N, *_U) != 0)
  714. return (_U - _Ptr);
  715. }
  716. return (npos);
  717. }
  718. size_type find_first_of(const _E *_S, size_type _P = 0) const
  719. {
  720. return (find_first_of(_S, _P, _Tr::length(_S)));
  721. }
  722. size_type find_first_of(_E _C, size_type _P = 0) const
  723. {
  724. return (find((const _E *)&_C, _P, 1));
  725. }
  726. size_type find_last_of(const _Myt& _X,
  727. size_type _P = npos) const
  728. {
  729. return (find_last_of(_X.c_str(), _P, _X.size()));
  730. }
  731. size_type find_last_of(const _E *_S, size_type _P,
  732. size_type _N) const
  733. {
  734. if (0 < _N && 0 < _Len)
  735. for (const _E *_U = _Ptr
  736. + (_P < _Len ? _P : _Len - 1); ; --_U)
  737. if (_Tr::find(_S, _N, *_U) != 0)
  738. return (_U - _Ptr);
  739. else if (_U == _Ptr)
  740. break;
  741. return (npos);
  742. }
  743. size_type find_last_of(const _E *_S,
  744. size_type _P = npos) const
  745. {
  746. return (find_last_of(_S, _P, _Tr::length(_S)));
  747. }
  748. size_type find_last_of(_E _C, size_type _P = npos) const
  749. {
  750. return (rfind((const _E *)&_C, _P, 1));
  751. }
  752. size_type find_first_not_of(const _Myt& _X,
  753. size_type _P = 0) const
  754. {
  755. return (find_first_not_of(_X.c_str(), _P,
  756. _X.size()));
  757. }
  758. size_type find_first_not_of(const _E *_S, size_type _P,
  759. size_type _N) const
  760. {
  761. if (_P < _Len)
  762. {
  763. const _E *const _V = _Ptr + _Len;
  764. for (const _E *_U = _Ptr + _P; _U < _V; ++_U)
  765. if (_Tr::find(_S, _N, *_U) == 0)
  766. return (_U - _Ptr);
  767. }
  768. return (npos);
  769. }
  770. size_type find_first_not_of(const _E *_S,
  771. size_type _P = 0) const
  772. {
  773. return (find_first_not_of(_S, _P, _Tr::length(_S)));
  774. }
  775. size_type find_first_not_of(_E _C, size_type _P = 0) const
  776. {
  777. return (find_first_not_of((const _E *)&_C, _P, 1));
  778. }
  779. size_type find_last_not_of(const _Myt& _X,
  780. size_type _P = npos) const
  781. {
  782. return (find_last_not_of(_X.c_str(), _P, _X.size()));
  783. }
  784. size_type find_last_not_of(const _E *_S, size_type _P,
  785. size_type _N) const
  786. {
  787. if (0 < _Len)
  788. for (const _E *_U = _Ptr
  789. + (_P < _Len ? _P : _Len - 1); ; --_U)
  790. if (_Tr::find(_S, _N, *_U) == 0)
  791. return (_U - _Ptr);
  792. else if (_U == _Ptr)
  793. break;
  794. return (npos);
  795. }
  796. size_type find_last_not_of(const _E *_S,
  797. size_type _P = npos) const
  798. {
  799. return (find_last_not_of(_S, _P, _Tr::length(_S)));
  800. }
  801. size_type find_last_not_of(_E _C, size_type _P = npos) const
  802. {
  803. return (find_last_not_of((const _E *)&_C, _P, 1));
  804. }
  805. _Myt substr(size_type _P = 0, size_type _M = npos) const
  806. {
  807. return (_Myt(*this, _P, _M));
  808. }
  809. int compare(const _Myt& _X) const
  810. {
  811. return (compare(0, _Len, _X.c_str(), _X.size()));
  812. }
  813. int compare(size_type _P0, size_type _N0,
  814. const _Myt& _X) const
  815. {
  816. return (compare(_P0, _N0, _X, 0, npos));
  817. }
  818. int compare(size_type _P0, size_type _N0, const _Myt& _X,
  819. size_type _P, size_type _M) const
  820. {
  821. AssertH (_X.size() >= _P);
  822. //if (_X.size() < _P)
  823. // _Xran();
  824. if (_X._Len - _P < _M)
  825. _M = _X._Len - _P;
  826. return (compare(_P0, _N0, _X.c_str() + _P, _M));
  827. }
  828. int compare(const _E *_S) const
  829. {
  830. return (compare(0, _Len, _S, _Tr::length(_S)));
  831. }
  832. int compare(size_type _P0, size_type _N0, const _E *_S) const
  833. {
  834. return (compare(_P0, _N0, _S, _Tr::length(_S)));
  835. }
  836. int compare(size_type _P0, size_type _N0, const _E *_S,
  837. size_type _M) const
  838. {
  839. AssertH (_Len >= _P0);
  840. //if (_Len < _P0)
  841. // _Xran();
  842. if (_Len - _P0 < _N0)
  843. _N0 = _Len - _P0;
  844. size_type _Ans = _Tr::compare(_Psum(_Ptr, _P0), _S,
  845. _N0 < _M ? _N0 : _M);
  846. return (_Ans != 0 ? _Ans : _N0 < _M ? -1
  847. : _N0 == _M ? 0 : +1);
  848. }
  849. private:
  850. enum
  851. {
  852. // the number of characters that, when multiplied by sizeof(_E) will
  853. // still fit within the range of size_type. (We allocate two extra
  854. // characters -- one for the refcount, the other for the terminator.)
  855. //
  856. _MAX_SIZE = (((unsigned int)(-1)) / sizeof(_E)) - 2,
  857. // _MIN_SIZE seems to be an allocation granularity (in characters).
  858. // Allocation requests are bit ORed with _MIN_SIZE.
  859. //
  860. _MIN_SIZE = 7,
  861. //_MIN_SIZE = sizeof (_E) <= 32 ? 31 : 7
  862. };
  863. void _Copy(size_type _N)
  864. {
  865. //AssertSzH (_Len <= _N, "Can't allocate less than we need to copy");
  866. size_type _Ns = _N | _MIN_SIZE;
  867. if (_MAX_SIZE < _Ns)
  868. _Ns = _N;
  869. size_type _NewLen = (_Ns < _Len) ? _Ns : _Len;
  870. _E *_S = (_E*) MemAllocRaiseException ((_Ns + 2) * sizeof(_E));
  871. //_TRY_BEGIN
  872. //_S = allocator.allocate(_Ns + 2, (void *)0);
  873. //_CATCH_ALL
  874. //_Ns = _N;
  875. //_S = allocator.allocate(_Ns + 2, (void *)0);
  876. //_CATCH_END
  877. if (_Len)
  878. {
  879. _Tr::copy(_S + 1, _Ptr, _NewLen);
  880. }
  881. _Tidy(true);
  882. _Ptr = _S + 1;
  883. _Refcnt(_Ptr) = 0;
  884. _Res = _Ns;
  885. _Eos(_NewLen);
  886. }
  887. void _Eos(size_type _N)
  888. {
  889. _Tr::assign(_Ptr[_Len = _N], _E(0));
  890. }
  891. void _Freeze()
  892. {
  893. if (_Ptr != 0
  894. && _Refcnt(_Ptr) != 0 && _Refcnt(_Ptr) != _FROZEN)
  895. _Grow(_Len);
  896. if (_Ptr != 0)
  897. _Refcnt(_Ptr) = _FROZEN;
  898. }
  899. bool _Grow(size_type _N, bool _Trim = false)
  900. {
  901. AssertH (_N < _MAX_SIZE);
  902. //if (_MAX_SIZE < _N)
  903. // _Xlen();
  904. if (_Ptr != 0 && _Refcnt(_Ptr) != 0 && _Refcnt(_Ptr) != _FROZEN)
  905. {
  906. if (_N == 0)
  907. {
  908. --_Refcnt(_Ptr), _Tidy();
  909. return (false);
  910. }
  911. else
  912. {
  913. _Copy(_N);
  914. return (true);
  915. }
  916. }
  917. else if (_N == 0)
  918. {
  919. if (_Trim)
  920. {
  921. _Tidy(true);
  922. }
  923. else if (_Ptr != 0)
  924. {
  925. _Eos(0);
  926. }
  927. return (false);
  928. }
  929. else
  930. {
  931. if (_Trim && (_N > _Res || _Res > _MIN_SIZE))
  932. {
  933. _Tidy(true);
  934. _Copy(_N);
  935. }
  936. else if (!_Trim && (_N > _Res))
  937. {
  938. _Copy(_N);
  939. }
  940. return (true);
  941. }
  942. }
  943. static const _E * __cdecl _Nullstr()
  944. {
  945. static const _E _C = _E(0);
  946. return (&_C);
  947. }
  948. static size_type _Pdif(const_pointer _P2, const_pointer _P1)
  949. {
  950. return (_P2 == 0 ? 0 : _P2 - _P1);
  951. }
  952. static const_pointer _Psum(const_pointer _P, size_type _N)
  953. {
  954. return (_P == 0 ? 0 : _P + _N);
  955. }
  956. static pointer _Psum(pointer _P, size_type _N)
  957. {
  958. return (_P == 0 ? 0 : _P + _N);
  959. }
  960. unsigned short& _Refcnt(const _E *_U)
  961. {
  962. return (((unsigned short *)_U)[-1]);
  963. }
  964. void _Split()
  965. {
  966. if (_Ptr != 0 && _Refcnt(_Ptr) != 0 && _Refcnt(_Ptr) != _FROZEN)
  967. {
  968. _E *_Temp = _Ptr;
  969. _Tidy(true);
  970. assign(_Temp);
  971. }
  972. }
  973. void _Tidy(bool _Built = false)
  974. {
  975. if (!_Built || _Ptr == 0)
  976. {
  977. ;
  978. }
  979. else if (_Refcnt(_Ptr) == 0 || _Refcnt(_Ptr) == _FROZEN)
  980. {
  981. MemFree(_Ptr - 1);
  982. //allocator.deallocate(_Ptr - 1, _Res + 2);
  983. }
  984. else
  985. {
  986. --_Refcnt(_Ptr);
  987. }
  988. _Ptr = 0, _Len = 0, _Res = 0;
  989. }
  990. _E *_Ptr;
  991. size_type _Len, _Res;
  992. };
  993. inline
  994. CWideString __cdecl operator+(
  995. const CWideString& _L,
  996. const CWideString& _R)
  997. {return (CWideString(_L) += _R); }
  998. inline
  999. CWideString __cdecl operator+(
  1000. const CWideString::_E *_L,
  1001. const CWideString& _R)
  1002. {return (CWideString(_L) += _R); }
  1003. inline
  1004. CWideString __cdecl operator+(
  1005. const CWideString::_E _L,
  1006. const CWideString& _R)
  1007. {return (CWideString(1, _L) += _R); }
  1008. inline
  1009. CWideString __cdecl operator+(
  1010. const CWideString& _L,
  1011. const CWideString::_E *_R)
  1012. {return (CWideString(_L) += _R); }
  1013. inline
  1014. CWideString __cdecl operator+(
  1015. const CWideString& _L,
  1016. const CWideString::_E _R)
  1017. {return (CWideString(_L) += _R); }
  1018. inline
  1019. bool __cdecl operator==(
  1020. const CWideString& _L,
  1021. const CWideString& _R)
  1022. {return (_L.compare(_R) == 0); }
  1023. inline
  1024. bool __cdecl operator==(
  1025. const CWideString::_E * _L,
  1026. const CWideString& _R)
  1027. {return (_R.compare(_L) == 0); }
  1028. inline
  1029. bool __cdecl operator==(
  1030. const CWideString& _L,
  1031. const CWideString::_E *_R)
  1032. {return (_L.compare(_R) == 0); }
  1033. inline
  1034. bool __cdecl operator!=(
  1035. const CWideString& _L,
  1036. const CWideString& _R)
  1037. {return (!(_L == _R)); }
  1038. inline
  1039. bool __cdecl operator!=(
  1040. const CWideString::_E *_L,
  1041. const CWideString& _R)
  1042. {return (!(_L == _R)); }
  1043. inline
  1044. bool __cdecl operator!=(
  1045. const CWideString& _L,
  1046. const CWideString::_E *_R)
  1047. {return (!(_L == _R)); }
  1048. inline
  1049. bool __cdecl operator<(
  1050. const CWideString& _L,
  1051. const CWideString& _R)
  1052. {return (_L.compare(_R) < 0); }
  1053. inline
  1054. bool __cdecl operator<(
  1055. const CWideString::_E * _L,
  1056. const CWideString& _R)
  1057. {return (_R.compare(_L) > 0); }
  1058. inline
  1059. bool __cdecl operator<(
  1060. const CWideString& _L,
  1061. const CWideString::_E *_R)
  1062. {return (_L.compare(_R) < 0); }
  1063. inline
  1064. bool __cdecl operator>(
  1065. const CWideString& _L,
  1066. const CWideString& _R)
  1067. {return (_R < _L); }
  1068. inline
  1069. bool __cdecl operator>(
  1070. const CWideString::_E * _L,
  1071. const CWideString& _R)
  1072. {return (_R < _L); }
  1073. inline
  1074. bool __cdecl operator>(
  1075. const CWideString& _L,
  1076. const CWideString::_E *_R)
  1077. {return (_R < _L); }
  1078. inline
  1079. bool __cdecl operator<=(
  1080. const CWideString& _L,
  1081. const CWideString& _R)
  1082. {return (!(_R < _L)); }
  1083. inline
  1084. bool __cdecl operator<=(
  1085. const CWideString::_E * _L,
  1086. const CWideString& _R)
  1087. {return (!(_R < _L)); }
  1088. inline
  1089. bool __cdecl operator<=(
  1090. const CWideString& _L,
  1091. const CWideString::_E *_R)
  1092. {return (!(_R < _L)); }
  1093. inline
  1094. bool __cdecl operator>=(
  1095. const CWideString& _L,
  1096. const CWideString& _R)
  1097. {return (!(_L < _R)); }
  1098. inline
  1099. bool __cdecl operator>=(
  1100. const CWideString::_E * _L,
  1101. const CWideString& _R)
  1102. {return (!(_L < _R)); }
  1103. inline
  1104. bool __cdecl operator>=(
  1105. const CWideString& _L,
  1106. const CWideString::_E *_R)
  1107. {return (!(_L < _R)); }
  1108. #endif // _NCSTLSTR_H_