]>
Commit | Line | Data |
---|---|---|
725dc051 BK |
1 | // Components for manipulating sequences of characters -*- C++ -*- |
2 | ||
9c96a689 | 3 | // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 |
c68cd521 | 4 | // Free Software Foundation, Inc. |
725dc051 BK |
5 | // |
6 | // This file is part of the GNU ISO C++ Library. This library is free | |
7 | // software; you can redistribute it and/or modify it under the | |
8 | // terms of the GNU General Public License as published by the | |
9 | // Free Software Foundation; either version 2, or (at your option) | |
10 | // any later version. | |
11 | ||
12 | // This library is distributed in the hope that it will be useful, | |
13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | // GNU General Public License for more details. | |
16 | ||
17 | // You should have received a copy of the GNU General Public License along | |
18 | // with this library; see the file COPYING. If not, write to the Free | |
19 | // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, | |
20 | // USA. | |
21 | ||
22 | // As a special exception, you may use this file as part of a free software | |
23 | // library without restriction. Specifically, if other files instantiate | |
24 | // templates or use macros or inline functions from this file, or you compile | |
25 | // this file and link it with other files to produce an executable, this | |
26 | // file does not by itself cause the resulting executable to be covered by | |
27 | // the GNU General Public License. This exception does not however | |
28 | // invalidate any other reasons why the executable file might be covered by | |
29 | // the GNU General Public License. | |
30 | ||
31 | // | |
32 | // ISO C++ 14882: 21 Strings library | |
33 | // | |
34 | ||
35 | // This file is included by <string>. It is not meant to be included | |
36 | // separately. | |
37 | ||
38 | // Written by Jason Merrill based upon the specification by Takanori Adachi | |
39 | // in ANSI X3J16/94-0013R2. Rewritten by Nathan Myers to ISO-14882. | |
40 | ||
3d7c150e BK |
41 | #ifndef _BASIC_STRING_TCC |
42 | #define _BASIC_STRING_TCC 1 | |
725dc051 | 43 | |
3b794528 BK |
44 | #pragma GCC system_header |
45 | ||
725dc051 BK |
46 | namespace std |
47 | { | |
285b36d6 BK |
48 | template<typename _Type> |
49 | inline bool | |
50 | __is_null_pointer(_Type* __ptr) | |
51 | { return __ptr == 0; } | |
52 | ||
53 | template<typename _Type> | |
54 | inline bool | |
1b80d64a | 55 | __is_null_pointer(_Type) |
285b36d6 BK |
56 | { return false; } |
57 | ||
725dc051 | 58 | template<typename _CharT, typename _Traits, typename _Alloc> |
ed6814f7 | 59 | const typename basic_string<_CharT, _Traits, _Alloc>::size_type |
725dc051 | 60 | basic_string<_CharT, _Traits, _Alloc>:: |
ca566e4c | 61 | _Rep::_S_max_size = (((npos - sizeof(_Rep_base))/sizeof(_CharT)) - 1) / 4; |
725dc051 BK |
62 | |
63 | template<typename _CharT, typename _Traits, typename _Alloc> | |
ed6814f7 | 64 | const _CharT |
725dc051 | 65 | basic_string<_CharT, _Traits, _Alloc>:: |
00532602 | 66 | _Rep::_S_terminal = _CharT(); |
725dc051 BK |
67 | |
68 | template<typename _CharT, typename _Traits, typename _Alloc> | |
4f12dd3c | 69 | const typename basic_string<_CharT, _Traits, _Alloc>::size_type |
725dc051 BK |
70 | basic_string<_CharT, _Traits, _Alloc>::npos; |
71 | ||
72 | // Linker sets _S_empty_rep_storage to all 0s (one reference, empty string) | |
73 | // at static init time (before static ctors are run). | |
74 | template<typename _CharT, typename _Traits, typename _Alloc> | |
4f12dd3c | 75 | typename basic_string<_CharT, _Traits, _Alloc>::size_type |
ca566e4c NM |
76 | basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_empty_rep_storage[ |
77 | (sizeof(_Rep_base) + sizeof(_CharT) + sizeof(size_type) - 1) / | |
78 | sizeof(size_type)]; | |
725dc051 BK |
79 | |
80 | // NB: This is the special case for Input Iterators, used in | |
81 | // istreambuf_iterators, etc. | |
82 | // Input Iterators have a cost structure very different from | |
83 | // pointers, calling for a different coding style. | |
84 | template<typename _CharT, typename _Traits, typename _Alloc> | |
08addde6 | 85 | template<typename _InIterator> |
725dc051 BK |
86 | _CharT* |
87 | basic_string<_CharT, _Traits, _Alloc>:: | |
08addde6 | 88 | _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, |
725dc051 BK |
89 | input_iterator_tag) |
90 | { | |
1165dc50 | 91 | #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING |
725dc051 | 92 | if (__beg == __end && __a == _Alloc()) |
ca566e4c | 93 | return _S_empty_rep()._M_refdata(); |
1165dc50 | 94 | #endif |
725dc051 | 95 | // Avoid reallocation for common case. |
247791f5 | 96 | _CharT __buf[128]; |
690495b0 PC |
97 | size_type __len = 0; |
98 | while (__beg != __end && __len < sizeof(__buf) / sizeof(_CharT)) | |
ed6814f7 BI |
99 | { |
100 | __buf[__len++] = *__beg; | |
690495b0 | 101 | ++__beg; |
725dc051 | 102 | } |
690495b0 PC |
103 | _Rep* __r = _Rep::_S_create(__len, size_type(0), __a); |
104 | traits_type::copy(__r->_M_refdata(), __buf, __len); | |
ed6814f7 | 105 | try |
e2c09482 | 106 | { |
690495b0 | 107 | while (__beg != __end) |
e2c09482 | 108 | { |
690495b0 | 109 | if (__len == __r->_M_capacity) |
e2c09482 | 110 | { |
690495b0 PC |
111 | // Allocate more space. |
112 | _Rep* __another = _Rep::_S_create(__len + 1, __len, __a); | |
ed6814f7 | 113 | traits_type::copy(__another->_M_refdata(), |
690495b0 PC |
114 | __r->_M_refdata(), __len); |
115 | __r->_M_destroy(__a); | |
116 | __r = __another; | |
e2c09482 | 117 | } |
ed6814f7 | 118 | __r->_M_refdata()[__len++] = *__beg; |
690495b0 | 119 | ++__beg; |
e2c09482 BK |
120 | } |
121 | } | |
ed6814f7 | 122 | catch(...) |
e2c09482 | 123 | { |
ed6814f7 | 124 | __r->_M_destroy(__a); |
e2c09482 BK |
125 | __throw_exception_again; |
126 | } | |
cbf52bfa | 127 | __r->_M_set_length_and_sharable(__len); |
690495b0 | 128 | return __r->_M_refdata(); |
725dc051 | 129 | } |
ed6814f7 | 130 | |
725dc051 | 131 | template<typename _CharT, typename _Traits, typename _Alloc> |
91eab378 | 132 | template <typename _InIterator> |
725dc051 | 133 | _CharT* |
9a304d17 | 134 | basic_string<_CharT, _Traits, _Alloc>:: |
ed6814f7 | 135 | _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, |
725dc051 BK |
136 | forward_iterator_tag) |
137 | { | |
1165dc50 | 138 | #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING |
085825b8 | 139 | if (__beg == __end && __a == _Alloc()) |
ca566e4c | 140 | return _S_empty_rep()._M_refdata(); |
1165dc50 | 141 | #endif |
ed6814f7 | 142 | // NB: Not required, but considered best practice. |
1165dc50 | 143 | if (__builtin_expect(__is_null_pointer(__beg) && __beg != __end, 0)) |
0e50667c | 144 | __throw_logic_error(__N("basic_string::_S_construct NULL not valid")); |
aa863dca | 145 | |
0e50667c PC |
146 | const size_type __dnew = static_cast<size_type>(std::distance(__beg, |
147 | __end)); | |
725dc051 | 148 | // Check for out_of_range and length_error exceptions. |
234e0d31 | 149 | _Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a); |
ed6814f7 | 150 | try |
e2c09482 | 151 | { _S_copy_chars(__r->_M_refdata(), __beg, __end); } |
ed6814f7 BI |
152 | catch(...) |
153 | { | |
154 | __r->_M_destroy(__a); | |
e2c09482 BK |
155 | __throw_exception_again; |
156 | } | |
cbf52bfa | 157 | __r->_M_set_length_and_sharable(__dnew); |
725dc051 BK |
158 | return __r->_M_refdata(); |
159 | } | |
160 | ||
161 | template<typename _CharT, typename _Traits, typename _Alloc> | |
162 | _CharT* | |
9a304d17 | 163 | basic_string<_CharT, _Traits, _Alloc>:: |
725dc051 BK |
164 | _S_construct(size_type __n, _CharT __c, const _Alloc& __a) |
165 | { | |
1165dc50 | 166 | #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING |
725dc051 | 167 | if (__n == 0 && __a == _Alloc()) |
ca566e4c | 168 | return _S_empty_rep()._M_refdata(); |
1165dc50 | 169 | #endif |
725dc051 | 170 | // Check for out_of_range and length_error exceptions. |
234e0d31 | 171 | _Rep* __r = _Rep::_S_create(__n, size_type(0), __a); |
ed6814f7 BI |
172 | if (__n) |
173 | traits_type::assign(__r->_M_refdata(), __n, __c); | |
954b12d2 | 174 | |
cbf52bfa | 175 | __r->_M_set_length_and_sharable(__n); |
725dc051 BK |
176 | return __r->_M_refdata(); |
177 | } | |
178 | ||
179 | template<typename _CharT, typename _Traits, typename _Alloc> | |
180 | basic_string<_CharT, _Traits, _Alloc>:: | |
181 | basic_string(const basic_string& __str) | |
f26e5597 CB |
182 | : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(__str.get_allocator()), |
183 | __str.get_allocator()), | |
184 | __str.get_allocator()) | |
725dc051 BK |
185 | { } |
186 | ||
187 | template<typename _CharT, typename _Traits, typename _Alloc> | |
188 | basic_string<_CharT, _Traits, _Alloc>:: | |
189 | basic_string(const _Alloc& __a) | |
190 | : _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a) | |
191 | { } | |
ed6814f7 | 192 | |
725dc051 BK |
193 | template<typename _CharT, typename _Traits, typename _Alloc> |
194 | basic_string<_CharT, _Traits, _Alloc>:: | |
195 | basic_string(const basic_string& __str, size_type __pos, size_type __n) | |
a3af79ea | 196 | : _M_dataplus(_S_construct(__str._M_data() |
0e50667c PC |
197 | + __str._M_check(__pos, |
198 | "basic_string::basic_string"), | |
690495b0 PC |
199 | __str._M_data() + __str._M_limit(__pos, __n) |
200 | + __pos, _Alloc()), _Alloc()) | |
725dc051 BK |
201 | { } |
202 | ||
203 | template<typename _CharT, typename _Traits, typename _Alloc> | |
204 | basic_string<_CharT, _Traits, _Alloc>:: | |
205 | basic_string(const basic_string& __str, size_type __pos, | |
206 | size_type __n, const _Alloc& __a) | |
a3af79ea | 207 | : _M_dataplus(_S_construct(__str._M_data() |
0e50667c PC |
208 | + __str._M_check(__pos, |
209 | "basic_string::basic_string"), | |
690495b0 PC |
210 | __str._M_data() + __str._M_limit(__pos, __n) |
211 | + __pos, __a), __a) | |
725dc051 BK |
212 | { } |
213 | ||
285b36d6 | 214 | // TBD: DPG annotate |
725dc051 BK |
215 | template<typename _CharT, typename _Traits, typename _Alloc> |
216 | basic_string<_CharT, _Traits, _Alloc>:: | |
217 | basic_string(const _CharT* __s, size_type __n, const _Alloc& __a) | |
218 | : _M_dataplus(_S_construct(__s, __s + __n, __a), __a) | |
219 | { } | |
220 | ||
285b36d6 | 221 | // TBD: DPG annotate |
725dc051 BK |
222 | template<typename _CharT, typename _Traits, typename _Alloc> |
223 | basic_string<_CharT, _Traits, _Alloc>:: | |
224 | basic_string(const _CharT* __s, const _Alloc& __a) | |
085825b8 PC |
225 | : _M_dataplus(_S_construct(__s, __s ? __s + traits_type::length(__s) : |
226 | __s + npos, __a), __a) | |
725dc051 BK |
227 | { } |
228 | ||
229 | template<typename _CharT, typename _Traits, typename _Alloc> | |
230 | basic_string<_CharT, _Traits, _Alloc>:: | |
231 | basic_string(size_type __n, _CharT __c, const _Alloc& __a) | |
232 | : _M_dataplus(_S_construct(__n, __c, __a), __a) | |
233 | { } | |
285b36d6 | 234 | |
ed6814f7 | 235 | // TBD: DPG annotate |
725dc051 | 236 | template<typename _CharT, typename _Traits, typename _Alloc> |
08addde6 | 237 | template<typename _InputIterator> |
725dc051 | 238 | basic_string<_CharT, _Traits, _Alloc>:: |
08addde6 | 239 | basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a) |
725dc051 BK |
240 | : _M_dataplus(_S_construct(__beg, __end, __a), __a) |
241 | { } | |
242 | ||
243 | template<typename _CharT, typename _Traits, typename _Alloc> | |
244 | basic_string<_CharT, _Traits, _Alloc>& | |
ca566e4c NM |
245 | basic_string<_CharT, _Traits, _Alloc>:: |
246 | assign(const basic_string& __str) | |
725dc051 BK |
247 | { |
248 | if (_M_rep() != __str._M_rep()) | |
249 | { | |
250 | // XXX MT | |
690495b0 | 251 | const allocator_type __a = this->get_allocator(); |
725dc051 BK |
252 | _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator()); |
253 | _M_rep()->_M_dispose(__a); | |
254 | _M_data(__tmp); | |
255 | } | |
256 | return *this; | |
257 | } | |
2d9d5235 | 258 | |
2d9d5235 NM |
259 | template<typename _CharT, typename _Traits, typename _Alloc> |
260 | basic_string<_CharT, _Traits, _Alloc>& | |
261 | basic_string<_CharT, _Traits, _Alloc>:: | |
262 | assign(const _CharT* __s, size_type __n) | |
263 | { | |
285b36d6 | 264 | __glibcxx_requires_string_len(__s, __n); |
2d9d5235 | 265 | if (__n > this->max_size()) |
0e50667c | 266 | __throw_length_error(__N("basic_string::assign")); |
2d9d5235 NM |
267 | if (_M_rep()->_M_is_shared() || less<const _CharT*>()(__s, _M_data()) |
268 | || less<const _CharT*>()(_M_data() + this->size(), __s)) | |
7bb9b33b | 269 | return _M_replace_safe(size_type(0), this->size(), __s, __n); |
2d9d5235 NM |
270 | else |
271 | { | |
272 | // Work in-place | |
273 | const size_type __pos = __s - _M_data(); | |
274 | if (__pos >= __n) | |
275 | traits_type::copy(_M_data(), __s, __n); | |
276 | else if (__pos) | |
277 | traits_type::move(_M_data(), __s, __n); | |
cbf52bfa | 278 | _M_rep()->_M_set_length_and_sharable(__n); |
2d9d5235 NM |
279 | return *this; |
280 | } | |
281 | } | |
282 | ||
2d9d5235 NM |
283 | template<typename _CharT, typename _Traits, typename _Alloc> |
284 | basic_string<_CharT, _Traits, _Alloc>& | |
285 | basic_string<_CharT, _Traits, _Alloc>:: | |
286 | insert(size_type __pos, const _CharT* __s, size_type __n) | |
287 | { | |
285b36d6 | 288 | __glibcxx_requires_string_len(__s, __n); |
04cc8aef | 289 | _M_check(__pos, "basic_string::insert"); |
251804e6 | 290 | if (this->max_size() - this->size() < __n) |
0e50667c | 291 | __throw_length_error(__N("basic_string::insert")); |
2d9d5235 | 292 | if (_M_rep()->_M_is_shared() || less<const _CharT*>()(__s, _M_data()) |
e03a6fb7 | 293 | || less<const _CharT*>()(_M_data() + this->size(), __s)) |
7bb9b33b | 294 | return _M_replace_safe(__pos, size_type(0), __s, __n); |
2d9d5235 NM |
295 | else |
296 | { | |
297 | // Work in-place. If _M_mutate reallocates the string, __s | |
298 | // does not point anymore to valid data, therefore we save its | |
299 | // offset, then we restore it. | |
300 | const size_type __off = __s - _M_data(); | |
301 | _M_mutate(__pos, 0, __n); | |
302 | __s = _M_data() + __off; | |
303 | _CharT* __p = _M_data() + __pos; | |
304 | if (__s + __n <= __p) | |
305 | traits_type::copy(__p, __s, __n); | |
306 | else if (__s >= __p) | |
307 | traits_type::copy(__p, __s + __n, __n); | |
308 | else | |
309 | { | |
2cb612d1 PC |
310 | const size_type __nleft = __p - __s; |
311 | traits_type::copy(__p, __s, __nleft); | |
312 | traits_type::copy(__p + __nleft, __p + __n, __n - __nleft); | |
2d9d5235 NM |
313 | } |
314 | return *this; | |
315 | } | |
316 | } | |
ed6814f7 | 317 | |
2d9d5235 NM |
318 | template<typename _CharT, typename _Traits, typename _Alloc> |
319 | basic_string<_CharT, _Traits, _Alloc>& | |
320 | basic_string<_CharT, _Traits, _Alloc>:: | |
321 | replace(size_type __pos, size_type __n1, const _CharT* __s, | |
322 | size_type __n2) | |
323 | { | |
285b36d6 | 324 | __glibcxx_requires_string_len(__s, __n2); |
04cc8aef | 325 | _M_check(__pos, "basic_string::replace"); |
e03a6fb7 | 326 | __n1 = _M_limit(__pos, __n1); |
251804e6 | 327 | if (this->max_size() - (this->size() - __n1) < __n2) |
0e50667c | 328 | __throw_length_error(__N("basic_string::replace")); |
2cb612d1 | 329 | bool __left; |
2d9d5235 | 330 | if (_M_rep()->_M_is_shared() || less<const _CharT*>()(__s, _M_data()) |
251804e6 | 331 | || less<const _CharT*>()(_M_data() + this->size(), __s)) |
7bb9b33b | 332 | return _M_replace_safe(__pos, __n1, __s, __n2); |
2cb612d1 PC |
333 | else if ((__left = __s + __n2 <= _M_data() + __pos) |
334 | || _M_data() + __pos + __n1 <= __s) | |
335 | { | |
336 | // Work in-place: non-overlapping case. | |
337 | const size_type __off = __s - _M_data(); | |
338 | _M_mutate(__pos, __n1, __n2); | |
339 | if (__left) | |
340 | traits_type::copy(_M_data() + __pos, | |
341 | _M_data() + __off, __n2); | |
342 | else | |
343 | traits_type::copy(_M_data() + __pos, | |
344 | _M_data() + __off + __n2 - __n1, __n2); | |
345 | return *this; | |
346 | } | |
2d9d5235 | 347 | else |
251804e6 | 348 | { |
2cb612d1 | 349 | // Todo: overlapping case. |
251804e6 PC |
350 | const basic_string __tmp(__s, __n2); |
351 | return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2); | |
352 | } | |
2d9d5235 | 353 | } |
ed6814f7 | 354 | |
725dc051 BK |
355 | template<typename _CharT, typename _Traits, typename _Alloc> |
356 | void | |
357 | basic_string<_CharT, _Traits, _Alloc>::_Rep:: | |
358 | _M_destroy(const _Alloc& __a) throw () | |
359 | { | |
1165dc50 | 360 | #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING |
ca566e4c | 361 | if (this == &_S_empty_rep()) |
1165dc50 PC |
362 | return; |
363 | #endif | |
ca566e4c NM |
364 | const size_type __size = sizeof(_Rep_base) + |
365 | (this->_M_capacity + 1) * sizeof(_CharT); | |
725dc051 BK |
366 | _Raw_bytes_alloc(__a).deallocate(reinterpret_cast<char*>(this), __size); |
367 | } | |
368 | ||
369 | template<typename _CharT, typename _Traits, typename _Alloc> | |
370 | void | |
cc6e67d4 PC |
371 | basic_string<_CharT, _Traits, _Alloc>:: |
372 | _M_leak_hard() | |
725dc051 | 373 | { |
1165dc50 | 374 | #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING |
ca566e4c | 375 | if (_M_rep() == &_S_empty_rep()) |
1165dc50 PC |
376 | return; |
377 | #endif | |
ed6814f7 | 378 | if (_M_rep()->_M_is_shared()) |
725dc051 BK |
379 | _M_mutate(0, 0, 0); |
380 | _M_rep()->_M_set_leaked(); | |
381 | } | |
382 | ||
383 | template<typename _CharT, typename _Traits, typename _Alloc> | |
384 | void | |
385 | basic_string<_CharT, _Traits, _Alloc>:: | |
386 | _M_mutate(size_type __pos, size_type __len1, size_type __len2) | |
387 | { | |
7778fa6e | 388 | const size_type __old_size = this->size(); |
725dc051 | 389 | const size_type __new_size = __old_size + __len2 - __len1; |
725dc051 | 390 | const size_type __how_much = __old_size - __pos - __len1; |
ed6814f7 | 391 | |
cc6e67d4 | 392 | if (__new_size > this->capacity() || _M_rep()->_M_is_shared()) |
725dc051 BK |
393 | { |
394 | // Must reallocate. | |
91eab378 | 395 | const allocator_type __a = get_allocator(); |
cc6e67d4 | 396 | _Rep* __r = _Rep::_S_create(__new_size, this->capacity(), __a); |
954b12d2 PC |
397 | |
398 | if (__pos) | |
399 | traits_type::copy(__r->_M_refdata(), _M_data(), __pos); | |
400 | if (__how_much) | |
234e0d31 | 401 | traits_type::copy(__r->_M_refdata() + __pos + __len2, |
0a746019 | 402 | _M_data() + __pos + __len1, __how_much); |
954b12d2 | 403 | |
725dc051 BK |
404 | _M_rep()->_M_dispose(__a); |
405 | _M_data(__r->_M_refdata()); | |
ca566e4c | 406 | } |
725dc051 BK |
407 | else if (__how_much && __len1 != __len2) |
408 | { | |
409 | // Work in-place | |
0a746019 PC |
410 | traits_type::move(_M_data() + __pos + __len2, |
411 | _M_data() + __pos + __len1, __how_much); | |
725dc051 | 412 | } |
cbf52bfa | 413 | _M_rep()->_M_set_length_and_sharable(__new_size); |
725dc051 | 414 | } |
ed6814f7 | 415 | |
725dc051 BK |
416 | template<typename _CharT, typename _Traits, typename _Alloc> |
417 | void | |
cc6e67d4 PC |
418 | basic_string<_CharT, _Traits, _Alloc>:: |
419 | reserve(size_type __res) | |
725dc051 | 420 | { |
cbc67955 | 421 | if (__res != this->capacity() || _M_rep()->_M_is_shared()) |
725dc051 | 422 | { |
e2c09482 | 423 | if (__res > this->max_size()) |
0e50667c | 424 | __throw_length_error(__N("basic_string::reserve")); |
dcc61724 PC |
425 | // Make sure we don't shrink below the current size |
426 | if (__res < this->size()) | |
427 | __res = this->size(); | |
91eab378 | 428 | const allocator_type __a = get_allocator(); |
725dc051 BK |
429 | _CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size()); |
430 | _M_rep()->_M_dispose(__a); | |
431 | _M_data(__tmp); | |
432 | } | |
433 | } | |
ed6814f7 | 434 | |
725dc051 | 435 | template<typename _CharT, typename _Traits, typename _Alloc> |
cc6e67d4 PC |
436 | void |
437 | basic_string<_CharT, _Traits, _Alloc>:: | |
438 | swap(basic_string& __s) | |
725dc051 | 439 | { |
ed6814f7 | 440 | if (_M_rep()->_M_is_leaked()) |
725dc051 | 441 | _M_rep()->_M_set_sharable(); |
ed6814f7 | 442 | if (__s._M_rep()->_M_is_leaked()) |
725dc051 BK |
443 | __s._M_rep()->_M_set_sharable(); |
444 | if (this->get_allocator() == __s.get_allocator()) | |
445 | { | |
446 | _CharT* __tmp = _M_data(); | |
447 | _M_data(__s._M_data()); | |
448 | __s._M_data(__tmp); | |
449 | } | |
450 | // The code below can usually be optimized away. | |
ed6814f7 | 451 | else |
725dc051 | 452 | { |
0e50667c PC |
453 | const basic_string __tmp1(_M_ibegin(), _M_iend(), |
454 | __s.get_allocator()); | |
ed6814f7 | 455 | const basic_string __tmp2(__s._M_ibegin(), __s._M_iend(), |
0e50667c | 456 | this->get_allocator()); |
725dc051 BK |
457 | *this = __tmp2; |
458 | __s = __tmp1; | |
459 | } | |
460 | } | |
461 | ||
725dc051 | 462 | template<typename _CharT, typename _Traits, typename _Alloc> |
31bfa177 | 463 | typename basic_string<_CharT, _Traits, _Alloc>::_Rep* |
725dc051 | 464 | basic_string<_CharT, _Traits, _Alloc>::_Rep:: |
234e0d31 PC |
465 | _S_create(size_type __capacity, size_type __old_capacity, |
466 | const _Alloc& __alloc) | |
725dc051 | 467 | { |
f5677b15 | 468 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
725dc051 | 469 | // 83. String::npos vs. string::max_size() |
e2c09482 | 470 | if (__capacity > _S_max_size) |
0e50667c | 471 | __throw_length_error(__N("basic_string::_S_create")); |
725dc051 | 472 | |
2883d58b LR |
473 | // The standard places no restriction on allocating more memory |
474 | // than is strictly needed within this layer at the moment or as | |
234e0d31 PC |
475 | // requested by an explicit application call to reserve(). |
476 | ||
477 | // Many malloc implementations perform quite poorly when an | |
2883d58b LR |
478 | // application attempts to allocate memory in a stepwise fashion |
479 | // growing each allocation size by only 1 char. Additionally, | |
480 | // it makes little sense to allocate less linear memory than the | |
481 | // natural blocking size of the malloc implementation. | |
482 | // Unfortunately, we would need a somewhat low-level calculation | |
483 | // with tuned parameters to get this perfect for any particular | |
484 | // malloc implementation. Fortunately, generalizations about | |
485 | // common features seen among implementations seems to suffice. | |
2883d58b LR |
486 | |
487 | // __pagesize need not match the actual VM page size for good | |
488 | // results in practice, thus we pick a common value on the low | |
489 | // side. __malloc_header_size is an estimate of the amount of | |
490 | // overhead per memory allocation (in practice seen N * sizeof | |
491 | // (void*) where N is 0, 2 or 4). According to folklore, | |
492 | // picking this value on the high side is better than | |
493 | // low-balling it (especially when this algorithm is used with | |
494 | // malloc implementations that allocate memory blocks rounded up | |
495 | // to a size which is a power of 2). | |
cbb0dcef PC |
496 | const size_type __pagesize = 4096; |
497 | const size_type __malloc_header_size = 4 * sizeof(void*); | |
234e0d31 PC |
498 | |
499 | // The below implements an exponential growth policy, necessary to | |
500 | // meet amortized linear time requirements of the library: see | |
501 | // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html. | |
502 | // It's active for allocations requiring an amount of memory above | |
503 | // system pagesize. This is consistent with the requirements of the | |
504 | // standard: http://gcc.gnu.org/ml/libstdc++/2001-07/msg00130.html | |
cbb0dcef | 505 | if (__capacity > __old_capacity && __capacity < 2 * __old_capacity) |
234e0d31 PC |
506 | __capacity = 2 * __old_capacity; |
507 | ||
508 | // NB: Need an array of char_type[__capacity], plus a terminating | |
509 | // null char_type() element, plus enough for the _Rep data structure. | |
510 | // Whew. Seemingly so needy, yet so elemental. | |
511 | size_type __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); | |
512 | ||
24f33069 PC |
513 | const size_type __adj_size = __size + __malloc_header_size; |
514 | if (__adj_size > __pagesize) | |
2883d58b | 515 | { |
24f33069 | 516 | const size_type __extra = __pagesize - __adj_size % __pagesize; |
2883d58b | 517 | __capacity += __extra / sizeof(_CharT); |
d1615643 PC |
518 | // Never allocate a string bigger than _S_max_size. |
519 | if (__capacity > _S_max_size) | |
520 | __capacity = _S_max_size; | |
521 | __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); | |
2883d58b | 522 | } |
2883d58b | 523 | |
725dc051 BK |
524 | // NB: Might throw, but no worries about a leak, mate: _Rep() |
525 | // does not throw. | |
526 | void* __place = _Raw_bytes_alloc(__alloc).allocate(__size); | |
527 | _Rep *__p = new (__place) _Rep; | |
528 | __p->_M_capacity = __capacity; | |
725dc051 BK |
529 | return __p; |
530 | } | |
531 | ||
532 | template<typename _CharT, typename _Traits, typename _Alloc> | |
533 | _CharT* | |
534 | basic_string<_CharT, _Traits, _Alloc>::_Rep:: | |
535 | _M_clone(const _Alloc& __alloc, size_type __res) | |
536 | { | |
79f57f23 | 537 | // Requested capacity of the clone. |
ca566e4c | 538 | const size_type __requested_cap = this->_M_length + __res; |
234e0d31 PC |
539 | _Rep* __r = _Rep::_S_create(__requested_cap, this->_M_capacity, |
540 | __alloc); | |
ca566e4c | 541 | if (this->_M_length) |
cbf52bfa | 542 | traits_type::copy(__r->_M_refdata(), _M_refdata(), this->_M_length); |
954b12d2 | 543 | |
cbf52bfa | 544 | __r->_M_set_length_and_sharable(this->_M_length); |
725dc051 BK |
545 | return __r->_M_refdata(); |
546 | } | |
ed6814f7 | 547 | |
725dc051 BK |
548 | template<typename _CharT, typename _Traits, typename _Alloc> |
549 | void | |
cc6e67d4 PC |
550 | basic_string<_CharT, _Traits, _Alloc>:: |
551 | resize(size_type __n, _CharT __c) | |
725dc051 | 552 | { |
e2c09482 | 553 | if (__n > max_size()) |
0e50667c | 554 | __throw_length_error(__N("basic_string::resize")); |
7778fa6e | 555 | const size_type __size = this->size(); |
725dc051 BK |
556 | if (__size < __n) |
557 | this->append(__n - __size, __c); | |
558 | else if (__n < __size) | |
559 | this->erase(__n); | |
560 | // else nothing (in particular, avoid calling _M_mutate() unnecessarily.) | |
561 | } | |
418bb880 | 562 | |
725dc051 | 563 | template<typename _CharT, typename _Traits, typename _Alloc> |
08addde6 | 564 | template<typename _InputIterator> |
725dc051 BK |
565 | basic_string<_CharT, _Traits, _Alloc>& |
566 | basic_string<_CharT, _Traits, _Alloc>:: | |
ed6814f7 | 567 | _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1, |
fefe561e | 568 | _InputIterator __k2, __false_type) |
725dc051 | 569 | { |
7778fa6e | 570 | const basic_string __s(__k1, __k2); |
251804e6 PC |
571 | const size_type __n1 = __i2 - __i1; |
572 | if (this->max_size() - (this->size() - __n1) < __s.size()) | |
0e50667c | 573 | __throw_length_error(__N("basic_string::_M_replace_dispatch")); |
251804e6 | 574 | return _M_replace_safe(__i1 - _M_ibegin(), __n1, __s._M_data(), |
7bb9b33b | 575 | __s.size()); |
725dc051 BK |
576 | } |
577 | ||
725dc051 | 578 | template<typename _CharT, typename _Traits, typename _Alloc> |
9a304d17 PC |
579 | basic_string<_CharT, _Traits, _Alloc>& |
580 | basic_string<_CharT, _Traits, _Alloc>:: | |
725dc051 | 581 | append(const basic_string& __str) |
3e7782b2 PC |
582 | { |
583 | // Iff appending itself, string needs to pre-reserve the | |
584 | // correct size so that _M_mutate does not clobber the | |
251804e6 | 585 | // pointer __str._M_data() formed here. |
3e7782b2 PC |
586 | const size_type __size = __str.size(); |
587 | const size_type __len = __size + this->size(); | |
588 | if (__len > this->capacity()) | |
589 | this->reserve(__len); | |
7bb9b33b PC |
590 | return _M_replace_safe(this->size(), size_type(0), __str._M_data(), |
591 | __str.size()); | |
3e7782b2 | 592 | } |
725dc051 BK |
593 | |
594 | template<typename _CharT, typename _Traits, typename _Alloc> | |
9a304d17 PC |
595 | basic_string<_CharT, _Traits, _Alloc>& |
596 | basic_string<_CharT, _Traits, _Alloc>:: | |
725dc051 BK |
597 | append(const basic_string& __str, size_type __pos, size_type __n) |
598 | { | |
3e7782b2 PC |
599 | // Iff appending itself, string needs to pre-reserve the |
600 | // correct size so that _M_mutate does not clobber the | |
251804e6 | 601 | // pointer __str._M_data() formed here. |
04cc8aef | 602 | __str._M_check(__pos, "basic_string::append"); |
3e7782b2 PC |
603 | __n = __str._M_limit(__pos, __n); |
604 | const size_type __len = __n + this->size(); | |
605 | if (__len > this->capacity()) | |
606 | this->reserve(__len); | |
7bb9b33b PC |
607 | return _M_replace_safe(this->size(), size_type(0), __str._M_data() |
608 | + __pos, __n); | |
725dc051 BK |
609 | } |
610 | ||
611 | template<typename _CharT, typename _Traits, typename _Alloc> | |
9a304d17 PC |
612 | basic_string<_CharT, _Traits, _Alloc>& |
613 | basic_string<_CharT, _Traits, _Alloc>:: | |
725dc051 BK |
614 | append(const _CharT* __s, size_type __n) |
615 | { | |
285b36d6 | 616 | __glibcxx_requires_string_len(__s, __n); |
7778fa6e | 617 | const size_type __len = __n + this->size(); |
725dc051 BK |
618 | if (__len > this->capacity()) |
619 | this->reserve(__len); | |
7bb9b33b | 620 | return _M_replace_safe(this->size(), size_type(0), __s, __n); |
725dc051 BK |
621 | } |
622 | ||
623 | template<typename _CharT, typename _Traits, typename _Alloc> | |
9a304d17 | 624 | basic_string<_CharT, _Traits, _Alloc> |
725dc051 | 625 | operator+(const _CharT* __lhs, |
9a304d17 | 626 | const basic_string<_CharT, _Traits, _Alloc>& __rhs) |
725dc051 | 627 | { |
285b36d6 | 628 | __glibcxx_requires_string(__lhs); |
9a304d17 | 629 | typedef basic_string<_CharT, _Traits, _Alloc> __string_type; |
725dc051 | 630 | typedef typename __string_type::size_type __size_type; |
7778fa6e | 631 | const __size_type __len = _Traits::length(__lhs); |
725dc051 BK |
632 | __string_type __str; |
633 | __str.reserve(__len + __rhs.size()); | |
bb9909b0 | 634 | __str.append(__lhs, __len); |
725dc051 BK |
635 | __str.append(__rhs); |
636 | return __str; | |
637 | } | |
638 | ||
639 | template<typename _CharT, typename _Traits, typename _Alloc> | |
9a304d17 PC |
640 | basic_string<_CharT, _Traits, _Alloc> |
641 | operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) | |
725dc051 | 642 | { |
9a304d17 | 643 | typedef basic_string<_CharT, _Traits, _Alloc> __string_type; |
725dc051 BK |
644 | typedef typename __string_type::size_type __size_type; |
645 | __string_type __str; | |
7778fa6e | 646 | const __size_type __len = __rhs.size(); |
725dc051 | 647 | __str.reserve(__len + 1); |
15f13f01 | 648 | __str.append(__size_type(1), __lhs); |
725dc051 BK |
649 | __str.append(__rhs); |
650 | return __str; | |
651 | } | |
652 | ||
725dc051 | 653 | template<typename _CharT, typename _Traits, typename _Alloc> |
31bfa177 | 654 | typename basic_string<_CharT, _Traits, _Alloc>::size_type |
725dc051 BK |
655 | basic_string<_CharT, _Traits, _Alloc>:: |
656 | copy(_CharT* __s, size_type __n, size_type __pos) const | |
657 | { | |
04cc8aef | 658 | _M_check(__pos, "basic_string::copy"); |
e03a6fb7 | 659 | __n = _M_limit(__pos, __n); |
285b36d6 | 660 | __glibcxx_requires_string_len(__s, __n); |
251804e6 PC |
661 | if (__n) |
662 | traits_type::copy(__s, _M_data() + __pos, __n); | |
725dc051 BK |
663 | // 21.3.5.7 par 3: do not append null. (good.) |
664 | return __n; | |
665 | } | |
666 | ||
725dc051 | 667 | template<typename _CharT, typename _Traits, typename _Alloc> |
31bfa177 | 668 | typename basic_string<_CharT, _Traits, _Alloc>::size_type |
725dc051 BK |
669 | basic_string<_CharT, _Traits, _Alloc>:: |
670 | find(const _CharT* __s, size_type __pos, size_type __n) const | |
671 | { | |
285b36d6 | 672 | __glibcxx_requires_string_len(__s, __n); |
4a787fa8 | 673 | size_type __ret = npos; |
7778fa6e | 674 | const size_type __size = this->size(); |
4a787fa8 PC |
675 | if (__pos + __n <= __size) |
676 | { | |
677 | const _CharT* __data = _M_data(); | |
678 | const _CharT* __p = std::search(__data + __pos, __data + __size, | |
679 | __s, __s + __n, traits_type::eq); | |
680 | if (__p != __data + __size || __n == 0) | |
681 | __ret = __p - __data; | |
682 | } | |
683 | return __ret; | |
725dc051 BK |
684 | } |
685 | ||
686 | template<typename _CharT, typename _Traits, typename _Alloc> | |
31bfa177 | 687 | typename basic_string<_CharT, _Traits, _Alloc>::size_type |
725dc051 BK |
688 | basic_string<_CharT, _Traits, _Alloc>:: |
689 | find(_CharT __c, size_type __pos) const | |
690 | { | |
725dc051 | 691 | size_type __ret = npos; |
4a787fa8 | 692 | const size_type __size = this->size(); |
725dc051 BK |
693 | if (__pos < __size) |
694 | { | |
695 | const _CharT* __data = _M_data(); | |
7778fa6e | 696 | const size_type __n = __size - __pos; |
97644827 BK |
697 | const _CharT* __p = traits_type::find(__data + __pos, __n, __c); |
698 | if (__p) | |
725dc051 BK |
699 | __ret = __p - __data; |
700 | } | |
701 | return __ret; | |
702 | } | |
703 | ||
725dc051 | 704 | template<typename _CharT, typename _Traits, typename _Alloc> |
31bfa177 | 705 | typename basic_string<_CharT, _Traits, _Alloc>::size_type |
725dc051 BK |
706 | basic_string<_CharT, _Traits, _Alloc>:: |
707 | rfind(const _CharT* __s, size_type __pos, size_type __n) const | |
708 | { | |
285b36d6 | 709 | __glibcxx_requires_string_len(__s, __n); |
7778fa6e | 710 | const size_type __size = this->size(); |
725dc051 BK |
711 | if (__n <= __size) |
712 | { | |
dd6eaaed | 713 | __pos = std::min(size_type(__size - __n), __pos); |
725dc051 | 714 | const _CharT* __data = _M_data(); |
ed6814f7 | 715 | do |
725dc051 BK |
716 | { |
717 | if (traits_type::compare(__data + __pos, __s, __n) == 0) | |
718 | return __pos; | |
ed6814f7 | 719 | } |
725dc051 BK |
720 | while (__pos-- > 0); |
721 | } | |
722 | return npos; | |
723 | } | |
ed6814f7 | 724 | |
725dc051 | 725 | template<typename _CharT, typename _Traits, typename _Alloc> |
31bfa177 | 726 | typename basic_string<_CharT, _Traits, _Alloc>::size_type |
725dc051 BK |
727 | basic_string<_CharT, _Traits, _Alloc>:: |
728 | rfind(_CharT __c, size_type __pos) const | |
729 | { | |
04cc8aef | 730 | size_type __size = this->size(); |
725dc051 BK |
731 | if (__size) |
732 | { | |
04cc8aef PC |
733 | if (--__size > __pos) |
734 | __size = __pos; | |
735 | for (++__size; __size-- > 0; ) | |
736 | if (traits_type::eq(_M_data()[__size], __c)) | |
737 | return __size; | |
725dc051 BK |
738 | } |
739 | return npos; | |
740 | } | |
ed6814f7 | 741 | |
725dc051 | 742 | template<typename _CharT, typename _Traits, typename _Alloc> |
31bfa177 | 743 | typename basic_string<_CharT, _Traits, _Alloc>::size_type |
725dc051 BK |
744 | basic_string<_CharT, _Traits, _Alloc>:: |
745 | find_first_of(const _CharT* __s, size_type __pos, size_type __n) const | |
746 | { | |
285b36d6 | 747 | __glibcxx_requires_string_len(__s, __n); |
725dc051 BK |
748 | for (; __n && __pos < this->size(); ++__pos) |
749 | { | |
97644827 BK |
750 | const _CharT* __p = traits_type::find(__s, __n, _M_data()[__pos]); |
751 | if (__p) | |
725dc051 BK |
752 | return __pos; |
753 | } | |
754 | return npos; | |
755 | } | |
ed6814f7 | 756 | |
725dc051 | 757 | template<typename _CharT, typename _Traits, typename _Alloc> |
31bfa177 | 758 | typename basic_string<_CharT, _Traits, _Alloc>::size_type |
725dc051 BK |
759 | basic_string<_CharT, _Traits, _Alloc>:: |
760 | find_last_of(const _CharT* __s, size_type __pos, size_type __n) const | |
761 | { | |
285b36d6 | 762 | __glibcxx_requires_string_len(__s, __n); |
725dc051 BK |
763 | size_type __size = this->size(); |
764 | if (__size && __n) | |
ed6814f7 BI |
765 | { |
766 | if (--__size > __pos) | |
725dc051 BK |
767 | __size = __pos; |
768 | do | |
769 | { | |
97644827 | 770 | if (traits_type::find(__s, __n, _M_data()[__size])) |
725dc051 | 771 | return __size; |
ed6814f7 | 772 | } |
725dc051 BK |
773 | while (__size-- != 0); |
774 | } | |
775 | return npos; | |
776 | } | |
ed6814f7 | 777 | |
725dc051 | 778 | template<typename _CharT, typename _Traits, typename _Alloc> |
31bfa177 | 779 | typename basic_string<_CharT, _Traits, _Alloc>::size_type |
725dc051 BK |
780 | basic_string<_CharT, _Traits, _Alloc>:: |
781 | find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const | |
782 | { | |
285b36d6 | 783 | __glibcxx_requires_string_len(__s, __n); |
fefe561e PC |
784 | for (; __pos < this->size(); ++__pos) |
785 | if (!traits_type::find(__s, __n, _M_data()[__pos])) | |
786 | return __pos; | |
725dc051 BK |
787 | return npos; |
788 | } | |
789 | ||
790 | template<typename _CharT, typename _Traits, typename _Alloc> | |
31bfa177 | 791 | typename basic_string<_CharT, _Traits, _Alloc>::size_type |
725dc051 BK |
792 | basic_string<_CharT, _Traits, _Alloc>:: |
793 | find_first_not_of(_CharT __c, size_type __pos) const | |
794 | { | |
fefe561e PC |
795 | for (; __pos < this->size(); ++__pos) |
796 | if (!traits_type::eq(_M_data()[__pos], __c)) | |
797 | return __pos; | |
725dc051 BK |
798 | return npos; |
799 | } | |
800 | ||
801 | template<typename _CharT, typename _Traits, typename _Alloc> | |
31bfa177 | 802 | typename basic_string<_CharT, _Traits, _Alloc>::size_type |
725dc051 BK |
803 | basic_string<_CharT, _Traits, _Alloc>:: |
804 | find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const | |
805 | { | |
285b36d6 | 806 | __glibcxx_requires_string_len(__s, __n); |
04cc8aef | 807 | size_type __size = this->size(); |
ba317c52 | 808 | if (__size) |
04cc8aef PC |
809 | { |
810 | if (--__size > __pos) | |
811 | __size = __pos; | |
ed6814f7 | 812 | do |
725dc051 | 813 | { |
04cc8aef PC |
814 | if (!traits_type::find(__s, __n, _M_data()[__size])) |
815 | return __size; | |
ed6814f7 | 816 | } |
04cc8aef | 817 | while (__size--); |
725dc051 BK |
818 | } |
819 | return npos; | |
820 | } | |
821 | ||
822 | template<typename _CharT, typename _Traits, typename _Alloc> | |
31bfa177 | 823 | typename basic_string<_CharT, _Traits, _Alloc>::size_type |
725dc051 BK |
824 | basic_string<_CharT, _Traits, _Alloc>:: |
825 | find_last_not_of(_CharT __c, size_type __pos) const | |
826 | { | |
04cc8aef | 827 | size_type __size = this->size(); |
725dc051 | 828 | if (__size) |
fefe561e | 829 | { |
04cc8aef | 830 | if (--__size > __pos) |
ed6814f7 | 831 | __size = __pos; |
725dc051 BK |
832 | do |
833 | { | |
04cc8aef PC |
834 | if (!traits_type::eq(_M_data()[__size], __c)) |
835 | return __size; | |
ed6814f7 | 836 | } |
04cc8aef | 837 | while (__size--); |
725dc051 BK |
838 | } |
839 | return npos; | |
840 | } | |
ed6814f7 | 841 | |
725dc051 BK |
842 | template<typename _CharT, typename _Traits, typename _Alloc> |
843 | int | |
844 | basic_string<_CharT, _Traits, _Alloc>:: | |
845 | compare(size_type __pos, size_type __n, const basic_string& __str) const | |
846 | { | |
04cc8aef | 847 | _M_check(__pos, "basic_string::compare"); |
e03a6fb7 | 848 | __n = _M_limit(__pos, __n); |
7778fa6e | 849 | const size_type __osize = __str.size(); |
e03a6fb7 | 850 | const size_type __len = std::min(__n, __osize); |
725dc051 BK |
851 | int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len); |
852 | if (!__r) | |
e03a6fb7 | 853 | __r = __n - __osize; |
725dc051 BK |
854 | return __r; |
855 | } | |
856 | ||
857 | template<typename _CharT, typename _Traits, typename _Alloc> | |
858 | int | |
859 | basic_string<_CharT, _Traits, _Alloc>:: | |
860 | compare(size_type __pos1, size_type __n1, const basic_string& __str, | |
861 | size_type __pos2, size_type __n2) const | |
862 | { | |
04cc8aef PC |
863 | _M_check(__pos1, "basic_string::compare"); |
864 | __str._M_check(__pos2, "basic_string::compare"); | |
e03a6fb7 PC |
865 | __n1 = _M_limit(__pos1, __n1); |
866 | __n2 = __str._M_limit(__pos2, __n2); | |
867 | const size_type __len = std::min(__n1, __n2); | |
ed6814f7 | 868 | int __r = traits_type::compare(_M_data() + __pos1, |
725dc051 BK |
869 | __str.data() + __pos2, __len); |
870 | if (!__r) | |
e03a6fb7 | 871 | __r = __n1 - __n2; |
725dc051 BK |
872 | return __r; |
873 | } | |
874 | ||
725dc051 BK |
875 | template<typename _CharT, typename _Traits, typename _Alloc> |
876 | int | |
877 | basic_string<_CharT, _Traits, _Alloc>:: | |
878 | compare(const _CharT* __s) const | |
879 | { | |
285b36d6 | 880 | __glibcxx_requires_string(__s); |
7778fa6e PC |
881 | const size_type __size = this->size(); |
882 | const size_type __osize = traits_type::length(__s); | |
883 | const size_type __len = std::min(__size, __osize); | |
c86c54e6 | 884 | int __r = traits_type::compare(_M_data(), __s, __len); |
725dc051 | 885 | if (!__r) |
c86c54e6 | 886 | __r = __size - __osize; |
725dc051 BK |
887 | return __r; |
888 | } | |
889 | ||
3b0fd4bc BK |
890 | template<typename _CharT, typename _Traits, typename _Alloc> |
891 | int | |
9a304d17 | 892 | basic_string <_CharT, _Traits, _Alloc>:: |
3b0fd4bc BK |
893 | compare(size_type __pos, size_type __n1, const _CharT* __s) const |
894 | { | |
285b36d6 | 895 | __glibcxx_requires_string(__s); |
04cc8aef | 896 | _M_check(__pos, "basic_string::compare"); |
e03a6fb7 | 897 | __n1 = _M_limit(__pos, __n1); |
7778fa6e | 898 | const size_type __osize = traits_type::length(__s); |
e03a6fb7 | 899 | const size_type __len = std::min(__n1, __osize); |
3b0fd4bc BK |
900 | int __r = traits_type::compare(_M_data() + __pos, __s, __len); |
901 | if (!__r) | |
e03a6fb7 | 902 | __r = __n1 - __osize; |
3b0fd4bc BK |
903 | return __r; |
904 | } | |
905 | ||
725dc051 BK |
906 | template<typename _CharT, typename _Traits, typename _Alloc> |
907 | int | |
9a304d17 | 908 | basic_string <_CharT, _Traits, _Alloc>:: |
ed6814f7 | 909 | compare(size_type __pos, size_type __n1, const _CharT* __s, |
725dc051 BK |
910 | size_type __n2) const |
911 | { | |
285b36d6 | 912 | __glibcxx_requires_string_len(__s, __n2); |
04cc8aef | 913 | _M_check(__pos, "basic_string::compare"); |
e03a6fb7 PC |
914 | __n1 = _M_limit(__pos, __n1); |
915 | const size_type __len = std::min(__n1, __n2); | |
725dc051 BK |
916 | int __r = traits_type::compare(_M_data() + __pos, __s, __len); |
917 | if (!__r) | |
e03a6fb7 | 918 | __r = __n1 - __n2; |
725dc051 BK |
919 | return __r; |
920 | } | |
921 | ||
a32e3c09 | 922 | // Inhibit implicit instantiations for required instantiations, |
ed6814f7 | 923 | // which are defined via explicit instantiations elsewhere. |
a32e3c09 | 924 | // NB: This syntax is a GNU extension. |
3d7c150e | 925 | #if _GLIBCXX_EXTERN_TEMPLATE |
a32e3c09 | 926 | extern template class basic_string<char>; |
ed6814f7 BI |
927 | extern template |
928 | basic_istream<char>& | |
a32e3c09 | 929 | operator>>(basic_istream<char>&, string&); |
ed6814f7 BI |
930 | extern template |
931 | basic_ostream<char>& | |
a32e3c09 | 932 | operator<<(basic_ostream<char>&, const string&); |
ed6814f7 BI |
933 | extern template |
934 | basic_istream<char>& | |
a32e3c09 | 935 | getline(basic_istream<char>&, string&, char); |
ed6814f7 BI |
936 | extern template |
937 | basic_istream<char>& | |
a32e3c09 BK |
938 | getline(basic_istream<char>&, string&); |
939 | ||
3d7c150e | 940 | #ifdef _GLIBCXX_USE_WCHAR_T |
a32e3c09 | 941 | extern template class basic_string<wchar_t>; |
ed6814f7 BI |
942 | extern template |
943 | basic_istream<wchar_t>& | |
a32e3c09 | 944 | operator>>(basic_istream<wchar_t>&, wstring&); |
ed6814f7 BI |
945 | extern template |
946 | basic_ostream<wchar_t>& | |
a32e3c09 | 947 | operator<<(basic_ostream<wchar_t>&, const wstring&); |
ed6814f7 BI |
948 | extern template |
949 | basic_istream<wchar_t>& | |
a32e3c09 | 950 | getline(basic_istream<wchar_t>&, wstring&, wchar_t); |
ed6814f7 BI |
951 | extern template |
952 | basic_istream<wchar_t>& | |
a32e3c09 | 953 | getline(basic_istream<wchar_t>&, wstring&); |
5112ae3a | 954 | #endif |
1bc8b0ad | 955 | #endif |
3b0fd4bc | 956 | } // namespace std |
725dc051 | 957 | |
3b0fd4bc | 958 | #endif |