1 // Components for manipulating sequences of characters -*- C++ -*-
3 // Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
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)
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,
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>
44 // Documentation? What's that?
45 // Nathan Myers <ncm@cantrip.org>.
47 // A string looks like this:
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
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
>
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
;
103 // _Rep: string representation
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.
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
132 // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT)
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
;
140 size_type _M_capacity
;
141 _Atomic_word _M_references
;
145 { return _M_references
< 0; }
149 { return _M_references
> 0; }
153 { _M_references
= -1; }
157 { _M_references
= 0; }
161 { return reinterpret_cast<_CharT
*> (this + 1); }
164 operator[](size_t __s
) throw()
165 { return _M_refdata() [__s
]; }
168 _M_grab(const _Alloc
& __alloc1
, const _Alloc
& __alloc2
)
169 { return (!_M_is_leaked() && __alloc1
== __alloc2
) ?
170 _M_refcopy() : _M_clone(__alloc1
); }
174 _S_create(size_t, const _Alloc
&);
177 _M_dispose(const _Alloc
& __a
)
179 if (__exchange_and_add(&_M_references
, -1) <= 0)
184 _M_destroy(const _Alloc
&) throw();
189 __atomic_add(&_M_references
, 1);
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
202 // Returns true if ALLOCATED is too much larger than LENGTH
203 static bool (*_S_excess_slop
) (size_t __length
, size_t __allocated
);
206 __default_excess(size_t, size_t);
209 _S_excess_slop(size_t, size_t);
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.
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);
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
)];
238 { return _M_dataplus
._M_p
; }
242 { return (_M_dataplus
._M_p
= __p
); }
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.
251 _M_ibegin() const { return iterator(_M_data()); }
254 _M_iend() const { return iterator(_M_data() + this->size()); }
257 _M_leak() // for use in begin() & non-const op[]
259 if (!_M_rep()->_M_is_leaked())
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.
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
>
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
291 _S_copy_chars(_CharT
* __p
, iterator __k1
, iterator __k2
)
292 { _S_copy_chars(__p
, __k1
.base(), __k2
.base()); }
295 _S_copy_chars(_CharT
* __p
, const_iterator __k1
, const_iterator __k2
)
296 { _S_copy_chars(__p
, __k1
.base(), __k2
.base()); }
299 _S_copy_chars(_CharT
* __p
, _CharT
* __k1
, _CharT
* __k2
)
300 { traits_type::copy(__p
, __k1
, __k2
- __k1
); }
303 _S_copy_chars(_CharT
* __p
, const _CharT
* __k1
, const _CharT
* __k2
)
304 { traits_type::copy(__p
, __k1
, __k2
- __k1
); }
307 _M_mutate(size_type __pos
, size_type __len1
, size_type __len2
);
314 { return *reinterpret_cast<_Rep
*>(&_S_empty_rep_storage
); }
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.
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());
344 { _M_rep()->_M_dispose(this->get_allocator()); }
347 operator=(const basic_string
& __str
) { return this->assign(__str
); }
350 operator=(const _CharT
* __s
) { return this->assign(__s
); }
353 operator=(_CharT __c
) { return this->assign(1, __c
); }
360 return iterator(_M_data());
365 { return const_iterator(_M_data()); }
371 return iterator(_M_data() + this->size());
376 { return const_iterator(_M_data() + this->size()); }
380 { return reverse_iterator(this->end()); }
382 const_reverse_iterator
384 { return const_reverse_iterator(this->end()); }
388 { return reverse_iterator(this->begin()); }
390 const_reverse_iterator
392 { return const_reverse_iterator(this->begin()); }
397 size() const { return _M_rep()->_M_length
; }
400 length() const { return _M_rep()->_M_length
; }
403 max_size() const { return _Rep::_S_max_size
; }
406 resize(size_type __n
, _CharT __c
);
409 resize(size_type __n
) { this->resize(__n
, _CharT()); }
412 capacity() const { return _M_rep()->_M_capacity
; }
415 reserve(size_type __res_arg
= 0);
418 clear() { _M_mutate(0, this->size(), 0); }
421 empty() const { return this->size() == 0; }
425 operator[] (size_type __pos
) const
426 { return _M_data()[__pos
]; }
429 operator[](size_type __pos
)
432 return _M_data()[__pos
];
436 at(size_type __n
) const
438 if (__n
>= this->size())
439 __throw_out_of_range("basic_string::at");
440 return _M_data()[__n
];
447 __throw_out_of_range("basic_string::at");
449 return _M_data()[__n
];
454 operator+=(const basic_string
& __str
) { return this->append(__str
); }
457 operator+=(const _CharT
* __s
) { return this->append(__s
); }
460 operator+=(_CharT __c
) { return this->append(size_type(1), __c
); }
463 append(const basic_string
& __str
);
466 append(const basic_string
& __str
, size_type __pos
, size_type __n
);
469 append(const _CharT
* __s
, size_type __n
);
472 append(const _CharT
* __s
)
473 { return this->append(__s
, traits_type::length(__s
)); }
476 append(size_type __n
, _CharT __c
);
478 template<class _InputIterator
>
480 append(_InputIterator __first
, _InputIterator __last
)
481 { return this->replace(_M_iend(), _M_iend(), __first
, __last
); }
484 push_back(_CharT __c
)
485 { this->replace(_M_iend(), _M_iend(), 1, __c
); }
488 assign(const basic_string
& __str
);
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
));
497 assign(const _CharT
* __s
, size_type __n
)
498 { return this->assign(__s
, __s
+ __n
); }
501 assign(const _CharT
* __s
)
502 { return this->assign(__s
, __s
+ traits_type::length(__s
)); }
505 assign(size_type __n
, _CharT __c
)
506 { return this->replace(_M_ibegin(), _M_iend(), __n
, __c
); }
508 template<class _InputIterator
>
510 assign(_InputIterator __first
, _InputIterator __last
)
511 { return this->replace(_M_ibegin(), _M_iend(), __first
, __last
); }
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
); }
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());
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
));
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
);
548 insert(size_type __pos
, const _CharT
* __s
)
549 { return this->insert(__pos
, __s
, traits_type::length(__s
)); }
552 insert(size_type __pos
, size_type __n
, _CharT __c
)
554 this->insert(_M_check(__pos
), __n
, __c
);
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
;
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());
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
;
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
;
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());
600 replace(size_type __pos1
, size_type __n1
, const basic_string
& __str
,
601 size_type __pos2
, size_type __n2
);
604 replace(size_type __pos
, size_type __n1
, const _CharT
* __s
,
607 return this->replace(_M_check(__pos
), _M_fold(__pos
, __n1
),
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
));
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
);
625 replace(iterator __i1
, iterator __i2
, const basic_string
& __str
)
626 { return this->replace(__i1
, __i2
, __str
.begin(), __str
.end()); }
629 replace(iterator __i1
, iterator __i2
,
630 const _CharT
* __s
, size_type __n
)
631 { return this->replace(__i1
, __i2
, __s
, __s
+ __n
); }
634 replace(iterator __i1
, iterator __i2
, const _CharT
* __s
)
635 { return this->replace(__i1
, __i2
, __s
,
636 __s
+ traits_type::length(__s
)); }
639 replace(iterator __i1
, iterator __i2
, size_type __n
, _CharT __c
);
641 template<class _InputIterator
>
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()); }
649 template<class _InputIterator
>
651 _M_replace(iterator __i1
, iterator __i2
, _InputIterator __k1
,
652 _InputIterator __k2
, input_iterator_tag
);
654 template<class _FwdIterator
>
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
>
663 _S_construct_aux(_InIter __beg
, _InIter __end
, const _Alloc
& __a
,
666 typedef typename iterator_traits
<_InIter
>::iterator_category _Tag
;
667 return _S_construct(__beg
, __end
, __a
, _Tag());
670 template<class _InIter
>
672 _S_construct_aux(_InIter __beg
, _InIter __end
, const _Alloc
& __a
,
675 return _S_construct(static_cast<size_type
>(__beg
),
676 static_cast<value_type
>(__end
), __a
);
679 template<class _InIter
>
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
>
690 _S_construct(_InIter __beg
, _InIter __end
, const _Alloc
& __a
,
693 // For forward_iterators up to random_access_iterators, used for
694 // string::iterator, _CharT*, etc.
695 template<class _FwdIter
>
697 _S_construct(_FwdIter __end
, _FwdIter __beg
, const _Alloc
& __a
,
698 forward_iterator_tag
);
701 _S_construct(size_type __req
, _CharT __c
, const _Alloc
& __a
);
706 copy(_CharT
* __s
, size_type __n
, size_type __pos
= 0) const;
709 swap(basic_string
<_CharT
, _Traits
, _Alloc
>& __s
);
711 // String operations:
715 // MT: This assumes concurrent writes are OK.
716 size_type __n
= this->size();
717 traits_type::assign(_M_data()[__n
], _Rep::_S_terminal
);
722 data() const { return _M_data(); }
725 get_allocator() const { return _M_dataplus
; }
728 find(const _CharT
* __s
, size_type __pos
, size_type __n
) const;
731 find(const basic_string
& __str
, size_type __pos
= 0) const
732 { return this->find(__str
.data(), __pos
, __str
.size()); }
735 find(const _CharT
* __s
, size_type __pos
= 0) const
736 { return this->find(__s
, __pos
, traits_type::length(__s
)); }
739 find(_CharT __c
, size_type __pos
= 0) const;
742 rfind(const basic_string
& __str
, size_type __pos
= npos
) const
743 { return this->rfind(__str
.data(), __pos
, __str
.size()); }
746 rfind(const _CharT
* __s
, size_type __pos
, size_type __n
) const;
749 rfind(const _CharT
* __s
, size_type __pos
= npos
) const
750 { return this->rfind(__s
, __pos
, traits_type::length(__s
)); }
753 rfind(_CharT __c
, size_type __pos
= npos
) const;
756 find_first_of(const basic_string
& __str
, size_type __pos
= 0) const
757 { return this->find_first_of(__str
.data(), __pos
, __str
.size()); }
760 find_first_of(const _CharT
* __s
, size_type __pos
, size_type __n
) const;
763 find_first_of(const _CharT
* __s
, size_type __pos
= 0) const
764 { return this->find_first_of(__s
, __pos
, traits_type::length(__s
)); }
767 find_first_of(_CharT __c
, size_type __pos
= 0) const
768 { return this->find(__c
, __pos
); }
771 find_last_of(const basic_string
& __str
, size_type __pos
= npos
) const
772 { return this->find_last_of(__str
.data(), __pos
, __str
.size()); }
775 find_last_of(const _CharT
* __s
, size_type __pos
, size_type __n
) const;
778 find_last_of(const _CharT
* __s
, size_type __pos
= npos
) const
779 { return this->find_last_of(__s
, __pos
, traits_type::length(__s
)); }
782 find_last_of(_CharT __c
, size_type __pos
= npos
) const
783 { return this->rfind(__c
, __pos
); }
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()); }
790 find_first_not_of(const _CharT
* __s
, size_type __pos
,
791 size_type __n
) const;
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
)); }
798 find_first_not_of(_CharT __c
, size_type __pos
= 0) const;
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()); }
805 find_last_not_of(const _CharT
* __s
, size_type __pos
,
806 size_type __n
) const;
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
)); }
812 find_last_not_of(_CharT __c
, size_type __pos
= npos
) const;
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
);
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
);
831 __r
= __size
- __osize
;
836 compare(size_type __pos
, size_type __n
, const basic_string
& __str
) const;
839 compare(size_type __pos1
, size_type __n1
, const basic_string
& __str
,
840 size_type __pos2
, size_type __n2
) const;
843 compare(const _CharT
* __s
) const;
845 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
846 // 5. String::compare specification questionable
848 compare(size_type __pos
, size_type __n1
, const _CharT
* __s
) const;
851 compare(size_type __pos
, size_type __n1
, const _CharT
* __s
,
852 size_type __n2
) const;
857 template<typename _CharT
, typename _Traits
, typename _Alloc
>
858 inline basic_string
<_CharT
, _Traits
, _Alloc
>::
860 : _M_dataplus(_S_empty_rep()._M_refcopy(), _Alloc()) { }
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
);
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
,
887 basic_string
<_CharT
, _Traits
, _Alloc
> __str(__lhs
);
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
);
904 template<typename _CharT
, typename _Traits
, typename _Alloc
>
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
>
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
>
918 operator==(const basic_string
<_CharT
, _Traits
, _Alloc
>& __lhs
,
920 { return __lhs
.compare(__rhs
) == 0; }
923 template<typename _CharT
, typename _Traits
, typename _Alloc
>
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
>
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
>
937 operator!=(const basic_string
<_CharT
, _Traits
, _Alloc
>& __lhs
,
939 { return __lhs
.compare(__rhs
) != 0; }
942 template<typename _CharT
, typename _Traits
, typename _Alloc
>
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
>
950 operator<(const basic_string
<_CharT
, _Traits
, _Alloc
>& __lhs
,
952 { return __lhs
.compare(__rhs
) < 0; }
954 template<typename _CharT
, typename _Traits
, typename _Alloc
>
956 operator<(const _CharT
* __lhs
,
957 const basic_string
<_CharT
, _Traits
, _Alloc
>& __rhs
)
958 { return __rhs
.compare(__lhs
) > 0; }
961 template<typename _CharT
, typename _Traits
, typename _Alloc
>
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
>
969 operator>(const basic_string
<_CharT
, _Traits
, _Alloc
>& __lhs
,
971 { return __lhs
.compare(__rhs
) > 0; }
973 template<typename _CharT
, typename _Traits
, typename _Alloc
>
975 operator>(const _CharT
* __lhs
,
976 const basic_string
<_CharT
, _Traits
, _Alloc
>& __rhs
)
977 { return __rhs
.compare(__lhs
) < 0; }
980 template<typename _CharT
, typename _Traits
, typename _Alloc
>
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
>
988 operator<=(const basic_string
<_CharT
, _Traits
, _Alloc
>& __lhs
,
990 { return __lhs
.compare(__rhs
) <= 0; }
992 template<typename _CharT
, typename _Traits
, typename _Alloc
>
994 operator<=(const _CharT
* __lhs
,
995 const basic_string
<_CharT
, _Traits
, _Alloc
>& __rhs
)
996 { return __rhs
.compare(__lhs
) >= 0; }
999 template<typename _CharT
, typename _Traits
, typename _Alloc
>
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
>
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
>
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
>
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
);
1045 #endif /* _CPP_BITS_STRING_H */