1 // Components for manipulating sequences of characters -*- C++ -*-
3 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
4 // Free Software Foundation, Inc.
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)
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.
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,
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.
32 // ISO C++ 14882: 21 Strings library
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.
40 #ifndef _CPP_BITS_STRING_H
41 #define _CPP_BITS_STRING_H 1
43 #pragma GCC system_header
45 #include <bits/atomicity.h>
50 * @class basic_string basic_string.h <string>
51 * @brief Managing sequences of characters and character-like objects.
56 * Meets the requirements of a <a href="tables.html#65">container</a>, a
57 * <a href="tables.html#66">reversible container</a>, and a
58 * <a href="tables.html#67">sequence</a>. Of the
59 * <a href="tables.html#68">optional sequence requirements</a>, only
60 * @c push_back, @c at, and array access are supported.
66 * Documentation? What's that?
67 * Nathan Myers <ncm@cantrip.org>.
69 * A string looks like this:
74 * [basic_string<char_type>] _M_capacity
75 * _M_dataplus _M_state
76 * _M_p ----------------> unnamed array of char_type
79 * Where the _M_p points to the first character in the string, and
80 * you cast it to a pointer-to-_Rep and subtract 1 to get a
81 * pointer to the header.
83 * This approach has the enormous advantage that a string object
84 * requires only one allocation. All the ugliness is confined
85 * within a single pair of inline functions, which each compile to
86 * a single "add" instruction: _Rep::_M_data(), and
87 * string::_M_rep(); and the allocation function which gets a
88 * block of raw bytes and with room enough and constructs a _Rep
89 * object at the front.
91 * The reason you want _M_data pointing to the character array and
92 * not the _Rep is so that the debugger can see the string
93 * contents. (Probably we should add a non-inline member to get
94 * the _Rep for the debugger to use, so users can check the actual
97 * Note that the _Rep object is a POD so that you can have a
98 * static "empty string" _Rep object already "constructed" before
99 * static constructors have run. The reference-count encoding is
100 * chosen so that a 0 indicates one reference, so you never try to
101 * destroy the empty-string _Rep object.
103 * All but the last paragraph is considered pretty conventional
104 * for a C++ string implementation.
107 // 21.3 Template class basic_string
108 template<typename _CharT
, typename _Traits
, typename _Alloc
>
113 typedef _Traits traits_type
;
114 typedef typename
_Traits::char_type value_type
;
115 typedef _Alloc allocator_type
;
116 typedef typename
_Alloc::size_type size_type
;
117 typedef typename
_Alloc::difference_type difference_type
;
118 typedef typename
_Alloc::reference reference
;
119 typedef typename
_Alloc::const_reference const_reference
;
120 typedef typename
_Alloc::pointer pointer
;
121 typedef typename
_Alloc::const_pointer const_pointer
;
122 typedef __gnu_cxx::__normal_iterator
<pointer
, basic_string
> iterator
;
123 typedef __gnu_cxx::__normal_iterator
<const_pointer
, basic_string
>
125 typedef reverse_iterator
<const_iterator
> const_reverse_iterator
;
126 typedef reverse_iterator
<iterator
> reverse_iterator
;
129 // _Rep: string representation
131 // 1. String really contains _M_length + 1 characters; last is set
132 // to 0 only on call to c_str(). We avoid instantiating
133 // _CharT() where the interface does not require it.
134 // 2. _M_capacity >= _M_length
135 // Allocated memory is always _M_capacity + (1 * sizeof(_CharT)).
136 // 3. _M_references has three states:
137 // -1: leaked, one reference, no ref-copies allowed, non-const.
138 // 0: one reference, non-const.
139 // n>0: n + 1 references, operations require a lock, const.
140 // 4. All fields==0 is an empty string, given the extra storage
141 // beyond-the-end for a null terminator; thus, the shared
142 // empty string representation needs no constructor.
146 typedef typename
_Alloc::template rebind
<char>::other _Raw_bytes_alloc
;
148 // (Public) Data members:
150 // The maximum number of individual char_type elements of an
151 // individual string is determined by _S_max_size. This is the
152 // value that will be returned by max_size(). (Whereas npos
153 // is the maximum number of bytes the allocator can allocate.)
154 // If one was to divvy up the theoretical largest size string,
155 // with a terminating character and m _CharT elements, it'd
157 // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT)
159 // m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1
160 // In addition, this implementation quarters this ammount.
161 static const size_type _S_max_size
;
162 static const _CharT _S_terminal
;
165 size_type _M_capacity
;
166 _Atomic_word _M_references
;
170 { return _M_references
< 0; }
174 { return _M_references
> 0; }
178 { _M_references
= -1; }
182 { _M_references
= 0; }
186 { return reinterpret_cast<_CharT
*>(this + 1); }
189 operator[](size_t __s
) throw()
190 { return _M_refdata() [__s
]; }
193 _M_grab(const _Alloc
& __alloc1
, const _Alloc
& __alloc2
)
195 return (!_M_is_leaked() && __alloc1
== __alloc2
)
196 ? _M_refcopy() : _M_clone(__alloc1
);
201 _S_create(size_t, const _Alloc
&);
204 _M_dispose(const _Alloc
& __a
)
206 if (__exchange_and_add(&_M_references
, -1) <= 0)
211 _M_destroy(const _Alloc
&) throw();
216 __atomic_add(&_M_references
, 1);
221 _M_clone(const _Alloc
&, size_type __res
= 0);
224 // Use empty-base optimization: http://www.cantrip.org/emptyopt.html
225 struct _Alloc_hider
: _Alloc
227 _Alloc_hider(_CharT
* __dat
, const _Alloc
& __a
)
228 : _Alloc(__a
), _M_p(__dat
) { }
230 _CharT
* _M_p
; // The actual data.
234 // Data Members (public):
235 // NB: This is an unsigned type, and thus represents the maximum
236 // size that the allocator can hold.
237 static const size_type npos
= static_cast<size_type
>(-1);
240 // Data Members (private):
241 mutable _Alloc_hider _M_dataplus
;
243 // The following storage is init'd to 0 by the linker, resulting
244 // (carefully) in an empty string with one reference.
245 static size_type _S_empty_rep_storage
[(sizeof(_Rep
) + sizeof(_CharT
) + sizeof(size_type
) - 1)/sizeof(size_type
)];
249 { return _M_dataplus
._M_p
; }
253 { return (_M_dataplus
._M_p
= __p
); }
257 { return &((reinterpret_cast<_Rep
*> (_M_data()))[-1]); }
259 // For the internal use we have functions similar to `begin'/`end'
260 // but they do not call _M_leak.
262 _M_ibegin() const { return iterator(_M_data()); }
265 _M_iend() const { return iterator(_M_data() + this->size()); }
268 _M_leak() // for use in begin() & non-const op[]
270 if (!_M_rep()->_M_is_leaked())
275 _M_check(size_type __pos
) const
277 if (__pos
> this->size())
278 __throw_out_of_range("basic_string::_M_check");
279 return _M_ibegin() + __pos
;
282 // NB: _M_fold doesn't check for a bad __pos1 value.
284 _M_fold(size_type __pos
, size_type __off
) const
286 bool __testoff
= __off
< this->size() - __pos
;
287 size_type __newoff
= __testoff
? __off
: this->size() - __pos
;
288 return (_M_ibegin() + __pos
+ __newoff
);
291 // _S_copy_chars is a separate template to permit specialization
292 // to optimize for the common case of pointers as iterators.
293 template<class _Iterator
>
295 _S_copy_chars(_CharT
* __p
, _Iterator __k1
, _Iterator __k2
)
297 for (; __k1
!= __k2
; ++__k1
, ++__p
)
298 traits_type::assign(*__p
, *__k1
); // These types are off.
302 _S_copy_chars(_CharT
* __p
, iterator __k1
, iterator __k2
)
303 { _S_copy_chars(__p
, __k1
.base(), __k2
.base()); }
306 _S_copy_chars(_CharT
* __p
, const_iterator __k1
, const_iterator __k2
)
307 { _S_copy_chars(__p
, __k1
.base(), __k2
.base()); }
310 _S_copy_chars(_CharT
* __p
, _CharT
* __k1
, _CharT
* __k2
)
311 { traits_type::copy(__p
, __k1
, __k2
- __k1
); }
314 _S_copy_chars(_CharT
* __p
, const _CharT
* __k1
, const _CharT
* __k2
)
315 { traits_type::copy(__p
, __k1
, __k2
- __k1
); }
318 _M_mutate(size_type __pos
, size_type __len1
, size_type __len2
);
325 { return *reinterpret_cast<_Rep
*>(&_S_empty_rep_storage
); }
328 // Construct/copy/destroy:
329 // NB: We overload ctors in some cases instead of using default
330 // arguments, per 17.4.4.4 para. 2 item 2.
336 basic_string(const _Alloc
& __a
);
338 // NB: per LWG issue 42, semantics different from IS:
339 basic_string(const basic_string
& __str
);
340 basic_string(const basic_string
& __str
, size_type __pos
,
341 size_type __n
= npos
);
342 basic_string(const basic_string
& __str
, size_type __pos
,
343 size_type __n
, const _Alloc
& __a
);
345 basic_string(const _CharT
* __s
, size_type __n
,
346 const _Alloc
& __a
= _Alloc());
347 basic_string(const _CharT
* __s
, const _Alloc
& __a
= _Alloc());
348 basic_string(size_type __n
, _CharT __c
, const _Alloc
& __a
= _Alloc());
350 template<class _InputIterator
>
351 basic_string(_InputIterator __beg
, _InputIterator __end
,
352 const _Alloc
& __a
= _Alloc());
355 { _M_rep()->_M_dispose(this->get_allocator()); }
358 operator=(const basic_string
& __str
) { return this->assign(__str
); }
361 operator=(const _CharT
* __s
) { return this->assign(__s
); }
364 operator=(_CharT __c
) { return this->assign(1, __c
); }
371 return iterator(_M_data());
376 { return const_iterator(_M_data()); }
382 return iterator(_M_data() + this->size());
387 { return const_iterator(_M_data() + this->size()); }
391 { return reverse_iterator(this->end()); }
393 const_reverse_iterator
395 { return const_reverse_iterator(this->end()); }
399 { return reverse_iterator(this->begin()); }
401 const_reverse_iterator
403 { return const_reverse_iterator(this->begin()); }
408 size() const { return _M_rep()->_M_length
; }
411 length() const { return _M_rep()->_M_length
; }
414 max_size() const { return _Rep::_S_max_size
; }
417 resize(size_type __n
, _CharT __c
);
420 resize(size_type __n
) { this->resize(__n
, _CharT()); }
423 capacity() const { return _M_rep()->_M_capacity
; }
426 reserve(size_type __res_arg
= 0);
429 clear() { _M_mutate(0, this->size(), 0); }
432 empty() const { return this->size() == 0; }
436 operator[] (size_type __pos
) const
437 { return _M_data()[__pos
]; }
440 operator[](size_type __pos
)
443 return _M_data()[__pos
];
447 at(size_type __n
) const
449 if (__n
>= this->size())
450 __throw_out_of_range("basic_string::at");
451 return _M_data()[__n
];
458 __throw_out_of_range("basic_string::at");
460 return _M_data()[__n
];
465 operator+=(const basic_string
& __str
) { return this->append(__str
); }
468 operator+=(const _CharT
* __s
) { return this->append(__s
); }
471 operator+=(_CharT __c
) { return this->append(size_type(1), __c
); }
474 append(const basic_string
& __str
);
477 append(const basic_string
& __str
, size_type __pos
, size_type __n
);
480 append(const _CharT
* __s
, size_type __n
);
483 append(const _CharT
* __s
)
484 { return this->append(__s
, traits_type::length(__s
)); }
487 append(size_type __n
, _CharT __c
);
489 template<class _InputIterator
>
491 append(_InputIterator __first
, _InputIterator __last
)
492 { return this->replace(_M_iend(), _M_iend(), __first
, __last
); }
495 push_back(_CharT __c
)
496 { this->replace(_M_iend(), _M_iend(), 1, __c
); }
499 assign(const basic_string
& __str
);
502 assign(const basic_string
& __str
, size_type __pos
, size_type __n
)
504 const size_type __strsize
= __str
.size();
505 if (__pos
> __strsize
)
506 __throw_out_of_range("basic_string::assign");
507 const bool __testn
= __n
< __strsize
- __pos
;
508 const size_type __newsize
= __testn
? __n
: __strsize
- __pos
;
509 return this->assign(__str
._M_data() + __pos
, __newsize
);
513 assign(const _CharT
* __s
, size_type __n
)
515 if (__n
> this->max_size())
516 __throw_length_error("basic_string::assign");
517 if (_M_rep()->_M_is_shared() || less
<const _CharT
*>()(__s
, _M_data())
518 || less
<const _CharT
*>()(_M_data() + this->size(), __s
))
519 return _M_replace_safe(_M_ibegin(), _M_iend(), __s
, __s
+ __n
);
523 const size_type __pos
= __s
- _M_data();
525 traits_type::copy(_M_data(), __s
, __n
);
527 traits_type::move(_M_data(), __s
, __n
);
528 _M_rep()->_M_length
= __n
;
529 _M_data()[__n
] = _Rep::_S_terminal
;
535 assign(const _CharT
* __s
)
536 { return this->assign(__s
, traits_type::length(__s
)); }
539 assign(size_type __n
, _CharT __c
)
540 { return this->replace(_M_ibegin(), _M_iend(), __n
, __c
); }
542 template<class _InputIterator
>
544 assign(_InputIterator __first
, _InputIterator __last
)
545 { return this->replace(_M_ibegin(), _M_iend(), __first
, __last
); }
548 insert(iterator __p
, size_type __n
, _CharT __c
)
549 { this->replace(__p
, __p
, __n
, __c
); }
551 template<class _InputIterator
>
552 void insert(iterator __p
, _InputIterator __beg
, _InputIterator __end
)
553 { this->replace(__p
, __p
, __beg
, __end
); }
556 insert(size_type __pos1
, const basic_string
& __str
)
557 { return this->insert(__pos1
, __str
, 0, __str
.size()); }
560 insert(size_type __pos1
, const basic_string
& __str
,
561 size_type __pos2
, size_type __n
)
563 const size_type __strsize
= __str
.size();
564 if (__pos2
> __strsize
)
565 __throw_out_of_range("basic_string::insert");
566 const bool __testn
= __n
< __strsize
- __pos2
;
567 const size_type __newsize
= __testn
? __n
: __strsize
- __pos2
;
568 return this->insert(__pos1
, __str
._M_data() + __pos2
, __newsize
);
572 insert(size_type __pos
, const _CharT
* __s
, size_type __n
)
574 const size_type __size
= this->size();
576 __throw_out_of_range("basic_string::insert");
577 if (__size
> this->max_size() - __n
)
578 __throw_length_error("basic_string::insert");
579 if (_M_rep()->_M_is_shared() || less
<const _CharT
*>()(__s
, _M_data())
580 || less
<const _CharT
*>()(_M_data() + __size
, __s
))
581 return _M_replace_safe(_M_ibegin() + __pos
, _M_ibegin() + __pos
,
585 // Work in-place. If _M_mutate reallocates the string, __s
586 // does not point anymore to valid data, therefore we save its
587 // offset, then we restore it.
588 const size_type __off
= __s
- _M_data();
589 _M_mutate(__pos
, 0, __n
);
590 __s
= _M_data() + __off
;
591 _CharT
* __p
= _M_data() + __pos
;
592 if (__s
+ __n
<= __p
)
593 traits_type::copy(__p
, __s
, __n
);
595 traits_type::copy(__p
, __s
+ __n
, __n
);
598 traits_type::copy(__p
, __s
, __p
- __s
);
599 traits_type::copy(__p
+ (__p
- __s
), __p
+ __n
, __n
- (__p
- __s
));
606 insert(size_type __pos
, const _CharT
* __s
)
607 { return this->insert(__pos
, __s
, traits_type::length(__s
)); }
610 insert(size_type __pos
, size_type __n
, _CharT __c
)
612 this->insert(_M_check(__pos
), __n
, __c
);
617 insert(iterator __p
, _CharT __c
= _CharT())
619 size_type __pos
= __p
- _M_ibegin();
620 this->insert(_M_check(__pos
), size_type(1), __c
);
621 _M_rep()->_M_set_leaked();
622 return this->_M_ibegin() + __pos
;
626 erase(size_type __pos
= 0, size_type __n
= npos
)
628 return this->replace(_M_check(__pos
), _M_fold(__pos
, __n
),
629 _M_data(), _M_data());
633 erase(iterator __position
)
635 size_type __i
= __position
- _M_ibegin();
636 this->replace(__position
, __position
+ 1, _M_data(), _M_data());
637 _M_rep()->_M_set_leaked();
638 return _M_ibegin() + __i
;
642 erase(iterator __first
, iterator __last
)
644 size_type __i
= __first
- _M_ibegin();
645 this->replace(__first
, __last
, _M_data(), _M_data());
646 _M_rep()->_M_set_leaked();
647 return _M_ibegin() + __i
;
651 replace(size_type __pos
, size_type __n
, const basic_string
& __str
)
652 { return this->replace(__pos
, __n
, __str
._M_data(), __str
.size()); }
655 replace(size_type __pos1
, size_type __n1
, const basic_string
& __str
,
656 size_type __pos2
, size_type __n2
);
659 replace(size_type __pos
, size_type __n1
, const _CharT
* __s
,
662 const size_type __size
= this->size();
664 __throw_out_of_range("basic_string::replace");
665 const bool __testn1
= __n1
< __size
- __pos
;
666 const size_type __foldn1
= __testn1
? __n1
: __size
- __pos
;
667 if (__size
- __foldn1
> this->max_size() - __n2
)
668 __throw_length_error("basic_string::replace");
669 if (_M_rep()->_M_is_shared() || less
<const _CharT
*>()(__s
, _M_data())
670 || less
<const _CharT
*>()(_M_data() + __size
, __s
))
671 return _M_replace_safe(_M_ibegin() + __pos
,
672 _M_ibegin() + __pos
+ __foldn1
, __s
, __s
+ __n2
);
673 // Todo: optimized in-place replace.
675 _M_replace(_M_ibegin() + __pos
, _M_ibegin() + __pos
+ __foldn1
,
677 typename iterator_traits
<const _CharT
*>::iterator_category());
681 replace(size_type __pos
, size_type __n1
, const _CharT
* __s
)
682 { return this->replace(__pos
, __n1
, __s
, traits_type::length(__s
)); }
685 replace(size_type __pos
, size_type __n1
, size_type __n2
, _CharT __c
)
686 { return this->replace(_M_check(__pos
), _M_fold(__pos
, __n1
), __n2
, __c
); }
689 replace(iterator __i1
, iterator __i2
, const basic_string
& __str
)
690 { return this->replace(__i1
, __i2
, __str
._M_data(), __str
.size()); }
693 replace(iterator __i1
, iterator __i2
,
694 const _CharT
* __s
, size_type __n
)
695 { return this->replace(__i1
- _M_ibegin(), __i2
- __i1
, __s
, __n
); }
698 replace(iterator __i1
, iterator __i2
, const _CharT
* __s
)
699 { return this->replace(__i1
, __i2
, __s
, traits_type::length(__s
)); }
702 replace(iterator __i1
, iterator __i2
, size_type __n
, _CharT __c
);
704 template<class _InputIterator
>
706 replace(iterator __i1
, iterator __i2
,
707 _InputIterator __k1
, _InputIterator __k2
)
708 { return _M_replace(__i1
, __i2
, __k1
, __k2
,
709 typename iterator_traits
<_InputIterator
>::iterator_category()); }
711 // Specializations for the common case of pointer and iterator:
712 // useful to avoid the overhead of temporary buffering in _M_replace.
714 replace(iterator __i1
, iterator __i2
, _CharT
* __k1
, _CharT
* __k2
)
715 { return this->replace(__i1
- _M_ibegin(), __i2
- __i1
,
716 __k1
, __k2
- __k1
); }
719 replace(iterator __i1
, iterator __i2
, const _CharT
* __k1
, const _CharT
* __k2
)
720 { return this->replace(__i1
- _M_ibegin(), __i2
- __i1
,
721 __k1
, __k2
- __k1
); }
724 replace(iterator __i1
, iterator __i2
, iterator __k1
, iterator __k2
)
725 { return this->replace(__i1
- _M_ibegin(), __i2
- __i1
,
726 __k1
.base(), __k2
- __k1
);
730 replace(iterator __i1
, iterator __i2
, const_iterator __k1
, const_iterator __k2
)
731 { return this->replace(__i1
- _M_ibegin(), __i2
- __i1
,
732 __k1
.base(), __k2
- __k1
);
736 template<class _InputIterator
>
738 _M_replace(iterator __i1
, iterator __i2
, _InputIterator __k1
,
739 _InputIterator __k2
, input_iterator_tag
);
741 template<class _ForwardIterator
>
743 _M_replace_safe(iterator __i1
, iterator __i2
, _ForwardIterator __k1
,
744 _ForwardIterator __k2
);
746 // _S_construct_aux is used to implement the 21.3.1 para 15 which
747 // requires special behaviour if _InIter is an integral type
748 template<class _InIter
>
750 _S_construct_aux(_InIter __beg
, _InIter __end
, const _Alloc
& __a
,
753 typedef typename iterator_traits
<_InIter
>::iterator_category _Tag
;
754 return _S_construct(__beg
, __end
, __a
, _Tag());
757 template<class _InIter
>
759 _S_construct_aux(_InIter __beg
, _InIter __end
, const _Alloc
& __a
,
762 return _S_construct(static_cast<size_type
>(__beg
),
763 static_cast<value_type
>(__end
), __a
);
766 template<class _InIter
>
768 _S_construct(_InIter __beg
, _InIter __end
, const _Alloc
& __a
)
770 typedef typename _Is_integer
<_InIter
>::_Integral _Integral
;
771 return _S_construct_aux(__beg
, __end
, __a
, _Integral());
774 // For Input Iterators, used in istreambuf_iterators, etc.
775 template<class _InIter
>
777 _S_construct(_InIter __beg
, _InIter __end
, const _Alloc
& __a
,
780 // For forward_iterators up to random_access_iterators, used for
781 // string::iterator, _CharT*, etc.
782 template<class _FwdIter
>
784 _S_construct(_FwdIter __beg
, _FwdIter __end
, const _Alloc
& __a
,
785 forward_iterator_tag
);
788 _S_construct(size_type __req
, _CharT __c
, const _Alloc
& __a
);
793 copy(_CharT
* __s
, size_type __n
, size_type __pos
= 0) const;
796 swap(basic_string
<_CharT
, _Traits
, _Alloc
>& __s
);
798 // String operations:
802 // MT: This assumes concurrent writes are OK.
803 size_type __n
= this->size();
804 traits_type::assign(_M_data()[__n
], _Rep::_S_terminal
);
809 data() const { return _M_data(); }
812 get_allocator() const { return _M_dataplus
; }
815 find(const _CharT
* __s
, size_type __pos
, size_type __n
) const;
818 find(const basic_string
& __str
, size_type __pos
= 0) const
819 { return this->find(__str
.data(), __pos
, __str
.size()); }
822 find(const _CharT
* __s
, size_type __pos
= 0) const
823 { return this->find(__s
, __pos
, traits_type::length(__s
)); }
826 find(_CharT __c
, size_type __pos
= 0) const;
829 rfind(const basic_string
& __str
, size_type __pos
= npos
) const
830 { return this->rfind(__str
.data(), __pos
, __str
.size()); }
833 rfind(const _CharT
* __s
, size_type __pos
, size_type __n
) const;
836 rfind(const _CharT
* __s
, size_type __pos
= npos
) const
837 { return this->rfind(__s
, __pos
, traits_type::length(__s
)); }
840 rfind(_CharT __c
, size_type __pos
= npos
) const;
843 find_first_of(const basic_string
& __str
, size_type __pos
= 0) const
844 { return this->find_first_of(__str
.data(), __pos
, __str
.size()); }
847 find_first_of(const _CharT
* __s
, size_type __pos
, size_type __n
) const;
850 find_first_of(const _CharT
* __s
, size_type __pos
= 0) const
851 { return this->find_first_of(__s
, __pos
, traits_type::length(__s
)); }
854 find_first_of(_CharT __c
, size_type __pos
= 0) const
855 { return this->find(__c
, __pos
); }
858 find_last_of(const basic_string
& __str
, size_type __pos
= npos
) const
859 { return this->find_last_of(__str
.data(), __pos
, __str
.size()); }
862 find_last_of(const _CharT
* __s
, size_type __pos
, size_type __n
) const;
865 find_last_of(const _CharT
* __s
, size_type __pos
= npos
) const
866 { return this->find_last_of(__s
, __pos
, traits_type::length(__s
)); }
869 find_last_of(_CharT __c
, size_type __pos
= npos
) const
870 { return this->rfind(__c
, __pos
); }
873 find_first_not_of(const basic_string
& __str
, size_type __pos
= 0) const
874 { return this->find_first_not_of(__str
.data(), __pos
, __str
.size()); }
877 find_first_not_of(const _CharT
* __s
, size_type __pos
,
878 size_type __n
) const;
881 find_first_not_of(const _CharT
* __s
, size_type __pos
= 0) const
882 { return this->find_first_not_of(__s
, __pos
, traits_type::length(__s
)); }
885 find_first_not_of(_CharT __c
, size_type __pos
= 0) const;
888 find_last_not_of(const basic_string
& __str
, size_type __pos
= npos
) const
889 { return this->find_last_not_of(__str
.data(), __pos
, __str
.size()); }
892 find_last_not_of(const _CharT
* __s
, size_type __pos
,
893 size_type __n
) const;
895 find_last_not_of(const _CharT
* __s
, size_type __pos
= npos
) const
896 { return this->find_last_not_of(__s
, __pos
, traits_type::length(__s
)); }
899 find_last_not_of(_CharT __c
, size_type __pos
= npos
) const;
902 substr(size_type __pos
= 0, size_type __n
= npos
) const
904 if (__pos
> this->size())
905 __throw_out_of_range("basic_string::substr");
906 return basic_string(*this, __pos
, __n
);
910 compare(const basic_string
& __str
) const
912 size_type __size
= this->size();
913 size_type __osize
= __str
.size();
914 size_type __len
= min(__size
, __osize
);
916 int __r
= traits_type::compare(_M_data(), __str
.data(), __len
);
918 __r
= __size
- __osize
;
923 compare(size_type __pos
, size_type __n
, const basic_string
& __str
) const;
926 compare(size_type __pos1
, size_type __n1
, const basic_string
& __str
,
927 size_type __pos2
, size_type __n2
) const;
930 compare(const _CharT
* __s
) const;
932 // _GLIBCPP_RESOLVE_LIB_DEFECTS
933 // 5. String::compare specification questionable
935 compare(size_type __pos
, size_type __n1
, const _CharT
* __s
) const;
938 compare(size_type __pos
, size_type __n1
, const _CharT
* __s
,
939 size_type __n2
) const;
943 template<typename _CharT
, typename _Traits
, typename _Alloc
>
944 inline basic_string
<_CharT
, _Traits
, _Alloc
>::
946 : _M_dataplus(_S_empty_rep()._M_refcopy(), _Alloc()) { }
949 template<typename _CharT
, typename _Traits
, typename _Alloc
>
950 basic_string
<_CharT
, _Traits
, _Alloc
>
951 operator+(const basic_string
<_CharT
, _Traits
, _Alloc
>& __lhs
,
952 const basic_string
<_CharT
, _Traits
, _Alloc
>& __rhs
)
954 basic_string
<_CharT
, _Traits
, _Alloc
> __str(__lhs
);
959 template<typename _CharT
, typename _Traits
, typename _Alloc
>
960 basic_string
<_CharT
,_Traits
,_Alloc
>
961 operator+(const _CharT
* __lhs
,
962 const basic_string
<_CharT
,_Traits
,_Alloc
>& __rhs
);
964 template<typename _CharT
, typename _Traits
, typename _Alloc
>
965 basic_string
<_CharT
,_Traits
,_Alloc
>
966 operator+(_CharT __lhs
, const basic_string
<_CharT
,_Traits
,_Alloc
>& __rhs
);
968 template<typename _CharT
, typename _Traits
, typename _Alloc
>
969 inline basic_string
<_CharT
, _Traits
, _Alloc
>
970 operator+(const basic_string
<_CharT
, _Traits
, _Alloc
>& __lhs
,
973 basic_string
<_CharT
, _Traits
, _Alloc
> __str(__lhs
);
978 template<typename _CharT
, typename _Traits
, typename _Alloc
>
979 inline basic_string
<_CharT
, _Traits
, _Alloc
>
980 operator+(const basic_string
<_CharT
, _Traits
, _Alloc
>& __lhs
, _CharT __rhs
)
982 typedef basic_string
<_CharT
, _Traits
, _Alloc
> __string_type
;
983 typedef typename
__string_type::size_type __size_type
;
984 __string_type
__str(__lhs
);
985 __str
.append(__size_type(1), __rhs
);
990 template<typename _CharT
, typename _Traits
, typename _Alloc
>
992 operator==(const basic_string
<_CharT
, _Traits
, _Alloc
>& __lhs
,
993 const basic_string
<_CharT
, _Traits
, _Alloc
>& __rhs
)
994 { return __lhs
.compare(__rhs
) == 0; }
996 template<typename _CharT
, typename _Traits
, typename _Alloc
>
998 operator==(const _CharT
* __lhs
,
999 const basic_string
<_CharT
, _Traits
, _Alloc
>& __rhs
)
1000 { return __rhs
.compare(__lhs
) == 0; }
1002 template<typename _CharT
, typename _Traits
, typename _Alloc
>
1004 operator==(const basic_string
<_CharT
, _Traits
, _Alloc
>& __lhs
,
1005 const _CharT
* __rhs
)
1006 { return __lhs
.compare(__rhs
) == 0; }
1009 template<typename _CharT
, typename _Traits
, typename _Alloc
>
1011 operator!=(const basic_string
<_CharT
, _Traits
, _Alloc
>& __lhs
,
1012 const basic_string
<_CharT
, _Traits
, _Alloc
>& __rhs
)
1013 { return __rhs
.compare(__lhs
) != 0; }
1015 template<typename _CharT
, typename _Traits
, typename _Alloc
>
1017 operator!=(const _CharT
* __lhs
,
1018 const basic_string
<_CharT
, _Traits
, _Alloc
>& __rhs
)
1019 { return __rhs
.compare(__lhs
) != 0; }
1021 template<typename _CharT
, typename _Traits
, typename _Alloc
>
1023 operator!=(const basic_string
<_CharT
, _Traits
, _Alloc
>& __lhs
,
1024 const _CharT
* __rhs
)
1025 { return __lhs
.compare(__rhs
) != 0; }
1028 template<typename _CharT
, typename _Traits
, typename _Alloc
>
1030 operator<(const basic_string
<_CharT
, _Traits
, _Alloc
>& __lhs
,
1031 const basic_string
<_CharT
, _Traits
, _Alloc
>& __rhs
)
1032 { return __lhs
.compare(__rhs
) < 0; }
1034 template<typename _CharT
, typename _Traits
, typename _Alloc
>
1036 operator<(const basic_string
<_CharT
, _Traits
, _Alloc
>& __lhs
,
1037 const _CharT
* __rhs
)
1038 { return __lhs
.compare(__rhs
) < 0; }
1040 template<typename _CharT
, typename _Traits
, typename _Alloc
>
1042 operator<(const _CharT
* __lhs
,
1043 const basic_string
<_CharT
, _Traits
, _Alloc
>& __rhs
)
1044 { return __rhs
.compare(__lhs
) > 0; }
1047 template<typename _CharT
, typename _Traits
, typename _Alloc
>
1049 operator>(const basic_string
<_CharT
, _Traits
, _Alloc
>& __lhs
,
1050 const basic_string
<_CharT
, _Traits
, _Alloc
>& __rhs
)
1051 { return __lhs
.compare(__rhs
) > 0; }
1053 template<typename _CharT
, typename _Traits
, typename _Alloc
>
1055 operator>(const basic_string
<_CharT
, _Traits
, _Alloc
>& __lhs
,
1056 const _CharT
* __rhs
)
1057 { return __lhs
.compare(__rhs
) > 0; }
1059 template<typename _CharT
, typename _Traits
, typename _Alloc
>
1061 operator>(const _CharT
* __lhs
,
1062 const basic_string
<_CharT
, _Traits
, _Alloc
>& __rhs
)
1063 { return __rhs
.compare(__lhs
) < 0; }
1066 template<typename _CharT
, typename _Traits
, typename _Alloc
>
1068 operator<=(const basic_string
<_CharT
, _Traits
, _Alloc
>& __lhs
,
1069 const basic_string
<_CharT
, _Traits
, _Alloc
>& __rhs
)
1070 { return __lhs
.compare(__rhs
) <= 0; }
1072 template<typename _CharT
, typename _Traits
, typename _Alloc
>
1074 operator<=(const basic_string
<_CharT
, _Traits
, _Alloc
>& __lhs
,
1075 const _CharT
* __rhs
)
1076 { return __lhs
.compare(__rhs
) <= 0; }
1078 template<typename _CharT
, typename _Traits
, typename _Alloc
>
1080 operator<=(const _CharT
* __lhs
,
1081 const basic_string
<_CharT
, _Traits
, _Alloc
>& __rhs
)
1082 { return __rhs
.compare(__lhs
) >= 0; }
1085 template<typename _CharT
, typename _Traits
, typename _Alloc
>
1087 operator>=(const basic_string
<_CharT
, _Traits
, _Alloc
>& __lhs
,
1088 const basic_string
<_CharT
, _Traits
, _Alloc
>& __rhs
)
1089 { return __lhs
.compare(__rhs
) >= 0; }
1091 template<typename _CharT
, typename _Traits
, typename _Alloc
>
1093 operator>=(const basic_string
<_CharT
, _Traits
, _Alloc
>& __lhs
,
1094 const _CharT
* __rhs
)
1095 { return __lhs
.compare(__rhs
) >= 0; }
1097 template<typename _CharT
, typename _Traits
, typename _Alloc
>
1099 operator>=(const _CharT
* __lhs
,
1100 const basic_string
<_CharT
, _Traits
, _Alloc
>& __rhs
)
1101 { return __rhs
.compare(__lhs
) <= 0; }
1104 template<typename _CharT
, typename _Traits
, typename _Alloc
>
1106 swap(basic_string
<_CharT
, _Traits
, _Alloc
>& __lhs
,
1107 basic_string
<_CharT
, _Traits
, _Alloc
>& __rhs
)
1108 { __lhs
.swap(__rhs
); }
1110 template<typename _CharT
, typename _Traits
, typename _Alloc
>
1111 basic_istream
<_CharT
, _Traits
>&
1112 operator>>(basic_istream
<_CharT
, _Traits
>& __is
,
1113 basic_string
<_CharT
, _Traits
, _Alloc
>& __str
);
1115 template<typename _CharT
, typename _Traits
, typename _Alloc
>
1116 basic_ostream
<_CharT
, _Traits
>&
1117 operator<<(basic_ostream
<_CharT
, _Traits
>& __os
,
1118 const basic_string
<_CharT
, _Traits
, _Alloc
>& __str
);
1120 template<typename _CharT
, typename _Traits
, typename _Alloc
>
1121 basic_istream
<_CharT
,_Traits
>&
1122 getline(basic_istream
<_CharT
, _Traits
>& __is
,
1123 basic_string
<_CharT
, _Traits
, _Alloc
>& __str
, _CharT __delim
);
1125 template<typename _CharT
, typename _Traits
, typename _Alloc
>
1126 inline basic_istream
<_CharT
,_Traits
>&
1127 getline(basic_istream
<_CharT
, _Traits
>& __is
,
1128 basic_string
<_CharT
, _Traits
, _Alloc
>& __str
);
1131 #endif /* _CPP_BITS_STRING_H */