vstring.tcc 23 KB

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