basic_string.tcc 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129
  1. // Components for manipulating sequences of characters -*- C++ -*-
  2. // Copyright (C) 1997-2022 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 bits/basic_string.tcc
  21. * This is an internal header file, included by other library headers.
  22. * Do not attempt to use it directly. @headername{string}
  23. */
  24. //
  25. // ISO C++ 14882: 21 Strings library
  26. //
  27. // Written by Jason Merrill based upon the specification by Takanori Adachi
  28. // in ANSI X3J16/94-0013R2. Rewritten by Nathan Myers to ISO-14882.
  29. // Non-reference-counted implementation written by Paolo Carlini and
  30. // updated by Jonathan Wakely for ISO-14882-2011.
  31. #ifndef _BASIC_STRING_TCC
  32. #define _BASIC_STRING_TCC 1
  33. #pragma GCC system_header
  34. #include <bits/cxxabi_forced.h>
  35. namespace std _GLIBCXX_VISIBILITY(default)
  36. {
  37. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  38. #if _GLIBCXX_USE_CXX11_ABI
  39. template<typename _CharT, typename _Traits, typename _Alloc>
  40. const typename basic_string<_CharT, _Traits, _Alloc>::size_type
  41. basic_string<_CharT, _Traits, _Alloc>::npos;
  42. template<typename _CharT, typename _Traits, typename _Alloc>
  43. _GLIBCXX20_CONSTEXPR
  44. void
  45. basic_string<_CharT, _Traits, _Alloc>::
  46. swap(basic_string& __s) _GLIBCXX_NOEXCEPT
  47. {
  48. if (this == std::__addressof(__s))
  49. return;
  50. _Alloc_traits::_S_on_swap(_M_get_allocator(), __s._M_get_allocator());
  51. if (_M_is_local())
  52. if (__s._M_is_local())
  53. {
  54. if (length() && __s.length())
  55. {
  56. _CharT __tmp_data[_S_local_capacity + 1];
  57. traits_type::copy(__tmp_data, __s._M_local_buf,
  58. __s.length() + 1);
  59. traits_type::copy(__s._M_local_buf, _M_local_buf,
  60. length() + 1);
  61. traits_type::copy(_M_local_buf, __tmp_data,
  62. __s.length() + 1);
  63. }
  64. else if (__s.length())
  65. {
  66. traits_type::copy(_M_local_buf, __s._M_local_buf,
  67. __s.length() + 1);
  68. _M_length(__s.length());
  69. __s._M_set_length(0);
  70. return;
  71. }
  72. else if (length())
  73. {
  74. traits_type::copy(__s._M_local_buf, _M_local_buf,
  75. length() + 1);
  76. __s._M_length(length());
  77. _M_set_length(0);
  78. return;
  79. }
  80. }
  81. else
  82. {
  83. const size_type __tmp_capacity = __s._M_allocated_capacity;
  84. traits_type::copy(__s._M_local_buf, _M_local_buf,
  85. length() + 1);
  86. _M_data(__s._M_data());
  87. __s._M_data(__s._M_local_buf);
  88. _M_capacity(__tmp_capacity);
  89. }
  90. else
  91. {
  92. const size_type __tmp_capacity = _M_allocated_capacity;
  93. if (__s._M_is_local())
  94. {
  95. traits_type::copy(_M_local_buf, __s._M_local_buf,
  96. __s.length() + 1);
  97. __s._M_data(_M_data());
  98. _M_data(_M_local_buf);
  99. }
  100. else
  101. {
  102. pointer __tmp_ptr = _M_data();
  103. _M_data(__s._M_data());
  104. __s._M_data(__tmp_ptr);
  105. _M_capacity(__s._M_allocated_capacity);
  106. }
  107. __s._M_capacity(__tmp_capacity);
  108. }
  109. const size_type __tmp_length = length();
  110. _M_length(__s.length());
  111. __s._M_length(__tmp_length);
  112. }
  113. template<typename _CharT, typename _Traits, typename _Alloc>
  114. _GLIBCXX20_CONSTEXPR
  115. typename basic_string<_CharT, _Traits, _Alloc>::pointer
  116. basic_string<_CharT, _Traits, _Alloc>::
  117. _M_create(size_type& __capacity, size_type __old_capacity)
  118. {
  119. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  120. // 83. String::npos vs. string::max_size()
  121. if (__capacity > max_size())
  122. std::__throw_length_error(__N("basic_string::_M_create"));
  123. // The below implements an exponential growth policy, necessary to
  124. // meet amortized linear time requirements of the library: see
  125. // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html.
  126. if (__capacity > __old_capacity && __capacity < 2 * __old_capacity)
  127. {
  128. __capacity = 2 * __old_capacity;
  129. // Never allocate a string bigger than max_size.
  130. if (__capacity > max_size())
  131. __capacity = max_size();
  132. }
  133. // NB: Need an array of char_type[__capacity], plus a terminating
  134. // null char_type() element.
  135. return _Alloc_traits::allocate(_M_get_allocator(), __capacity + 1);
  136. }
  137. // NB: This is the special case for Input Iterators, used in
  138. // istreambuf_iterators, etc.
  139. // Input Iterators have a cost structure very different from
  140. // pointers, calling for a different coding style.
  141. template<typename _CharT, typename _Traits, typename _Alloc>
  142. template<typename _InIterator>
  143. _GLIBCXX20_CONSTEXPR
  144. void
  145. basic_string<_CharT, _Traits, _Alloc>::
  146. _M_construct(_InIterator __beg, _InIterator __end,
  147. std::input_iterator_tag)
  148. {
  149. size_type __len = 0;
  150. size_type __capacity = size_type(_S_local_capacity);
  151. pointer __p = _M_use_local_data();
  152. while (__beg != __end && __len < __capacity)
  153. {
  154. __p[__len++] = *__beg;
  155. ++__beg;
  156. }
  157. struct _Guard
  158. {
  159. _GLIBCXX20_CONSTEXPR
  160. explicit _Guard(basic_string* __s) : _M_guarded(__s) { }
  161. _GLIBCXX20_CONSTEXPR
  162. ~_Guard() { if (_M_guarded) _M_guarded->_M_dispose(); }
  163. basic_string* _M_guarded;
  164. } __guard(this);
  165. while (__beg != __end)
  166. {
  167. if (__len == __capacity)
  168. {
  169. // Allocate more space.
  170. __capacity = __len + 1;
  171. pointer __another = _M_create(__capacity, __len);
  172. this->_S_copy(__another, _M_data(), __len);
  173. _M_dispose();
  174. _M_data(__another);
  175. _M_capacity(__capacity);
  176. }
  177. traits_type::assign(_M_data()[__len++], *__beg);
  178. ++__beg;
  179. }
  180. __guard._M_guarded = 0;
  181. _M_set_length(__len);
  182. }
  183. template<typename _CharT, typename _Traits, typename _Alloc>
  184. template<typename _InIterator>
  185. _GLIBCXX20_CONSTEXPR
  186. void
  187. basic_string<_CharT, _Traits, _Alloc>::
  188. _M_construct(_InIterator __beg, _InIterator __end,
  189. std::forward_iterator_tag)
  190. {
  191. size_type __dnew = static_cast<size_type>(std::distance(__beg, __end));
  192. if (__dnew > size_type(_S_local_capacity))
  193. {
  194. _M_data(_M_create(__dnew, size_type(0)));
  195. _M_capacity(__dnew);
  196. }
  197. else
  198. _M_use_local_data();
  199. // Check for out_of_range and length_error exceptions.
  200. struct _Guard
  201. {
  202. _GLIBCXX20_CONSTEXPR
  203. explicit _Guard(basic_string* __s) : _M_guarded(__s) { }
  204. _GLIBCXX20_CONSTEXPR
  205. ~_Guard() { if (_M_guarded) _M_guarded->_M_dispose(); }
  206. basic_string* _M_guarded;
  207. } __guard(this);
  208. this->_S_copy_chars(_M_data(), __beg, __end);
  209. __guard._M_guarded = 0;
  210. _M_set_length(__dnew);
  211. }
  212. template<typename _CharT, typename _Traits, typename _Alloc>
  213. _GLIBCXX20_CONSTEXPR
  214. void
  215. basic_string<_CharT, _Traits, _Alloc>::
  216. _M_construct(size_type __n, _CharT __c)
  217. {
  218. if (__n > size_type(_S_local_capacity))
  219. {
  220. _M_data(_M_create(__n, size_type(0)));
  221. _M_capacity(__n);
  222. }
  223. else
  224. _M_use_local_data();
  225. if (__n)
  226. this->_S_assign(_M_data(), __n, __c);
  227. _M_set_length(__n);
  228. }
  229. template<typename _CharT, typename _Traits, typename _Alloc>
  230. _GLIBCXX20_CONSTEXPR
  231. void
  232. basic_string<_CharT, _Traits, _Alloc>::
  233. _M_assign(const basic_string& __str)
  234. {
  235. if (this != std::__addressof(__str))
  236. {
  237. const size_type __rsize = __str.length();
  238. const size_type __capacity = capacity();
  239. if (__rsize > __capacity)
  240. {
  241. size_type __new_capacity = __rsize;
  242. pointer __tmp = _M_create(__new_capacity, __capacity);
  243. _M_dispose();
  244. _M_data(__tmp);
  245. _M_capacity(__new_capacity);
  246. }
  247. if (__rsize)
  248. this->_S_copy(_M_data(), __str._M_data(), __rsize);
  249. _M_set_length(__rsize);
  250. }
  251. }
  252. template<typename _CharT, typename _Traits, typename _Alloc>
  253. _GLIBCXX20_CONSTEXPR
  254. void
  255. basic_string<_CharT, _Traits, _Alloc>::
  256. reserve(size_type __res)
  257. {
  258. const size_type __capacity = capacity();
  259. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  260. // 2968. Inconsistencies between basic_string reserve and
  261. // vector/unordered_map/unordered_set reserve functions
  262. // P0966 reserve should not shrink
  263. if (__res <= __capacity)
  264. return;
  265. pointer __tmp = _M_create(__res, __capacity);
  266. this->_S_copy(__tmp, _M_data(), length() + 1);
  267. _M_dispose();
  268. _M_data(__tmp);
  269. _M_capacity(__res);
  270. }
  271. template<typename _CharT, typename _Traits, typename _Alloc>
  272. _GLIBCXX20_CONSTEXPR
  273. void
  274. basic_string<_CharT, _Traits, _Alloc>::
  275. _M_mutate(size_type __pos, size_type __len1, const _CharT* __s,
  276. size_type __len2)
  277. {
  278. const size_type __how_much = length() - __pos - __len1;
  279. size_type __new_capacity = length() + __len2 - __len1;
  280. pointer __r = _M_create(__new_capacity, capacity());
  281. if (__pos)
  282. this->_S_copy(__r, _M_data(), __pos);
  283. if (__s && __len2)
  284. this->_S_copy(__r + __pos, __s, __len2);
  285. if (__how_much)
  286. this->_S_copy(__r + __pos + __len2,
  287. _M_data() + __pos + __len1, __how_much);
  288. _M_dispose();
  289. _M_data(__r);
  290. _M_capacity(__new_capacity);
  291. }
  292. template<typename _CharT, typename _Traits, typename _Alloc>
  293. _GLIBCXX20_CONSTEXPR
  294. void
  295. basic_string<_CharT, _Traits, _Alloc>::
  296. _M_erase(size_type __pos, size_type __n)
  297. {
  298. const size_type __how_much = length() - __pos - __n;
  299. if (__how_much && __n)
  300. this->_S_move(_M_data() + __pos, _M_data() + __pos + __n, __how_much);
  301. _M_set_length(length() - __n);
  302. }
  303. template<typename _CharT, typename _Traits, typename _Alloc>
  304. _GLIBCXX20_CONSTEXPR
  305. void
  306. basic_string<_CharT, _Traits, _Alloc>::
  307. reserve()
  308. {
  309. if (_M_is_local())
  310. return;
  311. const size_type __length = length();
  312. const size_type __capacity = _M_allocated_capacity;
  313. if (__length <= size_type(_S_local_capacity))
  314. {
  315. this->_S_copy(_M_use_local_data(), _M_data(), __length + 1);
  316. _M_destroy(__capacity);
  317. _M_data(_M_local_data());
  318. }
  319. #if __cpp_exceptions
  320. else if (__length < __capacity)
  321. try
  322. {
  323. pointer __tmp
  324. = _Alloc_traits::allocate(_M_get_allocator(), __length + 1);
  325. this->_S_copy(__tmp, _M_data(), __length + 1);
  326. _M_dispose();
  327. _M_data(__tmp);
  328. _M_capacity(__length);
  329. }
  330. catch (const __cxxabiv1::__forced_unwind&)
  331. { throw; }
  332. catch (...)
  333. { /* swallow the exception */ }
  334. #endif
  335. }
  336. template<typename _CharT, typename _Traits, typename _Alloc>
  337. _GLIBCXX20_CONSTEXPR
  338. void
  339. basic_string<_CharT, _Traits, _Alloc>::
  340. resize(size_type __n, _CharT __c)
  341. {
  342. const size_type __size = this->size();
  343. if (__size < __n)
  344. this->append(__n - __size, __c);
  345. else if (__n < __size)
  346. this->_M_set_length(__n);
  347. }
  348. template<typename _CharT, typename _Traits, typename _Alloc>
  349. _GLIBCXX20_CONSTEXPR
  350. basic_string<_CharT, _Traits, _Alloc>&
  351. basic_string<_CharT, _Traits, _Alloc>::
  352. _M_append(const _CharT* __s, size_type __n)
  353. {
  354. const size_type __len = __n + this->size();
  355. if (__len <= this->capacity())
  356. {
  357. if (__n)
  358. this->_S_copy(this->_M_data() + this->size(), __s, __n);
  359. }
  360. else
  361. this->_M_mutate(this->size(), size_type(0), __s, __n);
  362. this->_M_set_length(__len);
  363. return *this;
  364. }
  365. template<typename _CharT, typename _Traits, typename _Alloc>
  366. template<typename _InputIterator>
  367. _GLIBCXX20_CONSTEXPR
  368. basic_string<_CharT, _Traits, _Alloc>&
  369. basic_string<_CharT, _Traits, _Alloc>::
  370. _M_replace_dispatch(const_iterator __i1, const_iterator __i2,
  371. _InputIterator __k1, _InputIterator __k2,
  372. std::__false_type)
  373. {
  374. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  375. // 2788. unintentionally require a default constructible allocator
  376. const basic_string __s(__k1, __k2, this->get_allocator());
  377. const size_type __n1 = __i2 - __i1;
  378. return _M_replace(__i1 - begin(), __n1, __s._M_data(),
  379. __s.size());
  380. }
  381. template<typename _CharT, typename _Traits, typename _Alloc>
  382. _GLIBCXX20_CONSTEXPR
  383. basic_string<_CharT, _Traits, _Alloc>&
  384. basic_string<_CharT, _Traits, _Alloc>::
  385. _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
  386. _CharT __c)
  387. {
  388. _M_check_length(__n1, __n2, "basic_string::_M_replace_aux");
  389. const size_type __old_size = this->size();
  390. const size_type __new_size = __old_size + __n2 - __n1;
  391. if (__new_size <= this->capacity())
  392. {
  393. pointer __p = this->_M_data() + __pos1;
  394. const size_type __how_much = __old_size - __pos1 - __n1;
  395. if (__how_much && __n1 != __n2)
  396. this->_S_move(__p + __n2, __p + __n1, __how_much);
  397. }
  398. else
  399. this->_M_mutate(__pos1, __n1, 0, __n2);
  400. if (__n2)
  401. this->_S_assign(this->_M_data() + __pos1, __n2, __c);
  402. this->_M_set_length(__new_size);
  403. return *this;
  404. }
  405. template<typename _CharT, typename _Traits, typename _Alloc>
  406. _GLIBCXX20_CONSTEXPR
  407. basic_string<_CharT, _Traits, _Alloc>&
  408. basic_string<_CharT, _Traits, _Alloc>::
  409. _M_replace(size_type __pos, size_type __len1, const _CharT* __s,
  410. const size_type __len2)
  411. {
  412. _M_check_length(__len1, __len2, "basic_string::_M_replace");
  413. const size_type __old_size = this->size();
  414. const size_type __new_size = __old_size + __len2 - __len1;
  415. if (__new_size <= this->capacity())
  416. {
  417. pointer __p = this->_M_data() + __pos;
  418. const size_type __how_much = __old_size - __pos - __len1;
  419. #if __cpp_lib_is_constant_evaluated
  420. if (std::is_constant_evaluated())
  421. {
  422. auto __newp = _Alloc_traits::allocate(_M_get_allocator(),
  423. __new_size);
  424. _S_copy(__newp, this->_M_data(), __pos);
  425. _S_copy(__newp + __pos, __s, __len2);
  426. _S_copy(__newp + __pos + __len2, __p + __len1, __how_much);
  427. _S_copy(this->_M_data(), __newp, __new_size);
  428. this->_M_get_allocator().deallocate(__newp, __new_size);
  429. }
  430. else
  431. #endif
  432. if (_M_disjunct(__s))
  433. {
  434. if (__how_much && __len1 != __len2)
  435. this->_S_move(__p + __len2, __p + __len1, __how_much);
  436. if (__len2)
  437. this->_S_copy(__p, __s, __len2);
  438. }
  439. else
  440. {
  441. // Work in-place.
  442. if (__len2 && __len2 <= __len1)
  443. this->_S_move(__p, __s, __len2);
  444. if (__how_much && __len1 != __len2)
  445. this->_S_move(__p + __len2, __p + __len1, __how_much);
  446. if (__len2 > __len1)
  447. {
  448. if (__s + __len2 <= __p + __len1)
  449. this->_S_move(__p, __s, __len2);
  450. else if (__s >= __p + __len1)
  451. {
  452. // Hint to middle end that __p and __s overlap
  453. // (PR 98465).
  454. const size_type __poff = (__s - __p) + (__len2 - __len1);
  455. this->_S_copy(__p, __p + __poff, __len2);
  456. }
  457. else
  458. {
  459. const size_type __nleft = (__p + __len1) - __s;
  460. this->_S_move(__p, __s, __nleft);
  461. this->_S_copy(__p + __nleft, __p + __len2,
  462. __len2 - __nleft);
  463. }
  464. }
  465. }
  466. }
  467. else
  468. this->_M_mutate(__pos, __len1, __s, __len2);
  469. this->_M_set_length(__new_size);
  470. return *this;
  471. }
  472. template<typename _CharT, typename _Traits, typename _Alloc>
  473. _GLIBCXX20_CONSTEXPR
  474. typename basic_string<_CharT, _Traits, _Alloc>::size_type
  475. basic_string<_CharT, _Traits, _Alloc>::
  476. copy(_CharT* __s, size_type __n, size_type __pos) const
  477. {
  478. _M_check(__pos, "basic_string::copy");
  479. __n = _M_limit(__pos, __n);
  480. __glibcxx_requires_string_len(__s, __n);
  481. if (__n)
  482. _S_copy(__s, _M_data() + __pos, __n);
  483. // 21.3.5.7 par 3: do not append null. (good.)
  484. return __n;
  485. }
  486. #if __cplusplus > 202002L
  487. template<typename _CharT, typename _Traits, typename _Alloc>
  488. template<typename _Operation>
  489. constexpr void
  490. basic_string<_CharT, _Traits, _Alloc>::
  491. resize_and_overwrite(size_type __n, _Operation __op)
  492. {
  493. const size_type __capacity = capacity();
  494. _CharT* __p;
  495. if (__n > __capacity)
  496. {
  497. __p = _M_create(__n, __capacity);
  498. this->_S_copy(__p, _M_data(), length()); // exclude trailing null
  499. #if __cpp_lib_is_constant_evaluated
  500. if (std::is_constant_evaluated())
  501. traits_type::assign(__p + length(), __n - length(), _CharT());
  502. #endif
  503. _M_dispose();
  504. _M_data(__p);
  505. _M_capacity(__n);
  506. }
  507. else
  508. __p = _M_data();
  509. struct _Terminator {
  510. constexpr ~_Terminator() { _M_this->_M_set_length(_M_r); }
  511. basic_string* _M_this;
  512. size_type _M_r;
  513. };
  514. _Terminator __term{this};
  515. const size_type __n2 [[maybe_unused]] = __n;
  516. __term._M_r = std::move(__op)(__p, __n);
  517. _GLIBCXX_DEBUG_ASSERT(__term._M_r >= 0 && __term._M_r <= __n2);
  518. }
  519. #endif // C++23
  520. #endif // _GLIBCXX_USE_CXX11_ABI
  521. #if __cpp_lib_constexpr_string >= 201907L
  522. # define _GLIBCXX_STRING_CONSTEXPR constexpr
  523. #else
  524. # define _GLIBCXX_STRING_CONSTEXPR
  525. #endif
  526. template<typename _CharT, typename _Traits, typename _Alloc>
  527. _GLIBCXX20_CONSTEXPR
  528. basic_string<_CharT, _Traits, _Alloc>
  529. operator+(const _CharT* __lhs,
  530. const basic_string<_CharT, _Traits, _Alloc>& __rhs)
  531. {
  532. __glibcxx_requires_string(__lhs);
  533. typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
  534. typedef typename __string_type::size_type __size_type;
  535. typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
  536. rebind<_CharT>::other _Char_alloc_type;
  537. typedef __gnu_cxx::__alloc_traits<_Char_alloc_type> _Alloc_traits;
  538. const __size_type __len = _Traits::length(__lhs);
  539. __string_type __str(_Alloc_traits::_S_select_on_copy(
  540. __rhs.get_allocator()));
  541. __str.reserve(__len + __rhs.size());
  542. __str.append(__lhs, __len);
  543. __str.append(__rhs);
  544. return __str;
  545. }
  546. template<typename _CharT, typename _Traits, typename _Alloc>
  547. _GLIBCXX20_CONSTEXPR
  548. basic_string<_CharT, _Traits, _Alloc>
  549. operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs)
  550. {
  551. typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
  552. typedef typename __string_type::size_type __size_type;
  553. typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
  554. rebind<_CharT>::other _Char_alloc_type;
  555. typedef __gnu_cxx::__alloc_traits<_Char_alloc_type> _Alloc_traits;
  556. __string_type __str(_Alloc_traits::_S_select_on_copy(
  557. __rhs.get_allocator()));
  558. const __size_type __len = __rhs.size();
  559. __str.reserve(__len + 1);
  560. __str.append(__size_type(1), __lhs);
  561. __str.append(__rhs);
  562. return __str;
  563. }
  564. template<typename _CharT, typename _Traits, typename _Alloc>
  565. _GLIBCXX_STRING_CONSTEXPR
  566. typename basic_string<_CharT, _Traits, _Alloc>::size_type
  567. basic_string<_CharT, _Traits, _Alloc>::
  568. find(const _CharT* __s, size_type __pos, size_type __n) const
  569. _GLIBCXX_NOEXCEPT
  570. {
  571. __glibcxx_requires_string_len(__s, __n);
  572. const size_type __size = this->size();
  573. if (__n == 0)
  574. return __pos <= __size ? __pos : npos;
  575. if (__pos >= __size)
  576. return npos;
  577. const _CharT __elem0 = __s[0];
  578. const _CharT* const __data = data();
  579. const _CharT* __first = __data + __pos;
  580. const _CharT* const __last = __data + __size;
  581. size_type __len = __size - __pos;
  582. while (__len >= __n)
  583. {
  584. // Find the first occurrence of __elem0:
  585. __first = traits_type::find(__first, __len - __n + 1, __elem0);
  586. if (!__first)
  587. return npos;
  588. // Compare the full strings from the first occurrence of __elem0.
  589. // We already know that __first[0] == __s[0] but compare them again
  590. // anyway because __s is probably aligned, which helps memcmp.
  591. if (traits_type::compare(__first, __s, __n) == 0)
  592. return __first - __data;
  593. __len = __last - ++__first;
  594. }
  595. return npos;
  596. }
  597. template<typename _CharT, typename _Traits, typename _Alloc>
  598. _GLIBCXX_STRING_CONSTEXPR
  599. typename basic_string<_CharT, _Traits, _Alloc>::size_type
  600. basic_string<_CharT, _Traits, _Alloc>::
  601. find(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
  602. {
  603. size_type __ret = npos;
  604. const size_type __size = this->size();
  605. if (__pos < __size)
  606. {
  607. const _CharT* __data = _M_data();
  608. const size_type __n = __size - __pos;
  609. const _CharT* __p = traits_type::find(__data + __pos, __n, __c);
  610. if (__p)
  611. __ret = __p - __data;
  612. }
  613. return __ret;
  614. }
  615. template<typename _CharT, typename _Traits, typename _Alloc>
  616. _GLIBCXX_STRING_CONSTEXPR
  617. typename basic_string<_CharT, _Traits, _Alloc>::size_type
  618. basic_string<_CharT, _Traits, _Alloc>::
  619. rfind(const _CharT* __s, size_type __pos, size_type __n) const
  620. _GLIBCXX_NOEXCEPT
  621. {
  622. __glibcxx_requires_string_len(__s, __n);
  623. const size_type __size = this->size();
  624. if (__n <= __size)
  625. {
  626. __pos = std::min(size_type(__size - __n), __pos);
  627. const _CharT* __data = _M_data();
  628. do
  629. {
  630. if (traits_type::compare(__data + __pos, __s, __n) == 0)
  631. return __pos;
  632. }
  633. while (__pos-- > 0);
  634. }
  635. return npos;
  636. }
  637. template<typename _CharT, typename _Traits, typename _Alloc>
  638. _GLIBCXX_STRING_CONSTEXPR
  639. typename basic_string<_CharT, _Traits, _Alloc>::size_type
  640. basic_string<_CharT, _Traits, _Alloc>::
  641. rfind(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
  642. {
  643. size_type __size = this->size();
  644. if (__size)
  645. {
  646. if (--__size > __pos)
  647. __size = __pos;
  648. for (++__size; __size-- > 0; )
  649. if (traits_type::eq(_M_data()[__size], __c))
  650. return __size;
  651. }
  652. return npos;
  653. }
  654. template<typename _CharT, typename _Traits, typename _Alloc>
  655. _GLIBCXX_STRING_CONSTEXPR
  656. typename basic_string<_CharT, _Traits, _Alloc>::size_type
  657. basic_string<_CharT, _Traits, _Alloc>::
  658. find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
  659. _GLIBCXX_NOEXCEPT
  660. {
  661. __glibcxx_requires_string_len(__s, __n);
  662. for (; __n && __pos < this->size(); ++__pos)
  663. {
  664. const _CharT* __p = traits_type::find(__s, __n, _M_data()[__pos]);
  665. if (__p)
  666. return __pos;
  667. }
  668. return npos;
  669. }
  670. template<typename _CharT, typename _Traits, typename _Alloc>
  671. _GLIBCXX_STRING_CONSTEXPR
  672. typename basic_string<_CharT, _Traits, _Alloc>::size_type
  673. basic_string<_CharT, _Traits, _Alloc>::
  674. find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
  675. _GLIBCXX_NOEXCEPT
  676. {
  677. __glibcxx_requires_string_len(__s, __n);
  678. size_type __size = this->size();
  679. if (__size && __n)
  680. {
  681. if (--__size > __pos)
  682. __size = __pos;
  683. do
  684. {
  685. if (traits_type::find(__s, __n, _M_data()[__size]))
  686. return __size;
  687. }
  688. while (__size-- != 0);
  689. }
  690. return npos;
  691. }
  692. template<typename _CharT, typename _Traits, typename _Alloc>
  693. _GLIBCXX_STRING_CONSTEXPR
  694. typename basic_string<_CharT, _Traits, _Alloc>::size_type
  695. basic_string<_CharT, _Traits, _Alloc>::
  696. find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
  697. _GLIBCXX_NOEXCEPT
  698. {
  699. __glibcxx_requires_string_len(__s, __n);
  700. for (; __pos < this->size(); ++__pos)
  701. if (!traits_type::find(__s, __n, _M_data()[__pos]))
  702. return __pos;
  703. return npos;
  704. }
  705. template<typename _CharT, typename _Traits, typename _Alloc>
  706. _GLIBCXX_STRING_CONSTEXPR
  707. typename basic_string<_CharT, _Traits, _Alloc>::size_type
  708. basic_string<_CharT, _Traits, _Alloc>::
  709. find_first_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
  710. {
  711. for (; __pos < this->size(); ++__pos)
  712. if (!traits_type::eq(_M_data()[__pos], __c))
  713. return __pos;
  714. return npos;
  715. }
  716. template<typename _CharT, typename _Traits, typename _Alloc>
  717. _GLIBCXX_STRING_CONSTEXPR
  718. typename basic_string<_CharT, _Traits, _Alloc>::size_type
  719. basic_string<_CharT, _Traits, _Alloc>::
  720. find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
  721. _GLIBCXX_NOEXCEPT
  722. {
  723. __glibcxx_requires_string_len(__s, __n);
  724. size_type __size = this->size();
  725. if (__size)
  726. {
  727. if (--__size > __pos)
  728. __size = __pos;
  729. do
  730. {
  731. if (!traits_type::find(__s, __n, _M_data()[__size]))
  732. return __size;
  733. }
  734. while (__size--);
  735. }
  736. return npos;
  737. }
  738. template<typename _CharT, typename _Traits, typename _Alloc>
  739. _GLIBCXX_STRING_CONSTEXPR
  740. typename basic_string<_CharT, _Traits, _Alloc>::size_type
  741. basic_string<_CharT, _Traits, _Alloc>::
  742. find_last_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
  743. {
  744. size_type __size = this->size();
  745. if (__size)
  746. {
  747. if (--__size > __pos)
  748. __size = __pos;
  749. do
  750. {
  751. if (!traits_type::eq(_M_data()[__size], __c))
  752. return __size;
  753. }
  754. while (__size--);
  755. }
  756. return npos;
  757. }
  758. template<typename _CharT, typename _Traits, typename _Alloc>
  759. _GLIBCXX_STRING_CONSTEXPR
  760. int
  761. basic_string<_CharT, _Traits, _Alloc>::
  762. compare(size_type __pos, size_type __n, const basic_string& __str) const
  763. {
  764. _M_check(__pos, "basic_string::compare");
  765. __n = _M_limit(__pos, __n);
  766. const size_type __osize = __str.size();
  767. const size_type __len = std::min(__n, __osize);
  768. int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len);
  769. if (!__r)
  770. __r = _S_compare(__n, __osize);
  771. return __r;
  772. }
  773. template<typename _CharT, typename _Traits, typename _Alloc>
  774. _GLIBCXX_STRING_CONSTEXPR
  775. int
  776. basic_string<_CharT, _Traits, _Alloc>::
  777. compare(size_type __pos1, size_type __n1, const basic_string& __str,
  778. size_type __pos2, size_type __n2) const
  779. {
  780. _M_check(__pos1, "basic_string::compare");
  781. __str._M_check(__pos2, "basic_string::compare");
  782. __n1 = _M_limit(__pos1, __n1);
  783. __n2 = __str._M_limit(__pos2, __n2);
  784. const size_type __len = std::min(__n1, __n2);
  785. int __r = traits_type::compare(_M_data() + __pos1,
  786. __str.data() + __pos2, __len);
  787. if (!__r)
  788. __r = _S_compare(__n1, __n2);
  789. return __r;
  790. }
  791. template<typename _CharT, typename _Traits, typename _Alloc>
  792. _GLIBCXX_STRING_CONSTEXPR
  793. int
  794. basic_string<_CharT, _Traits, _Alloc>::
  795. compare(const _CharT* __s) const _GLIBCXX_NOEXCEPT
  796. {
  797. __glibcxx_requires_string(__s);
  798. const size_type __size = this->size();
  799. const size_type __osize = traits_type::length(__s);
  800. const size_type __len = std::min(__size, __osize);
  801. int __r = traits_type::compare(_M_data(), __s, __len);
  802. if (!__r)
  803. __r = _S_compare(__size, __osize);
  804. return __r;
  805. }
  806. template<typename _CharT, typename _Traits, typename _Alloc>
  807. _GLIBCXX_STRING_CONSTEXPR
  808. int
  809. basic_string <_CharT, _Traits, _Alloc>::
  810. compare(size_type __pos, size_type __n1, const _CharT* __s) const
  811. {
  812. __glibcxx_requires_string(__s);
  813. _M_check(__pos, "basic_string::compare");
  814. __n1 = _M_limit(__pos, __n1);
  815. const size_type __osize = traits_type::length(__s);
  816. const size_type __len = std::min(__n1, __osize);
  817. int __r = traits_type::compare(_M_data() + __pos, __s, __len);
  818. if (!__r)
  819. __r = _S_compare(__n1, __osize);
  820. return __r;
  821. }
  822. template<typename _CharT, typename _Traits, typename _Alloc>
  823. _GLIBCXX_STRING_CONSTEXPR
  824. int
  825. basic_string <_CharT, _Traits, _Alloc>::
  826. compare(size_type __pos, size_type __n1, const _CharT* __s,
  827. size_type __n2) const
  828. {
  829. __glibcxx_requires_string_len(__s, __n2);
  830. _M_check(__pos, "basic_string::compare");
  831. __n1 = _M_limit(__pos, __n1);
  832. const size_type __len = std::min(__n1, __n2);
  833. int __r = traits_type::compare(_M_data() + __pos, __s, __len);
  834. if (!__r)
  835. __r = _S_compare(__n1, __n2);
  836. return __r;
  837. }
  838. #undef _GLIBCXX_STRING_CONSTEXPR
  839. // 21.3.7.9 basic_string::getline and operators
  840. template<typename _CharT, typename _Traits, typename _Alloc>
  841. basic_istream<_CharT, _Traits>&
  842. operator>>(basic_istream<_CharT, _Traits>& __in,
  843. basic_string<_CharT, _Traits, _Alloc>& __str)
  844. {
  845. typedef basic_istream<_CharT, _Traits> __istream_type;
  846. typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
  847. typedef typename __istream_type::ios_base __ios_base;
  848. typedef typename __istream_type::int_type __int_type;
  849. typedef typename __string_type::size_type __size_type;
  850. typedef ctype<_CharT> __ctype_type;
  851. typedef typename __ctype_type::ctype_base __ctype_base;
  852. __size_type __extracted = 0;
  853. typename __ios_base::iostate __err = __ios_base::goodbit;
  854. typename __istream_type::sentry __cerb(__in, false);
  855. if (__cerb)
  856. {
  857. __try
  858. {
  859. // Avoid reallocation for common case.
  860. __str.erase();
  861. _CharT __buf[128];
  862. __size_type __len = 0;
  863. const streamsize __w = __in.width();
  864. const __size_type __n = __w > 0 ? static_cast<__size_type>(__w)
  865. : __str.max_size();
  866. const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
  867. const __int_type __eof = _Traits::eof();
  868. __int_type __c = __in.rdbuf()->sgetc();
  869. while (__extracted < __n
  870. && !_Traits::eq_int_type(__c, __eof)
  871. && !__ct.is(__ctype_base::space,
  872. _Traits::to_char_type(__c)))
  873. {
  874. if (__len == sizeof(__buf) / sizeof(_CharT))
  875. {
  876. __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
  877. __len = 0;
  878. }
  879. __buf[__len++] = _Traits::to_char_type(__c);
  880. ++__extracted;
  881. __c = __in.rdbuf()->snextc();
  882. }
  883. __str.append(__buf, __len);
  884. if (__extracted < __n && _Traits::eq_int_type(__c, __eof))
  885. __err |= __ios_base::eofbit;
  886. __in.width(0);
  887. }
  888. __catch(__cxxabiv1::__forced_unwind&)
  889. {
  890. __in._M_setstate(__ios_base::badbit);
  891. __throw_exception_again;
  892. }
  893. __catch(...)
  894. {
  895. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  896. // 91. Description of operator>> and getline() for string<>
  897. // might cause endless loop
  898. __in._M_setstate(__ios_base::badbit);
  899. }
  900. }
  901. // 211. operator>>(istream&, string&) doesn't set failbit
  902. if (!__extracted)
  903. __err |= __ios_base::failbit;
  904. if (__err)
  905. __in.setstate(__err);
  906. return __in;
  907. }
  908. template<typename _CharT, typename _Traits, typename _Alloc>
  909. basic_istream<_CharT, _Traits>&
  910. getline(basic_istream<_CharT, _Traits>& __in,
  911. basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim)
  912. {
  913. typedef basic_istream<_CharT, _Traits> __istream_type;
  914. typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
  915. typedef typename __istream_type::ios_base __ios_base;
  916. typedef typename __istream_type::int_type __int_type;
  917. typedef typename __string_type::size_type __size_type;
  918. __size_type __extracted = 0;
  919. const __size_type __n = __str.max_size();
  920. typename __ios_base::iostate __err = __ios_base::goodbit;
  921. typename __istream_type::sentry __cerb(__in, true);
  922. if (__cerb)
  923. {
  924. __try
  925. {
  926. __str.erase();
  927. const __int_type __idelim = _Traits::to_int_type(__delim);
  928. const __int_type __eof = _Traits::eof();
  929. __int_type __c = __in.rdbuf()->sgetc();
  930. while (__extracted < __n
  931. && !_Traits::eq_int_type(__c, __eof)
  932. && !_Traits::eq_int_type(__c, __idelim))
  933. {
  934. __str += _Traits::to_char_type(__c);
  935. ++__extracted;
  936. __c = __in.rdbuf()->snextc();
  937. }
  938. if (_Traits::eq_int_type(__c, __eof))
  939. __err |= __ios_base::eofbit;
  940. else if (_Traits::eq_int_type(__c, __idelim))
  941. {
  942. ++__extracted;
  943. __in.rdbuf()->sbumpc();
  944. }
  945. else
  946. __err |= __ios_base::failbit;
  947. }
  948. __catch(__cxxabiv1::__forced_unwind&)
  949. {
  950. __in._M_setstate(__ios_base::badbit);
  951. __throw_exception_again;
  952. }
  953. __catch(...)
  954. {
  955. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  956. // 91. Description of operator>> and getline() for string<>
  957. // might cause endless loop
  958. __in._M_setstate(__ios_base::badbit);
  959. }
  960. }
  961. if (!__extracted)
  962. __err |= __ios_base::failbit;
  963. if (__err)
  964. __in.setstate(__err);
  965. return __in;
  966. }
  967. // Inhibit implicit instantiations for required instantiations,
  968. // which are defined via explicit instantiations elsewhere.
  969. #if _GLIBCXX_EXTERN_TEMPLATE
  970. // The explicit instantiation definitions in src/c++11/string-inst.cc and
  971. // src/c++17/string-inst.cc only instantiate the members required for C++17
  972. // and earlier standards (so not C++20's starts_with and ends_with).
  973. // Suppress the explicit instantiation declarations for C++20, so C++20
  974. // code will implicitly instantiate std::string and std::wstring as needed.
  975. # if __cplusplus <= 201703L && _GLIBCXX_EXTERN_TEMPLATE > 0
  976. extern template class basic_string<char>;
  977. # elif ! _GLIBCXX_USE_CXX11_ABI
  978. // Still need to prevent implicit instantiation of the COW empty rep,
  979. // to ensure the definition in libstdc++.so is unique (PR 86138).
  980. extern template basic_string<char>::size_type
  981. basic_string<char>::_Rep::_S_empty_rep_storage[];
  982. # endif
  983. extern template
  984. basic_istream<char>&
  985. operator>>(basic_istream<char>&, string&);
  986. extern template
  987. basic_ostream<char>&
  988. operator<<(basic_ostream<char>&, const string&);
  989. extern template
  990. basic_istream<char>&
  991. getline(basic_istream<char>&, string&, char);
  992. extern template
  993. basic_istream<char>&
  994. getline(basic_istream<char>&, string&);
  995. #ifdef _GLIBCXX_USE_WCHAR_T
  996. # if __cplusplus <= 201703L && _GLIBCXX_EXTERN_TEMPLATE > 0
  997. extern template class basic_string<wchar_t>;
  998. # elif ! _GLIBCXX_USE_CXX11_ABI
  999. extern template basic_string<wchar_t>::size_type
  1000. basic_string<wchar_t>::_Rep::_S_empty_rep_storage[];
  1001. # endif
  1002. extern template
  1003. basic_istream<wchar_t>&
  1004. operator>>(basic_istream<wchar_t>&, wstring&);
  1005. extern template
  1006. basic_ostream<wchar_t>&
  1007. operator<<(basic_ostream<wchar_t>&, const wstring&);
  1008. extern template
  1009. basic_istream<wchar_t>&
  1010. getline(basic_istream<wchar_t>&, wstring&, wchar_t);
  1011. extern template
  1012. basic_istream<wchar_t>&
  1013. getline(basic_istream<wchar_t>&, wstring&);
  1014. #endif // _GLIBCXX_USE_WCHAR_T
  1015. #endif // _GLIBCXX_EXTERN_TEMPLATE
  1016. _GLIBCXX_END_NAMESPACE_VERSION
  1017. } // namespace std
  1018. #endif