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.

1325 lines
37 KiB

  1. // xstring internal header (from <string>)
  2. #pragma once
  3. #ifndef _XSTRING_
  4. #define _XSTRING_
  5. #include <xmemory>
  6. #pragma pack(push,8)
  7. #pragma warning(push,3)
  8. #pragma warning(disable: 4251)
  9. _STD_BEGIN
  10. // CLASS _String_base
  11. class _CRTIMP2 _String_base
  12. { // ultimate base class for basic_string to hold error reporters
  13. public:
  14. void _Xlen() const; // report a length_error
  15. void _Xran() const; // report an out_of_range error
  16. };
  17. // TEMPLATE CLASS _String_val
  18. template<class _Ty,
  19. class _Alloc>
  20. class _String_val
  21. : public _String_base
  22. { // base class for basic_string to hold allocator _Alval
  23. protected:
  24. typedef typename _Alloc::_TEMPLATE_MEMBER
  25. rebind<_Ty>::other _Alty;
  26. _String_val(_Alty _Al = _Alty())
  27. : _Alval(_Al)
  28. { // construct allocator from _Al
  29. }
  30. _Alty _Alval; // allocator object for strings
  31. };
  32. // TEMPLATE CLASS basic_string
  33. template<class _Elem,
  34. class _Traits = char_traits<_Elem>,
  35. class _Ax = allocator<_Elem> >
  36. class basic_string
  37. : public _String_val<_Elem, _Ax>
  38. { // null-terminated transparent array of elements
  39. public:
  40. typedef basic_string<_Elem, _Traits, _Ax> _Myt;
  41. typedef _String_val<_Elem, _Ax> _Mybase;
  42. typedef typename _Mybase::_Alty _Alloc;
  43. typedef typename _Alloc::size_type size_type;
  44. typedef typename _Alloc::difference_type difference_type;
  45. typedef typename _Alloc::pointer _Tptr;
  46. typedef typename _Alloc::const_pointer _Ctptr;
  47. typedef _Tptr pointer;
  48. typedef _Ctptr const_pointer;
  49. typedef typename _Alloc::reference reference;
  50. typedef typename _Alloc::const_reference const_reference;
  51. typedef typename _Alloc::value_type value_type;
  52. typedef _Ptrit<value_type, difference_type, _Tptr,
  53. reference, _Tptr, reference> iterator;
  54. typedef _Ptrit<value_type, difference_type, _Ctptr,
  55. const_reference, _Tptr, reference> const_iterator;
  56. typedef std::reverse_iterator<iterator>
  57. reverse_iterator;
  58. typedef std::reverse_iterator<const_iterator>
  59. const_reverse_iterator;
  60. basic_string()
  61. : _Mybase()
  62. { // construct empty string
  63. _Tidy();
  64. }
  65. explicit basic_string(const _Alloc& _Al)
  66. : _Mybase(_Al)
  67. { // construct empty string with allocator
  68. _Tidy();
  69. }
  70. basic_string(const _Myt& _Right)
  71. : _Mybase(_Right._Alval)
  72. { // construct by copying _Right
  73. _Tidy();
  74. assign(_Right, 0, npos);
  75. }
  76. basic_string(const _Myt& _Right, size_type _Roff,
  77. size_type _Count = npos)
  78. : _Mybase()
  79. { // construct from _Right [_Roff, _Roff + _Count)
  80. _Tidy();
  81. assign(_Right, _Roff, _Count);
  82. }
  83. basic_string(const _Myt& _Right, size_type _Roff, size_type _Count,
  84. const _Alloc& _Al)
  85. : _Mybase(_Al)
  86. { // construct from _Right [_Roff, _Roff + _Count) with allocator
  87. _Tidy();
  88. assign(_Right, _Roff, _Count);
  89. }
  90. basic_string(const _Elem *_Ptr, size_type _Count)
  91. : _Mybase()
  92. { // construct from [_Ptr, _Ptr + _Count)
  93. _Tidy();
  94. assign(_Ptr, _Count);
  95. }
  96. basic_string(const _Elem *_Ptr, size_type _Count, const _Alloc& _Al)
  97. : _Mybase(_Al)
  98. { // construct from [_Ptr, _Ptr + _Count) with allocator
  99. _Tidy();
  100. assign(_Ptr, _Count);
  101. }
  102. basic_string(const _Elem *_Ptr)
  103. : _Mybase()
  104. { // construct from [_Ptr, <null>)
  105. _Tidy();
  106. assign(_Ptr);
  107. }
  108. basic_string(const _Elem *_Ptr, const _Alloc& _Al)
  109. : _Mybase(_Al)
  110. { // construct from [_Ptr, <null>) with allocator
  111. _Tidy();
  112. assign(_Ptr);
  113. }
  114. basic_string(size_type _Count, _Elem _Ch)
  115. : _Mybase()
  116. { // construct from _Count * _Ch
  117. _Tidy();
  118. assign(_Count, _Ch);
  119. }
  120. basic_string(size_type _Count, _Elem _Ch, const _Alloc& _Al)
  121. : _Mybase(_Al)
  122. { // construct from _Count * _Ch with allocator
  123. _Tidy();
  124. assign(_Count, _Ch);
  125. }
  126. template<class _It>
  127. basic_string(_It _First, _It _Last)
  128. : _Mybase()
  129. { // construct from [_First, _Last)
  130. _Tidy();
  131. _Construct(_First, _Last, _Iter_cat(_First));
  132. }
  133. template<class _It>
  134. basic_string(_It _First, _It _Last, const _Alloc& _Al)
  135. : _Mybase(_Al)
  136. { // construct from [_First, _Last) with allocator
  137. _Tidy();
  138. _Construct(_First, _Last, _Iter_cat(_First));
  139. }
  140. template<class _It>
  141. void _Construct(_It _Count, _It _Ch, _Int_iterator_tag)
  142. { // initialize from _Count * _Ch
  143. assign((size_type)_Count, (_Elem)_Ch);
  144. }
  145. template<class _It>
  146. void _Construct(_It _First, _It _Last, input_iterator_tag)
  147. { // initialize from [_First, _Last), input iterators
  148. _TRY_BEGIN
  149. for (; _First != _Last; ++_First)
  150. append((size_type)1, (_Elem)*_First);
  151. _CATCH_ALL
  152. _Tidy(true);
  153. _RERAISE;
  154. _CATCH_END
  155. }
  156. template<class _It>
  157. void _Construct(_It _First, _It _Last, forward_iterator_tag)
  158. { // initialize from [_First, _Last), forward iterators
  159. size_type _Count = 0;
  160. _Distance(_First, _Last, _Count);
  161. reserve(_Count);
  162. _TRY_BEGIN
  163. for (; _First != _Last; ++_First)
  164. append((size_type)1, (_Elem)*_First);
  165. _CATCH_ALL
  166. _Tidy(true);
  167. _RERAISE;
  168. _CATCH_END
  169. }
  170. basic_string(const_pointer _First, const_pointer _Last)
  171. : _Mybase()
  172. { // construct from [_First, _Last), const pointers
  173. _Tidy();
  174. if (_First != _Last)
  175. assign(&*_First, _Last - _First);
  176. }
  177. basic_string(const_iterator _First, const_iterator _Last)
  178. : _Mybase()
  179. { // construct from [_First, _Last), const_iterators
  180. _Tidy();
  181. if (_First != _Last)
  182. assign(&*_First, _Last - _First);
  183. }
  184. ~basic_string()
  185. { // destroy the string
  186. _Tidy(true);
  187. }
  188. typedef _Traits traits_type;
  189. typedef _Alloc allocator_type;
  190. static const size_type npos; // generic bad/missing length/position
  191. _Myt& operator=(const _Myt& _Right)
  192. { // assign _Right
  193. return (assign(_Right));
  194. }
  195. _Myt& operator=(const _Elem *_Ptr)
  196. { // assign [_Ptr, <null>)
  197. return (assign(_Ptr));
  198. }
  199. _Myt& operator=(_Elem _Ch)
  200. { // assign 1 * _Ch
  201. return (assign(1, _Ch));
  202. }
  203. _Myt& operator+=(const _Myt& _Right)
  204. { // append _Right
  205. return (append(_Right));
  206. }
  207. _Myt& operator+=(const _Elem *_Ptr)
  208. { // append [_Ptr, <null>)
  209. return (append(_Ptr));
  210. }
  211. _Myt& operator+=(_Elem _Ch)
  212. { // append 1 * _Ch
  213. return (append((size_type)1, _Ch));
  214. }
  215. _Myt& append(const _Myt& _Right)
  216. { // append _Right
  217. return (append(_Right, 0, npos));
  218. }
  219. _Myt& append(const _Myt& _Right, size_type _Roff, size_type _Count)
  220. { // append _Right [_Roff, _Roff + _Count)
  221. if (_Right.size() < _Roff)
  222. _String_base::_Xran(); // _Roff off end
  223. size_type _Num = _Right.size() - _Roff;
  224. if (_Num < _Count)
  225. _Count = _Num; // trim _Count to size
  226. if (npos - _Mysize <= _Count)
  227. _String_base::_Xlen(); // result too long
  228. if (0 < _Count && _Grow(_Num = _Mysize + _Count))
  229. { // make room and append new stuff
  230. _Traits::copy(_Myptr() + _Mysize,
  231. _Right._Myptr() + _Roff, _Count);
  232. _Eos(_Num);
  233. }
  234. return (*this);
  235. }
  236. _Myt& append(const _Elem *_Ptr, size_type _Count)
  237. { // append [_Ptr, _Ptr + _Count)
  238. if (_Inside(_Ptr))
  239. return (append(*this, _Ptr - _Myptr(), _Count)); // substring
  240. if (npos - _Mysize <= _Count)
  241. _String_base::_Xlen(); // result too long
  242. size_type _Num;
  243. if (0 < _Count && _Grow(_Num = _Mysize + _Count))
  244. { // make room and append new stuff
  245. _Traits::copy(_Myptr() + _Mysize, _Ptr, _Count);
  246. _Eos(_Num);
  247. }
  248. return (*this);
  249. }
  250. _Myt& append(const _Elem *_Ptr)
  251. { // append [_Ptr, <null>)
  252. return (append(_Ptr, _Traits::length(_Ptr)));
  253. }
  254. _Myt& append(size_type _Count, _Elem _Ch)
  255. { // append _Count * _Ch
  256. if (npos - _Mysize <= _Count)
  257. _String_base::_Xlen(); // result too long
  258. size_type _Num;
  259. if (0 < _Count && _Grow(_Num = _Mysize + _Count))
  260. { // make room and append new stuff using assign
  261. _Traits::assign(_Myptr() + _Mysize, _Count, _Ch);
  262. _Eos(_Num);
  263. }
  264. return (*this);
  265. }
  266. template<class _It>
  267. _Myt& append(_It _First, _It _Last)
  268. { // append [_First, _Last)
  269. return (_Append(_First, _Last, _Iter_cat(_First)));
  270. }
  271. template<class _It>
  272. _Myt& _Append(_It _Count, _It _Ch, _Int_iterator_tag)
  273. { // append _Count * _Ch
  274. return (append((size_type)_Count, (_Elem)_Ch));
  275. }
  276. template<class _It>
  277. _Myt& _Append(_It _First, _It _Last, input_iterator_tag)
  278. { // append [_First, _Last), input iterators
  279. return (replace(end(), end(), _First, _Last));
  280. }
  281. _Myt& append(const_pointer _First, const_pointer _Last)
  282. { // append [_First, _Last), const pointers
  283. return (replace(end(), end(), _First, _Last));
  284. }
  285. _Myt& append(const_iterator _First, const_iterator _Last)
  286. { // append [_First, _Last), const_iterators
  287. return (replace(end(), end(), _First, _Last));
  288. }
  289. _Myt& assign(const _Myt& _Right)
  290. { // assign _Right
  291. return (assign(_Right, 0, npos));
  292. }
  293. _Myt& assign(const _Myt& _Right, size_type _Roff, size_type _Count)
  294. { // assign _Right [_Roff, _Roff + _Count)
  295. if (_Right.size() < _Roff)
  296. _String_base::_Xran(); // _Roff off end
  297. size_type _Num = _Right.size() - _Roff;
  298. if (_Count < _Num)
  299. _Num = _Count; // trim _Num to size
  300. if (this == &_Right)
  301. erase((size_type)(_Roff + _Num)), erase(0, _Roff); // substring
  302. else if (_Grow(_Num, true))
  303. { // make room and assign new stuff
  304. _Traits::copy(_Myptr(), _Right._Myptr() + _Roff, _Num);
  305. _Eos(_Num);
  306. }
  307. return (*this);
  308. }
  309. _Myt& assign(const _Elem *_Ptr, size_type _Num)
  310. { // assign [_Ptr, _Ptr + _Num)
  311. if (_Inside(_Ptr))
  312. return (assign(*this, _Ptr - _Myptr(), _Num)); // substring
  313. if (_Grow(_Num, true))
  314. { // make room and assign new stuff
  315. _Traits::copy(_Myptr(), _Ptr, _Num);
  316. _Eos(_Num);
  317. }
  318. return (*this);
  319. }
  320. _Myt& assign(const _Elem *_Ptr)
  321. { // assign [_Ptr, <null>)
  322. return (assign(_Ptr, _Traits::length(_Ptr)));
  323. }
  324. _Myt& assign(size_type _Count, _Elem _Ch)
  325. { // assign _Count * _Ch
  326. if (_Count == npos)
  327. _String_base::_Xlen(); // result too long
  328. if (_Grow(_Count, true))
  329. { // make room and assign new stuff
  330. _Traits::assign(_Myptr(), _Count, _Ch);
  331. _Eos(_Count);
  332. }
  333. return (*this);
  334. }
  335. template<class _It>
  336. _Myt& assign(_It _First, _It _Last)
  337. { // assign [First, _Last)
  338. return (_Assign(_First, _Last, _Iter_cat(_First)));
  339. }
  340. template<class _It>
  341. _Myt& _Assign(_It _Count, _It _Ch, _Int_iterator_tag)
  342. { // assign _Count * _Ch
  343. return (assign((size_type)_Count, (_Elem)_Ch));
  344. }
  345. template<class _It>
  346. _Myt& _Assign(_It _First, _It _Last, input_iterator_tag)
  347. { // assign [First, _Last), input iterators
  348. return (replace(begin(), end(), _First, _Last));
  349. }
  350. _Myt& assign(const_pointer _First, const_pointer _Last)
  351. { // assign [First, _Last), const pointers
  352. return (replace(begin(), end(), _First, _Last));
  353. }
  354. _Myt& assign(const_iterator _First, const_iterator _Last)
  355. { // assign [First, _Last), const_iterators
  356. return (replace(begin(), end(), _First, _Last));
  357. }
  358. _Myt& insert(size_type _Off, const _Myt& _Right)
  359. { // insert _Right at _Off
  360. return (insert(_Off, _Right, 0, npos));
  361. }
  362. _Myt& insert(size_type _Off, const _Myt& _Right, size_type _Roff,
  363. size_type _Count)
  364. { // insert _Right [_Roff, _Roff + _Count) at _Off
  365. if (_Mysize < _Off || _Right.size() < _Roff)
  366. _String_base::_Xran(); // _Off or _Roff off end
  367. size_type _Num = _Right.size() - _Roff;
  368. if (_Num < _Count)
  369. _Count = _Num; // trim _Count to size
  370. if (npos - _Mysize <= _Count)
  371. _String_base::_Xlen(); // result too long
  372. if (0 < _Count && _Grow(_Num = _Mysize + _Count))
  373. { // make room and insert new stuff
  374. _Traits::move(_Myptr() + _Off + _Count,
  375. _Myptr() + _Off, _Mysize - _Off); // empty out hole
  376. if (this == &_Right)
  377. _Traits::move(_Myptr() + _Off,
  378. _Myptr() + (_Off < _Roff ? _Roff + _Count : _Roff),
  379. _Count); // substring
  380. else
  381. _Traits::copy(_Myptr() + _Off,
  382. _Right._Myptr() + _Roff, _Count); // fill hole
  383. _Eos(_Num);
  384. }
  385. return (*this);
  386. }
  387. _Myt& insert(size_type _Off, const _Elem *_Ptr, size_type _Count)
  388. { // insert [_Ptr, _Ptr + _Count) at _Off
  389. if (_Inside(_Ptr))
  390. return (insert(_Off, *this,
  391. _Ptr - _Myptr(), _Count)); // substring
  392. if (_Mysize < _Off)
  393. _String_base::_Xran(); // _Off off end
  394. if (npos - _Mysize <= _Count)
  395. _String_base::_Xlen(); // result too long
  396. size_type _Num;
  397. if (0 < _Count && _Grow(_Num = _Mysize + _Count))
  398. { // make room and insert new stuff
  399. _Traits::move(_Myptr() + _Off + _Count,
  400. _Myptr() + _Off, _Mysize - _Off); // empty out hole
  401. _Traits::copy(_Myptr() + _Off, _Ptr, _Count); // fill hole
  402. _Eos(_Num);
  403. }
  404. return (*this);
  405. }
  406. _Myt& insert(size_type _Off, const _Elem *_Ptr)
  407. { // insert [_Ptr, <null>) at _Off
  408. return (insert(_Off, _Ptr, _Traits::length(_Ptr)));
  409. }
  410. _Myt& insert(size_type _Off, size_type _Count, _Elem _Ch)
  411. { // insert _Count * _Ch at _Off
  412. if (_Mysize < _Off)
  413. _String_base::_Xran(); // _Off off end
  414. if (npos - _Mysize <= _Count)
  415. _String_base::_Xlen(); // result too long
  416. size_type _Num;
  417. if (0 < _Count && _Grow(_Num = _Mysize + _Count))
  418. { // make room and insert new stuff
  419. _Traits::move(_Myptr() + _Off + _Count,
  420. _Myptr() + _Off, _Mysize - _Off); // empty out hole
  421. _Traits::assign(_Myptr() + _Off, _Count, _Ch); // fill hole
  422. _Eos(_Num);
  423. }
  424. return (*this);
  425. }
  426. iterator insert(iterator _Where)
  427. { // insert <null> at _Where
  428. return (insert(_Where, _Elem()));
  429. }
  430. iterator insert(iterator _Where, _Elem _Ch)
  431. { // insert _Ch at _Where
  432. size_type _Off = _Pdif(_Where, begin());
  433. insert(_Off, 1, _Ch);
  434. return (begin() + _Off);
  435. }
  436. void insert(iterator _Where, size_type _Count, _Elem _Ch)
  437. { // insert _Count * _Elem at _Where
  438. size_type _Off = _Pdif(_Where, begin());
  439. insert(_Off, _Count, _Ch);
  440. }
  441. template<class _It>
  442. void insert(iterator _Where, _It _First, _It _Last)
  443. { // insert [_First, _Last) at _Where
  444. _Insert(_Where, _First, _Last, _Iter_cat(_First));
  445. }
  446. template<class _It>
  447. void _Insert(iterator _Where, _It _Count, _It _Ch,
  448. _Int_iterator_tag)
  449. { // insert _Count * _Ch at _Where
  450. insert(_Where, (size_type)_Count, (_Elem)_Ch);
  451. }
  452. template<class _It>
  453. void _Insert(iterator _Where, _It _First, _It _Last,
  454. input_iterator_tag)
  455. { // insert [_First, _Last) at _Where, input iterators
  456. replace(_Where, _Where, _First, _Last);
  457. }
  458. void insert(iterator _Where, const_pointer _First, const_pointer _Last)
  459. { // insert [_First, _Last) at _Where, const pointers
  460. replace(_Where, _Where, _First, _Last);
  461. }
  462. void insert(iterator _Where, const_iterator _First, const_iterator _Last)
  463. { // insert [_First, _Last) at _Where, const_iterators
  464. replace(_Where, _Where, _First, _Last);
  465. }
  466. _Myt& erase(size_type _Off = 0, size_type _Count = npos)
  467. { // erase elements [_Off, _Off + _Count)
  468. if (_Mysize < _Off)
  469. _String_base::_Xran(); // _Off off end
  470. if (_Mysize - _Off < _Count)
  471. _Count = _Mysize - _Off; // trim _Count
  472. if (0 < _Count)
  473. { // move elements down
  474. _Traits::move(_Myptr() + _Off, _Myptr() + _Off + _Count,
  475. _Mysize - _Off - _Count);
  476. size_type _Newsize = _Mysize - _Count;
  477. if (_Grow(_Newsize))
  478. _Eos(_Newsize);
  479. }
  480. return (*this);
  481. }
  482. iterator erase(iterator _Where)
  483. { // erase element at _Where
  484. size_type _Count = _Pdif(_Where, begin());
  485. erase(_Count, 1);
  486. return (iterator(_Myptr() + _Count));
  487. }
  488. iterator erase(iterator _First, iterator _Last)
  489. { // erase substring [_First, _Last)
  490. size_type _Count = _Pdif(_First, begin());
  491. erase(_Count, _Pdif(_Last, _First));
  492. return (iterator(_Myptr() + _Count));
  493. }
  494. void clear()
  495. { // erase all
  496. erase(begin(), end());
  497. }
  498. _Myt& replace(size_type _Off, size_type _N0, const _Myt& _Right)
  499. { // replace [_Off, _Off + _N0) with _Right
  500. return (replace(_Off, _N0, _Right, 0, npos));
  501. }
  502. _Myt& replace(size_type _Off, size_type _N0, const _Myt& _Right,
  503. size_type _Roff, size_type _Count)
  504. { // replace [_Off, _Off + _N0) with _Right [_Roff, _Roff + _Count)
  505. if (_Mysize < _Off || _Right.size() < _Roff)
  506. _String_base::_Xran(); // _Off or _Roff off end
  507. if (_Mysize - _Off < _N0)
  508. _N0 = _Mysize - _Off; // trim _N0 to size
  509. size_type _Num = _Right.size() - _Roff;
  510. if (_Num < _Count)
  511. _Count = _Num; // trim _Count to size
  512. if (npos - _Count <= _Mysize - _N0)
  513. _String_base::_Xlen(); // result too long
  514. size_type _Nm = _Mysize - _N0 - _Off; // length of preserved tail
  515. size_type _Newsize = _Mysize + _Count - _N0;
  516. if (_Mysize < _Newsize)
  517. _Grow(_Newsize);
  518. if (this != &_Right)
  519. { // no overlap, just move down and copy in new stuff
  520. _Traits::move(_Myptr() + _Off + _Count,
  521. _Myptr() + _Off + _N0, _Nm); // empty hole
  522. _Traits::copy(_Myptr() + _Off,
  523. _Right._Myptr() + _Roff, _Count); // fill hole
  524. }
  525. else if (_Count <= _N0)
  526. { // hole doesn't get larger, just copy in substring
  527. _Traits::move(_Myptr() + _Off,
  528. _Myptr() + _Roff, _Count); // fill hole
  529. _Traits::move(_Myptr() + _Off + _Count,
  530. _Myptr() + _Off + _N0, _Nm); // move tail down
  531. }
  532. else if (_Roff <= _Off)
  533. { // hole gets larger, substring begins before hole
  534. _Traits::move(_Myptr() + _Off + _Count,
  535. _Myptr() + _Off + _N0, _Nm); // move tail down
  536. _Traits::move(_Myptr() + _Off,
  537. _Myptr() + _Roff, _Count); // fill hole
  538. }
  539. else if (_Off + _N0 <= _Roff)
  540. { // hole gets larger, substring begins after hole
  541. _Traits::move(_Myptr() + _Off + _Count,
  542. _Myptr() + _Off + _N0, _Nm); // move tail down
  543. _Traits::move(_Myptr() + _Off,
  544. _Myptr() + (_Roff + _Count - _N0), _Count); // fill hole
  545. }
  546. else
  547. { // hole gets larger, substring begins in hole
  548. _Traits::move(_Myptr() + _Off,
  549. _Myptr() + _Roff, _N0); // fill old hole
  550. _Traits::move(_Myptr() + _Off + _Count,
  551. _Myptr() + _Off + _N0, _Nm); // move tail down
  552. _Traits::move(_Myptr() + _Off + _N0, _Myptr() + _Roff + _Count,
  553. _Count - _N0); // fill rest of new hole
  554. }
  555. if (_Mysize < _Newsize || _Grow(_Newsize))
  556. _Eos(_Newsize); // truncate if need be and terminate
  557. return (*this);
  558. }
  559. _Myt& replace(size_type _Off, size_type _N0, const _Elem *_Ptr,
  560. size_type _Count)
  561. { // replace [_Off, _Off + _N0) with [_Ptr, _Ptr + _Count)
  562. if (_Inside(_Ptr))
  563. return (replace(_Off, _N0, *this,
  564. _Ptr - _Myptr(), _Count)); // substring, replace carefully
  565. if (_Mysize < _Off)
  566. _String_base::_Xran(); // _Off off end
  567. if (_Mysize - _Off < _N0)
  568. _N0 = _Mysize - _Off; // trim _N0 to size
  569. if (npos - _Count <= _Mysize - _N0)
  570. _String_base::_Xlen(); // result too long
  571. size_type _Nm = _Mysize - _N0 - _Off;
  572. if (_Count < _N0)
  573. _Traits::move(_Myptr() + _Off + _Count,
  574. _Myptr() + _Off + _N0, _Nm); // smaller hole, move tail up
  575. size_type _Num;
  576. if ((0 < _Count || 0 < _N0) && _Grow(_Num = _Mysize + _Count - _N0))
  577. { // make room and rearrange
  578. if (_N0 < _Count)
  579. _Traits::move(_Myptr() + _Off + _Count,
  580. _Myptr() + _Off + _N0, _Nm); // move tail down
  581. _Traits::copy(_Myptr() + _Off, _Ptr, _Count); // fill hole
  582. _Eos(_Num);
  583. }
  584. return (*this);
  585. }
  586. _Myt& replace(size_type _Off, size_type _N0, const _Elem *_Ptr)
  587. { // replace [_Off, _Off + _N0) with [_Ptr, <null>)
  588. return (replace(_Off, _N0, _Ptr, _Traits::length(_Ptr)));
  589. }
  590. _Myt& replace(size_type _Off, size_type _N0,
  591. size_type _Count, _Elem _Ch)
  592. { // replace [_Off, _Off + _N0) with _Count * _Ch
  593. if (_Mysize < _Off)
  594. _String_base::_Xran(); // _Off off end
  595. if (_Mysize - _Off < _N0)
  596. _N0 = _Mysize - _Off; // trim _N0 to size
  597. if (npos - _Count <= _Mysize - _N0)
  598. _String_base::_Xlen(); // result too long
  599. size_type _Nm = _Mysize - _N0 - _Off;
  600. if (_Count < _N0)
  601. _Traits::move(_Myptr() + _Off + _Count,
  602. _Myptr() + _Off + _N0, _Nm); // smaller hole, move tail up
  603. size_type _Num;
  604. if ((0 < _Count || 0 < _N0) && _Grow(_Num = _Mysize + _Count - _N0))
  605. { // make room and rearrange
  606. if (_N0 < _Count)
  607. _Traits::move(_Myptr() + _Off + _Count,
  608. _Myptr() + _Off + _N0, _Nm); // move tail down
  609. _Traits::assign(_Myptr() + _Off, _Count, _Ch); // fill hole
  610. _Eos(_Num);
  611. }
  612. return (*this);
  613. }
  614. _Myt& replace(iterator _First, iterator _Last, const _Myt& _Right)
  615. { // replace [_First, _Last) with _Right
  616. return (replace(
  617. _Pdif(_First, begin()), _Pdif(_Last, _First), _Right));
  618. }
  619. _Myt& replace(iterator _First, iterator _Last, const _Elem *_Ptr,
  620. size_type _Count)
  621. { // replace [_First, _Last) with [_Ptr, _Ptr + _Count)
  622. return (replace(
  623. _Pdif(_First, begin()), _Pdif(_Last, _First), _Ptr, _Count));
  624. }
  625. _Myt& replace(iterator _First, iterator _Last, const _Elem *_Ptr)
  626. { // replace [_First, _Last) with [_Ptr, <null>)
  627. return (replace(
  628. _Pdif(_First, begin()), _Pdif(_Last, _First), _Ptr));
  629. }
  630. _Myt& replace(iterator _First, iterator _Last,
  631. size_type _Count, _Elem _Ch)
  632. { // replace [_First, _Last) with _Count * _Ch
  633. return (replace(
  634. _Pdif(_First, begin()), _Pdif(_Last, _First), _Count, _Ch));
  635. }
  636. template<class _It>
  637. _Myt& replace(iterator _First, iterator _Last,
  638. _It _First2, _It _Last2)
  639. { // replace [_First, _Last) with [_First2, _Last2)
  640. return (_Replace(_First, _Last,
  641. _First2, _Last2, _Iter_cat(_First2)));
  642. }
  643. template<class _It>
  644. _Myt& _Replace(iterator _First, iterator _Last,
  645. _It _Count, _It _Ch, _Int_iterator_tag)
  646. { // replace [_First, _Last) with _Count * _Ch
  647. return (replace(_First, _Last, (size_type)_Count, (_Elem)_Ch));
  648. }
  649. template<class _It>
  650. _Myt& _Replace(iterator _First, iterator _Last,
  651. _It _First2, _It _Last2, input_iterator_tag)
  652. { // replace [_First, _Last) with [_First2, _Last2), input iterators
  653. _Myt _Right(_First2, _Last2);
  654. replace(_First, _Last, _Right);
  655. return (*this);
  656. }
  657. _Myt& replace(iterator _First, iterator _Last,
  658. const_pointer _First2, const_pointer _Last2)
  659. { // replace [_First, _Last) with [_First2, _Last2), const pointers
  660. if (_First2 == _Last2)
  661. erase(_Pdif(_First, begin()), _Pdif(_Last, _First));
  662. else
  663. replace(_Pdif(_First, begin()), _Pdif(_Last, _First),
  664. &*_First2, _Last2 - _First2);
  665. return (*this);
  666. }
  667. _Myt& replace(iterator _First, iterator _Last,
  668. const_iterator _First2, const_iterator _Last2)
  669. { // replace [_First, _Last) with [_First2, _Last2), const_iterators
  670. if (_First2 == _Last2)
  671. erase(_Pdif(_First, begin()), _Pdif(_Last, _First));
  672. else
  673. replace(_Pdif(_First, begin()), _Pdif(_Last, _First),
  674. &*_First2, _Last2 - _First2);
  675. return (*this);
  676. }
  677. iterator begin()
  678. { // return iterator for beginning of mutable sequence
  679. return (iterator(_Myptr()));
  680. }
  681. const_iterator begin() const
  682. { // return iterator for beginning of nonmutable sequence
  683. return (const_iterator(_Myptr()));
  684. }
  685. iterator end()
  686. { // return iterator for end of mutable sequence
  687. return (iterator(_Myptr() + _Mysize));
  688. }
  689. const_iterator end() const
  690. { // return iterator for end of nonmutable sequence
  691. return (const_iterator(_Myptr() + _Mysize));
  692. }
  693. reverse_iterator rbegin()
  694. { // return iterator for beginning of reversed mutable sequence
  695. return (reverse_iterator(end()));
  696. }
  697. const_reverse_iterator rbegin() const
  698. { // return iterator for beginning of reversed nonmutable sequence
  699. return (const_reverse_iterator(end()));
  700. }
  701. reverse_iterator rend()
  702. { // return iterator for end of reversed mutable sequence
  703. return (reverse_iterator(begin()));
  704. }
  705. const_reverse_iterator rend() const
  706. { // return iterator for end of reversed nonmutable sequence
  707. return (const_reverse_iterator(begin()));
  708. }
  709. reference at(size_type _Off)
  710. { // subscript mutable sequence with checking
  711. if (_Mysize <= _Off)
  712. _String_base::_Xran(); // _Off off end
  713. return (_Myptr()[_Off]);
  714. }
  715. const_reference at(size_type _Off) const
  716. { // subscript nonmutable sequence with checking
  717. if (_Mysize <= _Off)
  718. _String_base::_Xran(); // _Off off end
  719. return (_Myptr()[_Off]);
  720. }
  721. reference operator[](size_type _Off)
  722. { // subscript mutable sequence
  723. return (_Myptr()[_Off]);
  724. }
  725. const_reference operator[](size_type _Off) const
  726. { // subscript nonmutable sequence
  727. return (_Myptr()[_Off]);
  728. }
  729. void push_back(_Elem _Ch)
  730. { // insert element at end
  731. insert(end(), _Ch);
  732. }
  733. const _Elem *c_str() const
  734. { // return pointer to null-terminated nonmutable array
  735. return (_Myptr());
  736. }
  737. const _Elem *data() const
  738. { // return pointer to nonmutable array
  739. return (c_str());
  740. }
  741. size_type length() const
  742. { // return length of sequence
  743. return (_Mysize);
  744. }
  745. size_type size() const
  746. { // return length of sequence
  747. return (_Mysize);
  748. }
  749. size_type max_size() const
  750. { // return maximum possible length of sequence
  751. size_type _Num = _Mybase::_Alval.max_size();
  752. return (_Num <= 1 ? 1 : _Num - 1);
  753. }
  754. void resize(size_type _Newsize)
  755. { // determine new length, padding with null elements as needed
  756. resize(_Newsize, _Elem());
  757. }
  758. void resize(size_type _Newsize, _Elem _Ch)
  759. { // determine new length, padding with _Ch elements as needed
  760. if (_Newsize <= _Mysize)
  761. erase(_Newsize);
  762. else
  763. append(_Newsize - _Mysize, _Ch);
  764. }
  765. size_type capacity() const
  766. { // return current length of allocated storage
  767. return (_Myres);
  768. }
  769. void reserve(size_type _Newcap = 0)
  770. { // determine new minimum length of allocated storage
  771. if (_Myres < _Newcap)
  772. _Grow(_Newcap);
  773. }
  774. bool empty() const
  775. { // test if sequence is empty
  776. return (_Mysize == 0);
  777. }
  778. size_type copy(_Elem *_Ptr, size_type _Count, size_type _Off = 0) const
  779. { // copy [_Off, _Off + _Count) to [_Ptr, _Ptr + _Count)
  780. if (_Mysize < _Off)
  781. _String_base::_Xran(); // _Off off end
  782. if (_Mysize - _Off < _Count)
  783. _Count = _Mysize - _Off;
  784. _Traits::copy(_Ptr, _Myptr() + _Off, _Count);
  785. return (_Count);
  786. }
  787. void swap(_Myt& _Right)
  788. { // exchange contents with _Right
  789. if (_Mybase::_Alval == _Right._Alval)
  790. { // same allocator, swap control information
  791. _Bxty _Tbx = _Bx;
  792. _Bx = _Right._Bx, _Right._Bx = _Tbx;
  793. size_type _Tlen = _Mysize;
  794. _Mysize = _Right._Mysize, _Right._Mysize = _Tlen;
  795. size_type _Tres = _Myres;
  796. _Myres = _Right._Myres, _Right._Myres = _Tres;
  797. }
  798. else
  799. { // different allocator, do multiple assigns
  800. _Myt _Tmp = *this; *this = _Right, _Right = _Tmp;
  801. }
  802. }
  803. friend void swap(_Myt& _Left, _Myt& _Right)
  804. { // swap _Left and _Right strings
  805. _Left.swap(_Right);
  806. }
  807. size_type find(const _Myt& _Right, size_type _Off = 0) const
  808. { // look for _Right beginnng at or after _Off
  809. return (find(_Right._Myptr(), _Off, _Right.size()));
  810. }
  811. size_type find(const _Elem *_Ptr, size_type _Off,
  812. size_type _Count) const
  813. { // look for [_Ptr, _Ptr + _Count) beginnng at or after _Off
  814. if (_Count == 0 && _Off <= _Mysize)
  815. return (_Off); // null string always matches (if inside string)
  816. size_type _Nm;
  817. if (_Off < _Mysize && _Count <= (_Nm = _Mysize - _Off))
  818. { // room for match, look for it
  819. const _Elem *_Uptr, *_Vptr;
  820. for (_Nm -= _Count - 1, _Vptr = _Myptr() + _Off;
  821. (_Uptr = _Traits::find(_Vptr, _Nm, *_Ptr)) != 0;
  822. _Nm -= _Uptr - _Vptr + 1, _Vptr = _Uptr + 1)
  823. if (_Traits::compare(_Uptr, _Ptr, _Count) == 0)
  824. return (_Uptr - _Myptr()); // found a match
  825. }
  826. return (npos); // no match
  827. }
  828. size_type find(const _Elem *_Ptr, size_type _Off = 0) const
  829. { // look for [_Ptr, <null>) beginnng at or after _Off
  830. return (find(_Ptr, _Off, _Traits::length(_Ptr)));
  831. }
  832. size_type find(_Elem _Ch, size_type _Off = 0) const
  833. { // look for _Ch at or after _Off
  834. return (find((const _Elem *)&_Ch, _Off, 1));
  835. }
  836. size_type rfind(const _Myt& _Right, size_type _Off = npos) const
  837. { // look for _Right beginning before _Off
  838. return (rfind(_Right._Myptr(), _Off, _Right.size()));
  839. }
  840. size_type rfind(const _Elem *_Ptr, size_type _Off,
  841. size_type _Count) const
  842. { // look for [_Ptr, _Ptr + _Count) beginning before _Off
  843. if (_Count == 0)
  844. return (_Off < _Mysize ? _Off : _Mysize); // null always matches
  845. if (_Count <= _Mysize)
  846. { // room for match, look for it
  847. const _Elem *_Uptr = _Myptr() +
  848. (_Off < _Mysize - _Count ? _Off : _Mysize - _Count);
  849. for (; ; --_Uptr)
  850. if (_Traits::eq(*_Uptr, *_Ptr)
  851. && _Traits::compare(_Uptr, _Ptr, _Count) == 0)
  852. return (_Uptr - _Myptr()); // found a match
  853. else if (_Uptr == _Myptr())
  854. break; // at beginning, no more chance for match
  855. }
  856. return (npos); // no match
  857. }
  858. size_type rfind(const _Elem *_Ptr, size_type _Off = npos) const
  859. { // look for [_Ptr, <null>) beginning before _Off
  860. return (rfind(_Ptr, _Off, _Traits::length(_Ptr)));
  861. }
  862. size_type rfind(_Elem _Ch, size_type _Off = npos) const
  863. { // look for _Ch before _Off
  864. return (rfind((const _Elem *)&_Ch, _Off, 1));
  865. }
  866. size_type find_first_of(const _Myt& _Right,
  867. size_type _Off = 0) const
  868. { // look for one of _Right at or after _Off
  869. return (find_first_of(_Right._Myptr(), _Off, _Right.size()));
  870. }
  871. size_type find_first_of(const _Elem *_Ptr, size_type _Off,
  872. size_type _Count) const
  873. { // look for one of [_Ptr, _Ptr + _Count) at or after _Off
  874. if (0 < _Count && _Off < _Mysize)
  875. { // room for match, look for it
  876. const _Elem *const _Vptr = _Myptr() + _Mysize;
  877. for (const _Elem *_Uptr = _Myptr() + _Off; _Uptr < _Vptr; ++_Uptr)
  878. if (_Traits::find(_Ptr, _Count, *_Uptr) != 0)
  879. return (_Uptr - _Myptr()); // found a match
  880. }
  881. return (npos); // no match
  882. }
  883. size_type find_first_of(const _Elem *_Ptr, size_type _Off = 0) const
  884. { // look for one of [_Ptr, <null>) at or after _Off
  885. return (find_first_of(_Ptr, _Off, _Traits::length(_Ptr)));
  886. }
  887. size_type find_first_of(_Elem _Ch, size_type _Off = 0) const
  888. { // look for _Ch at or after _Off
  889. return (find((const _Elem *)&_Ch, _Off, 1));
  890. }
  891. size_type find_last_of(const _Myt& _Right,
  892. size_type _Off = npos) const
  893. { // look for one of _Right before _Off
  894. return (find_last_of(_Right._Myptr(), _Off, _Right.size()));
  895. }
  896. size_type find_last_of(const _Elem *_Ptr, size_type _Off,
  897. size_type _Count) const
  898. { // look for one of [_Ptr, _Ptr + _Count) before _Off
  899. if (0 < _Count && 0 < _Mysize)
  900. for (const _Elem *_Uptr = _Myptr()
  901. + (_Off < _Mysize ? _Off : _Mysize - 1); ; --_Uptr)
  902. if (_Traits::find(_Ptr, _Count, *_Uptr) != 0)
  903. return (_Uptr - _Myptr()); // found a match
  904. else if (_Uptr == _Myptr())
  905. break; // at beginning, no more chance for match
  906. return (npos); // no match
  907. }
  908. size_type find_last_of(const _Elem *_Ptr,
  909. size_type _Off = npos) const
  910. { // look for one of [_Ptr, <null>) before _Off
  911. return (find_last_of(_Ptr, _Off, _Traits::length(_Ptr)));
  912. }
  913. size_type find_last_of(_Elem _Ch, size_type _Off = npos) const
  914. { // look for _Ch before _Off
  915. return (rfind((const _Elem *)&_Ch, _Off, 1));
  916. }
  917. size_type find_first_not_of(const _Myt& _Right,
  918. size_type _Off = 0) const
  919. { // look for none of _Right at or after _Off
  920. return (find_first_not_of(_Right._Myptr(), _Off,
  921. _Right.size()));
  922. }
  923. size_type find_first_not_of(const _Elem *_Ptr, size_type _Off,
  924. size_type _Count) const
  925. { // look for none of [_Ptr, _Ptr + _Count) at or after _Off
  926. if (_Off < _Mysize)
  927. { // room for match, look for it
  928. const _Elem *const _Vptr = _Myptr() + _Mysize;
  929. for (const _Elem *_Uptr = _Myptr() + _Off; _Uptr < _Vptr; ++_Uptr)
  930. if (_Traits::find(_Ptr, _Count, *_Uptr) == 0)
  931. return (_Uptr - _Myptr());
  932. }
  933. return (npos);
  934. }
  935. size_type find_first_not_of(const _Elem *_Ptr,
  936. size_type _Off = 0) const
  937. { // look for one of [_Ptr, <null>) at or after _Off
  938. return (find_first_not_of(_Ptr, _Off, _Traits::length(_Ptr)));
  939. }
  940. size_type find_first_not_of(_Elem _Ch, size_type _Off = 0) const
  941. { // look for non _Ch at or after _Off
  942. return (find_first_not_of((const _Elem *)&_Ch, _Off, 1));
  943. }
  944. size_type find_last_not_of(const _Myt& _Right,
  945. size_type _Off = npos) const
  946. { // look for none of _Right before _Off
  947. return (find_last_not_of(_Right._Myptr(), _Off, _Right.size()));
  948. }
  949. size_type find_last_not_of(const _Elem *_Ptr, size_type _Off,
  950. size_type _Count) const
  951. { // look for none of [_Ptr, _Ptr + _Count) before _Off
  952. if (0 < _Mysize)
  953. for (const _Elem *_Uptr = _Myptr()
  954. + (_Off < _Mysize ? _Off : _Mysize - 1); ; --_Uptr)
  955. if (_Traits::find(_Ptr, _Count, *_Uptr) == 0)
  956. return (_Uptr - _Myptr());
  957. else if (_Uptr == _Myptr())
  958. break;
  959. return (npos);
  960. }
  961. size_type find_last_not_of(const _Elem *_Ptr,
  962. size_type _Off = npos) const
  963. { // look for none of [_Ptr, <null>) before _Off
  964. return (find_last_not_of(_Ptr, _Off, _Traits::length(_Ptr)));
  965. }
  966. size_type find_last_not_of(_Elem _Ch, size_type _Off = npos) const
  967. { // look for non _Ch before _Off
  968. return (find_last_not_of((const _Elem *)&_Ch, _Off, 1));
  969. }
  970. _Myt substr(size_type _Off = 0, size_type _Count = npos) const
  971. { // return [_Off, _Off + _Count) as new string
  972. return (_Myt(*this, _Off, _Count));
  973. }
  974. int compare(const _Myt& _Right) const
  975. { // compare [0, _Mysize) with _Right
  976. return (compare(0, _Mysize, _Right._Myptr(), _Right.size()));
  977. }
  978. int compare(size_type _Off, size_type _N0,
  979. const _Myt& _Right) const
  980. { // compare [_Off, _Off + _N0) with _Right
  981. return (compare(_Off, _N0, _Right, 0, npos));
  982. }
  983. int compare(size_type _Off, size_type _N0, const _Myt& _Right,
  984. size_type _Roff, size_type _Count) const
  985. { // compare [_Off, _Off + _N0) with _Right [_Roff, _Roff + _Count)
  986. if (_Right.size() < _Roff)
  987. _String_base::_Xran(); // _Off off end
  988. if (_Right._Mysize - _Roff < _Count)
  989. _Count = _Right._Mysize - _Roff; // trim _Count to size
  990. return (compare(_Off, _N0, _Right._Myptr() + _Roff, _Count));
  991. }
  992. int compare(const _Elem *_Ptr) const
  993. { // compare [0, _Mysize) with [_Ptr, <null>)
  994. return (compare(0, _Mysize, _Ptr, _Traits::length(_Ptr)));
  995. }
  996. int compare(size_type _Off, size_type _N0, const _Elem *_Ptr) const
  997. { // compare [_Off, _Off + _N0) with [_Ptr, <null>)
  998. return (compare(_Off, _N0, _Ptr, _Traits::length(_Ptr)));
  999. }
  1000. int compare(size_type _Off, size_type _N0, const _Elem *_Ptr,
  1001. size_type _Count) const
  1002. { // compare [_Off, _Off + _N0) with [_Ptr, _Ptr + _Count)
  1003. if (_Mysize < _Off)
  1004. _String_base::_Xran(); // _Off off end
  1005. if (_Mysize - _Off < _N0)
  1006. _N0 = _Mysize - _Off; // trim _N0 to size
  1007. size_type _Ans = _N0 == 0 ? 0
  1008. : _Traits::compare(_Myptr() + _Off, _Ptr,
  1009. _N0 < _Count ? _N0 : _Count);
  1010. return (_Ans != 0 ? (int)_Ans : _N0 < _Count ? -1
  1011. : _N0 == _Count ? 0 : +1);
  1012. }
  1013. allocator_type get_allocator() const
  1014. { // return allocator object for values
  1015. return (_Mybase::_Alval);
  1016. }
  1017. enum
  1018. { // length of internal buffer, [1, 16]
  1019. _BUF_SIZE = 16 / sizeof (_Elem) < 1 ? 1
  1020. : 16 / sizeof(_Elem)};
  1021. private:
  1022. enum
  1023. { // roundup mask for allocated buffers, [0, 15]
  1024. _ALLOC_MASK = sizeof (_Elem) <= 1 ? 15
  1025. : sizeof (_Elem) <= 2 ? 7
  1026. : sizeof (_Elem) <= 4 ? 3
  1027. : sizeof (_Elem) <= 8 ? 1 : 0};
  1028. void _Copy(size_type _Newsize, size_type _Oldlen)
  1029. { // copy _Oldlen elements to newly allocated buffer
  1030. size_type _Newres = _Newsize | _ALLOC_MASK;
  1031. if (max_size() < _Newres)
  1032. _Newres = _Newsize; // undo roundup if too big
  1033. _Elem *_Ptr;
  1034. _TRY_BEGIN
  1035. _Ptr = _Mybase::_Alval.allocate(_Newres + 1, (void *)0);
  1036. _CATCH_ALL
  1037. _Newres = _Newsize; // allocation failed, undo roundup and retry
  1038. _TRY_BEGIN
  1039. _Ptr = _Mybase::_Alval.allocate(_Newres + 1, (void *)0);
  1040. _CATCH_ALL
  1041. _Tidy(true); // failed again, discard storage and reraise
  1042. _RERAISE;
  1043. _CATCH_END
  1044. _CATCH_END
  1045. if (0 < _Oldlen)
  1046. _Traits::copy(_Ptr, _Myptr(), _Oldlen); // copy existing elements
  1047. _Tidy(true);
  1048. _Bx._Ptr = _Ptr;
  1049. _Myres = _Newres;
  1050. _Eos(_Oldlen);
  1051. }
  1052. void _Eos(size_type _Newsize)
  1053. { // set new length and null terminator
  1054. _Traits::assign(_Myptr()[_Mysize = _Newsize], _Elem());
  1055. }
  1056. bool _Grow(size_type _Newsize, bool _Trim = false)
  1057. { // ensure buffer is big enough, trim to size if _Trim is true
  1058. if (max_size() < _Newsize)
  1059. _String_base::_Xlen(); // result too long
  1060. if (_Myres < _Newsize)
  1061. _Copy(_Newsize, _Trim ? 0 : _Mysize); // reallocate to grow
  1062. else if (_Trim && _Newsize < _BUF_SIZE)
  1063. _Tidy(true); // deallocate if assigning small string
  1064. else if (_Newsize == 0)
  1065. _Eos(0); // new size is zero, just null terminate
  1066. return (0 < _Newsize); // return true only if more work to do
  1067. }
  1068. bool _Inside(const _Elem *_Ptr)
  1069. { // test if _Ptr points inside string
  1070. return (_Myptr() <= _Ptr && _Ptr < _Myptr() + _Mysize);
  1071. }
  1072. static size_type __cdecl _Pdif(const_iterator _P2,
  1073. const_iterator _P1)
  1074. { // compute safe iterator difference
  1075. return (_P2.base() == 0 ? 0 : _P2 - _P1);
  1076. }
  1077. _Elem *_Myptr()
  1078. { // determine current pointer to buffer for mutable string
  1079. return (_BUF_SIZE <= _Myres ? _Bx._Ptr : _Bx._Buf);
  1080. }
  1081. const _Elem *_Myptr() const
  1082. { // determine current pointer to buffer for nonmutable string
  1083. return (_BUF_SIZE <= _Myres ? _Bx._Ptr : _Bx._Buf);
  1084. }
  1085. void _Tidy(bool _Built = false)
  1086. { // initialize buffer, deallocating any storage
  1087. if (!_Built)
  1088. ;
  1089. else if (_BUF_SIZE <= _Myres)
  1090. _Mybase::_Alval.deallocate(_Myptr(), _Myres + 1);
  1091. _Myres = _BUF_SIZE - 1;
  1092. _Eos(0);
  1093. }
  1094. union _Bxty
  1095. { // storage for small buffer or pointer to larger one
  1096. _Elem _Buf[_BUF_SIZE];
  1097. _Elem *_Ptr;
  1098. } _Bx;
  1099. size_type _Mysize; // current length of string
  1100. size_type _Myres; // current storage reserved for string
  1101. };
  1102. // STATIC npos OBJECT
  1103. template<class _Elem,
  1104. class _Traits,
  1105. class _Alloc>
  1106. const /* typename */ basic_string<_Elem, _Traits, _Alloc>::size_type
  1107. basic_string<_Elem, _Traits, _Alloc>::npos =
  1108. (basic_string<_Elem, _Traits, _Alloc>::size_type)(-1);
  1109. typedef basic_string<char, char_traits<char>, allocator<char> >
  1110. string;
  1111. typedef basic_string<wchar_t, char_traits<wchar_t>,
  1112. allocator<wchar_t> > wstring;
  1113. #ifdef _DLL_CPPLIB
  1114. #ifdef __FORCE_INSTANCE
  1115. #if _RETAIN_OLD_CRT_CODE
  1116. template class _CRTIMP2 allocator<char>;
  1117. template class _CRTIMP2 allocator<wchar_t>;
  1118. #ifdef _CRTBLD_NATIVE_WCHAR_T
  1119. template class _CRTIMP2 allocator<unsigned short>;
  1120. #endif
  1121. #endif // _RETAIN_OLD_CRT_CODE
  1122. template class _CRTIMP2 basic_string<char, char_traits<char>,
  1123. allocator<char> >;
  1124. template class _CRTIMP2 basic_string<wchar_t, char_traits<wchar_t>,
  1125. allocator<wchar_t> >;
  1126. #ifdef _CRTBLD_NATIVE_WCHAR_T
  1127. template class _CRTIMP2 basic_string<unsigned short, char_traits<unsigned short>,
  1128. allocator<unsigned short> >;
  1129. #endif
  1130. #else // __FORCE_INSTANCE
  1131. template class _CRTIMP2 basic_string<char, char_traits<char>,
  1132. allocator<char> >;
  1133. #endif // __FORCE_INSTANCE
  1134. #endif // _DLL_CPPLIB
  1135. _STD_END
  1136. #pragma warning(default: 4251)
  1137. #pragma warning(pop)
  1138. #pragma pack(pop)
  1139. #endif /* _XSTRING */
  1140. /*
  1141. * Copyright (c) 1992-2001 by P.J. Plauger. ALL RIGHTS RESERVED.
  1142. * Consult your license regarding permissions and restrictions.
  1143. V3.10:0009 */