1 // Versatile string -*- C++ -*-
3 // Copyright (C) 2005-2022 Free Software Foundation, Inc.
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
25 /** @file ext/vstring.tcc
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{ext/vstring.h}
31 #define _VSTRING_TCC 1
33 #pragma GCC system_header
35 #include <bits/requires_hosted.h> // GNU extensions are currently omitted
37 #include <bits/cxxabi_forced.h>
39 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
41 _GLIBCXX_BEGIN_NAMESPACE_VERSION
43 template<typename _CharT, typename _Traits, typename _Alloc,
44 template <typename, typename, typename> class _Base>
45 const typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
46 __versa_string<_CharT, _Traits, _Alloc, _Base>::npos;
48 template<typename _CharT, typename _Traits, typename _Alloc,
49 template <typename, typename, typename> class _Base>
51 __versa_string<_CharT, _Traits, _Alloc, _Base>::
52 resize(size_type __n, _CharT __c)
54 const size_type __size = this->size();
56 this->append(__n - __size, __c);
57 else if (__n < __size)
58 this->_M_erase(__n, __size - __n);
61 template<typename _CharT, typename _Traits, typename _Alloc,
62 template <typename, typename, typename> class _Base>
63 __versa_string<_CharT, _Traits, _Alloc, _Base>&
64 __versa_string<_CharT, _Traits, _Alloc, _Base>::
65 _M_append(const _CharT* __s, size_type __n)
67 const size_type __len = __n + this->size();
69 if (__len <= this->capacity() && !this->_M_is_shared())
72 this->_S_copy(this->_M_data() + this->size(), __s, __n);
75 this->_M_mutate(this->size(), size_type(0), __s, __n);
77 this->_M_set_length(__len);
81 template<typename _CharT, typename _Traits, typename _Alloc,
82 template <typename, typename, typename> class _Base>
83 template<typename _InputIterator>
84 __versa_string<_CharT, _Traits, _Alloc, _Base>&
85 __versa_string<_CharT, _Traits, _Alloc, _Base>::
86 _M_replace_dispatch(const_iterator __i1, const_iterator __i2,
87 _InputIterator __k1, _InputIterator __k2,
90 const __versa_string __s(__k1, __k2);
91 const size_type __n1 = __i2 - __i1;
92 return _M_replace(__i1 - _M_ibegin(), __n1, __s._M_data(),
96 template<typename _CharT, typename _Traits, typename _Alloc,
97 template <typename, typename, typename> class _Base>
98 __versa_string<_CharT, _Traits, _Alloc, _Base>&
99 __versa_string<_CharT, _Traits, _Alloc, _Base>::
100 _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
103 _M_check_length(__n1, __n2, "__versa_string::_M_replace_aux");
105 const size_type __old_size = this->size();
106 const size_type __new_size = __old_size + __n2 - __n1;
108 if (__new_size <= this->capacity() && !this->_M_is_shared())
110 _CharT* __p = this->_M_data() + __pos1;
112 const size_type __how_much = __old_size - __pos1 - __n1;
113 if (__how_much && __n1 != __n2)
114 this->_S_move(__p + __n2, __p + __n1, __how_much);
117 this->_M_mutate(__pos1, __n1, 0, __n2);
120 this->_S_assign(this->_M_data() + __pos1, __n2, __c);
122 this->_M_set_length(__new_size);
126 template<typename _CharT, typename _Traits, typename _Alloc,
127 template <typename, typename, typename> class _Base>
128 __versa_string<_CharT, _Traits, _Alloc, _Base>&
129 __versa_string<_CharT, _Traits, _Alloc, _Base>::
130 _M_replace(size_type __pos, size_type __len1, const _CharT* __s,
131 const size_type __len2)
133 _M_check_length(__len1, __len2, "__versa_string::_M_replace");
135 const size_type __old_size = this->size();
136 const size_type __new_size = __old_size + __len2 - __len1;
138 if (__new_size <= this->capacity() && !this->_M_is_shared())
140 _CharT* __p = this->_M_data() + __pos;
142 const size_type __how_much = __old_size - __pos - __len1;
143 if (_M_disjunct(__s))
145 if (__how_much && __len1 != __len2)
146 this->_S_move(__p + __len2, __p + __len1, __how_much);
148 this->_S_copy(__p, __s, __len2);
153 if (__len2 && __len2 <= __len1)
154 this->_S_move(__p, __s, __len2);
155 if (__how_much && __len1 != __len2)
156 this->_S_move(__p + __len2, __p + __len1, __how_much);
159 if (__s + __len2 <= __p + __len1)
160 this->_S_move(__p, __s, __len2);
161 else if (__s >= __p + __len1)
162 this->_S_copy(__p, __s + __len2 - __len1, __len2);
165 const size_type __nleft = (__p + __len1) - __s;
166 this->_S_move(__p, __s, __nleft);
167 this->_S_copy(__p + __nleft, __p + __len2,
174 this->_M_mutate(__pos, __len1, __s, __len2);
176 this->_M_set_length(__new_size);
180 template<typename _CharT, typename _Traits, typename _Alloc,
181 template <typename, typename, typename> class _Base>
182 __versa_string<_CharT, _Traits, _Alloc, _Base>
183 operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
184 const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
186 __versa_string<_CharT, _Traits, _Alloc, _Base> __str;
187 __str.reserve(__lhs.size() + __rhs.size());
193 template<typename _CharT, typename _Traits, typename _Alloc,
194 template <typename, typename, typename> class _Base>
195 __versa_string<_CharT, _Traits, _Alloc, _Base>
196 operator+(const _CharT* __lhs,
197 const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
199 __glibcxx_requires_string(__lhs);
200 typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type;
201 typedef typename __string_type::size_type __size_type;
202 const __size_type __len = _Traits::length(__lhs);
204 __str.reserve(__len + __rhs.size());
205 __str.append(__lhs, __len);
210 template<typename _CharT, typename _Traits, typename _Alloc,
211 template <typename, typename, typename> class _Base>
212 __versa_string<_CharT, _Traits, _Alloc, _Base>
213 operator+(_CharT __lhs,
214 const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
216 __versa_string<_CharT, _Traits, _Alloc, _Base> __str;
217 __str.reserve(__rhs.size() + 1);
218 __str.push_back(__lhs);
223 template<typename _CharT, typename _Traits, typename _Alloc,
224 template <typename, typename, typename> class _Base>
225 __versa_string<_CharT, _Traits, _Alloc, _Base>
226 operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
229 __glibcxx_requires_string(__rhs);
230 typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type;
231 typedef typename __string_type::size_type __size_type;
232 const __size_type __len = _Traits::length(__rhs);
234 __str.reserve(__lhs.size() + __len);
236 __str.append(__rhs, __len);
240 template<typename _CharT, typename _Traits, typename _Alloc,
241 template <typename, typename, typename> class _Base>
242 __versa_string<_CharT, _Traits, _Alloc, _Base>
243 operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
246 __versa_string<_CharT, _Traits, _Alloc, _Base> __str;
247 __str.reserve(__lhs.size() + 1);
249 __str.push_back(__rhs);
253 template<typename _CharT, typename _Traits, typename _Alloc,
254 template <typename, typename, typename> class _Base>
255 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
256 __versa_string<_CharT, _Traits, _Alloc, _Base>::
257 copy(_CharT* __s, size_type __n, size_type __pos) const
259 _M_check(__pos, "__versa_string::copy");
260 __n = _M_limit(__pos, __n);
261 __glibcxx_requires_string_len(__s, __n);
263 this->_S_copy(__s, this->_M_data() + __pos, __n);
264 // 21.3.5.7 par 3: do not append null. (good.)
268 template<typename _CharT, typename _Traits, typename _Alloc,
269 template <typename, typename, typename> class _Base>
270 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
271 __versa_string<_CharT, _Traits, _Alloc, _Base>::
272 find(const _CharT* __s, size_type __pos, size_type __n) const
274 __glibcxx_requires_string_len(__s, __n);
275 const size_type __size = this->size();
276 const _CharT* __data = this->_M_data();
279 return __pos <= __size ? __pos : npos;
283 for (; __pos <= __size - __n; ++__pos)
284 if (traits_type::eq(__data[__pos], __s[0])
285 && traits_type::compare(__data + __pos + 1,
286 __s + 1, __n - 1) == 0)
292 template<typename _CharT, typename _Traits, typename _Alloc,
293 template <typename, typename, typename> class _Base>
294 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
295 __versa_string<_CharT, _Traits, _Alloc, _Base>::
296 find(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
298 size_type __ret = npos;
299 const size_type __size = this->size();
302 const _CharT* __data = this->_M_data();
303 const size_type __n = __size - __pos;
304 const _CharT* __p = traits_type::find(__data + __pos, __n, __c);
306 __ret = __p - __data;
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 rfind(const _CharT* __s, size_type __pos, size_type __n) const
317 __glibcxx_requires_string_len(__s, __n);
318 const size_type __size = this->size();
321 __pos = std::min(size_type(__size - __n), __pos);
322 const _CharT* __data = this->_M_data();
325 if (traits_type::compare(__data + __pos, __s, __n) == 0)
333 template<typename _CharT, typename _Traits, typename _Alloc,
334 template <typename, typename, typename> class _Base>
335 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
336 __versa_string<_CharT, _Traits, _Alloc, _Base>::
337 rfind(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
339 size_type __size = this->size();
342 if (--__size > __pos)
344 for (++__size; __size-- > 0; )
345 if (traits_type::eq(this->_M_data()[__size], __c))
351 template<typename _CharT, typename _Traits, typename _Alloc,
352 template <typename, typename, typename> class _Base>
353 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
354 __versa_string<_CharT, _Traits, _Alloc, _Base>::
355 find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
357 __glibcxx_requires_string_len(__s, __n);
358 for (; __n && __pos < this->size(); ++__pos)
360 const _CharT* __p = traits_type::find(__s, __n,
361 this->_M_data()[__pos]);
368 template<typename _CharT, typename _Traits, typename _Alloc,
369 template <typename, typename, typename> class _Base>
370 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
371 __versa_string<_CharT, _Traits, _Alloc, _Base>::
372 find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
374 __glibcxx_requires_string_len(__s, __n);
375 size_type __size = this->size();
378 if (--__size > __pos)
382 if (traits_type::find(__s, __n, this->_M_data()[__size]))
385 while (__size-- != 0);
390 template<typename _CharT, typename _Traits, typename _Alloc,
391 template <typename, typename, typename> class _Base>
392 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
393 __versa_string<_CharT, _Traits, _Alloc, _Base>::
394 find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
396 __glibcxx_requires_string_len(__s, __n);
397 for (; __pos < this->size(); ++__pos)
398 if (!traits_type::find(__s, __n, this->_M_data()[__pos]))
403 template<typename _CharT, typename _Traits, typename _Alloc,
404 template <typename, typename, typename> class _Base>
405 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
406 __versa_string<_CharT, _Traits, _Alloc, _Base>::
407 find_first_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
409 for (; __pos < this->size(); ++__pos)
410 if (!traits_type::eq(this->_M_data()[__pos], __c))
415 template<typename _CharT, typename _Traits, typename _Alloc,
416 template <typename, typename, typename> class _Base>
417 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
418 __versa_string<_CharT, _Traits, _Alloc, _Base>::
419 find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
421 __glibcxx_requires_string_len(__s, __n);
422 size_type __size = this->size();
425 if (--__size > __pos)
429 if (!traits_type::find(__s, __n, this->_M_data()[__size]))
437 template<typename _CharT, typename _Traits, typename _Alloc,
438 template <typename, typename, typename> class _Base>
439 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
440 __versa_string<_CharT, _Traits, _Alloc, _Base>::
441 find_last_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
443 size_type __size = this->size();
446 if (--__size > __pos)
450 if (!traits_type::eq(this->_M_data()[__size], __c))
458 template<typename _CharT, typename _Traits, typename _Alloc,
459 template <typename, typename, typename> class _Base>
461 __versa_string<_CharT, _Traits, _Alloc, _Base>::
462 compare(size_type __pos, size_type __n, const __versa_string& __str) const
464 _M_check(__pos, "__versa_string::compare");
465 __n = _M_limit(__pos, __n);
466 const size_type __osize = __str.size();
467 const size_type __len = std::min(__n, __osize);
468 int __r = traits_type::compare(this->_M_data() + __pos,
469 __str.data(), __len);
471 __r = this->_S_compare(__n, __osize);
475 template<typename _CharT, typename _Traits, typename _Alloc,
476 template <typename, typename, typename> class _Base>
478 __versa_string<_CharT, _Traits, _Alloc, _Base>::
479 compare(size_type __pos1, size_type __n1, const __versa_string& __str,
480 size_type __pos2, size_type __n2) const
482 _M_check(__pos1, "__versa_string::compare");
483 __str._M_check(__pos2, "__versa_string::compare");
484 __n1 = _M_limit(__pos1, __n1);
485 __n2 = __str._M_limit(__pos2, __n2);
486 const size_type __len = std::min(__n1, __n2);
487 int __r = traits_type::compare(this->_M_data() + __pos1,
488 __str.data() + __pos2, __len);
490 __r = this->_S_compare(__n1, __n2);
494 template<typename _CharT, typename _Traits, typename _Alloc,
495 template <typename, typename, typename> class _Base>
497 __versa_string<_CharT, _Traits, _Alloc, _Base>::
498 compare(const _CharT* __s) const
500 __glibcxx_requires_string(__s);
501 const size_type __size = this->size();
502 const size_type __osize = traits_type::length(__s);
503 const size_type __len = std::min(__size, __osize);
504 int __r = traits_type::compare(this->_M_data(), __s, __len);
506 __r = this->_S_compare(__size, __osize);
510 template<typename _CharT, typename _Traits, typename _Alloc,
511 template <typename, typename, typename> class _Base>
513 __versa_string <_CharT, _Traits, _Alloc, _Base>::
514 compare(size_type __pos, size_type __n1, const _CharT* __s) const
516 __glibcxx_requires_string(__s);
517 _M_check(__pos, "__versa_string::compare");
518 __n1 = _M_limit(__pos, __n1);
519 const size_type __osize = traits_type::length(__s);
520 const size_type __len = std::min(__n1, __osize);
521 int __r = traits_type::compare(this->_M_data() + __pos, __s, __len);
523 __r = this->_S_compare(__n1, __osize);
527 template<typename _CharT, typename _Traits, typename _Alloc,
528 template <typename, typename, typename> class _Base>
530 __versa_string <_CharT, _Traits, _Alloc, _Base>::
531 compare(size_type __pos, size_type __n1, const _CharT* __s,
532 size_type __n2) const
534 __glibcxx_requires_string_len(__s, __n2);
535 _M_check(__pos, "__versa_string::compare");
536 __n1 = _M_limit(__pos, __n1);
537 const size_type __len = std::min(__n1, __n2);
538 int __r = traits_type::compare(this->_M_data() + __pos, __s, __len);
540 __r = this->_S_compare(__n1, __n2);
544 _GLIBCXX_END_NAMESPACE_VERSION
547 namespace std _GLIBCXX_VISIBILITY(default)
549 _GLIBCXX_BEGIN_NAMESPACE_VERSION
551 template<typename _CharT, typename _Traits, typename _Alloc,
552 template <typename, typename, typename> class _Base>
553 basic_istream<_CharT, _Traits>&
554 operator>>(basic_istream<_CharT, _Traits>& __in,
555 __gnu_cxx::__versa_string<_CharT, _Traits,
556 _Alloc, _Base>& __str)
558 typedef basic_istream<_CharT, _Traits> __istream_type;
559 typedef typename __istream_type::ios_base __ios_base;
560 typedef __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>
562 typedef typename __istream_type::int_type __int_type;
563 typedef typename __string_type::size_type __size_type;
564 typedef ctype<_CharT> __ctype_type;
565 typedef typename __ctype_type::ctype_base __ctype_base;
567 __size_type __extracted = 0;
568 typename __ios_base::iostate __err = __ios_base::goodbit;
569 typename __istream_type::sentry __cerb(__in, false);
574 // Avoid reallocation for common case.
577 __size_type __len = 0;
578 const streamsize __w = __in.width();
579 const __size_type __n = __w > 0 ? static_cast<__size_type>(__w)
581 const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
582 const __int_type __eof = _Traits::eof();
583 __int_type __c = __in.rdbuf()->sgetc();
585 while (__extracted < __n
586 && !_Traits::eq_int_type(__c, __eof)
587 && !__ct.is(__ctype_base::space,
588 _Traits::to_char_type(__c)))
590 if (__len == sizeof(__buf) / sizeof(_CharT))
592 __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
595 __buf[__len++] = _Traits::to_char_type(__c);
597 __c = __in.rdbuf()->snextc();
599 __str.append(__buf, __len);
601 if (_Traits::eq_int_type(__c, __eof))
602 __err |= __ios_base::eofbit;
605 __catch(__cxxabiv1::__forced_unwind&)
607 __in._M_setstate(__ios_base::badbit);
608 __throw_exception_again;
612 // _GLIBCXX_RESOLVE_LIB_DEFECTS
613 // 91. Description of operator>> and getline() for string<>
614 // might cause endless loop
615 __in._M_setstate(__ios_base::badbit);
618 // 211. operator>>(istream&, string&) doesn't set failbit
620 __err |= __ios_base::failbit;
622 __in.setstate(__err);
626 template<typename _CharT, typename _Traits, typename _Alloc,
627 template <typename, typename, typename> class _Base>
628 basic_istream<_CharT, _Traits>&
629 getline(basic_istream<_CharT, _Traits>& __in,
630 __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>& __str,
633 typedef basic_istream<_CharT, _Traits> __istream_type;
634 typedef typename __istream_type::ios_base __ios_base;
635 typedef __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>
637 typedef typename __istream_type::int_type __int_type;
638 typedef typename __string_type::size_type __size_type;
640 __size_type __extracted = 0;
641 const __size_type __n = __str.max_size();
642 typename __ios_base::iostate __err = __ios_base::goodbit;
643 typename __istream_type::sentry __cerb(__in, true);
648 // Avoid reallocation for common case.
651 __size_type __len = 0;
652 const __int_type __idelim = _Traits::to_int_type(__delim);
653 const __int_type __eof = _Traits::eof();
654 __int_type __c = __in.rdbuf()->sgetc();
656 while (__extracted < __n
657 && !_Traits::eq_int_type(__c, __eof)
658 && !_Traits::eq_int_type(__c, __idelim))
660 if (__len == sizeof(__buf) / sizeof(_CharT))
662 __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
665 __buf[__len++] = _Traits::to_char_type(__c);
667 __c = __in.rdbuf()->snextc();
669 __str.append(__buf, __len);
671 if (_Traits::eq_int_type(__c, __eof))
672 __err |= __ios_base::eofbit;
673 else if (_Traits::eq_int_type(__c, __idelim))
676 __in.rdbuf()->sbumpc();
679 __err |= __ios_base::failbit;
681 __catch(__cxxabiv1::__forced_unwind&)
683 __in._M_setstate(__ios_base::badbit);
684 __throw_exception_again;
688 // _GLIBCXX_RESOLVE_LIB_DEFECTS
689 // 91. Description of operator>> and getline() for string<>
690 // might cause endless loop
691 __in._M_setstate(__ios_base::badbit);
695 __err |= __ios_base::failbit;
697 __in.setstate(__err);
701 _GLIBCXX_END_NAMESPACE_VERSION
704 #endif // _VSTRING_TCC