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.

627 lines
19 KiB

  1. // xstring internal header (from <string>)
  2. #ifndef _XSTRING_
  3. #define _XSTRING_
  4. #include <xmemory>
  5. #ifdef _MSC_VER
  6. #pragma pack(push,8)
  7. #endif /* _MSC_VER */
  8. #include <xutility>
  9. _STD_BEGIN
  10. _CRTIMP2 void __cdecl _Xlen();
  11. _CRTIMP2 void __cdecl _Xran();
  12. // TEMPLATE CLASS basic_string
  13. template<class _E,
  14. class _Tr = char_traits<_E>,
  15. class _A = allocator<_E> >
  16. class basic_string {
  17. public:
  18. typedef basic_string<_E, _Tr, _A> _Myt;
  19. typedef _A::size_type size_type;
  20. typedef _A::difference_type difference_type;
  21. typedef _A::pointer pointer;
  22. typedef _A::const_pointer const_pointer;
  23. typedef _A::reference reference;
  24. typedef _A::const_reference const_reference;
  25. typedef _A::value_type value_type;
  26. typedef _A::pointer iterator;
  27. typedef _A::const_pointer const_iterator;
  28. typedef reverse_iterator<const_iterator, value_type,
  29. const_reference, const_pointer, difference_type>
  30. const_reverse_iterator;
  31. typedef reverse_iterator<iterator, value_type,
  32. reference, pointer, difference_type>
  33. reverse_iterator;
  34. explicit basic_string(const _A& _Al = _A())
  35. : allocator(_Al) {_Tidy(); }
  36. basic_string(const _Myt& _X)
  37. : allocator(_X.allocator)
  38. {_Tidy(), assign(_X, 0, npos); }
  39. basic_string(const _Myt& _X, size_type _P, size_type _M,
  40. const _A& _Al = _A())
  41. : allocator(_Al) {_Tidy(), assign(_X, _P, _M); }
  42. basic_string(const _E *_S, size_type _N,
  43. const _A& _Al = _A())
  44. : allocator(_Al) {_Tidy(), assign(_S, _N); }
  45. basic_string(const _E *_S, const _A& _Al = _A())
  46. : allocator(_Al) {_Tidy(), assign(_S); }
  47. basic_string(size_type _N, _E _C, const _A& _Al = _A())
  48. : allocator(_Al) {_Tidy(), assign(_N, _C); }
  49. typedef const_iterator _It;
  50. basic_string(_It _F, _It _L, const _A& _Al = _A())
  51. : allocator(_Al) {_Tidy(); assign(_F, _L); }
  52. ~basic_string()
  53. {_Tidy(true); }
  54. typedef _Tr traits_type;
  55. typedef _A allocator_type;
  56. enum _Mref {_FROZEN = 255};
  57. static const size_type npos;
  58. _Myt& operator=(const _Myt& _X)
  59. {return (assign(_X)); }
  60. _Myt& operator=(const _E *_S)
  61. {return (assign(_S)); }
  62. _Myt& operator=(_E _C)
  63. {return (assign(1, _C)); }
  64. _Myt& operator+=(const _Myt& _X)
  65. {return (append(_X)); }
  66. _Myt& operator+=(const _E *_S)
  67. {return (append(_S)); }
  68. _Myt& operator+=(_E _C)
  69. {return (append(1, _C)); }
  70. _Myt& append(const _Myt& _X)
  71. {return (append(_X, 0, npos)); }
  72. _Myt& append(const _Myt& _X, size_type _P, size_type _M)
  73. {if (_X.size() < _P)
  74. _Xran();
  75. size_type _N = _X.size() - _P;
  76. if (_N < _M)
  77. _M = _N;
  78. if (npos - _Len <= _M)
  79. _Xlen();
  80. if (0 < _M && _Grow(_N = _Len + _M))
  81. {_Tr::copy(_Ptr + _Len, &_X.c_str()[_P], _M);
  82. _Eos(_N); }
  83. return (*this); }
  84. _Myt& append(const _E *_S, size_type _M)
  85. {if (npos - _Len <= _M)
  86. _Xlen();
  87. size_type _N;
  88. if (0 < _M && _Grow(_N = _Len + _M))
  89. {_Tr::copy(_Ptr + _Len, _S, _M);
  90. _Eos(_N); }
  91. return (*this); }
  92. _Myt& append(const _E *_S)
  93. {return (append(_S, _Tr::length(_S))); }
  94. _Myt& append(size_type _M, _E _C)
  95. {if (npos - _Len <= _M)
  96. _Xlen();
  97. size_type _N;
  98. if (0 < _M && _Grow(_N = _Len + _M))
  99. {_Tr::assign(_Ptr + _Len, _M, _C);
  100. _Eos(_N); }
  101. return (*this); }
  102. _Myt& append(_It _F, _It _L)
  103. {return (replace(end(), end(), _F, _L)); }
  104. _Myt& assign(const _Myt& _X)
  105. {return (assign(_X, 0, npos)); }
  106. _Myt& assign(const _Myt& _X, size_type _P, size_type _M)
  107. {if (_X.size() < _P)
  108. _Xran();
  109. size_type _N = _X.size() - _P;
  110. if (_M < _N)
  111. _N = _M;
  112. if (this == &_X)
  113. erase((size_type)(_P + _N)), erase(0, _P);
  114. else if (0 < _N && _N == _X.size()
  115. && _Refcnt(_X.c_str()) < _FROZEN - 1
  116. && allocator == _X.allocator)
  117. {_Tidy(true);
  118. _Ptr = (_E *)_X.c_str();
  119. _Len = _X.size();
  120. _Res = _X.capacity();
  121. ++_Refcnt(_Ptr); }
  122. else if (_Grow(_N, true))
  123. {_Tr::copy(_Ptr, &_X.c_str()[_P], _N);
  124. _Eos(_N); }
  125. return (*this); }
  126. _Myt& assign(const _E *_S, size_type _N)
  127. {if (_Grow(_N, true))
  128. {_Tr::copy(_Ptr, _S, _N);
  129. _Eos(_N); }
  130. return (*this); }
  131. _Myt& assign(const _E *_S)
  132. {return (assign(_S, _Tr::length(_S))); }
  133. _Myt& assign(size_type _N, _E _C)
  134. {if (_N == npos)
  135. _Xlen();
  136. if (_Grow(_N, true))
  137. {_Tr::assign(_Ptr, _N, _C);
  138. _Eos(_N); }
  139. return (*this); }
  140. _Myt& assign(_It _F, _It _L)
  141. {return (replace(begin(), end(), _F, _L)); }
  142. _Myt& insert(size_type _P0, const _Myt& _X)
  143. {return (insert(_P0, _X, 0, npos)); }
  144. _Myt& insert(size_type _P0, const _Myt& _X, size_type _P,
  145. size_type _M)
  146. {if (_Len < _P0 || _X.size() < _P)
  147. _Xran();
  148. size_type _N = _X.size() - _P;
  149. if (_N < _M)
  150. _M = _N;
  151. if (npos - _Len <= _M)
  152. _Xlen();
  153. if (0 < _M && _Grow(_N = _Len + _M))
  154. {_Tr::move(_Ptr + _P0 + _M, _Ptr + _P0, _Len - _P0);
  155. _Tr::copy(_Ptr + _P0, &_X.c_str()[_P], _M);
  156. _Eos(_N); }
  157. return (*this); }
  158. _Myt& insert(size_type _P0, const _E *_S, size_type _M)
  159. {if (_Len < _P0)
  160. _Xran();
  161. if (npos - _Len <= _M)
  162. _Xlen();
  163. size_type _N;
  164. if (0 < _M && _Grow(_N = _Len + _M))
  165. {_Tr::move(_Ptr + _P0 + _M, _Ptr + _P0, _Len - _P0);
  166. _Tr::copy(_Ptr + _P0, _S, _M);
  167. _Eos(_N); }
  168. return (*this); }
  169. _Myt& insert(size_type _P0, const _E *_S)
  170. {return (insert(_P0, _S, _Tr::length(_S))); }
  171. _Myt& insert(size_type _P0, size_type _M, _E _C)
  172. {if (_Len < _P0)
  173. _Xran();
  174. if (npos - _Len <= _M)
  175. _Xlen();
  176. size_type _N;
  177. if (0 < _M && _Grow(_N = _Len + _M))
  178. {_Tr::move(_Ptr + _P0 + _M, _Ptr + _P0, _Len - _P0);
  179. _Tr::assign(_Ptr + _P0, _M, _C);
  180. _Eos(_N); }
  181. return (*this); }
  182. iterator insert(iterator _P, _E _C)
  183. {size_type _P0 = _Pdif(_P, begin());
  184. insert(_P0, 1, _C);
  185. return (begin() + _P0); }
  186. void insert(iterator _P, size_type _M, _E _C)
  187. {size_type _P0 = _Pdif(_P, begin());
  188. insert(_P0, _M, _C); }
  189. void insert(iterator _P, _It _F, _It _L)
  190. {replace(_P, _P, _F, _L); }
  191. _Myt& erase(size_type _P0 = 0, size_type _M = npos)
  192. {if (_Len < _P0)
  193. _Xran();
  194. _Split();
  195. if (_Len - _P0 < _M)
  196. _M = _Len - _P0;
  197. if (0 < _M)
  198. {_Tr::move(_Ptr + _P0, _Ptr + _P0 + _M,
  199. _Len - _P0 - _M);
  200. size_type _N = _Len - _M;
  201. if (_Grow(_N))
  202. _Eos(_N); }
  203. return (*this); }
  204. iterator erase(iterator _P)
  205. {size_t _M = _Pdif(_P, begin());
  206. erase(_M, 1);
  207. return (_Psum(_Ptr, _M)); }
  208. iterator erase(iterator _F, iterator _L)
  209. {size_t _M = _Pdif(_F, begin());
  210. erase(_M, _Pdif(_L, _F));
  211. return (_Psum(_Ptr, _M)); }
  212. _Myt& replace(size_type _P0, size_type _N0, const _Myt& _X)
  213. {return (replace(_P0, _N0, _X, 0, npos)); }
  214. _Myt& replace(size_type _P0, size_type _N0, const _Myt& _X,
  215. size_type _P, size_type _M)
  216. {if (_Len < _P0 || _X.size() < _P)
  217. _Xran();
  218. if (_Len - _P0 < _N0)
  219. _N0 = _Len - _P0;
  220. size_type _N = _X.size() - _P;
  221. if (_N < _M)
  222. _M = _N;
  223. if (npos - _M <= _Len - _N0)
  224. _Xlen();
  225. _Split();
  226. size_type _Nm = _Len - _N0 - _P0;
  227. if (_M < _N0)
  228. _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0 + _N0, _Nm);
  229. if ((0 < _M || 0 < _N0) && _Grow(_N = _Len + _M - _N0))
  230. {if (_N0 < _M)
  231. _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0 + _N0, _Nm);
  232. _Tr::copy(_Ptr + _P0, &_X.c_str()[_P], _M);
  233. _Eos(_N); }
  234. return (*this); }
  235. _Myt& replace(size_type _P0, size_type _N0, const _E *_S,
  236. size_type _M)
  237. {if (_Len < _P0)
  238. _Xran();
  239. if (_Len - _P0 < _N0)
  240. _N0 = _Len - _P0;
  241. if (npos - _M <= _Len - _N0)
  242. _Xlen();
  243. _Split();
  244. size_type _Nm = _Len - _N0 - _P0;
  245. if (_M < _N0)
  246. _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0 + _N0, _Nm);
  247. size_type _N;
  248. if ((0 < _M || 0 < _N0) && _Grow(_N = _Len + _M - _N0))
  249. {if (_N0 < _M)
  250. _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0 + _N0, _Nm);
  251. _Tr::copy(_Ptr + _P0, _S, _M);
  252. _Eos(_N); }
  253. return (*this); }
  254. _Myt& replace(size_type _P0, size_type _N0, const _E *_S)
  255. {return (replace(_P0, _N0, _S, _Tr::length(_S))); }
  256. _Myt& replace(size_type _P0, size_type _N0,
  257. size_type _M, _E _C)
  258. {if (_Len < _P0)
  259. _Xran();
  260. if (_Len - _P0 < _N0)
  261. _N0 = _Len - _P0;
  262. if (npos - _M <= _Len - _N0)
  263. _Xlen();
  264. _Split();
  265. size_type _Nm = _Len - _N0 - _P0;
  266. if (_M < _N0)
  267. _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0 + _N0, _Nm);
  268. size_type _N;
  269. if ((0 < _M || 0 < _N0) && _Grow(_N = _Len + _M - _N0))
  270. {if (_N0 < _M)
  271. _Tr::move(_Ptr + _P0 + _M, _Ptr + _P0 + _N0,
  272. _Nm);
  273. _Tr::assign(_Ptr + _P0, _M, _C);
  274. _Eos(_N); }
  275. return (*this); }
  276. _Myt& replace(iterator _F, iterator _L, const _Myt& _X)
  277. {return (replace(
  278. _Pdif(_F, begin()), _Pdif(_L, _F), _X)); }
  279. _Myt& replace(iterator _F, iterator _L, const _E *_S,
  280. size_type _M)
  281. {return (replace(
  282. _Pdif(_F, begin()), _Pdif(_L, _F), _S, _M)); }
  283. _Myt& replace(iterator _F, iterator _L, const _E *_S)
  284. {return (replace(
  285. _Pdif(_F, begin()), _Pdif(_L, _F), _S)); }
  286. _Myt& replace(iterator _F, iterator _L, size_type _M, _E _C)
  287. {return (replace(
  288. _Pdif(_F, begin()), _Pdif(_L, _F), _M, _C)); }
  289. _Myt& replace(iterator _F1, iterator _L1,
  290. _It _F2, _It _L2)
  291. {size_type _P0 = _Pdif(_F1, begin());
  292. size_type _M = 0;
  293. _Distance(_F2, _L2, _M);
  294. replace(_P0, _Pdif(_L1, _F1), _M, _E(0));
  295. for (_F1 = begin() + _P0; 0 < _M; ++_F1, ++_F2, --_M)
  296. *_F1 = *_F2;
  297. return (*this); }
  298. iterator begin()
  299. {_Freeze();
  300. return (_Ptr); }
  301. const_iterator begin() const
  302. {return (_Ptr); }
  303. iterator end()
  304. {_Freeze();
  305. return ((iterator)_Psum(_Ptr, _Len)); }
  306. const_iterator end() const
  307. {return ((const_iterator)_Psum(_Ptr, _Len)); }
  308. reverse_iterator rbegin()
  309. {return (reverse_iterator(end())); }
  310. const_reverse_iterator rbegin() const
  311. {return (const_reverse_iterator(end())); }
  312. reverse_iterator rend()
  313. {return (reverse_iterator(begin())); }
  314. const_reverse_iterator rend() const
  315. {return (const_reverse_iterator(begin())); }
  316. reference at(size_type _P0)
  317. {if (_Len <= _P0)
  318. _Xran();
  319. _Freeze();
  320. return (_Ptr[_P0]); }
  321. const_reference at(size_type _P0) const
  322. {if (_Len <= _P0)
  323. _Xran();
  324. return (_Ptr[_P0]); }
  325. reference operator[](size_type _P0)
  326. {if (_Len < _P0 || _Ptr == 0)
  327. return ((reference)*_Nullstr());
  328. _Freeze();
  329. return (_Ptr[_P0]); }
  330. const_reference operator[](size_type _P0) const
  331. {if (_Ptr == 0)
  332. return (*_Nullstr());
  333. else
  334. return (_Ptr[_P0]); }
  335. const _E *c_str() const
  336. {return (_Ptr == 0 ? _Nullstr() : _Ptr); }
  337. const _E *data() const
  338. {return (c_str()); }
  339. size_type length() const
  340. {return (_Len); }
  341. size_type size() const
  342. {return (_Len); }
  343. size_type max_size() const
  344. {size_type _N = allocator.max_size();
  345. return (_N <= 2 ? 1 : _N - 2); }
  346. void resize(size_type _N, _E _C)
  347. {_N <= _Len ? erase(_N) : append(_N - _Len, _C); }
  348. void resize(size_type _N)
  349. {_N <= _Len ? erase(_N) : append(_N - _Len, _E(0)); }
  350. size_type capacity() const
  351. {return (_Res); }
  352. void reserve(size_type _N = 0)
  353. {if (_Res < _N)
  354. _Grow(_N); }
  355. bool empty() const
  356. {return (_Len == 0); }
  357. size_type copy(_E *_S, size_type _N, size_type _P0 = 0) const
  358. {if (_Len < _P0)
  359. _Xran();
  360. if (_Len - _P0 < _N)
  361. _N = _Len - _P0;
  362. if (0 < _N)
  363. _Tr::copy(_S, _Ptr + _P0, _N);
  364. return (_N); }
  365. void swap(_Myt& _X)
  366. {if (allocator == _X.allocator)
  367. {std::swap(_Ptr, _X._Ptr);
  368. std::swap(_Len, _X._Len);
  369. std::swap(_Res, _X._Res); }
  370. else
  371. {_Myt _Ts = *this; *this = _X, _X = _Ts; }}
  372. friend void swap(_Myt& _X, _Myt& _Y)
  373. {_X.swap(_Y); }
  374. size_type find(const _Myt& _X, size_type _P = 0) const
  375. {return (find(_X.c_str(), _P, _X.size())); }
  376. size_type find(const _E *_S, size_type _P,
  377. size_type _N) const
  378. {if (_N == 0 && _P <= _Len)
  379. return (_P);
  380. size_type _Nm;
  381. if (_P < _Len && _N <= (_Nm = _Len - _P))
  382. {const _E *_U, *_V;
  383. for (_Nm -= _N - 1, _V = _Ptr + _P;
  384. (_U = _Tr::find(_V, _Nm, *_S)) != 0;
  385. _Nm -= (size_type) (_U - _V + 1), _V = _U + 1)
  386. if (_Tr::compare(_U, _S, _N) == 0)
  387. return (_U - _Ptr); }
  388. return (npos); }
  389. size_type find(const _E *_S, size_type _P = 0) const
  390. {return (find(_S, _P, _Tr::length(_S))); }
  391. size_type find(_E _C, size_type _P = 0) const
  392. {return (find((const _E *)&_C, _P, 1)); }
  393. size_type rfind(const _Myt& _X, size_type _P = npos) const
  394. {return (rfind(_X.c_str(), _P, _X.size())); }
  395. size_type rfind(const _E *_S, size_type _P,
  396. size_type _N) const
  397. {if (_N == 0)
  398. return (_P < _Len ? _P : _Len);
  399. if (_N <= _Len)
  400. for (const _E *_U = _Ptr +
  401. + (_P < _Len - _N ? _P : _Len - _N); ; --_U)
  402. if (_Tr::eq(*_U, *_S)
  403. && _Tr::compare(_U, _S, _N) == 0)
  404. return (_U - _Ptr);
  405. else if (_U == _Ptr)
  406. break;
  407. return (npos); }
  408. size_type rfind(const _E *_S, size_type _P = npos) const
  409. {return (rfind(_S, _P, _Tr::length(_S))); }
  410. size_type rfind(_E _C, size_type _P = npos) const
  411. {return (rfind((const _E *)&_C, _P, 1)); }
  412. size_type find_first_of(const _Myt& _X,
  413. size_type _P = 0) const
  414. {return (find_first_of(_X.c_str(), _P, _X.size())); }
  415. size_type find_first_of(const _E *_S, size_type _P,
  416. size_type _N) const
  417. {if (0 < _N && _P < _Len)
  418. {const _E *const _V = _Ptr + _Len;
  419. for (const _E *_U = _Ptr + _P; _U < _V; ++_U)
  420. if (_Tr::find(_S, _N, *_U) != 0)
  421. return (_U - _Ptr); }
  422. return (npos); }
  423. size_type find_first_of(const _E *_S, size_type _P = 0) const
  424. {return (find_first_of(_S, _P, _Tr::length(_S))); }
  425. size_type find_first_of(_E _C, size_type _P = 0) const
  426. {return (find((const _E *)&_C, _P, 1)); }
  427. size_type find_last_of(const _Myt& _X,
  428. size_type _P = npos) const
  429. {return (find_last_of(_X.c_str(), _P, _X.size())); }
  430. size_type find_last_of(const _E *_S, size_type _P,
  431. size_type _N) const
  432. {if (0 < _N && 0 < _Len)
  433. for (const _E *_U = _Ptr
  434. + (_P < _Len ? _P : _Len - 1); ; --_U)
  435. if (_Tr::find(_S, _N, *_U) != 0)
  436. return (_U - _Ptr);
  437. else if (_U == _Ptr)
  438. break;
  439. return (npos); }
  440. size_type find_last_of(const _E *_S,
  441. size_type _P = npos) const
  442. {return (find_last_of(_S, _P, _Tr::length(_S))); }
  443. size_type find_last_of(_E _C, size_type _P = npos) const
  444. {return (rfind((const _E *)&_C, _P, 1)); }
  445. size_type find_first_not_of(const _Myt& _X,
  446. size_type _P = 0) const
  447. {return (find_first_not_of(_X.c_str(), _P,
  448. _X.size())); }
  449. size_type find_first_not_of(const _E *_S, size_type _P,
  450. size_type _N) const
  451. {if (_P < _Len)
  452. {const _E *const _V = _Ptr + _Len;
  453. for (const _E *_U = _Ptr + _P; _U < _V; ++_U)
  454. if (_Tr::find(_S, _N, *_U) == 0)
  455. return (_U - _Ptr); }
  456. return (npos); }
  457. size_type find_first_not_of(const _E *_S,
  458. size_type _P = 0) const
  459. {return (find_first_not_of(_S, _P, _Tr::length(_S))); }
  460. size_type find_first_not_of(_E _C, size_type _P = 0) const
  461. {return (find_first_not_of((const _E *)&_C, _P, 1)); }
  462. size_type find_last_not_of(const _Myt& _X,
  463. size_type _P = npos) const
  464. {return (find_last_not_of(_X.c_str(), _P, _X.size())); }
  465. size_type find_last_not_of(const _E *_S, size_type _P,
  466. size_type _N) const
  467. {if (0 < _Len)
  468. for (const _E *_U = _Ptr
  469. + (_P < _Len ? _P : _Len - 1); ; --_U)
  470. if (_Tr::find(_S, _N, *_U) == 0)
  471. return (_U - _Ptr);
  472. else if (_U == _Ptr)
  473. break;
  474. return (npos); }
  475. size_type find_last_not_of(const _E *_S,
  476. size_type _P = npos) const
  477. {return (find_last_not_of(_S, _P, _Tr::length(_S))); }
  478. size_type find_last_not_of(_E _C, size_type _P = npos) const
  479. {return (find_last_not_of((const _E *)&_C, _P, 1)); }
  480. _Myt substr(size_type _P = 0, size_type _M = npos) const
  481. {return (_Myt(*this, _P, _M)); }
  482. int compare(const _Myt& _X) const
  483. {return (compare(0, _Len, _X.c_str(), _X.size())); }
  484. int compare(size_type _P0, size_type _N0,
  485. const _Myt& _X) const
  486. {return (compare(_P0, _N0, _X, 0, npos)); }
  487. int compare(size_type _P0, size_type _N0, const _Myt& _X,
  488. size_type _P, size_type _M) const
  489. {if (_X.size() < _P)
  490. _Xran();
  491. if (_X._Len - _P < _M)
  492. _M = _X._Len - _P;
  493. return (compare(_P0, _N0, _X.c_str() + _P, _M)); }
  494. int compare(const _E *_S) const
  495. {return (compare(0, _Len, _S, _Tr::length(_S))); }
  496. int compare(size_type _P0, size_type _N0, const _E *_S) const
  497. {return (compare(_P0, _N0, _S, _Tr::length(_S))); }
  498. int compare(size_type _P0, size_type _N0, const _E *_S,
  499. size_type _M) const
  500. {if (_Len < _P0)
  501. _Xran();
  502. if (_Len - _P0 < _N0)
  503. _N0 = _Len - _P0;
  504. size_type _Ans = _Tr::compare(_Psum(_Ptr, _P0), _S,
  505. _N0 < _M ? _N0 : _M);
  506. return (int)(_Ans != 0 ? _Ans : _N0 < _M ? -1
  507. : _N0 == _M ? 0 : +1); }
  508. _A get_allocator() const
  509. {return (allocator); }
  510. protected:
  511. _A allocator;
  512. private:
  513. enum {_MIN_SIZE = sizeof (_E) <= 32 ? 31 : 7};
  514. void _Copy(size_type _N)
  515. {size_type _Ns = _N | _MIN_SIZE;
  516. if (max_size() < _Ns)
  517. _Ns = _N;
  518. _E *_S;
  519. _TRY_BEGIN
  520. _S = allocator.allocate(_Ns + 2, (void *)0);
  521. _CATCH_ALL
  522. _Ns = _N;
  523. _S = allocator.allocate(_Ns + 2, (void *)0);
  524. _CATCH_END
  525. if (0 < _Len)
  526. _Tr::copy(_S + 1, _Ptr,_Len>_Ns?_Ns:_Len);
  527. size_type _Olen = _Len;
  528. _Tidy(true);
  529. _Ptr = _S + 1;
  530. _Refcnt(_Ptr) = 0;
  531. _Res = _Ns;
  532. _Eos(_Olen>_Ns?_Ns:_Olen); }
  533. void _Eos(size_type _N)
  534. {_Tr::assign(_Ptr[_Len = _N], _E(0)); }
  535. void _Freeze()
  536. {if (_Ptr != 0
  537. && _Refcnt(_Ptr) != 0 && _Refcnt(_Ptr) != _FROZEN)
  538. _Grow(_Len);
  539. if (_Ptr != 0)
  540. _Refcnt(_Ptr) = _FROZEN; }
  541. bool _Grow(size_type _N, bool _Trim = false)
  542. {if (max_size() < _N)
  543. _Xlen();
  544. if (_Ptr != 0
  545. && _Refcnt(_Ptr) != 0 && _Refcnt(_Ptr) != _FROZEN)
  546. if (_N == 0)
  547. {--_Refcnt(_Ptr), _Tidy();
  548. return (false); }
  549. else
  550. {_Copy(_N);
  551. return (true); }
  552. if (_N == 0)
  553. {if (_Trim)
  554. _Tidy(true);
  555. else if (_Ptr != 0)
  556. _Eos(0);
  557. return (false); }
  558. else
  559. {if (_Trim && (_MIN_SIZE < _Res || _Res < _N))
  560. {_Tidy(true);
  561. _Copy(_N); }
  562. else if (!_Trim && _Res < _N)
  563. _Copy(_N);
  564. return (true); }}
  565. static const _E * __cdecl _Nullstr()
  566. {static const _E _C = _E(0);
  567. return (&_C); }
  568. static size_type _Pdif(const_pointer _P2, const_pointer _P1)
  569. {return (_P2 == 0 ? 0 : _P2 - _P1); }
  570. static const_pointer _Psum(const_pointer _P, size_type _N)
  571. {return (_P == 0 ? 0 : _P + _N); }
  572. static pointer _Psum(pointer _P, size_type _N)
  573. {return (_P == 0 ? 0 : _P + _N); }
  574. unsigned char& _Refcnt(const _E *_U)
  575. {return (((unsigned char *)_U)[-1]); }
  576. void _Split()
  577. {if (_Ptr != 0 && _Refcnt(_Ptr) != 0 && _Refcnt(_Ptr) != _FROZEN)
  578. {_E *_Temp = _Ptr;
  579. _Tidy(true);
  580. assign(_Temp); }}
  581. void _Tidy(bool _Built = false)
  582. {if (!_Built || _Ptr == 0)
  583. ;
  584. else if (_Refcnt(_Ptr) == 0 || _Refcnt(_Ptr) == _FROZEN)
  585. allocator.deallocate(_Ptr - 1, _Res + 2);
  586. else
  587. --_Refcnt(_Ptr);
  588. _Ptr = 0, _Len = 0, _Res = 0; }
  589. _E *_Ptr;
  590. size_type _Len, _Res;
  591. };
  592. template<class _E, class _Tr, class _A>
  593. const basic_string<_E, _Tr, _A>::size_type
  594. basic_string<_E, _Tr, _A>::npos = -1;
  595. #ifdef _DLL
  596. #ifdef __FORCE_INSTANCE
  597. template class _CRTIMP2 basic_string<char, char_traits<char>, allocator<char> >;
  598. template class _CRTIMP2 basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> >;
  599. #else // __FORCE_INSTANCE
  600. #pragma warning(disable:4231) /* the extern before template is a non-standard extension */
  601. extern template class _CRTIMP2 basic_string<char, char_traits<char>, allocator<char> >;
  602. extern template class _CRTIMP2 basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> >;
  603. #pragma warning(default:4231) /* restore previous warning */
  604. #endif // __FORCE_INSTANCE
  605. #endif // _DLL
  606. typedef basic_string<char, char_traits<char>, allocator<char> >
  607. string;
  608. typedef basic_string<wchar_t, char_traits<wchar_t>,
  609. allocator<wchar_t> > wstring;
  610. _STD_END
  611. #ifdef _MSC_VER
  612. #pragma pack(pop)
  613. #endif /* _MSC_VER */
  614. #endif /* _XSTRING */
  615. /*
  616. * Copyright (c) 1995 by P.J. Plauger. ALL RIGHTS RESERVED.
  617. * Consult your license regarding permissions and restrictions.
  618. */