xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/bits/basic_string.h (revision 95059079af47f9a66a175f374f2da1a5020e3255)
138fd1498Szrj // Components for manipulating sequences of characters -*- C++ -*-
238fd1498Szrj 
338fd1498Szrj // Copyright (C) 1997-2018 Free Software Foundation, Inc.
438fd1498Szrj //
538fd1498Szrj // This file is part of the GNU ISO C++ Library.  This library is free
638fd1498Szrj // software; you can redistribute it and/or modify it under the
738fd1498Szrj // terms of the GNU General Public License as published by the
838fd1498Szrj // Free Software Foundation; either version 3, or (at your option)
938fd1498Szrj // any later version.
1038fd1498Szrj 
1138fd1498Szrj // This library is distributed in the hope that it will be useful,
1238fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
1338fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1438fd1498Szrj // GNU General Public License for more details.
1538fd1498Szrj 
1638fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional
1738fd1498Szrj // permissions described in the GCC Runtime Library Exception, version
1838fd1498Szrj // 3.1, as published by the Free Software Foundation.
1938fd1498Szrj 
2038fd1498Szrj // You should have received a copy of the GNU General Public License and
2138fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program;
2238fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2338fd1498Szrj // <http://www.gnu.org/licenses/>.
2438fd1498Szrj 
2538fd1498Szrj /** @file bits/basic_string.h
2638fd1498Szrj  *  This is an internal header file, included by other library headers.
2738fd1498Szrj  *  Do not attempt to use it directly. @headername{string}
2838fd1498Szrj  */
2938fd1498Szrj 
3038fd1498Szrj //
3138fd1498Szrj // ISO C++ 14882: 21 Strings library
3238fd1498Szrj //
3338fd1498Szrj 
3438fd1498Szrj #ifndef _BASIC_STRING_H
3538fd1498Szrj #define _BASIC_STRING_H 1
3638fd1498Szrj 
3738fd1498Szrj #pragma GCC system_header
3838fd1498Szrj 
3938fd1498Szrj #include <ext/atomicity.h>
4038fd1498Szrj #include <ext/alloc_traits.h>
4138fd1498Szrj #include <debug/debug.h>
4238fd1498Szrj 
4338fd1498Szrj #if __cplusplus >= 201103L
4438fd1498Szrj #include <initializer_list>
4538fd1498Szrj #endif
4638fd1498Szrj 
4738fd1498Szrj #if __cplusplus > 201402L
4838fd1498Szrj # include <string_view>
4938fd1498Szrj #endif
5038fd1498Szrj 
5138fd1498Szrj 
_GLIBCXX_VISIBILITY(default)5238fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
5338fd1498Szrj {
5438fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
5538fd1498Szrj 
5638fd1498Szrj #if _GLIBCXX_USE_CXX11_ABI
5738fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_CXX11
5838fd1498Szrj   /**
5938fd1498Szrj    *  @class basic_string basic_string.h <string>
6038fd1498Szrj    *  @brief  Managing sequences of characters and character-like objects.
6138fd1498Szrj    *
6238fd1498Szrj    *  @ingroup strings
6338fd1498Szrj    *  @ingroup sequences
6438fd1498Szrj    *
6538fd1498Szrj    *  @tparam _CharT  Type of character
6638fd1498Szrj    *  @tparam _Traits  Traits for character type, defaults to
6738fd1498Szrj    *                   char_traits<_CharT>.
6838fd1498Szrj    *  @tparam _Alloc  Allocator type, defaults to allocator<_CharT>.
6938fd1498Szrj    *
7038fd1498Szrj    *  Meets the requirements of a <a href="tables.html#65">container</a>, a
7138fd1498Szrj    *  <a href="tables.html#66">reversible container</a>, and a
7238fd1498Szrj    *  <a href="tables.html#67">sequence</a>.  Of the
7338fd1498Szrj    *  <a href="tables.html#68">optional sequence requirements</a>, only
7438fd1498Szrj    *  @c push_back, @c at, and @c %array access are supported.
7538fd1498Szrj    */
7638fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
7738fd1498Szrj     class basic_string
7838fd1498Szrj     {
7938fd1498Szrj       typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
8038fd1498Szrj 	rebind<_CharT>::other _Char_alloc_type;
8138fd1498Szrj       typedef __gnu_cxx::__alloc_traits<_Char_alloc_type> _Alloc_traits;
8238fd1498Szrj 
8338fd1498Szrj       // Types:
8438fd1498Szrj     public:
8538fd1498Szrj       typedef _Traits					traits_type;
8638fd1498Szrj       typedef typename _Traits::char_type		value_type;
8738fd1498Szrj       typedef _Char_alloc_type				allocator_type;
8838fd1498Szrj       typedef typename _Alloc_traits::size_type		size_type;
8938fd1498Szrj       typedef typename _Alloc_traits::difference_type	difference_type;
9038fd1498Szrj       typedef typename _Alloc_traits::reference		reference;
9138fd1498Szrj       typedef typename _Alloc_traits::const_reference	const_reference;
9238fd1498Szrj       typedef typename _Alloc_traits::pointer		pointer;
9338fd1498Szrj       typedef typename _Alloc_traits::const_pointer	const_pointer;
9438fd1498Szrj       typedef __gnu_cxx::__normal_iterator<pointer, basic_string>  iterator;
9538fd1498Szrj       typedef __gnu_cxx::__normal_iterator<const_pointer, basic_string>
9638fd1498Szrj 							const_iterator;
9738fd1498Szrj       typedef std::reverse_iterator<const_iterator>	const_reverse_iterator;
9838fd1498Szrj       typedef std::reverse_iterator<iterator>		reverse_iterator;
9938fd1498Szrj 
10038fd1498Szrj       ///  Value returned by various member functions when they fail.
10138fd1498Szrj       static const size_type	npos = static_cast<size_type>(-1);
10238fd1498Szrj 
10338fd1498Szrj     private:
10438fd1498Szrj       // type used for positions in insert, erase etc.
10538fd1498Szrj #if __cplusplus < 201103L
10638fd1498Szrj       typedef iterator __const_iterator;
10738fd1498Szrj #else
10838fd1498Szrj       typedef const_iterator __const_iterator;
10938fd1498Szrj #endif
11038fd1498Szrj 
11138fd1498Szrj #if __cplusplus > 201402L
11238fd1498Szrj       // A helper type for avoiding boiler-plate.
11338fd1498Szrj       typedef basic_string_view<_CharT, _Traits> __sv_type;
11438fd1498Szrj 
11538fd1498Szrj       template<typename _Tp, typename _Res>
11638fd1498Szrj 	using _If_sv = enable_if_t<
11738fd1498Szrj 	  __and_<is_convertible<const _Tp&, __sv_type>,
11838fd1498Szrj 		 __not_<is_convertible<const _Tp*, const basic_string*>>,
11938fd1498Szrj 		 __not_<is_convertible<const _Tp&, const _CharT*>>>::value,
12038fd1498Szrj 	  _Res>;
12138fd1498Szrj 
12238fd1498Szrj       // Allows an implicit conversion to __sv_type.
12338fd1498Szrj       static __sv_type
12438fd1498Szrj       _S_to_string_view(__sv_type __svt) noexcept
12538fd1498Szrj       { return __svt; }
12638fd1498Szrj 
12738fd1498Szrj       // Wraps a string_view by explicit conversion and thus
12838fd1498Szrj       // allows to add an internal constructor that does not
12938fd1498Szrj       // participate in overload resolution when a string_view
13038fd1498Szrj       // is provided.
13138fd1498Szrj       struct __sv_wrapper
13238fd1498Szrj       {
13338fd1498Szrj 	explicit __sv_wrapper(__sv_type __sv) noexcept : _M_sv(__sv) { }
13438fd1498Szrj 	__sv_type _M_sv;
13538fd1498Szrj       };
13638fd1498Szrj #endif
13738fd1498Szrj 
13838fd1498Szrj       // Use empty-base optimization: http://www.cantrip.org/emptyopt.html
13938fd1498Szrj       struct _Alloc_hider : allocator_type // TODO check __is_final
14038fd1498Szrj       {
14138fd1498Szrj #if __cplusplus < 201103L
14238fd1498Szrj 	_Alloc_hider(pointer __dat, const _Alloc& __a = _Alloc())
14338fd1498Szrj 	: allocator_type(__a), _M_p(__dat) { }
14438fd1498Szrj #else
14538fd1498Szrj 	_Alloc_hider(pointer __dat, const _Alloc& __a)
14638fd1498Szrj 	: allocator_type(__a), _M_p(__dat) { }
14738fd1498Szrj 
14838fd1498Szrj 	_Alloc_hider(pointer __dat, _Alloc&& __a = _Alloc())
14938fd1498Szrj 	: allocator_type(std::move(__a)), _M_p(__dat) { }
15038fd1498Szrj #endif
15138fd1498Szrj 
15238fd1498Szrj 	pointer _M_p; // The actual data.
15338fd1498Szrj       };
15438fd1498Szrj 
15538fd1498Szrj       _Alloc_hider	_M_dataplus;
15638fd1498Szrj       size_type		_M_string_length;
15738fd1498Szrj 
15838fd1498Szrj       enum { _S_local_capacity = 15 / sizeof(_CharT) };
15938fd1498Szrj 
16038fd1498Szrj       union
16138fd1498Szrj       {
16238fd1498Szrj 	_CharT           _M_local_buf[_S_local_capacity + 1];
16338fd1498Szrj 	size_type        _M_allocated_capacity;
16438fd1498Szrj       };
16538fd1498Szrj 
16638fd1498Szrj       void
16738fd1498Szrj       _M_data(pointer __p)
16838fd1498Szrj       { _M_dataplus._M_p = __p; }
16938fd1498Szrj 
17038fd1498Szrj       void
17138fd1498Szrj       _M_length(size_type __length)
17238fd1498Szrj       { _M_string_length = __length; }
17338fd1498Szrj 
17438fd1498Szrj       pointer
17538fd1498Szrj       _M_data() const
17638fd1498Szrj       { return _M_dataplus._M_p; }
17738fd1498Szrj 
17838fd1498Szrj       pointer
17938fd1498Szrj       _M_local_data()
18038fd1498Szrj       {
18138fd1498Szrj #if __cplusplus >= 201103L
18238fd1498Szrj 	return std::pointer_traits<pointer>::pointer_to(*_M_local_buf);
18338fd1498Szrj #else
18438fd1498Szrj 	return pointer(_M_local_buf);
18538fd1498Szrj #endif
18638fd1498Szrj       }
18738fd1498Szrj 
18838fd1498Szrj       const_pointer
18938fd1498Szrj       _M_local_data() const
19038fd1498Szrj       {
19138fd1498Szrj #if __cplusplus >= 201103L
19238fd1498Szrj 	return std::pointer_traits<const_pointer>::pointer_to(*_M_local_buf);
19338fd1498Szrj #else
19438fd1498Szrj 	return const_pointer(_M_local_buf);
19538fd1498Szrj #endif
19638fd1498Szrj       }
19738fd1498Szrj 
19838fd1498Szrj       void
19938fd1498Szrj       _M_capacity(size_type __capacity)
20038fd1498Szrj       { _M_allocated_capacity = __capacity; }
20138fd1498Szrj 
20238fd1498Szrj       void
20338fd1498Szrj       _M_set_length(size_type __n)
20438fd1498Szrj       {
20538fd1498Szrj 	_M_length(__n);
20638fd1498Szrj 	traits_type::assign(_M_data()[__n], _CharT());
20738fd1498Szrj       }
20838fd1498Szrj 
20938fd1498Szrj       bool
21038fd1498Szrj       _M_is_local() const
21138fd1498Szrj       { return _M_data() == _M_local_data(); }
21238fd1498Szrj 
21338fd1498Szrj       // Create & Destroy
21438fd1498Szrj       pointer
21538fd1498Szrj       _M_create(size_type&, size_type);
21638fd1498Szrj 
21738fd1498Szrj       void
21838fd1498Szrj       _M_dispose()
21938fd1498Szrj       {
22038fd1498Szrj 	if (!_M_is_local())
22138fd1498Szrj 	  _M_destroy(_M_allocated_capacity);
22238fd1498Szrj       }
22338fd1498Szrj 
22438fd1498Szrj       void
22538fd1498Szrj       _M_destroy(size_type __size) throw()
22638fd1498Szrj       { _Alloc_traits::deallocate(_M_get_allocator(), _M_data(), __size + 1); }
22738fd1498Szrj 
22838fd1498Szrj       // _M_construct_aux is used to implement the 21.3.1 para 15 which
22938fd1498Szrj       // requires special behaviour if _InIterator is an integral type
23038fd1498Szrj       template<typename _InIterator>
23138fd1498Szrj         void
23238fd1498Szrj         _M_construct_aux(_InIterator __beg, _InIterator __end,
23338fd1498Szrj 			 std::__false_type)
23438fd1498Szrj 	{
23538fd1498Szrj           typedef typename iterator_traits<_InIterator>::iterator_category _Tag;
23638fd1498Szrj           _M_construct(__beg, __end, _Tag());
23738fd1498Szrj 	}
23838fd1498Szrj 
23938fd1498Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
24038fd1498Szrj       // 438. Ambiguity in the "do the right thing" clause
24138fd1498Szrj       template<typename _Integer>
24238fd1498Szrj         void
24338fd1498Szrj         _M_construct_aux(_Integer __beg, _Integer __end, std::__true_type)
24438fd1498Szrj 	{ _M_construct_aux_2(static_cast<size_type>(__beg), __end); }
24538fd1498Szrj 
24638fd1498Szrj       void
24738fd1498Szrj       _M_construct_aux_2(size_type __req, _CharT __c)
24838fd1498Szrj       { _M_construct(__req, __c); }
24938fd1498Szrj 
25038fd1498Szrj       template<typename _InIterator>
25138fd1498Szrj         void
25238fd1498Szrj         _M_construct(_InIterator __beg, _InIterator __end)
25338fd1498Szrj 	{
25438fd1498Szrj 	  typedef typename std::__is_integer<_InIterator>::__type _Integral;
25538fd1498Szrj 	  _M_construct_aux(__beg, __end, _Integral());
25638fd1498Szrj         }
25738fd1498Szrj 
25838fd1498Szrj       // For Input Iterators, used in istreambuf_iterators, etc.
25938fd1498Szrj       template<typename _InIterator>
26038fd1498Szrj         void
26138fd1498Szrj         _M_construct(_InIterator __beg, _InIterator __end,
26238fd1498Szrj 		     std::input_iterator_tag);
26338fd1498Szrj 
26438fd1498Szrj       // For forward_iterators up to random_access_iterators, used for
26538fd1498Szrj       // string::iterator, _CharT*, etc.
26638fd1498Szrj       template<typename _FwdIterator>
26738fd1498Szrj         void
26838fd1498Szrj         _M_construct(_FwdIterator __beg, _FwdIterator __end,
26938fd1498Szrj 		     std::forward_iterator_tag);
27038fd1498Szrj 
27138fd1498Szrj       void
27238fd1498Szrj       _M_construct(size_type __req, _CharT __c);
27338fd1498Szrj 
27438fd1498Szrj       allocator_type&
27538fd1498Szrj       _M_get_allocator()
27638fd1498Szrj       { return _M_dataplus; }
27738fd1498Szrj 
27838fd1498Szrj       const allocator_type&
27938fd1498Szrj       _M_get_allocator() const
28038fd1498Szrj       { return _M_dataplus; }
28138fd1498Szrj 
28238fd1498Szrj     private:
28338fd1498Szrj 
28438fd1498Szrj #ifdef _GLIBCXX_DISAMBIGUATE_REPLACE_INST
28538fd1498Szrj       // The explicit instantiations in misc-inst.cc require this due to
28638fd1498Szrj       // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64063
28738fd1498Szrj       template<typename _Tp, bool _Requires =
28838fd1498Szrj 	       !__are_same<_Tp, _CharT*>::__value
28938fd1498Szrj 	       && !__are_same<_Tp, const _CharT*>::__value
29038fd1498Szrj 	       && !__are_same<_Tp, iterator>::__value
29138fd1498Szrj 	       && !__are_same<_Tp, const_iterator>::__value>
29238fd1498Szrj 	struct __enable_if_not_native_iterator
29338fd1498Szrj 	{ typedef basic_string& __type; };
29438fd1498Szrj       template<typename _Tp>
29538fd1498Szrj 	struct __enable_if_not_native_iterator<_Tp, false> { };
29638fd1498Szrj #endif
29738fd1498Szrj 
29838fd1498Szrj       size_type
29938fd1498Szrj       _M_check(size_type __pos, const char* __s) const
30038fd1498Szrj       {
30138fd1498Szrj 	if (__pos > this->size())
30238fd1498Szrj 	  __throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > "
30338fd1498Szrj 				       "this->size() (which is %zu)"),
30438fd1498Szrj 				   __s, __pos, this->size());
30538fd1498Szrj 	return __pos;
30638fd1498Szrj       }
30738fd1498Szrj 
30838fd1498Szrj       void
30938fd1498Szrj       _M_check_length(size_type __n1, size_type __n2, const char* __s) const
31038fd1498Szrj       {
31138fd1498Szrj 	if (this->max_size() - (this->size() - __n1) < __n2)
31238fd1498Szrj 	  __throw_length_error(__N(__s));
31338fd1498Szrj       }
31438fd1498Szrj 
31538fd1498Szrj 
31638fd1498Szrj       // NB: _M_limit doesn't check for a bad __pos value.
31738fd1498Szrj       size_type
31838fd1498Szrj       _M_limit(size_type __pos, size_type __off) const _GLIBCXX_NOEXCEPT
31938fd1498Szrj       {
32038fd1498Szrj 	const bool __testoff =  __off < this->size() - __pos;
32138fd1498Szrj 	return __testoff ? __off : this->size() - __pos;
32238fd1498Szrj       }
32338fd1498Szrj 
32438fd1498Szrj       // True if _Rep and source do not overlap.
32538fd1498Szrj       bool
32638fd1498Szrj       _M_disjunct(const _CharT* __s) const _GLIBCXX_NOEXCEPT
32738fd1498Szrj       {
32838fd1498Szrj 	return (less<const _CharT*>()(__s, _M_data())
32938fd1498Szrj 		|| less<const _CharT*>()(_M_data() + this->size(), __s));
33038fd1498Szrj       }
33138fd1498Szrj 
33238fd1498Szrj       // When __n = 1 way faster than the general multichar
33338fd1498Szrj       // traits_type::copy/move/assign.
33438fd1498Szrj       static void
33538fd1498Szrj       _S_copy(_CharT* __d, const _CharT* __s, size_type __n)
33638fd1498Szrj       {
33738fd1498Szrj 	if (__n == 1)
33838fd1498Szrj 	  traits_type::assign(*__d, *__s);
33938fd1498Szrj 	else
34038fd1498Szrj 	  traits_type::copy(__d, __s, __n);
34138fd1498Szrj       }
34238fd1498Szrj 
34338fd1498Szrj       static void
34438fd1498Szrj       _S_move(_CharT* __d, const _CharT* __s, size_type __n)
34538fd1498Szrj       {
34638fd1498Szrj 	if (__n == 1)
34738fd1498Szrj 	  traits_type::assign(*__d, *__s);
34838fd1498Szrj 	else
34938fd1498Szrj 	  traits_type::move(__d, __s, __n);
35038fd1498Szrj       }
35138fd1498Szrj 
35238fd1498Szrj       static void
35338fd1498Szrj       _S_assign(_CharT* __d, size_type __n, _CharT __c)
35438fd1498Szrj       {
35538fd1498Szrj 	if (__n == 1)
35638fd1498Szrj 	  traits_type::assign(*__d, __c);
35738fd1498Szrj 	else
35838fd1498Szrj 	  traits_type::assign(__d, __n, __c);
35938fd1498Szrj       }
36038fd1498Szrj 
36138fd1498Szrj       // _S_copy_chars is a separate template to permit specialization
36238fd1498Szrj       // to optimize for the common case of pointers as iterators.
36338fd1498Szrj       template<class _Iterator>
36438fd1498Szrj         static void
36538fd1498Szrj         _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2)
36638fd1498Szrj         {
36738fd1498Szrj 	  for (; __k1 != __k2; ++__k1, (void)++__p)
36838fd1498Szrj 	    traits_type::assign(*__p, *__k1); // These types are off.
36938fd1498Szrj 	}
37038fd1498Szrj 
37138fd1498Szrj       static void
37238fd1498Szrj       _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2) _GLIBCXX_NOEXCEPT
37338fd1498Szrj       { _S_copy_chars(__p, __k1.base(), __k2.base()); }
37438fd1498Szrj 
37538fd1498Szrj       static void
37638fd1498Szrj       _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2)
37738fd1498Szrj       _GLIBCXX_NOEXCEPT
37838fd1498Szrj       { _S_copy_chars(__p, __k1.base(), __k2.base()); }
37938fd1498Szrj 
38038fd1498Szrj       static void
38138fd1498Szrj       _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) _GLIBCXX_NOEXCEPT
38238fd1498Szrj       { _S_copy(__p, __k1, __k2 - __k1); }
38338fd1498Szrj 
38438fd1498Szrj       static void
38538fd1498Szrj       _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2)
38638fd1498Szrj       _GLIBCXX_NOEXCEPT
38738fd1498Szrj       { _S_copy(__p, __k1, __k2 - __k1); }
38838fd1498Szrj 
38938fd1498Szrj       static int
39038fd1498Szrj       _S_compare(size_type __n1, size_type __n2) _GLIBCXX_NOEXCEPT
39138fd1498Szrj       {
39238fd1498Szrj 	const difference_type __d = difference_type(__n1 - __n2);
39338fd1498Szrj 
39438fd1498Szrj 	if (__d > __gnu_cxx::__numeric_traits<int>::__max)
39538fd1498Szrj 	  return __gnu_cxx::__numeric_traits<int>::__max;
39638fd1498Szrj 	else if (__d < __gnu_cxx::__numeric_traits<int>::__min)
39738fd1498Szrj 	  return __gnu_cxx::__numeric_traits<int>::__min;
39838fd1498Szrj 	else
39938fd1498Szrj 	  return int(__d);
40038fd1498Szrj       }
40138fd1498Szrj 
40238fd1498Szrj       void
40338fd1498Szrj       _M_assign(const basic_string&);
40438fd1498Szrj 
40538fd1498Szrj       void
40638fd1498Szrj       _M_mutate(size_type __pos, size_type __len1, const _CharT* __s,
40738fd1498Szrj 		size_type __len2);
40838fd1498Szrj 
40938fd1498Szrj       void
41038fd1498Szrj       _M_erase(size_type __pos, size_type __n);
41138fd1498Szrj 
41238fd1498Szrj     public:
41338fd1498Szrj       // Construct/copy/destroy:
41438fd1498Szrj       // NB: We overload ctors in some cases instead of using default
41538fd1498Szrj       // arguments, per 17.4.4.4 para. 2 item 2.
41638fd1498Szrj 
41738fd1498Szrj       /**
41838fd1498Szrj        *  @brief  Default constructor creates an empty string.
41938fd1498Szrj        */
42038fd1498Szrj       basic_string()
42138fd1498Szrj       _GLIBCXX_NOEXCEPT_IF(is_nothrow_default_constructible<_Alloc>::value)
42238fd1498Szrj       : _M_dataplus(_M_local_data())
42338fd1498Szrj       { _M_set_length(0); }
42438fd1498Szrj 
42538fd1498Szrj       /**
42638fd1498Szrj        *  @brief  Construct an empty string using allocator @a a.
42738fd1498Szrj        */
42838fd1498Szrj       explicit
42938fd1498Szrj       basic_string(const _Alloc& __a) _GLIBCXX_NOEXCEPT
43038fd1498Szrj       : _M_dataplus(_M_local_data(), __a)
43138fd1498Szrj       { _M_set_length(0); }
43238fd1498Szrj 
43338fd1498Szrj       /**
43438fd1498Szrj        *  @brief  Construct string with copy of value of @a __str.
43538fd1498Szrj        *  @param  __str  Source string.
43638fd1498Szrj        */
43738fd1498Szrj       basic_string(const basic_string& __str)
43838fd1498Szrj       : _M_dataplus(_M_local_data(),
43938fd1498Szrj 		    _Alloc_traits::_S_select_on_copy(__str._M_get_allocator()))
44038fd1498Szrj       { _M_construct(__str._M_data(), __str._M_data() + __str.length()); }
44138fd1498Szrj 
44238fd1498Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
44338fd1498Szrj       // 2583. no way to supply an allocator for basic_string(str, pos)
44438fd1498Szrj       /**
44538fd1498Szrj        *  @brief  Construct string as copy of a substring.
44638fd1498Szrj        *  @param  __str  Source string.
44738fd1498Szrj        *  @param  __pos  Index of first character to copy from.
44838fd1498Szrj        *  @param  __a  Allocator to use.
44938fd1498Szrj        */
45038fd1498Szrj       basic_string(const basic_string& __str, size_type __pos,
45138fd1498Szrj 		   const _Alloc& __a = _Alloc())
45238fd1498Szrj       : _M_dataplus(_M_local_data(), __a)
45338fd1498Szrj       {
45438fd1498Szrj 	const _CharT* __start = __str._M_data()
45538fd1498Szrj 	  + __str._M_check(__pos, "basic_string::basic_string");
45638fd1498Szrj 	_M_construct(__start, __start + __str._M_limit(__pos, npos));
45738fd1498Szrj       }
45838fd1498Szrj 
45938fd1498Szrj       /**
46038fd1498Szrj        *  @brief  Construct string as copy of a substring.
46138fd1498Szrj        *  @param  __str  Source string.
46238fd1498Szrj        *  @param  __pos  Index of first character to copy from.
46338fd1498Szrj        *  @param  __n  Number of characters to copy.
46438fd1498Szrj        */
46538fd1498Szrj       basic_string(const basic_string& __str, size_type __pos,
46638fd1498Szrj 		   size_type __n)
46738fd1498Szrj       : _M_dataplus(_M_local_data())
46838fd1498Szrj       {
46938fd1498Szrj 	const _CharT* __start = __str._M_data()
47038fd1498Szrj 	  + __str._M_check(__pos, "basic_string::basic_string");
47138fd1498Szrj 	_M_construct(__start, __start + __str._M_limit(__pos, __n));
47238fd1498Szrj       }
47338fd1498Szrj 
47438fd1498Szrj       /**
47538fd1498Szrj        *  @brief  Construct string as copy of a substring.
47638fd1498Szrj        *  @param  __str  Source string.
47738fd1498Szrj        *  @param  __pos  Index of first character to copy from.
47838fd1498Szrj        *  @param  __n  Number of characters to copy.
47938fd1498Szrj        *  @param  __a  Allocator to use.
48038fd1498Szrj        */
48138fd1498Szrj       basic_string(const basic_string& __str, size_type __pos,
48238fd1498Szrj 		   size_type __n, const _Alloc& __a)
48338fd1498Szrj       : _M_dataplus(_M_local_data(), __a)
48438fd1498Szrj       {
48538fd1498Szrj 	const _CharT* __start
48638fd1498Szrj 	  = __str._M_data() + __str._M_check(__pos, "string::string");
48738fd1498Szrj 	_M_construct(__start, __start + __str._M_limit(__pos, __n));
48838fd1498Szrj       }
48938fd1498Szrj 
49038fd1498Szrj       /**
49138fd1498Szrj        *  @brief  Construct string initialized by a character %array.
49238fd1498Szrj        *  @param  __s  Source character %array.
49338fd1498Szrj        *  @param  __n  Number of characters to copy.
49438fd1498Szrj        *  @param  __a  Allocator to use (default is default allocator).
49538fd1498Szrj        *
49638fd1498Szrj        *  NB: @a __s must have at least @a __n characters, &apos;\\0&apos;
49738fd1498Szrj        *  has no special meaning.
49838fd1498Szrj        */
49938fd1498Szrj       basic_string(const _CharT* __s, size_type __n,
50038fd1498Szrj 		   const _Alloc& __a = _Alloc())
50138fd1498Szrj       : _M_dataplus(_M_local_data(), __a)
50238fd1498Szrj       { _M_construct(__s, __s + __n); }
50338fd1498Szrj 
50438fd1498Szrj       /**
50538fd1498Szrj        *  @brief  Construct string as copy of a C string.
50638fd1498Szrj        *  @param  __s  Source C string.
50738fd1498Szrj        *  @param  __a  Allocator to use (default is default allocator).
50838fd1498Szrj        */
509*58e805e6Szrj #if __cpp_deduction_guides && ! defined _GLIBCXX_DEFINING_STRING_INSTANTIATIONS
510*58e805e6Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
511*58e805e6Szrj       // 3076. basic_string CTAD ambiguity
512*58e805e6Szrj       template<typename = _RequireAllocator<_Alloc>>
513*58e805e6Szrj #endif
51438fd1498Szrj       basic_string(const _CharT* __s, const _Alloc& __a = _Alloc())
51538fd1498Szrj       : _M_dataplus(_M_local_data(), __a)
51638fd1498Szrj       { _M_construct(__s, __s ? __s + traits_type::length(__s) : __s+npos); }
51738fd1498Szrj 
51838fd1498Szrj       /**
51938fd1498Szrj        *  @brief  Construct string as multiple characters.
52038fd1498Szrj        *  @param  __n  Number of characters.
52138fd1498Szrj        *  @param  __c  Character to use.
52238fd1498Szrj        *  @param  __a  Allocator to use (default is default allocator).
52338fd1498Szrj        */
524*58e805e6Szrj #if __cpp_deduction_guides && ! defined _GLIBCXX_DEFINING_STRING_INSTANTIATIONS
525*58e805e6Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
526*58e805e6Szrj       // 3076. basic_string CTAD ambiguity
527*58e805e6Szrj       template<typename = _RequireAllocator<_Alloc>>
528*58e805e6Szrj #endif
52938fd1498Szrj       basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc())
53038fd1498Szrj       : _M_dataplus(_M_local_data(), __a)
53138fd1498Szrj       { _M_construct(__n, __c); }
53238fd1498Szrj 
53338fd1498Szrj #if __cplusplus >= 201103L
53438fd1498Szrj       /**
53538fd1498Szrj        *  @brief  Move construct string.
53638fd1498Szrj        *  @param  __str  Source string.
53738fd1498Szrj        *
53838fd1498Szrj        *  The newly-created string contains the exact contents of @a __str.
53938fd1498Szrj        *  @a __str is a valid, but unspecified string.
54038fd1498Szrj        **/
54138fd1498Szrj       basic_string(basic_string&& __str) noexcept
54238fd1498Szrj       : _M_dataplus(_M_local_data(), std::move(__str._M_get_allocator()))
54338fd1498Szrj       {
54438fd1498Szrj 	if (__str._M_is_local())
54538fd1498Szrj 	  {
54638fd1498Szrj 	    traits_type::copy(_M_local_buf, __str._M_local_buf,
54738fd1498Szrj 			      _S_local_capacity + 1);
54838fd1498Szrj 	  }
54938fd1498Szrj 	else
55038fd1498Szrj 	  {
55138fd1498Szrj 	    _M_data(__str._M_data());
55238fd1498Szrj 	    _M_capacity(__str._M_allocated_capacity);
55338fd1498Szrj 	  }
55438fd1498Szrj 
55538fd1498Szrj 	// Must use _M_length() here not _M_set_length() because
55638fd1498Szrj 	// basic_stringbuf relies on writing into unallocated capacity so
55738fd1498Szrj 	// we mess up the contents if we put a '\0' in the string.
55838fd1498Szrj 	_M_length(__str.length());
55938fd1498Szrj 	__str._M_data(__str._M_local_data());
56038fd1498Szrj 	__str._M_set_length(0);
56138fd1498Szrj       }
56238fd1498Szrj 
56338fd1498Szrj       /**
56438fd1498Szrj        *  @brief  Construct string from an initializer %list.
56538fd1498Szrj        *  @param  __l  std::initializer_list of characters.
56638fd1498Szrj        *  @param  __a  Allocator to use (default is default allocator).
56738fd1498Szrj        */
56838fd1498Szrj       basic_string(initializer_list<_CharT> __l, const _Alloc& __a = _Alloc())
56938fd1498Szrj       : _M_dataplus(_M_local_data(), __a)
57038fd1498Szrj       { _M_construct(__l.begin(), __l.end()); }
57138fd1498Szrj 
57238fd1498Szrj       basic_string(const basic_string& __str, const _Alloc& __a)
57338fd1498Szrj       : _M_dataplus(_M_local_data(), __a)
57438fd1498Szrj       { _M_construct(__str.begin(), __str.end()); }
57538fd1498Szrj 
57638fd1498Szrj       basic_string(basic_string&& __str, const _Alloc& __a)
57738fd1498Szrj       noexcept(_Alloc_traits::_S_always_equal())
57838fd1498Szrj       : _M_dataplus(_M_local_data(), __a)
57938fd1498Szrj       {
58038fd1498Szrj 	if (__str._M_is_local())
58138fd1498Szrj 	  {
58238fd1498Szrj 	    traits_type::copy(_M_local_buf, __str._M_local_buf,
58338fd1498Szrj 			      _S_local_capacity + 1);
58438fd1498Szrj 	    _M_length(__str.length());
58538fd1498Szrj 	    __str._M_set_length(0);
58638fd1498Szrj 	  }
58738fd1498Szrj 	else if (_Alloc_traits::_S_always_equal()
58838fd1498Szrj 	    || __str.get_allocator() == __a)
58938fd1498Szrj 	  {
59038fd1498Szrj 	    _M_data(__str._M_data());
59138fd1498Szrj 	    _M_length(__str.length());
59238fd1498Szrj 	    _M_capacity(__str._M_allocated_capacity);
59338fd1498Szrj 	    __str._M_data(__str._M_local_buf);
59438fd1498Szrj 	    __str._M_set_length(0);
59538fd1498Szrj 	  }
59638fd1498Szrj 	else
59738fd1498Szrj 	  _M_construct(__str.begin(), __str.end());
59838fd1498Szrj       }
59938fd1498Szrj 
60038fd1498Szrj #endif // C++11
60138fd1498Szrj 
60238fd1498Szrj       /**
60338fd1498Szrj        *  @brief  Construct string as copy of a range.
60438fd1498Szrj        *  @param  __beg  Start of range.
60538fd1498Szrj        *  @param  __end  End of range.
60638fd1498Szrj        *  @param  __a  Allocator to use (default is default allocator).
60738fd1498Szrj        */
60838fd1498Szrj #if __cplusplus >= 201103L
60938fd1498Szrj       template<typename _InputIterator,
61038fd1498Szrj 	       typename = std::_RequireInputIter<_InputIterator>>
61138fd1498Szrj #else
61238fd1498Szrj       template<typename _InputIterator>
61338fd1498Szrj #endif
61438fd1498Szrj         basic_string(_InputIterator __beg, _InputIterator __end,
61538fd1498Szrj 		     const _Alloc& __a = _Alloc())
61638fd1498Szrj 	: _M_dataplus(_M_local_data(), __a)
61738fd1498Szrj 	{ _M_construct(__beg, __end); }
61838fd1498Szrj 
61938fd1498Szrj #if __cplusplus > 201402L
62038fd1498Szrj       /**
62138fd1498Szrj        *  @brief  Construct string from a substring of a string_view.
62238fd1498Szrj        *  @param  __t   Source object convertible to string view.
62338fd1498Szrj        *  @param  __pos The index of the first character to copy from __t.
62438fd1498Szrj        *  @param  __n   The number of characters to copy from __t.
62538fd1498Szrj        *  @param  __a   Allocator to use.
62638fd1498Szrj        */
62738fd1498Szrj       template<typename _Tp, typename = _If_sv<_Tp, void>>
62838fd1498Szrj 	basic_string(const _Tp& __t, size_type __pos, size_type __n,
62938fd1498Szrj 		     const _Alloc& __a = _Alloc())
63038fd1498Szrj 	: basic_string(_S_to_string_view(__t).substr(__pos, __n), __a) { }
63138fd1498Szrj 
63238fd1498Szrj       /**
63338fd1498Szrj        *  @brief  Construct string from a string_view.
63438fd1498Szrj        *  @param  __t  Source object convertible to string view.
63538fd1498Szrj        *  @param  __a  Allocator to use (default is default allocator).
63638fd1498Szrj        */
63738fd1498Szrj       template<typename _Tp, typename = _If_sv<_Tp, void>>
63838fd1498Szrj 	explicit
63938fd1498Szrj 	basic_string(const _Tp& __t, const _Alloc& __a = _Alloc())
64038fd1498Szrj 	: basic_string(__sv_wrapper(_S_to_string_view(__t)), __a) { }
64138fd1498Szrj 
64238fd1498Szrj       /**
64338fd1498Szrj        *  @brief  Only internally used: Construct string from a string view
64438fd1498Szrj        *          wrapper.
64538fd1498Szrj        *  @param  __svw  string view wrapper.
64638fd1498Szrj        *  @param  __a  Allocator to use.
64738fd1498Szrj        */
64838fd1498Szrj       explicit
64938fd1498Szrj       basic_string(__sv_wrapper __svw, const _Alloc& __a)
65038fd1498Szrj       : basic_string(__svw._M_sv.data(), __svw._M_sv.size(), __a) { }
65138fd1498Szrj #endif // C++17
65238fd1498Szrj 
65338fd1498Szrj       /**
65438fd1498Szrj        *  @brief  Destroy the string instance.
65538fd1498Szrj        */
65638fd1498Szrj       ~basic_string()
65738fd1498Szrj       { _M_dispose(); }
65838fd1498Szrj 
65938fd1498Szrj       /**
66038fd1498Szrj        *  @brief  Assign the value of @a str to this string.
66138fd1498Szrj        *  @param  __str  Source string.
66238fd1498Szrj        */
66338fd1498Szrj       basic_string&
66438fd1498Szrj       operator=(const basic_string& __str)
66538fd1498Szrj       {
66638fd1498Szrj #if __cplusplus >= 201103L
66738fd1498Szrj 	if (_Alloc_traits::_S_propagate_on_copy_assign())
66838fd1498Szrj 	  {
66938fd1498Szrj 	    if (!_Alloc_traits::_S_always_equal() && !_M_is_local()
67038fd1498Szrj 		&& _M_get_allocator() != __str._M_get_allocator())
67138fd1498Szrj 	      {
67238fd1498Szrj 		// Propagating allocator cannot free existing storage so must
67338fd1498Szrj 		// deallocate it before replacing current allocator.
67438fd1498Szrj 		if (__str.size() <= _S_local_capacity)
67538fd1498Szrj 		  {
67638fd1498Szrj 		    _M_destroy(_M_allocated_capacity);
67738fd1498Szrj 		    _M_data(_M_local_data());
67838fd1498Szrj 		    _M_set_length(0);
67938fd1498Szrj 		  }
68038fd1498Szrj 		else
68138fd1498Szrj 		  {
68238fd1498Szrj 		    const auto __len = __str.size();
68338fd1498Szrj 		    auto __alloc = __str._M_get_allocator();
68438fd1498Szrj 		    // If this allocation throws there are no effects:
68538fd1498Szrj 		    auto __ptr = _Alloc_traits::allocate(__alloc, __len + 1);
68638fd1498Szrj 		    _M_destroy(_M_allocated_capacity);
68738fd1498Szrj 		    _M_data(__ptr);
68838fd1498Szrj 		    _M_capacity(__len);
68938fd1498Szrj 		    _M_set_length(__len);
69038fd1498Szrj 		  }
69138fd1498Szrj 	      }
69238fd1498Szrj 	    std::__alloc_on_copy(_M_get_allocator(), __str._M_get_allocator());
69338fd1498Szrj 	  }
69438fd1498Szrj #endif
69538fd1498Szrj 	return this->assign(__str);
69638fd1498Szrj       }
69738fd1498Szrj 
69838fd1498Szrj       /**
69938fd1498Szrj        *  @brief  Copy contents of @a s into this string.
70038fd1498Szrj        *  @param  __s  Source null-terminated string.
70138fd1498Szrj        */
70238fd1498Szrj       basic_string&
70338fd1498Szrj       operator=(const _CharT* __s)
70438fd1498Szrj       { return this->assign(__s); }
70538fd1498Szrj 
70638fd1498Szrj       /**
70738fd1498Szrj        *  @brief  Set value to string of length 1.
70838fd1498Szrj        *  @param  __c  Source character.
70938fd1498Szrj        *
71038fd1498Szrj        *  Assigning to a character makes this string length 1 and
71138fd1498Szrj        *  (*this)[0] == @a c.
71238fd1498Szrj        */
71338fd1498Szrj       basic_string&
71438fd1498Szrj       operator=(_CharT __c)
71538fd1498Szrj       {
71638fd1498Szrj 	this->assign(1, __c);
71738fd1498Szrj 	return *this;
71838fd1498Szrj       }
71938fd1498Szrj 
72038fd1498Szrj #if __cplusplus >= 201103L
72138fd1498Szrj       /**
72238fd1498Szrj        *  @brief  Move assign the value of @a str to this string.
72338fd1498Szrj        *  @param  __str  Source string.
72438fd1498Szrj        *
72538fd1498Szrj        *  The contents of @a str are moved into this string (without copying).
72638fd1498Szrj        *  @a str is a valid, but unspecified string.
72738fd1498Szrj        **/
72838fd1498Szrj       // PR 58265, this should be noexcept.
72938fd1498Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
73038fd1498Szrj       // 2063. Contradictory requirements for string move assignment
73138fd1498Szrj       basic_string&
73238fd1498Szrj       operator=(basic_string&& __str)
73338fd1498Szrj       noexcept(_Alloc_traits::_S_nothrow_move())
73438fd1498Szrj       {
73538fd1498Szrj 	if (!_M_is_local() && _Alloc_traits::_S_propagate_on_move_assign()
73638fd1498Szrj 	    && !_Alloc_traits::_S_always_equal()
73738fd1498Szrj 	    && _M_get_allocator() != __str._M_get_allocator())
73838fd1498Szrj 	  {
73938fd1498Szrj 	    // Destroy existing storage before replacing allocator.
74038fd1498Szrj 	    _M_destroy(_M_allocated_capacity);
74138fd1498Szrj 	    _M_data(_M_local_data());
74238fd1498Szrj 	    _M_set_length(0);
74338fd1498Szrj 	  }
74438fd1498Szrj 	// Replace allocator if POCMA is true.
74538fd1498Szrj 	std::__alloc_on_move(_M_get_allocator(), __str._M_get_allocator());
74638fd1498Szrj 
747*58e805e6Szrj 	if (__str._M_is_local())
74838fd1498Szrj 	  {
749*58e805e6Szrj 	    // We've always got room for a short string, just copy it.
750*58e805e6Szrj 	    if (__str.size())
751*58e805e6Szrj 	      this->_S_copy(_M_data(), __str._M_data(), __str.size());
752*58e805e6Szrj 	    _M_set_length(__str.size());
753*58e805e6Szrj 	  }
754*58e805e6Szrj 	else if (_Alloc_traits::_S_propagate_on_move_assign()
755*58e805e6Szrj 	    || _Alloc_traits::_S_always_equal()
756*58e805e6Szrj 	    || _M_get_allocator() == __str._M_get_allocator())
757*58e805e6Szrj 	  {
758*58e805e6Szrj 	    // Just move the allocated pointer, our allocator can free it.
75938fd1498Szrj 	    pointer __data = nullptr;
76038fd1498Szrj 	    size_type __capacity;
76138fd1498Szrj 	    if (!_M_is_local())
76238fd1498Szrj 	      {
76338fd1498Szrj 		if (_Alloc_traits::_S_always_equal())
76438fd1498Szrj 		  {
765*58e805e6Szrj 		    // __str can reuse our existing storage.
76638fd1498Szrj 		    __data = _M_data();
76738fd1498Szrj 		    __capacity = _M_allocated_capacity;
76838fd1498Szrj 		  }
769*58e805e6Szrj 		else // __str can't use it, so free it.
77038fd1498Szrj 		  _M_destroy(_M_allocated_capacity);
77138fd1498Szrj 	      }
77238fd1498Szrj 
77338fd1498Szrj 	    _M_data(__str._M_data());
77438fd1498Szrj 	    _M_length(__str.length());
77538fd1498Szrj 	    _M_capacity(__str._M_allocated_capacity);
77638fd1498Szrj 	    if (__data)
77738fd1498Szrj 	      {
77838fd1498Szrj 		__str._M_data(__data);
77938fd1498Szrj 		__str._M_capacity(__capacity);
78038fd1498Szrj 	      }
78138fd1498Szrj 	    else
78238fd1498Szrj 	      __str._M_data(__str._M_local_buf);
78338fd1498Szrj 	  }
784*58e805e6Szrj 	else // Need to do a deep copy
78538fd1498Szrj 	  assign(__str);
78638fd1498Szrj 	__str.clear();
78738fd1498Szrj 	return *this;
78838fd1498Szrj       }
78938fd1498Szrj 
79038fd1498Szrj       /**
79138fd1498Szrj        *  @brief  Set value to string constructed from initializer %list.
79238fd1498Szrj        *  @param  __l  std::initializer_list.
79338fd1498Szrj        */
79438fd1498Szrj       basic_string&
79538fd1498Szrj       operator=(initializer_list<_CharT> __l)
79638fd1498Szrj       {
79738fd1498Szrj 	this->assign(__l.begin(), __l.size());
79838fd1498Szrj 	return *this;
79938fd1498Szrj       }
80038fd1498Szrj #endif // C++11
80138fd1498Szrj 
80238fd1498Szrj #if __cplusplus > 201402L
80338fd1498Szrj       /**
80438fd1498Szrj        *  @brief  Set value to string constructed from a string_view.
80538fd1498Szrj        *  @param  __svt  An object convertible to string_view.
80638fd1498Szrj        */
80738fd1498Szrj      template<typename _Tp>
80838fd1498Szrj        _If_sv<_Tp, basic_string&>
80938fd1498Szrj        operator=(const _Tp& __svt)
81038fd1498Szrj        { return this->assign(__svt); }
81138fd1498Szrj 
81238fd1498Szrj       /**
81338fd1498Szrj        *  @brief  Convert to a string_view.
81438fd1498Szrj        *  @return A string_view.
81538fd1498Szrj        */
81638fd1498Szrj       operator __sv_type() const noexcept
81738fd1498Szrj       { return __sv_type(data(), size()); }
81838fd1498Szrj #endif // C++17
81938fd1498Szrj 
82038fd1498Szrj       // Iterators:
82138fd1498Szrj       /**
82238fd1498Szrj        *  Returns a read/write iterator that points to the first character in
82338fd1498Szrj        *  the %string.
82438fd1498Szrj        */
82538fd1498Szrj       iterator
82638fd1498Szrj       begin() _GLIBCXX_NOEXCEPT
82738fd1498Szrj       { return iterator(_M_data()); }
82838fd1498Szrj 
82938fd1498Szrj       /**
83038fd1498Szrj        *  Returns a read-only (constant) iterator that points to the first
83138fd1498Szrj        *  character in the %string.
83238fd1498Szrj        */
83338fd1498Szrj       const_iterator
83438fd1498Szrj       begin() const _GLIBCXX_NOEXCEPT
83538fd1498Szrj       { return const_iterator(_M_data()); }
83638fd1498Szrj 
83738fd1498Szrj       /**
83838fd1498Szrj        *  Returns a read/write iterator that points one past the last
83938fd1498Szrj        *  character in the %string.
84038fd1498Szrj        */
84138fd1498Szrj       iterator
84238fd1498Szrj       end() _GLIBCXX_NOEXCEPT
84338fd1498Szrj       { return iterator(_M_data() + this->size()); }
84438fd1498Szrj 
84538fd1498Szrj       /**
84638fd1498Szrj        *  Returns a read-only (constant) iterator that points one past the
84738fd1498Szrj        *  last character in the %string.
84838fd1498Szrj        */
84938fd1498Szrj       const_iterator
85038fd1498Szrj       end() const _GLIBCXX_NOEXCEPT
85138fd1498Szrj       { return const_iterator(_M_data() + this->size()); }
85238fd1498Szrj 
85338fd1498Szrj       /**
85438fd1498Szrj        *  Returns a read/write reverse iterator that points to the last
85538fd1498Szrj        *  character in the %string.  Iteration is done in reverse element
85638fd1498Szrj        *  order.
85738fd1498Szrj        */
85838fd1498Szrj       reverse_iterator
85938fd1498Szrj       rbegin() _GLIBCXX_NOEXCEPT
86038fd1498Szrj       { return reverse_iterator(this->end()); }
86138fd1498Szrj 
86238fd1498Szrj       /**
86338fd1498Szrj        *  Returns a read-only (constant) reverse iterator that points
86438fd1498Szrj        *  to the last character in the %string.  Iteration is done in
86538fd1498Szrj        *  reverse element order.
86638fd1498Szrj        */
86738fd1498Szrj       const_reverse_iterator
86838fd1498Szrj       rbegin() const _GLIBCXX_NOEXCEPT
86938fd1498Szrj       { return const_reverse_iterator(this->end()); }
87038fd1498Szrj 
87138fd1498Szrj       /**
87238fd1498Szrj        *  Returns a read/write reverse iterator that points to one before the
87338fd1498Szrj        *  first character in the %string.  Iteration is done in reverse
87438fd1498Szrj        *  element order.
87538fd1498Szrj        */
87638fd1498Szrj       reverse_iterator
87738fd1498Szrj       rend() _GLIBCXX_NOEXCEPT
87838fd1498Szrj       { return reverse_iterator(this->begin()); }
87938fd1498Szrj 
88038fd1498Szrj       /**
88138fd1498Szrj        *  Returns a read-only (constant) reverse iterator that points
88238fd1498Szrj        *  to one before the first character in the %string.  Iteration
88338fd1498Szrj        *  is done in reverse element order.
88438fd1498Szrj        */
88538fd1498Szrj       const_reverse_iterator
88638fd1498Szrj       rend() const _GLIBCXX_NOEXCEPT
88738fd1498Szrj       { return const_reverse_iterator(this->begin()); }
88838fd1498Szrj 
88938fd1498Szrj #if __cplusplus >= 201103L
89038fd1498Szrj       /**
89138fd1498Szrj        *  Returns a read-only (constant) iterator that points to the first
89238fd1498Szrj        *  character in the %string.
89338fd1498Szrj        */
89438fd1498Szrj       const_iterator
89538fd1498Szrj       cbegin() const noexcept
89638fd1498Szrj       { return const_iterator(this->_M_data()); }
89738fd1498Szrj 
89838fd1498Szrj       /**
89938fd1498Szrj        *  Returns a read-only (constant) iterator that points one past the
90038fd1498Szrj        *  last character in the %string.
90138fd1498Szrj        */
90238fd1498Szrj       const_iterator
90338fd1498Szrj       cend() const noexcept
90438fd1498Szrj       { return const_iterator(this->_M_data() + this->size()); }
90538fd1498Szrj 
90638fd1498Szrj       /**
90738fd1498Szrj        *  Returns a read-only (constant) reverse iterator that points
90838fd1498Szrj        *  to the last character in the %string.  Iteration is done in
90938fd1498Szrj        *  reverse element order.
91038fd1498Szrj        */
91138fd1498Szrj       const_reverse_iterator
91238fd1498Szrj       crbegin() const noexcept
91338fd1498Szrj       { return const_reverse_iterator(this->end()); }
91438fd1498Szrj 
91538fd1498Szrj       /**
91638fd1498Szrj        *  Returns a read-only (constant) reverse iterator that points
91738fd1498Szrj        *  to one before the first character in the %string.  Iteration
91838fd1498Szrj        *  is done in reverse element order.
91938fd1498Szrj        */
92038fd1498Szrj       const_reverse_iterator
92138fd1498Szrj       crend() const noexcept
92238fd1498Szrj       { return const_reverse_iterator(this->begin()); }
92338fd1498Szrj #endif
92438fd1498Szrj 
92538fd1498Szrj     public:
92638fd1498Szrj       // Capacity:
92738fd1498Szrj       ///  Returns the number of characters in the string, not including any
92838fd1498Szrj       ///  null-termination.
92938fd1498Szrj       size_type
93038fd1498Szrj       size() const _GLIBCXX_NOEXCEPT
93138fd1498Szrj       { return _M_string_length; }
93238fd1498Szrj 
93338fd1498Szrj       ///  Returns the number of characters in the string, not including any
93438fd1498Szrj       ///  null-termination.
93538fd1498Szrj       size_type
93638fd1498Szrj       length() const _GLIBCXX_NOEXCEPT
93738fd1498Szrj       { return _M_string_length; }
93838fd1498Szrj 
93938fd1498Szrj       ///  Returns the size() of the largest possible %string.
94038fd1498Szrj       size_type
94138fd1498Szrj       max_size() const _GLIBCXX_NOEXCEPT
94238fd1498Szrj       { return (_Alloc_traits::max_size(_M_get_allocator()) - 1) / 2; }
94338fd1498Szrj 
94438fd1498Szrj       /**
94538fd1498Szrj        *  @brief  Resizes the %string to the specified number of characters.
94638fd1498Szrj        *  @param  __n  Number of characters the %string should contain.
94738fd1498Szrj        *  @param  __c  Character to fill any new elements.
94838fd1498Szrj        *
94938fd1498Szrj        *  This function will %resize the %string to the specified
95038fd1498Szrj        *  number of characters.  If the number is smaller than the
95138fd1498Szrj        *  %string's current size the %string is truncated, otherwise
95238fd1498Szrj        *  the %string is extended and new elements are %set to @a __c.
95338fd1498Szrj        */
95438fd1498Szrj       void
95538fd1498Szrj       resize(size_type __n, _CharT __c);
95638fd1498Szrj 
95738fd1498Szrj       /**
95838fd1498Szrj        *  @brief  Resizes the %string to the specified number of characters.
95938fd1498Szrj        *  @param  __n  Number of characters the %string should contain.
96038fd1498Szrj        *
96138fd1498Szrj        *  This function will resize the %string to the specified length.  If
96238fd1498Szrj        *  the new size is smaller than the %string's current size the %string
96338fd1498Szrj        *  is truncated, otherwise the %string is extended and new characters
96438fd1498Szrj        *  are default-constructed.  For basic types such as char, this means
96538fd1498Szrj        *  setting them to 0.
96638fd1498Szrj        */
96738fd1498Szrj       void
96838fd1498Szrj       resize(size_type __n)
96938fd1498Szrj       { this->resize(__n, _CharT()); }
97038fd1498Szrj 
97138fd1498Szrj #if __cplusplus >= 201103L
97238fd1498Szrj       ///  A non-binding request to reduce capacity() to size().
97338fd1498Szrj       void
97438fd1498Szrj       shrink_to_fit() noexcept
97538fd1498Szrj       {
97638fd1498Szrj #if __cpp_exceptions
97738fd1498Szrj 	if (capacity() > size())
97838fd1498Szrj 	  {
97938fd1498Szrj 	    try
98038fd1498Szrj 	      { reserve(0); }
98138fd1498Szrj 	    catch(...)
98238fd1498Szrj 	      { }
98338fd1498Szrj 	  }
98438fd1498Szrj #endif
98538fd1498Szrj       }
98638fd1498Szrj #endif
98738fd1498Szrj 
98838fd1498Szrj       /**
98938fd1498Szrj        *  Returns the total number of characters that the %string can hold
99038fd1498Szrj        *  before needing to allocate more memory.
99138fd1498Szrj        */
99238fd1498Szrj       size_type
99338fd1498Szrj       capacity() const _GLIBCXX_NOEXCEPT
99438fd1498Szrj       {
99538fd1498Szrj 	return _M_is_local() ? size_type(_S_local_capacity)
99638fd1498Szrj 	                     : _M_allocated_capacity;
99738fd1498Szrj       }
99838fd1498Szrj 
99938fd1498Szrj       /**
100038fd1498Szrj        *  @brief  Attempt to preallocate enough memory for specified number of
100138fd1498Szrj        *          characters.
100238fd1498Szrj        *  @param  __res_arg  Number of characters required.
100338fd1498Szrj        *  @throw  std::length_error  If @a __res_arg exceeds @c max_size().
100438fd1498Szrj        *
100538fd1498Szrj        *  This function attempts to reserve enough memory for the
100638fd1498Szrj        *  %string to hold the specified number of characters.  If the
100738fd1498Szrj        *  number requested is more than max_size(), length_error is
100838fd1498Szrj        *  thrown.
100938fd1498Szrj        *
101038fd1498Szrj        *  The advantage of this function is that if optimal code is a
101138fd1498Szrj        *  necessity and the user can determine the string length that will be
101238fd1498Szrj        *  required, the user can reserve the memory in %advance, and thus
101338fd1498Szrj        *  prevent a possible reallocation of memory and copying of %string
101438fd1498Szrj        *  data.
101538fd1498Szrj        */
101638fd1498Szrj       void
101738fd1498Szrj       reserve(size_type __res_arg = 0);
101838fd1498Szrj 
101938fd1498Szrj       /**
102038fd1498Szrj        *  Erases the string, making it empty.
102138fd1498Szrj        */
102238fd1498Szrj       void
102338fd1498Szrj       clear() _GLIBCXX_NOEXCEPT
102438fd1498Szrj       { _M_set_length(0); }
102538fd1498Szrj 
102638fd1498Szrj       /**
102738fd1498Szrj        *  Returns true if the %string is empty.  Equivalent to
102838fd1498Szrj        *  <code>*this == ""</code>.
102938fd1498Szrj        */
103038fd1498Szrj       bool
103138fd1498Szrj       empty() const _GLIBCXX_NOEXCEPT
103238fd1498Szrj       { return this->size() == 0; }
103338fd1498Szrj 
103438fd1498Szrj       // Element access:
103538fd1498Szrj       /**
103638fd1498Szrj        *  @brief  Subscript access to the data contained in the %string.
103738fd1498Szrj        *  @param  __pos  The index of the character to access.
103838fd1498Szrj        *  @return  Read-only (constant) reference to the character.
103938fd1498Szrj        *
104038fd1498Szrj        *  This operator allows for easy, array-style, data access.
104138fd1498Szrj        *  Note that data access with this operator is unchecked and
104238fd1498Szrj        *  out_of_range lookups are not defined. (For checked lookups
104338fd1498Szrj        *  see at().)
104438fd1498Szrj        */
104538fd1498Szrj       const_reference
104638fd1498Szrj       operator[] (size_type __pos) const _GLIBCXX_NOEXCEPT
104738fd1498Szrj       {
104838fd1498Szrj 	__glibcxx_assert(__pos <= size());
104938fd1498Szrj 	return _M_data()[__pos];
105038fd1498Szrj       }
105138fd1498Szrj 
105238fd1498Szrj       /**
105338fd1498Szrj        *  @brief  Subscript access to the data contained in the %string.
105438fd1498Szrj        *  @param  __pos  The index of the character to access.
105538fd1498Szrj        *  @return  Read/write reference to the character.
105638fd1498Szrj        *
105738fd1498Szrj        *  This operator allows for easy, array-style, data access.
105838fd1498Szrj        *  Note that data access with this operator is unchecked and
105938fd1498Szrj        *  out_of_range lookups are not defined. (For checked lookups
106038fd1498Szrj        *  see at().)
106138fd1498Szrj        */
106238fd1498Szrj       reference
106338fd1498Szrj       operator[](size_type __pos)
106438fd1498Szrj       {
106538fd1498Szrj         // Allow pos == size() both in C++98 mode, as v3 extension,
106638fd1498Szrj 	// and in C++11 mode.
106738fd1498Szrj 	__glibcxx_assert(__pos <= size());
106838fd1498Szrj         // In pedantic mode be strict in C++98 mode.
106938fd1498Szrj 	_GLIBCXX_DEBUG_PEDASSERT(__cplusplus >= 201103L || __pos < size());
107038fd1498Szrj 	return _M_data()[__pos];
107138fd1498Szrj       }
107238fd1498Szrj 
107338fd1498Szrj       /**
107438fd1498Szrj        *  @brief  Provides access to the data contained in the %string.
107538fd1498Szrj        *  @param __n The index of the character to access.
107638fd1498Szrj        *  @return  Read-only (const) reference to the character.
107738fd1498Szrj        *  @throw  std::out_of_range  If @a n is an invalid index.
107838fd1498Szrj        *
107938fd1498Szrj        *  This function provides for safer data access.  The parameter is
108038fd1498Szrj        *  first checked that it is in the range of the string.  The function
108138fd1498Szrj        *  throws out_of_range if the check fails.
108238fd1498Szrj        */
108338fd1498Szrj       const_reference
108438fd1498Szrj       at(size_type __n) const
108538fd1498Szrj       {
108638fd1498Szrj 	if (__n >= this->size())
108738fd1498Szrj 	  __throw_out_of_range_fmt(__N("basic_string::at: __n "
108838fd1498Szrj 				       "(which is %zu) >= this->size() "
108938fd1498Szrj 				       "(which is %zu)"),
109038fd1498Szrj 				   __n, this->size());
109138fd1498Szrj 	return _M_data()[__n];
109238fd1498Szrj       }
109338fd1498Szrj 
109438fd1498Szrj       /**
109538fd1498Szrj        *  @brief  Provides access to the data contained in the %string.
109638fd1498Szrj        *  @param __n The index of the character to access.
109738fd1498Szrj        *  @return  Read/write reference to the character.
109838fd1498Szrj        *  @throw  std::out_of_range  If @a n is an invalid index.
109938fd1498Szrj        *
110038fd1498Szrj        *  This function provides for safer data access.  The parameter is
110138fd1498Szrj        *  first checked that it is in the range of the string.  The function
110238fd1498Szrj        *  throws out_of_range if the check fails.
110338fd1498Szrj        */
110438fd1498Szrj       reference
110538fd1498Szrj       at(size_type __n)
110638fd1498Szrj       {
110738fd1498Szrj 	if (__n >= size())
110838fd1498Szrj 	  __throw_out_of_range_fmt(__N("basic_string::at: __n "
110938fd1498Szrj 				       "(which is %zu) >= this->size() "
111038fd1498Szrj 				       "(which is %zu)"),
111138fd1498Szrj 				   __n, this->size());
111238fd1498Szrj 	return _M_data()[__n];
111338fd1498Szrj       }
111438fd1498Szrj 
111538fd1498Szrj #if __cplusplus >= 201103L
111638fd1498Szrj       /**
111738fd1498Szrj        *  Returns a read/write reference to the data at the first
111838fd1498Szrj        *  element of the %string.
111938fd1498Szrj        */
112038fd1498Szrj       reference
112138fd1498Szrj       front() noexcept
112238fd1498Szrj       {
112338fd1498Szrj 	__glibcxx_assert(!empty());
112438fd1498Szrj 	return operator[](0);
112538fd1498Szrj       }
112638fd1498Szrj 
112738fd1498Szrj       /**
112838fd1498Szrj        *  Returns a read-only (constant) reference to the data at the first
112938fd1498Szrj        *  element of the %string.
113038fd1498Szrj        */
113138fd1498Szrj       const_reference
113238fd1498Szrj       front() const noexcept
113338fd1498Szrj       {
113438fd1498Szrj 	__glibcxx_assert(!empty());
113538fd1498Szrj 	return operator[](0);
113638fd1498Szrj       }
113738fd1498Szrj 
113838fd1498Szrj       /**
113938fd1498Szrj        *  Returns a read/write reference to the data at the last
114038fd1498Szrj        *  element of the %string.
114138fd1498Szrj        */
114238fd1498Szrj       reference
114338fd1498Szrj       back() noexcept
114438fd1498Szrj       {
114538fd1498Szrj 	__glibcxx_assert(!empty());
114638fd1498Szrj 	return operator[](this->size() - 1);
114738fd1498Szrj       }
114838fd1498Szrj 
114938fd1498Szrj       /**
115038fd1498Szrj        *  Returns a read-only (constant) reference to the data at the
115138fd1498Szrj        *  last element of the %string.
115238fd1498Szrj        */
115338fd1498Szrj       const_reference
115438fd1498Szrj       back() const noexcept
115538fd1498Szrj       {
115638fd1498Szrj 	__glibcxx_assert(!empty());
115738fd1498Szrj 	return operator[](this->size() - 1);
115838fd1498Szrj       }
115938fd1498Szrj #endif
116038fd1498Szrj 
116138fd1498Szrj       // Modifiers:
116238fd1498Szrj       /**
116338fd1498Szrj        *  @brief  Append a string to this string.
116438fd1498Szrj        *  @param __str  The string to append.
116538fd1498Szrj        *  @return  Reference to this string.
116638fd1498Szrj        */
116738fd1498Szrj       basic_string&
116838fd1498Szrj       operator+=(const basic_string& __str)
116938fd1498Szrj       { return this->append(__str); }
117038fd1498Szrj 
117138fd1498Szrj       /**
117238fd1498Szrj        *  @brief  Append a C string.
117338fd1498Szrj        *  @param __s  The C string to append.
117438fd1498Szrj        *  @return  Reference to this string.
117538fd1498Szrj        */
117638fd1498Szrj       basic_string&
117738fd1498Szrj       operator+=(const _CharT* __s)
117838fd1498Szrj       { return this->append(__s); }
117938fd1498Szrj 
118038fd1498Szrj       /**
118138fd1498Szrj        *  @brief  Append a character.
118238fd1498Szrj        *  @param __c  The character to append.
118338fd1498Szrj        *  @return  Reference to this string.
118438fd1498Szrj        */
118538fd1498Szrj       basic_string&
118638fd1498Szrj       operator+=(_CharT __c)
118738fd1498Szrj       {
118838fd1498Szrj 	this->push_back(__c);
118938fd1498Szrj 	return *this;
119038fd1498Szrj       }
119138fd1498Szrj 
119238fd1498Szrj #if __cplusplus >= 201103L
119338fd1498Szrj       /**
119438fd1498Szrj        *  @brief  Append an initializer_list of characters.
119538fd1498Szrj        *  @param __l  The initializer_list of characters to be appended.
119638fd1498Szrj        *  @return  Reference to this string.
119738fd1498Szrj        */
119838fd1498Szrj       basic_string&
119938fd1498Szrj       operator+=(initializer_list<_CharT> __l)
120038fd1498Szrj       { return this->append(__l.begin(), __l.size()); }
120138fd1498Szrj #endif // C++11
120238fd1498Szrj 
120338fd1498Szrj #if __cplusplus > 201402L
120438fd1498Szrj       /**
120538fd1498Szrj        *  @brief  Append a string_view.
120638fd1498Szrj        *  @param __svt  An object convertible to string_view to be appended.
120738fd1498Szrj        *  @return  Reference to this string.
120838fd1498Szrj        */
120938fd1498Szrj       template<typename _Tp>
121038fd1498Szrj 	_If_sv<_Tp, basic_string&>
121138fd1498Szrj 	operator+=(const _Tp& __svt)
121238fd1498Szrj 	{ return this->append(__svt); }
121338fd1498Szrj #endif // C++17
121438fd1498Szrj 
121538fd1498Szrj       /**
121638fd1498Szrj        *  @brief  Append a string to this string.
121738fd1498Szrj        *  @param __str  The string to append.
121838fd1498Szrj        *  @return  Reference to this string.
121938fd1498Szrj        */
122038fd1498Szrj       basic_string&
122138fd1498Szrj       append(const basic_string& __str)
122238fd1498Szrj       { return _M_append(__str._M_data(), __str.size()); }
122338fd1498Szrj 
122438fd1498Szrj       /**
122538fd1498Szrj        *  @brief  Append a substring.
122638fd1498Szrj        *  @param __str  The string to append.
122738fd1498Szrj        *  @param __pos  Index of the first character of str to append.
122838fd1498Szrj        *  @param __n  The number of characters to append.
122938fd1498Szrj        *  @return  Reference to this string.
123038fd1498Szrj        *  @throw  std::out_of_range if @a __pos is not a valid index.
123138fd1498Szrj        *
123238fd1498Szrj        *  This function appends @a __n characters from @a __str
123338fd1498Szrj        *  starting at @a __pos to this string.  If @a __n is is larger
123438fd1498Szrj        *  than the number of available characters in @a __str, the
123538fd1498Szrj        *  remainder of @a __str is appended.
123638fd1498Szrj        */
123738fd1498Szrj       basic_string&
1238*58e805e6Szrj       append(const basic_string& __str, size_type __pos, size_type __n = npos)
123938fd1498Szrj       { return _M_append(__str._M_data()
124038fd1498Szrj 			 + __str._M_check(__pos, "basic_string::append"),
124138fd1498Szrj 			 __str._M_limit(__pos, __n)); }
124238fd1498Szrj 
124338fd1498Szrj       /**
124438fd1498Szrj        *  @brief  Append a C substring.
124538fd1498Szrj        *  @param __s  The C string to append.
124638fd1498Szrj        *  @param __n  The number of characters to append.
124738fd1498Szrj        *  @return  Reference to this string.
124838fd1498Szrj        */
124938fd1498Szrj       basic_string&
125038fd1498Szrj       append(const _CharT* __s, size_type __n)
125138fd1498Szrj       {
125238fd1498Szrj 	__glibcxx_requires_string_len(__s, __n);
125338fd1498Szrj 	_M_check_length(size_type(0), __n, "basic_string::append");
125438fd1498Szrj 	return _M_append(__s, __n);
125538fd1498Szrj       }
125638fd1498Szrj 
125738fd1498Szrj       /**
125838fd1498Szrj        *  @brief  Append a C string.
125938fd1498Szrj        *  @param __s  The C string to append.
126038fd1498Szrj        *  @return  Reference to this string.
126138fd1498Szrj        */
126238fd1498Szrj       basic_string&
126338fd1498Szrj       append(const _CharT* __s)
126438fd1498Szrj       {
126538fd1498Szrj 	__glibcxx_requires_string(__s);
126638fd1498Szrj 	const size_type __n = traits_type::length(__s);
126738fd1498Szrj 	_M_check_length(size_type(0), __n, "basic_string::append");
126838fd1498Szrj 	return _M_append(__s, __n);
126938fd1498Szrj       }
127038fd1498Szrj 
127138fd1498Szrj       /**
127238fd1498Szrj        *  @brief  Append multiple characters.
127338fd1498Szrj        *  @param __n  The number of characters to append.
127438fd1498Szrj        *  @param __c  The character to use.
127538fd1498Szrj        *  @return  Reference to this string.
127638fd1498Szrj        *
127738fd1498Szrj        *  Appends __n copies of __c to this string.
127838fd1498Szrj        */
127938fd1498Szrj       basic_string&
128038fd1498Szrj       append(size_type __n, _CharT __c)
128138fd1498Szrj       { return _M_replace_aux(this->size(), size_type(0), __n, __c); }
128238fd1498Szrj 
128338fd1498Szrj #if __cplusplus >= 201103L
128438fd1498Szrj       /**
128538fd1498Szrj        *  @brief  Append an initializer_list of characters.
128638fd1498Szrj        *  @param __l  The initializer_list of characters to append.
128738fd1498Szrj        *  @return  Reference to this string.
128838fd1498Szrj        */
128938fd1498Szrj       basic_string&
129038fd1498Szrj       append(initializer_list<_CharT> __l)
129138fd1498Szrj       { return this->append(__l.begin(), __l.size()); }
129238fd1498Szrj #endif // C++11
129338fd1498Szrj 
129438fd1498Szrj       /**
129538fd1498Szrj        *  @brief  Append a range of characters.
129638fd1498Szrj        *  @param __first  Iterator referencing the first character to append.
129738fd1498Szrj        *  @param __last  Iterator marking the end of the range.
129838fd1498Szrj        *  @return  Reference to this string.
129938fd1498Szrj        *
130038fd1498Szrj        *  Appends characters in the range [__first,__last) to this string.
130138fd1498Szrj        */
130238fd1498Szrj #if __cplusplus >= 201103L
130338fd1498Szrj       template<class _InputIterator,
130438fd1498Szrj 	       typename = std::_RequireInputIter<_InputIterator>>
130538fd1498Szrj #else
130638fd1498Szrj       template<class _InputIterator>
130738fd1498Szrj #endif
130838fd1498Szrj         basic_string&
130938fd1498Szrj         append(_InputIterator __first, _InputIterator __last)
131038fd1498Szrj         { return this->replace(end(), end(), __first, __last); }
131138fd1498Szrj 
131238fd1498Szrj #if __cplusplus > 201402L
131338fd1498Szrj       /**
131438fd1498Szrj        *  @brief  Append a string_view.
131538fd1498Szrj        *  @param __svt  An object convertible to string_view to be appended.
131638fd1498Szrj        *  @return  Reference to this string.
131738fd1498Szrj        */
131838fd1498Szrj       template<typename _Tp>
131938fd1498Szrj         _If_sv<_Tp, basic_string&>
132038fd1498Szrj         append(const _Tp& __svt)
132138fd1498Szrj         {
132238fd1498Szrj           __sv_type __sv = __svt;
132338fd1498Szrj           return this->append(__sv.data(), __sv.size());
132438fd1498Szrj         }
132538fd1498Szrj 
132638fd1498Szrj       /**
132738fd1498Szrj        *  @brief  Append a range of characters from a string_view.
132838fd1498Szrj        *  @param __svt  An object convertible to string_view to be appended from.
132938fd1498Szrj        *  @param __pos The position in the string_view to append from.
133038fd1498Szrj        *  @param __n   The number of characters to append from the string_view.
133138fd1498Szrj        *  @return  Reference to this string.
133238fd1498Szrj        */
133338fd1498Szrj       template<typename _Tp>
133438fd1498Szrj         _If_sv<_Tp, basic_string&>
133538fd1498Szrj 	append(const _Tp& __svt, size_type __pos, size_type __n = npos)
133638fd1498Szrj 	{
133738fd1498Szrj 	  __sv_type __sv = __svt;
133838fd1498Szrj 	  return _M_append(__sv.data()
133938fd1498Szrj 			   + __sv._M_check(__pos, "basic_string::append"),
134038fd1498Szrj 			   __sv._M_limit(__pos, __n));
134138fd1498Szrj 	}
134238fd1498Szrj #endif // C++17
134338fd1498Szrj 
134438fd1498Szrj       /**
134538fd1498Szrj        *  @brief  Append a single character.
134638fd1498Szrj        *  @param __c  Character to append.
134738fd1498Szrj        */
134838fd1498Szrj       void
134938fd1498Szrj       push_back(_CharT __c)
135038fd1498Szrj       {
135138fd1498Szrj 	const size_type __size = this->size();
135238fd1498Szrj 	if (__size + 1 > this->capacity())
135338fd1498Szrj 	  this->_M_mutate(__size, size_type(0), 0, size_type(1));
135438fd1498Szrj 	traits_type::assign(this->_M_data()[__size], __c);
135538fd1498Szrj 	this->_M_set_length(__size + 1);
135638fd1498Szrj       }
135738fd1498Szrj 
135838fd1498Szrj       /**
135938fd1498Szrj        *  @brief  Set value to contents of another string.
136038fd1498Szrj        *  @param  __str  Source string to use.
136138fd1498Szrj        *  @return  Reference to this string.
136238fd1498Szrj        */
136338fd1498Szrj       basic_string&
136438fd1498Szrj       assign(const basic_string& __str)
136538fd1498Szrj       {
136638fd1498Szrj 	this->_M_assign(__str);
136738fd1498Szrj 	return *this;
136838fd1498Szrj       }
136938fd1498Szrj 
137038fd1498Szrj #if __cplusplus >= 201103L
137138fd1498Szrj       /**
137238fd1498Szrj        *  @brief  Set value to contents of another string.
137338fd1498Szrj        *  @param  __str  Source string to use.
137438fd1498Szrj        *  @return  Reference to this string.
137538fd1498Szrj        *
137638fd1498Szrj        *  This function sets this string to the exact contents of @a __str.
137738fd1498Szrj        *  @a __str is a valid, but unspecified string.
137838fd1498Szrj        */
137938fd1498Szrj       basic_string&
138038fd1498Szrj       assign(basic_string&& __str)
138138fd1498Szrj       noexcept(_Alloc_traits::_S_nothrow_move())
138238fd1498Szrj       {
138338fd1498Szrj 	// _GLIBCXX_RESOLVE_LIB_DEFECTS
138438fd1498Szrj 	// 2063. Contradictory requirements for string move assignment
138538fd1498Szrj 	return *this = std::move(__str);
138638fd1498Szrj       }
138738fd1498Szrj #endif // C++11
138838fd1498Szrj 
138938fd1498Szrj       /**
139038fd1498Szrj        *  @brief  Set value to a substring of a string.
139138fd1498Szrj        *  @param __str  The string to use.
139238fd1498Szrj        *  @param __pos  Index of the first character of str.
139338fd1498Szrj        *  @param __n  Number of characters to use.
139438fd1498Szrj        *  @return  Reference to this string.
139538fd1498Szrj        *  @throw  std::out_of_range if @a pos is not a valid index.
139638fd1498Szrj        *
139738fd1498Szrj        *  This function sets this string to the substring of @a __str
139838fd1498Szrj        *  consisting of @a __n characters at @a __pos.  If @a __n is
139938fd1498Szrj        *  is larger than the number of available characters in @a
140038fd1498Szrj        *  __str, the remainder of @a __str is used.
140138fd1498Szrj        */
140238fd1498Szrj       basic_string&
1403*58e805e6Szrj       assign(const basic_string& __str, size_type __pos, size_type __n = npos)
140438fd1498Szrj       { return _M_replace(size_type(0), this->size(), __str._M_data()
140538fd1498Szrj 			  + __str._M_check(__pos, "basic_string::assign"),
140638fd1498Szrj 			  __str._M_limit(__pos, __n)); }
140738fd1498Szrj 
140838fd1498Szrj       /**
140938fd1498Szrj        *  @brief  Set value to a C substring.
141038fd1498Szrj        *  @param __s  The C string to use.
141138fd1498Szrj        *  @param __n  Number of characters to use.
141238fd1498Szrj        *  @return  Reference to this string.
141338fd1498Szrj        *
141438fd1498Szrj        *  This function sets the value of this string to the first @a __n
141538fd1498Szrj        *  characters of @a __s.  If @a __n is is larger than the number of
141638fd1498Szrj        *  available characters in @a __s, the remainder of @a __s is used.
141738fd1498Szrj        */
141838fd1498Szrj       basic_string&
141938fd1498Szrj       assign(const _CharT* __s, size_type __n)
142038fd1498Szrj       {
142138fd1498Szrj 	__glibcxx_requires_string_len(__s, __n);
142238fd1498Szrj 	return _M_replace(size_type(0), this->size(), __s, __n);
142338fd1498Szrj       }
142438fd1498Szrj 
142538fd1498Szrj       /**
142638fd1498Szrj        *  @brief  Set value to contents of a C string.
142738fd1498Szrj        *  @param __s  The C string to use.
142838fd1498Szrj        *  @return  Reference to this string.
142938fd1498Szrj        *
143038fd1498Szrj        *  This function sets the value of this string to the value of @a __s.
143138fd1498Szrj        *  The data is copied, so there is no dependence on @a __s once the
143238fd1498Szrj        *  function returns.
143338fd1498Szrj        */
143438fd1498Szrj       basic_string&
143538fd1498Szrj       assign(const _CharT* __s)
143638fd1498Szrj       {
143738fd1498Szrj 	__glibcxx_requires_string(__s);
143838fd1498Szrj 	return _M_replace(size_type(0), this->size(), __s,
143938fd1498Szrj 			  traits_type::length(__s));
144038fd1498Szrj       }
144138fd1498Szrj 
144238fd1498Szrj       /**
144338fd1498Szrj        *  @brief  Set value to multiple characters.
144438fd1498Szrj        *  @param __n  Length of the resulting string.
144538fd1498Szrj        *  @param __c  The character to use.
144638fd1498Szrj        *  @return  Reference to this string.
144738fd1498Szrj        *
144838fd1498Szrj        *  This function sets the value of this string to @a __n copies of
144938fd1498Szrj        *  character @a __c.
145038fd1498Szrj        */
145138fd1498Szrj       basic_string&
145238fd1498Szrj       assign(size_type __n, _CharT __c)
145338fd1498Szrj       { return _M_replace_aux(size_type(0), this->size(), __n, __c); }
145438fd1498Szrj 
145538fd1498Szrj       /**
145638fd1498Szrj        *  @brief  Set value to a range of characters.
145738fd1498Szrj        *  @param __first  Iterator referencing the first character to append.
145838fd1498Szrj        *  @param __last  Iterator marking the end of the range.
145938fd1498Szrj        *  @return  Reference to this string.
146038fd1498Szrj        *
146138fd1498Szrj        *  Sets value of string to characters in the range [__first,__last).
146238fd1498Szrj       */
146338fd1498Szrj #if __cplusplus >= 201103L
146438fd1498Szrj       template<class _InputIterator,
146538fd1498Szrj 	       typename = std::_RequireInputIter<_InputIterator>>
146638fd1498Szrj #else
146738fd1498Szrj       template<class _InputIterator>
146838fd1498Szrj #endif
146938fd1498Szrj         basic_string&
147038fd1498Szrj         assign(_InputIterator __first, _InputIterator __last)
147138fd1498Szrj         { return this->replace(begin(), end(), __first, __last); }
147238fd1498Szrj 
147338fd1498Szrj #if __cplusplus >= 201103L
147438fd1498Szrj       /**
147538fd1498Szrj        *  @brief  Set value to an initializer_list of characters.
147638fd1498Szrj        *  @param __l  The initializer_list of characters to assign.
147738fd1498Szrj        *  @return  Reference to this string.
147838fd1498Szrj        */
147938fd1498Szrj       basic_string&
148038fd1498Szrj       assign(initializer_list<_CharT> __l)
148138fd1498Szrj       { return this->assign(__l.begin(), __l.size()); }
148238fd1498Szrj #endif // C++11
148338fd1498Szrj 
148438fd1498Szrj #if __cplusplus > 201402L
148538fd1498Szrj       /**
148638fd1498Szrj        *  @brief  Set value from a string_view.
148738fd1498Szrj        *  @param __svt  The source object convertible to string_view.
148838fd1498Szrj        *  @return  Reference to this string.
148938fd1498Szrj        */
149038fd1498Szrj       template<typename _Tp>
149138fd1498Szrj 	_If_sv<_Tp, basic_string&>
149238fd1498Szrj 	assign(const _Tp& __svt)
149338fd1498Szrj 	{
149438fd1498Szrj 	  __sv_type __sv = __svt;
149538fd1498Szrj 	  return this->assign(__sv.data(), __sv.size());
149638fd1498Szrj 	}
149738fd1498Szrj 
149838fd1498Szrj       /**
149938fd1498Szrj        *  @brief  Set value from a range of characters in a string_view.
150038fd1498Szrj        *  @param __svt  The source object convertible to string_view.
150138fd1498Szrj        *  @param __pos  The position in the string_view to assign from.
150238fd1498Szrj        *  @param __n  The number of characters to assign.
150338fd1498Szrj        *  @return  Reference to this string.
150438fd1498Szrj        */
150538fd1498Szrj       template<typename _Tp>
150638fd1498Szrj 	_If_sv<_Tp, basic_string&>
150738fd1498Szrj 	assign(const _Tp& __svt, size_type __pos, size_type __n = npos)
150838fd1498Szrj 	{
150938fd1498Szrj 	  __sv_type __sv = __svt;
151038fd1498Szrj 	  return _M_replace(size_type(0), this->size(), __sv.data()
151138fd1498Szrj 			    + __sv._M_check(__pos, "basic_string::assign"),
151238fd1498Szrj 			    __sv._M_limit(__pos, __n));
151338fd1498Szrj 	}
151438fd1498Szrj #endif // C++17
151538fd1498Szrj 
151638fd1498Szrj #if __cplusplus >= 201103L
151738fd1498Szrj       /**
151838fd1498Szrj        *  @brief  Insert multiple characters.
151938fd1498Szrj        *  @param __p  Const_iterator referencing location in string to
152038fd1498Szrj        *              insert at.
152138fd1498Szrj        *  @param __n  Number of characters to insert
152238fd1498Szrj        *  @param __c  The character to insert.
152338fd1498Szrj        *  @return  Iterator referencing the first inserted char.
152438fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
152538fd1498Szrj        *
152638fd1498Szrj        *  Inserts @a __n copies of character @a __c starting at the
152738fd1498Szrj        *  position referenced by iterator @a __p.  If adding
152838fd1498Szrj        *  characters causes the length to exceed max_size(),
152938fd1498Szrj        *  length_error is thrown.  The value of the string doesn't
153038fd1498Szrj        *  change if an error is thrown.
153138fd1498Szrj       */
153238fd1498Szrj       iterator
153338fd1498Szrj       insert(const_iterator __p, size_type __n, _CharT __c)
153438fd1498Szrj       {
153538fd1498Szrj 	_GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end());
153638fd1498Szrj 	const size_type __pos = __p - begin();
153738fd1498Szrj 	this->replace(__p, __p, __n, __c);
153838fd1498Szrj 	return iterator(this->_M_data() + __pos);
153938fd1498Szrj       }
154038fd1498Szrj #else
154138fd1498Szrj       /**
154238fd1498Szrj        *  @brief  Insert multiple characters.
154338fd1498Szrj        *  @param __p  Iterator referencing location in string to insert at.
154438fd1498Szrj        *  @param __n  Number of characters to insert
154538fd1498Szrj        *  @param __c  The character to insert.
154638fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
154738fd1498Szrj        *
154838fd1498Szrj        *  Inserts @a __n copies of character @a __c starting at the
154938fd1498Szrj        *  position referenced by iterator @a __p.  If adding
155038fd1498Szrj        *  characters causes the length to exceed max_size(),
155138fd1498Szrj        *  length_error is thrown.  The value of the string doesn't
155238fd1498Szrj        *  change if an error is thrown.
155338fd1498Szrj       */
155438fd1498Szrj       void
155538fd1498Szrj       insert(iterator __p, size_type __n, _CharT __c)
155638fd1498Szrj       {	this->replace(__p, __p, __n, __c);  }
155738fd1498Szrj #endif
155838fd1498Szrj 
155938fd1498Szrj #if __cplusplus >= 201103L
156038fd1498Szrj       /**
156138fd1498Szrj        *  @brief  Insert a range of characters.
156238fd1498Szrj        *  @param __p  Const_iterator referencing location in string to
156338fd1498Szrj        *              insert at.
156438fd1498Szrj        *  @param __beg  Start of range.
156538fd1498Szrj        *  @param __end  End of range.
156638fd1498Szrj        *  @return  Iterator referencing the first inserted char.
156738fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
156838fd1498Szrj        *
156938fd1498Szrj        *  Inserts characters in range [beg,end).  If adding characters
157038fd1498Szrj        *  causes the length to exceed max_size(), length_error is
157138fd1498Szrj        *  thrown.  The value of the string doesn't change if an error
157238fd1498Szrj        *  is thrown.
157338fd1498Szrj       */
157438fd1498Szrj       template<class _InputIterator,
157538fd1498Szrj 	       typename = std::_RequireInputIter<_InputIterator>>
157638fd1498Szrj 	iterator
157738fd1498Szrj         insert(const_iterator __p, _InputIterator __beg, _InputIterator __end)
157838fd1498Szrj         {
157938fd1498Szrj 	  _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end());
158038fd1498Szrj 	  const size_type __pos = __p - begin();
158138fd1498Szrj 	  this->replace(__p, __p, __beg, __end);
158238fd1498Szrj 	  return iterator(this->_M_data() + __pos);
158338fd1498Szrj 	}
158438fd1498Szrj #else
158538fd1498Szrj       /**
158638fd1498Szrj        *  @brief  Insert a range of characters.
158738fd1498Szrj        *  @param __p  Iterator referencing location in string to insert at.
158838fd1498Szrj        *  @param __beg  Start of range.
158938fd1498Szrj        *  @param __end  End of range.
159038fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
159138fd1498Szrj        *
159238fd1498Szrj        *  Inserts characters in range [__beg,__end).  If adding
159338fd1498Szrj        *  characters causes the length to exceed max_size(),
159438fd1498Szrj        *  length_error is thrown.  The value of the string doesn't
159538fd1498Szrj        *  change if an error is thrown.
159638fd1498Szrj       */
159738fd1498Szrj       template<class _InputIterator>
159838fd1498Szrj         void
159938fd1498Szrj         insert(iterator __p, _InputIterator __beg, _InputIterator __end)
160038fd1498Szrj         { this->replace(__p, __p, __beg, __end); }
160138fd1498Szrj #endif
160238fd1498Szrj 
160338fd1498Szrj #if __cplusplus >= 201103L
160438fd1498Szrj       /**
160538fd1498Szrj        *  @brief  Insert an initializer_list of characters.
160638fd1498Szrj        *  @param __p  Iterator referencing location in string to insert at.
160738fd1498Szrj        *  @param __l  The initializer_list of characters to insert.
160838fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
160938fd1498Szrj        */
161038fd1498Szrj       void
161138fd1498Szrj       insert(iterator __p, initializer_list<_CharT> __l)
161238fd1498Szrj       {
161338fd1498Szrj 	_GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end());
161438fd1498Szrj 	this->insert(__p - begin(), __l.begin(), __l.size());
161538fd1498Szrj       }
161638fd1498Szrj #endif // C++11
161738fd1498Szrj 
161838fd1498Szrj       /**
161938fd1498Szrj        *  @brief  Insert value of a string.
162038fd1498Szrj        *  @param __pos1  Iterator referencing location in string to insert at.
162138fd1498Szrj        *  @param __str  The string to insert.
162238fd1498Szrj        *  @return  Reference to this string.
162338fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
162438fd1498Szrj        *
162538fd1498Szrj        *  Inserts value of @a __str starting at @a __pos1.  If adding
162638fd1498Szrj        *  characters causes the length to exceed max_size(),
162738fd1498Szrj        *  length_error is thrown.  The value of the string doesn't
162838fd1498Szrj        *  change if an error is thrown.
162938fd1498Szrj       */
163038fd1498Szrj       basic_string&
163138fd1498Szrj       insert(size_type __pos1, const basic_string& __str)
163238fd1498Szrj       { return this->replace(__pos1, size_type(0),
163338fd1498Szrj 			     __str._M_data(), __str.size()); }
163438fd1498Szrj 
163538fd1498Szrj       /**
163638fd1498Szrj        *  @brief  Insert a substring.
163738fd1498Szrj        *  @param __pos1  Iterator referencing location in string to insert at.
163838fd1498Szrj        *  @param __str  The string to insert.
163938fd1498Szrj        *  @param __pos2  Start of characters in str to insert.
164038fd1498Szrj        *  @param __n  Number of characters to insert.
164138fd1498Szrj        *  @return  Reference to this string.
164238fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
164338fd1498Szrj        *  @throw  std::out_of_range  If @a pos1 > size() or
164438fd1498Szrj        *  @a __pos2 > @a str.size().
164538fd1498Szrj        *
164638fd1498Szrj        *  Starting at @a pos1, insert @a __n character of @a __str
164738fd1498Szrj        *  beginning with @a __pos2.  If adding characters causes the
164838fd1498Szrj        *  length to exceed max_size(), length_error is thrown.  If @a
164938fd1498Szrj        *  __pos1 is beyond the end of this string or @a __pos2 is
165038fd1498Szrj        *  beyond the end of @a __str, out_of_range is thrown.  The
165138fd1498Szrj        *  value of the string doesn't change if an error is thrown.
165238fd1498Szrj       */
165338fd1498Szrj       basic_string&
165438fd1498Szrj       insert(size_type __pos1, const basic_string& __str,
1655*58e805e6Szrj 	     size_type __pos2, size_type __n = npos)
165638fd1498Szrj       { return this->replace(__pos1, size_type(0), __str._M_data()
165738fd1498Szrj 			     + __str._M_check(__pos2, "basic_string::insert"),
165838fd1498Szrj 			     __str._M_limit(__pos2, __n)); }
165938fd1498Szrj 
166038fd1498Szrj       /**
166138fd1498Szrj        *  @brief  Insert a C substring.
166238fd1498Szrj        *  @param __pos  Iterator referencing location in string to insert at.
166338fd1498Szrj        *  @param __s  The C string to insert.
166438fd1498Szrj        *  @param __n  The number of characters to insert.
166538fd1498Szrj        *  @return  Reference to this string.
166638fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
166738fd1498Szrj        *  @throw  std::out_of_range  If @a __pos is beyond the end of this
166838fd1498Szrj        *  string.
166938fd1498Szrj        *
167038fd1498Szrj        *  Inserts the first @a __n characters of @a __s starting at @a
167138fd1498Szrj        *  __pos.  If adding characters causes the length to exceed
167238fd1498Szrj        *  max_size(), length_error is thrown.  If @a __pos is beyond
167338fd1498Szrj        *  end(), out_of_range is thrown.  The value of the string
167438fd1498Szrj        *  doesn't change if an error is thrown.
167538fd1498Szrj       */
167638fd1498Szrj       basic_string&
167738fd1498Szrj       insert(size_type __pos, const _CharT* __s, size_type __n)
167838fd1498Szrj       { return this->replace(__pos, size_type(0), __s, __n); }
167938fd1498Szrj 
168038fd1498Szrj       /**
168138fd1498Szrj        *  @brief  Insert a C string.
168238fd1498Szrj        *  @param __pos  Iterator referencing location in string to insert at.
168338fd1498Szrj        *  @param __s  The C string to insert.
168438fd1498Szrj        *  @return  Reference to this string.
168538fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
168638fd1498Szrj        *  @throw  std::out_of_range  If @a pos is beyond the end of this
168738fd1498Szrj        *  string.
168838fd1498Szrj        *
168938fd1498Szrj        *  Inserts the first @a n characters of @a __s starting at @a __pos.  If
169038fd1498Szrj        *  adding characters causes the length to exceed max_size(),
169138fd1498Szrj        *  length_error is thrown.  If @a __pos is beyond end(), out_of_range is
169238fd1498Szrj        *  thrown.  The value of the string doesn't change if an error is
169338fd1498Szrj        *  thrown.
169438fd1498Szrj       */
169538fd1498Szrj       basic_string&
169638fd1498Szrj       insert(size_type __pos, const _CharT* __s)
169738fd1498Szrj       {
169838fd1498Szrj 	__glibcxx_requires_string(__s);
169938fd1498Szrj 	return this->replace(__pos, size_type(0), __s,
170038fd1498Szrj 			     traits_type::length(__s));
170138fd1498Szrj       }
170238fd1498Szrj 
170338fd1498Szrj       /**
170438fd1498Szrj        *  @brief  Insert multiple characters.
170538fd1498Szrj        *  @param __pos  Index in string to insert at.
170638fd1498Szrj        *  @param __n  Number of characters to insert
170738fd1498Szrj        *  @param __c  The character to insert.
170838fd1498Szrj        *  @return  Reference to this string.
170938fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
171038fd1498Szrj        *  @throw  std::out_of_range  If @a __pos is beyond the end of this
171138fd1498Szrj        *  string.
171238fd1498Szrj        *
171338fd1498Szrj        *  Inserts @a __n copies of character @a __c starting at index
171438fd1498Szrj        *  @a __pos.  If adding characters causes the length to exceed
171538fd1498Szrj        *  max_size(), length_error is thrown.  If @a __pos > length(),
171638fd1498Szrj        *  out_of_range is thrown.  The value of the string doesn't
171738fd1498Szrj        *  change if an error is thrown.
171838fd1498Szrj       */
171938fd1498Szrj       basic_string&
172038fd1498Szrj       insert(size_type __pos, size_type __n, _CharT __c)
172138fd1498Szrj       { return _M_replace_aux(_M_check(__pos, "basic_string::insert"),
172238fd1498Szrj 			      size_type(0), __n, __c); }
172338fd1498Szrj 
172438fd1498Szrj       /**
172538fd1498Szrj        *  @brief  Insert one character.
172638fd1498Szrj        *  @param __p  Iterator referencing position in string to insert at.
172738fd1498Szrj        *  @param __c  The character to insert.
172838fd1498Szrj        *  @return  Iterator referencing newly inserted char.
172938fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
173038fd1498Szrj        *
173138fd1498Szrj        *  Inserts character @a __c at position referenced by @a __p.
173238fd1498Szrj        *  If adding character causes the length to exceed max_size(),
173338fd1498Szrj        *  length_error is thrown.  If @a __p is beyond end of string,
173438fd1498Szrj        *  out_of_range is thrown.  The value of the string doesn't
173538fd1498Szrj        *  change if an error is thrown.
173638fd1498Szrj       */
173738fd1498Szrj       iterator
173838fd1498Szrj       insert(__const_iterator __p, _CharT __c)
173938fd1498Szrj       {
174038fd1498Szrj 	_GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end());
174138fd1498Szrj 	const size_type __pos = __p - begin();
174238fd1498Szrj 	_M_replace_aux(__pos, size_type(0), size_type(1), __c);
174338fd1498Szrj 	return iterator(_M_data() + __pos);
174438fd1498Szrj       }
174538fd1498Szrj 
174638fd1498Szrj #if __cplusplus > 201402L
174738fd1498Szrj       /**
174838fd1498Szrj        *  @brief  Insert a string_view.
174938fd1498Szrj        *  @param __pos  Iterator referencing position in string to insert at.
175038fd1498Szrj        *  @param __svt  The object convertible to string_view to insert.
175138fd1498Szrj        *  @return  Reference to this string.
175238fd1498Szrj       */
175338fd1498Szrj       template<typename _Tp>
175438fd1498Szrj 	_If_sv<_Tp, basic_string&>
175538fd1498Szrj 	insert(size_type __pos, const _Tp& __svt)
175638fd1498Szrj 	{
175738fd1498Szrj 	  __sv_type __sv = __svt;
175838fd1498Szrj 	  return this->insert(__pos, __sv.data(), __sv.size());
175938fd1498Szrj 	}
176038fd1498Szrj 
176138fd1498Szrj       /**
176238fd1498Szrj        *  @brief  Insert a string_view.
176338fd1498Szrj        *  @param __pos  Iterator referencing position in string to insert at.
176438fd1498Szrj        *  @param __svt  The object convertible to string_view to insert from.
176538fd1498Szrj        *  @param __pos  Iterator referencing position in string_view to insert
176638fd1498Szrj        *  from.
176738fd1498Szrj        *  @param __n    The number of characters to insert.
176838fd1498Szrj        *  @return  Reference to this string.
176938fd1498Szrj       */
177038fd1498Szrj       template<typename _Tp>
177138fd1498Szrj 	_If_sv<_Tp, basic_string&>
177238fd1498Szrj 	insert(size_type __pos1, const _Tp& __svt,
177338fd1498Szrj 	       size_type __pos2, size_type __n = npos)
177438fd1498Szrj 	{
177538fd1498Szrj 	  __sv_type __sv = __svt;
177638fd1498Szrj 	  return this->replace(__pos1, size_type(0), __sv.data()
177738fd1498Szrj 			       + __sv._M_check(__pos2, "basic_string::insert"),
177838fd1498Szrj 			       __sv._M_limit(__pos2, __n));
177938fd1498Szrj 	}
178038fd1498Szrj #endif // C++17
178138fd1498Szrj 
178238fd1498Szrj       /**
178338fd1498Szrj        *  @brief  Remove characters.
178438fd1498Szrj        *  @param __pos  Index of first character to remove (default 0).
178538fd1498Szrj        *  @param __n  Number of characters to remove (default remainder).
178638fd1498Szrj        *  @return  Reference to this string.
178738fd1498Szrj        *  @throw  std::out_of_range  If @a pos is beyond the end of this
178838fd1498Szrj        *  string.
178938fd1498Szrj        *
179038fd1498Szrj        *  Removes @a __n characters from this string starting at @a
179138fd1498Szrj        *  __pos.  The length of the string is reduced by @a __n.  If
179238fd1498Szrj        *  there are < @a __n characters to remove, the remainder of
179338fd1498Szrj        *  the string is truncated.  If @a __p is beyond end of string,
179438fd1498Szrj        *  out_of_range is thrown.  The value of the string doesn't
179538fd1498Szrj        *  change if an error is thrown.
179638fd1498Szrj       */
179738fd1498Szrj       basic_string&
179838fd1498Szrj       erase(size_type __pos = 0, size_type __n = npos)
179938fd1498Szrj       {
180038fd1498Szrj 	_M_check(__pos, "basic_string::erase");
180138fd1498Szrj 	if (__n == npos)
180238fd1498Szrj 	  this->_M_set_length(__pos);
180338fd1498Szrj 	else if (__n != 0)
180438fd1498Szrj 	  this->_M_erase(__pos, _M_limit(__pos, __n));
180538fd1498Szrj 	return *this;
180638fd1498Szrj       }
180738fd1498Szrj 
180838fd1498Szrj       /**
180938fd1498Szrj        *  @brief  Remove one character.
181038fd1498Szrj        *  @param __position  Iterator referencing the character to remove.
181138fd1498Szrj        *  @return  iterator referencing same location after removal.
181238fd1498Szrj        *
181338fd1498Szrj        *  Removes the character at @a __position from this string. The value
181438fd1498Szrj        *  of the string doesn't change if an error is thrown.
181538fd1498Szrj       */
181638fd1498Szrj       iterator
181738fd1498Szrj       erase(__const_iterator __position)
181838fd1498Szrj       {
181938fd1498Szrj 	_GLIBCXX_DEBUG_PEDASSERT(__position >= begin()
182038fd1498Szrj 				 && __position < end());
182138fd1498Szrj 	const size_type __pos = __position - begin();
182238fd1498Szrj 	this->_M_erase(__pos, size_type(1));
182338fd1498Szrj 	return iterator(_M_data() + __pos);
182438fd1498Szrj       }
182538fd1498Szrj 
182638fd1498Szrj       /**
182738fd1498Szrj        *  @brief  Remove a range of characters.
182838fd1498Szrj        *  @param __first  Iterator referencing the first character to remove.
182938fd1498Szrj        *  @param __last  Iterator referencing the end of the range.
183038fd1498Szrj        *  @return  Iterator referencing location of first after removal.
183138fd1498Szrj        *
183238fd1498Szrj        *  Removes the characters in the range [first,last) from this string.
183338fd1498Szrj        *  The value of the string doesn't change if an error is thrown.
183438fd1498Szrj       */
183538fd1498Szrj       iterator
183638fd1498Szrj       erase(__const_iterator __first, __const_iterator __last)
183738fd1498Szrj       {
183838fd1498Szrj 	_GLIBCXX_DEBUG_PEDASSERT(__first >= begin() && __first <= __last
183938fd1498Szrj 				 && __last <= end());
184038fd1498Szrj         const size_type __pos = __first - begin();
184138fd1498Szrj 	if (__last == end())
184238fd1498Szrj 	  this->_M_set_length(__pos);
184338fd1498Szrj 	else
184438fd1498Szrj 	  this->_M_erase(__pos, __last - __first);
184538fd1498Szrj 	return iterator(this->_M_data() + __pos);
184638fd1498Szrj       }
184738fd1498Szrj 
184838fd1498Szrj #if __cplusplus >= 201103L
184938fd1498Szrj       /**
185038fd1498Szrj        *  @brief  Remove the last character.
185138fd1498Szrj        *
185238fd1498Szrj        *  The string must be non-empty.
185338fd1498Szrj        */
185438fd1498Szrj       void
185538fd1498Szrj       pop_back() noexcept
185638fd1498Szrj       {
185738fd1498Szrj 	__glibcxx_assert(!empty());
185838fd1498Szrj 	_M_erase(size() - 1, 1);
185938fd1498Szrj       }
186038fd1498Szrj #endif // C++11
186138fd1498Szrj 
186238fd1498Szrj       /**
186338fd1498Szrj        *  @brief  Replace characters with value from another string.
186438fd1498Szrj        *  @param __pos  Index of first character to replace.
186538fd1498Szrj        *  @param __n  Number of characters to be replaced.
186638fd1498Szrj        *  @param __str  String to insert.
186738fd1498Szrj        *  @return  Reference to this string.
186838fd1498Szrj        *  @throw  std::out_of_range  If @a pos is beyond the end of this
186938fd1498Szrj        *  string.
187038fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
187138fd1498Szrj        *
187238fd1498Szrj        *  Removes the characters in the range [__pos,__pos+__n) from
187338fd1498Szrj        *  this string.  In place, the value of @a __str is inserted.
187438fd1498Szrj        *  If @a __pos is beyond end of string, out_of_range is thrown.
187538fd1498Szrj        *  If the length of the result exceeds max_size(), length_error
187638fd1498Szrj        *  is thrown.  The value of the string doesn't change if an
187738fd1498Szrj        *  error is thrown.
187838fd1498Szrj       */
187938fd1498Szrj       basic_string&
188038fd1498Szrj       replace(size_type __pos, size_type __n, const basic_string& __str)
188138fd1498Szrj       { return this->replace(__pos, __n, __str._M_data(), __str.size()); }
188238fd1498Szrj 
188338fd1498Szrj       /**
188438fd1498Szrj        *  @brief  Replace characters with value from another string.
188538fd1498Szrj        *  @param __pos1  Index of first character to replace.
188638fd1498Szrj        *  @param __n1  Number of characters to be replaced.
188738fd1498Szrj        *  @param __str  String to insert.
188838fd1498Szrj        *  @param __pos2  Index of first character of str to use.
188938fd1498Szrj        *  @param __n2  Number of characters from str to use.
189038fd1498Szrj        *  @return  Reference to this string.
189138fd1498Szrj        *  @throw  std::out_of_range  If @a __pos1 > size() or @a __pos2 >
189238fd1498Szrj        *  __str.size().
189338fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
189438fd1498Szrj        *
189538fd1498Szrj        *  Removes the characters in the range [__pos1,__pos1 + n) from this
189638fd1498Szrj        *  string.  In place, the value of @a __str is inserted.  If @a __pos is
189738fd1498Szrj        *  beyond end of string, out_of_range is thrown.  If the length of the
189838fd1498Szrj        *  result exceeds max_size(), length_error is thrown.  The value of the
189938fd1498Szrj        *  string doesn't change if an error is thrown.
190038fd1498Szrj       */
190138fd1498Szrj       basic_string&
190238fd1498Szrj       replace(size_type __pos1, size_type __n1, const basic_string& __str,
1903*58e805e6Szrj 	      size_type __pos2, size_type __n2 = npos)
190438fd1498Szrj       { return this->replace(__pos1, __n1, __str._M_data()
190538fd1498Szrj 			     + __str._M_check(__pos2, "basic_string::replace"),
190638fd1498Szrj 			     __str._M_limit(__pos2, __n2)); }
190738fd1498Szrj 
190838fd1498Szrj       /**
190938fd1498Szrj        *  @brief  Replace characters with value of a C substring.
191038fd1498Szrj        *  @param __pos  Index of first character to replace.
191138fd1498Szrj        *  @param __n1  Number of characters to be replaced.
191238fd1498Szrj        *  @param __s  C string to insert.
191338fd1498Szrj        *  @param __n2  Number of characters from @a s to use.
191438fd1498Szrj        *  @return  Reference to this string.
191538fd1498Szrj        *  @throw  std::out_of_range  If @a pos1 > size().
191638fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
191738fd1498Szrj        *
191838fd1498Szrj        *  Removes the characters in the range [__pos,__pos + __n1)
191938fd1498Szrj        *  from this string.  In place, the first @a __n2 characters of
192038fd1498Szrj        *  @a __s are inserted, or all of @a __s if @a __n2 is too large.  If
192138fd1498Szrj        *  @a __pos is beyond end of string, out_of_range is thrown.  If
192238fd1498Szrj        *  the length of result exceeds max_size(), length_error is
192338fd1498Szrj        *  thrown.  The value of the string doesn't change if an error
192438fd1498Szrj        *  is thrown.
192538fd1498Szrj       */
192638fd1498Szrj       basic_string&
192738fd1498Szrj       replace(size_type __pos, size_type __n1, const _CharT* __s,
192838fd1498Szrj 	      size_type __n2)
192938fd1498Szrj       {
193038fd1498Szrj 	__glibcxx_requires_string_len(__s, __n2);
193138fd1498Szrj 	return _M_replace(_M_check(__pos, "basic_string::replace"),
193238fd1498Szrj 			  _M_limit(__pos, __n1), __s, __n2);
193338fd1498Szrj       }
193438fd1498Szrj 
193538fd1498Szrj       /**
193638fd1498Szrj        *  @brief  Replace characters with value of a C string.
193738fd1498Szrj        *  @param __pos  Index of first character to replace.
193838fd1498Szrj        *  @param __n1  Number of characters to be replaced.
193938fd1498Szrj        *  @param __s  C string to insert.
194038fd1498Szrj        *  @return  Reference to this string.
194138fd1498Szrj        *  @throw  std::out_of_range  If @a pos > size().
194238fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
194338fd1498Szrj        *
194438fd1498Szrj        *  Removes the characters in the range [__pos,__pos + __n1)
194538fd1498Szrj        *  from this string.  In place, the characters of @a __s are
194638fd1498Szrj        *  inserted.  If @a __pos is beyond end of string, out_of_range
194738fd1498Szrj        *  is thrown.  If the length of result exceeds max_size(),
194838fd1498Szrj        *  length_error is thrown.  The value of the string doesn't
194938fd1498Szrj        *  change if an error is thrown.
195038fd1498Szrj       */
195138fd1498Szrj       basic_string&
195238fd1498Szrj       replace(size_type __pos, size_type __n1, const _CharT* __s)
195338fd1498Szrj       {
195438fd1498Szrj 	__glibcxx_requires_string(__s);
195538fd1498Szrj 	return this->replace(__pos, __n1, __s, traits_type::length(__s));
195638fd1498Szrj       }
195738fd1498Szrj 
195838fd1498Szrj       /**
195938fd1498Szrj        *  @brief  Replace characters with multiple characters.
196038fd1498Szrj        *  @param __pos  Index of first character to replace.
196138fd1498Szrj        *  @param __n1  Number of characters to be replaced.
196238fd1498Szrj        *  @param __n2  Number of characters to insert.
196338fd1498Szrj        *  @param __c  Character to insert.
196438fd1498Szrj        *  @return  Reference to this string.
196538fd1498Szrj        *  @throw  std::out_of_range  If @a __pos > size().
196638fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
196738fd1498Szrj        *
196838fd1498Szrj        *  Removes the characters in the range [pos,pos + n1) from this
196938fd1498Szrj        *  string.  In place, @a __n2 copies of @a __c are inserted.
197038fd1498Szrj        *  If @a __pos is beyond end of string, out_of_range is thrown.
197138fd1498Szrj        *  If the length of result exceeds max_size(), length_error is
197238fd1498Szrj        *  thrown.  The value of the string doesn't change if an error
197338fd1498Szrj        *  is thrown.
197438fd1498Szrj       */
197538fd1498Szrj       basic_string&
197638fd1498Szrj       replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
197738fd1498Szrj       { return _M_replace_aux(_M_check(__pos, "basic_string::replace"),
197838fd1498Szrj 			      _M_limit(__pos, __n1), __n2, __c); }
197938fd1498Szrj 
198038fd1498Szrj       /**
198138fd1498Szrj        *  @brief  Replace range of characters with string.
198238fd1498Szrj        *  @param __i1  Iterator referencing start of range to replace.
198338fd1498Szrj        *  @param __i2  Iterator referencing end of range to replace.
198438fd1498Szrj        *  @param __str  String value to insert.
198538fd1498Szrj        *  @return  Reference to this string.
198638fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
198738fd1498Szrj        *
198838fd1498Szrj        *  Removes the characters in the range [__i1,__i2).  In place,
198938fd1498Szrj        *  the value of @a __str is inserted.  If the length of result
199038fd1498Szrj        *  exceeds max_size(), length_error is thrown.  The value of
199138fd1498Szrj        *  the string doesn't change if an error is thrown.
199238fd1498Szrj       */
199338fd1498Szrj       basic_string&
199438fd1498Szrj       replace(__const_iterator __i1, __const_iterator __i2,
199538fd1498Szrj 	      const basic_string& __str)
199638fd1498Szrj       { return this->replace(__i1, __i2, __str._M_data(), __str.size()); }
199738fd1498Szrj 
199838fd1498Szrj       /**
199938fd1498Szrj        *  @brief  Replace range of characters with C substring.
200038fd1498Szrj        *  @param __i1  Iterator referencing start of range to replace.
200138fd1498Szrj        *  @param __i2  Iterator referencing end of range to replace.
200238fd1498Szrj        *  @param __s  C string value to insert.
200338fd1498Szrj        *  @param __n  Number of characters from s to insert.
200438fd1498Szrj        *  @return  Reference to this string.
200538fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
200638fd1498Szrj        *
200738fd1498Szrj        *  Removes the characters in the range [__i1,__i2).  In place,
200838fd1498Szrj        *  the first @a __n characters of @a __s are inserted.  If the
200938fd1498Szrj        *  length of result exceeds max_size(), length_error is thrown.
201038fd1498Szrj        *  The value of the string doesn't change if an error is
201138fd1498Szrj        *  thrown.
201238fd1498Szrj       */
201338fd1498Szrj       basic_string&
201438fd1498Szrj       replace(__const_iterator __i1, __const_iterator __i2,
201538fd1498Szrj 	      const _CharT* __s, size_type __n)
201638fd1498Szrj       {
201738fd1498Szrj 	_GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
201838fd1498Szrj 				 && __i2 <= end());
201938fd1498Szrj 	return this->replace(__i1 - begin(), __i2 - __i1, __s, __n);
202038fd1498Szrj       }
202138fd1498Szrj 
202238fd1498Szrj       /**
202338fd1498Szrj        *  @brief  Replace range of characters with C string.
202438fd1498Szrj        *  @param __i1  Iterator referencing start of range to replace.
202538fd1498Szrj        *  @param __i2  Iterator referencing end of range to replace.
202638fd1498Szrj        *  @param __s  C string value to insert.
202738fd1498Szrj        *  @return  Reference to this string.
202838fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
202938fd1498Szrj        *
203038fd1498Szrj        *  Removes the characters in the range [__i1,__i2).  In place,
203138fd1498Szrj        *  the characters of @a __s are inserted.  If the length of
203238fd1498Szrj        *  result exceeds max_size(), length_error is thrown.  The
203338fd1498Szrj        *  value of the string doesn't change if an error is thrown.
203438fd1498Szrj       */
203538fd1498Szrj       basic_string&
203638fd1498Szrj       replace(__const_iterator __i1, __const_iterator __i2, const _CharT* __s)
203738fd1498Szrj       {
203838fd1498Szrj 	__glibcxx_requires_string(__s);
203938fd1498Szrj 	return this->replace(__i1, __i2, __s, traits_type::length(__s));
204038fd1498Szrj       }
204138fd1498Szrj 
204238fd1498Szrj       /**
204338fd1498Szrj        *  @brief  Replace range of characters with multiple characters
204438fd1498Szrj        *  @param __i1  Iterator referencing start of range to replace.
204538fd1498Szrj        *  @param __i2  Iterator referencing end of range to replace.
204638fd1498Szrj        *  @param __n  Number of characters to insert.
204738fd1498Szrj        *  @param __c  Character to insert.
204838fd1498Szrj        *  @return  Reference to this string.
204938fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
205038fd1498Szrj        *
205138fd1498Szrj        *  Removes the characters in the range [__i1,__i2).  In place,
205238fd1498Szrj        *  @a __n copies of @a __c are inserted.  If the length of
205338fd1498Szrj        *  result exceeds max_size(), length_error is thrown.  The
205438fd1498Szrj        *  value of the string doesn't change if an error is thrown.
205538fd1498Szrj       */
205638fd1498Szrj       basic_string&
205738fd1498Szrj       replace(__const_iterator __i1, __const_iterator __i2, size_type __n,
205838fd1498Szrj 	      _CharT __c)
205938fd1498Szrj       {
206038fd1498Szrj 	_GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
206138fd1498Szrj 				 && __i2 <= end());
206238fd1498Szrj 	return _M_replace_aux(__i1 - begin(), __i2 - __i1, __n, __c);
206338fd1498Szrj       }
206438fd1498Szrj 
206538fd1498Szrj       /**
206638fd1498Szrj        *  @brief  Replace range of characters with range.
206738fd1498Szrj        *  @param __i1  Iterator referencing start of range to replace.
206838fd1498Szrj        *  @param __i2  Iterator referencing end of range to replace.
206938fd1498Szrj        *  @param __k1  Iterator referencing start of range to insert.
207038fd1498Szrj        *  @param __k2  Iterator referencing end of range to insert.
207138fd1498Szrj        *  @return  Reference to this string.
207238fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
207338fd1498Szrj        *
207438fd1498Szrj        *  Removes the characters in the range [__i1,__i2).  In place,
207538fd1498Szrj        *  characters in the range [__k1,__k2) are inserted.  If the
207638fd1498Szrj        *  length of result exceeds max_size(), length_error is thrown.
207738fd1498Szrj        *  The value of the string doesn't change if an error is
207838fd1498Szrj        *  thrown.
207938fd1498Szrj       */
208038fd1498Szrj #if __cplusplus >= 201103L
208138fd1498Szrj       template<class _InputIterator,
208238fd1498Szrj 	       typename = std::_RequireInputIter<_InputIterator>>
208338fd1498Szrj         basic_string&
208438fd1498Szrj         replace(const_iterator __i1, const_iterator __i2,
208538fd1498Szrj 		_InputIterator __k1, _InputIterator __k2)
208638fd1498Szrj         {
208738fd1498Szrj 	  _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
208838fd1498Szrj 				   && __i2 <= end());
208938fd1498Szrj 	  __glibcxx_requires_valid_range(__k1, __k2);
209038fd1498Szrj 	  return this->_M_replace_dispatch(__i1, __i2, __k1, __k2,
209138fd1498Szrj 					   std::__false_type());
209238fd1498Szrj 	}
209338fd1498Szrj #else
209438fd1498Szrj       template<class _InputIterator>
209538fd1498Szrj #ifdef _GLIBCXX_DISAMBIGUATE_REPLACE_INST
209638fd1498Szrj         typename __enable_if_not_native_iterator<_InputIterator>::__type
209738fd1498Szrj #else
209838fd1498Szrj         basic_string&
209938fd1498Szrj #endif
210038fd1498Szrj         replace(iterator __i1, iterator __i2,
210138fd1498Szrj 		_InputIterator __k1, _InputIterator __k2)
210238fd1498Szrj         {
210338fd1498Szrj 	  _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
210438fd1498Szrj 				   && __i2 <= end());
210538fd1498Szrj 	  __glibcxx_requires_valid_range(__k1, __k2);
210638fd1498Szrj 	  typedef typename std::__is_integer<_InputIterator>::__type _Integral;
210738fd1498Szrj 	  return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral());
210838fd1498Szrj 	}
210938fd1498Szrj #endif
211038fd1498Szrj 
211138fd1498Szrj       // Specializations for the common case of pointer and iterator:
211238fd1498Szrj       // useful to avoid the overhead of temporary buffering in _M_replace.
211338fd1498Szrj       basic_string&
211438fd1498Szrj       replace(__const_iterator __i1, __const_iterator __i2,
211538fd1498Szrj 	      _CharT* __k1, _CharT* __k2)
211638fd1498Szrj       {
211738fd1498Szrj 	_GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
211838fd1498Szrj 				 && __i2 <= end());
211938fd1498Szrj 	__glibcxx_requires_valid_range(__k1, __k2);
212038fd1498Szrj 	return this->replace(__i1 - begin(), __i2 - __i1,
212138fd1498Szrj 			     __k1, __k2 - __k1);
212238fd1498Szrj       }
212338fd1498Szrj 
212438fd1498Szrj       basic_string&
212538fd1498Szrj       replace(__const_iterator __i1, __const_iterator __i2,
212638fd1498Szrj 	      const _CharT* __k1, const _CharT* __k2)
212738fd1498Szrj       {
212838fd1498Szrj 	_GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
212938fd1498Szrj 				 && __i2 <= end());
213038fd1498Szrj 	__glibcxx_requires_valid_range(__k1, __k2);
213138fd1498Szrj 	return this->replace(__i1 - begin(), __i2 - __i1,
213238fd1498Szrj 			     __k1, __k2 - __k1);
213338fd1498Szrj       }
213438fd1498Szrj 
213538fd1498Szrj       basic_string&
213638fd1498Szrj       replace(__const_iterator __i1, __const_iterator __i2,
213738fd1498Szrj 	      iterator __k1, iterator __k2)
213838fd1498Szrj       {
213938fd1498Szrj 	_GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
214038fd1498Szrj 				 && __i2 <= end());
214138fd1498Szrj 	__glibcxx_requires_valid_range(__k1, __k2);
214238fd1498Szrj 	return this->replace(__i1 - begin(), __i2 - __i1,
214338fd1498Szrj 			     __k1.base(), __k2 - __k1);
214438fd1498Szrj       }
214538fd1498Szrj 
214638fd1498Szrj       basic_string&
214738fd1498Szrj       replace(__const_iterator __i1, __const_iterator __i2,
214838fd1498Szrj 	      const_iterator __k1, const_iterator __k2)
214938fd1498Szrj       {
215038fd1498Szrj 	_GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
215138fd1498Szrj 				 && __i2 <= end());
215238fd1498Szrj 	__glibcxx_requires_valid_range(__k1, __k2);
215338fd1498Szrj 	return this->replace(__i1 - begin(), __i2 - __i1,
215438fd1498Szrj 			     __k1.base(), __k2 - __k1);
215538fd1498Szrj       }
215638fd1498Szrj 
215738fd1498Szrj #if __cplusplus >= 201103L
215838fd1498Szrj       /**
215938fd1498Szrj        *  @brief  Replace range of characters with initializer_list.
216038fd1498Szrj        *  @param __i1  Iterator referencing start of range to replace.
216138fd1498Szrj        *  @param __i2  Iterator referencing end of range to replace.
216238fd1498Szrj        *  @param __l  The initializer_list of characters to insert.
216338fd1498Szrj        *  @return  Reference to this string.
216438fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
216538fd1498Szrj        *
216638fd1498Szrj        *  Removes the characters in the range [__i1,__i2).  In place,
216738fd1498Szrj        *  characters in the range [__k1,__k2) are inserted.  If the
216838fd1498Szrj        *  length of result exceeds max_size(), length_error is thrown.
216938fd1498Szrj        *  The value of the string doesn't change if an error is
217038fd1498Szrj        *  thrown.
217138fd1498Szrj       */
217238fd1498Szrj       basic_string& replace(const_iterator __i1, const_iterator __i2,
217338fd1498Szrj 			    initializer_list<_CharT> __l)
217438fd1498Szrj       { return this->replace(__i1, __i2, __l.begin(), __l.size()); }
217538fd1498Szrj #endif // C++11
217638fd1498Szrj 
217738fd1498Szrj #if __cplusplus > 201402L
217838fd1498Szrj       /**
217938fd1498Szrj        *  @brief  Replace range of characters with string_view.
218038fd1498Szrj        *  @param __pos  The position to replace at.
218138fd1498Szrj        *  @param __n    The number of characters to replace.
218238fd1498Szrj        *  @param __svt  The object convertible to string_view to insert.
218338fd1498Szrj        *  @return  Reference to this string.
218438fd1498Szrj       */
218538fd1498Szrj       template<typename _Tp>
218638fd1498Szrj 	_If_sv<_Tp, basic_string&>
218738fd1498Szrj 	replace(size_type __pos, size_type __n, const _Tp& __svt)
218838fd1498Szrj 	{
218938fd1498Szrj 	  __sv_type __sv = __svt;
219038fd1498Szrj 	  return this->replace(__pos, __n, __sv.data(), __sv.size());
219138fd1498Szrj 	}
219238fd1498Szrj 
219338fd1498Szrj       /**
219438fd1498Szrj        *  @brief  Replace range of characters with string_view.
219538fd1498Szrj        *  @param __pos1  The position to replace at.
219638fd1498Szrj        *  @param __n1    The number of characters to replace.
219738fd1498Szrj        *  @param __svt   The object convertible to string_view to insert from.
219838fd1498Szrj        *  @param __pos2  The position in the string_view to insert from.
219938fd1498Szrj        *  @param __n2    The number of characters to insert.
220038fd1498Szrj        *  @return  Reference to this string.
220138fd1498Szrj       */
220238fd1498Szrj       template<typename _Tp>
220338fd1498Szrj 	_If_sv<_Tp, basic_string&>
220438fd1498Szrj 	replace(size_type __pos1, size_type __n1, const _Tp& __svt,
220538fd1498Szrj 		size_type __pos2, size_type __n2 = npos)
220638fd1498Szrj 	{
220738fd1498Szrj 	  __sv_type __sv = __svt;
220838fd1498Szrj 	  return this->replace(__pos1, __n1, __sv.data()
220938fd1498Szrj 			       + __sv._M_check(__pos2, "basic_string::replace"),
221038fd1498Szrj 			       __sv._M_limit(__pos2, __n2));
221138fd1498Szrj 	}
221238fd1498Szrj 
221338fd1498Szrj       /**
221438fd1498Szrj        *  @brief  Replace range of characters with string_view.
221538fd1498Szrj        *  @param __i1    An iterator referencing the start position
221638fd1498Szrj           to replace at.
221738fd1498Szrj        *  @param __i2    An iterator referencing the end position
221838fd1498Szrj           for the replace.
221938fd1498Szrj        *  @param __svt   The object convertible to string_view to insert from.
222038fd1498Szrj        *  @return  Reference to this string.
222138fd1498Szrj       */
222238fd1498Szrj       template<typename _Tp>
222338fd1498Szrj 	_If_sv<_Tp, basic_string&>
222438fd1498Szrj 	replace(const_iterator __i1, const_iterator __i2, const _Tp& __svt)
222538fd1498Szrj 	{
222638fd1498Szrj 	  __sv_type __sv = __svt;
222738fd1498Szrj 	  return this->replace(__i1 - begin(), __i2 - __i1, __sv);
222838fd1498Szrj 	}
222938fd1498Szrj #endif // C++17
223038fd1498Szrj 
223138fd1498Szrj     private:
223238fd1498Szrj       template<class _Integer>
223338fd1498Szrj 	basic_string&
223438fd1498Szrj 	_M_replace_dispatch(const_iterator __i1, const_iterator __i2,
223538fd1498Szrj 			    _Integer __n, _Integer __val, __true_type)
223638fd1498Szrj         { return _M_replace_aux(__i1 - begin(), __i2 - __i1, __n, __val); }
223738fd1498Szrj 
223838fd1498Szrj       template<class _InputIterator>
223938fd1498Szrj 	basic_string&
224038fd1498Szrj 	_M_replace_dispatch(const_iterator __i1, const_iterator __i2,
224138fd1498Szrj 			    _InputIterator __k1, _InputIterator __k2,
224238fd1498Szrj 			    __false_type);
224338fd1498Szrj 
224438fd1498Szrj       basic_string&
224538fd1498Szrj       _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
224638fd1498Szrj 		     _CharT __c);
224738fd1498Szrj 
224838fd1498Szrj       basic_string&
224938fd1498Szrj       _M_replace(size_type __pos, size_type __len1, const _CharT* __s,
225038fd1498Szrj 		 const size_type __len2);
225138fd1498Szrj 
225238fd1498Szrj       basic_string&
225338fd1498Szrj       _M_append(const _CharT* __s, size_type __n);
225438fd1498Szrj 
225538fd1498Szrj     public:
225638fd1498Szrj 
225738fd1498Szrj       /**
225838fd1498Szrj        *  @brief  Copy substring into C string.
225938fd1498Szrj        *  @param __s  C string to copy value into.
226038fd1498Szrj        *  @param __n  Number of characters to copy.
226138fd1498Szrj        *  @param __pos  Index of first character to copy.
226238fd1498Szrj        *  @return  Number of characters actually copied
226338fd1498Szrj        *  @throw  std::out_of_range  If __pos > size().
226438fd1498Szrj        *
226538fd1498Szrj        *  Copies up to @a __n characters starting at @a __pos into the
226638fd1498Szrj        *  C string @a __s.  If @a __pos is %greater than size(),
226738fd1498Szrj        *  out_of_range is thrown.
226838fd1498Szrj       */
226938fd1498Szrj       size_type
227038fd1498Szrj       copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
227138fd1498Szrj 
227238fd1498Szrj       /**
227338fd1498Szrj        *  @brief  Swap contents with another string.
227438fd1498Szrj        *  @param __s  String to swap with.
227538fd1498Szrj        *
227638fd1498Szrj        *  Exchanges the contents of this string with that of @a __s in constant
227738fd1498Szrj        *  time.
227838fd1498Szrj       */
227938fd1498Szrj       void
228038fd1498Szrj       swap(basic_string& __s) _GLIBCXX_NOEXCEPT;
228138fd1498Szrj 
228238fd1498Szrj       // String operations:
228338fd1498Szrj       /**
228438fd1498Szrj        *  @brief  Return const pointer to null-terminated contents.
228538fd1498Szrj        *
228638fd1498Szrj        *  This is a handle to internal data.  Do not modify or dire things may
228738fd1498Szrj        *  happen.
228838fd1498Szrj       */
228938fd1498Szrj       const _CharT*
229038fd1498Szrj       c_str() const _GLIBCXX_NOEXCEPT
229138fd1498Szrj       { return _M_data(); }
229238fd1498Szrj 
229338fd1498Szrj       /**
229438fd1498Szrj        *  @brief  Return const pointer to contents.
229538fd1498Szrj        *
229638fd1498Szrj        *  This is a pointer to internal data.  It is undefined to modify
229738fd1498Szrj        *  the contents through the returned pointer. To get a pointer that
229838fd1498Szrj        *  allows modifying the contents use @c &str[0] instead,
229938fd1498Szrj        *  (or in C++17 the non-const @c str.data() overload).
230038fd1498Szrj       */
230138fd1498Szrj       const _CharT*
230238fd1498Szrj       data() const _GLIBCXX_NOEXCEPT
230338fd1498Szrj       { return _M_data(); }
230438fd1498Szrj 
230538fd1498Szrj #if __cplusplus > 201402L
230638fd1498Szrj       /**
230738fd1498Szrj        *  @brief  Return non-const pointer to contents.
230838fd1498Szrj        *
230938fd1498Szrj        *  This is a pointer to the character sequence held by the string.
231038fd1498Szrj        *  Modifying the characters in the sequence is allowed.
231138fd1498Szrj       */
231238fd1498Szrj       _CharT*
231338fd1498Szrj       data() noexcept
231438fd1498Szrj       { return _M_data(); }
231538fd1498Szrj #endif
231638fd1498Szrj 
231738fd1498Szrj       /**
231838fd1498Szrj        *  @brief  Return copy of allocator used to construct this string.
231938fd1498Szrj       */
232038fd1498Szrj       allocator_type
232138fd1498Szrj       get_allocator() const _GLIBCXX_NOEXCEPT
232238fd1498Szrj       { return _M_get_allocator(); }
232338fd1498Szrj 
232438fd1498Szrj       /**
232538fd1498Szrj        *  @brief  Find position of a C substring.
232638fd1498Szrj        *  @param __s  C string to locate.
232738fd1498Szrj        *  @param __pos  Index of character to search from.
232838fd1498Szrj        *  @param __n  Number of characters from @a s to search for.
232938fd1498Szrj        *  @return  Index of start of first occurrence.
233038fd1498Szrj        *
233138fd1498Szrj        *  Starting from @a __pos, searches forward for the first @a
233238fd1498Szrj        *  __n characters in @a __s within this string.  If found,
233338fd1498Szrj        *  returns the index where it begins.  If not found, returns
233438fd1498Szrj        *  npos.
233538fd1498Szrj       */
233638fd1498Szrj       size_type
233738fd1498Szrj       find(const _CharT* __s, size_type __pos, size_type __n) const
233838fd1498Szrj       _GLIBCXX_NOEXCEPT;
233938fd1498Szrj 
234038fd1498Szrj       /**
234138fd1498Szrj        *  @brief  Find position of a string.
234238fd1498Szrj        *  @param __str  String to locate.
234338fd1498Szrj        *  @param __pos  Index of character to search from (default 0).
234438fd1498Szrj        *  @return  Index of start of first occurrence.
234538fd1498Szrj        *
234638fd1498Szrj        *  Starting from @a __pos, searches forward for value of @a __str within
234738fd1498Szrj        *  this string.  If found, returns the index where it begins.  If not
234838fd1498Szrj        *  found, returns npos.
234938fd1498Szrj       */
235038fd1498Szrj       size_type
235138fd1498Szrj       find(const basic_string& __str, size_type __pos = 0) const
235238fd1498Szrj       _GLIBCXX_NOEXCEPT
235338fd1498Szrj       { return this->find(__str.data(), __pos, __str.size()); }
235438fd1498Szrj 
235538fd1498Szrj #if __cplusplus > 201402L
235638fd1498Szrj       /**
235738fd1498Szrj        *  @brief  Find position of a string_view.
235838fd1498Szrj        *  @param __svt  The object convertible to string_view to locate.
235938fd1498Szrj        *  @param __pos  Index of character to search from (default 0).
236038fd1498Szrj        *  @return  Index of start of first occurrence.
236138fd1498Szrj       */
236238fd1498Szrj       template<typename _Tp>
236338fd1498Szrj 	_If_sv<_Tp, size_type>
236438fd1498Szrj 	find(const _Tp& __svt, size_type __pos = 0) const
236538fd1498Szrj 	noexcept(is_same<_Tp, __sv_type>::value)
236638fd1498Szrj 	{
236738fd1498Szrj 	  __sv_type __sv = __svt;
236838fd1498Szrj 	  return this->find(__sv.data(), __pos, __sv.size());
236938fd1498Szrj 	}
237038fd1498Szrj #endif // C++17
237138fd1498Szrj 
237238fd1498Szrj       /**
237338fd1498Szrj        *  @brief  Find position of a C string.
237438fd1498Szrj        *  @param __s  C string to locate.
237538fd1498Szrj        *  @param __pos  Index of character to search from (default 0).
237638fd1498Szrj        *  @return  Index of start of first occurrence.
237738fd1498Szrj        *
237838fd1498Szrj        *  Starting from @a __pos, searches forward for the value of @a
237938fd1498Szrj        *  __s within this string.  If found, returns the index where
238038fd1498Szrj        *  it begins.  If not found, returns npos.
238138fd1498Szrj       */
238238fd1498Szrj       size_type
238338fd1498Szrj       find(const _CharT* __s, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
238438fd1498Szrj       {
238538fd1498Szrj 	__glibcxx_requires_string(__s);
238638fd1498Szrj 	return this->find(__s, __pos, traits_type::length(__s));
238738fd1498Szrj       }
238838fd1498Szrj 
238938fd1498Szrj       /**
239038fd1498Szrj        *  @brief  Find position of a character.
239138fd1498Szrj        *  @param __c  Character to locate.
239238fd1498Szrj        *  @param __pos  Index of character to search from (default 0).
239338fd1498Szrj        *  @return  Index of first occurrence.
239438fd1498Szrj        *
239538fd1498Szrj        *  Starting from @a __pos, searches forward for @a __c within
239638fd1498Szrj        *  this string.  If found, returns the index where it was
239738fd1498Szrj        *  found.  If not found, returns npos.
239838fd1498Szrj       */
239938fd1498Szrj       size_type
240038fd1498Szrj       find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT;
240138fd1498Szrj 
240238fd1498Szrj       /**
240338fd1498Szrj        *  @brief  Find last position of a string.
240438fd1498Szrj        *  @param __str  String to locate.
240538fd1498Szrj        *  @param __pos  Index of character to search back from (default end).
240638fd1498Szrj        *  @return  Index of start of last occurrence.
240738fd1498Szrj        *
240838fd1498Szrj        *  Starting from @a __pos, searches backward for value of @a
240938fd1498Szrj        *  __str within this string.  If found, returns the index where
241038fd1498Szrj        *  it begins.  If not found, returns npos.
241138fd1498Szrj       */
241238fd1498Szrj       size_type
241338fd1498Szrj       rfind(const basic_string& __str, size_type __pos = npos) const
241438fd1498Szrj       _GLIBCXX_NOEXCEPT
241538fd1498Szrj       { return this->rfind(__str.data(), __pos, __str.size()); }
241638fd1498Szrj 
241738fd1498Szrj #if __cplusplus > 201402L
241838fd1498Szrj       /**
241938fd1498Szrj        *  @brief  Find last position of a string_view.
242038fd1498Szrj        *  @param __svt  The object convertible to string_view to locate.
242138fd1498Szrj        *  @param __pos  Index of character to search back from (default end).
242238fd1498Szrj        *  @return  Index of start of last occurrence.
242338fd1498Szrj       */
242438fd1498Szrj       template<typename _Tp>
242538fd1498Szrj 	_If_sv<_Tp, size_type>
242638fd1498Szrj 	rfind(const _Tp& __svt, size_type __pos = npos) const
242738fd1498Szrj 	noexcept(is_same<_Tp, __sv_type>::value)
242838fd1498Szrj 	{
242938fd1498Szrj 	  __sv_type __sv = __svt;
243038fd1498Szrj 	  return this->rfind(__sv.data(), __pos, __sv.size());
243138fd1498Szrj 	}
243238fd1498Szrj #endif // C++17
243338fd1498Szrj 
243438fd1498Szrj       /**
243538fd1498Szrj        *  @brief  Find last position of a C substring.
243638fd1498Szrj        *  @param __s  C string to locate.
243738fd1498Szrj        *  @param __pos  Index of character to search back from.
243838fd1498Szrj        *  @param __n  Number of characters from s to search for.
243938fd1498Szrj        *  @return  Index of start of last occurrence.
244038fd1498Szrj        *
244138fd1498Szrj        *  Starting from @a __pos, searches backward for the first @a
244238fd1498Szrj        *  __n characters in @a __s within this string.  If found,
244338fd1498Szrj        *  returns the index where it begins.  If not found, returns
244438fd1498Szrj        *  npos.
244538fd1498Szrj       */
244638fd1498Szrj       size_type
244738fd1498Szrj       rfind(const _CharT* __s, size_type __pos, size_type __n) const
244838fd1498Szrj       _GLIBCXX_NOEXCEPT;
244938fd1498Szrj 
245038fd1498Szrj       /**
245138fd1498Szrj        *  @brief  Find last position of a C string.
245238fd1498Szrj        *  @param __s  C string to locate.
245338fd1498Szrj        *  @param __pos  Index of character to start search at (default end).
245438fd1498Szrj        *  @return  Index of start of  last occurrence.
245538fd1498Szrj        *
245638fd1498Szrj        *  Starting from @a __pos, searches backward for the value of
245738fd1498Szrj        *  @a __s within this string.  If found, returns the index
245838fd1498Szrj        *  where it begins.  If not found, returns npos.
245938fd1498Szrj       */
246038fd1498Szrj       size_type
246138fd1498Szrj       rfind(const _CharT* __s, size_type __pos = npos) const
246238fd1498Szrj       {
246338fd1498Szrj 	__glibcxx_requires_string(__s);
246438fd1498Szrj 	return this->rfind(__s, __pos, traits_type::length(__s));
246538fd1498Szrj       }
246638fd1498Szrj 
246738fd1498Szrj       /**
246838fd1498Szrj        *  @brief  Find last position of a character.
246938fd1498Szrj        *  @param __c  Character to locate.
247038fd1498Szrj        *  @param __pos  Index of character to search back from (default end).
247138fd1498Szrj        *  @return  Index of last occurrence.
247238fd1498Szrj        *
247338fd1498Szrj        *  Starting from @a __pos, searches backward for @a __c within
247438fd1498Szrj        *  this string.  If found, returns the index where it was
247538fd1498Szrj        *  found.  If not found, returns npos.
247638fd1498Szrj       */
247738fd1498Szrj       size_type
247838fd1498Szrj       rfind(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT;
247938fd1498Szrj 
248038fd1498Szrj       /**
248138fd1498Szrj        *  @brief  Find position of a character of string.
248238fd1498Szrj        *  @param __str  String containing characters to locate.
248338fd1498Szrj        *  @param __pos  Index of character to search from (default 0).
248438fd1498Szrj        *  @return  Index of first occurrence.
248538fd1498Szrj        *
248638fd1498Szrj        *  Starting from @a __pos, searches forward for one of the
248738fd1498Szrj        *  characters of @a __str within this string.  If found,
248838fd1498Szrj        *  returns the index where it was found.  If not found, returns
248938fd1498Szrj        *  npos.
249038fd1498Szrj       */
249138fd1498Szrj       size_type
249238fd1498Szrj       find_first_of(const basic_string& __str, size_type __pos = 0) const
249338fd1498Szrj       _GLIBCXX_NOEXCEPT
249438fd1498Szrj       { return this->find_first_of(__str.data(), __pos, __str.size()); }
249538fd1498Szrj 
249638fd1498Szrj #if __cplusplus > 201402L
249738fd1498Szrj       /**
249838fd1498Szrj        *  @brief  Find position of a character of a string_view.
249938fd1498Szrj        *  @param __svt  An object convertible to string_view containing
250038fd1498Szrj        *                characters to locate.
250138fd1498Szrj        *  @param __pos  Index of character to search from (default 0).
250238fd1498Szrj        *  @return  Index of first occurrence.
250338fd1498Szrj       */
250438fd1498Szrj       template<typename _Tp>
250538fd1498Szrj 	_If_sv<_Tp, size_type>
250638fd1498Szrj 	find_first_of(const _Tp& __svt, size_type __pos = 0) const
250738fd1498Szrj 	noexcept(is_same<_Tp, __sv_type>::value)
250838fd1498Szrj 	{
250938fd1498Szrj 	  __sv_type __sv = __svt;
251038fd1498Szrj 	  return this->find_first_of(__sv.data(), __pos, __sv.size());
251138fd1498Szrj 	}
251238fd1498Szrj #endif // C++17
251338fd1498Szrj 
251438fd1498Szrj       /**
251538fd1498Szrj        *  @brief  Find position of a character of C substring.
251638fd1498Szrj        *  @param __s  String containing characters to locate.
251738fd1498Szrj        *  @param __pos  Index of character to search from.
251838fd1498Szrj        *  @param __n  Number of characters from s to search for.
251938fd1498Szrj        *  @return  Index of first occurrence.
252038fd1498Szrj        *
252138fd1498Szrj        *  Starting from @a __pos, searches forward for one of the
252238fd1498Szrj        *  first @a __n characters of @a __s within this string.  If
252338fd1498Szrj        *  found, returns the index where it was found.  If not found,
252438fd1498Szrj        *  returns npos.
252538fd1498Szrj       */
252638fd1498Szrj       size_type
252738fd1498Szrj       find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
252838fd1498Szrj       _GLIBCXX_NOEXCEPT;
252938fd1498Szrj 
253038fd1498Szrj       /**
253138fd1498Szrj        *  @brief  Find position of a character of C string.
253238fd1498Szrj        *  @param __s  String containing characters to locate.
253338fd1498Szrj        *  @param __pos  Index of character to search from (default 0).
253438fd1498Szrj        *  @return  Index of first occurrence.
253538fd1498Szrj        *
253638fd1498Szrj        *  Starting from @a __pos, searches forward for one of the
253738fd1498Szrj        *  characters of @a __s within this string.  If found, returns
253838fd1498Szrj        *  the index where it was found.  If not found, returns npos.
253938fd1498Szrj       */
254038fd1498Szrj       size_type
254138fd1498Szrj       find_first_of(const _CharT* __s, size_type __pos = 0) const
254238fd1498Szrj       _GLIBCXX_NOEXCEPT
254338fd1498Szrj       {
254438fd1498Szrj 	__glibcxx_requires_string(__s);
254538fd1498Szrj 	return this->find_first_of(__s, __pos, traits_type::length(__s));
254638fd1498Szrj       }
254738fd1498Szrj 
254838fd1498Szrj       /**
254938fd1498Szrj        *  @brief  Find position of a character.
255038fd1498Szrj        *  @param __c  Character to locate.
255138fd1498Szrj        *  @param __pos  Index of character to search from (default 0).
255238fd1498Szrj        *  @return  Index of first occurrence.
255338fd1498Szrj        *
255438fd1498Szrj        *  Starting from @a __pos, searches forward for the character
255538fd1498Szrj        *  @a __c within this string.  If found, returns the index
255638fd1498Szrj        *  where it was found.  If not found, returns npos.
255738fd1498Szrj        *
255838fd1498Szrj        *  Note: equivalent to find(__c, __pos).
255938fd1498Szrj       */
256038fd1498Szrj       size_type
256138fd1498Szrj       find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
256238fd1498Szrj       { return this->find(__c, __pos); }
256338fd1498Szrj 
256438fd1498Szrj       /**
256538fd1498Szrj        *  @brief  Find last position of a character of string.
256638fd1498Szrj        *  @param __str  String containing characters to locate.
256738fd1498Szrj        *  @param __pos  Index of character to search back from (default end).
256838fd1498Szrj        *  @return  Index of last occurrence.
256938fd1498Szrj        *
257038fd1498Szrj        *  Starting from @a __pos, searches backward for one of the
257138fd1498Szrj        *  characters of @a __str within this string.  If found,
257238fd1498Szrj        *  returns the index where it was found.  If not found, returns
257338fd1498Szrj        *  npos.
257438fd1498Szrj       */
257538fd1498Szrj       size_type
257638fd1498Szrj       find_last_of(const basic_string& __str, size_type __pos = npos) const
257738fd1498Szrj       _GLIBCXX_NOEXCEPT
257838fd1498Szrj       { return this->find_last_of(__str.data(), __pos, __str.size()); }
257938fd1498Szrj 
258038fd1498Szrj #if __cplusplus > 201402L
258138fd1498Szrj       /**
258238fd1498Szrj        *  @brief  Find last position of a character of string.
258338fd1498Szrj        *  @param __svt  An object convertible to string_view containing
258438fd1498Szrj        *                characters to locate.
258538fd1498Szrj        *  @param __pos  Index of character to search back from (default end).
258638fd1498Szrj        *  @return  Index of last occurrence.
258738fd1498Szrj       */
258838fd1498Szrj       template<typename _Tp>
258938fd1498Szrj 	_If_sv<_Tp, size_type>
259038fd1498Szrj 	find_last_of(const _Tp& __svt, size_type __pos = npos) const
259138fd1498Szrj 	noexcept(is_same<_Tp, __sv_type>::value)
259238fd1498Szrj 	{
259338fd1498Szrj 	  __sv_type __sv = __svt;
259438fd1498Szrj 	  return this->find_last_of(__sv.data(), __pos, __sv.size());
259538fd1498Szrj 	}
259638fd1498Szrj #endif // C++17
259738fd1498Szrj 
259838fd1498Szrj       /**
259938fd1498Szrj        *  @brief  Find last position of a character of C substring.
260038fd1498Szrj        *  @param __s  C string containing characters to locate.
260138fd1498Szrj        *  @param __pos  Index of character to search back from.
260238fd1498Szrj        *  @param __n  Number of characters from s to search for.
260338fd1498Szrj        *  @return  Index of last occurrence.
260438fd1498Szrj        *
260538fd1498Szrj        *  Starting from @a __pos, searches backward for one of the
260638fd1498Szrj        *  first @a __n characters of @a __s within this string.  If
260738fd1498Szrj        *  found, returns the index where it was found.  If not found,
260838fd1498Szrj        *  returns npos.
260938fd1498Szrj       */
261038fd1498Szrj       size_type
261138fd1498Szrj       find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
261238fd1498Szrj       _GLIBCXX_NOEXCEPT;
261338fd1498Szrj 
261438fd1498Szrj       /**
261538fd1498Szrj        *  @brief  Find last position of a character of C string.
261638fd1498Szrj        *  @param __s  C string containing characters to locate.
261738fd1498Szrj        *  @param __pos  Index of character to search back from (default end).
261838fd1498Szrj        *  @return  Index of last occurrence.
261938fd1498Szrj        *
262038fd1498Szrj        *  Starting from @a __pos, searches backward for one of the
262138fd1498Szrj        *  characters of @a __s within this string.  If found, returns
262238fd1498Szrj        *  the index where it was found.  If not found, returns npos.
262338fd1498Szrj       */
262438fd1498Szrj       size_type
262538fd1498Szrj       find_last_of(const _CharT* __s, size_type __pos = npos) const
262638fd1498Szrj       _GLIBCXX_NOEXCEPT
262738fd1498Szrj       {
262838fd1498Szrj 	__glibcxx_requires_string(__s);
262938fd1498Szrj 	return this->find_last_of(__s, __pos, traits_type::length(__s));
263038fd1498Szrj       }
263138fd1498Szrj 
263238fd1498Szrj       /**
263338fd1498Szrj        *  @brief  Find last position of a character.
263438fd1498Szrj        *  @param __c  Character to locate.
263538fd1498Szrj        *  @param __pos  Index of character to search back from (default end).
263638fd1498Szrj        *  @return  Index of last occurrence.
263738fd1498Szrj        *
263838fd1498Szrj        *  Starting from @a __pos, searches backward for @a __c within
263938fd1498Szrj        *  this string.  If found, returns the index where it was
264038fd1498Szrj        *  found.  If not found, returns npos.
264138fd1498Szrj        *
264238fd1498Szrj        *  Note: equivalent to rfind(__c, __pos).
264338fd1498Szrj       */
264438fd1498Szrj       size_type
264538fd1498Szrj       find_last_of(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT
264638fd1498Szrj       { return this->rfind(__c, __pos); }
264738fd1498Szrj 
264838fd1498Szrj       /**
264938fd1498Szrj        *  @brief  Find position of a character not in string.
265038fd1498Szrj        *  @param __str  String containing characters to avoid.
265138fd1498Szrj        *  @param __pos  Index of character to search from (default 0).
265238fd1498Szrj        *  @return  Index of first occurrence.
265338fd1498Szrj        *
265438fd1498Szrj        *  Starting from @a __pos, searches forward for a character not contained
265538fd1498Szrj        *  in @a __str within this string.  If found, returns the index where it
265638fd1498Szrj        *  was found.  If not found, returns npos.
265738fd1498Szrj       */
265838fd1498Szrj       size_type
265938fd1498Szrj       find_first_not_of(const basic_string& __str, size_type __pos = 0) const
266038fd1498Szrj       _GLIBCXX_NOEXCEPT
266138fd1498Szrj       { return this->find_first_not_of(__str.data(), __pos, __str.size()); }
266238fd1498Szrj 
266338fd1498Szrj #if __cplusplus > 201402L
266438fd1498Szrj       /**
266538fd1498Szrj        *  @brief  Find position of a character not in a string_view.
266638fd1498Szrj        *  @param __svt  A object convertible to string_view containing
266738fd1498Szrj        *                characters to avoid.
266838fd1498Szrj        *  @param __pos  Index of character to search from (default 0).
266938fd1498Szrj        *  @return  Index of first occurrence.
267038fd1498Szrj        */
267138fd1498Szrj       template<typename _Tp>
267238fd1498Szrj 	_If_sv<_Tp, size_type>
267338fd1498Szrj 	find_first_not_of(const _Tp& __svt, size_type __pos = 0) const
267438fd1498Szrj 	noexcept(is_same<_Tp, __sv_type>::value)
267538fd1498Szrj 	{
267638fd1498Szrj 	  __sv_type __sv = __svt;
267738fd1498Szrj 	  return this->find_first_not_of(__sv.data(), __pos, __sv.size());
267838fd1498Szrj 	}
267938fd1498Szrj #endif // C++17
268038fd1498Szrj 
268138fd1498Szrj       /**
268238fd1498Szrj        *  @brief  Find position of a character not in C substring.
268338fd1498Szrj        *  @param __s  C string containing characters to avoid.
268438fd1498Szrj        *  @param __pos  Index of character to search from.
268538fd1498Szrj        *  @param __n  Number of characters from __s to consider.
268638fd1498Szrj        *  @return  Index of first occurrence.
268738fd1498Szrj        *
268838fd1498Szrj        *  Starting from @a __pos, searches forward for a character not
268938fd1498Szrj        *  contained in the first @a __n characters of @a __s within
269038fd1498Szrj        *  this string.  If found, returns the index where it was
269138fd1498Szrj        *  found.  If not found, returns npos.
269238fd1498Szrj       */
269338fd1498Szrj       size_type
269438fd1498Szrj       find_first_not_of(const _CharT* __s, size_type __pos,
269538fd1498Szrj 			size_type __n) const _GLIBCXX_NOEXCEPT;
269638fd1498Szrj 
269738fd1498Szrj       /**
269838fd1498Szrj        *  @brief  Find position of a character not in C string.
269938fd1498Szrj        *  @param __s  C string containing characters to avoid.
270038fd1498Szrj        *  @param __pos  Index of character to search from (default 0).
270138fd1498Szrj        *  @return  Index of first occurrence.
270238fd1498Szrj        *
270338fd1498Szrj        *  Starting from @a __pos, searches forward for a character not
270438fd1498Szrj        *  contained in @a __s within this string.  If found, returns
270538fd1498Szrj        *  the index where it was found.  If not found, returns npos.
270638fd1498Szrj       */
270738fd1498Szrj       size_type
270838fd1498Szrj       find_first_not_of(const _CharT* __s, size_type __pos = 0) const
270938fd1498Szrj       _GLIBCXX_NOEXCEPT
271038fd1498Szrj       {
271138fd1498Szrj 	__glibcxx_requires_string(__s);
271238fd1498Szrj 	return this->find_first_not_of(__s, __pos, traits_type::length(__s));
271338fd1498Szrj       }
271438fd1498Szrj 
271538fd1498Szrj       /**
271638fd1498Szrj        *  @brief  Find position of a different character.
271738fd1498Szrj        *  @param __c  Character to avoid.
271838fd1498Szrj        *  @param __pos  Index of character to search from (default 0).
271938fd1498Szrj        *  @return  Index of first occurrence.
272038fd1498Szrj        *
272138fd1498Szrj        *  Starting from @a __pos, searches forward for a character
272238fd1498Szrj        *  other than @a __c within this string.  If found, returns the
272338fd1498Szrj        *  index where it was found.  If not found, returns npos.
272438fd1498Szrj       */
272538fd1498Szrj       size_type
272638fd1498Szrj       find_first_not_of(_CharT __c, size_type __pos = 0) const
272738fd1498Szrj       _GLIBCXX_NOEXCEPT;
272838fd1498Szrj 
272938fd1498Szrj       /**
273038fd1498Szrj        *  @brief  Find last position of a character not in string.
273138fd1498Szrj        *  @param __str  String containing characters to avoid.
273238fd1498Szrj        *  @param __pos  Index of character to search back from (default end).
273338fd1498Szrj        *  @return  Index of last occurrence.
273438fd1498Szrj        *
273538fd1498Szrj        *  Starting from @a __pos, searches backward for a character
273638fd1498Szrj        *  not contained in @a __str within this string.  If found,
273738fd1498Szrj        *  returns the index where it was found.  If not found, returns
273838fd1498Szrj        *  npos.
273938fd1498Szrj       */
274038fd1498Szrj       size_type
274138fd1498Szrj       find_last_not_of(const basic_string& __str, size_type __pos = npos) const
274238fd1498Szrj       _GLIBCXX_NOEXCEPT
274338fd1498Szrj       { return this->find_last_not_of(__str.data(), __pos, __str.size()); }
274438fd1498Szrj 
274538fd1498Szrj #if __cplusplus > 201402L
274638fd1498Szrj       /**
274738fd1498Szrj        *  @brief  Find last position of a character not in a string_view.
274838fd1498Szrj        *  @param __svt  An object convertible to string_view containing
274938fd1498Szrj        *                characters to avoid.
275038fd1498Szrj        *  @param __pos  Index of character to search back from (default end).
275138fd1498Szrj        *  @return  Index of last occurrence.
275238fd1498Szrj        */
275338fd1498Szrj       template<typename _Tp>
275438fd1498Szrj 	_If_sv<_Tp, size_type>
275538fd1498Szrj 	find_last_not_of(const _Tp& __svt, size_type __pos = npos) const
275638fd1498Szrj 	noexcept(is_same<_Tp, __sv_type>::value)
275738fd1498Szrj 	{
275838fd1498Szrj 	  __sv_type __sv = __svt;
275938fd1498Szrj 	  return this->find_last_not_of(__sv.data(), __pos, __sv.size());
276038fd1498Szrj 	}
276138fd1498Szrj #endif // C++17
276238fd1498Szrj 
276338fd1498Szrj       /**
276438fd1498Szrj        *  @brief  Find last position of a character not in C substring.
276538fd1498Szrj        *  @param __s  C string containing characters to avoid.
276638fd1498Szrj        *  @param __pos  Index of character to search back from.
276738fd1498Szrj        *  @param __n  Number of characters from s to consider.
276838fd1498Szrj        *  @return  Index of last occurrence.
276938fd1498Szrj        *
277038fd1498Szrj        *  Starting from @a __pos, searches backward for a character not
277138fd1498Szrj        *  contained in the first @a __n characters of @a __s within this string.
277238fd1498Szrj        *  If found, returns the index where it was found.  If not found,
277338fd1498Szrj        *  returns npos.
277438fd1498Szrj       */
277538fd1498Szrj       size_type
277638fd1498Szrj       find_last_not_of(const _CharT* __s, size_type __pos,
277738fd1498Szrj 		       size_type __n) const _GLIBCXX_NOEXCEPT;
277838fd1498Szrj       /**
277938fd1498Szrj        *  @brief  Find last position of a character not in C string.
278038fd1498Szrj        *  @param __s  C string containing characters to avoid.
278138fd1498Szrj        *  @param __pos  Index of character to search back from (default end).
278238fd1498Szrj        *  @return  Index of last occurrence.
278338fd1498Szrj        *
278438fd1498Szrj        *  Starting from @a __pos, searches backward for a character
278538fd1498Szrj        *  not contained in @a __s within this string.  If found,
278638fd1498Szrj        *  returns the index where it was found.  If not found, returns
278738fd1498Szrj        *  npos.
278838fd1498Szrj       */
278938fd1498Szrj       size_type
279038fd1498Szrj       find_last_not_of(const _CharT* __s, size_type __pos = npos) const
279138fd1498Szrj       _GLIBCXX_NOEXCEPT
279238fd1498Szrj       {
279338fd1498Szrj 	__glibcxx_requires_string(__s);
279438fd1498Szrj 	return this->find_last_not_of(__s, __pos, traits_type::length(__s));
279538fd1498Szrj       }
279638fd1498Szrj 
279738fd1498Szrj       /**
279838fd1498Szrj        *  @brief  Find last position of a different character.
279938fd1498Szrj        *  @param __c  Character to avoid.
280038fd1498Szrj        *  @param __pos  Index of character to search back from (default end).
280138fd1498Szrj        *  @return  Index of last occurrence.
280238fd1498Szrj        *
280338fd1498Szrj        *  Starting from @a __pos, searches backward for a character other than
280438fd1498Szrj        *  @a __c within this string.  If found, returns the index where it was
280538fd1498Szrj        *  found.  If not found, returns npos.
280638fd1498Szrj       */
280738fd1498Szrj       size_type
280838fd1498Szrj       find_last_not_of(_CharT __c, size_type __pos = npos) const
280938fd1498Szrj       _GLIBCXX_NOEXCEPT;
281038fd1498Szrj 
281138fd1498Szrj       /**
281238fd1498Szrj        *  @brief  Get a substring.
281338fd1498Szrj        *  @param __pos  Index of first character (default 0).
281438fd1498Szrj        *  @param __n  Number of characters in substring (default remainder).
281538fd1498Szrj        *  @return  The new string.
281638fd1498Szrj        *  @throw  std::out_of_range  If __pos > size().
281738fd1498Szrj        *
281838fd1498Szrj        *  Construct and return a new string using the @a __n
281938fd1498Szrj        *  characters starting at @a __pos.  If the string is too
282038fd1498Szrj        *  short, use the remainder of the characters.  If @a __pos is
282138fd1498Szrj        *  beyond the end of the string, out_of_range is thrown.
282238fd1498Szrj       */
282338fd1498Szrj       basic_string
282438fd1498Szrj       substr(size_type __pos = 0, size_type __n = npos) const
282538fd1498Szrj       { return basic_string(*this,
282638fd1498Szrj 			    _M_check(__pos, "basic_string::substr"), __n); }
282738fd1498Szrj 
282838fd1498Szrj       /**
282938fd1498Szrj        *  @brief  Compare to a string.
283038fd1498Szrj        *  @param __str  String to compare against.
283138fd1498Szrj        *  @return  Integer < 0, 0, or > 0.
283238fd1498Szrj        *
283338fd1498Szrj        *  Returns an integer < 0 if this string is ordered before @a
283438fd1498Szrj        *  __str, 0 if their values are equivalent, or > 0 if this
283538fd1498Szrj        *  string is ordered after @a __str.  Determines the effective
283638fd1498Szrj        *  length rlen of the strings to compare as the smallest of
283738fd1498Szrj        *  size() and str.size().  The function then compares the two
283838fd1498Szrj        *  strings by calling traits::compare(data(), str.data(),rlen).
283938fd1498Szrj        *  If the result of the comparison is nonzero returns it,
284038fd1498Szrj        *  otherwise the shorter one is ordered first.
284138fd1498Szrj       */
284238fd1498Szrj       int
284338fd1498Szrj       compare(const basic_string& __str) const
284438fd1498Szrj       {
284538fd1498Szrj 	const size_type __size = this->size();
284638fd1498Szrj 	const size_type __osize = __str.size();
284738fd1498Szrj 	const size_type __len = std::min(__size, __osize);
284838fd1498Szrj 
284938fd1498Szrj 	int __r = traits_type::compare(_M_data(), __str.data(), __len);
285038fd1498Szrj 	if (!__r)
285138fd1498Szrj 	  __r = _S_compare(__size, __osize);
285238fd1498Szrj 	return __r;
285338fd1498Szrj       }
285438fd1498Szrj 
285538fd1498Szrj #if __cplusplus > 201402L
285638fd1498Szrj       /**
285738fd1498Szrj        *  @brief  Compare to a string_view.
285838fd1498Szrj        *  @param __svt An object convertible to string_view to compare against.
285938fd1498Szrj        *  @return  Integer < 0, 0, or > 0.
286038fd1498Szrj        */
286138fd1498Szrj       template<typename _Tp>
286238fd1498Szrj 	_If_sv<_Tp, int>
286338fd1498Szrj 	compare(const _Tp& __svt) const
286438fd1498Szrj 	noexcept(is_same<_Tp, __sv_type>::value)
286538fd1498Szrj 	{
286638fd1498Szrj 	  __sv_type __sv = __svt;
286738fd1498Szrj 	  const size_type __size = this->size();
286838fd1498Szrj 	  const size_type __osize = __sv.size();
286938fd1498Szrj 	  const size_type __len = std::min(__size, __osize);
287038fd1498Szrj 
287138fd1498Szrj 	  int __r = traits_type::compare(_M_data(), __sv.data(), __len);
287238fd1498Szrj 	  if (!__r)
287338fd1498Szrj 	    __r = _S_compare(__size, __osize);
287438fd1498Szrj 	  return __r;
287538fd1498Szrj 	}
287638fd1498Szrj 
287738fd1498Szrj       /**
287838fd1498Szrj        *  @brief  Compare to a string_view.
287938fd1498Szrj        *  @param __pos  A position in the string to start comparing from.
288038fd1498Szrj        *  @param __n  The number of characters to compare.
288138fd1498Szrj        *  @param __svt  An object convertible to string_view to compare
288238fd1498Szrj        *                against.
288338fd1498Szrj        *  @return  Integer < 0, 0, or > 0.
288438fd1498Szrj        */
288538fd1498Szrj       template<typename _Tp>
288638fd1498Szrj 	_If_sv<_Tp, int>
288738fd1498Szrj 	compare(size_type __pos, size_type __n, const _Tp& __svt) const
288838fd1498Szrj 	noexcept(is_same<_Tp, __sv_type>::value)
288938fd1498Szrj 	{
289038fd1498Szrj 	  __sv_type __sv = __svt;
289138fd1498Szrj 	  return __sv_type(*this).substr(__pos, __n).compare(__sv);
289238fd1498Szrj 	}
289338fd1498Szrj 
289438fd1498Szrj       /**
289538fd1498Szrj        *  @brief  Compare to a string_view.
289638fd1498Szrj        *  @param __pos1  A position in the string to start comparing from.
289738fd1498Szrj        *  @param __n1  The number of characters to compare.
289838fd1498Szrj        *  @param __svt  An object convertible to string_view to compare
289938fd1498Szrj        *                against.
290038fd1498Szrj        *  @param __pos2  A position in the string_view to start comparing from.
290138fd1498Szrj        *  @param __n2  The number of characters to compare.
290238fd1498Szrj        *  @return  Integer < 0, 0, or > 0.
290338fd1498Szrj        */
290438fd1498Szrj       template<typename _Tp>
290538fd1498Szrj 	_If_sv<_Tp, int>
290638fd1498Szrj 	compare(size_type __pos1, size_type __n1, const _Tp& __svt,
290738fd1498Szrj 		size_type __pos2, size_type __n2 = npos) const
290838fd1498Szrj 	noexcept(is_same<_Tp, __sv_type>::value)
290938fd1498Szrj 	{
291038fd1498Szrj 	  __sv_type __sv = __svt;
291138fd1498Szrj 	  return __sv_type(*this)
291238fd1498Szrj 	    .substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
291338fd1498Szrj 	}
291438fd1498Szrj #endif // C++17
291538fd1498Szrj 
291638fd1498Szrj       /**
291738fd1498Szrj        *  @brief  Compare substring to a string.
291838fd1498Szrj        *  @param __pos  Index of first character of substring.
291938fd1498Szrj        *  @param __n  Number of characters in substring.
292038fd1498Szrj        *  @param __str  String to compare against.
292138fd1498Szrj        *  @return  Integer < 0, 0, or > 0.
292238fd1498Szrj        *
292338fd1498Szrj        *  Form the substring of this string from the @a __n characters
292438fd1498Szrj        *  starting at @a __pos.  Returns an integer < 0 if the
292538fd1498Szrj        *  substring is ordered before @a __str, 0 if their values are
292638fd1498Szrj        *  equivalent, or > 0 if the substring is ordered after @a
292738fd1498Szrj        *  __str.  Determines the effective length rlen of the strings
292838fd1498Szrj        *  to compare as the smallest of the length of the substring
292938fd1498Szrj        *  and @a __str.size().  The function then compares the two
293038fd1498Szrj        *  strings by calling
293138fd1498Szrj        *  traits::compare(substring.data(),str.data(),rlen).  If the
293238fd1498Szrj        *  result of the comparison is nonzero returns it, otherwise
293338fd1498Szrj        *  the shorter one is ordered first.
293438fd1498Szrj       */
293538fd1498Szrj       int
293638fd1498Szrj       compare(size_type __pos, size_type __n, const basic_string& __str) const;
293738fd1498Szrj 
293838fd1498Szrj       /**
293938fd1498Szrj        *  @brief  Compare substring to a substring.
294038fd1498Szrj        *  @param __pos1  Index of first character of substring.
294138fd1498Szrj        *  @param __n1  Number of characters in substring.
294238fd1498Szrj        *  @param __str  String to compare against.
294338fd1498Szrj        *  @param __pos2  Index of first character of substring of str.
294438fd1498Szrj        *  @param __n2  Number of characters in substring of str.
294538fd1498Szrj        *  @return  Integer < 0, 0, or > 0.
294638fd1498Szrj        *
294738fd1498Szrj        *  Form the substring of this string from the @a __n1
294838fd1498Szrj        *  characters starting at @a __pos1.  Form the substring of @a
294938fd1498Szrj        *  __str from the @a __n2 characters starting at @a __pos2.
295038fd1498Szrj        *  Returns an integer < 0 if this substring is ordered before
295138fd1498Szrj        *  the substring of @a __str, 0 if their values are equivalent,
295238fd1498Szrj        *  or > 0 if this substring is ordered after the substring of
295338fd1498Szrj        *  @a __str.  Determines the effective length rlen of the
295438fd1498Szrj        *  strings to compare as the smallest of the lengths of the
295538fd1498Szrj        *  substrings.  The function then compares the two strings by
295638fd1498Szrj        *  calling
295738fd1498Szrj        *  traits::compare(substring.data(),str.substr(pos2,n2).data(),rlen).
295838fd1498Szrj        *  If the result of the comparison is nonzero returns it,
295938fd1498Szrj        *  otherwise the shorter one is ordered first.
296038fd1498Szrj       */
296138fd1498Szrj       int
296238fd1498Szrj       compare(size_type __pos1, size_type __n1, const basic_string& __str,
2963*58e805e6Szrj 	      size_type __pos2, size_type __n2 = npos) const;
296438fd1498Szrj 
296538fd1498Szrj       /**
296638fd1498Szrj        *  @brief  Compare to a C string.
296738fd1498Szrj        *  @param __s  C string to compare against.
296838fd1498Szrj        *  @return  Integer < 0, 0, or > 0.
296938fd1498Szrj        *
297038fd1498Szrj        *  Returns an integer < 0 if this string is ordered before @a __s, 0 if
297138fd1498Szrj        *  their values are equivalent, or > 0 if this string is ordered after
297238fd1498Szrj        *  @a __s.  Determines the effective length rlen of the strings to
297338fd1498Szrj        *  compare as the smallest of size() and the length of a string
297438fd1498Szrj        *  constructed from @a __s.  The function then compares the two strings
297538fd1498Szrj        *  by calling traits::compare(data(),s,rlen).  If the result of the
297638fd1498Szrj        *  comparison is nonzero returns it, otherwise the shorter one is
297738fd1498Szrj        *  ordered first.
297838fd1498Szrj       */
297938fd1498Szrj       int
298038fd1498Szrj       compare(const _CharT* __s) const _GLIBCXX_NOEXCEPT;
298138fd1498Szrj 
298238fd1498Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
298338fd1498Szrj       // 5 String::compare specification questionable
298438fd1498Szrj       /**
298538fd1498Szrj        *  @brief  Compare substring to a C string.
298638fd1498Szrj        *  @param __pos  Index of first character of substring.
298738fd1498Szrj        *  @param __n1  Number of characters in substring.
298838fd1498Szrj        *  @param __s  C string to compare against.
298938fd1498Szrj        *  @return  Integer < 0, 0, or > 0.
299038fd1498Szrj        *
299138fd1498Szrj        *  Form the substring of this string from the @a __n1
299238fd1498Szrj        *  characters starting at @a pos.  Returns an integer < 0 if
299338fd1498Szrj        *  the substring is ordered before @a __s, 0 if their values
299438fd1498Szrj        *  are equivalent, or > 0 if the substring is ordered after @a
299538fd1498Szrj        *  __s.  Determines the effective length rlen of the strings to
299638fd1498Szrj        *  compare as the smallest of the length of the substring and
299738fd1498Szrj        *  the length of a string constructed from @a __s.  The
299838fd1498Szrj        *  function then compares the two string by calling
299938fd1498Szrj        *  traits::compare(substring.data(),__s,rlen).  If the result of
300038fd1498Szrj        *  the comparison is nonzero returns it, otherwise the shorter
300138fd1498Szrj        *  one is ordered first.
300238fd1498Szrj       */
300338fd1498Szrj       int
300438fd1498Szrj       compare(size_type __pos, size_type __n1, const _CharT* __s) const;
300538fd1498Szrj 
300638fd1498Szrj       /**
300738fd1498Szrj        *  @brief  Compare substring against a character %array.
300838fd1498Szrj        *  @param __pos  Index of first character of substring.
300938fd1498Szrj        *  @param __n1  Number of characters in substring.
301038fd1498Szrj        *  @param __s  character %array to compare against.
301138fd1498Szrj        *  @param __n2  Number of characters of s.
301238fd1498Szrj        *  @return  Integer < 0, 0, or > 0.
301338fd1498Szrj        *
301438fd1498Szrj        *  Form the substring of this string from the @a __n1
301538fd1498Szrj        *  characters starting at @a __pos.  Form a string from the
301638fd1498Szrj        *  first @a __n2 characters of @a __s.  Returns an integer < 0
301738fd1498Szrj        *  if this substring is ordered before the string from @a __s,
301838fd1498Szrj        *  0 if their values are equivalent, or > 0 if this substring
301938fd1498Szrj        *  is ordered after the string from @a __s.  Determines the
302038fd1498Szrj        *  effective length rlen of the strings to compare as the
302138fd1498Szrj        *  smallest of the length of the substring and @a __n2.  The
302238fd1498Szrj        *  function then compares the two strings by calling
302338fd1498Szrj        *  traits::compare(substring.data(),s,rlen).  If the result of
302438fd1498Szrj        *  the comparison is nonzero returns it, otherwise the shorter
302538fd1498Szrj        *  one is ordered first.
302638fd1498Szrj        *
302738fd1498Szrj        *  NB: s must have at least n2 characters, &apos;\\0&apos; has
302838fd1498Szrj        *  no special meaning.
302938fd1498Szrj       */
303038fd1498Szrj       int
303138fd1498Szrj       compare(size_type __pos, size_type __n1, const _CharT* __s,
303238fd1498Szrj 	      size_type __n2) const;
303338fd1498Szrj 
303438fd1498Szrj       // Allow basic_stringbuf::__xfer_bufptrs to call _M_length:
303538fd1498Szrj       template<typename, typename, typename> friend class basic_stringbuf;
303638fd1498Szrj     };
303738fd1498Szrj _GLIBCXX_END_NAMESPACE_CXX11
303838fd1498Szrj #else  // !_GLIBCXX_USE_CXX11_ABI
303938fd1498Szrj   // Reference-counted COW string implentation
304038fd1498Szrj 
304138fd1498Szrj   /**
304238fd1498Szrj    *  @class basic_string basic_string.h <string>
304338fd1498Szrj    *  @brief  Managing sequences of characters and character-like objects.
304438fd1498Szrj    *
304538fd1498Szrj    *  @ingroup strings
304638fd1498Szrj    *  @ingroup sequences
304738fd1498Szrj    *
304838fd1498Szrj    *  @tparam _CharT  Type of character
304938fd1498Szrj    *  @tparam _Traits  Traits for character type, defaults to
305038fd1498Szrj    *                   char_traits<_CharT>.
305138fd1498Szrj    *  @tparam _Alloc  Allocator type, defaults to allocator<_CharT>.
305238fd1498Szrj    *
305338fd1498Szrj    *  Meets the requirements of a <a href="tables.html#65">container</a>, a
305438fd1498Szrj    *  <a href="tables.html#66">reversible container</a>, and a
305538fd1498Szrj    *  <a href="tables.html#67">sequence</a>.  Of the
305638fd1498Szrj    *  <a href="tables.html#68">optional sequence requirements</a>, only
305738fd1498Szrj    *  @c push_back, @c at, and @c %array access are supported.
305838fd1498Szrj    *
305938fd1498Szrj    *  @doctodo
306038fd1498Szrj    *
306138fd1498Szrj    *
306238fd1498Szrj    *  Documentation?  What's that?
306338fd1498Szrj    *  Nathan Myers <ncm@cantrip.org>.
306438fd1498Szrj    *
306538fd1498Szrj    *  A string looks like this:
306638fd1498Szrj    *
306738fd1498Szrj    *  @code
306838fd1498Szrj    *                                        [_Rep]
306938fd1498Szrj    *                                        _M_length
307038fd1498Szrj    *   [basic_string<char_type>]            _M_capacity
307138fd1498Szrj    *   _M_dataplus                          _M_refcount
307238fd1498Szrj    *   _M_p ---------------->               unnamed array of char_type
307338fd1498Szrj    *  @endcode
307438fd1498Szrj    *
307538fd1498Szrj    *  Where the _M_p points to the first character in the string, and
307638fd1498Szrj    *  you cast it to a pointer-to-_Rep and subtract 1 to get a
307738fd1498Szrj    *  pointer to the header.
307838fd1498Szrj    *
307938fd1498Szrj    *  This approach has the enormous advantage that a string object
308038fd1498Szrj    *  requires only one allocation.  All the ugliness is confined
308138fd1498Szrj    *  within a single %pair of inline functions, which each compile to
308238fd1498Szrj    *  a single @a add instruction: _Rep::_M_data(), and
308338fd1498Szrj    *  string::_M_rep(); and the allocation function which gets a
308438fd1498Szrj    *  block of raw bytes and with room enough and constructs a _Rep
308538fd1498Szrj    *  object at the front.
308638fd1498Szrj    *
308738fd1498Szrj    *  The reason you want _M_data pointing to the character %array and
308838fd1498Szrj    *  not the _Rep is so that the debugger can see the string
308938fd1498Szrj    *  contents. (Probably we should add a non-inline member to get
309038fd1498Szrj    *  the _Rep for the debugger to use, so users can check the actual
309138fd1498Szrj    *  string length.)
309238fd1498Szrj    *
309338fd1498Szrj    *  Note that the _Rep object is a POD so that you can have a
309438fd1498Szrj    *  static <em>empty string</em> _Rep object already @a constructed before
309538fd1498Szrj    *  static constructors have run.  The reference-count encoding is
309638fd1498Szrj    *  chosen so that a 0 indicates one reference, so you never try to
309738fd1498Szrj    *  destroy the empty-string _Rep object.
309838fd1498Szrj    *
309938fd1498Szrj    *  All but the last paragraph is considered pretty conventional
310038fd1498Szrj    *  for a C++ string implementation.
310138fd1498Szrj   */
310238fd1498Szrj   // 21.3  Template class basic_string
310338fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
310438fd1498Szrj     class basic_string
310538fd1498Szrj     {
310638fd1498Szrj       typedef typename _Alloc::template rebind<_CharT>::other _CharT_alloc_type;
310738fd1498Szrj 
310838fd1498Szrj       // Types:
310938fd1498Szrj     public:
311038fd1498Szrj       typedef _Traits					    traits_type;
311138fd1498Szrj       typedef typename _Traits::char_type		    value_type;
311238fd1498Szrj       typedef _Alloc					    allocator_type;
311338fd1498Szrj       typedef typename _CharT_alloc_type::size_type	    size_type;
311438fd1498Szrj       typedef typename _CharT_alloc_type::difference_type   difference_type;
311538fd1498Szrj       typedef typename _CharT_alloc_type::reference	    reference;
311638fd1498Szrj       typedef typename _CharT_alloc_type::const_reference   const_reference;
311738fd1498Szrj       typedef typename _CharT_alloc_type::pointer	    pointer;
311838fd1498Szrj       typedef typename _CharT_alloc_type::const_pointer	    const_pointer;
311938fd1498Szrj       typedef __gnu_cxx::__normal_iterator<pointer, basic_string>  iterator;
312038fd1498Szrj       typedef __gnu_cxx::__normal_iterator<const_pointer, basic_string>
312138fd1498Szrj                                                             const_iterator;
312238fd1498Szrj       typedef std::reverse_iterator<const_iterator>	const_reverse_iterator;
312338fd1498Szrj       typedef std::reverse_iterator<iterator>		    reverse_iterator;
312438fd1498Szrj 
312538fd1498Szrj     private:
312638fd1498Szrj       // _Rep: string representation
312738fd1498Szrj       //   Invariants:
312838fd1498Szrj       //   1. String really contains _M_length + 1 characters: due to 21.3.4
312938fd1498Szrj       //      must be kept null-terminated.
313038fd1498Szrj       //   2. _M_capacity >= _M_length
313138fd1498Szrj       //      Allocated memory is always (_M_capacity + 1) * sizeof(_CharT).
313238fd1498Szrj       //   3. _M_refcount has three states:
313338fd1498Szrj       //      -1: leaked, one reference, no ref-copies allowed, non-const.
313438fd1498Szrj       //       0: one reference, non-const.
313538fd1498Szrj       //     n>0: n + 1 references, operations require a lock, const.
313638fd1498Szrj       //   4. All fields==0 is an empty string, given the extra storage
313738fd1498Szrj       //      beyond-the-end for a null terminator; thus, the shared
313838fd1498Szrj       //      empty string representation needs no constructor.
313938fd1498Szrj 
314038fd1498Szrj       struct _Rep_base
314138fd1498Szrj       {
314238fd1498Szrj 	size_type		_M_length;
314338fd1498Szrj 	size_type		_M_capacity;
314438fd1498Szrj 	_Atomic_word		_M_refcount;
314538fd1498Szrj       };
314638fd1498Szrj 
314738fd1498Szrj       struct _Rep : _Rep_base
314838fd1498Szrj       {
314938fd1498Szrj 	// Types:
315038fd1498Szrj 	typedef typename _Alloc::template rebind<char>::other _Raw_bytes_alloc;
315138fd1498Szrj 
315238fd1498Szrj 	// (Public) Data members:
315338fd1498Szrj 
315438fd1498Szrj 	// The maximum number of individual char_type elements of an
315538fd1498Szrj 	// individual string is determined by _S_max_size. This is the
315638fd1498Szrj 	// value that will be returned by max_size().  (Whereas npos
315738fd1498Szrj 	// is the maximum number of bytes the allocator can allocate.)
315838fd1498Szrj 	// If one was to divvy up the theoretical largest size string,
315938fd1498Szrj 	// with a terminating character and m _CharT elements, it'd
316038fd1498Szrj 	// look like this:
316138fd1498Szrj 	// npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT)
316238fd1498Szrj 	// Solving for m:
316338fd1498Szrj 	// m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1
316438fd1498Szrj 	// In addition, this implementation quarters this amount.
316538fd1498Szrj 	static const size_type	_S_max_size;
316638fd1498Szrj 	static const _CharT	_S_terminal;
316738fd1498Szrj 
316838fd1498Szrj 	// The following storage is init'd to 0 by the linker, resulting
316938fd1498Szrj         // (carefully) in an empty string with one reference.
317038fd1498Szrj         static size_type _S_empty_rep_storage[];
317138fd1498Szrj 
317238fd1498Szrj         static _Rep&
317338fd1498Szrj         _S_empty_rep() _GLIBCXX_NOEXCEPT
317438fd1498Szrj         {
317538fd1498Szrj 	  // NB: Mild hack to avoid strict-aliasing warnings.  Note that
317638fd1498Szrj 	  // _S_empty_rep_storage is never modified and the punning should
317738fd1498Szrj 	  // be reasonably safe in this case.
317838fd1498Szrj 	  void* __p = reinterpret_cast<void*>(&_S_empty_rep_storage);
317938fd1498Szrj 	  return *reinterpret_cast<_Rep*>(__p);
318038fd1498Szrj 	}
318138fd1498Szrj 
318238fd1498Szrj         bool
318338fd1498Szrj 	_M_is_leaked() const _GLIBCXX_NOEXCEPT
318438fd1498Szrj         {
318538fd1498Szrj #if defined(__GTHREADS)
318638fd1498Szrj           // _M_refcount is mutated concurrently by _M_refcopy/_M_dispose,
318738fd1498Szrj           // so we need to use an atomic load. However, _M_is_leaked
318838fd1498Szrj           // predicate does not change concurrently (i.e. the string is either
318938fd1498Szrj           // leaked or not), so a relaxed load is enough.
319038fd1498Szrj           return __atomic_load_n(&this->_M_refcount, __ATOMIC_RELAXED) < 0;
319138fd1498Szrj #else
319238fd1498Szrj           return this->_M_refcount < 0;
319338fd1498Szrj #endif
319438fd1498Szrj         }
319538fd1498Szrj 
319638fd1498Szrj         bool
319738fd1498Szrj 	_M_is_shared() const _GLIBCXX_NOEXCEPT
319838fd1498Szrj 	{
319938fd1498Szrj #if defined(__GTHREADS)
320038fd1498Szrj           // _M_refcount is mutated concurrently by _M_refcopy/_M_dispose,
320138fd1498Szrj           // so we need to use an atomic load. Another thread can drop last
320238fd1498Szrj           // but one reference concurrently with this check, so we need this
320338fd1498Szrj           // load to be acquire to synchronize with release fetch_and_add in
320438fd1498Szrj           // _M_dispose.
320538fd1498Szrj           return __atomic_load_n(&this->_M_refcount, __ATOMIC_ACQUIRE) > 0;
320638fd1498Szrj #else
320738fd1498Szrj           return this->_M_refcount > 0;
320838fd1498Szrj #endif
320938fd1498Szrj         }
321038fd1498Szrj 
321138fd1498Szrj         void
321238fd1498Szrj 	_M_set_leaked() _GLIBCXX_NOEXCEPT
321338fd1498Szrj         { this->_M_refcount = -1; }
321438fd1498Szrj 
321538fd1498Szrj         void
321638fd1498Szrj 	_M_set_sharable() _GLIBCXX_NOEXCEPT
321738fd1498Szrj         { this->_M_refcount = 0; }
321838fd1498Szrj 
321938fd1498Szrj 	void
322038fd1498Szrj 	_M_set_length_and_sharable(size_type __n) _GLIBCXX_NOEXCEPT
322138fd1498Szrj 	{
322238fd1498Szrj #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
322338fd1498Szrj 	  if (__builtin_expect(this != &_S_empty_rep(), false))
322438fd1498Szrj #endif
322538fd1498Szrj 	    {
322638fd1498Szrj 	      this->_M_set_sharable();  // One reference.
322738fd1498Szrj 	      this->_M_length = __n;
322838fd1498Szrj 	      traits_type::assign(this->_M_refdata()[__n], _S_terminal);
322938fd1498Szrj 	      // grrr. (per 21.3.4)
323038fd1498Szrj 	      // You cannot leave those LWG people alone for a second.
323138fd1498Szrj 	    }
323238fd1498Szrj 	}
323338fd1498Szrj 
323438fd1498Szrj 	_CharT*
323538fd1498Szrj 	_M_refdata() throw()
323638fd1498Szrj 	{ return reinterpret_cast<_CharT*>(this + 1); }
323738fd1498Szrj 
323838fd1498Szrj 	_CharT*
323938fd1498Szrj 	_M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2)
324038fd1498Szrj 	{
324138fd1498Szrj 	  return (!_M_is_leaked() && __alloc1 == __alloc2)
324238fd1498Szrj 	          ? _M_refcopy() : _M_clone(__alloc1);
324338fd1498Szrj 	}
324438fd1498Szrj 
324538fd1498Szrj 	// Create & Destroy
324638fd1498Szrj 	static _Rep*
324738fd1498Szrj 	_S_create(size_type, size_type, const _Alloc&);
324838fd1498Szrj 
324938fd1498Szrj 	void
325038fd1498Szrj 	_M_dispose(const _Alloc& __a) _GLIBCXX_NOEXCEPT
325138fd1498Szrj 	{
325238fd1498Szrj #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
325338fd1498Szrj 	  if (__builtin_expect(this != &_S_empty_rep(), false))
325438fd1498Szrj #endif
325538fd1498Szrj 	    {
325638fd1498Szrj 	      // Be race-detector-friendly.  For more info see bits/c++config.
325738fd1498Szrj 	      _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&this->_M_refcount);
325838fd1498Szrj               // Decrement of _M_refcount is acq_rel, because:
325938fd1498Szrj               // - all but last decrements need to release to synchronize with
326038fd1498Szrj               //   the last decrement that will delete the object.
326138fd1498Szrj               // - the last decrement needs to acquire to synchronize with
326238fd1498Szrj               //   all the previous decrements.
326338fd1498Szrj               // - last but one decrement needs to release to synchronize with
326438fd1498Szrj               //   the acquire load in _M_is_shared that will conclude that
326538fd1498Szrj               //   the object is not shared anymore.
326638fd1498Szrj 	      if (__gnu_cxx::__exchange_and_add_dispatch(&this->_M_refcount,
326738fd1498Szrj 							 -1) <= 0)
326838fd1498Szrj 		{
326938fd1498Szrj 		  _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&this->_M_refcount);
327038fd1498Szrj 		  _M_destroy(__a);
327138fd1498Szrj 		}
327238fd1498Szrj 	    }
327338fd1498Szrj 	}  // XXX MT
327438fd1498Szrj 
327538fd1498Szrj 	void
327638fd1498Szrj 	_M_destroy(const _Alloc&) throw();
327738fd1498Szrj 
327838fd1498Szrj 	_CharT*
327938fd1498Szrj 	_M_refcopy() throw()
328038fd1498Szrj 	{
328138fd1498Szrj #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
328238fd1498Szrj 	  if (__builtin_expect(this != &_S_empty_rep(), false))
328338fd1498Szrj #endif
328438fd1498Szrj             __gnu_cxx::__atomic_add_dispatch(&this->_M_refcount, 1);
328538fd1498Szrj 	  return _M_refdata();
328638fd1498Szrj 	}  // XXX MT
328738fd1498Szrj 
328838fd1498Szrj 	_CharT*
328938fd1498Szrj 	_M_clone(const _Alloc&, size_type __res = 0);
329038fd1498Szrj       };
329138fd1498Szrj 
329238fd1498Szrj       // Use empty-base optimization: http://www.cantrip.org/emptyopt.html
329338fd1498Szrj       struct _Alloc_hider : _Alloc
329438fd1498Szrj       {
329538fd1498Szrj 	_Alloc_hider(_CharT* __dat, const _Alloc& __a) _GLIBCXX_NOEXCEPT
329638fd1498Szrj 	: _Alloc(__a), _M_p(__dat) { }
329738fd1498Szrj 
329838fd1498Szrj 	_CharT* _M_p; // The actual data.
329938fd1498Szrj       };
330038fd1498Szrj 
330138fd1498Szrj     public:
330238fd1498Szrj       // Data Members (public):
330338fd1498Szrj       // NB: This is an unsigned type, and thus represents the maximum
330438fd1498Szrj       // size that the allocator can hold.
330538fd1498Szrj       ///  Value returned by various member functions when they fail.
330638fd1498Szrj       static const size_type	npos = static_cast<size_type>(-1);
330738fd1498Szrj 
330838fd1498Szrj     private:
330938fd1498Szrj       // Data Members (private):
331038fd1498Szrj       mutable _Alloc_hider	_M_dataplus;
331138fd1498Szrj 
331238fd1498Szrj       _CharT*
331338fd1498Szrj       _M_data() const _GLIBCXX_NOEXCEPT
331438fd1498Szrj       { return  _M_dataplus._M_p; }
331538fd1498Szrj 
331638fd1498Szrj       _CharT*
331738fd1498Szrj       _M_data(_CharT* __p) _GLIBCXX_NOEXCEPT
331838fd1498Szrj       { return (_M_dataplus._M_p = __p); }
331938fd1498Szrj 
332038fd1498Szrj       _Rep*
332138fd1498Szrj       _M_rep() const _GLIBCXX_NOEXCEPT
332238fd1498Szrj       { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); }
332338fd1498Szrj 
332438fd1498Szrj       // For the internal use we have functions similar to `begin'/`end'
332538fd1498Szrj       // but they do not call _M_leak.
332638fd1498Szrj       iterator
332738fd1498Szrj       _M_ibegin() const _GLIBCXX_NOEXCEPT
332838fd1498Szrj       { return iterator(_M_data()); }
332938fd1498Szrj 
333038fd1498Szrj       iterator
333138fd1498Szrj       _M_iend() const _GLIBCXX_NOEXCEPT
333238fd1498Szrj       { return iterator(_M_data() + this->size()); }
333338fd1498Szrj 
333438fd1498Szrj       void
333538fd1498Szrj       _M_leak()    // for use in begin() & non-const op[]
333638fd1498Szrj       {
333738fd1498Szrj 	if (!_M_rep()->_M_is_leaked())
333838fd1498Szrj 	  _M_leak_hard();
333938fd1498Szrj       }
334038fd1498Szrj 
334138fd1498Szrj       size_type
334238fd1498Szrj       _M_check(size_type __pos, const char* __s) const
334338fd1498Szrj       {
334438fd1498Szrj 	if (__pos > this->size())
334538fd1498Szrj 	  __throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > "
334638fd1498Szrj 				       "this->size() (which is %zu)"),
334738fd1498Szrj 				   __s, __pos, this->size());
334838fd1498Szrj 	return __pos;
334938fd1498Szrj       }
335038fd1498Szrj 
335138fd1498Szrj       void
335238fd1498Szrj       _M_check_length(size_type __n1, size_type __n2, const char* __s) const
335338fd1498Szrj       {
335438fd1498Szrj 	if (this->max_size() - (this->size() - __n1) < __n2)
335538fd1498Szrj 	  __throw_length_error(__N(__s));
335638fd1498Szrj       }
335738fd1498Szrj 
335838fd1498Szrj       // NB: _M_limit doesn't check for a bad __pos value.
335938fd1498Szrj       size_type
336038fd1498Szrj       _M_limit(size_type __pos, size_type __off) const _GLIBCXX_NOEXCEPT
336138fd1498Szrj       {
336238fd1498Szrj 	const bool __testoff =  __off < this->size() - __pos;
336338fd1498Szrj 	return __testoff ? __off : this->size() - __pos;
336438fd1498Szrj       }
336538fd1498Szrj 
336638fd1498Szrj       // True if _Rep and source do not overlap.
336738fd1498Szrj       bool
336838fd1498Szrj       _M_disjunct(const _CharT* __s) const _GLIBCXX_NOEXCEPT
336938fd1498Szrj       {
337038fd1498Szrj 	return (less<const _CharT*>()(__s, _M_data())
337138fd1498Szrj 		|| less<const _CharT*>()(_M_data() + this->size(), __s));
337238fd1498Szrj       }
337338fd1498Szrj 
337438fd1498Szrj       // When __n = 1 way faster than the general multichar
337538fd1498Szrj       // traits_type::copy/move/assign.
337638fd1498Szrj       static void
337738fd1498Szrj       _M_copy(_CharT* __d, const _CharT* __s, size_type __n) _GLIBCXX_NOEXCEPT
337838fd1498Szrj       {
337938fd1498Szrj 	if (__n == 1)
338038fd1498Szrj 	  traits_type::assign(*__d, *__s);
338138fd1498Szrj 	else
338238fd1498Szrj 	  traits_type::copy(__d, __s, __n);
338338fd1498Szrj       }
338438fd1498Szrj 
338538fd1498Szrj       static void
338638fd1498Szrj       _M_move(_CharT* __d, const _CharT* __s, size_type __n) _GLIBCXX_NOEXCEPT
338738fd1498Szrj       {
338838fd1498Szrj 	if (__n == 1)
338938fd1498Szrj 	  traits_type::assign(*__d, *__s);
339038fd1498Szrj 	else
339138fd1498Szrj 	  traits_type::move(__d, __s, __n);
339238fd1498Szrj       }
339338fd1498Szrj 
339438fd1498Szrj       static void
339538fd1498Szrj       _M_assign(_CharT* __d, size_type __n, _CharT __c) _GLIBCXX_NOEXCEPT
339638fd1498Szrj       {
339738fd1498Szrj 	if (__n == 1)
339838fd1498Szrj 	  traits_type::assign(*__d, __c);
339938fd1498Szrj 	else
340038fd1498Szrj 	  traits_type::assign(__d, __n, __c);
340138fd1498Szrj       }
340238fd1498Szrj 
340338fd1498Szrj       // _S_copy_chars is a separate template to permit specialization
340438fd1498Szrj       // to optimize for the common case of pointers as iterators.
340538fd1498Szrj       template<class _Iterator>
340638fd1498Szrj         static void
340738fd1498Szrj         _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2)
340838fd1498Szrj         {
340938fd1498Szrj 	  for (; __k1 != __k2; ++__k1, (void)++__p)
341038fd1498Szrj 	    traits_type::assign(*__p, *__k1); // These types are off.
341138fd1498Szrj 	}
341238fd1498Szrj 
341338fd1498Szrj       static void
341438fd1498Szrj       _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2) _GLIBCXX_NOEXCEPT
341538fd1498Szrj       { _S_copy_chars(__p, __k1.base(), __k2.base()); }
341638fd1498Szrj 
341738fd1498Szrj       static void
341838fd1498Szrj       _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2)
341938fd1498Szrj       _GLIBCXX_NOEXCEPT
342038fd1498Szrj       { _S_copy_chars(__p, __k1.base(), __k2.base()); }
342138fd1498Szrj 
342238fd1498Szrj       static void
342338fd1498Szrj       _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) _GLIBCXX_NOEXCEPT
342438fd1498Szrj       { _M_copy(__p, __k1, __k2 - __k1); }
342538fd1498Szrj 
342638fd1498Szrj       static void
342738fd1498Szrj       _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2)
342838fd1498Szrj       _GLIBCXX_NOEXCEPT
342938fd1498Szrj       { _M_copy(__p, __k1, __k2 - __k1); }
343038fd1498Szrj 
343138fd1498Szrj       static int
343238fd1498Szrj       _S_compare(size_type __n1, size_type __n2) _GLIBCXX_NOEXCEPT
343338fd1498Szrj       {
343438fd1498Szrj 	const difference_type __d = difference_type(__n1 - __n2);
343538fd1498Szrj 
343638fd1498Szrj 	if (__d > __gnu_cxx::__numeric_traits<int>::__max)
343738fd1498Szrj 	  return __gnu_cxx::__numeric_traits<int>::__max;
343838fd1498Szrj 	else if (__d < __gnu_cxx::__numeric_traits<int>::__min)
343938fd1498Szrj 	  return __gnu_cxx::__numeric_traits<int>::__min;
344038fd1498Szrj 	else
344138fd1498Szrj 	  return int(__d);
344238fd1498Szrj       }
344338fd1498Szrj 
344438fd1498Szrj       void
344538fd1498Szrj       _M_mutate(size_type __pos, size_type __len1, size_type __len2);
344638fd1498Szrj 
344738fd1498Szrj       void
344838fd1498Szrj       _M_leak_hard();
344938fd1498Szrj 
345038fd1498Szrj       static _Rep&
345138fd1498Szrj       _S_empty_rep() _GLIBCXX_NOEXCEPT
345238fd1498Szrj       { return _Rep::_S_empty_rep(); }
345338fd1498Szrj 
345438fd1498Szrj #if __cplusplus > 201402L
345538fd1498Szrj       // A helper type for avoiding boiler-plate.
345638fd1498Szrj       typedef basic_string_view<_CharT, _Traits> __sv_type;
345738fd1498Szrj 
345838fd1498Szrj       template<typename _Tp, typename _Res>
345938fd1498Szrj 	using _If_sv = enable_if_t<
346038fd1498Szrj 	  __and_<is_convertible<const _Tp&, __sv_type>,
346138fd1498Szrj 		 __not_<is_convertible<const _Tp*, const basic_string*>>,
346238fd1498Szrj 		 __not_<is_convertible<const _Tp&, const _CharT*>>>::value,
346338fd1498Szrj 	  _Res>;
346438fd1498Szrj 
346538fd1498Szrj       // Allows an implicit conversion to __sv_type.
346638fd1498Szrj       static __sv_type
346738fd1498Szrj       _S_to_string_view(__sv_type __svt) noexcept
346838fd1498Szrj       { return __svt; }
346938fd1498Szrj 
347038fd1498Szrj       // Wraps a string_view by explicit conversion and thus
347138fd1498Szrj       // allows to add an internal constructor that does not
347238fd1498Szrj       // participate in overload resolution when a string_view
347338fd1498Szrj       // is provided.
347438fd1498Szrj       struct __sv_wrapper
347538fd1498Szrj       {
347638fd1498Szrj 	explicit __sv_wrapper(__sv_type __sv) noexcept : _M_sv(__sv) { }
347738fd1498Szrj 	__sv_type _M_sv;
347838fd1498Szrj       };
347938fd1498Szrj #endif
348038fd1498Szrj 
348138fd1498Szrj     public:
348238fd1498Szrj       // Construct/copy/destroy:
348338fd1498Szrj       // NB: We overload ctors in some cases instead of using default
348438fd1498Szrj       // arguments, per 17.4.4.4 para. 2 item 2.
348538fd1498Szrj 
348638fd1498Szrj       /**
348738fd1498Szrj        *  @brief  Default constructor creates an empty string.
348838fd1498Szrj        */
348938fd1498Szrj       basic_string()
349038fd1498Szrj #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
349138fd1498Szrj       : _M_dataplus(_S_empty_rep()._M_refdata(), _Alloc()) { }
349238fd1498Szrj #else
349338fd1498Szrj       : _M_dataplus(_S_construct(size_type(), _CharT(), _Alloc()), _Alloc()){ }
349438fd1498Szrj #endif
349538fd1498Szrj 
349638fd1498Szrj       /**
349738fd1498Szrj        *  @brief  Construct an empty string using allocator @a a.
349838fd1498Szrj        */
349938fd1498Szrj       explicit
350038fd1498Szrj       basic_string(const _Alloc& __a);
350138fd1498Szrj 
350238fd1498Szrj       // NB: per LWG issue 42, semantics different from IS:
350338fd1498Szrj       /**
350438fd1498Szrj        *  @brief  Construct string with copy of value of @a str.
350538fd1498Szrj        *  @param  __str  Source string.
350638fd1498Szrj        */
350738fd1498Szrj       basic_string(const basic_string& __str);
350838fd1498Szrj 
350938fd1498Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
351038fd1498Szrj       // 2583. no way to supply an allocator for basic_string(str, pos)
351138fd1498Szrj       /**
351238fd1498Szrj        *  @brief  Construct string as copy of a substring.
351338fd1498Szrj        *  @param  __str  Source string.
351438fd1498Szrj        *  @param  __pos  Index of first character to copy from.
351538fd1498Szrj        *  @param  __a  Allocator to use.
351638fd1498Szrj        */
351738fd1498Szrj       basic_string(const basic_string& __str, size_type __pos,
351838fd1498Szrj 		   const _Alloc& __a = _Alloc());
351938fd1498Szrj 
352038fd1498Szrj       /**
352138fd1498Szrj        *  @brief  Construct string as copy of a substring.
352238fd1498Szrj        *  @param  __str  Source string.
352338fd1498Szrj        *  @param  __pos  Index of first character to copy from.
352438fd1498Szrj        *  @param  __n  Number of characters to copy.
352538fd1498Szrj        */
352638fd1498Szrj       basic_string(const basic_string& __str, size_type __pos,
352738fd1498Szrj 		   size_type __n);
352838fd1498Szrj       /**
352938fd1498Szrj        *  @brief  Construct string as copy of a substring.
353038fd1498Szrj        *  @param  __str  Source string.
353138fd1498Szrj        *  @param  __pos  Index of first character to copy from.
353238fd1498Szrj        *  @param  __n  Number of characters to copy.
353338fd1498Szrj        *  @param  __a  Allocator to use.
353438fd1498Szrj        */
353538fd1498Szrj       basic_string(const basic_string& __str, size_type __pos,
353638fd1498Szrj 		   size_type __n, const _Alloc& __a);
353738fd1498Szrj 
353838fd1498Szrj       /**
353938fd1498Szrj        *  @brief  Construct string initialized by a character %array.
354038fd1498Szrj        *  @param  __s  Source character %array.
354138fd1498Szrj        *  @param  __n  Number of characters to copy.
354238fd1498Szrj        *  @param  __a  Allocator to use (default is default allocator).
354338fd1498Szrj        *
354438fd1498Szrj        *  NB: @a __s must have at least @a __n characters, &apos;\\0&apos;
354538fd1498Szrj        *  has no special meaning.
354638fd1498Szrj        */
354738fd1498Szrj       basic_string(const _CharT* __s, size_type __n,
354838fd1498Szrj 		   const _Alloc& __a = _Alloc());
354938fd1498Szrj       /**
355038fd1498Szrj        *  @brief  Construct string as copy of a C string.
355138fd1498Szrj        *  @param  __s  Source C string.
355238fd1498Szrj        *  @param  __a  Allocator to use (default is default allocator).
355338fd1498Szrj        */
355438fd1498Szrj       basic_string(const _CharT* __s, const _Alloc& __a = _Alloc());
355538fd1498Szrj       /**
355638fd1498Szrj        *  @brief  Construct string as multiple characters.
355738fd1498Szrj        *  @param  __n  Number of characters.
355838fd1498Szrj        *  @param  __c  Character to use.
355938fd1498Szrj        *  @param  __a  Allocator to use (default is default allocator).
356038fd1498Szrj        */
356138fd1498Szrj       basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc());
356238fd1498Szrj 
356338fd1498Szrj #if __cplusplus >= 201103L
356438fd1498Szrj       /**
356538fd1498Szrj        *  @brief  Move construct string.
356638fd1498Szrj        *  @param  __str  Source string.
356738fd1498Szrj        *
356838fd1498Szrj        *  The newly-created string contains the exact contents of @a __str.
356938fd1498Szrj        *  @a __str is a valid, but unspecified string.
357038fd1498Szrj        **/
357138fd1498Szrj       basic_string(basic_string&& __str)
357238fd1498Szrj #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
357338fd1498Szrj       noexcept // FIXME C++11: should always be noexcept.
357438fd1498Szrj #endif
357538fd1498Szrj       : _M_dataplus(__str._M_dataplus)
357638fd1498Szrj       {
357738fd1498Szrj #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
357838fd1498Szrj 	__str._M_data(_S_empty_rep()._M_refdata());
357938fd1498Szrj #else
358038fd1498Szrj 	__str._M_data(_S_construct(size_type(), _CharT(), get_allocator()));
358138fd1498Szrj #endif
358238fd1498Szrj       }
358338fd1498Szrj 
358438fd1498Szrj       /**
358538fd1498Szrj        *  @brief  Construct string from an initializer %list.
358638fd1498Szrj        *  @param  __l  std::initializer_list of characters.
358738fd1498Szrj        *  @param  __a  Allocator to use (default is default allocator).
358838fd1498Szrj        */
358938fd1498Szrj       basic_string(initializer_list<_CharT> __l, const _Alloc& __a = _Alloc());
359038fd1498Szrj #endif // C++11
359138fd1498Szrj 
359238fd1498Szrj       /**
359338fd1498Szrj        *  @brief  Construct string as copy of a range.
359438fd1498Szrj        *  @param  __beg  Start of range.
359538fd1498Szrj        *  @param  __end  End of range.
359638fd1498Szrj        *  @param  __a  Allocator to use (default is default allocator).
359738fd1498Szrj        */
359838fd1498Szrj       template<class _InputIterator>
359938fd1498Szrj         basic_string(_InputIterator __beg, _InputIterator __end,
360038fd1498Szrj 		     const _Alloc& __a = _Alloc());
360138fd1498Szrj 
360238fd1498Szrj #if __cplusplus > 201402L
360338fd1498Szrj       /**
360438fd1498Szrj        *  @brief  Construct string from a substring of a string_view.
360538fd1498Szrj        *  @param  __t   Source object convertible to string view.
360638fd1498Szrj        *  @param  __pos The index of the first character to copy from __t.
360738fd1498Szrj        *  @param  __n   The number of characters to copy from __t.
360838fd1498Szrj        *  @param  __a   Allocator to use.
360938fd1498Szrj        */
361038fd1498Szrj       template<typename _Tp, typename = _If_sv<_Tp, void>>
361138fd1498Szrj 	basic_string(const _Tp& __t, size_type __pos, size_type __n,
361238fd1498Szrj 		     const _Alloc& __a = _Alloc())
361338fd1498Szrj 	: basic_string(_S_to_string_view(__t).substr(__pos, __n), __a) { }
361438fd1498Szrj 
361538fd1498Szrj       /**
361638fd1498Szrj        *  @brief  Construct string from a string_view.
361738fd1498Szrj        *  @param  __t  Source object convertible to string view.
361838fd1498Szrj        *  @param  __a  Allocator to use (default is default allocator).
361938fd1498Szrj        */
362038fd1498Szrj       template<typename _Tp, typename = _If_sv<_Tp, void>>
362138fd1498Szrj 	explicit
362238fd1498Szrj 	basic_string(const _Tp& __t, const _Alloc& __a = _Alloc())
362338fd1498Szrj 	: basic_string(__sv_wrapper(_S_to_string_view(__t)), __a) { }
362438fd1498Szrj 
362538fd1498Szrj       /**
362638fd1498Szrj        *  @brief  Only internally used: Construct string from a string view
362738fd1498Szrj        *          wrapper.
362838fd1498Szrj        *  @param  __svw  string view wrapper.
362938fd1498Szrj        *  @param  __a  Allocator to use.
363038fd1498Szrj        */
363138fd1498Szrj       explicit
363238fd1498Szrj       basic_string(__sv_wrapper __svw, const _Alloc& __a)
363338fd1498Szrj       : basic_string(__svw._M_sv.data(), __svw._M_sv.size(), __a) { }
363438fd1498Szrj #endif // C++17
363538fd1498Szrj 
363638fd1498Szrj       /**
363738fd1498Szrj        *  @brief  Destroy the string instance.
363838fd1498Szrj        */
363938fd1498Szrj       ~basic_string() _GLIBCXX_NOEXCEPT
364038fd1498Szrj       { _M_rep()->_M_dispose(this->get_allocator()); }
364138fd1498Szrj 
364238fd1498Szrj       /**
364338fd1498Szrj        *  @brief  Assign the value of @a str to this string.
364438fd1498Szrj        *  @param  __str  Source string.
364538fd1498Szrj        */
364638fd1498Szrj       basic_string&
364738fd1498Szrj       operator=(const basic_string& __str)
364838fd1498Szrj       { return this->assign(__str); }
364938fd1498Szrj 
365038fd1498Szrj       /**
365138fd1498Szrj        *  @brief  Copy contents of @a s into this string.
365238fd1498Szrj        *  @param  __s  Source null-terminated string.
365338fd1498Szrj        */
365438fd1498Szrj       basic_string&
365538fd1498Szrj       operator=(const _CharT* __s)
365638fd1498Szrj       { return this->assign(__s); }
365738fd1498Szrj 
365838fd1498Szrj       /**
365938fd1498Szrj        *  @brief  Set value to string of length 1.
366038fd1498Szrj        *  @param  __c  Source character.
366138fd1498Szrj        *
366238fd1498Szrj        *  Assigning to a character makes this string length 1 and
366338fd1498Szrj        *  (*this)[0] == @a c.
366438fd1498Szrj        */
366538fd1498Szrj       basic_string&
366638fd1498Szrj       operator=(_CharT __c)
366738fd1498Szrj       {
366838fd1498Szrj 	this->assign(1, __c);
366938fd1498Szrj 	return *this;
367038fd1498Szrj       }
367138fd1498Szrj 
367238fd1498Szrj #if __cplusplus >= 201103L
367338fd1498Szrj       /**
367438fd1498Szrj        *  @brief  Move assign the value of @a str to this string.
367538fd1498Szrj        *  @param  __str  Source string.
367638fd1498Szrj        *
367738fd1498Szrj        *  The contents of @a str are moved into this string (without copying).
367838fd1498Szrj        *  @a str is a valid, but unspecified string.
367938fd1498Szrj        **/
368038fd1498Szrj       // PR 58265, this should be noexcept.
368138fd1498Szrj       basic_string&
368238fd1498Szrj       operator=(basic_string&& __str)
368338fd1498Szrj       {
368438fd1498Szrj 	// NB: DR 1204.
368538fd1498Szrj 	this->swap(__str);
368638fd1498Szrj 	return *this;
368738fd1498Szrj       }
368838fd1498Szrj 
368938fd1498Szrj       /**
369038fd1498Szrj        *  @brief  Set value to string constructed from initializer %list.
369138fd1498Szrj        *  @param  __l  std::initializer_list.
369238fd1498Szrj        */
369338fd1498Szrj       basic_string&
369438fd1498Szrj       operator=(initializer_list<_CharT> __l)
369538fd1498Szrj       {
369638fd1498Szrj 	this->assign(__l.begin(), __l.size());
369738fd1498Szrj 	return *this;
369838fd1498Szrj       }
369938fd1498Szrj #endif // C++11
370038fd1498Szrj 
370138fd1498Szrj #if __cplusplus > 201402L
370238fd1498Szrj       /**
370338fd1498Szrj        *  @brief  Set value to string constructed from a string_view.
370438fd1498Szrj        *  @param  __svt An object convertible to  string_view.
370538fd1498Szrj        */
370638fd1498Szrj       template<typename _Tp>
370738fd1498Szrj 	_If_sv<_Tp, basic_string&>
370838fd1498Szrj 	operator=(const _Tp& __svt)
370938fd1498Szrj 	{ return this->assign(__svt); }
371038fd1498Szrj 
371138fd1498Szrj       /**
371238fd1498Szrj        *  @brief  Convert to a string_view.
371338fd1498Szrj        *  @return A string_view.
371438fd1498Szrj        */
371538fd1498Szrj       operator __sv_type() const noexcept
371638fd1498Szrj       { return __sv_type(data(), size()); }
371738fd1498Szrj #endif // C++17
371838fd1498Szrj 
371938fd1498Szrj       // Iterators:
372038fd1498Szrj       /**
372138fd1498Szrj        *  Returns a read/write iterator that points to the first character in
372238fd1498Szrj        *  the %string.  Unshares the string.
372338fd1498Szrj        */
372438fd1498Szrj       iterator
372538fd1498Szrj       begin() // FIXME C++11: should be noexcept.
372638fd1498Szrj       {
372738fd1498Szrj 	_M_leak();
372838fd1498Szrj 	return iterator(_M_data());
372938fd1498Szrj       }
373038fd1498Szrj 
373138fd1498Szrj       /**
373238fd1498Szrj        *  Returns a read-only (constant) iterator that points to the first
373338fd1498Szrj        *  character in the %string.
373438fd1498Szrj        */
373538fd1498Szrj       const_iterator
373638fd1498Szrj       begin() const _GLIBCXX_NOEXCEPT
373738fd1498Szrj       { return const_iterator(_M_data()); }
373838fd1498Szrj 
373938fd1498Szrj       /**
374038fd1498Szrj        *  Returns a read/write iterator that points one past the last
374138fd1498Szrj        *  character in the %string.  Unshares the string.
374238fd1498Szrj        */
374338fd1498Szrj       iterator
374438fd1498Szrj       end() // FIXME C++11: should be noexcept.
374538fd1498Szrj       {
374638fd1498Szrj 	_M_leak();
374738fd1498Szrj 	return iterator(_M_data() + this->size());
374838fd1498Szrj       }
374938fd1498Szrj 
375038fd1498Szrj       /**
375138fd1498Szrj        *  Returns a read-only (constant) iterator that points one past the
375238fd1498Szrj        *  last character in the %string.
375338fd1498Szrj        */
375438fd1498Szrj       const_iterator
375538fd1498Szrj       end() const _GLIBCXX_NOEXCEPT
375638fd1498Szrj       { return const_iterator(_M_data() + this->size()); }
375738fd1498Szrj 
375838fd1498Szrj       /**
375938fd1498Szrj        *  Returns a read/write reverse iterator that points to the last
376038fd1498Szrj        *  character in the %string.  Iteration is done in reverse element
376138fd1498Szrj        *  order.  Unshares the string.
376238fd1498Szrj        */
376338fd1498Szrj       reverse_iterator
376438fd1498Szrj       rbegin() // FIXME C++11: should be noexcept.
376538fd1498Szrj       { return reverse_iterator(this->end()); }
376638fd1498Szrj 
376738fd1498Szrj       /**
376838fd1498Szrj        *  Returns a read-only (constant) reverse iterator that points
376938fd1498Szrj        *  to the last character in the %string.  Iteration is done in
377038fd1498Szrj        *  reverse element order.
377138fd1498Szrj        */
377238fd1498Szrj       const_reverse_iterator
377338fd1498Szrj       rbegin() const _GLIBCXX_NOEXCEPT
377438fd1498Szrj       { return const_reverse_iterator(this->end()); }
377538fd1498Szrj 
377638fd1498Szrj       /**
377738fd1498Szrj        *  Returns a read/write reverse iterator that points to one before the
377838fd1498Szrj        *  first character in the %string.  Iteration is done in reverse
377938fd1498Szrj        *  element order.  Unshares the string.
378038fd1498Szrj        */
378138fd1498Szrj       reverse_iterator
378238fd1498Szrj       rend() // FIXME C++11: should be noexcept.
378338fd1498Szrj       { return reverse_iterator(this->begin()); }
378438fd1498Szrj 
378538fd1498Szrj       /**
378638fd1498Szrj        *  Returns a read-only (constant) reverse iterator that points
378738fd1498Szrj        *  to one before the first character in the %string.  Iteration
378838fd1498Szrj        *  is done in reverse element order.
378938fd1498Szrj        */
379038fd1498Szrj       const_reverse_iterator
379138fd1498Szrj       rend() const _GLIBCXX_NOEXCEPT
379238fd1498Szrj       { return const_reverse_iterator(this->begin()); }
379338fd1498Szrj 
379438fd1498Szrj #if __cplusplus >= 201103L
379538fd1498Szrj       /**
379638fd1498Szrj        *  Returns a read-only (constant) iterator that points to the first
379738fd1498Szrj        *  character in the %string.
379838fd1498Szrj        */
379938fd1498Szrj       const_iterator
380038fd1498Szrj       cbegin() const noexcept
380138fd1498Szrj       { return const_iterator(this->_M_data()); }
380238fd1498Szrj 
380338fd1498Szrj       /**
380438fd1498Szrj        *  Returns a read-only (constant) iterator that points one past the
380538fd1498Szrj        *  last character in the %string.
380638fd1498Szrj        */
380738fd1498Szrj       const_iterator
380838fd1498Szrj       cend() const noexcept
380938fd1498Szrj       { return const_iterator(this->_M_data() + this->size()); }
381038fd1498Szrj 
381138fd1498Szrj       /**
381238fd1498Szrj        *  Returns a read-only (constant) reverse iterator that points
381338fd1498Szrj        *  to the last character in the %string.  Iteration is done in
381438fd1498Szrj        *  reverse element order.
381538fd1498Szrj        */
381638fd1498Szrj       const_reverse_iterator
381738fd1498Szrj       crbegin() const noexcept
381838fd1498Szrj       { return const_reverse_iterator(this->end()); }
381938fd1498Szrj 
382038fd1498Szrj       /**
382138fd1498Szrj        *  Returns a read-only (constant) reverse iterator that points
382238fd1498Szrj        *  to one before the first character in the %string.  Iteration
382338fd1498Szrj        *  is done in reverse element order.
382438fd1498Szrj        */
382538fd1498Szrj       const_reverse_iterator
382638fd1498Szrj       crend() const noexcept
382738fd1498Szrj       { return const_reverse_iterator(this->begin()); }
382838fd1498Szrj #endif
382938fd1498Szrj 
383038fd1498Szrj     public:
383138fd1498Szrj       // Capacity:
383238fd1498Szrj       ///  Returns the number of characters in the string, not including any
383338fd1498Szrj       ///  null-termination.
383438fd1498Szrj       size_type
383538fd1498Szrj       size() const _GLIBCXX_NOEXCEPT
383638fd1498Szrj       { return _M_rep()->_M_length; }
383738fd1498Szrj 
383838fd1498Szrj       ///  Returns the number of characters in the string, not including any
383938fd1498Szrj       ///  null-termination.
384038fd1498Szrj       size_type
384138fd1498Szrj       length() const _GLIBCXX_NOEXCEPT
384238fd1498Szrj       { return _M_rep()->_M_length; }
384338fd1498Szrj 
384438fd1498Szrj       ///  Returns the size() of the largest possible %string.
384538fd1498Szrj       size_type
384638fd1498Szrj       max_size() const _GLIBCXX_NOEXCEPT
384738fd1498Szrj       { return _Rep::_S_max_size; }
384838fd1498Szrj 
384938fd1498Szrj       /**
385038fd1498Szrj        *  @brief  Resizes the %string to the specified number of characters.
385138fd1498Szrj        *  @param  __n  Number of characters the %string should contain.
385238fd1498Szrj        *  @param  __c  Character to fill any new elements.
385338fd1498Szrj        *
385438fd1498Szrj        *  This function will %resize the %string to the specified
385538fd1498Szrj        *  number of characters.  If the number is smaller than the
385638fd1498Szrj        *  %string's current size the %string is truncated, otherwise
385738fd1498Szrj        *  the %string is extended and new elements are %set to @a __c.
385838fd1498Szrj        */
385938fd1498Szrj       void
386038fd1498Szrj       resize(size_type __n, _CharT __c);
386138fd1498Szrj 
386238fd1498Szrj       /**
386338fd1498Szrj        *  @brief  Resizes the %string to the specified number of characters.
386438fd1498Szrj        *  @param  __n  Number of characters the %string should contain.
386538fd1498Szrj        *
386638fd1498Szrj        *  This function will resize the %string to the specified length.  If
386738fd1498Szrj        *  the new size is smaller than the %string's current size the %string
386838fd1498Szrj        *  is truncated, otherwise the %string is extended and new characters
386938fd1498Szrj        *  are default-constructed.  For basic types such as char, this means
387038fd1498Szrj        *  setting them to 0.
387138fd1498Szrj        */
387238fd1498Szrj       void
387338fd1498Szrj       resize(size_type __n)
387438fd1498Szrj       { this->resize(__n, _CharT()); }
387538fd1498Szrj 
387638fd1498Szrj #if __cplusplus >= 201103L
387738fd1498Szrj       ///  A non-binding request to reduce capacity() to size().
387838fd1498Szrj       void
387938fd1498Szrj       shrink_to_fit() _GLIBCXX_NOEXCEPT
388038fd1498Szrj       {
388138fd1498Szrj #if __cpp_exceptions
388238fd1498Szrj 	if (capacity() > size())
388338fd1498Szrj 	  {
388438fd1498Szrj 	    try
388538fd1498Szrj 	      { reserve(0); }
388638fd1498Szrj 	    catch(...)
388738fd1498Szrj 	      { }
388838fd1498Szrj 	  }
388938fd1498Szrj #endif
389038fd1498Szrj       }
389138fd1498Szrj #endif
389238fd1498Szrj 
389338fd1498Szrj       /**
389438fd1498Szrj        *  Returns the total number of characters that the %string can hold
389538fd1498Szrj        *  before needing to allocate more memory.
389638fd1498Szrj        */
389738fd1498Szrj       size_type
389838fd1498Szrj       capacity() const _GLIBCXX_NOEXCEPT
389938fd1498Szrj       { return _M_rep()->_M_capacity; }
390038fd1498Szrj 
390138fd1498Szrj       /**
390238fd1498Szrj        *  @brief  Attempt to preallocate enough memory for specified number of
390338fd1498Szrj        *          characters.
390438fd1498Szrj        *  @param  __res_arg  Number of characters required.
390538fd1498Szrj        *  @throw  std::length_error  If @a __res_arg exceeds @c max_size().
390638fd1498Szrj        *
390738fd1498Szrj        *  This function attempts to reserve enough memory for the
390838fd1498Szrj        *  %string to hold the specified number of characters.  If the
390938fd1498Szrj        *  number requested is more than max_size(), length_error is
391038fd1498Szrj        *  thrown.
391138fd1498Szrj        *
391238fd1498Szrj        *  The advantage of this function is that if optimal code is a
391338fd1498Szrj        *  necessity and the user can determine the string length that will be
391438fd1498Szrj        *  required, the user can reserve the memory in %advance, and thus
391538fd1498Szrj        *  prevent a possible reallocation of memory and copying of %string
391638fd1498Szrj        *  data.
391738fd1498Szrj        */
391838fd1498Szrj       void
391938fd1498Szrj       reserve(size_type __res_arg = 0);
392038fd1498Szrj 
392138fd1498Szrj       /**
392238fd1498Szrj        *  Erases the string, making it empty.
392338fd1498Szrj        */
392438fd1498Szrj #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
392538fd1498Szrj       void
392638fd1498Szrj       clear() _GLIBCXX_NOEXCEPT
392738fd1498Szrj       {
392838fd1498Szrj 	if (_M_rep()->_M_is_shared())
392938fd1498Szrj 	  {
393038fd1498Szrj 	    _M_rep()->_M_dispose(this->get_allocator());
393138fd1498Szrj 	    _M_data(_S_empty_rep()._M_refdata());
393238fd1498Szrj 	  }
393338fd1498Szrj 	else
393438fd1498Szrj 	  _M_rep()->_M_set_length_and_sharable(0);
393538fd1498Szrj       }
393638fd1498Szrj #else
393738fd1498Szrj       // PR 56166: this should not throw.
393838fd1498Szrj       void
393938fd1498Szrj       clear()
394038fd1498Szrj       { _M_mutate(0, this->size(), 0); }
394138fd1498Szrj #endif
394238fd1498Szrj 
394338fd1498Szrj       /**
394438fd1498Szrj        *  Returns true if the %string is empty.  Equivalent to
394538fd1498Szrj        *  <code>*this == ""</code>.
394638fd1498Szrj        */
394738fd1498Szrj       bool
394838fd1498Szrj       empty() const _GLIBCXX_NOEXCEPT
394938fd1498Szrj       { return this->size() == 0; }
395038fd1498Szrj 
395138fd1498Szrj       // Element access:
395238fd1498Szrj       /**
395338fd1498Szrj        *  @brief  Subscript access to the data contained in the %string.
395438fd1498Szrj        *  @param  __pos  The index of the character to access.
395538fd1498Szrj        *  @return  Read-only (constant) reference to the character.
395638fd1498Szrj        *
395738fd1498Szrj        *  This operator allows for easy, array-style, data access.
395838fd1498Szrj        *  Note that data access with this operator is unchecked and
395938fd1498Szrj        *  out_of_range lookups are not defined. (For checked lookups
396038fd1498Szrj        *  see at().)
396138fd1498Szrj        */
396238fd1498Szrj       const_reference
396338fd1498Szrj       operator[] (size_type __pos) const _GLIBCXX_NOEXCEPT
396438fd1498Szrj       {
396538fd1498Szrj 	__glibcxx_assert(__pos <= size());
396638fd1498Szrj 	return _M_data()[__pos];
396738fd1498Szrj       }
396838fd1498Szrj 
396938fd1498Szrj       /**
397038fd1498Szrj        *  @brief  Subscript access to the data contained in the %string.
397138fd1498Szrj        *  @param  __pos  The index of the character to access.
397238fd1498Szrj        *  @return  Read/write reference to the character.
397338fd1498Szrj        *
397438fd1498Szrj        *  This operator allows for easy, array-style, data access.
397538fd1498Szrj        *  Note that data access with this operator is unchecked and
397638fd1498Szrj        *  out_of_range lookups are not defined. (For checked lookups
397738fd1498Szrj        *  see at().)  Unshares the string.
397838fd1498Szrj        */
397938fd1498Szrj       reference
398038fd1498Szrj       operator[](size_type __pos)
398138fd1498Szrj       {
398238fd1498Szrj         // Allow pos == size() both in C++98 mode, as v3 extension,
398338fd1498Szrj 	// and in C++11 mode.
398438fd1498Szrj 	__glibcxx_assert(__pos <= size());
398538fd1498Szrj         // In pedantic mode be strict in C++98 mode.
398638fd1498Szrj 	_GLIBCXX_DEBUG_PEDASSERT(__cplusplus >= 201103L || __pos < size());
398738fd1498Szrj 	_M_leak();
398838fd1498Szrj 	return _M_data()[__pos];
398938fd1498Szrj       }
399038fd1498Szrj 
399138fd1498Szrj       /**
399238fd1498Szrj        *  @brief  Provides access to the data contained in the %string.
399338fd1498Szrj        *  @param __n The index of the character to access.
399438fd1498Szrj        *  @return  Read-only (const) reference to the character.
399538fd1498Szrj        *  @throw  std::out_of_range  If @a n is an invalid index.
399638fd1498Szrj        *
399738fd1498Szrj        *  This function provides for safer data access.  The parameter is
399838fd1498Szrj        *  first checked that it is in the range of the string.  The function
399938fd1498Szrj        *  throws out_of_range if the check fails.
400038fd1498Szrj        */
400138fd1498Szrj       const_reference
400238fd1498Szrj       at(size_type __n) const
400338fd1498Szrj       {
400438fd1498Szrj 	if (__n >= this->size())
400538fd1498Szrj 	  __throw_out_of_range_fmt(__N("basic_string::at: __n "
400638fd1498Szrj 				       "(which is %zu) >= this->size() "
400738fd1498Szrj 				       "(which is %zu)"),
400838fd1498Szrj 				   __n, this->size());
400938fd1498Szrj 	return _M_data()[__n];
401038fd1498Szrj       }
401138fd1498Szrj 
401238fd1498Szrj       /**
401338fd1498Szrj        *  @brief  Provides access to the data contained in the %string.
401438fd1498Szrj        *  @param __n The index of the character to access.
401538fd1498Szrj        *  @return  Read/write reference to the character.
401638fd1498Szrj        *  @throw  std::out_of_range  If @a n is an invalid index.
401738fd1498Szrj        *
401838fd1498Szrj        *  This function provides for safer data access.  The parameter is
401938fd1498Szrj        *  first checked that it is in the range of the string.  The function
402038fd1498Szrj        *  throws out_of_range if the check fails.  Success results in
402138fd1498Szrj        *  unsharing the string.
402238fd1498Szrj        */
402338fd1498Szrj       reference
402438fd1498Szrj       at(size_type __n)
402538fd1498Szrj       {
402638fd1498Szrj 	if (__n >= size())
402738fd1498Szrj 	  __throw_out_of_range_fmt(__N("basic_string::at: __n "
402838fd1498Szrj 				       "(which is %zu) >= this->size() "
402938fd1498Szrj 				       "(which is %zu)"),
403038fd1498Szrj 				   __n, this->size());
403138fd1498Szrj 	_M_leak();
403238fd1498Szrj 	return _M_data()[__n];
403338fd1498Szrj       }
403438fd1498Szrj 
403538fd1498Szrj #if __cplusplus >= 201103L
403638fd1498Szrj       /**
403738fd1498Szrj        *  Returns a read/write reference to the data at the first
403838fd1498Szrj        *  element of the %string.
403938fd1498Szrj        */
404038fd1498Szrj       reference
404138fd1498Szrj       front()
404238fd1498Szrj       {
404338fd1498Szrj 	__glibcxx_assert(!empty());
404438fd1498Szrj 	return operator[](0);
404538fd1498Szrj       }
404638fd1498Szrj 
404738fd1498Szrj       /**
404838fd1498Szrj        *  Returns a read-only (constant) reference to the data at the first
404938fd1498Szrj        *  element of the %string.
405038fd1498Szrj        */
405138fd1498Szrj       const_reference
405238fd1498Szrj       front() const noexcept
405338fd1498Szrj       {
405438fd1498Szrj 	__glibcxx_assert(!empty());
405538fd1498Szrj 	return operator[](0);
405638fd1498Szrj       }
405738fd1498Szrj 
405838fd1498Szrj       /**
405938fd1498Szrj        *  Returns a read/write reference to the data at the last
406038fd1498Szrj        *  element of the %string.
406138fd1498Szrj        */
406238fd1498Szrj       reference
406338fd1498Szrj       back()
406438fd1498Szrj       {
406538fd1498Szrj 	__glibcxx_assert(!empty());
406638fd1498Szrj 	return operator[](this->size() - 1);
406738fd1498Szrj       }
406838fd1498Szrj 
406938fd1498Szrj       /**
407038fd1498Szrj        *  Returns a read-only (constant) reference to the data at the
407138fd1498Szrj        *  last element of the %string.
407238fd1498Szrj        */
407338fd1498Szrj       const_reference
407438fd1498Szrj       back() const noexcept
407538fd1498Szrj       {
407638fd1498Szrj 	__glibcxx_assert(!empty());
407738fd1498Szrj 	return operator[](this->size() - 1);
407838fd1498Szrj       }
407938fd1498Szrj #endif
408038fd1498Szrj 
408138fd1498Szrj       // Modifiers:
408238fd1498Szrj       /**
408338fd1498Szrj        *  @brief  Append a string to this string.
408438fd1498Szrj        *  @param __str  The string to append.
408538fd1498Szrj        *  @return  Reference to this string.
408638fd1498Szrj        */
408738fd1498Szrj       basic_string&
408838fd1498Szrj       operator+=(const basic_string& __str)
408938fd1498Szrj       { return this->append(__str); }
409038fd1498Szrj 
409138fd1498Szrj       /**
409238fd1498Szrj        *  @brief  Append a C string.
409338fd1498Szrj        *  @param __s  The C string to append.
409438fd1498Szrj        *  @return  Reference to this string.
409538fd1498Szrj        */
409638fd1498Szrj       basic_string&
409738fd1498Szrj       operator+=(const _CharT* __s)
409838fd1498Szrj       { return this->append(__s); }
409938fd1498Szrj 
410038fd1498Szrj       /**
410138fd1498Szrj        *  @brief  Append a character.
410238fd1498Szrj        *  @param __c  The character to append.
410338fd1498Szrj        *  @return  Reference to this string.
410438fd1498Szrj        */
410538fd1498Szrj       basic_string&
410638fd1498Szrj       operator+=(_CharT __c)
410738fd1498Szrj       {
410838fd1498Szrj 	this->push_back(__c);
410938fd1498Szrj 	return *this;
411038fd1498Szrj       }
411138fd1498Szrj 
411238fd1498Szrj #if __cplusplus >= 201103L
411338fd1498Szrj       /**
411438fd1498Szrj        *  @brief  Append an initializer_list of characters.
411538fd1498Szrj        *  @param __l  The initializer_list of characters to be appended.
411638fd1498Szrj        *  @return  Reference to this string.
411738fd1498Szrj        */
411838fd1498Szrj       basic_string&
411938fd1498Szrj       operator+=(initializer_list<_CharT> __l)
412038fd1498Szrj       { return this->append(__l.begin(), __l.size()); }
412138fd1498Szrj #endif // C++11
412238fd1498Szrj 
412338fd1498Szrj #if __cplusplus > 201402L
412438fd1498Szrj       /**
412538fd1498Szrj        *  @brief  Append a string_view.
412638fd1498Szrj        *  @param __svt The object convertible to string_view to be appended.
412738fd1498Szrj        *  @return  Reference to this string.
412838fd1498Szrj        */
412938fd1498Szrj       template<typename _Tp>
413038fd1498Szrj 	_If_sv<_Tp, basic_string&>
413138fd1498Szrj 	operator+=(const _Tp& __svt)
413238fd1498Szrj 	{ return this->append(__svt); }
413338fd1498Szrj #endif // C++17
413438fd1498Szrj 
413538fd1498Szrj       /**
413638fd1498Szrj        *  @brief  Append a string to this string.
413738fd1498Szrj        *  @param __str  The string to append.
413838fd1498Szrj        *  @return  Reference to this string.
413938fd1498Szrj        */
414038fd1498Szrj       basic_string&
414138fd1498Szrj       append(const basic_string& __str);
414238fd1498Szrj 
414338fd1498Szrj       /**
414438fd1498Szrj        *  @brief  Append a substring.
414538fd1498Szrj        *  @param __str  The string to append.
414638fd1498Szrj        *  @param __pos  Index of the first character of str to append.
414738fd1498Szrj        *  @param __n  The number of characters to append.
414838fd1498Szrj        *  @return  Reference to this string.
414938fd1498Szrj        *  @throw  std::out_of_range if @a __pos is not a valid index.
415038fd1498Szrj        *
415138fd1498Szrj        *  This function appends @a __n characters from @a __str
415238fd1498Szrj        *  starting at @a __pos to this string.  If @a __n is is larger
415338fd1498Szrj        *  than the number of available characters in @a __str, the
415438fd1498Szrj        *  remainder of @a __str is appended.
415538fd1498Szrj        */
415638fd1498Szrj       basic_string&
4157*58e805e6Szrj       append(const basic_string& __str, size_type __pos, size_type __n = npos);
415838fd1498Szrj 
415938fd1498Szrj       /**
416038fd1498Szrj        *  @brief  Append a C substring.
416138fd1498Szrj        *  @param __s  The C string to append.
416238fd1498Szrj        *  @param __n  The number of characters to append.
416338fd1498Szrj        *  @return  Reference to this string.
416438fd1498Szrj        */
416538fd1498Szrj       basic_string&
416638fd1498Szrj       append(const _CharT* __s, size_type __n);
416738fd1498Szrj 
416838fd1498Szrj       /**
416938fd1498Szrj        *  @brief  Append a C string.
417038fd1498Szrj        *  @param __s  The C string to append.
417138fd1498Szrj        *  @return  Reference to this string.
417238fd1498Szrj        */
417338fd1498Szrj       basic_string&
417438fd1498Szrj       append(const _CharT* __s)
417538fd1498Szrj       {
417638fd1498Szrj 	__glibcxx_requires_string(__s);
417738fd1498Szrj 	return this->append(__s, traits_type::length(__s));
417838fd1498Szrj       }
417938fd1498Szrj 
418038fd1498Szrj       /**
418138fd1498Szrj        *  @brief  Append multiple characters.
418238fd1498Szrj        *  @param __n  The number of characters to append.
418338fd1498Szrj        *  @param __c  The character to use.
418438fd1498Szrj        *  @return  Reference to this string.
418538fd1498Szrj        *
418638fd1498Szrj        *  Appends __n copies of __c to this string.
418738fd1498Szrj        */
418838fd1498Szrj       basic_string&
418938fd1498Szrj       append(size_type __n, _CharT __c);
419038fd1498Szrj 
419138fd1498Szrj #if __cplusplus >= 201103L
419238fd1498Szrj       /**
419338fd1498Szrj        *  @brief  Append an initializer_list of characters.
419438fd1498Szrj        *  @param __l  The initializer_list of characters to append.
419538fd1498Szrj        *  @return  Reference to this string.
419638fd1498Szrj        */
419738fd1498Szrj       basic_string&
419838fd1498Szrj       append(initializer_list<_CharT> __l)
419938fd1498Szrj       { return this->append(__l.begin(), __l.size()); }
420038fd1498Szrj #endif // C++11
420138fd1498Szrj 
420238fd1498Szrj       /**
420338fd1498Szrj        *  @brief  Append a range of characters.
420438fd1498Szrj        *  @param __first  Iterator referencing the first character to append.
420538fd1498Szrj        *  @param __last  Iterator marking the end of the range.
420638fd1498Szrj        *  @return  Reference to this string.
420738fd1498Szrj        *
420838fd1498Szrj        *  Appends characters in the range [__first,__last) to this string.
420938fd1498Szrj        */
421038fd1498Szrj       template<class _InputIterator>
421138fd1498Szrj         basic_string&
421238fd1498Szrj         append(_InputIterator __first, _InputIterator __last)
421338fd1498Szrj         { return this->replace(_M_iend(), _M_iend(), __first, __last); }
421438fd1498Szrj 
421538fd1498Szrj #if __cplusplus > 201402L
421638fd1498Szrj       /**
421738fd1498Szrj        *  @brief  Append a string_view.
421838fd1498Szrj        *  @param __svt The object convertible to string_view to be appended.
421938fd1498Szrj        *  @return  Reference to this string.
422038fd1498Szrj        */
422138fd1498Szrj       template<typename _Tp>
422238fd1498Szrj 	_If_sv<_Tp, basic_string&>
422338fd1498Szrj 	append(const _Tp& __svt)
422438fd1498Szrj 	{
422538fd1498Szrj 	  __sv_type __sv = __svt;
422638fd1498Szrj 	  return this->append(__sv.data(), __sv.size());
422738fd1498Szrj 	}
422838fd1498Szrj 
422938fd1498Szrj       /**
423038fd1498Szrj        *  @brief  Append a range of characters from a string_view.
423138fd1498Szrj        *  @param __svt The object convertible to string_view to be appended
423238fd1498Szrj        *               from.
423338fd1498Szrj        *  @param __pos The position in the string_view to append from.
423438fd1498Szrj        *  @param __n   The number of characters to append from the string_view.
423538fd1498Szrj        *  @return  Reference to this string.
423638fd1498Szrj        */
423738fd1498Szrj       template<typename _Tp>
423838fd1498Szrj         _If_sv<_Tp, basic_string&>
423938fd1498Szrj 	append(const _Tp& __svt, size_type __pos, size_type __n = npos)
424038fd1498Szrj 	{
424138fd1498Szrj 	  __sv_type __sv = __svt;
424238fd1498Szrj 	  return append(__sv.data()
424338fd1498Szrj 			+ __sv._M_check(__pos, "basic_string::append"),
424438fd1498Szrj 			__sv._M_limit(__pos, __n));
424538fd1498Szrj 	}
424638fd1498Szrj #endif // C++17
424738fd1498Szrj 
424838fd1498Szrj       /**
424938fd1498Szrj        *  @brief  Append a single character.
425038fd1498Szrj        *  @param __c  Character to append.
425138fd1498Szrj        */
425238fd1498Szrj       void
425338fd1498Szrj       push_back(_CharT __c)
425438fd1498Szrj       {
425538fd1498Szrj 	const size_type __len = 1 + this->size();
425638fd1498Szrj 	if (__len > this->capacity() || _M_rep()->_M_is_shared())
425738fd1498Szrj 	  this->reserve(__len);
425838fd1498Szrj 	traits_type::assign(_M_data()[this->size()], __c);
425938fd1498Szrj 	_M_rep()->_M_set_length_and_sharable(__len);
426038fd1498Szrj       }
426138fd1498Szrj 
426238fd1498Szrj       /**
426338fd1498Szrj        *  @brief  Set value to contents of another string.
426438fd1498Szrj        *  @param  __str  Source string to use.
426538fd1498Szrj        *  @return  Reference to this string.
426638fd1498Szrj        */
426738fd1498Szrj       basic_string&
426838fd1498Szrj       assign(const basic_string& __str);
426938fd1498Szrj 
427038fd1498Szrj #if __cplusplus >= 201103L
427138fd1498Szrj       /**
427238fd1498Szrj        *  @brief  Set value to contents of another string.
427338fd1498Szrj        *  @param  __str  Source string to use.
427438fd1498Szrj        *  @return  Reference to this string.
427538fd1498Szrj        *
427638fd1498Szrj        *  This function sets this string to the exact contents of @a __str.
427738fd1498Szrj        *  @a __str is a valid, but unspecified string.
427838fd1498Szrj        */
427938fd1498Szrj       // PR 58265, this should be noexcept.
428038fd1498Szrj       basic_string&
428138fd1498Szrj       assign(basic_string&& __str)
428238fd1498Szrj       {
428338fd1498Szrj 	this->swap(__str);
428438fd1498Szrj 	return *this;
428538fd1498Szrj       }
428638fd1498Szrj #endif // C++11
428738fd1498Szrj 
428838fd1498Szrj       /**
428938fd1498Szrj        *  @brief  Set value to a substring of a string.
429038fd1498Szrj        *  @param __str  The string to use.
429138fd1498Szrj        *  @param __pos  Index of the first character of str.
429238fd1498Szrj        *  @param __n  Number of characters to use.
429338fd1498Szrj        *  @return  Reference to this string.
429438fd1498Szrj        *  @throw  std::out_of_range if @a pos is not a valid index.
429538fd1498Szrj        *
429638fd1498Szrj        *  This function sets this string to the substring of @a __str
429738fd1498Szrj        *  consisting of @a __n characters at @a __pos.  If @a __n is
429838fd1498Szrj        *  is larger than the number of available characters in @a
429938fd1498Szrj        *  __str, the remainder of @a __str is used.
430038fd1498Szrj        */
430138fd1498Szrj       basic_string&
4302*58e805e6Szrj       assign(const basic_string& __str, size_type __pos, size_type __n = npos)
430338fd1498Szrj       { return this->assign(__str._M_data()
430438fd1498Szrj 			    + __str._M_check(__pos, "basic_string::assign"),
430538fd1498Szrj 			    __str._M_limit(__pos, __n)); }
430638fd1498Szrj 
430738fd1498Szrj       /**
430838fd1498Szrj        *  @brief  Set value to a C substring.
430938fd1498Szrj        *  @param __s  The C string to use.
431038fd1498Szrj        *  @param __n  Number of characters to use.
431138fd1498Szrj        *  @return  Reference to this string.
431238fd1498Szrj        *
431338fd1498Szrj        *  This function sets the value of this string to the first @a __n
431438fd1498Szrj        *  characters of @a __s.  If @a __n is is larger than the number of
431538fd1498Szrj        *  available characters in @a __s, the remainder of @a __s is used.
431638fd1498Szrj        */
431738fd1498Szrj       basic_string&
431838fd1498Szrj       assign(const _CharT* __s, size_type __n);
431938fd1498Szrj 
432038fd1498Szrj       /**
432138fd1498Szrj        *  @brief  Set value to contents of a C string.
432238fd1498Szrj        *  @param __s  The C string to use.
432338fd1498Szrj        *  @return  Reference to this string.
432438fd1498Szrj        *
432538fd1498Szrj        *  This function sets the value of this string to the value of @a __s.
432638fd1498Szrj        *  The data is copied, so there is no dependence on @a __s once the
432738fd1498Szrj        *  function returns.
432838fd1498Szrj        */
432938fd1498Szrj       basic_string&
433038fd1498Szrj       assign(const _CharT* __s)
433138fd1498Szrj       {
433238fd1498Szrj 	__glibcxx_requires_string(__s);
433338fd1498Szrj 	return this->assign(__s, traits_type::length(__s));
433438fd1498Szrj       }
433538fd1498Szrj 
433638fd1498Szrj       /**
433738fd1498Szrj        *  @brief  Set value to multiple characters.
433838fd1498Szrj        *  @param __n  Length of the resulting string.
433938fd1498Szrj        *  @param __c  The character to use.
434038fd1498Szrj        *  @return  Reference to this string.
434138fd1498Szrj        *
434238fd1498Szrj        *  This function sets the value of this string to @a __n copies of
434338fd1498Szrj        *  character @a __c.
434438fd1498Szrj        */
434538fd1498Szrj       basic_string&
434638fd1498Szrj       assign(size_type __n, _CharT __c)
434738fd1498Szrj       { return _M_replace_aux(size_type(0), this->size(), __n, __c); }
434838fd1498Szrj 
434938fd1498Szrj       /**
435038fd1498Szrj        *  @brief  Set value to a range of characters.
435138fd1498Szrj        *  @param __first  Iterator referencing the first character to append.
435238fd1498Szrj        *  @param __last  Iterator marking the end of the range.
435338fd1498Szrj        *  @return  Reference to this string.
435438fd1498Szrj        *
435538fd1498Szrj        *  Sets value of string to characters in the range [__first,__last).
435638fd1498Szrj       */
435738fd1498Szrj       template<class _InputIterator>
435838fd1498Szrj         basic_string&
435938fd1498Szrj         assign(_InputIterator __first, _InputIterator __last)
436038fd1498Szrj         { return this->replace(_M_ibegin(), _M_iend(), __first, __last); }
436138fd1498Szrj 
436238fd1498Szrj #if __cplusplus >= 201103L
436338fd1498Szrj       /**
436438fd1498Szrj        *  @brief  Set value to an initializer_list of characters.
436538fd1498Szrj        *  @param __l  The initializer_list of characters to assign.
436638fd1498Szrj        *  @return  Reference to this string.
436738fd1498Szrj        */
436838fd1498Szrj       basic_string&
436938fd1498Szrj       assign(initializer_list<_CharT> __l)
437038fd1498Szrj       { return this->assign(__l.begin(), __l.size()); }
437138fd1498Szrj #endif // C++11
437238fd1498Szrj 
437338fd1498Szrj #if __cplusplus > 201402L
437438fd1498Szrj       /**
437538fd1498Szrj        *  @brief  Set value from a string_view.
437638fd1498Szrj        *  @param __svt The source object convertible to string_view.
437738fd1498Szrj        *  @return  Reference to this string.
437838fd1498Szrj        */
437938fd1498Szrj       template<typename _Tp>
438038fd1498Szrj 	_If_sv<_Tp, basic_string&>
438138fd1498Szrj 	assign(const _Tp& __svt)
438238fd1498Szrj 	{
438338fd1498Szrj 	  __sv_type __sv = __svt;
438438fd1498Szrj 	  return this->assign(__sv.data(), __sv.size());
438538fd1498Szrj 	}
438638fd1498Szrj 
438738fd1498Szrj       /**
438838fd1498Szrj        *  @brief  Set value from a range of characters in a string_view.
438938fd1498Szrj        *  @param __svt  The source object convertible to string_view.
439038fd1498Szrj        *  @param __pos  The position in the string_view to assign from.
439138fd1498Szrj        *  @param __n  The number of characters to assign.
439238fd1498Szrj        *  @return  Reference to this string.
439338fd1498Szrj        */
439438fd1498Szrj       template<typename _Tp>
439538fd1498Szrj         _If_sv<_Tp, basic_string&>
439638fd1498Szrj         assign(const _Tp& __svt, size_type __pos, size_type __n = npos)
439738fd1498Szrj 	{
439838fd1498Szrj 	  __sv_type __sv = __svt;
439938fd1498Szrj 	  return assign(__sv.data()
440038fd1498Szrj 			+ __sv._M_check(__pos, "basic_string::assign"),
440138fd1498Szrj 			__sv._M_limit(__pos, __n));
440238fd1498Szrj 	}
440338fd1498Szrj #endif // C++17
440438fd1498Szrj 
440538fd1498Szrj       /**
440638fd1498Szrj        *  @brief  Insert multiple characters.
440738fd1498Szrj        *  @param __p  Iterator referencing location in string to insert at.
440838fd1498Szrj        *  @param __n  Number of characters to insert
440938fd1498Szrj        *  @param __c  The character to insert.
441038fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
441138fd1498Szrj        *
441238fd1498Szrj        *  Inserts @a __n copies of character @a __c starting at the
441338fd1498Szrj        *  position referenced by iterator @a __p.  If adding
441438fd1498Szrj        *  characters causes the length to exceed max_size(),
441538fd1498Szrj        *  length_error is thrown.  The value of the string doesn't
441638fd1498Szrj        *  change if an error is thrown.
441738fd1498Szrj       */
441838fd1498Szrj       void
441938fd1498Szrj       insert(iterator __p, size_type __n, _CharT __c)
442038fd1498Szrj       {	this->replace(__p, __p, __n, __c);  }
442138fd1498Szrj 
442238fd1498Szrj       /**
442338fd1498Szrj        *  @brief  Insert a range of characters.
442438fd1498Szrj        *  @param __p  Iterator referencing location in string to insert at.
442538fd1498Szrj        *  @param __beg  Start of range.
442638fd1498Szrj        *  @param __end  End of range.
442738fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
442838fd1498Szrj        *
442938fd1498Szrj        *  Inserts characters in range [__beg,__end).  If adding
443038fd1498Szrj        *  characters causes the length to exceed max_size(),
443138fd1498Szrj        *  length_error is thrown.  The value of the string doesn't
443238fd1498Szrj        *  change if an error is thrown.
443338fd1498Szrj       */
443438fd1498Szrj       template<class _InputIterator>
443538fd1498Szrj         void
443638fd1498Szrj         insert(iterator __p, _InputIterator __beg, _InputIterator __end)
443738fd1498Szrj         { this->replace(__p, __p, __beg, __end); }
443838fd1498Szrj 
443938fd1498Szrj #if __cplusplus >= 201103L
444038fd1498Szrj       /**
444138fd1498Szrj        *  @brief  Insert an initializer_list of characters.
444238fd1498Szrj        *  @param __p  Iterator referencing location in string to insert at.
444338fd1498Szrj        *  @param __l  The initializer_list of characters to insert.
444438fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
444538fd1498Szrj        */
444638fd1498Szrj       void
444738fd1498Szrj       insert(iterator __p, initializer_list<_CharT> __l)
444838fd1498Szrj       {
444938fd1498Szrj 	_GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend());
445038fd1498Szrj 	this->insert(__p - _M_ibegin(), __l.begin(), __l.size());
445138fd1498Szrj       }
445238fd1498Szrj #endif // C++11
445338fd1498Szrj 
445438fd1498Szrj       /**
445538fd1498Szrj        *  @brief  Insert value of a string.
445638fd1498Szrj        *  @param __pos1  Iterator referencing location in string to insert at.
445738fd1498Szrj        *  @param __str  The string to insert.
445838fd1498Szrj        *  @return  Reference to this string.
445938fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
446038fd1498Szrj        *
446138fd1498Szrj        *  Inserts value of @a __str starting at @a __pos1.  If adding
446238fd1498Szrj        *  characters causes the length to exceed max_size(),
446338fd1498Szrj        *  length_error is thrown.  The value of the string doesn't
446438fd1498Szrj        *  change if an error is thrown.
446538fd1498Szrj       */
446638fd1498Szrj       basic_string&
446738fd1498Szrj       insert(size_type __pos1, const basic_string& __str)
446838fd1498Szrj       { return this->insert(__pos1, __str, size_type(0), __str.size()); }
446938fd1498Szrj 
447038fd1498Szrj       /**
447138fd1498Szrj        *  @brief  Insert a substring.
447238fd1498Szrj        *  @param __pos1  Iterator referencing location in string to insert at.
447338fd1498Szrj        *  @param __str  The string to insert.
447438fd1498Szrj        *  @param __pos2  Start of characters in str to insert.
447538fd1498Szrj        *  @param __n  Number of characters to insert.
447638fd1498Szrj        *  @return  Reference to this string.
447738fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
447838fd1498Szrj        *  @throw  std::out_of_range  If @a pos1 > size() or
447938fd1498Szrj        *  @a __pos2 > @a str.size().
448038fd1498Szrj        *
448138fd1498Szrj        *  Starting at @a pos1, insert @a __n character of @a __str
448238fd1498Szrj        *  beginning with @a __pos2.  If adding characters causes the
448338fd1498Szrj        *  length to exceed max_size(), length_error is thrown.  If @a
448438fd1498Szrj        *  __pos1 is beyond the end of this string or @a __pos2 is
448538fd1498Szrj        *  beyond the end of @a __str, out_of_range is thrown.  The
448638fd1498Szrj        *  value of the string doesn't change if an error is thrown.
448738fd1498Szrj       */
448838fd1498Szrj       basic_string&
448938fd1498Szrj       insert(size_type __pos1, const basic_string& __str,
4490*58e805e6Szrj 	     size_type __pos2, size_type __n = npos)
449138fd1498Szrj       { return this->insert(__pos1, __str._M_data()
449238fd1498Szrj 			    + __str._M_check(__pos2, "basic_string::insert"),
449338fd1498Szrj 			    __str._M_limit(__pos2, __n)); }
449438fd1498Szrj 
449538fd1498Szrj       /**
449638fd1498Szrj        *  @brief  Insert a C substring.
449738fd1498Szrj        *  @param __pos  Iterator referencing location in string to insert at.
449838fd1498Szrj        *  @param __s  The C string to insert.
449938fd1498Szrj        *  @param __n  The number of characters to insert.
450038fd1498Szrj        *  @return  Reference to this string.
450138fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
450238fd1498Szrj        *  @throw  std::out_of_range  If @a __pos is beyond the end of this
450338fd1498Szrj        *  string.
450438fd1498Szrj        *
450538fd1498Szrj        *  Inserts the first @a __n characters of @a __s starting at @a
450638fd1498Szrj        *  __pos.  If adding characters causes the length to exceed
450738fd1498Szrj        *  max_size(), length_error is thrown.  If @a __pos is beyond
450838fd1498Szrj        *  end(), out_of_range is thrown.  The value of the string
450938fd1498Szrj        *  doesn't change if an error is thrown.
451038fd1498Szrj       */
451138fd1498Szrj       basic_string&
451238fd1498Szrj       insert(size_type __pos, const _CharT* __s, size_type __n);
451338fd1498Szrj 
451438fd1498Szrj       /**
451538fd1498Szrj        *  @brief  Insert a C string.
451638fd1498Szrj        *  @param __pos  Iterator referencing location in string to insert at.
451738fd1498Szrj        *  @param __s  The C string to insert.
451838fd1498Szrj        *  @return  Reference to this string.
451938fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
452038fd1498Szrj        *  @throw  std::out_of_range  If @a pos is beyond the end of this
452138fd1498Szrj        *  string.
452238fd1498Szrj        *
452338fd1498Szrj        *  Inserts the first @a n characters of @a __s starting at @a __pos.  If
452438fd1498Szrj        *  adding characters causes the length to exceed max_size(),
452538fd1498Szrj        *  length_error is thrown.  If @a __pos is beyond end(), out_of_range is
452638fd1498Szrj        *  thrown.  The value of the string doesn't change if an error is
452738fd1498Szrj        *  thrown.
452838fd1498Szrj       */
452938fd1498Szrj       basic_string&
453038fd1498Szrj       insert(size_type __pos, const _CharT* __s)
453138fd1498Szrj       {
453238fd1498Szrj 	__glibcxx_requires_string(__s);
453338fd1498Szrj 	return this->insert(__pos, __s, traits_type::length(__s));
453438fd1498Szrj       }
453538fd1498Szrj 
453638fd1498Szrj       /**
453738fd1498Szrj        *  @brief  Insert multiple characters.
453838fd1498Szrj        *  @param __pos  Index in string to insert at.
453938fd1498Szrj        *  @param __n  Number of characters to insert
454038fd1498Szrj        *  @param __c  The character to insert.
454138fd1498Szrj        *  @return  Reference to this string.
454238fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
454338fd1498Szrj        *  @throw  std::out_of_range  If @a __pos is beyond the end of this
454438fd1498Szrj        *  string.
454538fd1498Szrj        *
454638fd1498Szrj        *  Inserts @a __n copies of character @a __c starting at index
454738fd1498Szrj        *  @a __pos.  If adding characters causes the length to exceed
454838fd1498Szrj        *  max_size(), length_error is thrown.  If @a __pos > length(),
454938fd1498Szrj        *  out_of_range is thrown.  The value of the string doesn't
455038fd1498Szrj        *  change if an error is thrown.
455138fd1498Szrj       */
455238fd1498Szrj       basic_string&
455338fd1498Szrj       insert(size_type __pos, size_type __n, _CharT __c)
455438fd1498Szrj       { return _M_replace_aux(_M_check(__pos, "basic_string::insert"),
455538fd1498Szrj 			      size_type(0), __n, __c); }
455638fd1498Szrj 
455738fd1498Szrj       /**
455838fd1498Szrj        *  @brief  Insert one character.
455938fd1498Szrj        *  @param __p  Iterator referencing position in string to insert at.
456038fd1498Szrj        *  @param __c  The character to insert.
456138fd1498Szrj        *  @return  Iterator referencing newly inserted char.
456238fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
456338fd1498Szrj        *
456438fd1498Szrj        *  Inserts character @a __c at position referenced by @a __p.
456538fd1498Szrj        *  If adding character causes the length to exceed max_size(),
456638fd1498Szrj        *  length_error is thrown.  If @a __p is beyond end of string,
456738fd1498Szrj        *  out_of_range is thrown.  The value of the string doesn't
456838fd1498Szrj        *  change if an error is thrown.
456938fd1498Szrj       */
457038fd1498Szrj       iterator
457138fd1498Szrj       insert(iterator __p, _CharT __c)
457238fd1498Szrj       {
457338fd1498Szrj 	_GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend());
457438fd1498Szrj 	const size_type __pos = __p - _M_ibegin();
457538fd1498Szrj 	_M_replace_aux(__pos, size_type(0), size_type(1), __c);
457638fd1498Szrj 	_M_rep()->_M_set_leaked();
457738fd1498Szrj 	return iterator(_M_data() + __pos);
457838fd1498Szrj       }
457938fd1498Szrj 
458038fd1498Szrj #if __cplusplus > 201402L
458138fd1498Szrj       /**
458238fd1498Szrj        *  @brief  Insert a string_view.
458338fd1498Szrj        *  @param __pos  Iterator referencing position in string to insert at.
458438fd1498Szrj        *  @param __svt  The object convertible to string_view to insert.
458538fd1498Szrj        *  @return  Reference to this string.
458638fd1498Szrj       */
458738fd1498Szrj       template<typename _Tp>
458838fd1498Szrj 	_If_sv<_Tp, basic_string&>
458938fd1498Szrj 	insert(size_type __pos, const _Tp& __svt)
459038fd1498Szrj 	{
459138fd1498Szrj 	  __sv_type __sv = __svt;
459238fd1498Szrj 	  return this->insert(__pos, __sv.data(), __sv.size());
459338fd1498Szrj 	}
459438fd1498Szrj 
459538fd1498Szrj       /**
459638fd1498Szrj        *  @brief  Insert a string_view.
459738fd1498Szrj        *  @param __pos  Iterator referencing position in string to insert at.
459838fd1498Szrj        *  @param __svt  The object convertible to string_view to insert from.
459938fd1498Szrj        *  @param __pos  Iterator referencing position in string_view to insert
460038fd1498Szrj        *  from.
460138fd1498Szrj        *  @param __n    The number of characters to insert.
460238fd1498Szrj        *  @return  Reference to this string.
460338fd1498Szrj       */
460438fd1498Szrj       template<typename _Tp>
460538fd1498Szrj         _If_sv<_Tp, basic_string&>
460638fd1498Szrj         insert(size_type __pos1, const _Tp& __svt,
460738fd1498Szrj 	       size_type __pos2, size_type __n = npos)
460838fd1498Szrj 	{
460938fd1498Szrj 	  __sv_type __sv = __svt;
461038fd1498Szrj 	  return this->replace(__pos1, size_type(0), __sv.data()
461138fd1498Szrj 			       + __sv._M_check(__pos2, "basic_string::insert"),
461238fd1498Szrj 			       __sv._M_limit(__pos2, __n));
461338fd1498Szrj 	}
461438fd1498Szrj #endif // C++17
461538fd1498Szrj 
461638fd1498Szrj       /**
461738fd1498Szrj        *  @brief  Remove characters.
461838fd1498Szrj        *  @param __pos  Index of first character to remove (default 0).
461938fd1498Szrj        *  @param __n  Number of characters to remove (default remainder).
462038fd1498Szrj        *  @return  Reference to this string.
462138fd1498Szrj        *  @throw  std::out_of_range  If @a pos is beyond the end of this
462238fd1498Szrj        *  string.
462338fd1498Szrj        *
462438fd1498Szrj        *  Removes @a __n characters from this string starting at @a
462538fd1498Szrj        *  __pos.  The length of the string is reduced by @a __n.  If
462638fd1498Szrj        *  there are < @a __n characters to remove, the remainder of
462738fd1498Szrj        *  the string is truncated.  If @a __p is beyond end of string,
462838fd1498Szrj        *  out_of_range is thrown.  The value of the string doesn't
462938fd1498Szrj        *  change if an error is thrown.
463038fd1498Szrj       */
463138fd1498Szrj       basic_string&
463238fd1498Szrj       erase(size_type __pos = 0, size_type __n = npos)
463338fd1498Szrj       {
463438fd1498Szrj 	_M_mutate(_M_check(__pos, "basic_string::erase"),
463538fd1498Szrj 		  _M_limit(__pos, __n), size_type(0));
463638fd1498Szrj 	return *this;
463738fd1498Szrj       }
463838fd1498Szrj 
463938fd1498Szrj       /**
464038fd1498Szrj        *  @brief  Remove one character.
464138fd1498Szrj        *  @param __position  Iterator referencing the character to remove.
464238fd1498Szrj        *  @return  iterator referencing same location after removal.
464338fd1498Szrj        *
464438fd1498Szrj        *  Removes the character at @a __position from this string. The value
464538fd1498Szrj        *  of the string doesn't change if an error is thrown.
464638fd1498Szrj       */
464738fd1498Szrj       iterator
464838fd1498Szrj       erase(iterator __position)
464938fd1498Szrj       {
465038fd1498Szrj 	_GLIBCXX_DEBUG_PEDASSERT(__position >= _M_ibegin()
465138fd1498Szrj 				 && __position < _M_iend());
465238fd1498Szrj 	const size_type __pos = __position - _M_ibegin();
465338fd1498Szrj 	_M_mutate(__pos, size_type(1), size_type(0));
465438fd1498Szrj 	_M_rep()->_M_set_leaked();
465538fd1498Szrj 	return iterator(_M_data() + __pos);
465638fd1498Szrj       }
465738fd1498Szrj 
465838fd1498Szrj       /**
465938fd1498Szrj        *  @brief  Remove a range of characters.
466038fd1498Szrj        *  @param __first  Iterator referencing the first character to remove.
466138fd1498Szrj        *  @param __last  Iterator referencing the end of the range.
466238fd1498Szrj        *  @return  Iterator referencing location of first after removal.
466338fd1498Szrj        *
466438fd1498Szrj        *  Removes the characters in the range [first,last) from this string.
466538fd1498Szrj        *  The value of the string doesn't change if an error is thrown.
466638fd1498Szrj       */
466738fd1498Szrj       iterator
466838fd1498Szrj       erase(iterator __first, iterator __last);
466938fd1498Szrj 
467038fd1498Szrj #if __cplusplus >= 201103L
467138fd1498Szrj       /**
467238fd1498Szrj        *  @brief  Remove the last character.
467338fd1498Szrj        *
467438fd1498Szrj        *  The string must be non-empty.
467538fd1498Szrj        */
467638fd1498Szrj       void
467738fd1498Szrj       pop_back() // FIXME C++11: should be noexcept.
467838fd1498Szrj       {
467938fd1498Szrj 	__glibcxx_assert(!empty());
468038fd1498Szrj 	erase(size() - 1, 1);
468138fd1498Szrj       }
468238fd1498Szrj #endif // C++11
468338fd1498Szrj 
468438fd1498Szrj       /**
468538fd1498Szrj        *  @brief  Replace characters with value from another string.
468638fd1498Szrj        *  @param __pos  Index of first character to replace.
468738fd1498Szrj        *  @param __n  Number of characters to be replaced.
468838fd1498Szrj        *  @param __str  String to insert.
468938fd1498Szrj        *  @return  Reference to this string.
469038fd1498Szrj        *  @throw  std::out_of_range  If @a pos is beyond the end of this
469138fd1498Szrj        *  string.
469238fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
469338fd1498Szrj        *
469438fd1498Szrj        *  Removes the characters in the range [__pos,__pos+__n) from
469538fd1498Szrj        *  this string.  In place, the value of @a __str is inserted.
469638fd1498Szrj        *  If @a __pos is beyond end of string, out_of_range is thrown.
469738fd1498Szrj        *  If the length of the result exceeds max_size(), length_error
469838fd1498Szrj        *  is thrown.  The value of the string doesn't change if an
469938fd1498Szrj        *  error is thrown.
470038fd1498Szrj       */
470138fd1498Szrj       basic_string&
470238fd1498Szrj       replace(size_type __pos, size_type __n, const basic_string& __str)
470338fd1498Szrj       { return this->replace(__pos, __n, __str._M_data(), __str.size()); }
470438fd1498Szrj 
470538fd1498Szrj       /**
470638fd1498Szrj        *  @brief  Replace characters with value from another string.
470738fd1498Szrj        *  @param __pos1  Index of first character to replace.
470838fd1498Szrj        *  @param __n1  Number of characters to be replaced.
470938fd1498Szrj        *  @param __str  String to insert.
471038fd1498Szrj        *  @param __pos2  Index of first character of str to use.
471138fd1498Szrj        *  @param __n2  Number of characters from str to use.
471238fd1498Szrj        *  @return  Reference to this string.
471338fd1498Szrj        *  @throw  std::out_of_range  If @a __pos1 > size() or @a __pos2 >
471438fd1498Szrj        *  __str.size().
471538fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
471638fd1498Szrj        *
471738fd1498Szrj        *  Removes the characters in the range [__pos1,__pos1 + n) from this
471838fd1498Szrj        *  string.  In place, the value of @a __str is inserted.  If @a __pos is
471938fd1498Szrj        *  beyond end of string, out_of_range is thrown.  If the length of the
472038fd1498Szrj        *  result exceeds max_size(), length_error is thrown.  The value of the
472138fd1498Szrj        *  string doesn't change if an error is thrown.
472238fd1498Szrj       */
472338fd1498Szrj       basic_string&
472438fd1498Szrj       replace(size_type __pos1, size_type __n1, const basic_string& __str,
4725*58e805e6Szrj 	      size_type __pos2, size_type __n2 = npos)
472638fd1498Szrj       { return this->replace(__pos1, __n1, __str._M_data()
472738fd1498Szrj 			     + __str._M_check(__pos2, "basic_string::replace"),
472838fd1498Szrj 			     __str._M_limit(__pos2, __n2)); }
472938fd1498Szrj 
473038fd1498Szrj       /**
473138fd1498Szrj        *  @brief  Replace characters with value of a C substring.
473238fd1498Szrj        *  @param __pos  Index of first character to replace.
473338fd1498Szrj        *  @param __n1  Number of characters to be replaced.
473438fd1498Szrj        *  @param __s  C string to insert.
473538fd1498Szrj        *  @param __n2  Number of characters from @a s to use.
473638fd1498Szrj        *  @return  Reference to this string.
473738fd1498Szrj        *  @throw  std::out_of_range  If @a pos1 > size().
473838fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
473938fd1498Szrj        *
474038fd1498Szrj        *  Removes the characters in the range [__pos,__pos + __n1)
474138fd1498Szrj        *  from this string.  In place, the first @a __n2 characters of
474238fd1498Szrj        *  @a __s are inserted, or all of @a __s if @a __n2 is too large.  If
474338fd1498Szrj        *  @a __pos is beyond end of string, out_of_range is thrown.  If
474438fd1498Szrj        *  the length of result exceeds max_size(), length_error is
474538fd1498Szrj        *  thrown.  The value of the string doesn't change if an error
474638fd1498Szrj        *  is thrown.
474738fd1498Szrj       */
474838fd1498Szrj       basic_string&
474938fd1498Szrj       replace(size_type __pos, size_type __n1, const _CharT* __s,
475038fd1498Szrj 	      size_type __n2);
475138fd1498Szrj 
475238fd1498Szrj       /**
475338fd1498Szrj        *  @brief  Replace characters with value of a C string.
475438fd1498Szrj        *  @param __pos  Index of first character to replace.
475538fd1498Szrj        *  @param __n1  Number of characters to be replaced.
475638fd1498Szrj        *  @param __s  C string to insert.
475738fd1498Szrj        *  @return  Reference to this string.
475838fd1498Szrj        *  @throw  std::out_of_range  If @a pos > size().
475938fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
476038fd1498Szrj        *
476138fd1498Szrj        *  Removes the characters in the range [__pos,__pos + __n1)
476238fd1498Szrj        *  from this string.  In place, the characters of @a __s are
476338fd1498Szrj        *  inserted.  If @a __pos is beyond end of string, out_of_range
476438fd1498Szrj        *  is thrown.  If the length of result exceeds max_size(),
476538fd1498Szrj        *  length_error is thrown.  The value of the string doesn't
476638fd1498Szrj        *  change if an error is thrown.
476738fd1498Szrj       */
476838fd1498Szrj       basic_string&
476938fd1498Szrj       replace(size_type __pos, size_type __n1, const _CharT* __s)
477038fd1498Szrj       {
477138fd1498Szrj 	__glibcxx_requires_string(__s);
477238fd1498Szrj 	return this->replace(__pos, __n1, __s, traits_type::length(__s));
477338fd1498Szrj       }
477438fd1498Szrj 
477538fd1498Szrj       /**
477638fd1498Szrj        *  @brief  Replace characters with multiple characters.
477738fd1498Szrj        *  @param __pos  Index of first character to replace.
477838fd1498Szrj        *  @param __n1  Number of characters to be replaced.
477938fd1498Szrj        *  @param __n2  Number of characters to insert.
478038fd1498Szrj        *  @param __c  Character to insert.
478138fd1498Szrj        *  @return  Reference to this string.
478238fd1498Szrj        *  @throw  std::out_of_range  If @a __pos > size().
478338fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
478438fd1498Szrj        *
478538fd1498Szrj        *  Removes the characters in the range [pos,pos + n1) from this
478638fd1498Szrj        *  string.  In place, @a __n2 copies of @a __c are inserted.
478738fd1498Szrj        *  If @a __pos is beyond end of string, out_of_range is thrown.
478838fd1498Szrj        *  If the length of result exceeds max_size(), length_error is
478938fd1498Szrj        *  thrown.  The value of the string doesn't change if an error
479038fd1498Szrj        *  is thrown.
479138fd1498Szrj       */
479238fd1498Szrj       basic_string&
479338fd1498Szrj       replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
479438fd1498Szrj       { return _M_replace_aux(_M_check(__pos, "basic_string::replace"),
479538fd1498Szrj 			      _M_limit(__pos, __n1), __n2, __c); }
479638fd1498Szrj 
479738fd1498Szrj       /**
479838fd1498Szrj        *  @brief  Replace range of characters with string.
479938fd1498Szrj        *  @param __i1  Iterator referencing start of range to replace.
480038fd1498Szrj        *  @param __i2  Iterator referencing end of range to replace.
480138fd1498Szrj        *  @param __str  String value to insert.
480238fd1498Szrj        *  @return  Reference to this string.
480338fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
480438fd1498Szrj        *
480538fd1498Szrj        *  Removes the characters in the range [__i1,__i2).  In place,
480638fd1498Szrj        *  the value of @a __str is inserted.  If the length of result
480738fd1498Szrj        *  exceeds max_size(), length_error is thrown.  The value of
480838fd1498Szrj        *  the string doesn't change if an error is thrown.
480938fd1498Szrj       */
481038fd1498Szrj       basic_string&
481138fd1498Szrj       replace(iterator __i1, iterator __i2, const basic_string& __str)
481238fd1498Szrj       { return this->replace(__i1, __i2, __str._M_data(), __str.size()); }
481338fd1498Szrj 
481438fd1498Szrj       /**
481538fd1498Szrj        *  @brief  Replace range of characters with C substring.
481638fd1498Szrj        *  @param __i1  Iterator referencing start of range to replace.
481738fd1498Szrj        *  @param __i2  Iterator referencing end of range to replace.
481838fd1498Szrj        *  @param __s  C string value to insert.
481938fd1498Szrj        *  @param __n  Number of characters from s to insert.
482038fd1498Szrj        *  @return  Reference to this string.
482138fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
482238fd1498Szrj        *
482338fd1498Szrj        *  Removes the characters in the range [__i1,__i2).  In place,
482438fd1498Szrj        *  the first @a __n characters of @a __s are inserted.  If the
482538fd1498Szrj        *  length of result exceeds max_size(), length_error is thrown.
482638fd1498Szrj        *  The value of the string doesn't change if an error is
482738fd1498Szrj        *  thrown.
482838fd1498Szrj       */
482938fd1498Szrj       basic_string&
483038fd1498Szrj       replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n)
483138fd1498Szrj       {
483238fd1498Szrj 	_GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
483338fd1498Szrj 				 && __i2 <= _M_iend());
483438fd1498Szrj 	return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n);
483538fd1498Szrj       }
483638fd1498Szrj 
483738fd1498Szrj       /**
483838fd1498Szrj        *  @brief  Replace range of characters with C string.
483938fd1498Szrj        *  @param __i1  Iterator referencing start of range to replace.
484038fd1498Szrj        *  @param __i2  Iterator referencing end of range to replace.
484138fd1498Szrj        *  @param __s  C string value to insert.
484238fd1498Szrj        *  @return  Reference to this string.
484338fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
484438fd1498Szrj        *
484538fd1498Szrj        *  Removes the characters in the range [__i1,__i2).  In place,
484638fd1498Szrj        *  the characters of @a __s are inserted.  If the length of
484738fd1498Szrj        *  result exceeds max_size(), length_error is thrown.  The
484838fd1498Szrj        *  value of the string doesn't change if an error is thrown.
484938fd1498Szrj       */
485038fd1498Szrj       basic_string&
485138fd1498Szrj       replace(iterator __i1, iterator __i2, const _CharT* __s)
485238fd1498Szrj       {
485338fd1498Szrj 	__glibcxx_requires_string(__s);
485438fd1498Szrj 	return this->replace(__i1, __i2, __s, traits_type::length(__s));
485538fd1498Szrj       }
485638fd1498Szrj 
485738fd1498Szrj       /**
485838fd1498Szrj        *  @brief  Replace range of characters with multiple characters
485938fd1498Szrj        *  @param __i1  Iterator referencing start of range to replace.
486038fd1498Szrj        *  @param __i2  Iterator referencing end of range to replace.
486138fd1498Szrj        *  @param __n  Number of characters to insert.
486238fd1498Szrj        *  @param __c  Character to insert.
486338fd1498Szrj        *  @return  Reference to this string.
486438fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
486538fd1498Szrj        *
486638fd1498Szrj        *  Removes the characters in the range [__i1,__i2).  In place,
486738fd1498Szrj        *  @a __n copies of @a __c are inserted.  If the length of
486838fd1498Szrj        *  result exceeds max_size(), length_error is thrown.  The
486938fd1498Szrj        *  value of the string doesn't change if an error is thrown.
487038fd1498Szrj       */
487138fd1498Szrj       basic_string&
487238fd1498Szrj       replace(iterator __i1, iterator __i2, size_type __n, _CharT __c)
487338fd1498Szrj       {
487438fd1498Szrj 	_GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
487538fd1498Szrj 				 && __i2 <= _M_iend());
487638fd1498Szrj 	return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __c);
487738fd1498Szrj       }
487838fd1498Szrj 
487938fd1498Szrj       /**
488038fd1498Szrj        *  @brief  Replace range of characters with range.
488138fd1498Szrj        *  @param __i1  Iterator referencing start of range to replace.
488238fd1498Szrj        *  @param __i2  Iterator referencing end of range to replace.
488338fd1498Szrj        *  @param __k1  Iterator referencing start of range to insert.
488438fd1498Szrj        *  @param __k2  Iterator referencing end of range to insert.
488538fd1498Szrj        *  @return  Reference to this string.
488638fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
488738fd1498Szrj        *
488838fd1498Szrj        *  Removes the characters in the range [__i1,__i2).  In place,
488938fd1498Szrj        *  characters in the range [__k1,__k2) are inserted.  If the
489038fd1498Szrj        *  length of result exceeds max_size(), length_error is thrown.
489138fd1498Szrj        *  The value of the string doesn't change if an error is
489238fd1498Szrj        *  thrown.
489338fd1498Szrj       */
489438fd1498Szrj       template<class _InputIterator>
489538fd1498Szrj         basic_string&
489638fd1498Szrj         replace(iterator __i1, iterator __i2,
489738fd1498Szrj 		_InputIterator __k1, _InputIterator __k2)
489838fd1498Szrj         {
489938fd1498Szrj 	  _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
490038fd1498Szrj 				   && __i2 <= _M_iend());
490138fd1498Szrj 	  __glibcxx_requires_valid_range(__k1, __k2);
490238fd1498Szrj 	  typedef typename std::__is_integer<_InputIterator>::__type _Integral;
490338fd1498Szrj 	  return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral());
490438fd1498Szrj 	}
490538fd1498Szrj 
490638fd1498Szrj       // Specializations for the common case of pointer and iterator:
490738fd1498Szrj       // useful to avoid the overhead of temporary buffering in _M_replace.
490838fd1498Szrj       basic_string&
490938fd1498Szrj       replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2)
491038fd1498Szrj       {
491138fd1498Szrj 	_GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
491238fd1498Szrj 				 && __i2 <= _M_iend());
491338fd1498Szrj 	__glibcxx_requires_valid_range(__k1, __k2);
491438fd1498Szrj 	return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
491538fd1498Szrj 			     __k1, __k2 - __k1);
491638fd1498Szrj       }
491738fd1498Szrj 
491838fd1498Szrj       basic_string&
491938fd1498Szrj       replace(iterator __i1, iterator __i2,
492038fd1498Szrj 	      const _CharT* __k1, const _CharT* __k2)
492138fd1498Szrj       {
492238fd1498Szrj 	_GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
492338fd1498Szrj 				 && __i2 <= _M_iend());
492438fd1498Szrj 	__glibcxx_requires_valid_range(__k1, __k2);
492538fd1498Szrj 	return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
492638fd1498Szrj 			     __k1, __k2 - __k1);
492738fd1498Szrj       }
492838fd1498Szrj 
492938fd1498Szrj       basic_string&
493038fd1498Szrj       replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2)
493138fd1498Szrj       {
493238fd1498Szrj 	_GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
493338fd1498Szrj 				 && __i2 <= _M_iend());
493438fd1498Szrj 	__glibcxx_requires_valid_range(__k1, __k2);
493538fd1498Szrj 	return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
493638fd1498Szrj 			     __k1.base(), __k2 - __k1);
493738fd1498Szrj       }
493838fd1498Szrj 
493938fd1498Szrj       basic_string&
494038fd1498Szrj       replace(iterator __i1, iterator __i2,
494138fd1498Szrj 	      const_iterator __k1, const_iterator __k2)
494238fd1498Szrj       {
494338fd1498Szrj 	_GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
494438fd1498Szrj 				 && __i2 <= _M_iend());
494538fd1498Szrj 	__glibcxx_requires_valid_range(__k1, __k2);
494638fd1498Szrj 	return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
494738fd1498Szrj 			     __k1.base(), __k2 - __k1);
494838fd1498Szrj       }
494938fd1498Szrj 
495038fd1498Szrj #if __cplusplus >= 201103L
495138fd1498Szrj       /**
495238fd1498Szrj        *  @brief  Replace range of characters with initializer_list.
495338fd1498Szrj        *  @param __i1  Iterator referencing start of range to replace.
495438fd1498Szrj        *  @param __i2  Iterator referencing end of range to replace.
495538fd1498Szrj        *  @param __l  The initializer_list of characters to insert.
495638fd1498Szrj        *  @return  Reference to this string.
495738fd1498Szrj        *  @throw  std::length_error  If new length exceeds @c max_size().
495838fd1498Szrj        *
495938fd1498Szrj        *  Removes the characters in the range [__i1,__i2).  In place,
496038fd1498Szrj        *  characters in the range [__k1,__k2) are inserted.  If the
496138fd1498Szrj        *  length of result exceeds max_size(), length_error is thrown.
496238fd1498Szrj        *  The value of the string doesn't change if an error is
496338fd1498Szrj        *  thrown.
496438fd1498Szrj       */
496538fd1498Szrj       basic_string& replace(iterator __i1, iterator __i2,
496638fd1498Szrj 			    initializer_list<_CharT> __l)
496738fd1498Szrj       { return this->replace(__i1, __i2, __l.begin(), __l.end()); }
496838fd1498Szrj #endif // C++11
496938fd1498Szrj 
497038fd1498Szrj #if __cplusplus > 201402L
497138fd1498Szrj       /**
497238fd1498Szrj        *  @brief  Replace range of characters with string_view.
497338fd1498Szrj        *  @param __pos  The position to replace at.
497438fd1498Szrj        *  @param __n    The number of characters to replace.
497538fd1498Szrj        *  @param __svt  The object convertible to string_view to insert.
497638fd1498Szrj        *  @return  Reference to this string.
497738fd1498Szrj       */
497838fd1498Szrj       template<typename _Tp>
497938fd1498Szrj 	_If_sv<_Tp, basic_string&>
498038fd1498Szrj 	replace(size_type __pos, size_type __n, const _Tp& __svt)
498138fd1498Szrj 	{
498238fd1498Szrj 	  __sv_type __sv = __svt;
498338fd1498Szrj 	  return this->replace(__pos, __n, __sv.data(), __sv.size());
498438fd1498Szrj 	}
498538fd1498Szrj 
498638fd1498Szrj       /**
498738fd1498Szrj        *  @brief  Replace range of characters with string_view.
498838fd1498Szrj        *  @param __pos1  The position to replace at.
498938fd1498Szrj        *  @param __n1    The number of characters to replace.
499038fd1498Szrj        *  @param __svt   The object convertible to string_view to insert from.
499138fd1498Szrj        *  @param __pos2  The position in the string_view to insert from.
499238fd1498Szrj        *  @param __n2    The number of characters to insert.
499338fd1498Szrj        *  @return  Reference to this string.
499438fd1498Szrj       */
499538fd1498Szrj       template<typename _Tp>
499638fd1498Szrj         _If_sv<_Tp, basic_string&>
499738fd1498Szrj         replace(size_type __pos1, size_type __n1, const _Tp& __svt,
499838fd1498Szrj 		size_type __pos2, size_type __n2 = npos)
499938fd1498Szrj 	{
500038fd1498Szrj 	  __sv_type __sv = __svt;
500138fd1498Szrj 	  return this->replace(__pos1, __n1,
500238fd1498Szrj 	      __sv.data() + __sv._M_check(__pos2, "basic_string::replace"),
500338fd1498Szrj 	      __sv._M_limit(__pos2, __n2));
500438fd1498Szrj 	}
500538fd1498Szrj 
500638fd1498Szrj       /**
500738fd1498Szrj        *  @brief  Replace range of characters with string_view.
500838fd1498Szrj        *  @param __i1    An iterator referencing the start position
500938fd1498Szrj           to replace at.
501038fd1498Szrj        *  @param __i2    An iterator referencing the end position
501138fd1498Szrj           for the replace.
501238fd1498Szrj        *  @param __svt   The object convertible to string_view to insert from.
501338fd1498Szrj        *  @return  Reference to this string.
501438fd1498Szrj       */
501538fd1498Szrj       template<typename _Tp>
501638fd1498Szrj 	_If_sv<_Tp, basic_string&>
501738fd1498Szrj 	replace(const_iterator __i1, const_iterator __i2, const _Tp& __svt)
501838fd1498Szrj 	{
501938fd1498Szrj 	  __sv_type __sv = __svt;
502038fd1498Szrj 	  return this->replace(__i1 - begin(), __i2 - __i1, __sv);
502138fd1498Szrj 	}
502238fd1498Szrj #endif // C++17
502338fd1498Szrj 
502438fd1498Szrj     private:
502538fd1498Szrj       template<class _Integer>
502638fd1498Szrj 	basic_string&
502738fd1498Szrj 	_M_replace_dispatch(iterator __i1, iterator __i2, _Integer __n,
502838fd1498Szrj 			    _Integer __val, __true_type)
502938fd1498Szrj         { return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __val); }
503038fd1498Szrj 
503138fd1498Szrj       template<class _InputIterator>
503238fd1498Szrj 	basic_string&
503338fd1498Szrj 	_M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1,
503438fd1498Szrj 			    _InputIterator __k2, __false_type);
503538fd1498Szrj 
503638fd1498Szrj       basic_string&
503738fd1498Szrj       _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
503838fd1498Szrj 		     _CharT __c);
503938fd1498Szrj 
504038fd1498Szrj       basic_string&
504138fd1498Szrj       _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s,
504238fd1498Szrj 		      size_type __n2);
504338fd1498Szrj 
504438fd1498Szrj       // _S_construct_aux is used to implement the 21.3.1 para 15 which
504538fd1498Szrj       // requires special behaviour if _InIter is an integral type
504638fd1498Szrj       template<class _InIterator>
504738fd1498Szrj         static _CharT*
504838fd1498Szrj         _S_construct_aux(_InIterator __beg, _InIterator __end,
504938fd1498Szrj 			 const _Alloc& __a, __false_type)
505038fd1498Szrj 	{
505138fd1498Szrj           typedef typename iterator_traits<_InIterator>::iterator_category _Tag;
505238fd1498Szrj           return _S_construct(__beg, __end, __a, _Tag());
505338fd1498Szrj 	}
505438fd1498Szrj 
505538fd1498Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
505638fd1498Szrj       // 438. Ambiguity in the "do the right thing" clause
505738fd1498Szrj       template<class _Integer>
505838fd1498Szrj         static _CharT*
505938fd1498Szrj         _S_construct_aux(_Integer __beg, _Integer __end,
506038fd1498Szrj 			 const _Alloc& __a, __true_type)
506138fd1498Szrj         { return _S_construct_aux_2(static_cast<size_type>(__beg),
506238fd1498Szrj 				    __end, __a); }
506338fd1498Szrj 
506438fd1498Szrj       static _CharT*
506538fd1498Szrj       _S_construct_aux_2(size_type __req, _CharT __c, const _Alloc& __a)
506638fd1498Szrj       { return _S_construct(__req, __c, __a); }
506738fd1498Szrj 
506838fd1498Szrj       template<class _InIterator>
506938fd1498Szrj         static _CharT*
507038fd1498Szrj         _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a)
507138fd1498Szrj 	{
507238fd1498Szrj 	  typedef typename std::__is_integer<_InIterator>::__type _Integral;
507338fd1498Szrj 	  return _S_construct_aux(__beg, __end, __a, _Integral());
507438fd1498Szrj         }
507538fd1498Szrj 
507638fd1498Szrj       // For Input Iterators, used in istreambuf_iterators, etc.
507738fd1498Szrj       template<class _InIterator>
507838fd1498Szrj         static _CharT*
507938fd1498Szrj          _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,
508038fd1498Szrj 		      input_iterator_tag);
508138fd1498Szrj 
508238fd1498Szrj       // For forward_iterators up to random_access_iterators, used for
508338fd1498Szrj       // string::iterator, _CharT*, etc.
508438fd1498Szrj       template<class _FwdIterator>
508538fd1498Szrj         static _CharT*
508638fd1498Szrj         _S_construct(_FwdIterator __beg, _FwdIterator __end, const _Alloc& __a,
508738fd1498Szrj 		     forward_iterator_tag);
508838fd1498Szrj 
508938fd1498Szrj       static _CharT*
509038fd1498Szrj       _S_construct(size_type __req, _CharT __c, const _Alloc& __a);
509138fd1498Szrj 
509238fd1498Szrj     public:
509338fd1498Szrj 
509438fd1498Szrj       /**
509538fd1498Szrj        *  @brief  Copy substring into C string.
509638fd1498Szrj        *  @param __s  C string to copy value into.
509738fd1498Szrj        *  @param __n  Number of characters to copy.
509838fd1498Szrj        *  @param __pos  Index of first character to copy.
509938fd1498Szrj        *  @return  Number of characters actually copied
510038fd1498Szrj        *  @throw  std::out_of_range  If __pos > size().
510138fd1498Szrj        *
510238fd1498Szrj        *  Copies up to @a __n characters starting at @a __pos into the
510338fd1498Szrj        *  C string @a __s.  If @a __pos is %greater than size(),
510438fd1498Szrj        *  out_of_range is thrown.
510538fd1498Szrj       */
510638fd1498Szrj       size_type
510738fd1498Szrj       copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
510838fd1498Szrj 
510938fd1498Szrj       /**
511038fd1498Szrj        *  @brief  Swap contents with another string.
511138fd1498Szrj        *  @param __s  String to swap with.
511238fd1498Szrj        *
511338fd1498Szrj        *  Exchanges the contents of this string with that of @a __s in constant
511438fd1498Szrj        *  time.
511538fd1498Szrj       */
511638fd1498Szrj       // PR 58265, this should be noexcept.
511738fd1498Szrj       void
511838fd1498Szrj       swap(basic_string& __s);
511938fd1498Szrj 
512038fd1498Szrj       // String operations:
512138fd1498Szrj       /**
512238fd1498Szrj        *  @brief  Return const pointer to null-terminated contents.
512338fd1498Szrj        *
512438fd1498Szrj        *  This is a handle to internal data.  Do not modify or dire things may
512538fd1498Szrj        *  happen.
512638fd1498Szrj       */
512738fd1498Szrj       const _CharT*
512838fd1498Szrj       c_str() const _GLIBCXX_NOEXCEPT
512938fd1498Szrj       { return _M_data(); }
513038fd1498Szrj 
513138fd1498Szrj       /**
513238fd1498Szrj        *  @brief  Return const pointer to contents.
513338fd1498Szrj        *
513438fd1498Szrj        *  This is a pointer to internal data.  It is undefined to modify
513538fd1498Szrj        *  the contents through the returned pointer. To get a pointer that
513638fd1498Szrj        *  allows modifying the contents use @c &str[0] instead,
513738fd1498Szrj        *  (or in C++17 the non-const @c str.data() overload).
513838fd1498Szrj       */
513938fd1498Szrj       const _CharT*
514038fd1498Szrj       data() const _GLIBCXX_NOEXCEPT
514138fd1498Szrj       { return _M_data(); }
514238fd1498Szrj 
514338fd1498Szrj #if __cplusplus > 201402L
514438fd1498Szrj       /**
514538fd1498Szrj        *  @brief  Return non-const pointer to contents.
514638fd1498Szrj        *
514738fd1498Szrj        *  This is a pointer to the character sequence held by the string.
514838fd1498Szrj        *  Modifying the characters in the sequence is allowed.
514938fd1498Szrj       */
515038fd1498Szrj       _CharT*
515138fd1498Szrj       data() noexcept
5152*58e805e6Szrj       {
5153*58e805e6Szrj 	_M_leak();
5154*58e805e6Szrj 	return _M_data();
5155*58e805e6Szrj       }
515638fd1498Szrj #endif
515738fd1498Szrj 
515838fd1498Szrj       /**
515938fd1498Szrj        *  @brief  Return copy of allocator used to construct this string.
516038fd1498Szrj       */
516138fd1498Szrj       allocator_type
516238fd1498Szrj       get_allocator() const _GLIBCXX_NOEXCEPT
516338fd1498Szrj       { return _M_dataplus; }
516438fd1498Szrj 
516538fd1498Szrj       /**
516638fd1498Szrj        *  @brief  Find position of a C substring.
516738fd1498Szrj        *  @param __s  C string to locate.
516838fd1498Szrj        *  @param __pos  Index of character to search from.
516938fd1498Szrj        *  @param __n  Number of characters from @a s to search for.
517038fd1498Szrj        *  @return  Index of start of first occurrence.
517138fd1498Szrj        *
517238fd1498Szrj        *  Starting from @a __pos, searches forward for the first @a
517338fd1498Szrj        *  __n characters in @a __s within this string.  If found,
517438fd1498Szrj        *  returns the index where it begins.  If not found, returns
517538fd1498Szrj        *  npos.
517638fd1498Szrj       */
517738fd1498Szrj       size_type
517838fd1498Szrj       find(const _CharT* __s, size_type __pos, size_type __n) const
517938fd1498Szrj       _GLIBCXX_NOEXCEPT;
518038fd1498Szrj 
518138fd1498Szrj       /**
518238fd1498Szrj        *  @brief  Find position of a string.
518338fd1498Szrj        *  @param __str  String to locate.
518438fd1498Szrj        *  @param __pos  Index of character to search from (default 0).
518538fd1498Szrj        *  @return  Index of start of first occurrence.
518638fd1498Szrj        *
518738fd1498Szrj        *  Starting from @a __pos, searches forward for value of @a __str within
518838fd1498Szrj        *  this string.  If found, returns the index where it begins.  If not
518938fd1498Szrj        *  found, returns npos.
519038fd1498Szrj       */
519138fd1498Szrj       size_type
519238fd1498Szrj       find(const basic_string& __str, size_type __pos = 0) const
519338fd1498Szrj       _GLIBCXX_NOEXCEPT
519438fd1498Szrj       { return this->find(__str.data(), __pos, __str.size()); }
519538fd1498Szrj 
519638fd1498Szrj       /**
519738fd1498Szrj        *  @brief  Find position of a C string.
519838fd1498Szrj        *  @param __s  C string to locate.
519938fd1498Szrj        *  @param __pos  Index of character to search from (default 0).
520038fd1498Szrj        *  @return  Index of start of first occurrence.
520138fd1498Szrj        *
520238fd1498Szrj        *  Starting from @a __pos, searches forward for the value of @a
520338fd1498Szrj        *  __s within this string.  If found, returns the index where
520438fd1498Szrj        *  it begins.  If not found, returns npos.
520538fd1498Szrj       */
520638fd1498Szrj       size_type
520738fd1498Szrj       find(const _CharT* __s, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
520838fd1498Szrj       {
520938fd1498Szrj 	__glibcxx_requires_string(__s);
521038fd1498Szrj 	return this->find(__s, __pos, traits_type::length(__s));
521138fd1498Szrj       }
521238fd1498Szrj 
521338fd1498Szrj       /**
521438fd1498Szrj        *  @brief  Find position of a character.
521538fd1498Szrj        *  @param __c  Character to locate.
521638fd1498Szrj        *  @param __pos  Index of character to search from (default 0).
521738fd1498Szrj        *  @return  Index of first occurrence.
521838fd1498Szrj        *
521938fd1498Szrj        *  Starting from @a __pos, searches forward for @a __c within
522038fd1498Szrj        *  this string.  If found, returns the index where it was
522138fd1498Szrj        *  found.  If not found, returns npos.
522238fd1498Szrj       */
522338fd1498Szrj       size_type
522438fd1498Szrj       find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT;
522538fd1498Szrj 
522638fd1498Szrj #if __cplusplus > 201402L
522738fd1498Szrj       /**
522838fd1498Szrj        *  @brief  Find position of a string_view.
522938fd1498Szrj        *  @param __svt  The object convertible to string_view to locate.
523038fd1498Szrj        *  @param __pos  Index of character to search from (default 0).
523138fd1498Szrj        *  @return  Index of start of first occurrence.
523238fd1498Szrj       */
523338fd1498Szrj       template<typename _Tp>
523438fd1498Szrj 	_If_sv<_Tp, size_type>
523538fd1498Szrj 	find(const _Tp& __svt, size_type __pos = 0) const
523638fd1498Szrj 	noexcept(is_same<_Tp, __sv_type>::value)
523738fd1498Szrj 	{
523838fd1498Szrj 	  __sv_type __sv = __svt;
523938fd1498Szrj 	  return this->find(__sv.data(), __pos, __sv.size());
524038fd1498Szrj 	}
524138fd1498Szrj #endif // C++17
524238fd1498Szrj 
524338fd1498Szrj       /**
524438fd1498Szrj        *  @brief  Find last position of a string.
524538fd1498Szrj        *  @param __str  String to locate.
524638fd1498Szrj        *  @param __pos  Index of character to search back from (default end).
524738fd1498Szrj        *  @return  Index of start of last occurrence.
524838fd1498Szrj        *
524938fd1498Szrj        *  Starting from @a __pos, searches backward for value of @a
525038fd1498Szrj        *  __str within this string.  If found, returns the index where
525138fd1498Szrj        *  it begins.  If not found, returns npos.
525238fd1498Szrj       */
525338fd1498Szrj       size_type
525438fd1498Szrj       rfind(const basic_string& __str, size_type __pos = npos) const
525538fd1498Szrj       _GLIBCXX_NOEXCEPT
525638fd1498Szrj       { return this->rfind(__str.data(), __pos, __str.size()); }
525738fd1498Szrj 
525838fd1498Szrj       /**
525938fd1498Szrj        *  @brief  Find last position of a C substring.
526038fd1498Szrj        *  @param __s  C string to locate.
526138fd1498Szrj        *  @param __pos  Index of character to search back from.
526238fd1498Szrj        *  @param __n  Number of characters from s to search for.
526338fd1498Szrj        *  @return  Index of start of last occurrence.
526438fd1498Szrj        *
526538fd1498Szrj        *  Starting from @a __pos, searches backward for the first @a
526638fd1498Szrj        *  __n characters in @a __s within this string.  If found,
526738fd1498Szrj        *  returns the index where it begins.  If not found, returns
526838fd1498Szrj        *  npos.
526938fd1498Szrj       */
527038fd1498Szrj       size_type
527138fd1498Szrj       rfind(const _CharT* __s, size_type __pos, size_type __n) const
527238fd1498Szrj       _GLIBCXX_NOEXCEPT;
527338fd1498Szrj 
527438fd1498Szrj       /**
527538fd1498Szrj        *  @brief  Find last position of a C string.
527638fd1498Szrj        *  @param __s  C string to locate.
527738fd1498Szrj        *  @param __pos  Index of character to start search at (default end).
527838fd1498Szrj        *  @return  Index of start of  last occurrence.
527938fd1498Szrj        *
528038fd1498Szrj        *  Starting from @a __pos, searches backward for the value of
528138fd1498Szrj        *  @a __s within this string.  If found, returns the index
528238fd1498Szrj        *  where it begins.  If not found, returns npos.
528338fd1498Szrj       */
528438fd1498Szrj       size_type
528538fd1498Szrj       rfind(const _CharT* __s, size_type __pos = npos) const _GLIBCXX_NOEXCEPT
528638fd1498Szrj       {
528738fd1498Szrj 	__glibcxx_requires_string(__s);
528838fd1498Szrj 	return this->rfind(__s, __pos, traits_type::length(__s));
528938fd1498Szrj       }
529038fd1498Szrj 
529138fd1498Szrj       /**
529238fd1498Szrj        *  @brief  Find last position of a character.
529338fd1498Szrj        *  @param __c  Character to locate.
529438fd1498Szrj        *  @param __pos  Index of character to search back from (default end).
529538fd1498Szrj        *  @return  Index of last occurrence.
529638fd1498Szrj        *
529738fd1498Szrj        *  Starting from @a __pos, searches backward for @a __c within
529838fd1498Szrj        *  this string.  If found, returns the index where it was
529938fd1498Szrj        *  found.  If not found, returns npos.
530038fd1498Szrj       */
530138fd1498Szrj       size_type
530238fd1498Szrj       rfind(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT;
530338fd1498Szrj 
530438fd1498Szrj #if __cplusplus > 201402L
530538fd1498Szrj       /**
530638fd1498Szrj        *  @brief  Find last position of a string_view.
530738fd1498Szrj        *  @param __svt  The object convertible to string_view to locate.
530838fd1498Szrj        *  @param __pos  Index of character to search back from (default end).
530938fd1498Szrj        *  @return  Index of start of last occurrence.
531038fd1498Szrj       */
531138fd1498Szrj       template<typename _Tp>
531238fd1498Szrj 	_If_sv<_Tp, size_type>
531338fd1498Szrj 	rfind(const _Tp& __svt, size_type __pos = npos) const
531438fd1498Szrj 	noexcept(is_same<_Tp, __sv_type>::value)
531538fd1498Szrj 	{
531638fd1498Szrj 	  __sv_type __sv = __svt;
531738fd1498Szrj 	  return this->rfind(__sv.data(), __pos, __sv.size());
531838fd1498Szrj 	}
531938fd1498Szrj #endif // C++17
532038fd1498Szrj 
532138fd1498Szrj       /**
532238fd1498Szrj        *  @brief  Find position of a character of string.
532338fd1498Szrj        *  @param __str  String containing characters to locate.
532438fd1498Szrj        *  @param __pos  Index of character to search from (default 0).
532538fd1498Szrj        *  @return  Index of first occurrence.
532638fd1498Szrj        *
532738fd1498Szrj        *  Starting from @a __pos, searches forward for one of the
532838fd1498Szrj        *  characters of @a __str within this string.  If found,
532938fd1498Szrj        *  returns the index where it was found.  If not found, returns
533038fd1498Szrj        *  npos.
533138fd1498Szrj       */
533238fd1498Szrj       size_type
533338fd1498Szrj       find_first_of(const basic_string& __str, size_type __pos = 0) const
533438fd1498Szrj       _GLIBCXX_NOEXCEPT
533538fd1498Szrj       { return this->find_first_of(__str.data(), __pos, __str.size()); }
533638fd1498Szrj 
533738fd1498Szrj       /**
533838fd1498Szrj        *  @brief  Find position of a character of C substring.
533938fd1498Szrj        *  @param __s  String containing characters to locate.
534038fd1498Szrj        *  @param __pos  Index of character to search from.
534138fd1498Szrj        *  @param __n  Number of characters from s to search for.
534238fd1498Szrj        *  @return  Index of first occurrence.
534338fd1498Szrj        *
534438fd1498Szrj        *  Starting from @a __pos, searches forward for one of the
534538fd1498Szrj        *  first @a __n characters of @a __s within this string.  If
534638fd1498Szrj        *  found, returns the index where it was found.  If not found,
534738fd1498Szrj        *  returns npos.
534838fd1498Szrj       */
534938fd1498Szrj       size_type
535038fd1498Szrj       find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
535138fd1498Szrj       _GLIBCXX_NOEXCEPT;
535238fd1498Szrj 
535338fd1498Szrj       /**
535438fd1498Szrj        *  @brief  Find position of a character of C string.
535538fd1498Szrj        *  @param __s  String containing characters to locate.
535638fd1498Szrj        *  @param __pos  Index of character to search from (default 0).
535738fd1498Szrj        *  @return  Index of first occurrence.
535838fd1498Szrj        *
535938fd1498Szrj        *  Starting from @a __pos, searches forward for one of the
536038fd1498Szrj        *  characters of @a __s within this string.  If found, returns
536138fd1498Szrj        *  the index where it was found.  If not found, returns npos.
536238fd1498Szrj       */
536338fd1498Szrj       size_type
536438fd1498Szrj       find_first_of(const _CharT* __s, size_type __pos = 0) const
536538fd1498Szrj       _GLIBCXX_NOEXCEPT
536638fd1498Szrj       {
536738fd1498Szrj 	__glibcxx_requires_string(__s);
536838fd1498Szrj 	return this->find_first_of(__s, __pos, traits_type::length(__s));
536938fd1498Szrj       }
537038fd1498Szrj 
537138fd1498Szrj       /**
537238fd1498Szrj        *  @brief  Find position of a character.
537338fd1498Szrj        *  @param __c  Character to locate.
537438fd1498Szrj        *  @param __pos  Index of character to search from (default 0).
537538fd1498Szrj        *  @return  Index of first occurrence.
537638fd1498Szrj        *
537738fd1498Szrj        *  Starting from @a __pos, searches forward for the character
537838fd1498Szrj        *  @a __c within this string.  If found, returns the index
537938fd1498Szrj        *  where it was found.  If not found, returns npos.
538038fd1498Szrj        *
538138fd1498Szrj        *  Note: equivalent to find(__c, __pos).
538238fd1498Szrj       */
538338fd1498Szrj       size_type
538438fd1498Szrj       find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
538538fd1498Szrj       { return this->find(__c, __pos); }
538638fd1498Szrj 
538738fd1498Szrj #if __cplusplus > 201402L
538838fd1498Szrj       /**
538938fd1498Szrj        *  @brief  Find position of a character of a string_view.
539038fd1498Szrj        *  @param __svt  An object convertible to string_view containing
539138fd1498Szrj        *                characters to locate.
539238fd1498Szrj        *  @param __pos  Index of character to search from (default 0).
539338fd1498Szrj        *  @return  Index of first occurrence.
539438fd1498Szrj       */
539538fd1498Szrj       template<typename _Tp>
539638fd1498Szrj 	_If_sv<_Tp, size_type>
539738fd1498Szrj 	find_first_of(const _Tp& __svt, size_type __pos = 0) const
539838fd1498Szrj 	noexcept(is_same<_Tp, __sv_type>::value)
539938fd1498Szrj 	{
540038fd1498Szrj 	  __sv_type __sv = __svt;
540138fd1498Szrj 	  return this->find_first_of(__sv.data(), __pos, __sv.size());
540238fd1498Szrj 	}
540338fd1498Szrj #endif // C++17
540438fd1498Szrj 
540538fd1498Szrj       /**
540638fd1498Szrj        *  @brief  Find last position of a character of string.
540738fd1498Szrj        *  @param __str  String containing characters to locate.
540838fd1498Szrj        *  @param __pos  Index of character to search back from (default end).
540938fd1498Szrj        *  @return  Index of last occurrence.
541038fd1498Szrj        *
541138fd1498Szrj        *  Starting from @a __pos, searches backward for one of the
541238fd1498Szrj        *  characters of @a __str within this string.  If found,
541338fd1498Szrj        *  returns the index where it was found.  If not found, returns
541438fd1498Szrj        *  npos.
541538fd1498Szrj       */
541638fd1498Szrj       size_type
541738fd1498Szrj       find_last_of(const basic_string& __str, size_type __pos = npos) const
541838fd1498Szrj       _GLIBCXX_NOEXCEPT
541938fd1498Szrj       { return this->find_last_of(__str.data(), __pos, __str.size()); }
542038fd1498Szrj 
542138fd1498Szrj       /**
542238fd1498Szrj        *  @brief  Find last position of a character of C substring.
542338fd1498Szrj        *  @param __s  C string containing characters to locate.
542438fd1498Szrj        *  @param __pos  Index of character to search back from.
542538fd1498Szrj        *  @param __n  Number of characters from s to search for.
542638fd1498Szrj        *  @return  Index of last occurrence.
542738fd1498Szrj        *
542838fd1498Szrj        *  Starting from @a __pos, searches backward for one of the
542938fd1498Szrj        *  first @a __n characters of @a __s within this string.  If
543038fd1498Szrj        *  found, returns the index where it was found.  If not found,
543138fd1498Szrj        *  returns npos.
543238fd1498Szrj       */
543338fd1498Szrj       size_type
543438fd1498Szrj       find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
543538fd1498Szrj       _GLIBCXX_NOEXCEPT;
543638fd1498Szrj 
543738fd1498Szrj       /**
543838fd1498Szrj        *  @brief  Find last position of a character of C string.
543938fd1498Szrj        *  @param __s  C string containing characters to locate.
544038fd1498Szrj        *  @param __pos  Index of character to search back from (default end).
544138fd1498Szrj        *  @return  Index of last occurrence.
544238fd1498Szrj        *
544338fd1498Szrj        *  Starting from @a __pos, searches backward for one of the
544438fd1498Szrj        *  characters of @a __s within this string.  If found, returns
544538fd1498Szrj        *  the index where it was found.  If not found, returns npos.
544638fd1498Szrj       */
544738fd1498Szrj       size_type
544838fd1498Szrj       find_last_of(const _CharT* __s, size_type __pos = npos) const
544938fd1498Szrj       _GLIBCXX_NOEXCEPT
545038fd1498Szrj       {
545138fd1498Szrj 	__glibcxx_requires_string(__s);
545238fd1498Szrj 	return this->find_last_of(__s, __pos, traits_type::length(__s));
545338fd1498Szrj       }
545438fd1498Szrj 
545538fd1498Szrj       /**
545638fd1498Szrj        *  @brief  Find last position of a character.
545738fd1498Szrj        *  @param __c  Character to locate.
545838fd1498Szrj        *  @param __pos  Index of character to search back from (default end).
545938fd1498Szrj        *  @return  Index of last occurrence.
546038fd1498Szrj        *
546138fd1498Szrj        *  Starting from @a __pos, searches backward for @a __c within
546238fd1498Szrj        *  this string.  If found, returns the index where it was
546338fd1498Szrj        *  found.  If not found, returns npos.
546438fd1498Szrj        *
546538fd1498Szrj        *  Note: equivalent to rfind(__c, __pos).
546638fd1498Szrj       */
546738fd1498Szrj       size_type
546838fd1498Szrj       find_last_of(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT
546938fd1498Szrj       { return this->rfind(__c, __pos); }
547038fd1498Szrj 
547138fd1498Szrj #if __cplusplus > 201402L
547238fd1498Szrj       /**
547338fd1498Szrj        *  @brief  Find last position of a character of string.
547438fd1498Szrj        *  @param __svt  An object convertible to string_view containing
547538fd1498Szrj        *                characters to locate.
547638fd1498Szrj        *  @param __pos  Index of character to search back from (default end).
547738fd1498Szrj        *  @return  Index of last occurrence.
547838fd1498Szrj       */
547938fd1498Szrj       template<typename _Tp>
548038fd1498Szrj 	_If_sv<_Tp, size_type>
548138fd1498Szrj 	find_last_of(const _Tp& __svt, size_type __pos = npos) const
548238fd1498Szrj 	noexcept(is_same<_Tp, __sv_type>::value)
548338fd1498Szrj 	{
548438fd1498Szrj 	  __sv_type __sv = __svt;
548538fd1498Szrj 	  return this->find_last_of(__sv.data(), __pos, __sv.size());
548638fd1498Szrj 	}
548738fd1498Szrj #endif // C++17
548838fd1498Szrj 
548938fd1498Szrj       /**
549038fd1498Szrj        *  @brief  Find position of a character not in string.
549138fd1498Szrj        *  @param __str  String containing characters to avoid.
549238fd1498Szrj        *  @param __pos  Index of character to search from (default 0).
549338fd1498Szrj        *  @return  Index of first occurrence.
549438fd1498Szrj        *
549538fd1498Szrj        *  Starting from @a __pos, searches forward for a character not contained
549638fd1498Szrj        *  in @a __str within this string.  If found, returns the index where it
549738fd1498Szrj        *  was found.  If not found, returns npos.
549838fd1498Szrj       */
549938fd1498Szrj       size_type
550038fd1498Szrj       find_first_not_of(const basic_string& __str, size_type __pos = 0) const
550138fd1498Szrj       _GLIBCXX_NOEXCEPT
550238fd1498Szrj       { return this->find_first_not_of(__str.data(), __pos, __str.size()); }
550338fd1498Szrj 
550438fd1498Szrj       /**
550538fd1498Szrj        *  @brief  Find position of a character not in C substring.
550638fd1498Szrj        *  @param __s  C string containing characters to avoid.
550738fd1498Szrj        *  @param __pos  Index of character to search from.
550838fd1498Szrj        *  @param __n  Number of characters from __s to consider.
550938fd1498Szrj        *  @return  Index of first occurrence.
551038fd1498Szrj        *
551138fd1498Szrj        *  Starting from @a __pos, searches forward for a character not
551238fd1498Szrj        *  contained in the first @a __n characters of @a __s within
551338fd1498Szrj        *  this string.  If found, returns the index where it was
551438fd1498Szrj        *  found.  If not found, returns npos.
551538fd1498Szrj       */
551638fd1498Szrj       size_type
551738fd1498Szrj       find_first_not_of(const _CharT* __s, size_type __pos,
551838fd1498Szrj 			size_type __n) const _GLIBCXX_NOEXCEPT;
551938fd1498Szrj 
552038fd1498Szrj       /**
552138fd1498Szrj        *  @brief  Find position of a character not in C string.
552238fd1498Szrj        *  @param __s  C string containing characters to avoid.
552338fd1498Szrj        *  @param __pos  Index of character to search from (default 0).
552438fd1498Szrj        *  @return  Index of first occurrence.
552538fd1498Szrj        *
552638fd1498Szrj        *  Starting from @a __pos, searches forward for a character not
552738fd1498Szrj        *  contained in @a __s within this string.  If found, returns
552838fd1498Szrj        *  the index where it was found.  If not found, returns npos.
552938fd1498Szrj       */
553038fd1498Szrj       size_type
553138fd1498Szrj       find_first_not_of(const _CharT* __s, size_type __pos = 0) const
553238fd1498Szrj       _GLIBCXX_NOEXCEPT
553338fd1498Szrj       {
553438fd1498Szrj 	__glibcxx_requires_string(__s);
553538fd1498Szrj 	return this->find_first_not_of(__s, __pos, traits_type::length(__s));
553638fd1498Szrj       }
553738fd1498Szrj 
553838fd1498Szrj       /**
553938fd1498Szrj        *  @brief  Find position of a different character.
554038fd1498Szrj        *  @param __c  Character to avoid.
554138fd1498Szrj        *  @param __pos  Index of character to search from (default 0).
554238fd1498Szrj        *  @return  Index of first occurrence.
554338fd1498Szrj        *
554438fd1498Szrj        *  Starting from @a __pos, searches forward for a character
554538fd1498Szrj        *  other than @a __c within this string.  If found, returns the
554638fd1498Szrj        *  index where it was found.  If not found, returns npos.
554738fd1498Szrj       */
554838fd1498Szrj       size_type
554938fd1498Szrj       find_first_not_of(_CharT __c, size_type __pos = 0) const
555038fd1498Szrj       _GLIBCXX_NOEXCEPT;
555138fd1498Szrj 
555238fd1498Szrj #if __cplusplus > 201402L
555338fd1498Szrj       /**
555438fd1498Szrj        *  @brief  Find position of a character not in a string_view.
555538fd1498Szrj        *  @param __svt  An object convertible to string_view containing
555638fd1498Szrj        *                characters to avoid.
555738fd1498Szrj        *  @param __pos  Index of character to search from (default 0).
555838fd1498Szrj        *  @return  Index of first occurrence.
555938fd1498Szrj        */
556038fd1498Szrj       template<typename _Tp>
556138fd1498Szrj 	_If_sv<_Tp, size_type>
556238fd1498Szrj 	find_first_not_of(const _Tp& __svt, size_type __pos = 0) const
556338fd1498Szrj 	noexcept(is_same<_Tp, __sv_type>::value)
556438fd1498Szrj 	{
556538fd1498Szrj 	  __sv_type __sv = __svt;
556638fd1498Szrj 	  return this->find_first_not_of(__sv.data(), __pos, __sv.size());
556738fd1498Szrj 	}
556838fd1498Szrj #endif // C++17
556938fd1498Szrj 
557038fd1498Szrj       /**
557138fd1498Szrj        *  @brief  Find last position of a character not in string.
557238fd1498Szrj        *  @param __str  String containing characters to avoid.
557338fd1498Szrj        *  @param __pos  Index of character to search back from (default end).
557438fd1498Szrj        *  @return  Index of last occurrence.
557538fd1498Szrj        *
557638fd1498Szrj        *  Starting from @a __pos, searches backward for a character
557738fd1498Szrj        *  not contained in @a __str within this string.  If found,
557838fd1498Szrj        *  returns the index where it was found.  If not found, returns
557938fd1498Szrj        *  npos.
558038fd1498Szrj       */
558138fd1498Szrj       size_type
558238fd1498Szrj       find_last_not_of(const basic_string& __str, size_type __pos = npos) const
558338fd1498Szrj       _GLIBCXX_NOEXCEPT
558438fd1498Szrj       { return this->find_last_not_of(__str.data(), __pos, __str.size()); }
558538fd1498Szrj 
558638fd1498Szrj       /**
558738fd1498Szrj        *  @brief  Find last position of a character not in C substring.
558838fd1498Szrj        *  @param __s  C string containing characters to avoid.
558938fd1498Szrj        *  @param __pos  Index of character to search back from.
559038fd1498Szrj        *  @param __n  Number of characters from s to consider.
559138fd1498Szrj        *  @return  Index of last occurrence.
559238fd1498Szrj        *
559338fd1498Szrj        *  Starting from @a __pos, searches backward for a character not
559438fd1498Szrj        *  contained in the first @a __n characters of @a __s within this string.
559538fd1498Szrj        *  If found, returns the index where it was found.  If not found,
559638fd1498Szrj        *  returns npos.
559738fd1498Szrj       */
559838fd1498Szrj       size_type
559938fd1498Szrj       find_last_not_of(const _CharT* __s, size_type __pos,
560038fd1498Szrj 		       size_type __n) const _GLIBCXX_NOEXCEPT;
560138fd1498Szrj       /**
560238fd1498Szrj        *  @brief  Find last position of a character not in C string.
560338fd1498Szrj        *  @param __s  C string containing characters to avoid.
560438fd1498Szrj        *  @param __pos  Index of character to search back from (default end).
560538fd1498Szrj        *  @return  Index of last occurrence.
560638fd1498Szrj        *
560738fd1498Szrj        *  Starting from @a __pos, searches backward for a character
560838fd1498Szrj        *  not contained in @a __s within this string.  If found,
560938fd1498Szrj        *  returns the index where it was found.  If not found, returns
561038fd1498Szrj        *  npos.
561138fd1498Szrj       */
561238fd1498Szrj       size_type
561338fd1498Szrj       find_last_not_of(const _CharT* __s, size_type __pos = npos) const
561438fd1498Szrj       _GLIBCXX_NOEXCEPT
561538fd1498Szrj       {
561638fd1498Szrj 	__glibcxx_requires_string(__s);
561738fd1498Szrj 	return this->find_last_not_of(__s, __pos, traits_type::length(__s));
561838fd1498Szrj       }
561938fd1498Szrj 
562038fd1498Szrj       /**
562138fd1498Szrj        *  @brief  Find last position of a different character.
562238fd1498Szrj        *  @param __c  Character to avoid.
562338fd1498Szrj        *  @param __pos  Index of character to search back from (default end).
562438fd1498Szrj        *  @return  Index of last occurrence.
562538fd1498Szrj        *
562638fd1498Szrj        *  Starting from @a __pos, searches backward for a character other than
562738fd1498Szrj        *  @a __c within this string.  If found, returns the index where it was
562838fd1498Szrj        *  found.  If not found, returns npos.
562938fd1498Szrj       */
563038fd1498Szrj       size_type
563138fd1498Szrj       find_last_not_of(_CharT __c, size_type __pos = npos) const
563238fd1498Szrj       _GLIBCXX_NOEXCEPT;
563338fd1498Szrj 
563438fd1498Szrj #if __cplusplus > 201402L
563538fd1498Szrj       /**
563638fd1498Szrj        *  @brief  Find last position of a character not in a string_view.
563738fd1498Szrj        *  @param __svt  An object convertible to string_view containing
563838fd1498Szrj        *                characters to avoid.
563938fd1498Szrj        *  @param __pos  Index of character to search back from (default end).
564038fd1498Szrj        *  @return  Index of last occurrence.
564138fd1498Szrj        */
564238fd1498Szrj       template<typename _Tp>
564338fd1498Szrj 	_If_sv<_Tp, size_type>
564438fd1498Szrj 	find_last_not_of(const _Tp& __svt, size_type __pos = npos) const
564538fd1498Szrj 	noexcept(is_same<_Tp, __sv_type>::value)
564638fd1498Szrj 	{
564738fd1498Szrj 	  __sv_type __sv = __svt;
564838fd1498Szrj 	  return this->find_last_not_of(__sv.data(), __pos, __sv.size());
564938fd1498Szrj 	}
565038fd1498Szrj #endif // C++17
565138fd1498Szrj 
565238fd1498Szrj       /**
565338fd1498Szrj        *  @brief  Get a substring.
565438fd1498Szrj        *  @param __pos  Index of first character (default 0).
565538fd1498Szrj        *  @param __n  Number of characters in substring (default remainder).
565638fd1498Szrj        *  @return  The new string.
565738fd1498Szrj        *  @throw  std::out_of_range  If __pos > size().
565838fd1498Szrj        *
565938fd1498Szrj        *  Construct and return a new string using the @a __n
566038fd1498Szrj        *  characters starting at @a __pos.  If the string is too
566138fd1498Szrj        *  short, use the remainder of the characters.  If @a __pos is
566238fd1498Szrj        *  beyond the end of the string, out_of_range is thrown.
566338fd1498Szrj       */
566438fd1498Szrj       basic_string
566538fd1498Szrj       substr(size_type __pos = 0, size_type __n = npos) const
566638fd1498Szrj       { return basic_string(*this,
566738fd1498Szrj 			    _M_check(__pos, "basic_string::substr"), __n); }
566838fd1498Szrj 
566938fd1498Szrj       /**
567038fd1498Szrj        *  @brief  Compare to a string.
567138fd1498Szrj        *  @param __str  String to compare against.
567238fd1498Szrj        *  @return  Integer < 0, 0, or > 0.
567338fd1498Szrj        *
567438fd1498Szrj        *  Returns an integer < 0 if this string is ordered before @a
567538fd1498Szrj        *  __str, 0 if their values are equivalent, or > 0 if this
567638fd1498Szrj        *  string is ordered after @a __str.  Determines the effective
567738fd1498Szrj        *  length rlen of the strings to compare as the smallest of
567838fd1498Szrj        *  size() and str.size().  The function then compares the two
567938fd1498Szrj        *  strings by calling traits::compare(data(), str.data(),rlen).
568038fd1498Szrj        *  If the result of the comparison is nonzero returns it,
568138fd1498Szrj        *  otherwise the shorter one is ordered first.
568238fd1498Szrj       */
568338fd1498Szrj       int
568438fd1498Szrj       compare(const basic_string& __str) const
568538fd1498Szrj       {
568638fd1498Szrj 	const size_type __size = this->size();
568738fd1498Szrj 	const size_type __osize = __str.size();
568838fd1498Szrj 	const size_type __len = std::min(__size, __osize);
568938fd1498Szrj 
569038fd1498Szrj 	int __r = traits_type::compare(_M_data(), __str.data(), __len);
569138fd1498Szrj 	if (!__r)
569238fd1498Szrj 	  __r = _S_compare(__size, __osize);
569338fd1498Szrj 	return __r;
569438fd1498Szrj       }
569538fd1498Szrj 
569638fd1498Szrj #if __cplusplus > 201402L
569738fd1498Szrj       /**
569838fd1498Szrj        *  @brief  Compare to a string_view.
569938fd1498Szrj        *  @param __svt An object convertible to string_view to compare against.
570038fd1498Szrj        *  @return  Integer < 0, 0, or > 0.
570138fd1498Szrj        */
570238fd1498Szrj       template<typename _Tp>
570338fd1498Szrj 	_If_sv<_Tp, int>
570438fd1498Szrj 	compare(const _Tp& __svt) const
570538fd1498Szrj 	noexcept(is_same<_Tp, __sv_type>::value)
570638fd1498Szrj 	{
570738fd1498Szrj 	   __sv_type __sv = __svt;
570838fd1498Szrj 	  const size_type __size = this->size();
570938fd1498Szrj 	  const size_type __osize = __sv.size();
571038fd1498Szrj 	  const size_type __len = std::min(__size, __osize);
571138fd1498Szrj 
571238fd1498Szrj 	  int __r = traits_type::compare(_M_data(), __sv.data(), __len);
571338fd1498Szrj 	  if (!__r)
571438fd1498Szrj 	    __r = _S_compare(__size, __osize);
571538fd1498Szrj 	  return __r;
571638fd1498Szrj 	}
571738fd1498Szrj 
571838fd1498Szrj       /**
571938fd1498Szrj        *  @brief  Compare to a string_view.
572038fd1498Szrj        *  @param __pos  A position in the string to start comparing from.
572138fd1498Szrj        *  @param __n  The number of characters to compare.
572238fd1498Szrj        *  @param __svt  An object convertible to string_view to compare
572338fd1498Szrj        *                against.
572438fd1498Szrj        *  @return  Integer < 0, 0, or > 0.
572538fd1498Szrj        */
572638fd1498Szrj       template<typename _Tp>
572738fd1498Szrj 	_If_sv<_Tp, int>
572838fd1498Szrj 	compare(size_type __pos, size_type __n, const _Tp& __svt) const
572938fd1498Szrj 	noexcept(is_same<_Tp, __sv_type>::value)
573038fd1498Szrj 	{
573138fd1498Szrj 	  __sv_type __sv = __svt;
573238fd1498Szrj 	  return __sv_type(*this).substr(__pos, __n).compare(__sv);
573338fd1498Szrj 	}
573438fd1498Szrj 
573538fd1498Szrj       /**
573638fd1498Szrj        *  @brief  Compare to a string_view.
573738fd1498Szrj        *  @param __pos1  A position in the string to start comparing from.
573838fd1498Szrj        *  @param __n1  The number of characters to compare.
573938fd1498Szrj        *  @param __svt   An object convertible to string_view to compare
574038fd1498Szrj        *                 against.
574138fd1498Szrj        *  @param __pos2  A position in the string_view to start comparing from.
574238fd1498Szrj        *  @param __n2  The number of characters to compare.
574338fd1498Szrj        *  @return  Integer < 0, 0, or > 0.
574438fd1498Szrj        */
574538fd1498Szrj       template<typename _Tp>
574638fd1498Szrj 	_If_sv<_Tp, int>
574738fd1498Szrj 	compare(size_type __pos1, size_type __n1, const _Tp& __svt,
574838fd1498Szrj 		size_type __pos2, size_type __n2 = npos) const
574938fd1498Szrj 	noexcept(is_same<_Tp, __sv_type>::value)
575038fd1498Szrj 	{
575138fd1498Szrj 	  __sv_type __sv = __svt;
575238fd1498Szrj 	  return __sv_type(*this)
575338fd1498Szrj 	    .substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
575438fd1498Szrj 	}
575538fd1498Szrj #endif // C++17
575638fd1498Szrj 
575738fd1498Szrj       /**
575838fd1498Szrj        *  @brief  Compare substring to a string.
575938fd1498Szrj        *  @param __pos  Index of first character of substring.
576038fd1498Szrj        *  @param __n  Number of characters in substring.
576138fd1498Szrj        *  @param __str  String to compare against.
576238fd1498Szrj        *  @return  Integer < 0, 0, or > 0.
576338fd1498Szrj        *
576438fd1498Szrj        *  Form the substring of this string from the @a __n characters
576538fd1498Szrj        *  starting at @a __pos.  Returns an integer < 0 if the
576638fd1498Szrj        *  substring is ordered before @a __str, 0 if their values are
576738fd1498Szrj        *  equivalent, or > 0 if the substring is ordered after @a
576838fd1498Szrj        *  __str.  Determines the effective length rlen of the strings
576938fd1498Szrj        *  to compare as the smallest of the length of the substring
577038fd1498Szrj        *  and @a __str.size().  The function then compares the two
577138fd1498Szrj        *  strings by calling
577238fd1498Szrj        *  traits::compare(substring.data(),str.data(),rlen).  If the
577338fd1498Szrj        *  result of the comparison is nonzero returns it, otherwise
577438fd1498Szrj        *  the shorter one is ordered first.
577538fd1498Szrj       */
577638fd1498Szrj       int
577738fd1498Szrj       compare(size_type __pos, size_type __n, const basic_string& __str) const;
577838fd1498Szrj 
577938fd1498Szrj       /**
578038fd1498Szrj        *  @brief  Compare substring to a substring.
578138fd1498Szrj        *  @param __pos1  Index of first character of substring.
578238fd1498Szrj        *  @param __n1  Number of characters in substring.
578338fd1498Szrj        *  @param __str  String to compare against.
578438fd1498Szrj        *  @param __pos2  Index of first character of substring of str.
578538fd1498Szrj        *  @param __n2  Number of characters in substring of str.
578638fd1498Szrj        *  @return  Integer < 0, 0, or > 0.
578738fd1498Szrj        *
578838fd1498Szrj        *  Form the substring of this string from the @a __n1
578938fd1498Szrj        *  characters starting at @a __pos1.  Form the substring of @a
579038fd1498Szrj        *  __str from the @a __n2 characters starting at @a __pos2.
579138fd1498Szrj        *  Returns an integer < 0 if this substring is ordered before
579238fd1498Szrj        *  the substring of @a __str, 0 if their values are equivalent,
579338fd1498Szrj        *  or > 0 if this substring is ordered after the substring of
579438fd1498Szrj        *  @a __str.  Determines the effective length rlen of the
579538fd1498Szrj        *  strings to compare as the smallest of the lengths of the
579638fd1498Szrj        *  substrings.  The function then compares the two strings by
579738fd1498Szrj        *  calling
579838fd1498Szrj        *  traits::compare(substring.data(),str.substr(pos2,n2).data(),rlen).
579938fd1498Szrj        *  If the result of the comparison is nonzero returns it,
580038fd1498Szrj        *  otherwise the shorter one is ordered first.
580138fd1498Szrj       */
580238fd1498Szrj       int
580338fd1498Szrj       compare(size_type __pos1, size_type __n1, const basic_string& __str,
5804*58e805e6Szrj 	      size_type __pos2, size_type __n2 = npos) const;
580538fd1498Szrj 
580638fd1498Szrj       /**
580738fd1498Szrj        *  @brief  Compare to a C string.
580838fd1498Szrj        *  @param __s  C string to compare against.
580938fd1498Szrj        *  @return  Integer < 0, 0, or > 0.
581038fd1498Szrj        *
581138fd1498Szrj        *  Returns an integer < 0 if this string is ordered before @a __s, 0 if
581238fd1498Szrj        *  their values are equivalent, or > 0 if this string is ordered after
581338fd1498Szrj        *  @a __s.  Determines the effective length rlen of the strings to
581438fd1498Szrj        *  compare as the smallest of size() and the length of a string
581538fd1498Szrj        *  constructed from @a __s.  The function then compares the two strings
581638fd1498Szrj        *  by calling traits::compare(data(),s,rlen).  If the result of the
581738fd1498Szrj        *  comparison is nonzero returns it, otherwise the shorter one is
581838fd1498Szrj        *  ordered first.
581938fd1498Szrj       */
582038fd1498Szrj       int
582138fd1498Szrj       compare(const _CharT* __s) const _GLIBCXX_NOEXCEPT;
582238fd1498Szrj 
582338fd1498Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
582438fd1498Szrj       // 5 String::compare specification questionable
582538fd1498Szrj       /**
582638fd1498Szrj        *  @brief  Compare substring to a C string.
582738fd1498Szrj        *  @param __pos  Index of first character of substring.
582838fd1498Szrj        *  @param __n1  Number of characters in substring.
582938fd1498Szrj        *  @param __s  C string to compare against.
583038fd1498Szrj        *  @return  Integer < 0, 0, or > 0.
583138fd1498Szrj        *
583238fd1498Szrj        *  Form the substring of this string from the @a __n1
583338fd1498Szrj        *  characters starting at @a pos.  Returns an integer < 0 if
583438fd1498Szrj        *  the substring is ordered before @a __s, 0 if their values
583538fd1498Szrj        *  are equivalent, or > 0 if the substring is ordered after @a
583638fd1498Szrj        *  __s.  Determines the effective length rlen of the strings to
583738fd1498Szrj        *  compare as the smallest of the length of the substring and
583838fd1498Szrj        *  the length of a string constructed from @a __s.  The
583938fd1498Szrj        *  function then compares the two string by calling
584038fd1498Szrj        *  traits::compare(substring.data(),__s,rlen).  If the result of
584138fd1498Szrj        *  the comparison is nonzero returns it, otherwise the shorter
584238fd1498Szrj        *  one is ordered first.
584338fd1498Szrj       */
584438fd1498Szrj       int
584538fd1498Szrj       compare(size_type __pos, size_type __n1, const _CharT* __s) const;
584638fd1498Szrj 
584738fd1498Szrj       /**
584838fd1498Szrj        *  @brief  Compare substring against a character %array.
584938fd1498Szrj        *  @param __pos  Index of first character of substring.
585038fd1498Szrj        *  @param __n1  Number of characters in substring.
585138fd1498Szrj        *  @param __s  character %array to compare against.
585238fd1498Szrj        *  @param __n2  Number of characters of s.
585338fd1498Szrj        *  @return  Integer < 0, 0, or > 0.
585438fd1498Szrj        *
585538fd1498Szrj        *  Form the substring of this string from the @a __n1
585638fd1498Szrj        *  characters starting at @a __pos.  Form a string from the
585738fd1498Szrj        *  first @a __n2 characters of @a __s.  Returns an integer < 0
585838fd1498Szrj        *  if this substring is ordered before the string from @a __s,
585938fd1498Szrj        *  0 if their values are equivalent, or > 0 if this substring
586038fd1498Szrj        *  is ordered after the string from @a __s.  Determines the
586138fd1498Szrj        *  effective length rlen of the strings to compare as the
586238fd1498Szrj        *  smallest of the length of the substring and @a __n2.  The
586338fd1498Szrj        *  function then compares the two strings by calling
586438fd1498Szrj        *  traits::compare(substring.data(),s,rlen).  If the result of
586538fd1498Szrj        *  the comparison is nonzero returns it, otherwise the shorter
586638fd1498Szrj        *  one is ordered first.
586738fd1498Szrj        *
586838fd1498Szrj        *  NB: s must have at least n2 characters, &apos;\\0&apos; has
586938fd1498Szrj        *  no special meaning.
587038fd1498Szrj       */
587138fd1498Szrj       int
587238fd1498Szrj       compare(size_type __pos, size_type __n1, const _CharT* __s,
587338fd1498Szrj 	      size_type __n2) const;
587438fd1498Szrj 
587538fd1498Szrj # ifdef _GLIBCXX_TM_TS_INTERNAL
587638fd1498Szrj       friend void
587738fd1498Szrj       ::_txnal_cow_string_C1_for_exceptions(void* that, const char* s,
587838fd1498Szrj 					    void* exc);
587938fd1498Szrj       friend const char*
588038fd1498Szrj       ::_txnal_cow_string_c_str(const void *that);
588138fd1498Szrj       friend void
588238fd1498Szrj       ::_txnal_cow_string_D1(void *that);
588338fd1498Szrj       friend void
588438fd1498Szrj       ::_txnal_cow_string_D1_commit(void *that);
588538fd1498Szrj # endif
588638fd1498Szrj   };
588738fd1498Szrj #endif  // !_GLIBCXX_USE_CXX11_ABI
588838fd1498Szrj 
588938fd1498Szrj #if __cpp_deduction_guides >= 201606
589038fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_CXX11
589138fd1498Szrj   template<typename _InputIterator, typename _CharT
589238fd1498Szrj 	     = typename iterator_traits<_InputIterator>::value_type,
589338fd1498Szrj 	   typename _Allocator = allocator<_CharT>,
589438fd1498Szrj 	   typename = _RequireInputIter<_InputIterator>,
589538fd1498Szrj 	   typename = _RequireAllocator<_Allocator>>
589638fd1498Szrj     basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator())
589738fd1498Szrj       -> basic_string<_CharT, char_traits<_CharT>, _Allocator>;
5898*58e805e6Szrj 
5899*58e805e6Szrj   // _GLIBCXX_RESOLVE_LIB_DEFECTS
5900*58e805e6Szrj   // 3075. basic_string needs deduction guides from basic_string_view
5901*58e805e6Szrj   template<typename _CharT, typename _Traits,
5902*58e805e6Szrj 	   typename _Allocator = allocator<_CharT>,
5903*58e805e6Szrj 	   typename = _RequireAllocator<_Allocator>>
5904*58e805e6Szrj     basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _Allocator())
5905*58e805e6Szrj       -> basic_string<_CharT, _Traits, _Allocator>;
5906*58e805e6Szrj 
5907*58e805e6Szrj   template<typename _CharT, typename _Traits,
5908*58e805e6Szrj 	   typename _Allocator = allocator<_CharT>,
5909*58e805e6Szrj 	   typename = _RequireAllocator<_Allocator>>
5910*58e805e6Szrj     basic_string(basic_string_view<_CharT, _Traits>,
5911*58e805e6Szrj 		 typename basic_string<_CharT, _Traits, _Allocator>::size_type,
5912*58e805e6Szrj 		 typename basic_string<_CharT, _Traits, _Allocator>::size_type,
5913*58e805e6Szrj 		 const _Allocator& = _Allocator())
5914*58e805e6Szrj       -> basic_string<_CharT, _Traits, _Allocator>;
591538fd1498Szrj _GLIBCXX_END_NAMESPACE_CXX11
591638fd1498Szrj #endif
591738fd1498Szrj 
591838fd1498Szrj   // operator+
591938fd1498Szrj   /**
592038fd1498Szrj    *  @brief  Concatenate two strings.
592138fd1498Szrj    *  @param __lhs  First string.
592238fd1498Szrj    *  @param __rhs  Last string.
592338fd1498Szrj    *  @return  New string with value of @a __lhs followed by @a __rhs.
592438fd1498Szrj    */
592538fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
592638fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>
592738fd1498Szrj     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
592838fd1498Szrj 	      const basic_string<_CharT, _Traits, _Alloc>& __rhs)
592938fd1498Szrj     {
593038fd1498Szrj       basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
593138fd1498Szrj       __str.append(__rhs);
593238fd1498Szrj       return __str;
593338fd1498Szrj     }
593438fd1498Szrj 
593538fd1498Szrj   /**
593638fd1498Szrj    *  @brief  Concatenate C string and string.
593738fd1498Szrj    *  @param __lhs  First string.
593838fd1498Szrj    *  @param __rhs  Last string.
593938fd1498Szrj    *  @return  New string with value of @a __lhs followed by @a __rhs.
594038fd1498Szrj    */
594138fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
594238fd1498Szrj     basic_string<_CharT,_Traits,_Alloc>
594338fd1498Szrj     operator+(const _CharT* __lhs,
594438fd1498Szrj 	      const basic_string<_CharT,_Traits,_Alloc>& __rhs);
594538fd1498Szrj 
594638fd1498Szrj   /**
594738fd1498Szrj    *  @brief  Concatenate character and string.
594838fd1498Szrj    *  @param __lhs  First string.
594938fd1498Szrj    *  @param __rhs  Last string.
595038fd1498Szrj    *  @return  New string with @a __lhs followed by @a __rhs.
595138fd1498Szrj    */
595238fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
595338fd1498Szrj     basic_string<_CharT,_Traits,_Alloc>
595438fd1498Szrj     operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs);
595538fd1498Szrj 
595638fd1498Szrj   /**
595738fd1498Szrj    *  @brief  Concatenate string and C string.
595838fd1498Szrj    *  @param __lhs  First string.
595938fd1498Szrj    *  @param __rhs  Last string.
596038fd1498Szrj    *  @return  New string with @a __lhs followed by @a __rhs.
596138fd1498Szrj    */
596238fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
596338fd1498Szrj     inline basic_string<_CharT, _Traits, _Alloc>
596438fd1498Szrj     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
596538fd1498Szrj 	      const _CharT* __rhs)
596638fd1498Szrj     {
596738fd1498Szrj       basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
596838fd1498Szrj       __str.append(__rhs);
596938fd1498Szrj       return __str;
597038fd1498Szrj     }
597138fd1498Szrj 
597238fd1498Szrj   /**
597338fd1498Szrj    *  @brief  Concatenate string and character.
597438fd1498Szrj    *  @param __lhs  First string.
597538fd1498Szrj    *  @param __rhs  Last string.
597638fd1498Szrj    *  @return  New string with @a __lhs followed by @a __rhs.
597738fd1498Szrj    */
597838fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
597938fd1498Szrj     inline basic_string<_CharT, _Traits, _Alloc>
598038fd1498Szrj     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs)
598138fd1498Szrj     {
598238fd1498Szrj       typedef basic_string<_CharT, _Traits, _Alloc>	__string_type;
598338fd1498Szrj       typedef typename __string_type::size_type		__size_type;
598438fd1498Szrj       __string_type __str(__lhs);
598538fd1498Szrj       __str.append(__size_type(1), __rhs);
598638fd1498Szrj       return __str;
598738fd1498Szrj     }
598838fd1498Szrj 
598938fd1498Szrj #if __cplusplus >= 201103L
599038fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
599138fd1498Szrj     inline basic_string<_CharT, _Traits, _Alloc>
599238fd1498Szrj     operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
599338fd1498Szrj 	      const basic_string<_CharT, _Traits, _Alloc>& __rhs)
599438fd1498Szrj     { return std::move(__lhs.append(__rhs)); }
599538fd1498Szrj 
599638fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
599738fd1498Szrj     inline basic_string<_CharT, _Traits, _Alloc>
599838fd1498Szrj     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
599938fd1498Szrj 	      basic_string<_CharT, _Traits, _Alloc>&& __rhs)
600038fd1498Szrj     { return std::move(__rhs.insert(0, __lhs)); }
600138fd1498Szrj 
600238fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
600338fd1498Szrj     inline basic_string<_CharT, _Traits, _Alloc>
600438fd1498Szrj     operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
600538fd1498Szrj 	      basic_string<_CharT, _Traits, _Alloc>&& __rhs)
600638fd1498Szrj     {
600738fd1498Szrj       const auto __size = __lhs.size() + __rhs.size();
600838fd1498Szrj       const bool __cond = (__size > __lhs.capacity()
600938fd1498Szrj 			   && __size <= __rhs.capacity());
601038fd1498Szrj       return __cond ? std::move(__rhs.insert(0, __lhs))
601138fd1498Szrj 	            : std::move(__lhs.append(__rhs));
601238fd1498Szrj     }
601338fd1498Szrj 
601438fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
601538fd1498Szrj     inline basic_string<_CharT, _Traits, _Alloc>
601638fd1498Szrj     operator+(const _CharT* __lhs,
601738fd1498Szrj 	      basic_string<_CharT, _Traits, _Alloc>&& __rhs)
601838fd1498Szrj     { return std::move(__rhs.insert(0, __lhs)); }
601938fd1498Szrj 
602038fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
602138fd1498Szrj     inline basic_string<_CharT, _Traits, _Alloc>
602238fd1498Szrj     operator+(_CharT __lhs,
602338fd1498Szrj 	      basic_string<_CharT, _Traits, _Alloc>&& __rhs)
602438fd1498Szrj     { return std::move(__rhs.insert(0, 1, __lhs)); }
602538fd1498Szrj 
602638fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
602738fd1498Szrj     inline basic_string<_CharT, _Traits, _Alloc>
602838fd1498Szrj     operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
602938fd1498Szrj 	      const _CharT* __rhs)
603038fd1498Szrj     { return std::move(__lhs.append(__rhs)); }
603138fd1498Szrj 
603238fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
603338fd1498Szrj     inline basic_string<_CharT, _Traits, _Alloc>
603438fd1498Szrj     operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
603538fd1498Szrj 	      _CharT __rhs)
603638fd1498Szrj     { return std::move(__lhs.append(1, __rhs)); }
603738fd1498Szrj #endif
603838fd1498Szrj 
603938fd1498Szrj   // operator ==
604038fd1498Szrj   /**
604138fd1498Szrj    *  @brief  Test equivalence of two strings.
604238fd1498Szrj    *  @param __lhs  First string.
604338fd1498Szrj    *  @param __rhs  Second string.
604438fd1498Szrj    *  @return  True if @a __lhs.compare(@a __rhs) == 0.  False otherwise.
604538fd1498Szrj    */
604638fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
604738fd1498Szrj     inline bool
604838fd1498Szrj     operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
604938fd1498Szrj 	       const basic_string<_CharT, _Traits, _Alloc>& __rhs)
605038fd1498Szrj     _GLIBCXX_NOEXCEPT
605138fd1498Szrj     { return __lhs.compare(__rhs) == 0; }
605238fd1498Szrj 
605338fd1498Szrj   template<typename _CharT>
605438fd1498Szrj     inline
605538fd1498Szrj     typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, bool>::__type
605638fd1498Szrj     operator==(const basic_string<_CharT>& __lhs,
605738fd1498Szrj 	       const basic_string<_CharT>& __rhs) _GLIBCXX_NOEXCEPT
605838fd1498Szrj     { return (__lhs.size() == __rhs.size()
605938fd1498Szrj 	      && !std::char_traits<_CharT>::compare(__lhs.data(), __rhs.data(),
606038fd1498Szrj 						    __lhs.size())); }
606138fd1498Szrj 
606238fd1498Szrj   /**
606338fd1498Szrj    *  @brief  Test equivalence of C string and string.
606438fd1498Szrj    *  @param __lhs  C string.
606538fd1498Szrj    *  @param __rhs  String.
606638fd1498Szrj    *  @return  True if @a __rhs.compare(@a __lhs) == 0.  False otherwise.
606738fd1498Szrj    */
606838fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
606938fd1498Szrj     inline bool
607038fd1498Szrj     operator==(const _CharT* __lhs,
607138fd1498Szrj 	       const basic_string<_CharT, _Traits, _Alloc>& __rhs)
607238fd1498Szrj     { return __rhs.compare(__lhs) == 0; }
607338fd1498Szrj 
607438fd1498Szrj   /**
607538fd1498Szrj    *  @brief  Test equivalence of string and C string.
607638fd1498Szrj    *  @param __lhs  String.
607738fd1498Szrj    *  @param __rhs  C string.
607838fd1498Szrj    *  @return  True if @a __lhs.compare(@a __rhs) == 0.  False otherwise.
607938fd1498Szrj    */
608038fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
608138fd1498Szrj     inline bool
608238fd1498Szrj     operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
608338fd1498Szrj 	       const _CharT* __rhs)
608438fd1498Szrj     { return __lhs.compare(__rhs) == 0; }
608538fd1498Szrj 
608638fd1498Szrj   // operator !=
608738fd1498Szrj   /**
608838fd1498Szrj    *  @brief  Test difference of two strings.
608938fd1498Szrj    *  @param __lhs  First string.
609038fd1498Szrj    *  @param __rhs  Second string.
609138fd1498Szrj    *  @return  True if @a __lhs.compare(@a __rhs) != 0.  False otherwise.
609238fd1498Szrj    */
609338fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
609438fd1498Szrj     inline bool
609538fd1498Szrj     operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
609638fd1498Szrj 	       const basic_string<_CharT, _Traits, _Alloc>& __rhs)
609738fd1498Szrj     _GLIBCXX_NOEXCEPT
609838fd1498Szrj     { return !(__lhs == __rhs); }
609938fd1498Szrj 
610038fd1498Szrj   /**
610138fd1498Szrj    *  @brief  Test difference of C string and string.
610238fd1498Szrj    *  @param __lhs  C string.
610338fd1498Szrj    *  @param __rhs  String.
610438fd1498Szrj    *  @return  True if @a __rhs.compare(@a __lhs) != 0.  False otherwise.
610538fd1498Szrj    */
610638fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
610738fd1498Szrj     inline bool
610838fd1498Szrj     operator!=(const _CharT* __lhs,
610938fd1498Szrj 	       const basic_string<_CharT, _Traits, _Alloc>& __rhs)
611038fd1498Szrj     { return !(__lhs == __rhs); }
611138fd1498Szrj 
611238fd1498Szrj   /**
611338fd1498Szrj    *  @brief  Test difference of string and C string.
611438fd1498Szrj    *  @param __lhs  String.
611538fd1498Szrj    *  @param __rhs  C string.
611638fd1498Szrj    *  @return  True if @a __lhs.compare(@a __rhs) != 0.  False otherwise.
611738fd1498Szrj    */
611838fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
611938fd1498Szrj     inline bool
612038fd1498Szrj     operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
612138fd1498Szrj 	       const _CharT* __rhs)
612238fd1498Szrj     { return !(__lhs == __rhs); }
612338fd1498Szrj 
612438fd1498Szrj   // operator <
612538fd1498Szrj   /**
612638fd1498Szrj    *  @brief  Test if string precedes string.
612738fd1498Szrj    *  @param __lhs  First string.
612838fd1498Szrj    *  @param __rhs  Second string.
612938fd1498Szrj    *  @return  True if @a __lhs precedes @a __rhs.  False otherwise.
613038fd1498Szrj    */
613138fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
613238fd1498Szrj     inline bool
613338fd1498Szrj     operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
613438fd1498Szrj 	      const basic_string<_CharT, _Traits, _Alloc>& __rhs)
613538fd1498Szrj     _GLIBCXX_NOEXCEPT
613638fd1498Szrj     { return __lhs.compare(__rhs) < 0; }
613738fd1498Szrj 
613838fd1498Szrj   /**
613938fd1498Szrj    *  @brief  Test if string precedes C string.
614038fd1498Szrj    *  @param __lhs  String.
614138fd1498Szrj    *  @param __rhs  C string.
614238fd1498Szrj    *  @return  True if @a __lhs precedes @a __rhs.  False otherwise.
614338fd1498Szrj    */
614438fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
614538fd1498Szrj     inline bool
614638fd1498Szrj     operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
614738fd1498Szrj 	      const _CharT* __rhs)
614838fd1498Szrj     { return __lhs.compare(__rhs) < 0; }
614938fd1498Szrj 
615038fd1498Szrj   /**
615138fd1498Szrj    *  @brief  Test if C string precedes string.
615238fd1498Szrj    *  @param __lhs  C string.
615338fd1498Szrj    *  @param __rhs  String.
615438fd1498Szrj    *  @return  True if @a __lhs precedes @a __rhs.  False otherwise.
615538fd1498Szrj    */
615638fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
615738fd1498Szrj     inline bool
615838fd1498Szrj     operator<(const _CharT* __lhs,
615938fd1498Szrj 	      const basic_string<_CharT, _Traits, _Alloc>& __rhs)
616038fd1498Szrj     { return __rhs.compare(__lhs) > 0; }
616138fd1498Szrj 
616238fd1498Szrj   // operator >
616338fd1498Szrj   /**
616438fd1498Szrj    *  @brief  Test if string follows string.
616538fd1498Szrj    *  @param __lhs  First string.
616638fd1498Szrj    *  @param __rhs  Second string.
616738fd1498Szrj    *  @return  True if @a __lhs follows @a __rhs.  False otherwise.
616838fd1498Szrj    */
616938fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
617038fd1498Szrj     inline bool
617138fd1498Szrj     operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
617238fd1498Szrj 	      const basic_string<_CharT, _Traits, _Alloc>& __rhs)
617338fd1498Szrj     _GLIBCXX_NOEXCEPT
617438fd1498Szrj     { return __lhs.compare(__rhs) > 0; }
617538fd1498Szrj 
617638fd1498Szrj   /**
617738fd1498Szrj    *  @brief  Test if string follows C string.
617838fd1498Szrj    *  @param __lhs  String.
617938fd1498Szrj    *  @param __rhs  C string.
618038fd1498Szrj    *  @return  True if @a __lhs follows @a __rhs.  False otherwise.
618138fd1498Szrj    */
618238fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
618338fd1498Szrj     inline bool
618438fd1498Szrj     operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
618538fd1498Szrj 	      const _CharT* __rhs)
618638fd1498Szrj     { return __lhs.compare(__rhs) > 0; }
618738fd1498Szrj 
618838fd1498Szrj   /**
618938fd1498Szrj    *  @brief  Test if C string follows string.
619038fd1498Szrj    *  @param __lhs  C string.
619138fd1498Szrj    *  @param __rhs  String.
619238fd1498Szrj    *  @return  True if @a __lhs follows @a __rhs.  False otherwise.
619338fd1498Szrj    */
619438fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
619538fd1498Szrj     inline bool
619638fd1498Szrj     operator>(const _CharT* __lhs,
619738fd1498Szrj 	      const basic_string<_CharT, _Traits, _Alloc>& __rhs)
619838fd1498Szrj     { return __rhs.compare(__lhs) < 0; }
619938fd1498Szrj 
620038fd1498Szrj   // operator <=
620138fd1498Szrj   /**
620238fd1498Szrj    *  @brief  Test if string doesn't follow string.
620338fd1498Szrj    *  @param __lhs  First string.
620438fd1498Szrj    *  @param __rhs  Second string.
620538fd1498Szrj    *  @return  True if @a __lhs doesn't follow @a __rhs.  False otherwise.
620638fd1498Szrj    */
620738fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
620838fd1498Szrj     inline bool
620938fd1498Szrj     operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
621038fd1498Szrj 	       const basic_string<_CharT, _Traits, _Alloc>& __rhs)
621138fd1498Szrj     _GLIBCXX_NOEXCEPT
621238fd1498Szrj     { return __lhs.compare(__rhs) <= 0; }
621338fd1498Szrj 
621438fd1498Szrj   /**
621538fd1498Szrj    *  @brief  Test if string doesn't follow C string.
621638fd1498Szrj    *  @param __lhs  String.
621738fd1498Szrj    *  @param __rhs  C string.
621838fd1498Szrj    *  @return  True if @a __lhs doesn't follow @a __rhs.  False otherwise.
621938fd1498Szrj    */
622038fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
622138fd1498Szrj     inline bool
622238fd1498Szrj     operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
622338fd1498Szrj 	       const _CharT* __rhs)
622438fd1498Szrj     { return __lhs.compare(__rhs) <= 0; }
622538fd1498Szrj 
622638fd1498Szrj   /**
622738fd1498Szrj    *  @brief  Test if C string doesn't follow string.
622838fd1498Szrj    *  @param __lhs  C string.
622938fd1498Szrj    *  @param __rhs  String.
623038fd1498Szrj    *  @return  True if @a __lhs doesn't follow @a __rhs.  False otherwise.
623138fd1498Szrj    */
623238fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
623338fd1498Szrj     inline bool
623438fd1498Szrj     operator<=(const _CharT* __lhs,
623538fd1498Szrj 	       const basic_string<_CharT, _Traits, _Alloc>& __rhs)
623638fd1498Szrj     { return __rhs.compare(__lhs) >= 0; }
623738fd1498Szrj 
623838fd1498Szrj   // operator >=
623938fd1498Szrj   /**
624038fd1498Szrj    *  @brief  Test if string doesn't precede string.
624138fd1498Szrj    *  @param __lhs  First string.
624238fd1498Szrj    *  @param __rhs  Second string.
624338fd1498Szrj    *  @return  True if @a __lhs doesn't precede @a __rhs.  False otherwise.
624438fd1498Szrj    */
624538fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
624638fd1498Szrj     inline bool
624738fd1498Szrj     operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
624838fd1498Szrj 	       const basic_string<_CharT, _Traits, _Alloc>& __rhs)
624938fd1498Szrj     _GLIBCXX_NOEXCEPT
625038fd1498Szrj     { return __lhs.compare(__rhs) >= 0; }
625138fd1498Szrj 
625238fd1498Szrj   /**
625338fd1498Szrj    *  @brief  Test if string doesn't precede C string.
625438fd1498Szrj    *  @param __lhs  String.
625538fd1498Szrj    *  @param __rhs  C string.
625638fd1498Szrj    *  @return  True if @a __lhs doesn't precede @a __rhs.  False otherwise.
625738fd1498Szrj    */
625838fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
625938fd1498Szrj     inline bool
626038fd1498Szrj     operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
626138fd1498Szrj 	       const _CharT* __rhs)
626238fd1498Szrj     { return __lhs.compare(__rhs) >= 0; }
626338fd1498Szrj 
626438fd1498Szrj   /**
626538fd1498Szrj    *  @brief  Test if C string doesn't precede string.
626638fd1498Szrj    *  @param __lhs  C string.
626738fd1498Szrj    *  @param __rhs  String.
626838fd1498Szrj    *  @return  True if @a __lhs doesn't precede @a __rhs.  False otherwise.
626938fd1498Szrj    */
627038fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
627138fd1498Szrj     inline bool
627238fd1498Szrj     operator>=(const _CharT* __lhs,
627338fd1498Szrj 	     const basic_string<_CharT, _Traits, _Alloc>& __rhs)
627438fd1498Szrj     { return __rhs.compare(__lhs) <= 0; }
627538fd1498Szrj 
627638fd1498Szrj   /**
627738fd1498Szrj    *  @brief  Swap contents of two strings.
627838fd1498Szrj    *  @param __lhs  First string.
627938fd1498Szrj    *  @param __rhs  Second string.
628038fd1498Szrj    *
628138fd1498Szrj    *  Exchanges the contents of @a __lhs and @a __rhs in constant time.
628238fd1498Szrj    */
628338fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
628438fd1498Szrj     inline void
628538fd1498Szrj     swap(basic_string<_CharT, _Traits, _Alloc>& __lhs,
628638fd1498Szrj 	 basic_string<_CharT, _Traits, _Alloc>& __rhs)
628738fd1498Szrj     _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs)))
628838fd1498Szrj     { __lhs.swap(__rhs); }
628938fd1498Szrj 
629038fd1498Szrj 
629138fd1498Szrj   /**
629238fd1498Szrj    *  @brief  Read stream into a string.
629338fd1498Szrj    *  @param __is  Input stream.
629438fd1498Szrj    *  @param __str  Buffer to store into.
629538fd1498Szrj    *  @return  Reference to the input stream.
629638fd1498Szrj    *
629738fd1498Szrj    *  Stores characters from @a __is into @a __str until whitespace is
629838fd1498Szrj    *  found, the end of the stream is encountered, or str.max_size()
629938fd1498Szrj    *  is reached.  If is.width() is non-zero, that is the limit on the
630038fd1498Szrj    *  number of characters stored into @a __str.  Any previous
630138fd1498Szrj    *  contents of @a __str are erased.
630238fd1498Szrj    */
630338fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
630438fd1498Szrj     basic_istream<_CharT, _Traits>&
630538fd1498Szrj     operator>>(basic_istream<_CharT, _Traits>& __is,
630638fd1498Szrj 	       basic_string<_CharT, _Traits, _Alloc>& __str);
630738fd1498Szrj 
630838fd1498Szrj   template<>
630938fd1498Szrj     basic_istream<char>&
631038fd1498Szrj     operator>>(basic_istream<char>& __is, basic_string<char>& __str);
631138fd1498Szrj 
631238fd1498Szrj   /**
631338fd1498Szrj    *  @brief  Write string to a stream.
631438fd1498Szrj    *  @param __os  Output stream.
631538fd1498Szrj    *  @param __str  String to write out.
631638fd1498Szrj    *  @return  Reference to the output stream.
631738fd1498Szrj    *
631838fd1498Szrj    *  Output characters of @a __str into os following the same rules as for
631938fd1498Szrj    *  writing a C string.
632038fd1498Szrj    */
632138fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
632238fd1498Szrj     inline basic_ostream<_CharT, _Traits>&
632338fd1498Szrj     operator<<(basic_ostream<_CharT, _Traits>& __os,
632438fd1498Szrj 	       const basic_string<_CharT, _Traits, _Alloc>& __str)
632538fd1498Szrj     {
632638fd1498Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
632738fd1498Szrj       // 586. string inserter not a formatted function
632838fd1498Szrj       return __ostream_insert(__os, __str.data(), __str.size());
632938fd1498Szrj     }
633038fd1498Szrj 
633138fd1498Szrj   /**
633238fd1498Szrj    *  @brief  Read a line from stream into a string.
633338fd1498Szrj    *  @param __is  Input stream.
633438fd1498Szrj    *  @param __str  Buffer to store into.
633538fd1498Szrj    *  @param __delim  Character marking end of line.
633638fd1498Szrj    *  @return  Reference to the input stream.
633738fd1498Szrj    *
633838fd1498Szrj    *  Stores characters from @a __is into @a __str until @a __delim is
633938fd1498Szrj    *  found, the end of the stream is encountered, or str.max_size()
634038fd1498Szrj    *  is reached.  Any previous contents of @a __str are erased.  If
634138fd1498Szrj    *  @a __delim is encountered, it is extracted but not stored into
634238fd1498Szrj    *  @a __str.
634338fd1498Szrj    */
634438fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
634538fd1498Szrj     basic_istream<_CharT, _Traits>&
634638fd1498Szrj     getline(basic_istream<_CharT, _Traits>& __is,
634738fd1498Szrj 	    basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim);
634838fd1498Szrj 
634938fd1498Szrj   /**
635038fd1498Szrj    *  @brief  Read a line from stream into a string.
635138fd1498Szrj    *  @param __is  Input stream.
635238fd1498Szrj    *  @param __str  Buffer to store into.
635338fd1498Szrj    *  @return  Reference to the input stream.
635438fd1498Szrj    *
635538fd1498Szrj    *  Stores characters from is into @a __str until &apos;\n&apos; is
635638fd1498Szrj    *  found, the end of the stream is encountered, or str.max_size()
635738fd1498Szrj    *  is reached.  Any previous contents of @a __str are erased.  If
635838fd1498Szrj    *  end of line is encountered, it is extracted but not stored into
635938fd1498Szrj    *  @a __str.
636038fd1498Szrj    */
636138fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
636238fd1498Szrj     inline basic_istream<_CharT, _Traits>&
636338fd1498Szrj     getline(basic_istream<_CharT, _Traits>& __is,
636438fd1498Szrj 	    basic_string<_CharT, _Traits, _Alloc>& __str)
636538fd1498Szrj     { return std::getline(__is, __str, __is.widen('\n')); }
636638fd1498Szrj 
636738fd1498Szrj #if __cplusplus >= 201103L
636838fd1498Szrj   /// Read a line from an rvalue stream into a string.
636938fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
637038fd1498Szrj     inline basic_istream<_CharT, _Traits>&
637138fd1498Szrj     getline(basic_istream<_CharT, _Traits>&& __is,
637238fd1498Szrj 	    basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim)
637338fd1498Szrj     { return std::getline(__is, __str, __delim); }
637438fd1498Szrj 
637538fd1498Szrj   /// Read a line from an rvalue stream into a string.
637638fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
637738fd1498Szrj     inline basic_istream<_CharT, _Traits>&
637838fd1498Szrj     getline(basic_istream<_CharT, _Traits>&& __is,
637938fd1498Szrj 	    basic_string<_CharT, _Traits, _Alloc>& __str)
638038fd1498Szrj     { return std::getline(__is, __str); }
638138fd1498Szrj #endif
638238fd1498Szrj 
638338fd1498Szrj   template<>
638438fd1498Szrj     basic_istream<char>&
638538fd1498Szrj     getline(basic_istream<char>& __in, basic_string<char>& __str,
638638fd1498Szrj 	    char __delim);
638738fd1498Szrj 
638838fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T
638938fd1498Szrj   template<>
639038fd1498Szrj     basic_istream<wchar_t>&
639138fd1498Szrj     getline(basic_istream<wchar_t>& __in, basic_string<wchar_t>& __str,
639238fd1498Szrj 	    wchar_t __delim);
639338fd1498Szrj #endif
639438fd1498Szrj 
639538fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
639638fd1498Szrj } // namespace
639738fd1498Szrj 
639838fd1498Szrj #if __cplusplus >= 201103L
639938fd1498Szrj 
640038fd1498Szrj #include <ext/string_conversions.h>
640138fd1498Szrj 
640238fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
640338fd1498Szrj {
640438fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
640538fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_CXX11
640638fd1498Szrj 
640738fd1498Szrj #if _GLIBCXX_USE_C99_STDLIB
640838fd1498Szrj   // 21.4 Numeric Conversions [string.conversions].
640938fd1498Szrj   inline int
641038fd1498Szrj   stoi(const string& __str, size_t* __idx = 0, int __base = 10)
641138fd1498Szrj   { return __gnu_cxx::__stoa<long, int>(&std::strtol, "stoi", __str.c_str(),
641238fd1498Szrj 					__idx, __base); }
641338fd1498Szrj 
641438fd1498Szrj   inline long
641538fd1498Szrj   stol(const string& __str, size_t* __idx = 0, int __base = 10)
641638fd1498Szrj   { return __gnu_cxx::__stoa(&std::strtol, "stol", __str.c_str(),
641738fd1498Szrj 			     __idx, __base); }
641838fd1498Szrj 
641938fd1498Szrj   inline unsigned long
642038fd1498Szrj   stoul(const string& __str, size_t* __idx = 0, int __base = 10)
642138fd1498Szrj   { return __gnu_cxx::__stoa(&std::strtoul, "stoul", __str.c_str(),
642238fd1498Szrj 			     __idx, __base); }
642338fd1498Szrj 
642438fd1498Szrj   inline long long
642538fd1498Szrj   stoll(const string& __str, size_t* __idx = 0, int __base = 10)
642638fd1498Szrj   { return __gnu_cxx::__stoa(&std::strtoll, "stoll", __str.c_str(),
642738fd1498Szrj 			     __idx, __base); }
642838fd1498Szrj 
642938fd1498Szrj   inline unsigned long long
643038fd1498Szrj   stoull(const string& __str, size_t* __idx = 0, int __base = 10)
643138fd1498Szrj   { return __gnu_cxx::__stoa(&std::strtoull, "stoull", __str.c_str(),
643238fd1498Szrj 			     __idx, __base); }
643338fd1498Szrj 
643438fd1498Szrj   // NB: strtof vs strtod.
643538fd1498Szrj   inline float
643638fd1498Szrj   stof(const string& __str, size_t* __idx = 0)
643738fd1498Szrj   { return __gnu_cxx::__stoa(&std::strtof, "stof", __str.c_str(), __idx); }
643838fd1498Szrj 
643938fd1498Szrj   inline double
644038fd1498Szrj   stod(const string& __str, size_t* __idx = 0)
644138fd1498Szrj   { return __gnu_cxx::__stoa(&std::strtod, "stod", __str.c_str(), __idx); }
644238fd1498Szrj 
644338fd1498Szrj   inline long double
644438fd1498Szrj   stold(const string& __str, size_t* __idx = 0)
644538fd1498Szrj   { return __gnu_cxx::__stoa(&std::strtold, "stold", __str.c_str(), __idx); }
644638fd1498Szrj #endif // _GLIBCXX_USE_C99_STDLIB
644738fd1498Szrj 
644838fd1498Szrj #if _GLIBCXX_USE_C99_STDIO
644938fd1498Szrj   // NB: (v)snprintf vs sprintf.
645038fd1498Szrj 
645138fd1498Szrj   // DR 1261.
645238fd1498Szrj   inline string
645338fd1498Szrj   to_string(int __val)
645438fd1498Szrj   { return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, 4 * sizeof(int),
645538fd1498Szrj 					   "%d", __val); }
645638fd1498Szrj 
645738fd1498Szrj   inline string
645838fd1498Szrj   to_string(unsigned __val)
645938fd1498Szrj   { return __gnu_cxx::__to_xstring<string>(&std::vsnprintf,
646038fd1498Szrj 					   4 * sizeof(unsigned),
646138fd1498Szrj 					   "%u", __val); }
646238fd1498Szrj 
646338fd1498Szrj   inline string
646438fd1498Szrj   to_string(long __val)
646538fd1498Szrj   { return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, 4 * sizeof(long),
646638fd1498Szrj 					   "%ld", __val); }
646738fd1498Szrj 
646838fd1498Szrj   inline string
646938fd1498Szrj   to_string(unsigned long __val)
647038fd1498Szrj   { return __gnu_cxx::__to_xstring<string>(&std::vsnprintf,
647138fd1498Szrj 					   4 * sizeof(unsigned long),
647238fd1498Szrj 					   "%lu", __val); }
647338fd1498Szrj 
647438fd1498Szrj   inline string
647538fd1498Szrj   to_string(long long __val)
647638fd1498Szrj   { return __gnu_cxx::__to_xstring<string>(&std::vsnprintf,
647738fd1498Szrj 					   4 * sizeof(long long),
647838fd1498Szrj 					   "%lld", __val); }
647938fd1498Szrj 
648038fd1498Szrj   inline string
648138fd1498Szrj   to_string(unsigned long long __val)
648238fd1498Szrj   { return __gnu_cxx::__to_xstring<string>(&std::vsnprintf,
648338fd1498Szrj 					   4 * sizeof(unsigned long long),
648438fd1498Szrj 					   "%llu", __val); }
648538fd1498Szrj 
648638fd1498Szrj   inline string
648738fd1498Szrj   to_string(float __val)
648838fd1498Szrj   {
648938fd1498Szrj     const int __n =
649038fd1498Szrj       __gnu_cxx::__numeric_traits<float>::__max_exponent10 + 20;
649138fd1498Szrj     return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, __n,
649238fd1498Szrj 					   "%f", __val);
649338fd1498Szrj   }
649438fd1498Szrj 
649538fd1498Szrj   inline string
649638fd1498Szrj   to_string(double __val)
649738fd1498Szrj   {
649838fd1498Szrj     const int __n =
649938fd1498Szrj       __gnu_cxx::__numeric_traits<double>::__max_exponent10 + 20;
650038fd1498Szrj     return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, __n,
650138fd1498Szrj 					   "%f", __val);
650238fd1498Szrj   }
650338fd1498Szrj 
650438fd1498Szrj   inline string
650538fd1498Szrj   to_string(long double __val)
650638fd1498Szrj   {
650738fd1498Szrj     const int __n =
650838fd1498Szrj       __gnu_cxx::__numeric_traits<long double>::__max_exponent10 + 20;
650938fd1498Szrj     return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, __n,
651038fd1498Szrj 					   "%Lf", __val);
651138fd1498Szrj   }
651238fd1498Szrj #endif // _GLIBCXX_USE_C99_STDIO
651338fd1498Szrj 
651438fd1498Szrj #if defined(_GLIBCXX_USE_WCHAR_T) && _GLIBCXX_USE_C99_WCHAR
651538fd1498Szrj   inline int
651638fd1498Szrj   stoi(const wstring& __str, size_t* __idx = 0, int __base = 10)
651738fd1498Szrj   { return __gnu_cxx::__stoa<long, int>(&std::wcstol, "stoi", __str.c_str(),
651838fd1498Szrj 					__idx, __base); }
651938fd1498Szrj 
652038fd1498Szrj   inline long
652138fd1498Szrj   stol(const wstring& __str, size_t* __idx = 0, int __base = 10)
652238fd1498Szrj   { return __gnu_cxx::__stoa(&std::wcstol, "stol", __str.c_str(),
652338fd1498Szrj 			     __idx, __base); }
652438fd1498Szrj 
652538fd1498Szrj   inline unsigned long
652638fd1498Szrj   stoul(const wstring& __str, size_t* __idx = 0, int __base = 10)
652738fd1498Szrj   { return __gnu_cxx::__stoa(&std::wcstoul, "stoul", __str.c_str(),
652838fd1498Szrj 			     __idx, __base); }
652938fd1498Szrj 
653038fd1498Szrj   inline long long
653138fd1498Szrj   stoll(const wstring& __str, size_t* __idx = 0, int __base = 10)
653238fd1498Szrj   { return __gnu_cxx::__stoa(&std::wcstoll, "stoll", __str.c_str(),
653338fd1498Szrj 			     __idx, __base); }
653438fd1498Szrj 
653538fd1498Szrj   inline unsigned long long
653638fd1498Szrj   stoull(const wstring& __str, size_t* __idx = 0, int __base = 10)
653738fd1498Szrj   { return __gnu_cxx::__stoa(&std::wcstoull, "stoull", __str.c_str(),
653838fd1498Szrj 			     __idx, __base); }
653938fd1498Szrj 
654038fd1498Szrj   // NB: wcstof vs wcstod.
654138fd1498Szrj   inline float
654238fd1498Szrj   stof(const wstring& __str, size_t* __idx = 0)
654338fd1498Szrj   { return __gnu_cxx::__stoa(&std::wcstof, "stof", __str.c_str(), __idx); }
654438fd1498Szrj 
654538fd1498Szrj   inline double
654638fd1498Szrj   stod(const wstring& __str, size_t* __idx = 0)
654738fd1498Szrj   { return __gnu_cxx::__stoa(&std::wcstod, "stod", __str.c_str(), __idx); }
654838fd1498Szrj 
654938fd1498Szrj   inline long double
655038fd1498Szrj   stold(const wstring& __str, size_t* __idx = 0)
655138fd1498Szrj   { return __gnu_cxx::__stoa(&std::wcstold, "stold", __str.c_str(), __idx); }
655238fd1498Szrj 
655338fd1498Szrj #ifndef _GLIBCXX_HAVE_BROKEN_VSWPRINTF
655438fd1498Szrj   // DR 1261.
655538fd1498Szrj   inline wstring
655638fd1498Szrj   to_wstring(int __val)
655738fd1498Szrj   { return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf, 4 * sizeof(int),
655838fd1498Szrj 					    L"%d", __val); }
655938fd1498Szrj 
656038fd1498Szrj   inline wstring
656138fd1498Szrj   to_wstring(unsigned __val)
656238fd1498Szrj   { return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf,
656338fd1498Szrj 					    4 * sizeof(unsigned),
656438fd1498Szrj 					    L"%u", __val); }
656538fd1498Szrj 
656638fd1498Szrj   inline wstring
656738fd1498Szrj   to_wstring(long __val)
656838fd1498Szrj   { return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf, 4 * sizeof(long),
656938fd1498Szrj 					    L"%ld", __val); }
657038fd1498Szrj 
657138fd1498Szrj   inline wstring
657238fd1498Szrj   to_wstring(unsigned long __val)
657338fd1498Szrj   { return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf,
657438fd1498Szrj 					    4 * sizeof(unsigned long),
657538fd1498Szrj 					    L"%lu", __val); }
657638fd1498Szrj 
657738fd1498Szrj   inline wstring
657838fd1498Szrj   to_wstring(long long __val)
657938fd1498Szrj   { return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf,
658038fd1498Szrj 					    4 * sizeof(long long),
658138fd1498Szrj 					    L"%lld", __val); }
658238fd1498Szrj 
658338fd1498Szrj   inline wstring
658438fd1498Szrj   to_wstring(unsigned long long __val)
658538fd1498Szrj   { return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf,
658638fd1498Szrj 					    4 * sizeof(unsigned long long),
658738fd1498Szrj 					    L"%llu", __val); }
658838fd1498Szrj 
658938fd1498Szrj   inline wstring
659038fd1498Szrj   to_wstring(float __val)
659138fd1498Szrj   {
659238fd1498Szrj     const int __n =
659338fd1498Szrj       __gnu_cxx::__numeric_traits<float>::__max_exponent10 + 20;
659438fd1498Szrj     return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf, __n,
659538fd1498Szrj 					    L"%f", __val);
659638fd1498Szrj   }
659738fd1498Szrj 
659838fd1498Szrj   inline wstring
659938fd1498Szrj   to_wstring(double __val)
660038fd1498Szrj   {
660138fd1498Szrj     const int __n =
660238fd1498Szrj       __gnu_cxx::__numeric_traits<double>::__max_exponent10 + 20;
660338fd1498Szrj     return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf, __n,
660438fd1498Szrj 					    L"%f", __val);
660538fd1498Szrj   }
660638fd1498Szrj 
660738fd1498Szrj   inline wstring
660838fd1498Szrj   to_wstring(long double __val)
660938fd1498Szrj   {
661038fd1498Szrj     const int __n =
661138fd1498Szrj       __gnu_cxx::__numeric_traits<long double>::__max_exponent10 + 20;
661238fd1498Szrj     return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf, __n,
661338fd1498Szrj 					    L"%Lf", __val);
661438fd1498Szrj   }
661538fd1498Szrj #endif // _GLIBCXX_HAVE_BROKEN_VSWPRINTF
661638fd1498Szrj #endif // _GLIBCXX_USE_WCHAR_T && _GLIBCXX_USE_C99_WCHAR
661738fd1498Szrj 
661838fd1498Szrj _GLIBCXX_END_NAMESPACE_CXX11
661938fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
662038fd1498Szrj } // namespace
662138fd1498Szrj 
662238fd1498Szrj #endif /* C++11 */
662338fd1498Szrj 
662438fd1498Szrj #if __cplusplus >= 201103L
662538fd1498Szrj 
662638fd1498Szrj #include <bits/functional_hash.h>
662738fd1498Szrj 
662838fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
662938fd1498Szrj {
663038fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
663138fd1498Szrj 
663238fd1498Szrj   // DR 1182.
663338fd1498Szrj 
663438fd1498Szrj #ifndef _GLIBCXX_COMPATIBILITY_CXX0X
663538fd1498Szrj   /// std::hash specialization for string.
663638fd1498Szrj   template<>
663738fd1498Szrj     struct hash<string>
663838fd1498Szrj     : public __hash_base<size_t, string>
663938fd1498Szrj     {
664038fd1498Szrj       size_t
664138fd1498Szrj       operator()(const string& __s) const noexcept
664238fd1498Szrj       { return std::_Hash_impl::hash(__s.data(), __s.length()); }
664338fd1498Szrj     };
664438fd1498Szrj 
664538fd1498Szrj   template<>
664638fd1498Szrj     struct __is_fast_hash<hash<string>> : std::false_type
664738fd1498Szrj     { };
664838fd1498Szrj 
664938fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T
665038fd1498Szrj   /// std::hash specialization for wstring.
665138fd1498Szrj   template<>
665238fd1498Szrj     struct hash<wstring>
665338fd1498Szrj     : public __hash_base<size_t, wstring>
665438fd1498Szrj     {
665538fd1498Szrj       size_t
665638fd1498Szrj       operator()(const wstring& __s) const noexcept
665738fd1498Szrj       { return std::_Hash_impl::hash(__s.data(),
665838fd1498Szrj                                      __s.length() * sizeof(wchar_t)); }
665938fd1498Szrj     };
666038fd1498Szrj 
666138fd1498Szrj   template<>
666238fd1498Szrj     struct __is_fast_hash<hash<wstring>> : std::false_type
666338fd1498Szrj     { };
666438fd1498Szrj #endif
666538fd1498Szrj #endif /* _GLIBCXX_COMPATIBILITY_CXX0X */
666638fd1498Szrj 
666738fd1498Szrj #ifdef _GLIBCXX_USE_C99_STDINT_TR1
666838fd1498Szrj   /// std::hash specialization for u16string.
666938fd1498Szrj   template<>
667038fd1498Szrj     struct hash<u16string>
667138fd1498Szrj     : public __hash_base<size_t, u16string>
667238fd1498Szrj     {
667338fd1498Szrj       size_t
667438fd1498Szrj       operator()(const u16string& __s) const noexcept
667538fd1498Szrj       { return std::_Hash_impl::hash(__s.data(),
667638fd1498Szrj                                      __s.length() * sizeof(char16_t)); }
667738fd1498Szrj     };
667838fd1498Szrj 
667938fd1498Szrj   template<>
668038fd1498Szrj     struct __is_fast_hash<hash<u16string>> : std::false_type
668138fd1498Szrj     { };
668238fd1498Szrj 
668338fd1498Szrj   /// std::hash specialization for u32string.
668438fd1498Szrj   template<>
668538fd1498Szrj     struct hash<u32string>
668638fd1498Szrj     : public __hash_base<size_t, u32string>
668738fd1498Szrj     {
668838fd1498Szrj       size_t
668938fd1498Szrj       operator()(const u32string& __s) const noexcept
669038fd1498Szrj       { return std::_Hash_impl::hash(__s.data(),
669138fd1498Szrj                                      __s.length() * sizeof(char32_t)); }
669238fd1498Szrj     };
669338fd1498Szrj 
669438fd1498Szrj   template<>
669538fd1498Szrj     struct __is_fast_hash<hash<u32string>> : std::false_type
669638fd1498Szrj     { };
669738fd1498Szrj #endif
669838fd1498Szrj 
669938fd1498Szrj #if __cplusplus > 201103L
670038fd1498Szrj 
670138fd1498Szrj #define __cpp_lib_string_udls 201304
670238fd1498Szrj 
670338fd1498Szrj   inline namespace literals
670438fd1498Szrj   {
670538fd1498Szrj   inline namespace string_literals
670638fd1498Szrj   {
670738fd1498Szrj #pragma GCC diagnostic push
670838fd1498Szrj #pragma GCC diagnostic ignored "-Wliteral-suffix"
670938fd1498Szrj     _GLIBCXX_DEFAULT_ABI_TAG
671038fd1498Szrj     inline basic_string<char>
671138fd1498Szrj     operator""s(const char* __str, size_t __len)
671238fd1498Szrj     { return basic_string<char>{__str, __len}; }
671338fd1498Szrj 
671438fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T
671538fd1498Szrj     _GLIBCXX_DEFAULT_ABI_TAG
671638fd1498Szrj     inline basic_string<wchar_t>
671738fd1498Szrj     operator""s(const wchar_t* __str, size_t __len)
671838fd1498Szrj     { return basic_string<wchar_t>{__str, __len}; }
671938fd1498Szrj #endif
672038fd1498Szrj 
672138fd1498Szrj #ifdef _GLIBCXX_USE_C99_STDINT_TR1
672238fd1498Szrj     _GLIBCXX_DEFAULT_ABI_TAG
672338fd1498Szrj     inline basic_string<char16_t>
672438fd1498Szrj     operator""s(const char16_t* __str, size_t __len)
672538fd1498Szrj     { return basic_string<char16_t>{__str, __len}; }
672638fd1498Szrj 
672738fd1498Szrj     _GLIBCXX_DEFAULT_ABI_TAG
672838fd1498Szrj     inline basic_string<char32_t>
672938fd1498Szrj     operator""s(const char32_t* __str, size_t __len)
673038fd1498Szrj     { return basic_string<char32_t>{__str, __len}; }
673138fd1498Szrj #endif
673238fd1498Szrj 
673338fd1498Szrj #pragma GCC diagnostic pop
673438fd1498Szrj   } // inline namespace string_literals
673538fd1498Szrj   } // inline namespace literals
673638fd1498Szrj 
673738fd1498Szrj #endif // __cplusplus > 201103L
673838fd1498Szrj 
673938fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
674038fd1498Szrj } // namespace std
674138fd1498Szrj 
674238fd1498Szrj #endif // C++11
674338fd1498Szrj 
674438fd1498Szrj #endif /* _BASIC_STRING_H */
6745