Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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