backport: basic_string.h: Qualify symbols with 'template'.
[official-gcc.git] / libstdc++-v3 / include / bits / basic_string.h
blobdc62a542e5e03c920ac992d4079be48a55da8551
1 // Components for manipulating sequences of characters -*- C++ -*-
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.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING. If not, write to the Free
18 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 // USA.
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
31 // ISO C++ 14882: 21 Strings library
34 #ifndef _CPP_BITS_STRING_H
35 #define _CPP_BITS_STRING_H 1
37 #pragma GCC system_header
39 #include <bits/atomicity.h>
41 namespace std
44 // Documentation? What's that?
45 // Nathan Myers <ncm@cantrip.org>.
47 // A string looks like this:
49 // [_Rep]
50 // _M_length
51 // [basic_string<char_type>] _M_capacity
52 // _M_dataplus _M_state
53 // _M_p ----------------> unnamed array of char_type
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.
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.
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.)
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.
79 // All but the last paragraph is considered pretty conventional
80 // for a C++ string implementation.
82 // 21.3 Template class basic_string
83 template<typename _CharT, typename _Traits, typename _Alloc>
84 class basic_string
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<pointer, basic_string> iterator;
98 typedef __normal_iterator<const_pointer, basic_string> const_iterator;
99 typedef reverse_iterator<const_iterator> const_reverse_iterator;
100 typedef reverse_iterator<iterator> reverse_iterator;
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.
118 struct _Rep
120 // Types:
121 typedef typename _Alloc::template rebind<char>::other _Raw_bytes_alloc;
123 // (Public) Data members:
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;
139 size_type _M_length;
140 size_type _M_capacity;
141 _Atomic_word _M_references;
143 bool
144 _M_is_leaked() const
145 { return _M_references < 0; }
147 bool
148 _M_is_shared() const
149 { return _M_references > 0; }
151 void
152 _M_set_leaked()
153 { _M_references = -1; }
155 void
156 _M_set_sharable()
157 { _M_references = 0; }
159 _CharT*
160 _M_refdata() throw()
161 { return reinterpret_cast<_CharT*> (this + 1); }
163 _CharT&
164 operator[](size_t __s) throw()
165 { return _M_refdata() [__s]; }
167 _CharT*
168 _M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2)
169 { return (!_M_is_leaked() && __alloc1 == __alloc2) ?
170 _M_refcopy() : _M_clone(__alloc1); }
172 // Create & Destroy
173 static _Rep*
174 _S_create(size_t, const _Alloc&);
176 void
177 _M_dispose(const _Alloc& __a)
179 if (__exchange_and_add(&_M_references, -1) <= 0)
180 _M_destroy(__a);
181 } // XXX MT
183 void
184 _M_destroy(const _Alloc&) throw();
186 _CharT*
187 _M_refcopy() throw()
189 __atomic_add(&_M_references, 1);
190 return _M_refdata();
191 } // XXX MT
193 _CharT*
194 _M_clone(const _Alloc&, size_type __res = 0);
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.
202 // Returns true if ALLOCATED is too much larger than LENGTH
203 static bool (*_S_excess_slop) (size_t __length, size_t __allocated);
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
213 // Use empty-base optimization: http://www.cantrip.org/emptyopt.html
214 struct _Alloc_hider : _Alloc
216 _Alloc_hider(_CharT* __dat, const _Alloc& __a)
217 : _Alloc(__a), _M_p(__dat) { }
219 _CharT* _M_p; // The actual data.
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<size_type>(-1);
228 private:
229 // Data Members (private):
230 mutable _Alloc_hider _M_dataplus;
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)];
236 _CharT*
237 _M_data() const
238 { return _M_dataplus._M_p; }
240 _CharT*
241 _M_data(_CharT* __p)
242 { return (_M_dataplus._M_p = __p); }
244 _Rep*
245 _M_rep() const
246 { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); }
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()); }
253 iterator
254 _M_iend() const { return iterator(_M_data() + this->size()); }
256 void
257 _M_leak() // for use in begin() & non-const op[]
259 if (!_M_rep()->_M_is_leaked())
260 _M_leak_hard();
263 iterator
264 _M_check(size_type __pos) const
266 if (__pos > this->size())
267 __throw_out_of_range("basic_string::_M_check");
268 return _M_ibegin() + __pos;
271 // NB: _M_fold doesn't check for a bad __pos1 value.
272 iterator
273 _M_fold(size_type __pos, size_type __off) const
275 bool __testoff = __off < this->size() - __pos;
276 size_type __newoff = __testoff ? __off : this->size() - __pos;
277 return (_M_ibegin() + __pos + __newoff);
280 // _S_copy_chars is a separate template to permit specialization
281 // to optimize for the common case of pointers as iterators.
282 template<class _Iterator>
283 static void
284 _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2)
286 for (; __k1 != __k2; ++__k1, ++__p)
287 traits_type::assign(*__p, *__k1); //these types are off
290 static void
291 _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2)
292 { _S_copy_chars(__p, __k1.base(), __k2.base()); }
294 static void
295 _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2)
296 { _S_copy_chars(__p, __k1.base(), __k2.base()); }
298 static void
299 _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2)
300 { traits_type::copy(__p, __k1, __k2 - __k1); }
302 static void
303 _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2)
304 { traits_type::copy(__p, __k1, __k2 - __k1); }
306 void
307 _M_mutate(size_type __pos, size_type __len1, size_type __len2);
309 void
310 _M_leak_hard();
312 static _Rep&
313 _S_empty_rep()
314 { return *reinterpret_cast<_Rep*>(&_S_empty_rep_storage); }
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.
321 inline
322 basic_string();
324 explicit
325 basic_string(const _Alloc& __a);
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);
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());
339 template<class _InputIterator>
340 basic_string(_InputIterator __begin, _InputIterator __end,
341 const _Alloc& __a = _Alloc());
343 ~basic_string()
344 { _M_rep()->_M_dispose(this->get_allocator()); }
346 basic_string&
347 operator=(const basic_string& __str) { return this->assign(__str); }
349 basic_string&
350 operator=(const _CharT* __s) { return this->assign(__s); }
352 basic_string&
353 operator=(_CharT __c) { return this->assign(1, __c); }
355 // Iterators:
356 iterator
357 begin()
359 _M_leak();
360 return iterator(_M_data());
363 const_iterator
364 begin() const
365 { return const_iterator(_M_data()); }
367 iterator
368 end()
370 _M_leak();
371 return iterator(_M_data() + this->size());
374 const_iterator
375 end() const
376 { return const_iterator(_M_data() + this->size()); }
378 reverse_iterator
379 rbegin()
380 { return reverse_iterator(this->end()); }
382 const_reverse_iterator
383 rbegin() const
384 { return const_reverse_iterator(this->end()); }
386 reverse_iterator
387 rend()
388 { return reverse_iterator(this->begin()); }
390 const_reverse_iterator
391 rend() const
392 { return const_reverse_iterator(this->begin()); }
394 public:
395 // Capacity:
396 size_type
397 size() const { return _M_rep()->_M_length; }
399 size_type
400 length() const { return _M_rep()->_M_length; }
402 size_type
403 max_size() const { return _Rep::_S_max_size; }
405 void
406 resize(size_type __n, _CharT __c);
408 void
409 resize(size_type __n) { this->resize(__n, _CharT()); }
411 size_type
412 capacity() const { return _M_rep()->_M_capacity; }
414 void
415 reserve(size_type __res_arg = 0);
417 void
418 clear() { _M_mutate(0, this->size(), 0); }
420 bool
421 empty() const { return this->size() == 0; }
423 // Element access:
424 const_reference
425 operator[] (size_type __pos) const
426 { return _M_data()[__pos]; }
428 reference
429 operator[](size_type __pos)
431 _M_leak();
432 return _M_data()[__pos];
435 const_reference
436 at(size_type __n) const
438 if (__n >= this->size())
439 __throw_out_of_range("basic_string::at");
440 return _M_data()[__n];
443 reference
444 at(size_type __n)
446 if (__n >= size())
447 __throw_out_of_range("basic_string::at");
448 _M_leak();
449 return _M_data()[__n];
452 // Modifiers:
453 basic_string&
454 operator+=(const basic_string& __str) { return this->append(__str); }
456 basic_string&
457 operator+=(const _CharT* __s) { return this->append(__s); }
459 basic_string&
460 operator+=(_CharT __c) { return this->append(size_type(1), __c); }
462 basic_string&
463 append(const basic_string& __str);
465 basic_string&
466 append(const basic_string& __str, size_type __pos, size_type __n);
468 basic_string&
469 append(const _CharT* __s, size_type __n);
471 basic_string&
472 append(const _CharT* __s)
473 { return this->append(__s, traits_type::length(__s)); }
475 basic_string&
476 append(size_type __n, _CharT __c);
478 template<class _InputIterator>
479 basic_string&
480 append(_InputIterator __first, _InputIterator __last)
481 { return this->replace(_M_iend(), _M_iend(), __first, __last); }
483 void
484 push_back(_CharT __c)
485 { this->replace(_M_iend(), _M_iend(), 1, __c); }
487 basic_string&
488 assign(const basic_string& __str);
490 basic_string&
491 assign(const basic_string& __str, size_type __pos, size_type __n)
493 return this->assign(__str._M_check(__pos), __str._M_fold(__pos, __n));
496 basic_string&
497 assign(const _CharT* __s, size_type __n)
498 { return this->assign(__s, __s + __n); }
500 basic_string&
501 assign(const _CharT* __s)
502 { return this->assign(__s, __s + traits_type::length(__s)); }
504 basic_string&
505 assign(size_type __n, _CharT __c)
506 { return this->replace(_M_ibegin(), _M_iend(), __n, __c); }
508 template<class _InputIterator>
509 basic_string&
510 assign(_InputIterator __first, _InputIterator __last)
511 { return this->replace(_M_ibegin(), _M_iend(), __first, __last); }
513 void
514 insert(iterator __p, size_type __n, _CharT __c)
515 { this->replace(__p, __p, __n, __c); }
517 template<class _InputIterator>
518 void insert(iterator __p, _InputIterator __beg, _InputIterator __end)
519 { this->replace(__p, __p, __beg, __end); }
521 basic_string&
522 insert(size_type __pos1, const basic_string& __str)
524 iterator __p = _M_check(__pos1);
525 this->replace(__p, __p, __str._M_ibegin(), __str._M_iend());
526 return *this;
529 basic_string&
530 insert(size_type __pos1, const basic_string& __str,
531 size_type __pos2, size_type __n)
533 iterator __p = _M_check(__pos1);
534 this->replace(__p, __p, __str._M_check(__pos2),
535 __str._M_fold(__pos2, __n));
536 return *this;
539 basic_string&
540 insert(size_type __pos, const _CharT* __s, size_type __n)
542 iterator __p = _M_check(__pos);
543 this->replace(__p, __p, __s, __s + __n);
544 return *this;
547 basic_string&
548 insert(size_type __pos, const _CharT* __s)
549 { return this->insert(__pos, __s, traits_type::length(__s)); }
551 basic_string&
552 insert(size_type __pos, size_type __n, _CharT __c)
554 this->insert(_M_check(__pos), __n, __c);
555 return *this;
558 iterator
559 insert(iterator __p, _CharT __c = _CharT())
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;
567 basic_string&
568 erase(size_type __pos = 0, size_type __n = npos)
570 return this->replace(_M_check(__pos), _M_fold(__pos, __n),
571 _M_data(), _M_data());
574 iterator
575 erase(iterator __position)
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;
583 iterator
584 erase(iterator __first, iterator __last)
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;
592 basic_string&
593 replace(size_type __pos, size_type __n, const basic_string& __str)
595 return this->replace(_M_check(__pos), _M_fold(__pos, __n),
596 __str.begin(), __str.end());
599 basic_string&
600 replace(size_type __pos1, size_type __n1, const basic_string& __str,
601 size_type __pos2, size_type __n2);
603 basic_string&
604 replace(size_type __pos, size_type __n1, const _CharT* __s,
605 size_type __n2)
607 return this->replace(_M_check(__pos), _M_fold(__pos, __n1),
608 __s, __s + __n2);
611 basic_string&
612 replace(size_type __pos, size_type __n1, const _CharT* __s)
614 return this->replace(_M_check(__pos), _M_fold(__pos, __n1),
615 __s, __s + traits_type::length(__s));
618 basic_string&
619 replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
621 return this->replace(_M_check(__pos), _M_fold(__pos, __n1), __n2, __c);
624 basic_string&
625 replace(iterator __i1, iterator __i2, const basic_string& __str)
626 { return this->replace(__i1, __i2, __str.begin(), __str.end()); }
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); }
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)); }
638 basic_string&
639 replace(iterator __i1, iterator __i2, size_type __n, _CharT __c);
641 template<class _InputIterator>
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()); }
648 private:
649 template<class _InputIterator>
650 basic_string&
651 _M_replace(iterator __i1, iterator __i2, _InputIterator __k1,
652 _InputIterator __k2, input_iterator_tag);
654 template<class _FwdIterator>
655 basic_string&
656 _M_replace(iterator __i1, iterator __i2, _FwdIterator __k1,
657 _FwdIterator __k2, forward_iterator_tag);
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<class _InIter>
662 static _CharT*
663 _S_construct_aux(_InIter __beg, _InIter __end, const _Alloc& __a,
664 __false_type)
666 typedef typename iterator_traits<_InIter>::iterator_category _Tag;
667 return _S_construct(__beg, __end, __a, _Tag());
670 template<class _InIter>
671 static _CharT*
672 _S_construct_aux(_InIter __beg, _InIter __end, const _Alloc& __a,
673 __true_type)
675 return _S_construct(static_cast<size_type>(__beg),
676 static_cast<value_type>(__end), __a);
679 template<class _InIter>
680 static _CharT*
681 _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a)
683 typedef typename _Is_integer<_InIter>::_Integral _Integral;
684 return _S_construct_aux(__beg, __end, __a, _Integral());
687 // For Input Iterators, used in istreambuf_iterators, etc.
688 template<class _InIter>
689 static _CharT*
690 _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a,
691 input_iterator_tag);
693 // For forward_iterators up to random_access_iterators, used for
694 // string::iterator, _CharT*, etc.
695 template<class _FwdIter>
696 static _CharT*
697 _S_construct(_FwdIter __end, _FwdIter __beg, const _Alloc& __a,
698 forward_iterator_tag);
700 static _CharT*
701 _S_construct(size_type __req, _CharT __c, const _Alloc& __a);
703 public:
705 size_type
706 copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
708 void
709 swap(basic_string<_CharT, _Traits, _Alloc>& __s);
711 // String operations:
712 const _CharT*
713 c_str() const
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();
721 const _CharT*
722 data() const { return _M_data(); }
724 allocator_type
725 get_allocator() const { return _M_dataplus; }
727 size_type
728 find(const _CharT* __s, size_type __pos, size_type __n) const;
730 size_type
731 find(const basic_string& __str, size_type __pos = 0) const
732 { return this->find(__str.data(), __pos, __str.size()); }
734 size_type
735 find(const _CharT* __s, size_type __pos = 0) const
736 { return this->find(__s, __pos, traits_type::length(__s)); }
738 size_type
739 find(_CharT __c, size_type __pos = 0) const;
741 size_type
742 rfind(const basic_string& __str, size_type __pos = npos) const
743 { return this->rfind(__str.data(), __pos, __str.size()); }
745 size_type
746 rfind(const _CharT* __s, size_type __pos, size_type __n) const;
748 size_type
749 rfind(const _CharT* __s, size_type __pos = npos) const
750 { return this->rfind(__s, __pos, traits_type::length(__s)); }
752 size_type
753 rfind(_CharT __c, size_type __pos = npos) const;
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()); }
759 size_type
760 find_first_of(const _CharT* __s, size_type __pos, size_type __n) const;
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)); }
766 size_type
767 find_first_of(_CharT __c, size_type __pos = 0) const
768 { return this->find(__c, __pos); }
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()); }
774 size_type
775 find_last_of(const _CharT* __s, size_type __pos, size_type __n) const;
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)); }
781 size_type
782 find_last_of(_CharT __c, size_type __pos = npos) const
783 { return this->rfind(__c, __pos); }
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()); }
789 size_type
790 find_first_not_of(const _CharT* __s, size_type __pos,
791 size_type __n) const;
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)); }
797 size_type
798 find_first_not_of(_CharT __c, size_type __pos = 0) const;
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()); }
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)); }
811 size_type
812 find_last_not_of(_CharT __c, size_type __pos = npos) const;
814 basic_string
815 substr(size_type __pos = 0, size_type __n = npos) const
817 if (__pos > this->size())
818 __throw_out_of_range("basic_string::substr");
819 return basic_string(*this, __pos, __n);
822 int
823 compare(const basic_string& __str) const
825 size_type __size = this->size();
826 size_type __osize = __str.size();
827 size_type __len = min(__size, __osize);
829 int __r = traits_type::compare(_M_data(), __str.data(), __len);
830 if (!__r)
831 __r = __size - __osize;
832 return __r;
835 int
836 compare(size_type __pos, size_type __n, const basic_string& __str) const;
838 int
839 compare(size_type __pos1, size_type __n1, const basic_string& __str,
840 size_type __pos2, size_type __n2) const;
842 int
843 compare(const _CharT* __s) const;
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;
850 int
851 compare(size_type __pos, size_type __n1, const _CharT* __s,
852 size_type __n2) const;
853 #endif
857 template<typename _CharT, typename _Traits, typename _Alloc>
858 inline basic_string<_CharT, _Traits, _Alloc>::
859 basic_string()
860 : _M_dataplus(_S_empty_rep()._M_refcopy(), _Alloc()) { }
862 // operator+
863 template<typename _CharT, typename _Traits, typename _Alloc>
864 basic_string<_CharT, _Traits, _Alloc>
865 operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
866 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
868 basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
869 __str.append(__rhs);
870 return __str;
873 template<typename _CharT, typename _Traits, typename _Alloc>
874 basic_string<_CharT,_Traits,_Alloc>
875 operator+(const _CharT* __lhs,
876 const basic_string<_CharT,_Traits,_Alloc>& __rhs);
878 template<typename _CharT, typename _Traits, typename _Alloc>
879 basic_string<_CharT,_Traits,_Alloc>
880 operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs);
882 template<typename _CharT, typename _Traits, typename _Alloc>
883 inline basic_string<_CharT, _Traits, _Alloc>
884 operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
885 const _CharT* __rhs)
887 basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
888 __str.append(__rhs);
889 return __str;
892 template<typename _CharT, typename _Traits, typename _Alloc>
893 inline basic_string<_CharT, _Traits, _Alloc>
894 operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs)
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;
903 // operator ==
904 template<typename _CharT, typename _Traits, typename _Alloc>
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; }
910 template<typename _CharT, typename _Traits, typename _Alloc>
911 inline bool
912 operator==(const _CharT* __lhs,
913 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
914 { return __rhs.compare(__lhs) == 0; }
916 template<typename _CharT, typename _Traits, typename _Alloc>
917 inline bool
918 operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
919 const _CharT* __rhs)
920 { return __lhs.compare(__rhs) == 0; }
922 // operator !=
923 template<typename _CharT, typename _Traits, typename _Alloc>
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; }
929 template<typename _CharT, typename _Traits, typename _Alloc>
930 inline bool
931 operator!=(const _CharT* __lhs,
932 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
933 { return __rhs.compare(__lhs) != 0; }
935 template<typename _CharT, typename _Traits, typename _Alloc>
936 inline bool
937 operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
938 const _CharT* __rhs)
939 { return __lhs.compare(__rhs) != 0; }
941 // operator <
942 template<typename _CharT, typename _Traits, typename _Alloc>
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; }
948 template<typename _CharT, typename _Traits, typename _Alloc>
949 inline bool
950 operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
951 const _CharT* __rhs)
952 { return __lhs.compare(__rhs) < 0; }
954 template<typename _CharT, typename _Traits, typename _Alloc>
955 inline bool
956 operator<(const _CharT* __lhs,
957 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
958 { return __rhs.compare(__lhs) > 0; }
960 // operator >
961 template<typename _CharT, typename _Traits, typename _Alloc>
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; }
967 template<typename _CharT, typename _Traits, typename _Alloc>
968 inline bool
969 operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
970 const _CharT* __rhs)
971 { return __lhs.compare(__rhs) > 0; }
973 template<typename _CharT, typename _Traits, typename _Alloc>
974 inline bool
975 operator>(const _CharT* __lhs,
976 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
977 { return __rhs.compare(__lhs) < 0; }
979 // operator <=
980 template<typename _CharT, typename _Traits, typename _Alloc>
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; }
986 template<typename _CharT, typename _Traits, typename _Alloc>
987 inline bool
988 operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
989 const _CharT* __rhs)
990 { return __lhs.compare(__rhs) <= 0; }
992 template<typename _CharT, typename _Traits, typename _Alloc>
993 inline bool
994 operator<=(const _CharT* __lhs,
995 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
996 { return __rhs.compare(__lhs) >= 0; }
998 // operator >=
999 template<typename _CharT, typename _Traits, typename _Alloc>
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; }
1005 template<typename _CharT, typename _Traits, typename _Alloc>
1006 inline bool
1007 operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
1008 const _CharT* __rhs)
1009 { return __lhs.compare(__rhs) >= 0; }
1011 template<typename _CharT, typename _Traits, typename _Alloc>
1012 inline bool
1013 operator>=(const _CharT* __lhs,
1014 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
1015 { return __rhs.compare(__lhs) <= 0; }
1018 template<typename _CharT, typename _Traits, typename _Alloc>
1019 inline void
1020 swap(basic_string<_CharT, _Traits, _Alloc>& __lhs,
1021 basic_string<_CharT, _Traits, _Alloc>& __rhs)
1022 { __lhs.swap(__rhs); }
1024 template<typename _CharT, typename _Traits, typename _Alloc>
1025 basic_istream<_CharT, _Traits>&
1026 operator>>(basic_istream<_CharT, _Traits>& __is,
1027 basic_string<_CharT, _Traits, _Alloc>& __str);
1029 template<typename _CharT, typename _Traits, typename _Alloc>
1030 basic_ostream<_CharT, _Traits>&
1031 operator<<(basic_ostream<_CharT, _Traits>& __os,
1032 const basic_string<_CharT, _Traits, _Alloc>& __str);
1034 template<typename _CharT, typename _Traits, typename _Alloc>
1035 basic_istream<_CharT,_Traits>&
1036 getline(basic_istream<_CharT, _Traits>& __is,
1037 basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim);
1039 template<typename _CharT, typename _Traits, typename _Alloc>
1040 inline basic_istream<_CharT,_Traits>&
1041 getline(basic_istream<_CharT, _Traits>& __is,
1042 basic_string<_CharT, _Traits, _Alloc>& __str);
1043 } // namespace std
1045 #endif /* _CPP_BITS_STRING_H */