1 // Components for manipulating sequences of characters -*- C++ -*-
3 // Copyright (C) 2000, 1999, 1998, 1997 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 2, 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 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING. If not, write to the Free
18 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
31 // ISO C++ 14882: 21 Strings library
34 // This file is included by <string>. It is not meant to be included
37 // Written by Jason Merrill based upon the specification by Takanori Adachi
38 // in ANSI X3J16/94-0013R2. Rewritten by Nathan Myers to ISO-14882.
40 #ifndef _CPP_BITS_STRING_TCC
41 #define _CPP_BITS_STRING_TCC 1
46 template<typename _CharT, typename _Traits, typename _Alloc>
48 basic_string<_CharT, _Traits, _Alloc>::
49 _Rep::_S_terminal = _CharT();
51 template<typename _CharT, typename _Traits, typename _Alloc>
52 basic_string<_CharT, _Traits, _Alloc>::size_type
53 basic_string<_CharT, _Traits, _Alloc>::
54 _Rep::_S_max_size = (((npos - sizeof(_Rep))/sizeof(_CharT)) - 1) / 4;
56 // NB: This is the special case for Input Iterators, used in
57 // istreambuf_iterators, etc.
58 // Input Iterators have a cost structure very different from
59 // pointers, calling for a different coding style.
60 template<typename _CharT, typename _Traits, typename _Alloc>
61 template<typename _InIter>
63 basic_string<_CharT, _Traits, _Alloc>::
64 _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a,
67 if (__beg == __end && __a == _Alloc())
68 return _S_empty_rep()._M_refcopy();
69 // Avoid reallocation for common case.
72 while (__beg != __end && __i < sizeof(__buf) / sizeof(_CharT))
74 __buf[__i++] = *__beg;
77 _Rep* __r = _Rep::_S_create(__i, __a);
78 traits_type::copy(__r->_M_refdata(), __buf, __i);
81 // NB: this loop looks precisely this way because
82 // it avoids comparing __beg != __end any more
83 // than strictly necessary; != might be expensive!
86 _CharT* __p = __r->_M_refdata() + __r->_M_length;
87 _CharT* __last = __r->_M_refdata() + __r->_M_capacity;
92 __r->_M_length = __p - __r->_M_refdata();
93 *__p = _Rep::_S_terminal; // grrr.
94 return __r->_M_refdata();
101 // Allocate more space.
102 size_type __len = __p - __r->_M_refdata();
103 _Rep* __another = _Rep::_S_create(__len + 1, __a);
104 traits_type::copy(__another->_M_refdata(),
105 __r->_M_refdata(), __len);
106 __r->_M_destroy(__a);
108 __r->_M_length = __len;
112 __r->_M_destroy(__a);
118 template<typename _CharT, typename _Traits, typename _Alloc>
119 template <class _InIter>
121 basic_string<_CharT,_Traits,_Alloc>::
122 _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a,
123 forward_iterator_tag)
125 size_type __dnew = static_cast<size_type>(distance(__beg, __end));
127 if (__beg == __end && __a == _Alloc())
128 return _S_empty_rep()._M_refcopy();
130 // Check for out_of_range and length_error exceptions.
131 _Rep* __r = _Rep::_S_create(__dnew, __a);
133 _S_copy_chars(__r->_M_refdata(), __beg, __end);
136 __r->_M_destroy(__a);
139 __r->_M_length = __dnew;
141 __r->_M_refdata()[__dnew] = _Rep::_S_terminal; // grrr.
142 return __r->_M_refdata();
145 template<typename _CharT, typename _Traits, typename _Alloc>
147 basic_string<_CharT,_Traits, _Alloc>::
148 _S_construct(size_type __n, _CharT __c, const _Alloc& __a)
150 if (__n == 0 && __a == _Alloc())
151 return _S_empty_rep()._M_refcopy();
153 // Check for out_of_range and length_error exceptions.
154 _Rep* __r = _Rep::_S_create(__n, __a);
157 traits_type::assign(__r->_M_refdata(), __n, __c);
160 __r->_M_destroy(__a);
163 __r->_M_length = __n;
164 __r->_M_refdata()[__n] = _Rep::_S_terminal; // grrr
165 return __r->_M_refdata();
168 template<typename _CharT, typename _Traits, typename _Alloc>
169 basic_string<_CharT, _Traits, _Alloc>::
170 basic_string(const basic_string& __str)
171 : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(), __str.get_allocator()),
172 __str.get_allocator())
175 template<typename _CharT, typename _Traits, typename _Alloc>
176 basic_string<_CharT, _Traits, _Alloc>::
177 basic_string(const _Alloc& __a)
178 : _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a)
181 template<typename _CharT, typename _Traits, typename _Alloc>
182 basic_string<_CharT, _Traits, _Alloc>::
183 basic_string(const basic_string& __str, size_type __pos, size_type __n)
184 : _M_dataplus(_S_construct(__str._M_check(__pos),
185 __str._M_fold(__pos, __n), _Alloc()), _Alloc())
188 template<typename _CharT, typename _Traits, typename _Alloc>
189 basic_string<_CharT, _Traits, _Alloc>::
190 basic_string(const basic_string& __str, size_type __pos,
191 size_type __n, const _Alloc& __a)
192 : _M_dataplus(_S_construct(__str._M_check(__pos),
193 __str._M_fold(__pos, __n), __a), __a)
196 template<typename _CharT, typename _Traits, typename _Alloc>
197 basic_string<_CharT, _Traits, _Alloc>::
198 basic_string(const _CharT* __s, size_type __n, const _Alloc& __a)
199 : _M_dataplus(_S_construct(__s, __s + __n, __a), __a)
202 template<typename _CharT, typename _Traits, typename _Alloc>
203 basic_string<_CharT, _Traits, _Alloc>::
204 basic_string(const _CharT* __s, const _Alloc& __a)
205 : _M_dataplus(_S_construct(__s, __s + traits_type::length(__s), __a), __a)
208 template<typename _CharT, typename _Traits, typename _Alloc>
209 basic_string<_CharT, _Traits, _Alloc>::
210 basic_string(size_type __n, _CharT __c, const _Alloc& __a)
211 : _M_dataplus(_S_construct(__n, __c, __a), __a)
214 template<typename _CharT, typename _Traits, typename _Alloc>
215 template<typename _InputIter>
216 basic_string<_CharT, _Traits, _Alloc>::
217 basic_string(_InputIter __beg, _InputIter __end, const _Alloc& __a)
218 : _M_dataplus(_S_construct(__beg, __end, __a), __a)
221 template<typename _CharT, typename _Traits, typename _Alloc>
222 basic_string<_CharT, _Traits, _Alloc>&
223 basic_string<_CharT, _Traits, _Alloc>::assign(const basic_string& __str)
225 if (_M_rep() != __str._M_rep())
228 allocator_type __a = this->get_allocator();
229 _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator());
230 _M_rep()->_M_dispose(__a);
236 template<typename _CharT, typename _Traits, typename _Alloc>
238 basic_string<_CharT, _Traits, _Alloc>::_Rep::
239 _M_destroy(const _Alloc& __a) throw ()
241 size_type __size = sizeof(_Rep) + (_M_capacity + 1) * sizeof(_CharT);
242 _Raw_bytes_alloc(__a).deallocate(reinterpret_cast<char*>(this), __size);
245 template<typename _CharT, typename _Traits, typename _Alloc>
247 basic_string<_CharT, _Traits, _Alloc>::_M_leak_hard()
249 if (_M_rep()->_M_is_shared())
251 _M_rep()->_M_set_leaked();
254 template<typename _CharT, typename _Traits, typename _Alloc>
256 basic_string<_CharT, _Traits, _Alloc>::
257 _M_mutate(size_type __pos, size_type __len1, size_type __len2)
259 size_type __old_size = this->size();
260 const size_type __new_size = __old_size + __len2 - __len1;
261 const _CharT* __src = _M_data() + __pos + __len1;
262 const size_type __how_much = __old_size - __pos - __len1;
264 if (_M_rep()->_M_is_shared() || __new_size > capacity())
267 allocator_type __a = get_allocator();
268 _Rep* __r = _Rep::_S_create(__new_size, __a);
271 traits_type::copy(__r->_M_refdata(), _M_data(), __pos);
273 traits_type::copy(__r->_M_refdata() + __pos + __len2,
277 __r->_M_dispose(get_allocator());
280 _M_rep()->_M_dispose(__a);
281 _M_data(__r->_M_refdata());
286 traits_type::move(_M_data() + __pos + __len2, __src, __how_much);
288 _M_rep()->_M_set_sharable();
289 _M_rep()->_M_length = __new_size;
290 _M_data()[__new_size] = _Rep::_S_terminal; // grrr. (per 21.3.4)
291 // You cannot leave those LWG people alone for a second.
294 template<typename _CharT, typename _Traits, typename _Alloc>
296 basic_string<_CharT, _Traits, _Alloc>::reserve(size_type __res)
298 if (__res > this->capacity() || _M_rep()->_M_is_shared())
300 __LENGTHERROR(__res > this->max_size());
301 allocator_type __a = get_allocator();
302 _CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size());
303 _M_rep()->_M_dispose(__a);
308 template<typename _CharT, typename _Traits, typename _Alloc>
309 void basic_string<_CharT, _Traits, _Alloc>::swap(basic_string& __s)
311 if (_M_rep()->_M_is_leaked())
312 _M_rep()->_M_set_sharable();
313 if (__s._M_rep()->_M_is_leaked())
314 __s._M_rep()->_M_set_sharable();
315 if (this->get_allocator() == __s.get_allocator())
317 _CharT* __tmp = _M_data();
318 _M_data(__s._M_data());
321 // The code below can usually be optimized away.
324 basic_string __tmp1(_M_ibegin(), _M_iend(), __s.get_allocator());
325 basic_string __tmp2(__s._M_ibegin(), __s._M_iend(),
326 this->get_allocator());
332 #ifdef _GLIBCPP_ALLOC_CONTROL
333 template<typename _CharT, typename _Traits, typename _Alloc>
334 bool (*basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_excess_slop)
336 basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_default_excess;
339 template<typename _CharT, typename _Traits, typename _Alloc>
340 basic_string<_CharT, _Traits, _Alloc>::_Rep*
341 basic_string<_CharT, _Traits, _Alloc>::_Rep::
342 _S_create(size_t __capacity, const _Alloc& __alloc)
344 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
345 // 83. String::npos vs. string::max_size()
346 typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
347 __LENGTHERROR(__capacity > _S_max_size);
349 __LENGTHERROR(__capacity == npos);
352 // NB: Need an array of char_type[__capacity], plus a
353 // terminating null char_type() element, plus enough for the
354 // _Rep data structure. Whew. Seemingly so needy, yet so elemental.
355 size_t __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
356 // NB: Might throw, but no worries about a leak, mate: _Rep()
358 void* __place = _Raw_bytes_alloc(__alloc).allocate(__size);
359 _Rep *__p = new (__place) _Rep;
360 __p->_M_capacity = __capacity;
361 __p->_M_set_sharable(); // one reference
366 template<typename _CharT, typename _Traits, typename _Alloc>
368 basic_string<_CharT, _Traits, _Alloc>::_Rep::
369 _M_clone(const _Alloc& __alloc, size_type __res)
371 _Rep* __r = _Rep::_S_create(_M_length + __res, __alloc);
375 traits_type::copy(__r->_M_refdata(), _M_refdata(), _M_length);
378 __r->_M_destroy(__alloc);
382 __r->_M_length = _M_length;
383 return __r->_M_refdata();
386 template<typename _CharT, typename _Traits, typename _Alloc>
388 #ifdef _GLIBCPP_ALLOC_CONTROL
389 basic_string<_CharT, _Traits, _Alloc>::_Rep::
390 _S_default_excess(size_t __s, size_t __r)
392 basic_string<_CharT, _Traits, _Alloc>::_Rep::
393 _S_excess_slop(size_t __s, size_t __r)
396 return 2 * (__s <= 16 ? 16 : __s) < __r;
399 // Linker sets _S_empty_rep_storage to all 0s (one reference, empty string)
400 // at static init time (before static ctors are run).
401 template<typename _CharT, typename _Traits, typename _Alloc>
402 typename _Alloc::size_type
403 basic_string<_CharT, _Traits, _Alloc>::_S_empty_rep_storage[
404 (sizeof(_Rep) + sizeof(_CharT) + sizeof(size_type) - 1)/sizeof(size_type)];
406 template<typename _CharT, typename _Traits, typename _Alloc>
408 basic_string<_CharT, _Traits, _Alloc>::resize(size_type __n, _CharT __c)
410 __LENGTHERROR(__n > max_size());
411 size_type __size = this->size();
413 this->append(__n - __size, __c);
414 else if (__n < __size)
416 // else nothing (in particular, avoid calling _M_mutate() unnecessarily.)
419 template<typename _CharT, typename _Traits, typename _Alloc>
420 template<typename _InputIter>
421 basic_string<_CharT, _Traits, _Alloc>&
422 basic_string<_CharT, _Traits, _Alloc>::
423 _M_replace(iterator __i1, iterator __i2, _InputIter __j1,
424 _InputIter __j2, input_iterator_tag)
426 basic_string __s(__j1, __j2);
427 return this->replace(__i1, __i2, __s._M_ibegin(), __s._M_iend());
430 template<typename _CharT, typename _Traits, typename _Alloc>
431 template<typename _ForwardIter>
432 basic_string<_CharT, _Traits, _Alloc>&
433 basic_string<_CharT, _Traits, _Alloc>::
434 _M_replace(iterator __i1, iterator __i2, _ForwardIter __j1,
435 _ForwardIter __j2, forward_iterator_tag)
437 size_type __dold = __i2 - __i1;
438 size_type __dmax = this->max_size();
439 size_type __dnew = static_cast<size_type>(distance(__j1, __j2));
441 __LENGTHERROR(__dmax <= __dnew);
442 size_type __off = __i1 - _M_ibegin();
443 _M_mutate(__off, __dold, __dnew);
444 // Invalidated __i1, __i2
446 _S_copy_chars(_M_data() + __off, __j1, __j2);
451 template<typename _CharT, typename _Traits, typename _Alloc>
452 basic_string<_CharT, _Traits, _Alloc>&
453 basic_string<_CharT, _Traits, _Alloc>::
454 replace(size_type __pos1, size_type __n1, const basic_string& __str,
455 size_type __pos2, size_type __n2)
457 return this->replace(_M_check(__pos1), _M_fold(__pos1, __n1),
458 __str._M_check(__pos2),
459 __str._M_fold(__pos2, __n2));
462 template<typename _CharT, typename _Traits, typename _Alloc>
463 basic_string<_CharT,_Traits,_Alloc>&
464 basic_string<_CharT,_Traits,_Alloc>::
465 append(const basic_string& __str)
467 // Iff appending itself, string needs to pre-reserve the
468 // correct size so that _M_mutate does not clobber the
469 // iterators formed here.
470 size_type __size = __str.size();
471 size_type __len = __size + this->size();
472 if (__len > this->capacity())
473 this->reserve(__len);
474 return this->replace(_M_iend(), _M_iend(), __str._M_ibegin(),
478 template<typename _CharT, typename _Traits, typename _Alloc>
479 basic_string<_CharT,_Traits,_Alloc>&
480 basic_string<_CharT,_Traits,_Alloc>::
481 append(const basic_string& __str, size_type __pos, size_type __n)
483 // Iff appending itself, string needs to pre-reserve the
484 // correct size so that _M_mutate does not clobber the
485 // iterators formed here.
486 size_type __len = min(__str.size() - __pos, __n) + this->size();
487 if (__len > this->capacity())
488 this->reserve(__len);
489 return this->replace(_M_iend(), _M_iend(), __str._M_check(__pos),
490 __str._M_fold(__pos, __n));
493 template<typename _CharT, typename _Traits, typename _Alloc>
494 basic_string<_CharT,_Traits,_Alloc>&
495 basic_string<_CharT,_Traits,_Alloc>::
496 append(const _CharT* __s, size_type __n)
498 size_type __len = __n + this->size();
499 if (__len > this->capacity())
500 this->reserve(__len);
501 return this->replace(_M_iend(), _M_iend(), __s, __s + __n);
504 template<typename _CharT, typename _Traits, typename _Alloc>
505 basic_string<_CharT,_Traits,_Alloc>&
506 basic_string<_CharT,_Traits,_Alloc>::
507 append(size_type __n, _CharT __c)
509 size_type __len = __n + this->size();
510 if (__len > this->capacity())
511 this->reserve(__len);
512 return this->replace(_M_iend(), _M_iend(), __n, __c);
515 template<typename _CharT, typename _Traits, typename _Alloc>
516 basic_string<_CharT,_Traits,_Alloc>
517 operator+(const _CharT* __lhs,
518 const basic_string<_CharT,_Traits,_Alloc>& __rhs)
520 typedef basic_string<_CharT,_Traits,_Alloc> __string_type;
521 __string_type::size_type __len = _Traits::length(__lhs);
523 __str.reserve(__len + __rhs.size());
524 __str.append(__lhs, __lhs + __len);
529 template<typename _CharT, typename _Traits, typename _Alloc>
530 basic_string<_CharT,_Traits,_Alloc>
531 operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs)
533 typedef basic_string<_CharT,_Traits,_Alloc> __string_type;
535 __string_type::size_type __len = __rhs.size();
536 __str.reserve(__len + 1);
537 __str.append(__string_type::size_type(1), __lhs);
544 template<typename _CharT, typename _Traits, typename _Alloc>
545 basic_string<_CharT, _Traits, _Alloc>&
546 basic_string<_CharT, _Traits, _Alloc>::
547 replace(iterator __i1, iterator __i2, size_type __n2, _CharT __c)
549 size_type __n1 = __i2 - __i1;
550 size_type __off1 = __i1 - _M_ibegin();
551 __LENGTHERROR(max_size() - (this->size() - __n1) <= __n2);
552 _M_mutate (__off1, __n1, __n2);
553 // Invalidated __i1, __i2
555 traits_type::assign(_M_data() + __off1, __n2, __c);
560 template<typename _CharT, typename _Traits, typename _Alloc>
561 basic_string<_CharT, _Traits, _Alloc>::size_type
562 basic_string<_CharT, _Traits, _Alloc>::
563 copy(_CharT* __s, size_type __n, size_type __pos) const
565 __OUTOFRANGE(__pos > this->size());
567 if (__n > this->size() - __pos)
568 __n = this->size() - __pos;
570 traits_type::copy(__s, _M_data() + __pos, __n);
571 // 21.3.5.7 par 3: do not append null. (good.)
576 // NB: This is specialized for the standard char_traits<char>
577 // specialization to use the same optimizations as strchr.
578 template<typename _CharT, typename _Traits, typename _Alloc>
580 basic_string<_CharT, _Traits, _Alloc>::
581 _S_find(const _CharT* __beg, const _CharT* __end, _CharT __c)
583 return find_if(__beg, __end, _Char_traits_match<_CharT, _Traits>(__c));
586 // Specialization for char, definitions in src/string-inst.cc.
589 string::_S_find(const char* __beg, const char* __end, char __c);
591 // Specialization for wchar_t.
592 #ifdef _GLIBCPP_USE_WCHAR_T
595 wstring::_S_find(const wchar_t* __beg, const wchar_t* __end, wchar_t __c);
598 template<typename _CharT, typename _Traits, typename _Alloc>
599 basic_string<_CharT, _Traits, _Alloc>::size_type
600 basic_string<_CharT, _Traits, _Alloc>::
601 find(const _CharT* __s, size_type __pos, size_type __n) const
603 size_t __xpos = __pos;
604 const _CharT* __data = _M_data();
605 for (; __xpos + __n <= this->size(); ++__xpos)
606 if (traits_type::eq(__data[__xpos], *__s)
607 && traits_type::compare(__data + __xpos, __s, __n) == 0)
612 template<typename _CharT, typename _Traits, typename _Alloc>
613 basic_string<_CharT, _Traits, _Alloc>::size_type
614 basic_string<_CharT, _Traits, _Alloc>::
615 find(_CharT __c, size_type __pos) const
617 size_type __size = this->size();
618 size_type __retval = npos;
621 const _CharT* __data = _M_data();
622 const _CharT* __end = __data + __size;
623 const _CharT* __p = _S_find(__data + __pos, __end, __c);
625 __retval = __p - __data;
631 template<typename _CharT, typename _Traits, typename _Alloc>
632 basic_string<_CharT, _Traits, _Alloc>::size_type
633 basic_string<_CharT, _Traits, _Alloc>::
634 rfind(const _CharT* __s, size_type __pos, size_type __n) const
636 size_type __size = this->size();
639 size_t __xpos = __size - __n;
643 for (++__xpos; __xpos-- > 0; )
644 if (traits_type::eq(_M_data()[__xpos], *__s)
645 && traits_type::compare(_M_data() + __xpos, __s, __n) == 0)
651 template<typename _CharT, typename _Traits, typename _Alloc>
652 basic_string<_CharT, _Traits, _Alloc>::size_type
653 basic_string<_CharT, _Traits, _Alloc>::
654 rfind(_CharT __c, size_type __pos) const
656 size_type __size = this->size();
659 size_t __xpos = __size - 1;
663 for (++__xpos; __xpos-- > 0; )
664 if (traits_type::eq(_M_data()[__xpos], __c))
670 template<typename _CharT, typename _Traits, typename _Alloc>
671 basic_string<_CharT, _Traits, _Alloc>::size_type
672 basic_string<_CharT, _Traits, _Alloc>::
673 find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
675 const _CharT* __end = __s + __n;
676 for (; __n && __pos < this->size(); ++__pos)
678 const _CharT* __p = _S_find(__s, __end, _M_data()[__pos]);
685 template<typename _CharT, typename _Traits, typename _Alloc>
686 basic_string<_CharT, _Traits, _Alloc>::size_type
687 basic_string<_CharT, _Traits, _Alloc>::
688 find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
690 size_type __size = this->size();
693 if (--__size > __pos)
697 const _CharT* __p = _S_find(__s, __s + __n, _M_data()[__size]);
698 if (__p != __s + __n)
701 while (__size-- != 0);
706 template<typename _CharT, typename _Traits, typename _Alloc>
707 basic_string<_CharT, _Traits, _Alloc>::size_type
708 basic_string<_CharT, _Traits, _Alloc>::
709 find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
711 size_t __xpos = __pos;
712 for (; __n && __xpos < this->size(); ++__xpos)
713 if (_S_find(__s, __s + __n, _M_data()[__xpos]) == __s + __n)
718 template<typename _CharT, typename _Traits, typename _Alloc>
719 basic_string<_CharT, _Traits, _Alloc>::size_type
720 basic_string<_CharT, _Traits, _Alloc>::
721 find_first_not_of(_CharT __c, size_type __pos) const
723 size_t __xpos = __pos;
724 for (; __xpos < size(); ++__xpos)
725 if (!traits_type::eq(_M_data()[__xpos], __c))
730 template<typename _CharT, typename _Traits, typename _Alloc>
731 basic_string<_CharT, _Traits, _Alloc>::size_type
732 basic_string<_CharT, _Traits, _Alloc>::
733 find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
735 size_type __size = this->size();
738 if (--__size > __pos)
742 if (_S_find(__s, __s + __n, _M_data()[__size]) == __s + __n)
750 template<typename _CharT, typename _Traits, typename _Alloc>
751 basic_string<_CharT, _Traits, _Alloc>::size_type
752 basic_string<_CharT, _Traits, _Alloc>::
753 find_last_not_of(_CharT __c, size_type __pos) const
755 size_type __size = this->size();
758 if (--__size > __pos)
762 if (!traits_type::eq(_M_data()[__size], __c))
770 template<typename _CharT, typename _Traits, typename _Alloc>
772 basic_string<_CharT, _Traits, _Alloc>::
773 compare(size_type __pos, size_type __n, const basic_string& __str) const
775 size_type __size = this->size();
776 size_type __osize = __str.size();
777 __OUTOFRANGE(__pos > __size);
779 size_type __rsize= min(__size - __pos, __n);
780 size_type __len = min(__rsize, __osize);
781 int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len);
783 __r = __rsize - __osize;
787 template<typename _CharT, typename _Traits, typename _Alloc>
789 basic_string<_CharT, _Traits, _Alloc>::
790 compare(size_type __pos1, size_type __n1, const basic_string& __str,
791 size_type __pos2, size_type __n2) const
793 size_type __size = this->size();
794 size_type __osize = __str.size();
795 __OUTOFRANGE(__pos1 > __size);
796 __OUTOFRANGE(__pos2 > __osize);
798 size_type __rsize = min(__size - __pos1, __n1);
799 size_type __rosize = min(__osize - __pos2, __n2);
800 size_type __len = min(__rsize, __rosize);
801 int __r = traits_type::compare(_M_data() + __pos1,
802 __str.data() + __pos2, __len);
804 __r = __rsize - __rosize;
809 template<typename _CharT, typename _Traits, typename _Alloc>
811 basic_string<_CharT, _Traits, _Alloc>::
812 compare(const _CharT* __s) const
814 size_type __size = this->size();
815 int __r = traits_type::compare(_M_data(), __s, __size);
817 __r = __size - traits_type::length(__s);
822 template<typename _CharT, typename _Traits, typename _Alloc>
824 basic_string <_CharT,_Traits,_Alloc>::
825 compare(size_type __pos, size_type __n1, const _CharT* __s,
826 size_type __n2) const
828 size_type __size = this->size();
829 __OUTOFRANGE(__pos > __size);
831 size_type __osize = min(traits_type::length(__s), __n2);
832 size_type __rsize = min(__size - __pos, __n1);
833 size_type __len = min(__rsize, __osize);
834 int __r = traits_type::compare(_M_data() + __pos, __s, __len);
836 __r = __rsize - __osize;
840 template <class _CharT, class _Traits, class _Alloc>
842 _S_string_copy(const basic_string<_CharT, _Traits, _Alloc>& __str,
843 _CharT* __buf, typename _Alloc::size_type __bufsiz)
845 typedef typename _Alloc::size_type size_type;
846 size_type __strsize = __str.size();
847 size_type __bytes = min(__strsize, __bufsiz - 1);
848 _Traits::copy(__buf, __str.data(), __bytes);
849 __buf[__bytes] = _CharT();
854 #endif /* _CPP_BITS_STRING_TCC */