1 // Versatile string -*- C++ -*-
3 // Copyright (C) 2005-2016 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/cxxabi_forced.h>
37 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
39 _GLIBCXX_BEGIN_NAMESPACE_VERSION
41 template<typename _CharT, typename _Traits, typename _Alloc,
42 template <typename, typename, typename> class _Base>
43 const typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
44 __versa_string<_CharT, _Traits, _Alloc, _Base>::npos;
46 template<typename _CharT, typename _Traits, typename _Alloc,
47 template <typename, typename, typename> class _Base>
49 __versa_string<_CharT, _Traits, _Alloc, _Base>::
50 resize(size_type __n, _CharT __c)
52 const size_type __size = this->size();
54 this->append(__n - __size, __c);
55 else if (__n < __size)
56 this->_M_erase(__n, __size - __n);
59 template<typename _CharT, typename _Traits, typename _Alloc,
60 template <typename, typename, typename> class _Base>
61 __versa_string<_CharT, _Traits, _Alloc, _Base>&
62 __versa_string<_CharT, _Traits, _Alloc, _Base>::
63 _M_append(const _CharT* __s, size_type __n)
65 const size_type __len = __n + this->size();
67 if (__len <= this->capacity() && !this->_M_is_shared())
70 this->_S_copy(this->_M_data() + this->size(), __s, __n);
73 this->_M_mutate(this->size(), size_type(0), __s, __n);
75 this->_M_set_length(__len);
79 template<typename _CharT, typename _Traits, typename _Alloc,
80 template <typename, typename, typename> class _Base>
81 template<typename _InputIterator>
82 __versa_string<_CharT, _Traits, _Alloc, _Base>&
83 __versa_string<_CharT, _Traits, _Alloc, _Base>::
84 _M_replace_dispatch(const_iterator __i1, const_iterator __i2,
85 _InputIterator __k1, _InputIterator __k2,
88 const __versa_string __s(__k1, __k2);
89 const size_type __n1 = __i2 - __i1;
90 return _M_replace(__i1 - _M_ibegin(), __n1, __s._M_data(),
94 template<typename _CharT, typename _Traits, typename _Alloc,
95 template <typename, typename, typename> class _Base>
96 __versa_string<_CharT, _Traits, _Alloc, _Base>&
97 __versa_string<_CharT, _Traits, _Alloc, _Base>::
98 _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
101 _M_check_length(__n1, __n2, "__versa_string::_M_replace_aux");
103 const size_type __old_size = this->size();
104 const size_type __new_size = __old_size + __n2 - __n1;
106 if (__new_size <= this->capacity() && !this->_M_is_shared())
108 _CharT* __p = this->_M_data() + __pos1;
110 const size_type __how_much = __old_size - __pos1 - __n1;
111 if (__how_much && __n1 != __n2)
112 this->_S_move(__p + __n2, __p + __n1, __how_much);
115 this->_M_mutate(__pos1, __n1, 0, __n2);
118 this->_S_assign(this->_M_data() + __pos1, __n2, __c);
120 this->_M_set_length(__new_size);
124 template<typename _CharT, typename _Traits, typename _Alloc,
125 template <typename, typename, typename> class _Base>
126 __versa_string<_CharT, _Traits, _Alloc, _Base>&
127 __versa_string<_CharT, _Traits, _Alloc, _Base>::
128 _M_replace(size_type __pos, size_type __len1, const _CharT* __s,
129 const size_type __len2)
131 _M_check_length(__len1, __len2, "__versa_string::_M_replace");
133 const size_type __old_size = this->size();
134 const size_type __new_size = __old_size + __len2 - __len1;
136 if (__new_size <= this->capacity() && !this->_M_is_shared())
138 _CharT* __p = this->_M_data() + __pos;
140 const size_type __how_much = __old_size - __pos - __len1;
141 if (_M_disjunct(__s))
143 if (__how_much && __len1 != __len2)
144 this->_S_move(__p + __len2, __p + __len1, __how_much);
146 this->_S_copy(__p, __s, __len2);
151 if (__len2 && __len2 <= __len1)
152 this->_S_move(__p, __s, __len2);
153 if (__how_much && __len1 != __len2)
154 this->_S_move(__p + __len2, __p + __len1, __how_much);
157 if (__s + __len2 <= __p + __len1)
158 this->_S_move(__p, __s, __len2);
159 else if (__s >= __p + __len1)
160 this->_S_copy(__p, __s + __len2 - __len1, __len2);
163 const size_type __nleft = (__p + __len1) - __s;
164 this->_S_move(__p, __s, __nleft);
165 this->_S_copy(__p + __nleft, __p + __len2,
172 this->_M_mutate(__pos, __len1, __s, __len2);
174 this->_M_set_length(__new_size);
178 template<typename _CharT, typename _Traits, typename _Alloc,
179 template <typename, typename, typename> class _Base>
180 __versa_string<_CharT, _Traits, _Alloc, _Base>
181 operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
182 const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
184 __versa_string<_CharT, _Traits, _Alloc, _Base> __str;
185 __str.reserve(__lhs.size() + __rhs.size());
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 _CharT* __lhs,
195 const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
197 __glibcxx_requires_string(__lhs);
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(__lhs);
202 __str.reserve(__len + __rhs.size());
203 __str.append(__lhs, __len);
208 template<typename _CharT, typename _Traits, typename _Alloc,
209 template <typename, typename, typename> class _Base>
210 __versa_string<_CharT, _Traits, _Alloc, _Base>
211 operator+(_CharT __lhs,
212 const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
214 __versa_string<_CharT, _Traits, _Alloc, _Base> __str;
215 __str.reserve(__rhs.size() + 1);
216 __str.push_back(__lhs);
221 template<typename _CharT, typename _Traits, typename _Alloc,
222 template <typename, typename, typename> class _Base>
223 __versa_string<_CharT, _Traits, _Alloc, _Base>
224 operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
227 __glibcxx_requires_string(__rhs);
228 typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type;
229 typedef typename __string_type::size_type __size_type;
230 const __size_type __len = _Traits::length(__rhs);
232 __str.reserve(__lhs.size() + __len);
234 __str.append(__rhs, __len);
238 template<typename _CharT, typename _Traits, typename _Alloc,
239 template <typename, typename, typename> class _Base>
240 __versa_string<_CharT, _Traits, _Alloc, _Base>
241 operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
244 __versa_string<_CharT, _Traits, _Alloc, _Base> __str;
245 __str.reserve(__lhs.size() + 1);
247 __str.push_back(__rhs);
251 template<typename _CharT, typename _Traits, typename _Alloc,
252 template <typename, typename, typename> class _Base>
253 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
254 __versa_string<_CharT, _Traits, _Alloc, _Base>::
255 copy(_CharT* __s, size_type __n, size_type __pos) const
257 _M_check(__pos, "__versa_string::copy");
258 __n = _M_limit(__pos, __n);
259 __glibcxx_requires_string_len(__s, __n);
261 this->_S_copy(__s, this->_M_data() + __pos, __n);
262 // 21.3.5.7 par 3: do not append null. (good.)
266 template<typename _CharT, typename _Traits, typename _Alloc,
267 template <typename, typename, typename> class _Base>
268 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
269 __versa_string<_CharT, _Traits, _Alloc, _Base>::
270 find(const _CharT* __s, size_type __pos, size_type __n) const
272 __glibcxx_requires_string_len(__s, __n);
273 const size_type __size = this->size();
274 const _CharT* __data = this->_M_data();
277 return __pos <= __size ? __pos : npos;
281 for (; __pos <= __size - __n; ++__pos)
282 if (traits_type::eq(__data[__pos], __s[0])
283 && traits_type::compare(__data + __pos + 1,
284 __s + 1, __n - 1) == 0)
290 template<typename _CharT, typename _Traits, typename _Alloc,
291 template <typename, typename, typename> class _Base>
292 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
293 __versa_string<_CharT, _Traits, _Alloc, _Base>::
294 find(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
296 size_type __ret = npos;
297 const size_type __size = this->size();
300 const _CharT* __data = this->_M_data();
301 const size_type __n = __size - __pos;
302 const _CharT* __p = traits_type::find(__data + __pos, __n, __c);
304 __ret = __p - __data;
309 template<typename _CharT, typename _Traits, typename _Alloc,
310 template <typename, typename, typename> class _Base>
311 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
312 __versa_string<_CharT, _Traits, _Alloc, _Base>::
313 rfind(const _CharT* __s, size_type __pos, size_type __n) const
315 __glibcxx_requires_string_len(__s, __n);
316 const size_type __size = this->size();
319 __pos = std::min(size_type(__size - __n), __pos);
320 const _CharT* __data = this->_M_data();
323 if (traits_type::compare(__data + __pos, __s, __n) == 0)
331 template<typename _CharT, typename _Traits, typename _Alloc,
332 template <typename, typename, typename> class _Base>
333 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
334 __versa_string<_CharT, _Traits, _Alloc, _Base>::
335 rfind(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
337 size_type __size = this->size();
340 if (--__size > __pos)
342 for (++__size; __size-- > 0; )
343 if (traits_type::eq(this->_M_data()[__size], __c))
349 template<typename _CharT, typename _Traits, typename _Alloc,
350 template <typename, typename, typename> class _Base>
351 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
352 __versa_string<_CharT, _Traits, _Alloc, _Base>::
353 find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
355 __glibcxx_requires_string_len(__s, __n);
356 for (; __n && __pos < this->size(); ++__pos)
358 const _CharT* __p = traits_type::find(__s, __n,
359 this->_M_data()[__pos]);
366 template<typename _CharT, typename _Traits, typename _Alloc,
367 template <typename, typename, typename> class _Base>
368 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
369 __versa_string<_CharT, _Traits, _Alloc, _Base>::
370 find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
372 __glibcxx_requires_string_len(__s, __n);
373 size_type __size = this->size();
376 if (--__size > __pos)
380 if (traits_type::find(__s, __n, this->_M_data()[__size]))
383 while (__size-- != 0);
388 template<typename _CharT, typename _Traits, typename _Alloc,
389 template <typename, typename, typename> class _Base>
390 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
391 __versa_string<_CharT, _Traits, _Alloc, _Base>::
392 find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
394 __glibcxx_requires_string_len(__s, __n);
395 for (; __pos < this->size(); ++__pos)
396 if (!traits_type::find(__s, __n, this->_M_data()[__pos]))
401 template<typename _CharT, typename _Traits, typename _Alloc,
402 template <typename, typename, typename> class _Base>
403 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
404 __versa_string<_CharT, _Traits, _Alloc, _Base>::
405 find_first_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
407 for (; __pos < this->size(); ++__pos)
408 if (!traits_type::eq(this->_M_data()[__pos], __c))
413 template<typename _CharT, typename _Traits, typename _Alloc,
414 template <typename, typename, typename> class _Base>
415 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
416 __versa_string<_CharT, _Traits, _Alloc, _Base>::
417 find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
419 __glibcxx_requires_string_len(__s, __n);
420 size_type __size = this->size();
423 if (--__size > __pos)
427 if (!traits_type::find(__s, __n, this->_M_data()[__size]))
435 template<typename _CharT, typename _Traits, typename _Alloc,
436 template <typename, typename, typename> class _Base>
437 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type
438 __versa_string<_CharT, _Traits, _Alloc, _Base>::
439 find_last_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
441 size_type __size = this->size();
444 if (--__size > __pos)
448 if (!traits_type::eq(this->_M_data()[__size], __c))
456 template<typename _CharT, typename _Traits, typename _Alloc,
457 template <typename, typename, typename> class _Base>
459 __versa_string<_CharT, _Traits, _Alloc, _Base>::
460 compare(size_type __pos, size_type __n, const __versa_string& __str) const
462 _M_check(__pos, "__versa_string::compare");
463 __n = _M_limit(__pos, __n);
464 const size_type __osize = __str.size();
465 const size_type __len = std::min(__n, __osize);
466 int __r = traits_type::compare(this->_M_data() + __pos,
467 __str.data(), __len);
469 __r = this->_S_compare(__n, __osize);
473 template<typename _CharT, typename _Traits, typename _Alloc,
474 template <typename, typename, typename> class _Base>
476 __versa_string<_CharT, _Traits, _Alloc, _Base>::
477 compare(size_type __pos1, size_type __n1, const __versa_string& __str,
478 size_type __pos2, size_type __n2) const
480 _M_check(__pos1, "__versa_string::compare");
481 __str._M_check(__pos2, "__versa_string::compare");
482 __n1 = _M_limit(__pos1, __n1);
483 __n2 = __str._M_limit(__pos2, __n2);
484 const size_type __len = std::min(__n1, __n2);
485 int __r = traits_type::compare(this->_M_data() + __pos1,
486 __str.data() + __pos2, __len);
488 __r = this->_S_compare(__n1, __n2);
492 template<typename _CharT, typename _Traits, typename _Alloc,
493 template <typename, typename, typename> class _Base>
495 __versa_string<_CharT, _Traits, _Alloc, _Base>::
496 compare(const _CharT* __s) const
498 __glibcxx_requires_string(__s);
499 const size_type __size = this->size();
500 const size_type __osize = traits_type::length(__s);
501 const size_type __len = std::min(__size, __osize);
502 int __r = traits_type::compare(this->_M_data(), __s, __len);
504 __r = this->_S_compare(__size, __osize);
508 template<typename _CharT, typename _Traits, typename _Alloc,
509 template <typename, typename, typename> class _Base>
511 __versa_string <_CharT, _Traits, _Alloc, _Base>::
512 compare(size_type __pos, size_type __n1, const _CharT* __s) const
514 __glibcxx_requires_string(__s);
515 _M_check(__pos, "__versa_string::compare");
516 __n1 = _M_limit(__pos, __n1);
517 const size_type __osize = traits_type::length(__s);
518 const size_type __len = std::min(__n1, __osize);
519 int __r = traits_type::compare(this->_M_data() + __pos, __s, __len);
521 __r = this->_S_compare(__n1, __osize);
525 template<typename _CharT, typename _Traits, typename _Alloc,
526 template <typename, typename, typename> class _Base>
528 __versa_string <_CharT, _Traits, _Alloc, _Base>::
529 compare(size_type __pos, size_type __n1, const _CharT* __s,
530 size_type __n2) const
532 __glibcxx_requires_string_len(__s, __n2);
533 _M_check(__pos, "__versa_string::compare");
534 __n1 = _M_limit(__pos, __n1);
535 const size_type __len = std::min(__n1, __n2);
536 int __r = traits_type::compare(this->_M_data() + __pos, __s, __len);
538 __r = this->_S_compare(__n1, __n2);
542 _GLIBCXX_END_NAMESPACE_VERSION
545 namespace std _GLIBCXX_VISIBILITY(default)
547 _GLIBCXX_BEGIN_NAMESPACE_VERSION
549 template<typename _CharT, typename _Traits, typename _Alloc,
550 template <typename, typename, typename> class _Base>
551 basic_istream<_CharT, _Traits>&
552 operator>>(basic_istream<_CharT, _Traits>& __in,
553 __gnu_cxx::__versa_string<_CharT, _Traits,
554 _Alloc, _Base>& __str)
556 typedef basic_istream<_CharT, _Traits> __istream_type;
557 typedef typename __istream_type::ios_base __ios_base;
558 typedef __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>
560 typedef typename __istream_type::int_type __int_type;
561 typedef typename __string_type::size_type __size_type;
562 typedef ctype<_CharT> __ctype_type;
563 typedef typename __ctype_type::ctype_base __ctype_base;
565 __size_type __extracted = 0;
566 typename __ios_base::iostate __err = __ios_base::goodbit;
567 typename __istream_type::sentry __cerb(__in, false);
572 // Avoid reallocation for common case.
575 __size_type __len = 0;
576 const streamsize __w = __in.width();
577 const __size_type __n = __w > 0 ? static_cast<__size_type>(__w)
579 const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
580 const __int_type __eof = _Traits::eof();
581 __int_type __c = __in.rdbuf()->sgetc();
583 while (__extracted < __n
584 && !_Traits::eq_int_type(__c, __eof)
585 && !__ct.is(__ctype_base::space,
586 _Traits::to_char_type(__c)))
588 if (__len == sizeof(__buf) / sizeof(_CharT))
590 __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
593 __buf[__len++] = _Traits::to_char_type(__c);
595 __c = __in.rdbuf()->snextc();
597 __str.append(__buf, __len);
599 if (_Traits::eq_int_type(__c, __eof))
600 __err |= __ios_base::eofbit;
603 __catch(__cxxabiv1::__forced_unwind&)
605 __in._M_setstate(__ios_base::badbit);
606 __throw_exception_again;
610 // _GLIBCXX_RESOLVE_LIB_DEFECTS
611 // 91. Description of operator>> and getline() for string<>
612 // might cause endless loop
613 __in._M_setstate(__ios_base::badbit);
616 // 211. operator>>(istream&, string&) doesn't set failbit
618 __err |= __ios_base::failbit;
620 __in.setstate(__err);
624 template<typename _CharT, typename _Traits, typename _Alloc,
625 template <typename, typename, typename> class _Base>
626 basic_istream<_CharT, _Traits>&
627 getline(basic_istream<_CharT, _Traits>& __in,
628 __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>& __str,
631 typedef basic_istream<_CharT, _Traits> __istream_type;
632 typedef typename __istream_type::ios_base __ios_base;
633 typedef __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>
635 typedef typename __istream_type::int_type __int_type;
636 typedef typename __string_type::size_type __size_type;
638 __size_type __extracted = 0;
639 const __size_type __n = __str.max_size();
640 typename __ios_base::iostate __err = __ios_base::goodbit;
641 typename __istream_type::sentry __cerb(__in, true);
646 // Avoid reallocation for common case.
649 __size_type __len = 0;
650 const __int_type __idelim = _Traits::to_int_type(__delim);
651 const __int_type __eof = _Traits::eof();
652 __int_type __c = __in.rdbuf()->sgetc();
654 while (__extracted < __n
655 && !_Traits::eq_int_type(__c, __eof)
656 && !_Traits::eq_int_type(__c, __idelim))
658 if (__len == sizeof(__buf) / sizeof(_CharT))
660 __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
663 __buf[__len++] = _Traits::to_char_type(__c);
665 __c = __in.rdbuf()->snextc();
667 __str.append(__buf, __len);
669 if (_Traits::eq_int_type(__c, __eof))
670 __err |= __ios_base::eofbit;
671 else if (_Traits::eq_int_type(__c, __idelim))
674 __in.rdbuf()->sbumpc();
677 __err |= __ios_base::failbit;
679 __catch(__cxxabiv1::__forced_unwind&)
681 __in._M_setstate(__ios_base::badbit);
682 __throw_exception_again;
686 // _GLIBCXX_RESOLVE_LIB_DEFECTS
687 // 91. Description of operator>> and getline() for string<>
688 // might cause endless loop
689 __in._M_setstate(__ios_base::badbit);
693 __err |= __ios_base::failbit;
695 __in.setstate(__err);
699 _GLIBCXX_END_NAMESPACE_VERSION
702 #endif // _VSTRING_TCC