100db7afdSDavid E. O'Brien // Components for manipulating sequences of characters -*- C++ -*-
200db7afdSDavid E. O'Brien
3f8a1b7d9SAlexander Kabaev // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4f8a1b7d9SAlexander Kabaev // 2006, 2007
500db7afdSDavid E. O'Brien // Free Software Foundation, Inc.
600db7afdSDavid E. O'Brien //
700db7afdSDavid E. O'Brien // This file is part of the GNU ISO C++ Library. This library is free
800db7afdSDavid E. O'Brien // software; you can redistribute it and/or modify it under the
900db7afdSDavid E. O'Brien // terms of the GNU General Public License as published by the
1000db7afdSDavid E. O'Brien // Free Software Foundation; either version 2, or (at your option)
1100db7afdSDavid E. O'Brien // any later version.
1200db7afdSDavid E. O'Brien
1300db7afdSDavid E. O'Brien // This library is distributed in the hope that it will be useful,
1400db7afdSDavid E. O'Brien // but WITHOUT ANY WARRANTY; without even the implied warranty of
1500db7afdSDavid E. O'Brien // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1600db7afdSDavid E. O'Brien // GNU General Public License for more details.
1700db7afdSDavid E. O'Brien
1800db7afdSDavid E. O'Brien // You should have received a copy of the GNU General Public License along
1900db7afdSDavid E. O'Brien // with this library; see the file COPYING. If not, write to the Free
20f8a1b7d9SAlexander Kabaev // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
2100db7afdSDavid E. O'Brien // USA.
2200db7afdSDavid E. O'Brien
2300db7afdSDavid E. O'Brien // As a special exception, you may use this file as part of a free software
2400db7afdSDavid E. O'Brien // library without restriction. Specifically, if other files instantiate
2500db7afdSDavid E. O'Brien // templates or use macros or inline functions from this file, or you compile
2600db7afdSDavid E. O'Brien // this file and link it with other files to produce an executable, this
2700db7afdSDavid E. O'Brien // file does not by itself cause the resulting executable to be covered by
2800db7afdSDavid E. O'Brien // the GNU General Public License. This exception does not however
2900db7afdSDavid E. O'Brien // invalidate any other reasons why the executable file might be covered by
3000db7afdSDavid E. O'Brien // the GNU General Public License.
3100db7afdSDavid E. O'Brien
32f8a1b7d9SAlexander Kabaev /** @file basic_string.tcc
33f8a1b7d9SAlexander Kabaev * This is an internal header file, included by other library headers.
34f8a1b7d9SAlexander Kabaev * You should not attempt to use it directly.
35f8a1b7d9SAlexander Kabaev */
36f8a1b7d9SAlexander Kabaev
3700db7afdSDavid E. O'Brien //
3800db7afdSDavid E. O'Brien // ISO C++ 14882: 21 Strings library
3900db7afdSDavid E. O'Brien //
4000db7afdSDavid E. O'Brien
4100db7afdSDavid E. O'Brien // Written by Jason Merrill based upon the specification by Takanori Adachi
4200db7afdSDavid E. O'Brien // in ANSI X3J16/94-0013R2. Rewritten by Nathan Myers to ISO-14882.
4300db7afdSDavid E. O'Brien
44ffeaf689SAlexander Kabaev #ifndef _BASIC_STRING_TCC
45ffeaf689SAlexander Kabaev #define _BASIC_STRING_TCC 1
4600db7afdSDavid E. O'Brien
4700db7afdSDavid E. O'Brien #pragma GCC system_header
4800db7afdSDavid E. O'Brien
_GLIBCXX_BEGIN_NAMESPACE(std)49f8a1b7d9SAlexander Kabaev _GLIBCXX_BEGIN_NAMESPACE(std)
50f8a1b7d9SAlexander Kabaev
51ffeaf689SAlexander Kabaev template<typename _Type>
52ffeaf689SAlexander Kabaev inline bool
53ffeaf689SAlexander Kabaev __is_null_pointer(_Type* __ptr)
54ffeaf689SAlexander Kabaev { return __ptr == 0; }
55ffeaf689SAlexander Kabaev
56ffeaf689SAlexander Kabaev template<typename _Type>
57ffeaf689SAlexander Kabaev inline bool
__is_null_pointer(_Type)58ffeaf689SAlexander Kabaev __is_null_pointer(_Type)
59ffeaf689SAlexander Kabaev { return false; }
60ffeaf689SAlexander Kabaev
6100db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
6200db7afdSDavid E. O'Brien const typename basic_string<_CharT, _Traits, _Alloc>::size_type
6300db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
64ffeaf689SAlexander Kabaev _Rep::_S_max_size = (((npos - sizeof(_Rep_base))/sizeof(_CharT)) - 1) / 4;
6500db7afdSDavid E. O'Brien
6600db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
6700db7afdSDavid E. O'Brien const _CharT
6800db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
6900db7afdSDavid E. O'Brien _Rep::_S_terminal = _CharT();
7000db7afdSDavid E. O'Brien
7100db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
7200db7afdSDavid E. O'Brien const typename basic_string<_CharT, _Traits, _Alloc>::size_type
7300db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::npos;
7400db7afdSDavid E. O'Brien
7500db7afdSDavid E. O'Brien // Linker sets _S_empty_rep_storage to all 0s (one reference, empty string)
7600db7afdSDavid E. O'Brien // at static init time (before static ctors are run).
7700db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
7800db7afdSDavid E. O'Brien typename basic_string<_CharT, _Traits, _Alloc>::size_type
79ffeaf689SAlexander Kabaev basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_empty_rep_storage[
80ffeaf689SAlexander Kabaev (sizeof(_Rep_base) + sizeof(_CharT) + sizeof(size_type) - 1) /
81ffeaf689SAlexander Kabaev sizeof(size_type)];
8200db7afdSDavid E. O'Brien
8300db7afdSDavid E. O'Brien // NB: This is the special case for Input Iterators, used in
8400db7afdSDavid E. O'Brien // istreambuf_iterators, etc.
8500db7afdSDavid E. O'Brien // Input Iterators have a cost structure very different from
8600db7afdSDavid E. O'Brien // pointers, calling for a different coding style.
8700db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
88ffeaf689SAlexander Kabaev template<typename _InIterator>
8900db7afdSDavid E. O'Brien _CharT*
9000db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
_S_construct(_InIterator __beg,_InIterator __end,const _Alloc & __a,input_iterator_tag)91ffeaf689SAlexander Kabaev _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,
9200db7afdSDavid E. O'Brien input_iterator_tag)
9300db7afdSDavid E. O'Brien {
94f260e61bSAlexander Kabaev #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
9500db7afdSDavid E. O'Brien if (__beg == __end && __a == _Alloc())
96ffeaf689SAlexander Kabaev return _S_empty_rep()._M_refdata();
97f260e61bSAlexander Kabaev #endif
9800db7afdSDavid E. O'Brien // Avoid reallocation for common case.
99ffeaf689SAlexander Kabaev _CharT __buf[128];
100ffeaf689SAlexander Kabaev size_type __len = 0;
101ffeaf689SAlexander Kabaev while (__beg != __end && __len < sizeof(__buf) / sizeof(_CharT))
10200db7afdSDavid E. O'Brien {
103ffeaf689SAlexander Kabaev __buf[__len++] = *__beg;
10400db7afdSDavid E. O'Brien ++__beg;
10500db7afdSDavid E. O'Brien }
106ffeaf689SAlexander Kabaev _Rep* __r = _Rep::_S_create(__len, size_type(0), __a);
107f8a1b7d9SAlexander Kabaev _M_copy(__r->_M_refdata(), __buf, __len);
10800db7afdSDavid E. O'Brien try
10900db7afdSDavid E. O'Brien {
110ffeaf689SAlexander Kabaev while (__beg != __end)
11100db7afdSDavid E. O'Brien {
112ffeaf689SAlexander Kabaev if (__len == __r->_M_capacity)
11300db7afdSDavid E. O'Brien {
11400db7afdSDavid E. O'Brien // Allocate more space.
115ffeaf689SAlexander Kabaev _Rep* __another = _Rep::_S_create(__len + 1, __len, __a);
116f8a1b7d9SAlexander Kabaev _M_copy(__another->_M_refdata(), __r->_M_refdata(), __len);
11700db7afdSDavid E. O'Brien __r->_M_destroy(__a);
11800db7afdSDavid E. O'Brien __r = __another;
119ffeaf689SAlexander Kabaev }
120ffeaf689SAlexander Kabaev __r->_M_refdata()[__len++] = *__beg;
121ffeaf689SAlexander Kabaev ++__beg;
12200db7afdSDavid E. O'Brien }
12300db7afdSDavid E. O'Brien }
12400db7afdSDavid E. O'Brien catch(...)
12500db7afdSDavid E. O'Brien {
12600db7afdSDavid E. O'Brien __r->_M_destroy(__a);
12700db7afdSDavid E. O'Brien __throw_exception_again;
12800db7afdSDavid E. O'Brien }
129f8a1b7d9SAlexander Kabaev __r->_M_set_length_and_sharable(__len);
130ffeaf689SAlexander Kabaev return __r->_M_refdata();
13100db7afdSDavid E. O'Brien }
13200db7afdSDavid E. O'Brien
13300db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
134ffeaf689SAlexander Kabaev template <typename _InIterator>
13500db7afdSDavid E. O'Brien _CharT*
13600db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
_S_construct(_InIterator __beg,_InIterator __end,const _Alloc & __a,forward_iterator_tag)137ffeaf689SAlexander Kabaev _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,
13800db7afdSDavid E. O'Brien forward_iterator_tag)
13900db7afdSDavid E. O'Brien {
140f260e61bSAlexander Kabaev #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
1418f1134fbSDavid E. O'Brien if (__beg == __end && __a == _Alloc())
142ffeaf689SAlexander Kabaev return _S_empty_rep()._M_refdata();
143f260e61bSAlexander Kabaev #endif
14400db7afdSDavid E. O'Brien // NB: Not required, but considered best practice.
145f260e61bSAlexander Kabaev if (__builtin_expect(__is_null_pointer(__beg) && __beg != __end, 0))
146ffeaf689SAlexander Kabaev __throw_logic_error(__N("basic_string::_S_construct NULL not valid"));
14700db7afdSDavid E. O'Brien
148ffeaf689SAlexander Kabaev const size_type __dnew = static_cast<size_type>(std::distance(__beg,
149ffeaf689SAlexander Kabaev __end));
15000db7afdSDavid E. O'Brien // Check for out_of_range and length_error exceptions.
151ffeaf689SAlexander Kabaev _Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a);
15200db7afdSDavid E. O'Brien try
15300db7afdSDavid E. O'Brien { _S_copy_chars(__r->_M_refdata(), __beg, __end); }
15400db7afdSDavid E. O'Brien catch(...)
15500db7afdSDavid E. O'Brien {
15600db7afdSDavid E. O'Brien __r->_M_destroy(__a);
15700db7afdSDavid E. O'Brien __throw_exception_again;
15800db7afdSDavid E. O'Brien }
159f8a1b7d9SAlexander Kabaev __r->_M_set_length_and_sharable(__dnew);
16000db7afdSDavid E. O'Brien return __r->_M_refdata();
16100db7afdSDavid E. O'Brien }
16200db7afdSDavid E. O'Brien
16300db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
16400db7afdSDavid E. O'Brien _CharT*
16500db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
_S_construct(size_type __n,_CharT __c,const _Alloc & __a)16600db7afdSDavid E. O'Brien _S_construct(size_type __n, _CharT __c, const _Alloc& __a)
16700db7afdSDavid E. O'Brien {
168f260e61bSAlexander Kabaev #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
16900db7afdSDavid E. O'Brien if (__n == 0 && __a == _Alloc())
170ffeaf689SAlexander Kabaev return _S_empty_rep()._M_refdata();
171f260e61bSAlexander Kabaev #endif
17200db7afdSDavid E. O'Brien // Check for out_of_range and length_error exceptions.
173ffeaf689SAlexander Kabaev _Rep* __r = _Rep::_S_create(__n, size_type(0), __a);
17400db7afdSDavid E. O'Brien if (__n)
175f8a1b7d9SAlexander Kabaev _M_assign(__r->_M_refdata(), __n, __c);
176ffeaf689SAlexander Kabaev
177f8a1b7d9SAlexander Kabaev __r->_M_set_length_and_sharable(__n);
17800db7afdSDavid E. O'Brien return __r->_M_refdata();
17900db7afdSDavid E. O'Brien }
18000db7afdSDavid E. O'Brien
18100db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
18200db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
basic_string(const basic_string & __str)18300db7afdSDavid E. O'Brien basic_string(const basic_string& __str)
184ffeaf689SAlexander Kabaev : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(__str.get_allocator()),
185ffeaf689SAlexander Kabaev __str.get_allocator()),
18600db7afdSDavid E. O'Brien __str.get_allocator())
18700db7afdSDavid E. O'Brien { }
18800db7afdSDavid E. O'Brien
18900db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
19000db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
basic_string(const _Alloc & __a)19100db7afdSDavid E. O'Brien basic_string(const _Alloc& __a)
19200db7afdSDavid E. O'Brien : _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a)
19300db7afdSDavid E. O'Brien { }
19400db7afdSDavid E. O'Brien
19500db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
19600db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
basic_string(const basic_string & __str,size_type __pos,size_type __n)19700db7afdSDavid E. O'Brien basic_string(const basic_string& __str, size_type __pos, size_type __n)
198ffeaf689SAlexander Kabaev : _M_dataplus(_S_construct(__str._M_data()
199ffeaf689SAlexander Kabaev + __str._M_check(__pos,
200ffeaf689SAlexander Kabaev "basic_string::basic_string"),
201ffeaf689SAlexander Kabaev __str._M_data() + __str._M_limit(__pos, __n)
202ffeaf689SAlexander Kabaev + __pos, _Alloc()), _Alloc())
20300db7afdSDavid E. O'Brien { }
20400db7afdSDavid E. O'Brien
20500db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
20600db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
basic_string(const basic_string & __str,size_type __pos,size_type __n,const _Alloc & __a)20700db7afdSDavid E. O'Brien basic_string(const basic_string& __str, size_type __pos,
20800db7afdSDavid E. O'Brien size_type __n, const _Alloc& __a)
209ffeaf689SAlexander Kabaev : _M_dataplus(_S_construct(__str._M_data()
210ffeaf689SAlexander Kabaev + __str._M_check(__pos,
211ffeaf689SAlexander Kabaev "basic_string::basic_string"),
212ffeaf689SAlexander Kabaev __str._M_data() + __str._M_limit(__pos, __n)
213ffeaf689SAlexander Kabaev + __pos, __a), __a)
21400db7afdSDavid E. O'Brien { }
21500db7afdSDavid E. O'Brien
216ffeaf689SAlexander Kabaev // TBD: DPG annotate
21700db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
21800db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
basic_string(const _CharT * __s,size_type __n,const _Alloc & __a)21900db7afdSDavid E. O'Brien basic_string(const _CharT* __s, size_type __n, const _Alloc& __a)
22000db7afdSDavid E. O'Brien : _M_dataplus(_S_construct(__s, __s + __n, __a), __a)
22100db7afdSDavid E. O'Brien { }
22200db7afdSDavid E. O'Brien
223ffeaf689SAlexander Kabaev // TBD: DPG annotate
22400db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
22500db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
basic_string(const _CharT * __s,const _Alloc & __a)22600db7afdSDavid E. O'Brien basic_string(const _CharT* __s, const _Alloc& __a)
2278f1134fbSDavid E. O'Brien : _M_dataplus(_S_construct(__s, __s ? __s + traits_type::length(__s) :
2288f1134fbSDavid E. O'Brien __s + npos, __a), __a)
22900db7afdSDavid E. O'Brien { }
23000db7afdSDavid E. O'Brien
23100db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
23200db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
basic_string(size_type __n,_CharT __c,const _Alloc & __a)23300db7afdSDavid E. O'Brien basic_string(size_type __n, _CharT __c, const _Alloc& __a)
23400db7afdSDavid E. O'Brien : _M_dataplus(_S_construct(__n, __c, __a), __a)
23500db7afdSDavid E. O'Brien { }
23600db7afdSDavid E. O'Brien
237ffeaf689SAlexander Kabaev // TBD: DPG annotate
23800db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
239ffeaf689SAlexander Kabaev template<typename _InputIterator>
24000db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
basic_string(_InputIterator __beg,_InputIterator __end,const _Alloc & __a)241ffeaf689SAlexander Kabaev basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a)
24200db7afdSDavid E. O'Brien : _M_dataplus(_S_construct(__beg, __end, __a), __a)
24300db7afdSDavid E. O'Brien { }
24400db7afdSDavid E. O'Brien
24500db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
24600db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>&
247ffeaf689SAlexander Kabaev basic_string<_CharT, _Traits, _Alloc>::
assign(const basic_string & __str)248ffeaf689SAlexander Kabaev assign(const basic_string& __str)
24900db7afdSDavid E. O'Brien {
25000db7afdSDavid E. O'Brien if (_M_rep() != __str._M_rep())
25100db7afdSDavid E. O'Brien {
25200db7afdSDavid E. O'Brien // XXX MT
253ffeaf689SAlexander Kabaev const allocator_type __a = this->get_allocator();
25400db7afdSDavid E. O'Brien _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator());
25500db7afdSDavid E. O'Brien _M_rep()->_M_dispose(__a);
25600db7afdSDavid E. O'Brien _M_data(__tmp);
25700db7afdSDavid E. O'Brien }
25800db7afdSDavid E. O'Brien return *this;
25900db7afdSDavid E. O'Brien }
26000db7afdSDavid E. O'Brien
26100db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
2621b86b14eSAlexander Kabaev basic_string<_CharT, _Traits, _Alloc>&
2631b86b14eSAlexander Kabaev basic_string<_CharT, _Traits, _Alloc>::
assign(const _CharT * __s,size_type __n)2641b86b14eSAlexander Kabaev assign(const _CharT* __s, size_type __n)
2651b86b14eSAlexander Kabaev {
266ffeaf689SAlexander Kabaev __glibcxx_requires_string_len(__s, __n);
267f8a1b7d9SAlexander Kabaev _M_check_length(this->size(), __n, "basic_string::assign");
268f8a1b7d9SAlexander Kabaev if (_M_disjunct(__s) || _M_rep()->_M_is_shared())
269ffeaf689SAlexander Kabaev return _M_replace_safe(size_type(0), this->size(), __s, __n);
2701b86b14eSAlexander Kabaev else
2711b86b14eSAlexander Kabaev {
272f8a1b7d9SAlexander Kabaev // Work in-place.
2731b86b14eSAlexander Kabaev const size_type __pos = __s - _M_data();
2741b86b14eSAlexander Kabaev if (__pos >= __n)
275f8a1b7d9SAlexander Kabaev _M_copy(_M_data(), __s, __n);
2761b86b14eSAlexander Kabaev else if (__pos)
277f8a1b7d9SAlexander Kabaev _M_move(_M_data(), __s, __n);
278f8a1b7d9SAlexander Kabaev _M_rep()->_M_set_length_and_sharable(__n);
2791b86b14eSAlexander Kabaev return *this;
2801b86b14eSAlexander Kabaev }
2811b86b14eSAlexander Kabaev }
2821b86b14eSAlexander Kabaev
2831b86b14eSAlexander Kabaev template<typename _CharT, typename _Traits, typename _Alloc>
2841b86b14eSAlexander Kabaev basic_string<_CharT, _Traits, _Alloc>&
2851b86b14eSAlexander Kabaev basic_string<_CharT, _Traits, _Alloc>::
append(size_type __n,_CharT __c)286f8a1b7d9SAlexander Kabaev append(size_type __n, _CharT __c)
287f8a1b7d9SAlexander Kabaev {
288f8a1b7d9SAlexander Kabaev if (__n)
289f8a1b7d9SAlexander Kabaev {
290f8a1b7d9SAlexander Kabaev _M_check_length(size_type(0), __n, "basic_string::append");
291f8a1b7d9SAlexander Kabaev const size_type __len = __n + this->size();
292f8a1b7d9SAlexander Kabaev if (__len > this->capacity() || _M_rep()->_M_is_shared())
293f8a1b7d9SAlexander Kabaev this->reserve(__len);
294f8a1b7d9SAlexander Kabaev _M_assign(_M_data() + this->size(), __n, __c);
295f8a1b7d9SAlexander Kabaev _M_rep()->_M_set_length_and_sharable(__len);
296f8a1b7d9SAlexander Kabaev }
297f8a1b7d9SAlexander Kabaev return *this;
298f8a1b7d9SAlexander Kabaev }
299f8a1b7d9SAlexander Kabaev
300f8a1b7d9SAlexander Kabaev template<typename _CharT, typename _Traits, typename _Alloc>
301f8a1b7d9SAlexander Kabaev basic_string<_CharT, _Traits, _Alloc>&
302f8a1b7d9SAlexander Kabaev basic_string<_CharT, _Traits, _Alloc>::
append(const _CharT * __s,size_type __n)303f8a1b7d9SAlexander Kabaev append(const _CharT* __s, size_type __n)
304f8a1b7d9SAlexander Kabaev {
305f8a1b7d9SAlexander Kabaev __glibcxx_requires_string_len(__s, __n);
306f8a1b7d9SAlexander Kabaev if (__n)
307f8a1b7d9SAlexander Kabaev {
308f8a1b7d9SAlexander Kabaev _M_check_length(size_type(0), __n, "basic_string::append");
309f8a1b7d9SAlexander Kabaev const size_type __len = __n + this->size();
310f8a1b7d9SAlexander Kabaev if (__len > this->capacity() || _M_rep()->_M_is_shared())
311f8a1b7d9SAlexander Kabaev {
312f8a1b7d9SAlexander Kabaev if (_M_disjunct(__s))
313f8a1b7d9SAlexander Kabaev this->reserve(__len);
314f8a1b7d9SAlexander Kabaev else
315f8a1b7d9SAlexander Kabaev {
316f8a1b7d9SAlexander Kabaev const size_type __off = __s - _M_data();
317f8a1b7d9SAlexander Kabaev this->reserve(__len);
318f8a1b7d9SAlexander Kabaev __s = _M_data() + __off;
319f8a1b7d9SAlexander Kabaev }
320f8a1b7d9SAlexander Kabaev }
321f8a1b7d9SAlexander Kabaev _M_copy(_M_data() + this->size(), __s, __n);
322f8a1b7d9SAlexander Kabaev _M_rep()->_M_set_length_and_sharable(__len);
323f8a1b7d9SAlexander Kabaev }
324f8a1b7d9SAlexander Kabaev return *this;
325f8a1b7d9SAlexander Kabaev }
326f8a1b7d9SAlexander Kabaev
327f8a1b7d9SAlexander Kabaev template<typename _CharT, typename _Traits, typename _Alloc>
328f8a1b7d9SAlexander Kabaev basic_string<_CharT, _Traits, _Alloc>&
329f8a1b7d9SAlexander Kabaev basic_string<_CharT, _Traits, _Alloc>::
append(const basic_string & __str)330f8a1b7d9SAlexander Kabaev append(const basic_string& __str)
331f8a1b7d9SAlexander Kabaev {
332f8a1b7d9SAlexander Kabaev const size_type __size = __str.size();
333f8a1b7d9SAlexander Kabaev if (__size)
334f8a1b7d9SAlexander Kabaev {
335f8a1b7d9SAlexander Kabaev const size_type __len = __size + this->size();
336f8a1b7d9SAlexander Kabaev if (__len > this->capacity() || _M_rep()->_M_is_shared())
337f8a1b7d9SAlexander Kabaev this->reserve(__len);
338f8a1b7d9SAlexander Kabaev _M_copy(_M_data() + this->size(), __str._M_data(), __size);
339f8a1b7d9SAlexander Kabaev _M_rep()->_M_set_length_and_sharable(__len);
340f8a1b7d9SAlexander Kabaev }
341f8a1b7d9SAlexander Kabaev return *this;
342f8a1b7d9SAlexander Kabaev }
343f8a1b7d9SAlexander Kabaev
344f8a1b7d9SAlexander Kabaev template<typename _CharT, typename _Traits, typename _Alloc>
345f8a1b7d9SAlexander Kabaev basic_string<_CharT, _Traits, _Alloc>&
346f8a1b7d9SAlexander Kabaev basic_string<_CharT, _Traits, _Alloc>::
append(const basic_string & __str,size_type __pos,size_type __n)347f8a1b7d9SAlexander Kabaev append(const basic_string& __str, size_type __pos, size_type __n)
348f8a1b7d9SAlexander Kabaev {
349f8a1b7d9SAlexander Kabaev __str._M_check(__pos, "basic_string::append");
350f8a1b7d9SAlexander Kabaev __n = __str._M_limit(__pos, __n);
351f8a1b7d9SAlexander Kabaev if (__n)
352f8a1b7d9SAlexander Kabaev {
353f8a1b7d9SAlexander Kabaev const size_type __len = __n + this->size();
354f8a1b7d9SAlexander Kabaev if (__len > this->capacity() || _M_rep()->_M_is_shared())
355f8a1b7d9SAlexander Kabaev this->reserve(__len);
356f8a1b7d9SAlexander Kabaev _M_copy(_M_data() + this->size(), __str._M_data() + __pos, __n);
357f8a1b7d9SAlexander Kabaev _M_rep()->_M_set_length_and_sharable(__len);
358f8a1b7d9SAlexander Kabaev }
359f8a1b7d9SAlexander Kabaev return *this;
360f8a1b7d9SAlexander Kabaev }
361f8a1b7d9SAlexander Kabaev
362f8a1b7d9SAlexander Kabaev template<typename _CharT, typename _Traits, typename _Alloc>
363f8a1b7d9SAlexander Kabaev basic_string<_CharT, _Traits, _Alloc>&
364f8a1b7d9SAlexander Kabaev basic_string<_CharT, _Traits, _Alloc>::
insert(size_type __pos,const _CharT * __s,size_type __n)3651b86b14eSAlexander Kabaev insert(size_type __pos, const _CharT* __s, size_type __n)
3661b86b14eSAlexander Kabaev {
367ffeaf689SAlexander Kabaev __glibcxx_requires_string_len(__s, __n);
368ffeaf689SAlexander Kabaev _M_check(__pos, "basic_string::insert");
369f8a1b7d9SAlexander Kabaev _M_check_length(size_type(0), __n, "basic_string::insert");
370f8a1b7d9SAlexander Kabaev if (_M_disjunct(__s) || _M_rep()->_M_is_shared())
371ffeaf689SAlexander Kabaev return _M_replace_safe(__pos, size_type(0), __s, __n);
3721b86b14eSAlexander Kabaev else
3731b86b14eSAlexander Kabaev {
374f8a1b7d9SAlexander Kabaev // Work in-place.
3751b86b14eSAlexander Kabaev const size_type __off = __s - _M_data();
3761b86b14eSAlexander Kabaev _M_mutate(__pos, 0, __n);
3771b86b14eSAlexander Kabaev __s = _M_data() + __off;
3781b86b14eSAlexander Kabaev _CharT* __p = _M_data() + __pos;
3791b86b14eSAlexander Kabaev if (__s + __n <= __p)
380f8a1b7d9SAlexander Kabaev _M_copy(__p, __s, __n);
3811b86b14eSAlexander Kabaev else if (__s >= __p)
382f8a1b7d9SAlexander Kabaev _M_copy(__p, __s + __n, __n);
3831b86b14eSAlexander Kabaev else
3841b86b14eSAlexander Kabaev {
385ffeaf689SAlexander Kabaev const size_type __nleft = __p - __s;
386f8a1b7d9SAlexander Kabaev _M_copy(__p, __s, __nleft);
387f8a1b7d9SAlexander Kabaev _M_copy(__p + __nleft, __p + __n, __n - __nleft);
3881b86b14eSAlexander Kabaev }
3891b86b14eSAlexander Kabaev return *this;
3901b86b14eSAlexander Kabaev }
3911b86b14eSAlexander Kabaev }
3921b86b14eSAlexander Kabaev
3931b86b14eSAlexander Kabaev template<typename _CharT, typename _Traits, typename _Alloc>
3941b86b14eSAlexander Kabaev basic_string<_CharT, _Traits, _Alloc>&
3951b86b14eSAlexander Kabaev basic_string<_CharT, _Traits, _Alloc>::
replace(size_type __pos,size_type __n1,const _CharT * __s,size_type __n2)3961b86b14eSAlexander Kabaev replace(size_type __pos, size_type __n1, const _CharT* __s,
3971b86b14eSAlexander Kabaev size_type __n2)
3981b86b14eSAlexander Kabaev {
399ffeaf689SAlexander Kabaev __glibcxx_requires_string_len(__s, __n2);
400ffeaf689SAlexander Kabaev _M_check(__pos, "basic_string::replace");
401ffeaf689SAlexander Kabaev __n1 = _M_limit(__pos, __n1);
402f8a1b7d9SAlexander Kabaev _M_check_length(__n1, __n2, "basic_string::replace");
403ffeaf689SAlexander Kabaev bool __left;
404f8a1b7d9SAlexander Kabaev if (_M_disjunct(__s) || _M_rep()->_M_is_shared())
405ffeaf689SAlexander Kabaev return _M_replace_safe(__pos, __n1, __s, __n2);
406ffeaf689SAlexander Kabaev else if ((__left = __s + __n2 <= _M_data() + __pos)
407ffeaf689SAlexander Kabaev || _M_data() + __pos + __n1 <= __s)
408ffeaf689SAlexander Kabaev {
409ffeaf689SAlexander Kabaev // Work in-place: non-overlapping case.
410f8a1b7d9SAlexander Kabaev size_type __off = __s - _M_data();
411f8a1b7d9SAlexander Kabaev __left ? __off : (__off += __n2 - __n1);
412ffeaf689SAlexander Kabaev _M_mutate(__pos, __n1, __n2);
413f8a1b7d9SAlexander Kabaev _M_copy(_M_data() + __pos, _M_data() + __off, __n2);
414ffeaf689SAlexander Kabaev return *this;
415ffeaf689SAlexander Kabaev }
416ffeaf689SAlexander Kabaev else
417ffeaf689SAlexander Kabaev {
418ffeaf689SAlexander Kabaev // Todo: overlapping case.
419ffeaf689SAlexander Kabaev const basic_string __tmp(__s, __n2);
420ffeaf689SAlexander Kabaev return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2);
421ffeaf689SAlexander Kabaev }
4221b86b14eSAlexander Kabaev }
4231b86b14eSAlexander Kabaev
4241b86b14eSAlexander Kabaev template<typename _CharT, typename _Traits, typename _Alloc>
42500db7afdSDavid E. O'Brien void
42600db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::_Rep::
_M_destroy(const _Alloc & __a)42700db7afdSDavid E. O'Brien _M_destroy(const _Alloc& __a) throw ()
42800db7afdSDavid E. O'Brien {
429ffeaf689SAlexander Kabaev const size_type __size = sizeof(_Rep_base) +
430ffeaf689SAlexander Kabaev (this->_M_capacity + 1) * sizeof(_CharT);
43100db7afdSDavid E. O'Brien _Raw_bytes_alloc(__a).deallocate(reinterpret_cast<char*>(this), __size);
43200db7afdSDavid E. O'Brien }
43300db7afdSDavid E. O'Brien
43400db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
43500db7afdSDavid E. O'Brien void
436f8a1b7d9SAlexander Kabaev basic_string<_CharT, _Traits, _Alloc>::
_M_leak_hard()437f8a1b7d9SAlexander Kabaev _M_leak_hard()
43800db7afdSDavid E. O'Brien {
439f260e61bSAlexander Kabaev #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
440ffeaf689SAlexander Kabaev if (_M_rep() == &_S_empty_rep())
441ffeaf689SAlexander Kabaev return;
442f260e61bSAlexander Kabaev #endif
44300db7afdSDavid E. O'Brien if (_M_rep()->_M_is_shared())
44400db7afdSDavid E. O'Brien _M_mutate(0, 0, 0);
44500db7afdSDavid E. O'Brien _M_rep()->_M_set_leaked();
44600db7afdSDavid E. O'Brien }
44700db7afdSDavid E. O'Brien
44800db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
44900db7afdSDavid E. O'Brien void
45000db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
_M_mutate(size_type __pos,size_type __len1,size_type __len2)45100db7afdSDavid E. O'Brien _M_mutate(size_type __pos, size_type __len1, size_type __len2)
45200db7afdSDavid E. O'Brien {
453ffeaf689SAlexander Kabaev const size_type __old_size = this->size();
45400db7afdSDavid E. O'Brien const size_type __new_size = __old_size + __len2 - __len1;
45500db7afdSDavid E. O'Brien const size_type __how_much = __old_size - __pos - __len1;
45600db7afdSDavid E. O'Brien
457f8a1b7d9SAlexander Kabaev if (__new_size > this->capacity() || _M_rep()->_M_is_shared())
45800db7afdSDavid E. O'Brien {
45900db7afdSDavid E. O'Brien // Must reallocate.
460ffeaf689SAlexander Kabaev const allocator_type __a = get_allocator();
461f8a1b7d9SAlexander Kabaev _Rep* __r = _Rep::_S_create(__new_size, this->capacity(), __a);
462ffeaf689SAlexander Kabaev
46300db7afdSDavid E. O'Brien if (__pos)
464f8a1b7d9SAlexander Kabaev _M_copy(__r->_M_refdata(), _M_data(), __pos);
46500db7afdSDavid E. O'Brien if (__how_much)
466f8a1b7d9SAlexander Kabaev _M_copy(__r->_M_refdata() + __pos + __len2,
467ffeaf689SAlexander Kabaev _M_data() + __pos + __len1, __how_much);
468ffeaf689SAlexander Kabaev
46900db7afdSDavid E. O'Brien _M_rep()->_M_dispose(__a);
47000db7afdSDavid E. O'Brien _M_data(__r->_M_refdata());
47100db7afdSDavid E. O'Brien }
47200db7afdSDavid E. O'Brien else if (__how_much && __len1 != __len2)
47300db7afdSDavid E. O'Brien {
474f8a1b7d9SAlexander Kabaev // Work in-place.
475f8a1b7d9SAlexander Kabaev _M_move(_M_data() + __pos + __len2,
476ffeaf689SAlexander Kabaev _M_data() + __pos + __len1, __how_much);
47700db7afdSDavid E. O'Brien }
478f8a1b7d9SAlexander Kabaev _M_rep()->_M_set_length_and_sharable(__new_size);
47900db7afdSDavid E. O'Brien }
48000db7afdSDavid E. O'Brien
48100db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
48200db7afdSDavid E. O'Brien void
483f8a1b7d9SAlexander Kabaev basic_string<_CharT, _Traits, _Alloc>::
reserve(size_type __res)484f8a1b7d9SAlexander Kabaev reserve(size_type __res)
48500db7afdSDavid E. O'Brien {
486ffeaf689SAlexander Kabaev if (__res != this->capacity() || _M_rep()->_M_is_shared())
48700db7afdSDavid E. O'Brien {
48800db7afdSDavid E. O'Brien // Make sure we don't shrink below the current size
48900db7afdSDavid E. O'Brien if (__res < this->size())
49000db7afdSDavid E. O'Brien __res = this->size();
491ffeaf689SAlexander Kabaev const allocator_type __a = get_allocator();
49200db7afdSDavid E. O'Brien _CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size());
49300db7afdSDavid E. O'Brien _M_rep()->_M_dispose(__a);
49400db7afdSDavid E. O'Brien _M_data(__tmp);
49500db7afdSDavid E. O'Brien }
49600db7afdSDavid E. O'Brien }
49700db7afdSDavid E. O'Brien
49800db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
499f8a1b7d9SAlexander Kabaev void
500f8a1b7d9SAlexander Kabaev basic_string<_CharT, _Traits, _Alloc>::
swap(basic_string & __s)501f8a1b7d9SAlexander Kabaev swap(basic_string& __s)
50200db7afdSDavid E. O'Brien {
50300db7afdSDavid E. O'Brien if (_M_rep()->_M_is_leaked())
50400db7afdSDavid E. O'Brien _M_rep()->_M_set_sharable();
50500db7afdSDavid E. O'Brien if (__s._M_rep()->_M_is_leaked())
50600db7afdSDavid E. O'Brien __s._M_rep()->_M_set_sharable();
50700db7afdSDavid E. O'Brien if (this->get_allocator() == __s.get_allocator())
50800db7afdSDavid E. O'Brien {
50900db7afdSDavid E. O'Brien _CharT* __tmp = _M_data();
51000db7afdSDavid E. O'Brien _M_data(__s._M_data());
51100db7afdSDavid E. O'Brien __s._M_data(__tmp);
51200db7afdSDavid E. O'Brien }
51300db7afdSDavid E. O'Brien // The code below can usually be optimized away.
51400db7afdSDavid E. O'Brien else
51500db7afdSDavid E. O'Brien {
516ffeaf689SAlexander Kabaev const basic_string __tmp1(_M_ibegin(), _M_iend(),
517ffeaf689SAlexander Kabaev __s.get_allocator());
518ffeaf689SAlexander Kabaev const basic_string __tmp2(__s._M_ibegin(), __s._M_iend(),
51900db7afdSDavid E. O'Brien this->get_allocator());
52000db7afdSDavid E. O'Brien *this = __tmp2;
52100db7afdSDavid E. O'Brien __s = __tmp1;
52200db7afdSDavid E. O'Brien }
52300db7afdSDavid E. O'Brien }
52400db7afdSDavid E. O'Brien
52500db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
52600db7afdSDavid E. O'Brien typename basic_string<_CharT, _Traits, _Alloc>::_Rep*
52700db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::_Rep::
_S_create(size_type __capacity,size_type __old_capacity,const _Alloc & __alloc)528ffeaf689SAlexander Kabaev _S_create(size_type __capacity, size_type __old_capacity,
529ffeaf689SAlexander Kabaev const _Alloc& __alloc)
53000db7afdSDavid E. O'Brien {
531ffeaf689SAlexander Kabaev // _GLIBCXX_RESOLVE_LIB_DEFECTS
53200db7afdSDavid E. O'Brien // 83. String::npos vs. string::max_size()
53300db7afdSDavid E. O'Brien if (__capacity > _S_max_size)
534ffeaf689SAlexander Kabaev __throw_length_error(__N("basic_string::_S_create"));
53500db7afdSDavid E. O'Brien
53600db7afdSDavid E. O'Brien // The standard places no restriction on allocating more memory
53700db7afdSDavid E. O'Brien // than is strictly needed within this layer at the moment or as
538ffeaf689SAlexander Kabaev // requested by an explicit application call to reserve().
539ffeaf689SAlexander Kabaev
540ffeaf689SAlexander Kabaev // Many malloc implementations perform quite poorly when an
54100db7afdSDavid E. O'Brien // application attempts to allocate memory in a stepwise fashion
54200db7afdSDavid E. O'Brien // growing each allocation size by only 1 char. Additionally,
54300db7afdSDavid E. O'Brien // it makes little sense to allocate less linear memory than the
54400db7afdSDavid E. O'Brien // natural blocking size of the malloc implementation.
54500db7afdSDavid E. O'Brien // Unfortunately, we would need a somewhat low-level calculation
54600db7afdSDavid E. O'Brien // with tuned parameters to get this perfect for any particular
54700db7afdSDavid E. O'Brien // malloc implementation. Fortunately, generalizations about
54800db7afdSDavid E. O'Brien // common features seen among implementations seems to suffice.
54900db7afdSDavid E. O'Brien
55000db7afdSDavid E. O'Brien // __pagesize need not match the actual VM page size for good
55100db7afdSDavid E. O'Brien // results in practice, thus we pick a common value on the low
55200db7afdSDavid E. O'Brien // side. __malloc_header_size is an estimate of the amount of
55300db7afdSDavid E. O'Brien // overhead per memory allocation (in practice seen N * sizeof
55400db7afdSDavid E. O'Brien // (void*) where N is 0, 2 or 4). According to folklore,
55500db7afdSDavid E. O'Brien // picking this value on the high side is better than
55600db7afdSDavid E. O'Brien // low-balling it (especially when this algorithm is used with
55700db7afdSDavid E. O'Brien // malloc implementations that allocate memory blocks rounded up
55800db7afdSDavid E. O'Brien // to a size which is a power of 2).
559f8a1b7d9SAlexander Kabaev const size_type __pagesize = 4096;
560ffeaf689SAlexander Kabaev const size_type __malloc_header_size = 4 * sizeof(void*);
561ffeaf689SAlexander Kabaev
562ffeaf689SAlexander Kabaev // The below implements an exponential growth policy, necessary to
563ffeaf689SAlexander Kabaev // meet amortized linear time requirements of the library: see
564ffeaf689SAlexander Kabaev // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html.
565ffeaf689SAlexander Kabaev // It's active for allocations requiring an amount of memory above
566ffeaf689SAlexander Kabaev // system pagesize. This is consistent with the requirements of the
567ffeaf689SAlexander Kabaev // standard: http://gcc.gnu.org/ml/libstdc++/2001-07/msg00130.html
568f8a1b7d9SAlexander Kabaev if (__capacity > __old_capacity && __capacity < 2 * __old_capacity)
569ffeaf689SAlexander Kabaev __capacity = 2 * __old_capacity;
570ffeaf689SAlexander Kabaev
571ffeaf689SAlexander Kabaev // NB: Need an array of char_type[__capacity], plus a terminating
572ffeaf689SAlexander Kabaev // null char_type() element, plus enough for the _Rep data structure.
573ffeaf689SAlexander Kabaev // Whew. Seemingly so needy, yet so elemental.
574ffeaf689SAlexander Kabaev size_type __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
575ffeaf689SAlexander Kabaev
576ffeaf689SAlexander Kabaev const size_type __adj_size = __size + __malloc_header_size;
577f8a1b7d9SAlexander Kabaev if (__adj_size > __pagesize && __capacity > __old_capacity)
57800db7afdSDavid E. O'Brien {
579ffeaf689SAlexander Kabaev const size_type __extra = __pagesize - __adj_size % __pagesize;
58000db7afdSDavid E. O'Brien __capacity += __extra / sizeof(_CharT);
581ffeaf689SAlexander Kabaev // Never allocate a string bigger than _S_max_size.
582ffeaf689SAlexander Kabaev if (__capacity > _S_max_size)
583ffeaf689SAlexander Kabaev __capacity = _S_max_size;
58400db7afdSDavid E. O'Brien __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
58500db7afdSDavid E. O'Brien }
58600db7afdSDavid E. O'Brien
58700db7afdSDavid E. O'Brien // NB: Might throw, but no worries about a leak, mate: _Rep()
58800db7afdSDavid E. O'Brien // does not throw.
58900db7afdSDavid E. O'Brien void* __place = _Raw_bytes_alloc(__alloc).allocate(__size);
59000db7afdSDavid E. O'Brien _Rep *__p = new (__place) _Rep;
59100db7afdSDavid E. O'Brien __p->_M_capacity = __capacity;
592f8a1b7d9SAlexander Kabaev // ABI compatibility - 3.4.x set in _S_create both
593f8a1b7d9SAlexander Kabaev // _M_refcount and _M_length. All callers of _S_create
594f8a1b7d9SAlexander Kabaev // in basic_string.tcc then set just _M_length.
595f8a1b7d9SAlexander Kabaev // In 4.0.x and later both _M_refcount and _M_length
596f8a1b7d9SAlexander Kabaev // are initialized in the callers, unfortunately we can
597f8a1b7d9SAlexander Kabaev // have 3.4.x compiled code with _S_create callers inlined
598f8a1b7d9SAlexander Kabaev // calling 4.0.x+ _S_create.
599f8a1b7d9SAlexander Kabaev __p->_M_set_sharable();
60000db7afdSDavid E. O'Brien return __p;
60100db7afdSDavid E. O'Brien }
60200db7afdSDavid E. O'Brien
60300db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
60400db7afdSDavid E. O'Brien _CharT*
60500db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::_Rep::
_M_clone(const _Alloc & __alloc,size_type __res)60600db7afdSDavid E. O'Brien _M_clone(const _Alloc& __alloc, size_type __res)
60700db7afdSDavid E. O'Brien {
60800db7afdSDavid E. O'Brien // Requested capacity of the clone.
609ffeaf689SAlexander Kabaev const size_type __requested_cap = this->_M_length + __res;
610ffeaf689SAlexander Kabaev _Rep* __r = _Rep::_S_create(__requested_cap, this->_M_capacity,
611ffeaf689SAlexander Kabaev __alloc);
612ffeaf689SAlexander Kabaev if (this->_M_length)
613f8a1b7d9SAlexander Kabaev _M_copy(__r->_M_refdata(), _M_refdata(), this->_M_length);
61400db7afdSDavid E. O'Brien
615f8a1b7d9SAlexander Kabaev __r->_M_set_length_and_sharable(this->_M_length);
61600db7afdSDavid E. O'Brien return __r->_M_refdata();
61700db7afdSDavid E. O'Brien }
61800db7afdSDavid E. O'Brien
61900db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
62000db7afdSDavid E. O'Brien void
621f8a1b7d9SAlexander Kabaev basic_string<_CharT, _Traits, _Alloc>::
resize(size_type __n,_CharT __c)622f8a1b7d9SAlexander Kabaev resize(size_type __n, _CharT __c)
62300db7afdSDavid E. O'Brien {
624ffeaf689SAlexander Kabaev const size_type __size = this->size();
625f8a1b7d9SAlexander Kabaev _M_check_length(__size, __n, "basic_string::resize");
62600db7afdSDavid E. O'Brien if (__size < __n)
62700db7afdSDavid E. O'Brien this->append(__n - __size, __c);
62800db7afdSDavid E. O'Brien else if (__n < __size)
62900db7afdSDavid E. O'Brien this->erase(__n);
63000db7afdSDavid E. O'Brien // else nothing (in particular, avoid calling _M_mutate() unnecessarily.)
63100db7afdSDavid E. O'Brien }
63200db7afdSDavid E. O'Brien
63300db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
634ffeaf689SAlexander Kabaev template<typename _InputIterator>
63500db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>&
63600db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
_M_replace_dispatch(iterator __i1,iterator __i2,_InputIterator __k1,_InputIterator __k2,__false_type)637ffeaf689SAlexander Kabaev _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1,
638ffeaf689SAlexander Kabaev _InputIterator __k2, __false_type)
63900db7afdSDavid E. O'Brien {
640ffeaf689SAlexander Kabaev const basic_string __s(__k1, __k2);
641ffeaf689SAlexander Kabaev const size_type __n1 = __i2 - __i1;
642f8a1b7d9SAlexander Kabaev _M_check_length(__n1, __s.size(), "basic_string::_M_replace_dispatch");
643ffeaf689SAlexander Kabaev return _M_replace_safe(__i1 - _M_ibegin(), __n1, __s._M_data(),
644ffeaf689SAlexander Kabaev __s.size());
64500db7afdSDavid E. O'Brien }
64600db7afdSDavid E. O'Brien
64700db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
64800db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>&
64900db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
_M_replace_aux(size_type __pos1,size_type __n1,size_type __n2,_CharT __c)650f8a1b7d9SAlexander Kabaev _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
651f8a1b7d9SAlexander Kabaev _CharT __c)
65200db7afdSDavid E. O'Brien {
653f8a1b7d9SAlexander Kabaev _M_check_length(__n1, __n2, "basic_string::_M_replace_aux");
654f8a1b7d9SAlexander Kabaev _M_mutate(__pos1, __n1, __n2);
655f8a1b7d9SAlexander Kabaev if (__n2)
656f8a1b7d9SAlexander Kabaev _M_assign(_M_data() + __pos1, __n2, __c);
657f8a1b7d9SAlexander Kabaev return *this;
65800db7afdSDavid E. O'Brien }
65900db7afdSDavid E. O'Brien
66000db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
66100db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>&
66200db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
_M_replace_safe(size_type __pos1,size_type __n1,const _CharT * __s,size_type __n2)663f8a1b7d9SAlexander Kabaev _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s,
664f8a1b7d9SAlexander Kabaev size_type __n2)
66500db7afdSDavid E. O'Brien {
666f8a1b7d9SAlexander Kabaev _M_mutate(__pos1, __n1, __n2);
667f8a1b7d9SAlexander Kabaev if (__n2)
668f8a1b7d9SAlexander Kabaev _M_copy(_M_data() + __pos1, __s, __n2);
669f8a1b7d9SAlexander Kabaev return *this;
67000db7afdSDavid E. O'Brien }
67100db7afdSDavid E. O'Brien
67200db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
67300db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>
operator +(const _CharT * __lhs,const basic_string<_CharT,_Traits,_Alloc> & __rhs)67400db7afdSDavid E. O'Brien operator+(const _CharT* __lhs,
67500db7afdSDavid E. O'Brien const basic_string<_CharT, _Traits, _Alloc>& __rhs)
67600db7afdSDavid E. O'Brien {
677ffeaf689SAlexander Kabaev __glibcxx_requires_string(__lhs);
67800db7afdSDavid E. O'Brien typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
67900db7afdSDavid E. O'Brien typedef typename __string_type::size_type __size_type;
680ffeaf689SAlexander Kabaev const __size_type __len = _Traits::length(__lhs);
68100db7afdSDavid E. O'Brien __string_type __str;
68200db7afdSDavid E. O'Brien __str.reserve(__len + __rhs.size());
683ffeaf689SAlexander Kabaev __str.append(__lhs, __len);
68400db7afdSDavid E. O'Brien __str.append(__rhs);
68500db7afdSDavid E. O'Brien return __str;
68600db7afdSDavid E. O'Brien }
68700db7afdSDavid E. O'Brien
68800db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
68900db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>
operator +(_CharT __lhs,const basic_string<_CharT,_Traits,_Alloc> & __rhs)69000db7afdSDavid E. O'Brien operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs)
69100db7afdSDavid E. O'Brien {
69200db7afdSDavid E. O'Brien typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
69300db7afdSDavid E. O'Brien typedef typename __string_type::size_type __size_type;
69400db7afdSDavid E. O'Brien __string_type __str;
695ffeaf689SAlexander Kabaev const __size_type __len = __rhs.size();
69600db7afdSDavid E. O'Brien __str.reserve(__len + 1);
69700db7afdSDavid E. O'Brien __str.append(__size_type(1), __lhs);
69800db7afdSDavid E. O'Brien __str.append(__rhs);
69900db7afdSDavid E. O'Brien return __str;
70000db7afdSDavid E. O'Brien }
70100db7afdSDavid E. O'Brien
70200db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
70300db7afdSDavid E. O'Brien typename basic_string<_CharT, _Traits, _Alloc>::size_type
70400db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
copy(_CharT * __s,size_type __n,size_type __pos) const70500db7afdSDavid E. O'Brien copy(_CharT* __s, size_type __n, size_type __pos) const
70600db7afdSDavid E. O'Brien {
707ffeaf689SAlexander Kabaev _M_check(__pos, "basic_string::copy");
708ffeaf689SAlexander Kabaev __n = _M_limit(__pos, __n);
709ffeaf689SAlexander Kabaev __glibcxx_requires_string_len(__s, __n);
710ffeaf689SAlexander Kabaev if (__n)
711f8a1b7d9SAlexander Kabaev _M_copy(__s, _M_data() + __pos, __n);
71200db7afdSDavid E. O'Brien // 21.3.5.7 par 3: do not append null. (good.)
71300db7afdSDavid E. O'Brien return __n;
71400db7afdSDavid E. O'Brien }
71500db7afdSDavid E. O'Brien
71600db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
71700db7afdSDavid E. O'Brien typename basic_string<_CharT, _Traits, _Alloc>::size_type
71800db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
find(const _CharT * __s,size_type __pos,size_type __n) const71900db7afdSDavid E. O'Brien find(const _CharT* __s, size_type __pos, size_type __n) const
72000db7afdSDavid E. O'Brien {
721ffeaf689SAlexander Kabaev __glibcxx_requires_string_len(__s, __n);
722ffeaf689SAlexander Kabaev const size_type __size = this->size();
72300db7afdSDavid E. O'Brien const _CharT* __data = _M_data();
724f8a1b7d9SAlexander Kabaev
725f8a1b7d9SAlexander Kabaev if (__n == 0)
726f8a1b7d9SAlexander Kabaev return __pos <= __size ? __pos : npos;
727f8a1b7d9SAlexander Kabaev
728f8a1b7d9SAlexander Kabaev if (__n <= __size)
729f8a1b7d9SAlexander Kabaev {
730f8a1b7d9SAlexander Kabaev for (; __pos <= __size - __n; ++__pos)
731f8a1b7d9SAlexander Kabaev if (traits_type::eq(__data[__pos], __s[0])
732f8a1b7d9SAlexander Kabaev && traits_type::compare(__data + __pos + 1,
733f8a1b7d9SAlexander Kabaev __s + 1, __n - 1) == 0)
734ffeaf689SAlexander Kabaev return __pos;
735f8a1b7d9SAlexander Kabaev }
73600db7afdSDavid E. O'Brien return npos;
73700db7afdSDavid E. O'Brien }
73800db7afdSDavid E. O'Brien
73900db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
74000db7afdSDavid E. O'Brien typename basic_string<_CharT, _Traits, _Alloc>::size_type
74100db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
find(_CharT __c,size_type __pos) const74200db7afdSDavid E. O'Brien find(_CharT __c, size_type __pos) const
74300db7afdSDavid E. O'Brien {
74400db7afdSDavid E. O'Brien size_type __ret = npos;
745f8a1b7d9SAlexander Kabaev const size_type __size = this->size();
74600db7afdSDavid E. O'Brien if (__pos < __size)
74700db7afdSDavid E. O'Brien {
74800db7afdSDavid E. O'Brien const _CharT* __data = _M_data();
749ffeaf689SAlexander Kabaev const size_type __n = __size - __pos;
75000db7afdSDavid E. O'Brien const _CharT* __p = traits_type::find(__data + __pos, __n, __c);
75100db7afdSDavid E. O'Brien if (__p)
75200db7afdSDavid E. O'Brien __ret = __p - __data;
75300db7afdSDavid E. O'Brien }
75400db7afdSDavid E. O'Brien return __ret;
75500db7afdSDavid E. O'Brien }
75600db7afdSDavid E. O'Brien
75700db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
75800db7afdSDavid E. O'Brien typename basic_string<_CharT, _Traits, _Alloc>::size_type
75900db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
rfind(const _CharT * __s,size_type __pos,size_type __n) const76000db7afdSDavid E. O'Brien rfind(const _CharT* __s, size_type __pos, size_type __n) const
76100db7afdSDavid E. O'Brien {
762ffeaf689SAlexander Kabaev __glibcxx_requires_string_len(__s, __n);
763ffeaf689SAlexander Kabaev const size_type __size = this->size();
76400db7afdSDavid E. O'Brien if (__n <= __size)
76500db7afdSDavid E. O'Brien {
7661b86b14eSAlexander Kabaev __pos = std::min(size_type(__size - __n), __pos);
76700db7afdSDavid E. O'Brien const _CharT* __data = _M_data();
76800db7afdSDavid E. O'Brien do
76900db7afdSDavid E. O'Brien {
77000db7afdSDavid E. O'Brien if (traits_type::compare(__data + __pos, __s, __n) == 0)
77100db7afdSDavid E. O'Brien return __pos;
77200db7afdSDavid E. O'Brien }
77300db7afdSDavid E. O'Brien while (__pos-- > 0);
77400db7afdSDavid E. O'Brien }
77500db7afdSDavid E. O'Brien return npos;
77600db7afdSDavid E. O'Brien }
77700db7afdSDavid E. O'Brien
77800db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
77900db7afdSDavid E. O'Brien typename basic_string<_CharT, _Traits, _Alloc>::size_type
78000db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
rfind(_CharT __c,size_type __pos) const78100db7afdSDavid E. O'Brien rfind(_CharT __c, size_type __pos) const
78200db7afdSDavid E. O'Brien {
78300db7afdSDavid E. O'Brien size_type __size = this->size();
78400db7afdSDavid E. O'Brien if (__size)
78500db7afdSDavid E. O'Brien {
786ffeaf689SAlexander Kabaev if (--__size > __pos)
787ffeaf689SAlexander Kabaev __size = __pos;
788ffeaf689SAlexander Kabaev for (++__size; __size-- > 0; )
789ffeaf689SAlexander Kabaev if (traits_type::eq(_M_data()[__size], __c))
790ffeaf689SAlexander Kabaev return __size;
79100db7afdSDavid E. O'Brien }
79200db7afdSDavid E. O'Brien return npos;
79300db7afdSDavid E. O'Brien }
79400db7afdSDavid E. O'Brien
79500db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
79600db7afdSDavid E. O'Brien typename basic_string<_CharT, _Traits, _Alloc>::size_type
79700db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
find_first_of(const _CharT * __s,size_type __pos,size_type __n) const79800db7afdSDavid E. O'Brien find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
79900db7afdSDavid E. O'Brien {
800ffeaf689SAlexander Kabaev __glibcxx_requires_string_len(__s, __n);
80100db7afdSDavid E. O'Brien for (; __n && __pos < this->size(); ++__pos)
80200db7afdSDavid E. O'Brien {
80300db7afdSDavid E. O'Brien const _CharT* __p = traits_type::find(__s, __n, _M_data()[__pos]);
80400db7afdSDavid E. O'Brien if (__p)
80500db7afdSDavid E. O'Brien return __pos;
80600db7afdSDavid E. O'Brien }
80700db7afdSDavid E. O'Brien return npos;
80800db7afdSDavid E. O'Brien }
80900db7afdSDavid E. O'Brien
81000db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
81100db7afdSDavid E. O'Brien typename basic_string<_CharT, _Traits, _Alloc>::size_type
81200db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
find_last_of(const _CharT * __s,size_type __pos,size_type __n) const81300db7afdSDavid E. O'Brien find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
81400db7afdSDavid E. O'Brien {
815ffeaf689SAlexander Kabaev __glibcxx_requires_string_len(__s, __n);
81600db7afdSDavid E. O'Brien size_type __size = this->size();
81700db7afdSDavid E. O'Brien if (__size && __n)
81800db7afdSDavid E. O'Brien {
81900db7afdSDavid E. O'Brien if (--__size > __pos)
82000db7afdSDavid E. O'Brien __size = __pos;
82100db7afdSDavid E. O'Brien do
82200db7afdSDavid E. O'Brien {
82300db7afdSDavid E. O'Brien if (traits_type::find(__s, __n, _M_data()[__size]))
82400db7afdSDavid E. O'Brien return __size;
82500db7afdSDavid E. O'Brien }
82600db7afdSDavid E. O'Brien while (__size-- != 0);
82700db7afdSDavid E. O'Brien }
82800db7afdSDavid E. O'Brien return npos;
82900db7afdSDavid E. O'Brien }
83000db7afdSDavid E. O'Brien
83100db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
83200db7afdSDavid E. O'Brien typename basic_string<_CharT, _Traits, _Alloc>::size_type
83300db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
find_first_not_of(const _CharT * __s,size_type __pos,size_type __n) const83400db7afdSDavid E. O'Brien find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
83500db7afdSDavid E. O'Brien {
836ffeaf689SAlexander Kabaev __glibcxx_requires_string_len(__s, __n);
837ffeaf689SAlexander Kabaev for (; __pos < this->size(); ++__pos)
838ffeaf689SAlexander Kabaev if (!traits_type::find(__s, __n, _M_data()[__pos]))
839ffeaf689SAlexander Kabaev return __pos;
84000db7afdSDavid E. O'Brien return npos;
84100db7afdSDavid E. O'Brien }
84200db7afdSDavid E. O'Brien
84300db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
84400db7afdSDavid E. O'Brien typename basic_string<_CharT, _Traits, _Alloc>::size_type
84500db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
find_first_not_of(_CharT __c,size_type __pos) const84600db7afdSDavid E. O'Brien find_first_not_of(_CharT __c, size_type __pos) const
84700db7afdSDavid E. O'Brien {
848ffeaf689SAlexander Kabaev for (; __pos < this->size(); ++__pos)
849ffeaf689SAlexander Kabaev if (!traits_type::eq(_M_data()[__pos], __c))
850ffeaf689SAlexander Kabaev return __pos;
85100db7afdSDavid E. O'Brien return npos;
85200db7afdSDavid E. O'Brien }
85300db7afdSDavid E. O'Brien
85400db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
85500db7afdSDavid E. O'Brien typename basic_string<_CharT, _Traits, _Alloc>::size_type
85600db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
find_last_not_of(const _CharT * __s,size_type __pos,size_type __n) const85700db7afdSDavid E. O'Brien find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
85800db7afdSDavid E. O'Brien {
859ffeaf689SAlexander Kabaev __glibcxx_requires_string_len(__s, __n);
86000db7afdSDavid E. O'Brien size_type __size = this->size();
86100db7afdSDavid E. O'Brien if (__size)
86200db7afdSDavid E. O'Brien {
86300db7afdSDavid E. O'Brien if (--__size > __pos)
86400db7afdSDavid E. O'Brien __size = __pos;
86500db7afdSDavid E. O'Brien do
86600db7afdSDavid E. O'Brien {
86700db7afdSDavid E. O'Brien if (!traits_type::find(__s, __n, _M_data()[__size]))
86800db7afdSDavid E. O'Brien return __size;
86900db7afdSDavid E. O'Brien }
87000db7afdSDavid E. O'Brien while (__size--);
87100db7afdSDavid E. O'Brien }
87200db7afdSDavid E. O'Brien return npos;
87300db7afdSDavid E. O'Brien }
87400db7afdSDavid E. O'Brien
87500db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
87600db7afdSDavid E. O'Brien typename basic_string<_CharT, _Traits, _Alloc>::size_type
87700db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
find_last_not_of(_CharT __c,size_type __pos) const87800db7afdSDavid E. O'Brien find_last_not_of(_CharT __c, size_type __pos) const
87900db7afdSDavid E. O'Brien {
88000db7afdSDavid E. O'Brien size_type __size = this->size();
88100db7afdSDavid E. O'Brien if (__size)
88200db7afdSDavid E. O'Brien {
88300db7afdSDavid E. O'Brien if (--__size > __pos)
88400db7afdSDavid E. O'Brien __size = __pos;
88500db7afdSDavid E. O'Brien do
88600db7afdSDavid E. O'Brien {
88700db7afdSDavid E. O'Brien if (!traits_type::eq(_M_data()[__size], __c))
88800db7afdSDavid E. O'Brien return __size;
88900db7afdSDavid E. O'Brien }
89000db7afdSDavid E. O'Brien while (__size--);
89100db7afdSDavid E. O'Brien }
89200db7afdSDavid E. O'Brien return npos;
89300db7afdSDavid E. O'Brien }
89400db7afdSDavid E. O'Brien
89500db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
89600db7afdSDavid E. O'Brien int
89700db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
compare(size_type __pos,size_type __n,const basic_string & __str) const89800db7afdSDavid E. O'Brien compare(size_type __pos, size_type __n, const basic_string& __str) const
89900db7afdSDavid E. O'Brien {
900ffeaf689SAlexander Kabaev _M_check(__pos, "basic_string::compare");
901ffeaf689SAlexander Kabaev __n = _M_limit(__pos, __n);
902ffeaf689SAlexander Kabaev const size_type __osize = __str.size();
903ffeaf689SAlexander Kabaev const size_type __len = std::min(__n, __osize);
90400db7afdSDavid E. O'Brien int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len);
90500db7afdSDavid E. O'Brien if (!__r)
906*096464d3SPedro F. Giffuni __r = _S_compare(__n, __osize);
90700db7afdSDavid E. O'Brien return __r;
90800db7afdSDavid E. O'Brien }
90900db7afdSDavid E. O'Brien
91000db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
91100db7afdSDavid E. O'Brien int
91200db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
compare(size_type __pos1,size_type __n1,const basic_string & __str,size_type __pos2,size_type __n2) const91300db7afdSDavid E. O'Brien compare(size_type __pos1, size_type __n1, const basic_string& __str,
91400db7afdSDavid E. O'Brien size_type __pos2, size_type __n2) const
91500db7afdSDavid E. O'Brien {
916ffeaf689SAlexander Kabaev _M_check(__pos1, "basic_string::compare");
917ffeaf689SAlexander Kabaev __str._M_check(__pos2, "basic_string::compare");
918ffeaf689SAlexander Kabaev __n1 = _M_limit(__pos1, __n1);
919ffeaf689SAlexander Kabaev __n2 = __str._M_limit(__pos2, __n2);
920ffeaf689SAlexander Kabaev const size_type __len = std::min(__n1, __n2);
92100db7afdSDavid E. O'Brien int __r = traits_type::compare(_M_data() + __pos1,
92200db7afdSDavid E. O'Brien __str.data() + __pos2, __len);
92300db7afdSDavid E. O'Brien if (!__r)
924*096464d3SPedro F. Giffuni __r = _S_compare(__n1, __n2);
92500db7afdSDavid E. O'Brien return __r;
92600db7afdSDavid E. O'Brien }
92700db7afdSDavid E. O'Brien
92800db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
92900db7afdSDavid E. O'Brien int
93000db7afdSDavid E. O'Brien basic_string<_CharT, _Traits, _Alloc>::
compare(const _CharT * __s) const93100db7afdSDavid E. O'Brien compare(const _CharT* __s) const
93200db7afdSDavid E. O'Brien {
933ffeaf689SAlexander Kabaev __glibcxx_requires_string(__s);
934ffeaf689SAlexander Kabaev const size_type __size = this->size();
935ffeaf689SAlexander Kabaev const size_type __osize = traits_type::length(__s);
936ffeaf689SAlexander Kabaev const size_type __len = std::min(__size, __osize);
9378f1134fbSDavid E. O'Brien int __r = traits_type::compare(_M_data(), __s, __len);
93800db7afdSDavid E. O'Brien if (!__r)
939*096464d3SPedro F. Giffuni __r = _S_compare(__size, __osize);
94000db7afdSDavid E. O'Brien return __r;
94100db7afdSDavid E. O'Brien }
94200db7afdSDavid E. O'Brien
94300db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
94400db7afdSDavid E. O'Brien int
94500db7afdSDavid E. O'Brien basic_string <_CharT, _Traits, _Alloc>::
compare(size_type __pos,size_type __n1,const _CharT * __s) const94600db7afdSDavid E. O'Brien compare(size_type __pos, size_type __n1, const _CharT* __s) const
94700db7afdSDavid E. O'Brien {
948ffeaf689SAlexander Kabaev __glibcxx_requires_string(__s);
949ffeaf689SAlexander Kabaev _M_check(__pos, "basic_string::compare");
950ffeaf689SAlexander Kabaev __n1 = _M_limit(__pos, __n1);
951ffeaf689SAlexander Kabaev const size_type __osize = traits_type::length(__s);
952ffeaf689SAlexander Kabaev const size_type __len = std::min(__n1, __osize);
95300db7afdSDavid E. O'Brien int __r = traits_type::compare(_M_data() + __pos, __s, __len);
95400db7afdSDavid E. O'Brien if (!__r)
955*096464d3SPedro F. Giffuni __r = _S_compare(__n1, __osize);
95600db7afdSDavid E. O'Brien return __r;
95700db7afdSDavid E. O'Brien }
95800db7afdSDavid E. O'Brien
95900db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits, typename _Alloc>
96000db7afdSDavid E. O'Brien int
96100db7afdSDavid E. O'Brien basic_string <_CharT, _Traits, _Alloc>::
compare(size_type __pos,size_type __n1,const _CharT * __s,size_type __n2) const96200db7afdSDavid E. O'Brien compare(size_type __pos, size_type __n1, const _CharT* __s,
96300db7afdSDavid E. O'Brien size_type __n2) const
96400db7afdSDavid E. O'Brien {
965ffeaf689SAlexander Kabaev __glibcxx_requires_string_len(__s, __n2);
966ffeaf689SAlexander Kabaev _M_check(__pos, "basic_string::compare");
967ffeaf689SAlexander Kabaev __n1 = _M_limit(__pos, __n1);
968ffeaf689SAlexander Kabaev const size_type __len = std::min(__n1, __n2);
96900db7afdSDavid E. O'Brien int __r = traits_type::compare(_M_data() + __pos, __s, __len);
97000db7afdSDavid E. O'Brien if (!__r)
971*096464d3SPedro F. Giffuni __r = _S_compare(__n1, __n2);
97200db7afdSDavid E. O'Brien return __r;
97300db7afdSDavid E. O'Brien }
97400db7afdSDavid E. O'Brien
97500db7afdSDavid E. O'Brien // Inhibit implicit instantiations for required instantiations,
97600db7afdSDavid E. O'Brien // which are defined via explicit instantiations elsewhere.
97700db7afdSDavid E. O'Brien // NB: This syntax is a GNU extension.
978ffeaf689SAlexander Kabaev #if _GLIBCXX_EXTERN_TEMPLATE
97900db7afdSDavid E. O'Brien extern template class basic_string<char>;
98000db7afdSDavid E. O'Brien extern template
98100db7afdSDavid E. O'Brien basic_istream<char>&
98200db7afdSDavid E. O'Brien operator>>(basic_istream<char>&, string&);
98300db7afdSDavid E. O'Brien extern template
98400db7afdSDavid E. O'Brien basic_ostream<char>&
98500db7afdSDavid E. O'Brien operator<<(basic_ostream<char>&, const string&);
98600db7afdSDavid E. O'Brien extern template
98700db7afdSDavid E. O'Brien basic_istream<char>&
98800db7afdSDavid E. O'Brien getline(basic_istream<char>&, string&, char);
98900db7afdSDavid E. O'Brien extern template
99000db7afdSDavid E. O'Brien basic_istream<char>&
99100db7afdSDavid E. O'Brien getline(basic_istream<char>&, string&);
99200db7afdSDavid E. O'Brien
993ffeaf689SAlexander Kabaev #ifdef _GLIBCXX_USE_WCHAR_T
99400db7afdSDavid E. O'Brien extern template class basic_string<wchar_t>;
99500db7afdSDavid E. O'Brien extern template
99600db7afdSDavid E. O'Brien basic_istream<wchar_t>&
99700db7afdSDavid E. O'Brien operator>>(basic_istream<wchar_t>&, wstring&);
99800db7afdSDavid E. O'Brien extern template
99900db7afdSDavid E. O'Brien basic_ostream<wchar_t>&
100000db7afdSDavid E. O'Brien operator<<(basic_ostream<wchar_t>&, const wstring&);
100100db7afdSDavid E. O'Brien extern template
100200db7afdSDavid E. O'Brien basic_istream<wchar_t>&
100300db7afdSDavid E. O'Brien getline(basic_istream<wchar_t>&, wstring&, wchar_t);
100400db7afdSDavid E. O'Brien extern template
100500db7afdSDavid E. O'Brien basic_istream<wchar_t>&
100600db7afdSDavid E. O'Brien getline(basic_istream<wchar_t>&, wstring&);
10078f1134fbSDavid E. O'Brien #endif
10081b86b14eSAlexander Kabaev #endif
1009f8a1b7d9SAlexander Kabaev
1010f8a1b7d9SAlexander Kabaev _GLIBCXX_END_NAMESPACE
101100db7afdSDavid E. O'Brien
101200db7afdSDavid E. O'Brien #endif
1013