1 // Components for manipulating sequences of characters -*- C++ -*-
2 
3 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
4 // Free Software Foundation, Inc.
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 /** @file basic_string.h
36  *  This is an internal header file, included by other library headers.
37  *  You should not attempt to use it directly.
38  */
39 
40 #ifndef _CPP_BITS_STRING_H
41 #define _CPP_BITS_STRING_H	1
42 
43 #pragma GCC system_header
44 
45 #include <bits/atomicity.h>
46 
47 namespace std
48 {
49   // Documentation?  What's that?
50   // Nathan Myers <[email protected]>.
51   //
52   // A string looks like this:
53   //
54   //                               	[_Rep]
55   //                               	_M_length
56   //  [basic_string<char_type>]		_M_capacity
57   //  _M_dataplus                	_M_state
58   //  _M_p ---------------->   		unnamed array of char_type
59 
60   // Where the _M_p points to the first character in the string, and
61   // you cast it to a pointer-to-_Rep and subtract 1 to get a
62   // pointer to the header.
63 
64   // This approach has the enormous advantage that a string object
65   // requires only one allocation.  All the ugliness is confined
66   // within a single pair of inline functions, which each compile to
67   // a single "add" instruction: _Rep::_M_data(), and
68   // string::_M_rep(); and the allocation function which gets a
69   // block of raw bytes and with room enough and constructs a _Rep
70   // object at the front.
71 
72   // The reason you want _M_data pointing to the character array and
73   // not the _Rep is so that the debugger can see the string
74   // contents. (Probably we should add a non-inline member to get
75   // the _Rep for the debugger to use, so users can check the actual
76   // string length.)
77 
78   // Note that the _Rep object is a POD so that you can have a
79   // static "empty string" _Rep object already "constructed" before
80   // static constructors have run.  The reference-count encoding is
81   // chosen so that a 0 indicates one reference, so you never try to
82   // destroy the empty-string _Rep object.
83 
84   // All but the last paragraph is considered pretty conventional
85   // for a C++ string implementation.
86 
87   // 21.3  Template class basic_string
88   template<typename _CharT, typename _Traits, typename _Alloc>
89     class basic_string
90     {
91       // Types:
92     public:
93       typedef _Traits 					    traits_type;
94       typedef typename _Traits::char_type 		    value_type;
95       typedef _Alloc 					    allocator_type;
96       typedef typename _Alloc::size_type 		    size_type;
97       typedef typename _Alloc::difference_type 		    difference_type;
98       typedef typename _Alloc::reference 		    reference;
99       typedef typename _Alloc::const_reference 		    const_reference;
100       typedef typename _Alloc::pointer 			    pointer;
101       typedef typename _Alloc::const_pointer 	   	    const_pointer;
102       typedef __gnu_cxx::__normal_iterator<pointer, basic_string>  iterator;
103       typedef __gnu_cxx::__normal_iterator<const_pointer, basic_string>
104                                                             const_iterator;
105       typedef reverse_iterator<const_iterator> 	const_reverse_iterator;
106       typedef reverse_iterator<iterator> 		    reverse_iterator;
107 
108     private:
109       // _Rep: string representation
110       //   Invariants:
111       //   1. String really contains _M_length + 1 characters; last is set
112       //      to 0 only on call to c_str().  We avoid instantiating
113       //      _CharT() where the interface does not require it.
114       //   2. _M_capacity >= _M_length
115       //      Allocated memory is always _M_capacity + (1 * sizeof(_CharT)).
116       //   3. _M_references has three states:
117       //      -1: leaked, one reference, no ref-copies allowed, non-const.
118       //       0: one reference, non-const.
119       //     n>0: n + 1 references, operations require a lock, const.
120       //   4. All fields==0 is an empty string, given the extra storage
121       //      beyond-the-end for a null terminator; thus, the shared
122       //      empty string representation needs no constructor.
123       struct _Rep
124       {
125 	// Types:
126 	typedef typename _Alloc::template rebind<char>::other _Raw_bytes_alloc;
127 
128 	// (Public) Data members:
129 
130 	// The maximum number of individual char_type elements of an
131 	// individual string is determined by _S_max_size. This is the
132 	// value that will be returned by max_size().  (Whereas npos
133 	// is the maximum number of bytes the allocator can allocate.)
134 	// If one was to divvy up the theoretical largest size string,
135 	// with a terminating character and m _CharT elements, it'd
136 	// look like this:
137 	// npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT)
138 	// Solving for m:
139 	// m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1
140 	// In addition, this implementation quarters this ammount.
141 	static const size_type 	_S_max_size;
142 	static const _CharT 	_S_terminal;
143 
144 	size_type 		_M_length;
145 	size_type 		_M_capacity;
146 	_Atomic_word		_M_references;
147 
148         bool
149 	_M_is_leaked() const
150         { return _M_references < 0; }
151 
152         bool
153 	_M_is_shared() const
154         { return _M_references > 0; }
155 
156         void
157 	_M_set_leaked()
158         { _M_references = -1; }
159 
160         void
161 	_M_set_sharable()
162         { _M_references = 0; }
163 
164 	_CharT*
165 	_M_refdata() throw()
166 	{ return reinterpret_cast<_CharT*>(this + 1); }
167 
168 	_CharT&
169 	operator[](size_t __s) throw()
170 	{ return _M_refdata() [__s]; }
171 
172 	_CharT*
173 	_M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2)
174 	{
175 	  return (!_M_is_leaked() && __alloc1 == __alloc2)
176 	          ? _M_refcopy() : _M_clone(__alloc1);
177 	}
178 
179 	// Create & Destroy
180 	static _Rep*
181 	_S_create(size_t, const _Alloc&);
182 
183 	void
184 	_M_dispose(const _Alloc& __a)
185 	{
186 	  if (__exchange_and_add(&_M_references, -1) <= 0)
187 	    _M_destroy(__a);
188 	}  // XXX MT
189 
190 	void
191 	_M_destroy(const _Alloc&) throw();
192 
193 	_CharT*
194 	_M_refcopy() throw()
195 	{
196 	  __atomic_add(&_M_references, 1);
197 	  return _M_refdata();
198 	}  // XXX MT
199 
200 	_CharT*
201 	_M_clone(const _Alloc&, size_type __res = 0);
202       };
203 
204       // Use empty-base optimization: http://www.cantrip.org/emptyopt.html
205       struct _Alloc_hider : _Alloc
206       {
207 	_Alloc_hider(_CharT* __dat, const _Alloc& __a)
208 	: _Alloc(__a), _M_p(__dat) { }
209 
210 	_CharT* _M_p; // The actual data.
211       };
212 
213     public:
214       // Data Members (public):
215       // NB: This is an unsigned type, and thus represents the maximum
216       // size that the allocator can hold.
217       static const size_type 	npos = static_cast<size_type>(-1);
218 
219     private:
220       // Data Members (private):
221       mutable _Alloc_hider 	_M_dataplus;
222 
223       // The following storage is init'd to 0 by the linker, resulting
224       // (carefully) in an empty string with one reference.
225       static size_type _S_empty_rep_storage[(sizeof(_Rep) + sizeof(_CharT) + sizeof(size_type) - 1)/sizeof(size_type)];
226 
227       _CharT*
228       _M_data() const
229       { return  _M_dataplus._M_p; }
230 
231       _CharT*
232       _M_data(_CharT* __p)
233       { return (_M_dataplus._M_p = __p); }
234 
235       _Rep*
236       _M_rep() const
237       { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); }
238 
239       // For the internal use we have functions similar to `begin'/`end'
240       // but they do not call _M_leak.
241       iterator
242       _M_ibegin() const { return iterator(_M_data()); }
243 
244       iterator
245       _M_iend() const { return iterator(_M_data() + this->size()); }
246 
247       void
248       _M_leak()    // for use in begin() & non-const op[]
249       {
250 	if (!_M_rep()->_M_is_leaked())
251 	  _M_leak_hard();
252       }
253 
254       iterator
255       _M_check(size_type __pos) const
256       {
257 	if (__pos > this->size())
258 	  __throw_out_of_range("basic_string::_M_check");
259 	return _M_ibegin() + __pos;
260       }
261 
262       // NB: _M_fold doesn't check for a bad __pos1 value.
263       iterator
264       _M_fold(size_type __pos, size_type __off) const
265       {
266 	bool __testoff =  __off < this->size() - __pos;
267 	size_type __newoff = __testoff ? __off : this->size() - __pos;
268 	return (_M_ibegin() + __pos + __newoff);
269       }
270 
271       // _S_copy_chars is a separate template to permit specialization
272       // to optimize for the common case of pointers as iterators.
273       template<class _Iterator>
274         static void
275         _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2)
276         {
277 	  for (; __k1 != __k2; ++__k1, ++__p)
278 	    traits_type::assign(*__p, *__k1); // These types are off.
279 	}
280 
281       static void
282       _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2)
283       { _S_copy_chars(__p, __k1.base(), __k2.base()); }
284 
285       static void
286       _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2)
287       { _S_copy_chars(__p, __k1.base(), __k2.base()); }
288 
289       static void
290       _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2)
291       { traits_type::copy(__p, __k1, __k2 - __k1); }
292 
293       static void
294       _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2)
295       { traits_type::copy(__p, __k1, __k2 - __k1); }
296 
297       void
298       _M_mutate(size_type __pos, size_type __len1, size_type __len2);
299 
300       void
301       _M_leak_hard();
302 
303       static _Rep&
304       _S_empty_rep()
305       { return *reinterpret_cast<_Rep*>(&_S_empty_rep_storage); }
306 
307     public:
308       // Construct/copy/destroy:
309       // NB: We overload ctors in some cases instead of using default
310       // arguments, per 17.4.4.4 para. 2 item 2.
311 
312       inline
313       basic_string();
314 
315       explicit
316       basic_string(const _Alloc& __a);
317 
318       // NB: per LWG issue 42, semantics different from IS:
319       basic_string(const basic_string& __str);
320       basic_string(const basic_string& __str, size_type __pos,
321 		   size_type __n = npos);
322       basic_string(const basic_string& __str, size_type __pos,
323 		   size_type __n, const _Alloc& __a);
324 
325       basic_string(const _CharT* __s, size_type __n,
326 		   const _Alloc& __a = _Alloc());
327       basic_string(const _CharT* __s, const _Alloc& __a = _Alloc());
328       basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc());
329 
330       template<class _InputIterator>
331         basic_string(_InputIterator __beg, _InputIterator __end,
332 		     const _Alloc& __a = _Alloc());
333 
334       ~basic_string()
335       { _M_rep()->_M_dispose(this->get_allocator()); }
336 
337       basic_string&
338       operator=(const basic_string& __str) { return this->assign(__str); }
339 
340       basic_string&
341       operator=(const _CharT* __s) { return this->assign(__s); }
342 
343       basic_string&
344       operator=(_CharT __c) { return this->assign(1, __c); }
345 
346       // Iterators:
347       iterator
348       begin()
349       {
350 	_M_leak();
351 	return iterator(_M_data());
352       }
353 
354       const_iterator
355       begin() const
356       { return const_iterator(_M_data()); }
357 
358       iterator
359       end()
360       {
361          _M_leak();
362 	 return iterator(_M_data() + this->size());
363       }
364 
365       const_iterator
366       end() const
367       { return const_iterator(_M_data() + this->size()); }
368 
369       reverse_iterator
370       rbegin()
371       { return reverse_iterator(this->end()); }
372 
373       const_reverse_iterator
374       rbegin() const
375       { return const_reverse_iterator(this->end()); }
376 
377       reverse_iterator
378       rend()
379       { return reverse_iterator(this->begin()); }
380 
381       const_reverse_iterator
382       rend() const
383       { return const_reverse_iterator(this->begin()); }
384 
385     public:
386       // Capacity:
387       size_type
388       size() const { return _M_rep()->_M_length; }
389 
390       size_type
391       length() const { return _M_rep()->_M_length; }
392 
393       size_type
394       max_size() const { return _Rep::_S_max_size; }
395 
396       void
397       resize(size_type __n, _CharT __c);
398 
399       void
400       resize(size_type __n) { this->resize(__n, _CharT()); }
401 
402       size_type
403       capacity() const { return _M_rep()->_M_capacity; }
404 
405       void
406       reserve(size_type __res_arg = 0);
407 
408       void
409       clear() { _M_mutate(0, this->size(), 0); }
410 
411       bool
412       empty() const { return this->size() == 0; }
413 
414       // Element access:
415       const_reference
416       operator[] (size_type __pos) const
417       { return _M_data()[__pos]; }
418 
419       reference
420       operator[](size_type __pos)
421       {
422 	_M_leak();
423 	return _M_data()[__pos];
424       }
425 
426       const_reference
427       at(size_type __n) const
428       {
429 	if (__n >= this->size())
430 	  __throw_out_of_range("basic_string::at");
431 	return _M_data()[__n];
432       }
433 
434       reference
435       at(size_type __n)
436       {
437 	if (__n >= size())
438 	  __throw_out_of_range("basic_string::at");
439 	_M_leak();
440 	return _M_data()[__n];
441       }
442 
443       // Modifiers:
444       basic_string&
445       operator+=(const basic_string& __str) { return this->append(__str); }
446 
447       basic_string&
448       operator+=(const _CharT* __s) { return this->append(__s); }
449 
450       basic_string&
451       operator+=(_CharT __c) { return this->append(size_type(1), __c); }
452 
453       basic_string&
454       append(const basic_string& __str);
455 
456       basic_string&
457       append(const basic_string& __str, size_type __pos, size_type __n);
458 
459       basic_string&
460       append(const _CharT* __s, size_type __n);
461 
462       basic_string&
463       append(const _CharT* __s)
464       { return this->append(__s, traits_type::length(__s)); }
465 
466       basic_string&
467       append(size_type __n, _CharT __c);
468 
469       template<class _InputIterator>
470         basic_string&
471         append(_InputIterator __first, _InputIterator __last)
472         { return this->replace(_M_iend(), _M_iend(), __first, __last); }
473 
474       void
475       push_back(_CharT __c)
476       { this->replace(_M_iend(), _M_iend(), 1, __c); }
477 
478       basic_string&
479       assign(const basic_string& __str);
480 
481       basic_string&
482       assign(const basic_string& __str, size_type __pos, size_type __n)
483       {
484 	const size_type __strsize = __str.size();
485 	if (__pos > __strsize)
486 	  __throw_out_of_range("basic_string::assign");
487 	const bool __testn = __n < __strsize - __pos;
488 	const size_type __newsize = __testn ? __n : __strsize - __pos;
489 	return this->assign(__str._M_data() + __pos, __newsize);
490       }
491 
492       basic_string&
493       assign(const _CharT* __s, size_type __n)
494       {
495 	if (__n > this->max_size())
496 	  __throw_length_error("basic_string::assign");
497 	if (_M_rep()->_M_is_shared() || less<const _CharT*>()(__s, _M_data())
498 	    || less<const _CharT*>()(_M_data() + this->size(), __s))
499 	  return _M_replace_safe(_M_ibegin(), _M_iend(), __s, __s + __n);
500 	else
501 	  {
502 	    // Work in-place
503 	    const size_type __pos = __s - _M_data();
504 	    if (__pos >= __n)
505 	      traits_type::copy(_M_data(), __s, __n);
506 	    else if (__pos)
507 	      traits_type::move(_M_data(), __s, __n);
508 	    _M_rep()->_M_length = __n;
509 	    _M_data()[__n] = _Rep::_S_terminal;
510 	    return *this;
511 	  }
512       }
513 
514       basic_string&
515       assign(const _CharT* __s)
516       { return this->assign(__s, traits_type::length(__s)); }
517 
518       basic_string&
519       assign(size_type __n, _CharT __c)
520       { return this->replace(_M_ibegin(), _M_iend(), __n, __c); }
521 
522       template<class _InputIterator>
523         basic_string&
524         assign(_InputIterator __first, _InputIterator __last)
525         { return this->replace(_M_ibegin(), _M_iend(), __first, __last); }
526 
527       void
528       insert(iterator __p, size_type __n, _CharT __c)
529       {	this->replace(__p, __p, __n, __c);  }
530 
531       template<class _InputIterator>
532         void insert(iterator __p, _InputIterator __beg, _InputIterator __end)
533         { this->replace(__p, __p, __beg, __end); }
534 
535       basic_string&
536       insert(size_type __pos1, const basic_string& __str)
537       { return this->insert(__pos1, __str, 0, __str.size()); }
538 
539       basic_string&
540       insert(size_type __pos1, const basic_string& __str,
541 	     size_type __pos2, size_type __n)
542       {
543 	const size_type __strsize = __str.size();
544  	if (__pos2 > __strsize)
545 	  __throw_out_of_range("basic_string::insert");
546 	const bool __testn = __n < __strsize - __pos2;
547 	const size_type __newsize = __testn ? __n : __strsize - __pos2;
548 	return this->insert(__pos1, __str._M_data() + __pos2, __newsize);
549       }
550 
551       basic_string&
552       insert(size_type __pos, const _CharT* __s, size_type __n)
553       {
554 	const size_type __size = this->size();
555  	if (__pos > __size)
556 	  __throw_out_of_range("basic_string::insert");
557 	if (__size > this->max_size() - __n)
558 	  __throw_length_error("basic_string::insert");
559 	if (_M_rep()->_M_is_shared() || less<const _CharT*>()(__s, _M_data())
560 	    || less<const _CharT*>()(_M_data() + __size, __s))
561 	  return _M_replace_safe(_M_ibegin() + __pos, _M_ibegin() + __pos,
562 				 __s, __s + __n);
563 	else
564 	  {
565 	    // Work in-place. If _M_mutate reallocates the string, __s
566 	    // does not point anymore to valid data, therefore we save its
567 	    // offset, then we restore it.
568 	    const size_type __off = __s - _M_data();
569 	    _M_mutate(__pos, 0, __n);
570 	    __s = _M_data() + __off;
571 	    _CharT* __p = _M_data() + __pos;
572 	    if (__s  + __n <= __p)
573 	      traits_type::copy(__p, __s, __n);
574 	    else if (__s >= __p)
575 	      traits_type::copy(__p, __s + __n, __n);
576 	    else
577 	      {
578 		traits_type::copy(__p, __s, __p - __s);
579 		traits_type::copy(__p + (__p - __s), __p + __n, __n - (__p - __s));
580 	      }
581 	    return *this;
582 	  }
583        }
584 
585       basic_string&
586       insert(size_type __pos, const _CharT* __s)
587       { return this->insert(__pos, __s, traits_type::length(__s)); }
588 
589       basic_string&
590       insert(size_type __pos, size_type __n, _CharT __c)
591       {
592 	this->insert(_M_check(__pos), __n, __c);
593 	return *this;
594       }
595 
596       iterator
597       insert(iterator __p, _CharT __c = _CharT())
598       {
599 	size_type __pos = __p - _M_ibegin();
600 	this->insert(_M_check(__pos), size_type(1), __c);
601 	_M_rep()->_M_set_leaked();
602  	return this->_M_ibegin() + __pos;
603       }
604 
605       basic_string&
606       erase(size_type __pos = 0, size_type __n = npos)
607       {
608 	return this->replace(_M_check(__pos), _M_fold(__pos, __n),
609 			     _M_data(), _M_data());
610       }
611 
612       iterator
613       erase(iterator __position)
614       {
615 	size_type __i = __position - _M_ibegin();
616         this->replace(__position, __position + 1, _M_data(), _M_data());
617 	_M_rep()->_M_set_leaked();
618 	return _M_ibegin() + __i;
619       }
620 
621       iterator
622       erase(iterator __first, iterator __last)
623       {
624         size_type __i = __first - _M_ibegin();
625 	this->replace(__first, __last, _M_data(), _M_data());
626 	_M_rep()->_M_set_leaked();
627        return _M_ibegin() + __i;
628       }
629 
630       basic_string&
631       replace(size_type __pos, size_type __n, const basic_string& __str)
632       { return this->replace(__pos, __n, __str._M_data(), __str.size()); }
633 
634       basic_string&
635       replace(size_type __pos1, size_type __n1, const basic_string& __str,
636 	      size_type __pos2, size_type __n2);
637 
638       basic_string&
639       replace(size_type __pos, size_type __n1, const _CharT* __s,
640 	      size_type __n2)
641       {
642 	const size_type __size = this->size();
643  	if (__pos > __size)
644 	  __throw_out_of_range("basic_string::replace");
645 	const bool __testn1 = __n1 < __size - __pos;
646 	const size_type __foldn1 = __testn1 ? __n1 : __size - __pos;
647 	if (__size - __foldn1 > this->max_size() - __n2)
648 	  __throw_length_error("basic_string::replace");
649 	if (_M_rep()->_M_is_shared() || less<const _CharT*>()(__s, _M_data())
650 	    || less<const _CharT*>()(_M_data() + __size, __s))
651 	  return _M_replace_safe(_M_ibegin() + __pos,
652 				 _M_ibegin() + __pos + __foldn1, __s, __s + __n2);
653 	// Todo: optimized in-place replace.
654 	else return
655 	       _M_replace(_M_ibegin() + __pos, _M_ibegin() + __pos + __foldn1,
656 			  __s, __s + __n2,
657 			  typename iterator_traits<const _CharT*>::iterator_category());
658       }
659 
660       basic_string&
661       replace(size_type __pos, size_type __n1, const _CharT* __s)
662       { return this->replace(__pos, __n1, __s, traits_type::length(__s)); }
663 
664       basic_string&
665       replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
666       { return this->replace(_M_check(__pos), _M_fold(__pos, __n1), __n2, __c); }
667 
668       basic_string&
669       replace(iterator __i1, iterator __i2, const basic_string& __str)
670       { return this->replace(__i1, __i2, __str._M_data(), __str.size()); }
671 
672       basic_string&
673       replace(iterator __i1, iterator __i2,
674                            const _CharT* __s, size_type __n)
675       { return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n); }
676 
677       basic_string&
678       replace(iterator __i1, iterator __i2, const _CharT* __s)
679       { return this->replace(__i1, __i2, __s, traits_type::length(__s)); }
680 
681       basic_string&
682       replace(iterator __i1, iterator __i2, size_type __n, _CharT __c);
683 
684       template<class _InputIterator>
685         basic_string&
686         replace(iterator __i1, iterator __i2,
687 		_InputIterator __k1, _InputIterator __k2)
688         { return _M_replace(__i1, __i2, __k1, __k2,
689 	     typename iterator_traits<_InputIterator>::iterator_category()); }
690 
691       // Specializations for the common case of pointer and iterator:
692       // useful to avoid the overhead of temporary buffering in _M_replace.
693       basic_string&
694       replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2)
695         { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
696 			       __k1, __k2 - __k1); }
697 
698       basic_string&
699       replace(iterator __i1, iterator __i2, const _CharT* __k1, const _CharT* __k2)
700         { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
701 			       __k1, __k2 - __k1); }
702 
703       basic_string&
704       replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2)
705         { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
706 			       __k1.base(), __k2 - __k1);
707 	}
708 
709       basic_string&
710       replace(iterator __i1, iterator __i2, const_iterator __k1, const_iterator __k2)
711         { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
712 			       __k1.base(), __k2 - __k1);
713 	}
714 
715     private:
716       template<class _InputIterator>
717         basic_string&
718         _M_replace(iterator __i1, iterator __i2, _InputIterator __k1,
719 		   _InputIterator __k2, input_iterator_tag);
720 
721       template<class _ForwardIterator>
722         basic_string&
723         _M_replace_safe(iterator __i1, iterator __i2, _ForwardIterator __k1,
724 		   _ForwardIterator __k2);
725 
726       // _S_construct_aux is used to implement the 21.3.1 para 15 which
727       // requires special behaviour if _InIter is an integral type
728       template<class _InIter>
729         static _CharT*
730         _S_construct_aux(_InIter __beg, _InIter __end, const _Alloc& __a,
731 			 __false_type)
732 	{
733           typedef typename iterator_traits<_InIter>::iterator_category _Tag;
734           return _S_construct(__beg, __end, __a, _Tag());
735 	}
736 
737       template<class _InIter>
738         static _CharT*
739         _S_construct_aux(_InIter __beg, _InIter __end, const _Alloc& __a,
740 			 __true_type)
741 	{
742 	  return _S_construct(static_cast<size_type>(__beg),
743 			      static_cast<value_type>(__end), __a);
744 	}
745 
746       template<class _InIter>
747         static _CharT*
748         _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a)
749 	{
750 	  typedef typename _Is_integer<_InIter>::_Integral _Integral;
751 	  return _S_construct_aux(__beg, __end, __a, _Integral());
752         }
753 
754       // For Input Iterators, used in istreambuf_iterators, etc.
755       template<class _InIter>
756         static _CharT*
757          _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a,
758 		      input_iterator_tag);
759 
760       // For forward_iterators up to random_access_iterators, used for
761       // string::iterator, _CharT*, etc.
762       template<class _FwdIter>
763         static _CharT*
764         _S_construct(_FwdIter __beg, _FwdIter __end, const _Alloc& __a,
765 		     forward_iterator_tag);
766 
767       static _CharT*
768       _S_construct(size_type __req, _CharT __c, const _Alloc& __a);
769 
770     public:
771 
772       size_type
773       copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
774 
775       void
776       swap(basic_string<_CharT, _Traits, _Alloc>& __s);
777 
778       // String operations:
779       const _CharT*
780       c_str() const
781       {
782 	// MT: This assumes concurrent writes are OK.
783 	size_type __n = this->size();
784 	traits_type::assign(_M_data()[__n], _Rep::_S_terminal);
785         return _M_data();
786       }
787 
788       const _CharT*
789       data() const { return _M_data(); }
790 
791       allocator_type
792       get_allocator() const { return _M_dataplus; }
793 
794       size_type
795       find(const _CharT* __s, size_type __pos, size_type __n) const;
796 
797       size_type
798       find(const basic_string& __str, size_type __pos = 0) const
799       { return this->find(__str.data(), __pos, __str.size()); }
800 
801       size_type
802       find(const _CharT* __s, size_type __pos = 0) const
803       { return this->find(__s, __pos, traits_type::length(__s)); }
804 
805       size_type
806       find(_CharT __c, size_type __pos = 0) const;
807 
808       size_type
809       rfind(const basic_string& __str, size_type __pos = npos) const
810       { return this->rfind(__str.data(), __pos, __str.size()); }
811 
812       size_type
813       rfind(const _CharT* __s, size_type __pos, size_type __n) const;
814 
815       size_type
816       rfind(const _CharT* __s, size_type __pos = npos) const
817       { return this->rfind(__s, __pos, traits_type::length(__s)); }
818 
819       size_type
820       rfind(_CharT __c, size_type __pos = npos) const;
821 
822       size_type
823       find_first_of(const basic_string& __str, size_type __pos = 0) const
824       { return this->find_first_of(__str.data(), __pos, __str.size()); }
825 
826       size_type
827       find_first_of(const _CharT* __s, size_type __pos, size_type __n) const;
828 
829       size_type
830       find_first_of(const _CharT* __s, size_type __pos = 0) const
831       { return this->find_first_of(__s, __pos, traits_type::length(__s)); }
832 
833       size_type
834       find_first_of(_CharT __c, size_type __pos = 0) const
835       { return this->find(__c, __pos); }
836 
837       size_type
838       find_last_of(const basic_string& __str, size_type __pos = npos) const
839       { return this->find_last_of(__str.data(), __pos, __str.size()); }
840 
841       size_type
842       find_last_of(const _CharT* __s, size_type __pos, size_type __n) const;
843 
844       size_type
845       find_last_of(const _CharT* __s, size_type __pos = npos) const
846       { return this->find_last_of(__s, __pos, traits_type::length(__s)); }
847 
848       size_type
849       find_last_of(_CharT __c, size_type __pos = npos) const
850       { return this->rfind(__c, __pos); }
851 
852       size_type
853       find_first_not_of(const basic_string& __str, size_type __pos = 0) const
854       { return this->find_first_not_of(__str.data(), __pos, __str.size()); }
855 
856       size_type
857       find_first_not_of(const _CharT* __s, size_type __pos,
858 			size_type __n) const;
859 
860       size_type
861       find_first_not_of(const _CharT* __s, size_type __pos = 0) const
862       { return this->find_first_not_of(__s, __pos, traits_type::length(__s)); }
863 
864       size_type
865       find_first_not_of(_CharT __c, size_type __pos = 0) const;
866 
867       size_type
868       find_last_not_of(const basic_string& __str, size_type __pos = npos) const
869       { return this->find_last_not_of(__str.data(), __pos, __str.size()); }
870 
871       size_type
872       find_last_not_of(const _CharT* __s, size_type __pos,
873 		       size_type __n) const;
874       size_type
875       find_last_not_of(const _CharT* __s, size_type __pos = npos) const
876       { return this->find_last_not_of(__s, __pos, traits_type::length(__s)); }
877 
878       size_type
879       find_last_not_of(_CharT __c, size_type __pos = npos) const;
880 
881       basic_string
882       substr(size_type __pos = 0, size_type __n = npos) const
883       {
884 	if (__pos > this->size())
885 	  __throw_out_of_range("basic_string::substr");
886 	return basic_string(*this, __pos, __n);
887       }
888 
889       int
890       compare(const basic_string& __str) const
891       {
892 	size_type __size = this->size();
893 	size_type __osize = __str.size();
894 	size_type __len = min(__size, __osize);
895 
896 	int __r = traits_type::compare(_M_data(), __str.data(), __len);
897 	if (!__r)
898 	  __r =  __size - __osize;
899 	return __r;
900       }
901 
902       int
903       compare(size_type __pos, size_type __n, const basic_string& __str) const;
904 
905       int
906       compare(size_type __pos1, size_type __n1, const basic_string& __str,
907 	      size_type __pos2, size_type __n2) const;
908 
909       int
910       compare(const _CharT* __s) const;
911 
912       // _GLIBCPP_RESOLVE_LIB_DEFECTS
913       // 5. String::compare specification questionable
914       int
915       compare(size_type __pos, size_type __n1, const _CharT* __s) const;
916 
917       int
918       compare(size_type __pos, size_type __n1, const _CharT* __s,
919 	      size_type __n2) const;
920   };
921 
922 
923   template<typename _CharT, typename _Traits, typename _Alloc>
924     inline basic_string<_CharT, _Traits, _Alloc>::
925     basic_string()
926     : _M_dataplus(_S_empty_rep()._M_refcopy(), _Alloc()) { }
927 
928   // operator+
929   template<typename _CharT, typename _Traits, typename _Alloc>
930     basic_string<_CharT, _Traits, _Alloc>
931     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
932 	      const basic_string<_CharT, _Traits, _Alloc>& __rhs)
933     {
934       basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
935       __str.append(__rhs);
936       return __str;
937     }
938 
939   template<typename _CharT, typename _Traits, typename _Alloc>
940     basic_string<_CharT,_Traits,_Alloc>
941     operator+(const _CharT* __lhs,
942 	      const basic_string<_CharT,_Traits,_Alloc>& __rhs);
943 
944   template<typename _CharT, typename _Traits, typename _Alloc>
945     basic_string<_CharT,_Traits,_Alloc>
946     operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs);
947 
948   template<typename _CharT, typename _Traits, typename _Alloc>
949     inline basic_string<_CharT, _Traits, _Alloc>
950     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
951 	     const _CharT* __rhs)
952     {
953       basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
954       __str.append(__rhs);
955       return __str;
956     }
957 
958   template<typename _CharT, typename _Traits, typename _Alloc>
959     inline basic_string<_CharT, _Traits, _Alloc>
960     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs)
961     {
962       typedef basic_string<_CharT, _Traits, _Alloc> 	__string_type;
963       typedef typename __string_type::size_type		__size_type;
964       __string_type __str(__lhs);
965       __str.append(__size_type(1), __rhs);
966       return __str;
967     }
968 
969   // operator ==
970   template<typename _CharT, typename _Traits, typename _Alloc>
971     inline bool
972     operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
973 	       const basic_string<_CharT, _Traits, _Alloc>& __rhs)
974     { return __lhs.compare(__rhs) == 0; }
975 
976   template<typename _CharT, typename _Traits, typename _Alloc>
977     inline bool
978     operator==(const _CharT* __lhs,
979 	       const basic_string<_CharT, _Traits, _Alloc>& __rhs)
980     { return __rhs.compare(__lhs) == 0; }
981 
982   template<typename _CharT, typename _Traits, typename _Alloc>
983     inline bool
984     operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
985 	       const _CharT* __rhs)
986     { return __lhs.compare(__rhs) == 0; }
987 
988   // operator !=
989   template<typename _CharT, typename _Traits, typename _Alloc>
990     inline bool
991     operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
992 	       const basic_string<_CharT, _Traits, _Alloc>& __rhs)
993     { return __rhs.compare(__lhs) != 0; }
994 
995   template<typename _CharT, typename _Traits, typename _Alloc>
996     inline bool
997     operator!=(const _CharT* __lhs,
998 	       const basic_string<_CharT, _Traits, _Alloc>& __rhs)
999     { return __rhs.compare(__lhs) != 0; }
1000 
1001   template<typename _CharT, typename _Traits, typename _Alloc>
1002     inline bool
1003     operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
1004 	       const _CharT* __rhs)
1005     { return __lhs.compare(__rhs) != 0; }
1006 
1007   // operator <
1008   template<typename _CharT, typename _Traits, typename _Alloc>
1009     inline bool
1010     operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
1011 	      const basic_string<_CharT, _Traits, _Alloc>& __rhs)
1012     { return __lhs.compare(__rhs) < 0; }
1013 
1014   template<typename _CharT, typename _Traits, typename _Alloc>
1015     inline bool
1016     operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
1017 	      const _CharT* __rhs)
1018     { return __lhs.compare(__rhs) < 0; }
1019 
1020   template<typename _CharT, typename _Traits, typename _Alloc>
1021     inline bool
1022     operator<(const _CharT* __lhs,
1023 	      const basic_string<_CharT, _Traits, _Alloc>& __rhs)
1024     { return __rhs.compare(__lhs) > 0; }
1025 
1026   // operator >
1027   template<typename _CharT, typename _Traits, typename _Alloc>
1028     inline bool
1029     operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
1030 	      const basic_string<_CharT, _Traits, _Alloc>& __rhs)
1031     { return __lhs.compare(__rhs) > 0; }
1032 
1033   template<typename _CharT, typename _Traits, typename _Alloc>
1034     inline bool
1035     operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
1036 	      const _CharT* __rhs)
1037     { return __lhs.compare(__rhs) > 0; }
1038 
1039   template<typename _CharT, typename _Traits, typename _Alloc>
1040     inline bool
1041     operator>(const _CharT* __lhs,
1042 	      const basic_string<_CharT, _Traits, _Alloc>& __rhs)
1043     { return __rhs.compare(__lhs) < 0; }
1044 
1045   // operator <=
1046   template<typename _CharT, typename _Traits, typename _Alloc>
1047     inline bool
1048     operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
1049 	       const basic_string<_CharT, _Traits, _Alloc>& __rhs)
1050     { return __lhs.compare(__rhs) <= 0; }
1051 
1052   template<typename _CharT, typename _Traits, typename _Alloc>
1053     inline bool
1054     operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
1055 	       const _CharT* __rhs)
1056     { return __lhs.compare(__rhs) <= 0; }
1057 
1058   template<typename _CharT, typename _Traits, typename _Alloc>
1059     inline bool
1060     operator<=(const _CharT* __lhs,
1061 	       const basic_string<_CharT, _Traits, _Alloc>& __rhs)
1062   { return __rhs.compare(__lhs) >= 0; }
1063 
1064   // operator >=
1065   template<typename _CharT, typename _Traits, typename _Alloc>
1066     inline bool
1067     operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
1068 	       const basic_string<_CharT, _Traits, _Alloc>& __rhs)
1069     { return __lhs.compare(__rhs) >= 0; }
1070 
1071   template<typename _CharT, typename _Traits, typename _Alloc>
1072     inline bool
1073     operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
1074 	       const _CharT* __rhs)
1075     { return __lhs.compare(__rhs) >= 0; }
1076 
1077   template<typename _CharT, typename _Traits, typename _Alloc>
1078     inline bool
1079     operator>=(const _CharT* __lhs,
1080 	     const basic_string<_CharT, _Traits, _Alloc>& __rhs)
1081     { return __rhs.compare(__lhs) <= 0; }
1082 
1083 
1084   template<typename _CharT, typename _Traits, typename _Alloc>
1085     inline void
1086     swap(basic_string<_CharT, _Traits, _Alloc>& __lhs,
1087 	 basic_string<_CharT, _Traits, _Alloc>& __rhs)
1088     { __lhs.swap(__rhs); }
1089 
1090   template<typename _CharT, typename _Traits, typename _Alloc>
1091     basic_istream<_CharT, _Traits>&
1092     operator>>(basic_istream<_CharT, _Traits>& __is,
1093 	       basic_string<_CharT, _Traits, _Alloc>& __str);
1094 
1095   template<typename _CharT, typename _Traits, typename _Alloc>
1096     basic_ostream<_CharT, _Traits>&
1097     operator<<(basic_ostream<_CharT, _Traits>& __os,
1098 	       const basic_string<_CharT, _Traits, _Alloc>& __str);
1099 
1100   template<typename _CharT, typename _Traits, typename _Alloc>
1101     basic_istream<_CharT,_Traits>&
1102     getline(basic_istream<_CharT, _Traits>& __is,
1103 	    basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim);
1104 
1105   template<typename _CharT, typename _Traits, typename _Alloc>
1106     inline basic_istream<_CharT,_Traits>&
1107     getline(basic_istream<_CharT, _Traits>& __is,
1108 	    basic_string<_CharT, _Traits, _Alloc>& __str);
1109 } // namespace std
1110 
1111 #endif /* _CPP_BITS_STRING_H */
1112