vstring.tcc 23 KB

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