vstring.tcc 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697
  1. // Versatile string -*- C++ -*-
  2. // Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file ext/vstring.tcc
  21. * This file is a GNU extension to the Standard C++ Library.
  22. * This is an internal header file, included by other library headers.
  23. * You should not attempt to use it directly.
  24. */
  25. #ifndef _VSTRING_TCC
  26. #define _VSTRING_TCC 1
  27. #pragma GCC system_header
  28. #include <cxxabi-forced.h>
  29. _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
  30. template<typename _CharT, typename _Traits, typename _Alloc,
  31. template <typename, typename, typename> class _Base>
  32. const typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
  33. __versa_string<_CharT, _Traits, _Alloc, _Base>::npos;
  34. template<typename _CharT, typename _Traits, typename _Alloc,
  35. template <typename, typename, typename> class _Base>
  36. void
  37. __versa_string<_CharT, _Traits, _Alloc, _Base>::
  38. resize(size_type __n, _CharT __c)
  39. {
  40. const size_type __size = this->size();
  41. if (__size < __n)
  42. this->append(__n - __size, __c);
  43. else if (__n < __size)
  44. this->_M_erase(__n, __size - __n);
  45. }
  46. template<typename _CharT, typename _Traits, typename _Alloc,
  47. template <typename, typename, typename> class _Base>
  48. __versa_string<_CharT, _Traits, _Alloc, _Base>&
  49. __versa_string<_CharT, _Traits, _Alloc, _Base>::
  50. _M_append(const _CharT* __s, size_type __n)
  51. {
  52. const size_type __len = __n + this->size();
  53. if (__len <= this->capacity() && !this->_M_is_shared())
  54. {
  55. if (__n)
  56. this->_S_copy(this->_M_data() + this->size(), __s, __n);
  57. }
  58. else
  59. this->_M_mutate(this->size(), size_type(0), __s, __n);
  60. this->_M_set_length(__len);
  61. return *this;
  62. }
  63. template<typename _CharT, typename _Traits, typename _Alloc,
  64. template <typename, typename, typename> class _Base>
  65. template<typename _InputIterator>
  66. __versa_string<_CharT, _Traits, _Alloc, _Base>&
  67. __versa_string<_CharT, _Traits, _Alloc, _Base>::
  68. _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1,
  69. _InputIterator __k2, std::__false_type)
  70. {
  71. const __versa_string __s(__k1, __k2);
  72. const size_type __n1 = __i2 - __i1;
  73. return _M_replace(__i1 - _M_ibegin(), __n1, __s._M_data(),
  74. __s.size());
  75. }
  76. template<typename _CharT, typename _Traits, typename _Alloc,
  77. template <typename, typename, typename> class _Base>
  78. __versa_string<_CharT, _Traits, _Alloc, _Base>&
  79. __versa_string<_CharT, _Traits, _Alloc, _Base>::
  80. _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
  81. _CharT __c)
  82. {
  83. _M_check_length(__n1, __n2, "__versa_string::_M_replace_aux");
  84. const size_type __old_size = this->size();
  85. const size_type __new_size = __old_size + __n2 - __n1;
  86. if (__new_size <= this->capacity() && !this->_M_is_shared())
  87. {
  88. _CharT* __p = this->_M_data() + __pos1;
  89. const size_type __how_much = __old_size - __pos1 - __n1;
  90. if (__how_much && __n1 != __n2)
  91. this->_S_move(__p + __n2, __p + __n1, __how_much);
  92. }
  93. else
  94. this->_M_mutate(__pos1, __n1, 0, __n2);
  95. if (__n2)
  96. this->_S_assign(this->_M_data() + __pos1, __n2, __c);
  97. this->_M_set_length(__new_size);
  98. return *this;
  99. }
  100. template<typename _CharT, typename _Traits, typename _Alloc,
  101. template <typename, typename, typename> class _Base>
  102. __versa_string<_CharT, _Traits, _Alloc, _Base>&
  103. __versa_string<_CharT, _Traits, _Alloc, _Base>::
  104. _M_replace(size_type __pos, size_type __len1, const _CharT* __s,
  105. const size_type __len2)
  106. {
  107. _M_check_length(__len1, __len2, "__versa_string::_M_replace");
  108. const size_type __old_size = this->size();
  109. const size_type __new_size = __old_size + __len2 - __len1;
  110. if (__new_size <= this->capacity() && !this->_M_is_shared())
  111. {
  112. _CharT* __p = this->_M_data() + __pos;
  113. const size_type __how_much = __old_size - __pos - __len1;
  114. if (_M_disjunct(__s))
  115. {
  116. if (__how_much && __len1 != __len2)
  117. this->_S_move(__p + __len2, __p + __len1, __how_much);
  118. if (__len2)
  119. this->_S_copy(__p, __s, __len2);
  120. }
  121. else
  122. {
  123. // Work in-place.
  124. if (__len2 && __len2 <= __len1)
  125. this->_S_move(__p, __s, __len2);
  126. if (__how_much && __len1 != __len2)
  127. this->_S_move(__p + __len2, __p + __len1, __how_much);
  128. if (__len2 > __len1)
  129. {
  130. if (__s + __len2 <= __p + __len1)
  131. this->_S_move(__p, __s, __len2);
  132. else if (__s >= __p + __len1)
  133. this->_S_copy(__p, __s + __len2 - __len1, __len2);
  134. else
  135. {
  136. const size_type __nleft = (__p + __len1) - __s;
  137. this->_S_move(__p, __s, __nleft);
  138. this->_S_copy(__p + __nleft, __p + __len2,
  139. __len2 - __nleft);
  140. }
  141. }
  142. }
  143. }
  144. else
  145. this->_M_mutate(__pos, __len1, __s, __len2);
  146. this->_M_set_length(__new_size);
  147. return *this;
  148. }
  149. template<typename _CharT, typename _Traits, typename _Alloc,
  150. template <typename, typename, typename> class _Base>
  151. __versa_string<_CharT, _Traits, _Alloc, _Base>
  152. operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
  153. const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
  154. {
  155. __versa_string<_CharT, _Traits, _Alloc, _Base> __str;
  156. __str.reserve(__lhs.size() + __rhs.size());
  157. __str.append(__lhs);
  158. __str.append(__rhs);
  159. return __str;
  160. }
  161. template<typename _CharT, typename _Traits, typename _Alloc,
  162. template <typename, typename, typename> class _Base>
  163. __versa_string<_CharT, _Traits, _Alloc, _Base>
  164. operator+(const _CharT* __lhs,
  165. const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
  166. {
  167. __glibcxx_requires_string(__lhs);
  168. typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type;
  169. typedef typename __string_type::size_type __size_type;
  170. const __size_type __len = _Traits::length(__lhs);
  171. __string_type __str;
  172. __str.reserve(__len + __rhs.size());
  173. __str.append(__lhs, __len);
  174. __str.append(__rhs);
  175. return __str;
  176. }
  177. template<typename _CharT, typename _Traits, typename _Alloc,
  178. template <typename, typename, typename> class _Base>
  179. __versa_string<_CharT, _Traits, _Alloc, _Base>
  180. operator+(_CharT __lhs,
  181. const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
  182. {
  183. __versa_string<_CharT, _Traits, _Alloc, _Base> __str;
  184. __str.reserve(__rhs.size() + 1);
  185. __str.push_back(__lhs);
  186. __str.append(__rhs);
  187. return __str;
  188. }
  189. template<typename _CharT, typename _Traits, typename _Alloc,
  190. template <typename, typename, typename> class _Base>
  191. __versa_string<_CharT, _Traits, _Alloc, _Base>
  192. operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
  193. const _CharT* __rhs)
  194. {
  195. __glibcxx_requires_string(__rhs);
  196. typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type;
  197. typedef typename __string_type::size_type __size_type;
  198. const __size_type __len = _Traits::length(__rhs);
  199. __string_type __str;
  200. __str.reserve(__lhs.size() + __len);
  201. __str.append(__lhs);
  202. __str.append(__rhs, __len);
  203. return __str;
  204. }
  205. template<typename _CharT, typename _Traits, typename _Alloc,
  206. template <typename, typename, typename> class _Base>
  207. __versa_string<_CharT, _Traits, _Alloc, _Base>
  208. operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
  209. _CharT __rhs)
  210. {
  211. __versa_string<_CharT, _Traits, _Alloc, _Base> __str;
  212. __str.reserve(__lhs.size() + 1);
  213. __str.append(__lhs);
  214. __str.push_back(__rhs);
  215. return __str;
  216. }
  217. template<typename _CharT, typename _Traits, typename _Alloc,
  218. template <typename, typename, typename> class _Base>
  219. typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
  220. __versa_string<_CharT, _Traits, _Alloc, _Base>::
  221. copy(_CharT* __s, size_type __n, size_type __pos) const
  222. {
  223. _M_check(__pos, "__versa_string::copy");
  224. __n = _M_limit(__pos, __n);
  225. __glibcxx_requires_string_len(__s, __n);
  226. if (__n)
  227. this->_S_copy(__s, this->_M_data() + __pos, __n);
  228. // 21.3.5.7 par 3: do not append null. (good.)
  229. return __n;
  230. }
  231. template<typename _CharT, typename _Traits, typename _Alloc,
  232. template <typename, typename, typename> class _Base>
  233. typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
  234. __versa_string<_CharT, _Traits, _Alloc, _Base>::
  235. find(const _CharT* __s, size_type __pos, size_type __n) const
  236. {
  237. __glibcxx_requires_string_len(__s, __n);
  238. const size_type __size = this->size();
  239. const _CharT* __data = this->_M_data();
  240. if (__n == 0)
  241. return __pos <= __size ? __pos : npos;
  242. if (__n <= __size)
  243. {
  244. for (; __pos <= __size - __n; ++__pos)
  245. if (traits_type::eq(__data[__pos], __s[0])
  246. && traits_type::compare(__data + __pos + 1,
  247. __s + 1, __n - 1) == 0)
  248. return __pos;
  249. }
  250. return npos;
  251. }
  252. template<typename _CharT, typename _Traits, typename _Alloc,
  253. template <typename, typename, typename> class _Base>
  254. typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
  255. __versa_string<_CharT, _Traits, _Alloc, _Base>::
  256. find(_CharT __c, size_type __pos) const
  257. {
  258. size_type __ret = npos;
  259. const size_type __size = this->size();
  260. if (__pos < __size)
  261. {
  262. const _CharT* __data = this->_M_data();
  263. const size_type __n = __size - __pos;
  264. const _CharT* __p = traits_type::find(__data + __pos, __n, __c);
  265. if (__p)
  266. __ret = __p - __data;
  267. }
  268. return __ret;
  269. }
  270. template<typename _CharT, typename _Traits, typename _Alloc,
  271. template <typename, typename, typename> class _Base>
  272. typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
  273. __versa_string<_CharT, _Traits, _Alloc, _Base>::
  274. rfind(const _CharT* __s, size_type __pos, size_type __n) const
  275. {
  276. __glibcxx_requires_string_len(__s, __n);
  277. const size_type __size = this->size();
  278. if (__n <= __size)
  279. {
  280. __pos = std::min(size_type(__size - __n), __pos);
  281. const _CharT* __data = this->_M_data();
  282. do
  283. {
  284. if (traits_type::compare(__data + __pos, __s, __n) == 0)
  285. return __pos;
  286. }
  287. while (__pos-- > 0);
  288. }
  289. return npos;
  290. }
  291. template<typename _CharT, typename _Traits, typename _Alloc,
  292. template <typename, typename, typename> class _Base>
  293. typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
  294. __versa_string<_CharT, _Traits, _Alloc, _Base>::
  295. rfind(_CharT __c, size_type __pos) const
  296. {
  297. size_type __size = this->size();
  298. if (__size)
  299. {
  300. if (--__size > __pos)
  301. __size = __pos;
  302. for (++__size; __size-- > 0; )
  303. if (traits_type::eq(this->_M_data()[__size], __c))
  304. return __size;
  305. }
  306. return npos;
  307. }
  308. template<typename _CharT, typename _Traits, typename _Alloc,
  309. template <typename, typename, typename> class _Base>
  310. typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
  311. __versa_string<_CharT, _Traits, _Alloc, _Base>::
  312. find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
  313. {
  314. __glibcxx_requires_string_len(__s, __n);
  315. for (; __n && __pos < this->size(); ++__pos)
  316. {
  317. const _CharT* __p = traits_type::find(__s, __n,
  318. this->_M_data()[__pos]);
  319. if (__p)
  320. return __pos;
  321. }
  322. return npos;
  323. }
  324. template<typename _CharT, typename _Traits, typename _Alloc,
  325. template <typename, typename, typename> class _Base>
  326. typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
  327. __versa_string<_CharT, _Traits, _Alloc, _Base>::
  328. find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
  329. {
  330. __glibcxx_requires_string_len(__s, __n);
  331. size_type __size = this->size();
  332. if (__size && __n)
  333. {
  334. if (--__size > __pos)
  335. __size = __pos;
  336. do
  337. {
  338. if (traits_type::find(__s, __n, this->_M_data()[__size]))
  339. return __size;
  340. }
  341. while (__size-- != 0);
  342. }
  343. return npos;
  344. }
  345. template<typename _CharT, typename _Traits, typename _Alloc,
  346. template <typename, typename, typename> class _Base>
  347. typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
  348. __versa_string<_CharT, _Traits, _Alloc, _Base>::
  349. find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
  350. {
  351. __glibcxx_requires_string_len(__s, __n);
  352. for (; __pos < this->size(); ++__pos)
  353. if (!traits_type::find(__s, __n, this->_M_data()[__pos]))
  354. return __pos;
  355. return npos;
  356. }
  357. template<typename _CharT, typename _Traits, typename _Alloc,
  358. template <typename, typename, typename> class _Base>
  359. typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
  360. __versa_string<_CharT, _Traits, _Alloc, _Base>::
  361. find_first_not_of(_CharT __c, size_type __pos) const
  362. {
  363. for (; __pos < this->size(); ++__pos)
  364. if (!traits_type::eq(this->_M_data()[__pos], __c))
  365. return __pos;
  366. return npos;
  367. }
  368. template<typename _CharT, typename _Traits, typename _Alloc,
  369. template <typename, typename, typename> class _Base>
  370. typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
  371. __versa_string<_CharT, _Traits, _Alloc, _Base>::
  372. find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
  373. {
  374. __glibcxx_requires_string_len(__s, __n);
  375. size_type __size = this->size();
  376. if (__size)
  377. {
  378. if (--__size > __pos)
  379. __size = __pos;
  380. do
  381. {
  382. if (!traits_type::find(__s, __n, this->_M_data()[__size]))
  383. return __size;
  384. }
  385. while (__size--);
  386. }
  387. return npos;
  388. }
  389. template<typename _CharT, typename _Traits, typename _Alloc,
  390. template <typename, typename, typename> class _Base>
  391. typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
  392. __versa_string<_CharT, _Traits, _Alloc, _Base>::
  393. find_last_not_of(_CharT __c, size_type __pos) const
  394. {
  395. size_type __size = this->size();
  396. if (__size)
  397. {
  398. if (--__size > __pos)
  399. __size = __pos;
  400. do
  401. {
  402. if (!traits_type::eq(this->_M_data()[__size], __c))
  403. return __size;
  404. }
  405. while (__size--);
  406. }
  407. return npos;
  408. }
  409. template<typename _CharT, typename _Traits, typename _Alloc,
  410. template <typename, typename, typename> class _Base>
  411. int
  412. __versa_string<_CharT, _Traits, _Alloc, _Base>::
  413. compare(size_type __pos, size_type __n, const __versa_string& __str) const
  414. {
  415. _M_check(__pos, "__versa_string::compare");
  416. __n = _M_limit(__pos, __n);
  417. const size_type __osize = __str.size();
  418. const size_type __len = std::min(__n, __osize);
  419. int __r = traits_type::compare(this->_M_data() + __pos,
  420. __str.data(), __len);
  421. if (!__r)
  422. __r = _S_compare(__n, __osize);
  423. return __r;
  424. }
  425. template<typename _CharT, typename _Traits, typename _Alloc,
  426. template <typename, typename, typename> class _Base>
  427. int
  428. __versa_string<_CharT, _Traits, _Alloc, _Base>::
  429. compare(size_type __pos1, size_type __n1, const __versa_string& __str,
  430. size_type __pos2, size_type __n2) const
  431. {
  432. _M_check(__pos1, "__versa_string::compare");
  433. __str._M_check(__pos2, "__versa_string::compare");
  434. __n1 = _M_limit(__pos1, __n1);
  435. __n2 = __str._M_limit(__pos2, __n2);
  436. const size_type __len = std::min(__n1, __n2);
  437. int __r = traits_type::compare(this->_M_data() + __pos1,
  438. __str.data() + __pos2, __len);
  439. if (!__r)
  440. __r = _S_compare(__n1, __n2);
  441. return __r;
  442. }
  443. template<typename _CharT, typename _Traits, typename _Alloc,
  444. template <typename, typename, typename> class _Base>
  445. int
  446. __versa_string<_CharT, _Traits, _Alloc, _Base>::
  447. compare(const _CharT* __s) const
  448. {
  449. __glibcxx_requires_string(__s);
  450. const size_type __size = this->size();
  451. const size_type __osize = traits_type::length(__s);
  452. const size_type __len = std::min(__size, __osize);
  453. int __r = traits_type::compare(this->_M_data(), __s, __len);
  454. if (!__r)
  455. __r = _S_compare(__size, __osize);
  456. return __r;
  457. }
  458. template<typename _CharT, typename _Traits, typename _Alloc,
  459. template <typename, typename, typename> class _Base>
  460. int
  461. __versa_string <_CharT, _Traits, _Alloc, _Base>::
  462. compare(size_type __pos, size_type __n1, const _CharT* __s) const
  463. {
  464. __glibcxx_requires_string(__s);
  465. _M_check(__pos, "__versa_string::compare");
  466. __n1 = _M_limit(__pos, __n1);
  467. const size_type __osize = traits_type::length(__s);
  468. const size_type __len = std::min(__n1, __osize);
  469. int __r = traits_type::compare(this->_M_data() + __pos, __s, __len);
  470. if (!__r)
  471. __r = _S_compare(__n1, __osize);
  472. return __r;
  473. }
  474. template<typename _CharT, typename _Traits, typename _Alloc,
  475. template <typename, typename, typename> class _Base>
  476. int
  477. __versa_string <_CharT, _Traits, _Alloc, _Base>::
  478. compare(size_type __pos, size_type __n1, const _CharT* __s,
  479. size_type __n2) const
  480. {
  481. __glibcxx_requires_string_len(__s, __n2);
  482. _M_check(__pos, "__versa_string::compare");
  483. __n1 = _M_limit(__pos, __n1);
  484. const size_type __len = std::min(__n1, __n2);
  485. int __r = traits_type::compare(this->_M_data() + __pos, __s, __len);
  486. if (!__r)
  487. __r = _S_compare(__n1, __n2);
  488. return __r;
  489. }
  490. _GLIBCXX_END_NAMESPACE
  491. _GLIBCXX_BEGIN_NAMESPACE(std)
  492. template<typename _CharT, typename _Traits, typename _Alloc,
  493. template <typename, typename, typename> class _Base>
  494. basic_istream<_CharT, _Traits>&
  495. operator>>(basic_istream<_CharT, _Traits>& __in,
  496. __gnu_cxx::__versa_string<_CharT, _Traits,
  497. _Alloc, _Base>& __str)
  498. {
  499. typedef basic_istream<_CharT, _Traits> __istream_type;
  500. typedef typename __istream_type::ios_base __ios_base;
  501. typedef __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>
  502. __string_type;
  503. typedef typename __istream_type::int_type __int_type;
  504. typedef typename __string_type::size_type __size_type;
  505. typedef ctype<_CharT> __ctype_type;
  506. typedef typename __ctype_type::ctype_base __ctype_base;
  507. __size_type __extracted = 0;
  508. typename __ios_base::iostate __err = __ios_base::goodbit;
  509. typename __istream_type::sentry __cerb(__in, false);
  510. if (__cerb)
  511. {
  512. __try
  513. {
  514. // Avoid reallocation for common case.
  515. __str.erase();
  516. _CharT __buf[128];
  517. __size_type __len = 0;
  518. const streamsize __w = __in.width();
  519. const __size_type __n = __w > 0 ? static_cast<__size_type>(__w)
  520. : __str.max_size();
  521. const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
  522. const __int_type __eof = _Traits::eof();
  523. __int_type __c = __in.rdbuf()->sgetc();
  524. while (__extracted < __n
  525. && !_Traits::eq_int_type(__c, __eof)
  526. && !__ct.is(__ctype_base::space,
  527. _Traits::to_char_type(__c)))
  528. {
  529. if (__len == sizeof(__buf) / sizeof(_CharT))
  530. {
  531. __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
  532. __len = 0;
  533. }
  534. __buf[__len++] = _Traits::to_char_type(__c);
  535. ++__extracted;
  536. __c = __in.rdbuf()->snextc();
  537. }
  538. __str.append(__buf, __len);
  539. if (_Traits::eq_int_type(__c, __eof))
  540. __err |= __ios_base::eofbit;
  541. __in.width(0);
  542. }
  543. __catch(__cxxabiv1::__forced_unwind&)
  544. {
  545. __in._M_setstate(__ios_base::badbit);
  546. __throw_exception_again;
  547. }
  548. __catch(...)
  549. {
  550. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  551. // 91. Description of operator>> and getline() for string<>
  552. // might cause endless loop
  553. __in._M_setstate(__ios_base::badbit);
  554. }
  555. }
  556. // 211. operator>>(istream&, string&) doesn't set failbit
  557. if (!__extracted)
  558. __err |= __ios_base::failbit;
  559. if (__err)
  560. __in.setstate(__err);
  561. return __in;
  562. }
  563. template<typename _CharT, typename _Traits, typename _Alloc,
  564. template <typename, typename, typename> class _Base>
  565. basic_istream<_CharT, _Traits>&
  566. getline(basic_istream<_CharT, _Traits>& __in,
  567. __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>& __str,
  568. _CharT __delim)
  569. {
  570. typedef basic_istream<_CharT, _Traits> __istream_type;
  571. typedef typename __istream_type::ios_base __ios_base;
  572. typedef __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>
  573. __string_type;
  574. typedef typename __istream_type::int_type __int_type;
  575. typedef typename __string_type::size_type __size_type;
  576. __size_type __extracted = 0;
  577. const __size_type __n = __str.max_size();
  578. typename __ios_base::iostate __err = __ios_base::goodbit;
  579. typename __istream_type::sentry __cerb(__in, true);
  580. if (__cerb)
  581. {
  582. __try
  583. {
  584. // Avoid reallocation for common case.
  585. __str.erase();
  586. _CharT __buf[128];
  587. __size_type __len = 0;
  588. const __int_type __idelim = _Traits::to_int_type(__delim);
  589. const __int_type __eof = _Traits::eof();
  590. __int_type __c = __in.rdbuf()->sgetc();
  591. while (__extracted < __n
  592. && !_Traits::eq_int_type(__c, __eof)
  593. && !_Traits::eq_int_type(__c, __idelim))
  594. {
  595. if (__len == sizeof(__buf) / sizeof(_CharT))
  596. {
  597. __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
  598. __len = 0;
  599. }
  600. __buf[__len++] = _Traits::to_char_type(__c);
  601. ++__extracted;
  602. __c = __in.rdbuf()->snextc();
  603. }
  604. __str.append(__buf, __len);
  605. if (_Traits::eq_int_type(__c, __eof))
  606. __err |= __ios_base::eofbit;
  607. else if (_Traits::eq_int_type(__c, __idelim))
  608. {
  609. ++__extracted;
  610. __in.rdbuf()->sbumpc();
  611. }
  612. else
  613. __err |= __ios_base::failbit;
  614. }
  615. __catch(__cxxabiv1::__forced_unwind&)
  616. {
  617. __in._M_setstate(__ios_base::badbit);
  618. __throw_exception_again;
  619. }
  620. __catch(...)
  621. {
  622. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  623. // 91. Description of operator>> and getline() for string<>
  624. // might cause endless loop
  625. __in._M_setstate(__ios_base::badbit);
  626. }
  627. }
  628. if (!__extracted)
  629. __err |= __ios_base::failbit;
  630. if (__err)
  631. __in.setstate(__err);
  632. return __in;
  633. }
  634. _GLIBCXX_END_NAMESPACE
  635. #endif // _VSTRING_TCC