Bug Summary

File:home/fedora/workspace/kea-dev/clang-static-analyzer/src/lib/dhcp/option_space.cc
Warning:line 45, column 1
Potential memory leak

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name option_space.cc -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/home/fedora/workspace/kea-dev/clang-static-analyzer/src/lib/dhcp -fcoverage-compilation-dir=/home/fedora/workspace/kea-dev/clang-static-analyzer/src/lib/dhcp -resource-dir /usr/bin/../lib/clang/18 -D HAVE_CONFIG_H -I . -I ../../.. -I ../../../src/lib -I ../../../src/lib -D OS_LINUX -I ../../.. -I ../../.. -D PIC -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/backward -internal-isystem /usr/bin/../lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/14/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wwrite-strings -Wno-sign-compare -Wno-missing-field-initializers -std=c++20 -fdeprecated-macro -ferror-limit 19 -stack-protector 2 -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/fedora/workspace/kea-dev/clang-static-analyzer/report/2024-11-20-115345-18960-1 -x c++ option_space.cc

option_space.cc

1// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
8
9#include <dhcp/option_space.h>
10#include <boost/algorithm/string/classification.hpp>
11#include <boost/algorithm/string/predicate.hpp>
12
13namespace isc {
14namespace dhcp {
15
16OptionSpace::OptionSpace(const std::string& name, const bool vendor_space)
17 : name_(name), vendor_space_(vendor_space) {
18 // Check that provided option space name is valid.
19 if (!validateName(name_)) {
2
Calling 'OptionSpace::validateName'
20 isc_throw(InvalidOptionSpace, "Invalid option space name "do { std::ostringstream oss__; oss__ << "Invalid option space name "
<< name_; throw InvalidOptionSpace("option_space.cc", 21
, oss__.str().c_str()); } while (1)
21 << name_)do { std::ostringstream oss__; oss__ << "Invalid option space name "
<< name_; throw InvalidOptionSpace("option_space.cc", 21
, oss__.str().c_str()); } while (1)
;
22 }
23}
24
25bool
26OptionSpace::validateName(const std::string& name) {
27
28 using namespace boost::algorithm;
29
30 // Allowed characters are: lower or upper case letters, digits,
31 // underscores and hyphens. Empty option spaces are not allowed.
32 if (all(name, boost::is_from_range('a', 'z') ||
10
Taking true branch
33 boost::is_from_range('A', 'Z') ||
34 boost::is_digit() ||
35 boost::is_any_of(std::string("-_"))) &&
36 !name.empty() &&
3
Assuming the condition is true
37 // Hyphens and underscores are not allowed at the beginning
38 // and at the end of the option space name.
39 !all(find_head(name, 1), boost::is_any_of(std::string("-_"))) &&
40 !all(find_tail(name, 1), boost::is_any_of(std::string("-_")))) {
4
Calling 'is_any_of<std::basic_string<char>>'
9
Returned allocated memory
41 return (true);
42
43 }
44 return (false);
45}
11
Potential memory leak
46
47OptionSpace6::OptionSpace6(const std::string& name)
48 : OptionSpace(name),
49 enterprise_number_(0) {
50}
51
52OptionSpace6::OptionSpace6(const std::string& name,
53 const uint32_t enterprise_number)
54 : OptionSpace(name, true),
1
Calling constructor for 'OptionSpace'
55 enterprise_number_(enterprise_number) {
56}
57
58void
59OptionSpace6::setVendorSpace(const uint32_t enterprise_number) {
60 enterprise_number_ = enterprise_number;
61 OptionSpace::setVendorSpace();
62}
63
64} // end of isc::dhcp namespace
65} // end of isc namespace

/usr/include/boost/algorithm/string/classification.hpp

1// Boost string_algo library classification.hpp header file ---------------------------//
2
3// Copyright Pavol Droba 2002-2003.
4//
5// Distributed under the Boost Software License, Version 1.0.
6// (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8
9// See http://www.boost.org/ for updates, documentation, and revision history.
10
11#ifndef BOOST_STRING_CLASSIFICATION_HPP
12#define BOOST_STRING_CLASSIFICATION_HPP
13
14#include <algorithm>
15#include <locale>
16#include <boost/range/value_type.hpp>
17#include <boost/range/as_literal.hpp>
18#include <boost/algorithm/string/detail/classification.hpp>
19#include <boost/algorithm/string/predicate_facade.hpp>
20
21
22/*! \file
23 Classification predicates are included in the library to give
24 some more convenience when using algorithms like \c trim() and \c all().
25 They wrap functionality of STL classification functions ( e.g. \c std::isspace() )
26 into generic functors.
27*/
28
29namespace boost {
30 namespace algorithm {
31
32// classification functor generator -------------------------------------//
33
34 //! is_classified predicate
35 /*!
36 Construct the \c is_classified predicate. This predicate holds if the input is
37 of specified \c std::ctype category.
38
39 \param Type A \c std::ctype category
40 \param Loc A locale used for classification
41 \return An instance of the \c is_classified predicate
42 */
43 inline detail::is_classifiedF
44 is_classified(std::ctype_base::mask Type, const std::locale& Loc=std::locale())
45 {
46 return detail::is_classifiedF(Type, Loc);
47 }
48
49 //! is_space predicate
50 /*!
51 Construct the \c is_classified predicate for the \c ctype_base::space category.
52
53 \param Loc A locale used for classification
54 \return An instance of the \c is_classified predicate
55 */
56 inline detail::is_classifiedF
57 is_space(const std::locale& Loc=std::locale())
58 {
59 return detail::is_classifiedF(std::ctype_base::space, Loc);
60 }
61
62 //! is_alnum predicate
63 /*!
64 Construct the \c is_classified predicate for the \c ctype_base::alnum category.
65
66 \param Loc A locale used for classification
67 \return An instance of the \c is_classified predicate
68 */
69 inline detail::is_classifiedF
70 is_alnum(const std::locale& Loc=std::locale())
71 {
72 return detail::is_classifiedF(std::ctype_base::alnum, Loc);
73 }
74
75 //! is_alpha predicate
76 /*!
77 Construct the \c is_classified predicate for the \c ctype_base::alpha category.
78
79 \param Loc A locale used for classification
80 \return An instance of the \c is_classified predicate
81 */
82 inline detail::is_classifiedF
83 is_alpha(const std::locale& Loc=std::locale())
84 {
85 return detail::is_classifiedF(std::ctype_base::alpha, Loc);
86 }
87
88 //! is_cntrl predicate
89 /*!
90 Construct the \c is_classified predicate for the \c ctype_base::cntrl category.
91
92 \param Loc A locale used for classification
93 \return An instance of the \c is_classified predicate
94 */
95 inline detail::is_classifiedF
96 is_cntrl(const std::locale& Loc=std::locale())
97 {
98 return detail::is_classifiedF(std::ctype_base::cntrl, Loc);
99 }
100
101 //! is_digit predicate
102 /*!
103 Construct the \c is_classified predicate for the \c ctype_base::digit category.
104
105 \param Loc A locale used for classification
106 \return An instance of the \c is_classified predicate
107 */
108 inline detail::is_classifiedF
109 is_digit(const std::locale& Loc=std::locale())
110 {
111 return detail::is_classifiedF(std::ctype_base::digit, Loc);
112 }
113
114 //! is_graph predicate
115 /*!
116 Construct the \c is_classified predicate for the \c ctype_base::graph category.
117
118 \param Loc A locale used for classification
119 \return An instance of the \c is_classified predicate
120 */
121 inline detail::is_classifiedF
122 is_graph(const std::locale& Loc=std::locale())
123 {
124 return detail::is_classifiedF(std::ctype_base::graph, Loc);
125 }
126
127 //! is_lower predicate
128 /*!
129 Construct the \c is_classified predicate for the \c ctype_base::lower category.
130
131 \param Loc A locale used for classification
132 \return An instance of \c is_classified predicate
133 */
134 inline detail::is_classifiedF
135 is_lower(const std::locale& Loc=std::locale())
136 {
137 return detail::is_classifiedF(std::ctype_base::lower, Loc);
138 }
139
140 //! is_print predicate
141 /*!
142 Construct the \c is_classified predicate for the \c ctype_base::print category.
143
144 \param Loc A locale used for classification
145 \return An instance of the \c is_classified predicate
146 */
147 inline detail::is_classifiedF
148 is_print(const std::locale& Loc=std::locale())
149 {
150 return detail::is_classifiedF(std::ctype_base::print, Loc);
151 }
152
153 //! is_punct predicate
154 /*!
155 Construct the \c is_classified predicate for the \c ctype_base::punct category.
156
157 \param Loc A locale used for classification
158 \return An instance of the \c is_classified predicate
159 */
160 inline detail::is_classifiedF
161 is_punct(const std::locale& Loc=std::locale())
162 {
163 return detail::is_classifiedF(std::ctype_base::punct, Loc);
164 }
165
166 //! is_upper predicate
167 /*!
168 Construct the \c is_classified predicate for the \c ctype_base::upper category.
169
170 \param Loc A locale used for classification
171 \return An instance of the \c is_classified predicate
172 */
173 inline detail::is_classifiedF
174 is_upper(const std::locale& Loc=std::locale())
175 {
176 return detail::is_classifiedF(std::ctype_base::upper, Loc);
177 }
178
179 //! is_xdigit predicate
180 /*!
181 Construct the \c is_classified predicate for the \c ctype_base::xdigit category.
182
183 \param Loc A locale used for classification
184 \return An instance of the \c is_classified predicate
185 */
186 inline detail::is_classifiedF
187 is_xdigit(const std::locale& Loc=std::locale())
188 {
189 return detail::is_classifiedF(std::ctype_base::xdigit, Loc);
190 }
191
192 //! is_any_of predicate
193 /*!
194 Construct the \c is_any_of predicate. The predicate holds if the input
195 is included in the specified set of characters.
196
197 \param Set A set of characters to be recognized
198 \return An instance of the \c is_any_of predicate
199 */
200 template<typename RangeT>
201 inline detail::is_any_ofF<
202 BOOST_STRING_TYPENAMEtypename range_value<RangeT>::type>
203 is_any_of( const RangeT& Set )
204 {
205 iterator_range<BOOST_STRING_TYPENAMEtypename range_const_iterator<RangeT>::type> lit_set(boost::as_literal(Set));
206 return detail::is_any_ofF<BOOST_STRING_TYPENAMEtypename range_value<RangeT>::type>(lit_set);
5
Calling constructor for 'is_any_ofF<char>'
8
Returning from constructor for 'is_any_ofF<char>'
207 }
208
209 //! is_from_range predicate
210 /*!
211 Construct the \c is_from_range predicate. The predicate holds if the input
212 is included in the specified range. (i.e. From <= Ch <= To )
213
214 \param From The start of the range
215 \param To The end of the range
216 \return An instance of the \c is_from_range predicate
217 */
218 template<typename CharT>
219 inline detail::is_from_rangeF<CharT> is_from_range(CharT From, CharT To)
220 {
221 return detail::is_from_rangeF<CharT>(From,To);
222 }
223
224 // predicate combinators ---------------------------------------------------//
225
226 //! predicate 'and' composition predicate
227 /*!
228 Construct the \c class_and predicate. This predicate can be used
229 to logically combine two classification predicates. \c class_and holds,
230 if both predicates return true.
231
232 \param Pred1 The first predicate
233 \param Pred2 The second predicate
234 \return An instance of the \c class_and predicate
235 */
236 template<typename Pred1T, typename Pred2T>
237 inline detail::pred_andF<Pred1T, Pred2T>
238 operator&&(
239 const predicate_facade<Pred1T>& Pred1,
240 const predicate_facade<Pred2T>& Pred2 )
241 {
242 // Doing the static_cast with the pointer instead of the reference
243 // is a workaround for some compilers which have problems with
244 // static_cast's of template references, i.e. CW8. /grafik/
245 return detail::pred_andF<Pred1T,Pred2T>(
246 *static_cast<const Pred1T*>(&Pred1),
247 *static_cast<const Pred2T*>(&Pred2) );
248 }
249
250 //! predicate 'or' composition predicate
251 /*!
252 Construct the \c class_or predicate. This predicate can be used
253 to logically combine two classification predicates. \c class_or holds,
254 if one of the predicates return true.
255
256 \param Pred1 The first predicate
257 \param Pred2 The second predicate
258 \return An instance of the \c class_or predicate
259 */
260 template<typename Pred1T, typename Pred2T>
261 inline detail::pred_orF<Pred1T, Pred2T>
262 operator||(
263 const predicate_facade<Pred1T>& Pred1,
264 const predicate_facade<Pred2T>& Pred2 )
265 {
266 // Doing the static_cast with the pointer instead of the reference
267 // is a workaround for some compilers which have problems with
268 // static_cast's of template references, i.e. CW8. /grafik/
269 return detail::pred_orF<Pred1T,Pred2T>(
270 *static_cast<const Pred1T*>(&Pred1),
271 *static_cast<const Pred2T*>(&Pred2));
272 }
273
274 //! predicate negation operator
275 /*!
276 Construct the \c class_not predicate. This predicate represents a negation.
277 \c class_or holds if of the predicates return false.
278
279 \param Pred The predicate to be negated
280 \return An instance of the \c class_not predicate
281 */
282 template<typename PredT>
283 inline detail::pred_notF<PredT>
284 operator!( const predicate_facade<PredT>& Pred )
285 {
286 // Doing the static_cast with the pointer instead of the reference
287 // is a workaround for some compilers which have problems with
288 // static_cast's of template references, i.e. CW8. /grafik/
289 return detail::pred_notF<PredT>(*static_cast<const PredT*>(&Pred));
290 }
291
292 } // namespace algorithm
293
294 // pull names to the boost namespace
295 using algorithm::is_classified;
296 using algorithm::is_space;
297 using algorithm::is_alnum;
298 using algorithm::is_alpha;
299 using algorithm::is_cntrl;
300 using algorithm::is_digit;
301 using algorithm::is_graph;
302 using algorithm::is_lower;
303 using algorithm::is_upper;
304 using algorithm::is_print;
305 using algorithm::is_punct;
306 using algorithm::is_xdigit;
307 using algorithm::is_any_of;
308 using algorithm::is_from_range;
309
310} // namespace boost
311
312#endif // BOOST_STRING_PREDICATE_HPP

/usr/include/boost/algorithm/string/detail/classification.hpp

1// Boost string_algo library classification.hpp header file ---------------------------//
2
3// Copyright Pavol Droba 2002-2003.
4//
5// Distributed under the Boost Software License, Version 1.0.
6// (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8
9// See http://www.boost.org/ for updates, documentation, and revision history.
10
11#ifndef BOOST_STRING_CLASSIFICATION_DETAIL_HPP
12#define BOOST_STRING_CLASSIFICATION_DETAIL_HPP
13
14#include <boost/algorithm/string/config.hpp>
15#include <algorithm>
16#include <cstring>
17#include <functional>
18#include <locale>
19
20#include <boost/range/begin.hpp>
21#include <boost/range/distance.hpp>
22#include <boost/range/end.hpp>
23
24#include <boost/algorithm/string/predicate_facade.hpp>
25#include <boost/type_traits/remove_const.hpp>
26
27namespace boost {
28 namespace algorithm {
29 namespace detail {
30
31// classification functors -----------------------------------------------//
32
33 // is_classified functor
34 struct is_classifiedF :
35 public predicate_facade<is_classifiedF>
36 {
37 // Boost.ResultOf support
38 typedef bool result_type;
39
40 // Constructor from a locale
41 is_classifiedF(std::ctype_base::mask Type, std::locale const & Loc = std::locale()) :
42 m_Type(Type), m_Locale(Loc) {}
43 // Operation
44 template<typename CharT>
45 bool operator()( CharT Ch ) const
46 {
47 return std::use_facet< std::ctype<CharT> >(m_Locale).is( m_Type, Ch );
48 }
49
50 #if defined(BOOST_BORLANDC) && (BOOST_BORLANDC >= 0x560) && (BOOST_BORLANDC <= 0x582) && !defined(_USE_OLD_RW_STL)
51 template<>
52 bool operator()( char const Ch ) const
53 {
54 return std::use_facet< std::ctype<char> >(m_Locale).is( m_Type, Ch );
55 }
56 #endif
57
58 private:
59 std::ctype_base::mask m_Type;
60 std::locale m_Locale;
61 };
62
63
64 // is_any_of functor
65 /*
66 returns true if the value is from the specified set
67 */
68 template<typename CharT>
69 struct is_any_ofF :
70 public predicate_facade<is_any_ofF<CharT> >
71 {
72 private:
73 // set cannot operate on const value-type
74 typedef typename ::boost::remove_const<CharT>::type set_value_type;
75
76 public:
77 // Boost.ResultOf support
78 typedef bool result_type;
79
80 // Constructor
81 template<typename RangeT>
82 is_any_ofF( const RangeT& Range ) : m_Size(0)
83 {
84 // Prepare storage
85 m_Storage.m_dynSet=0;
86
87 std::size_t Size=::boost::distance(Range);
88 m_Size=Size;
89 set_value_type* Storage=0;
90
91 if(use_fixed_storage(m_Size))
6
Taking false branch
92 {
93 // Use fixed storage
94 Storage=&m_Storage.m_fixSet[0];
95 }
96 else
97 {
98 // Use dynamic storage
99 m_Storage.m_dynSet=new set_value_type[m_Size];
7
Memory is allocated
100 Storage=m_Storage.m_dynSet;
101 }
102
103 // Use fixed storage
104 ::std::copy(::boost::begin(Range), ::boost::end(Range), Storage);
105 ::std::sort(Storage, Storage+m_Size);
106 }
107
108 // Copy constructor
109 is_any_ofF(const is_any_ofF& Other) : m_Size(Other.m_Size)
110 {
111 // Prepare storage
112 m_Storage.m_dynSet=0;
113 const set_value_type* SrcStorage=0;
114 set_value_type* DestStorage=0;
115
116 if(use_fixed_storage(m_Size))
117 {
118 // Use fixed storage
119 DestStorage=&m_Storage.m_fixSet[0];
120 SrcStorage=&Other.m_Storage.m_fixSet[0];
121 }
122 else
123 {
124 // Use dynamic storage
125 m_Storage.m_dynSet=new set_value_type[m_Size];
126 DestStorage=m_Storage.m_dynSet;
127 SrcStorage=Other.m_Storage.m_dynSet;
128 }
129
130 // Use fixed storage
131 ::std::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size);
132 }
133
134 // Destructor
135 ~is_any_ofF()
136 {
137 if(!use_fixed_storage(m_Size) && m_Storage.m_dynSet!=0)
138 {
139 delete [] m_Storage.m_dynSet;
140 }
141 }
142
143 // Assignment
144 is_any_ofF& operator=(const is_any_ofF& Other)
145 {
146 // Handle self assignment
147 if(this==&Other) return *this;
148
149 // Prepare storage
150 const set_value_type* SrcStorage;
151 set_value_type* DestStorage;
152
153 if(use_fixed_storage(Other.m_Size))
154 {
155 // Use fixed storage
156 DestStorage=&m_Storage.m_fixSet[0];
157 SrcStorage=&Other.m_Storage.m_fixSet[0];
158
159 // Delete old storage if was present
160 if(!use_fixed_storage(m_Size) && m_Storage.m_dynSet!=0)
161 {
162 delete [] m_Storage.m_dynSet;
163 }
164
165 // Set new size
166 m_Size=Other.m_Size;
167 }
168 else
169 {
170 // Other uses dynamic storage
171 SrcStorage=Other.m_Storage.m_dynSet;
172
173 // Check what kind of storage are we using right now
174 if(use_fixed_storage(m_Size))
175 {
176 // Using fixed storage, allocate new
177 set_value_type* pTemp=new set_value_type[Other.m_Size];
178 DestStorage=pTemp;
179 m_Storage.m_dynSet=pTemp;
180 m_Size=Other.m_Size;
181 }
182 else
183 {
184 // Using dynamic storage, check if can reuse
185 if(m_Storage.m_dynSet!=0 && m_Size>=Other.m_Size && m_Size<Other.m_Size*2)
186 {
187 // Reuse the current storage
188 DestStorage=m_Storage.m_dynSet;
189 m_Size=Other.m_Size;
190 }
191 else
192 {
193 // Allocate the new one
194 set_value_type* pTemp=new set_value_type[Other.m_Size];
195 DestStorage=pTemp;
196
197 // Delete old storage if necessary
198 if(m_Storage.m_dynSet!=0)
199 {
200 delete [] m_Storage.m_dynSet;
201 }
202 // Store the new storage
203 m_Storage.m_dynSet=pTemp;
204 // Set new size
205 m_Size=Other.m_Size;
206 }
207 }
208 }
209
210 // Copy the data
211 ::std::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size);
212
213 return *this;
214 }
215
216 // Operation
217 template<typename Char2T>
218 bool operator()( Char2T Ch ) const
219 {
220 const set_value_type* Storage=
221 (use_fixed_storage(m_Size))
222 ? &m_Storage.m_fixSet[0]
223 : m_Storage.m_dynSet;
224
225 return ::std::binary_search(Storage, Storage+m_Size, Ch);
226 }
227 private:
228 // check if the size is eligible for fixed storage
229 static bool use_fixed_storage(std::size_t size)
230 {
231 return size<=sizeof(set_value_type*)*2;
232 }
233
234
235 private:
236 // storage
237 // The actual used storage is selected on the type
238 union
239 {
240 set_value_type* m_dynSet;
241 set_value_type m_fixSet[sizeof(set_value_type*)*2];
242 }
243 m_Storage;
244
245 // storage size
246 ::std::size_t m_Size;
247 };
248
249 // is_from_range functor
250 /*
251 returns true if the value is from the specified range.
252 (i.e. x>=From && x>=To)
253 */
254 template<typename CharT>
255 struct is_from_rangeF :
256 public predicate_facade< is_from_rangeF<CharT> >
257 {
258 // Boost.ResultOf support
259 typedef bool result_type;
260
261 // Constructor
262 is_from_rangeF( CharT From, CharT To ) : m_From(From), m_To(To) {}
263
264 // Operation
265 template<typename Char2T>
266 bool operator()( Char2T Ch ) const
267 {
268 return ( m_From <= Ch ) && ( Ch <= m_To );
269 }
270
271 private:
272 CharT m_From;
273 CharT m_To;
274 };
275
276 // class_and composition predicate
277 template<typename Pred1T, typename Pred2T>
278 struct pred_andF :
279 public predicate_facade< pred_andF<Pred1T,Pred2T> >
280 {
281 public:
282
283 // Boost.ResultOf support
284 typedef bool result_type;
285
286 // Constructor
287 pred_andF( Pred1T Pred1, Pred2T Pred2 ) :
288 m_Pred1(Pred1), m_Pred2(Pred2) {}
289
290 // Operation
291 template<typename CharT>
292 bool operator()( CharT Ch ) const
293 {
294 return m_Pred1(Ch) && m_Pred2(Ch);
295 }
296
297 private:
298 Pred1T m_Pred1;
299 Pred2T m_Pred2;
300 };
301
302 // class_or composition predicate
303 template<typename Pred1T, typename Pred2T>
304 struct pred_orF :
305 public predicate_facade< pred_orF<Pred1T,Pred2T> >
306 {
307 public:
308 // Boost.ResultOf support
309 typedef bool result_type;
310
311 // Constructor
312 pred_orF( Pred1T Pred1, Pred2T Pred2 ) :
313 m_Pred1(Pred1), m_Pred2(Pred2) {}
314
315 // Operation
316 template<typename CharT>
317 bool operator()( CharT Ch ) const
318 {
319 return m_Pred1(Ch) || m_Pred2(Ch);
320 }
321
322 private:
323 Pred1T m_Pred1;
324 Pred2T m_Pred2;
325 };
326
327 // class_not composition predicate
328 template< typename PredT >
329 struct pred_notF :
330 public predicate_facade< pred_notF<PredT> >
331 {
332 public:
333 // Boost.ResultOf support
334 typedef bool result_type;
335
336 // Constructor
337 pred_notF( PredT Pred ) : m_Pred(Pred) {}
338
339 // Operation
340 template<typename CharT>
341 bool operator()( CharT Ch ) const
342 {
343 return !m_Pred(Ch);
344 }
345
346 private:
347 PredT m_Pred;
348 };
349
350 } // namespace detail
351 } // namespace algorithm
352} // namespace boost
353
354
355#endif // BOOST_STRING_CLASSIFICATION_DETAIL_HPP

/usr/bin/../lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/basic_string.h

1// Components for manipulating sequences of characters -*- C++ -*-
2
3// Copyright (C) 1997-2024 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file bits/basic_string.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{string}
28 */
29
30//
31// ISO C++ 14882: 21 Strings library
32//
33
34#ifndef _BASIC_STRING_H1
35#define _BASIC_STRING_H1 1
36
37#pragma GCC system_header
38
39#include <ext/alloc_traits.h>
40#include <debug/debug.h>
41
42#if __cplusplus202002L >= 201103L
43#include <initializer_list>
44#endif
45
46#if __cplusplus202002L >= 201703L
47# include <string_view>
48#endif
49
50#if __cplusplus202002L > 202302L
51# include <charconv>
52#endif
53
54#include <bits/version.h>
55
56#if ! _GLIBCXX_USE_CXX11_ABI1
57# include "cow_string.h"
58#else
59
60namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
61{
62_GLIBCXX_BEGIN_NAMESPACE_VERSION
63_GLIBCXX_BEGIN_NAMESPACE_CXX11namespace __cxx11 {
64
65 /**
66 * @class basic_string basic_string.h <string>
67 * @brief Managing sequences of characters and character-like objects.
68 *
69 * @ingroup strings
70 * @ingroup sequences
71 * @headerfile string
72 * @since C++98
73 *
74 * @tparam _CharT Type of character
75 * @tparam _Traits Traits for character type, defaults to
76 * char_traits<_CharT>.
77 * @tparam _Alloc Allocator type, defaults to allocator<_CharT>.
78 *
79 * Meets the requirements of a <a href="tables.html#65">container</a>, a
80 * <a href="tables.html#66">reversible container</a>, and a
81 * <a href="tables.html#67">sequence</a>. Of the
82 * <a href="tables.html#68">optional sequence requirements</a>, only
83 * @c push_back, @c at, and @c %array access are supported.
84 */
85 template<typename _CharT, typename _Traits, typename _Alloc>
86 class basic_string
87 {
88#if __cplusplus202002L >= 202002L
89 static_assert(is_same_v<_CharT, typename _Traits::char_type>);
90 static_assert(is_same_v<_CharT, typename _Alloc::value_type>);
91 using _Char_alloc_type = _Alloc;
92#else
93 typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
94 rebind<_CharT>::other _Char_alloc_type;
95#endif
96
97 typedef __gnu_cxx::__alloc_traits<_Char_alloc_type> _Alloc_traits;
98
99 // Types:
100 public:
101 typedef _Traits traits_type;
102 typedef typename _Traits::char_type value_type;
103 typedef _Char_alloc_type allocator_type;
104 typedef typename _Alloc_traits::size_type size_type;
105 typedef typename _Alloc_traits::difference_type difference_type;
106 typedef typename _Alloc_traits::reference reference;
107 typedef typename _Alloc_traits::const_reference const_reference;
108 typedef typename _Alloc_traits::pointer pointer;
109 typedef typename _Alloc_traits::const_pointer const_pointer;
110 typedef __gnu_cxx::__normal_iterator<pointer, basic_string> iterator;
111 typedef __gnu_cxx::__normal_iterator<const_pointer, basic_string>
112 const_iterator;
113 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
114 typedef std::reverse_iterator<iterator> reverse_iterator;
115
116 /// Value returned by various member functions when they fail.
117 static const size_type npos = static_cast<size_type>(-1);
118
119 protected:
120 // type used for positions in insert, erase etc.
121#if __cplusplus202002L < 201103L
122 typedef iterator __const_iterator;
123#else
124 typedef const_iterator __const_iterator;
125#endif
126
127 private:
128 static _GLIBCXX20_CONSTEXPRconstexpr pointer
129 _S_allocate(_Char_alloc_type& __a, size_type __n)
130 {
131 pointer __p = _Alloc_traits::allocate(__a, __n);
132#if __glibcxx_constexpr_string201907L >= 201907L
133 // std::char_traits begins the lifetime of characters,
134 // but custom traits might not, so do it here.
135 if constexpr (!is_same_v<_Traits, char_traits<_CharT>>)
136 if (std::__is_constant_evaluated())
137 // Begin the lifetime of characters in allocated storage.
138 for (size_type __i = 0; __i < __n; ++__i)
139 std::construct_at(__builtin_addressof(__p[__i]));
140#endif
141 return __p;
142 }
143
144#if __cplusplus202002L >= 201703L
145 // A helper type for avoiding boiler-plate.
146 typedef basic_string_view<_CharT, _Traits> __sv_type;
147
148 template<typename _Tp, typename _Res>
149 using _If_sv = enable_if_t<
150 __and_<is_convertible<const _Tp&, __sv_type>,
151 __not_<is_convertible<const _Tp*, const basic_string*>>,
152 __not_<is_convertible<const _Tp&, const _CharT*>>>::value,
153 _Res>;
154
155 // Allows an implicit conversion to __sv_type.
156 _GLIBCXX20_CONSTEXPRconstexpr
157 static __sv_type
158 _S_to_string_view(__sv_type __svt) noexcept
159 { return __svt; }
160
161 // Wraps a string_view by explicit conversion and thus
162 // allows to add an internal constructor that does not
163 // participate in overload resolution when a string_view
164 // is provided.
165 struct __sv_wrapper
166 {
167 _GLIBCXX20_CONSTEXPRconstexpr explicit
168 __sv_wrapper(__sv_type __sv) noexcept : _M_sv(__sv) { }
169
170 __sv_type _M_sv;
171 };
172
173 /**
174 * @brief Only internally used: Construct string from a string view
175 * wrapper.
176 * @param __svw string view wrapper.
177 * @param __a Allocator to use.
178 */
179 _GLIBCXX20_CONSTEXPRconstexpr
180 explicit
181 basic_string(__sv_wrapper __svw, const _Alloc& __a)
182 : basic_string(__svw._M_sv.data(), __svw._M_sv.size(), __a) { }
183#endif
184
185 // Use empty-base optimization: http://www.cantrip.org/emptyopt.html
186 struct _Alloc_hider : allocator_type // TODO check __is_final
187 {
188#if __cplusplus202002L < 201103L
189 _Alloc_hider(pointer __dat, const _Alloc& __a = _Alloc())
190 : allocator_type(__a), _M_p(__dat) { }
191#else
192 _GLIBCXX20_CONSTEXPRconstexpr
193 _Alloc_hider(pointer __dat, const _Alloc& __a)
194 : allocator_type(__a), _M_p(__dat) { }
195
196 _GLIBCXX20_CONSTEXPRconstexpr
197 _Alloc_hider(pointer __dat, _Alloc&& __a = _Alloc())
198 : allocator_type(std::move(__a)), _M_p(__dat) { }
199#endif
200
201 pointer _M_p; // The actual data.
202 };
203
204 _Alloc_hider _M_dataplus;
205 size_type _M_string_length;
206
207 enum { _S_local_capacity = 15 / sizeof(_CharT) };
208
209 union
210 {
211 _CharT _M_local_buf[_S_local_capacity + 1];
212 size_type _M_allocated_capacity;
213 };
214
215 _GLIBCXX20_CONSTEXPRconstexpr
216 void
217 _M_data(pointer __p)
218 { _M_dataplus._M_p = __p; }
219
220 _GLIBCXX20_CONSTEXPRconstexpr
221 void
222 _M_length(size_type __length)
223 { _M_string_length = __length; }
224
225 _GLIBCXX20_CONSTEXPRconstexpr
226 pointer
227 _M_data() const
228 { return _M_dataplus._M_p; }
229
230 _GLIBCXX20_CONSTEXPRconstexpr
231 pointer
232 _M_local_data()
233 {
234#if __cplusplus202002L >= 201103L
235 return std::pointer_traits<pointer>::pointer_to(*_M_local_buf);
236#else
237 return pointer(_M_local_buf);
238#endif
239 }
240
241 _GLIBCXX20_CONSTEXPRconstexpr
242 const_pointer
243 _M_local_data() const
244 {
245#if __cplusplus202002L >= 201103L
246 return std::pointer_traits<const_pointer>::pointer_to(*_M_local_buf);
247#else
248 return const_pointer(_M_local_buf);
249#endif
250 }
251
252 _GLIBCXX20_CONSTEXPRconstexpr
253 void
254 _M_capacity(size_type __capacity)
255 { _M_allocated_capacity = __capacity; }
256
257 _GLIBCXX20_CONSTEXPRconstexpr
258 void
259 _M_set_length(size_type __n)
260 {
261 _M_length(__n);
262 traits_type::assign(_M_data()[__n], _CharT());
263 }
264
265 _GLIBCXX20_CONSTEXPRconstexpr
266 bool
267 _M_is_local() const
268 {
269 if (_M_data() == _M_local_data())
270 {
271 if (_M_string_length > _S_local_capacity)
272 __builtin_unreachable();
273 return true;
274 }
275 return false;
276 }
277
278 // Create & Destroy
279 _GLIBCXX20_CONSTEXPRconstexpr
280 pointer
281 _M_create(size_type&, size_type);
282
283 _GLIBCXX20_CONSTEXPRconstexpr
284 void
285 _M_dispose()
286 {
287 if (!_M_is_local())
288 _M_destroy(_M_allocated_capacity);
289 }
290
291 _GLIBCXX20_CONSTEXPRconstexpr
292 void
293 _M_destroy(size_type __size) throw()
294 { _Alloc_traits::deallocate(_M_get_allocator(), _M_data(), __size + 1); }
295
296#if __cplusplus202002L < 201103L || defined _GLIBCXX_DEFINING_STRING_INSTANTIATIONS
297 // _M_construct_aux is used to implement the 21.3.1 para 15 which
298 // requires special behaviour if _InIterator is an integral type
299 template<typename _InIterator>
300 void
301 _M_construct_aux(_InIterator __beg, _InIterator __end,
302 std::__false_type)
303 {
304 typedef typename iterator_traits<_InIterator>::iterator_category _Tag;
305 _M_construct(__beg, __end, _Tag());
306 }
307
308 // _GLIBCXX_RESOLVE_LIB_DEFECTS
309 // 438. Ambiguity in the "do the right thing" clause
310 template<typename _Integer>
311 void
312 _M_construct_aux(_Integer __beg, _Integer __end, std::__true_type)
313 { _M_construct_aux_2(static_cast<size_type>(__beg), __end); }
314
315 void
316 _M_construct_aux_2(size_type __req, _CharT __c)
317 { _M_construct(__req, __c); }
318#endif
319
320 // For Input Iterators, used in istreambuf_iterators, etc.
321 template<typename _InIterator>
322 _GLIBCXX20_CONSTEXPRconstexpr
323 void
324 _M_construct(_InIterator __beg, _InIterator __end,
325 std::input_iterator_tag);
326
327 // For forward_iterators up to random_access_iterators, used for
328 // string::iterator, _CharT*, etc.
329 template<typename _FwdIterator>
330 _GLIBCXX20_CONSTEXPRconstexpr
331 void
332 _M_construct(_FwdIterator __beg, _FwdIterator __end,
333 std::forward_iterator_tag);
334
335 _GLIBCXX20_CONSTEXPRconstexpr
336 void
337 _M_construct(size_type __req, _CharT __c);
338
339 _GLIBCXX20_CONSTEXPRconstexpr
340 allocator_type&
341 _M_get_allocator()
342 { return _M_dataplus; }
343
344 _GLIBCXX20_CONSTEXPRconstexpr
345 const allocator_type&
346 _M_get_allocator() const
347 { return _M_dataplus; }
348
349 // Ensure that _M_local_buf is the active member of the union.
350 __attribute__((__always_inline__))
351 _GLIBCXX14_CONSTEXPRconstexpr
352 void
353 _M_init_local_buf() _GLIBCXX_NOEXCEPTnoexcept
354 {
355#if __glibcxx_is_constant_evaluated201811L
356 if (std::is_constant_evaluated())
357 for (size_type __i = 0; __i <= _S_local_capacity; ++__i)
358 _M_local_buf[__i] = _CharT();
359#endif
360 }
361
362 __attribute__((__always_inline__))
363 _GLIBCXX14_CONSTEXPRconstexpr
364 pointer
365 _M_use_local_data() _GLIBCXX_NOEXCEPTnoexcept
366 {
367#if __cpp_lib_is_constant_evaluated201811L
368 _M_init_local_buf();
369#endif
370 return _M_local_data();
371 }
372
373 private:
374
375#ifdef _GLIBCXX_DISAMBIGUATE_REPLACE_INST
376 // The explicit instantiations in misc-inst.cc require this due to
377 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64063
378 template<typename _Tp, bool _Requires =
379 !__are_same<_Tp, _CharT*>::__value
380 && !__are_same<_Tp, const _CharT*>::__value
381 && !__are_same<_Tp, iterator>::__value
382 && !__are_same<_Tp, const_iterator>::__value>
383 struct __enable_if_not_native_iterator
384 { typedef basic_string& __type; };
385 template<typename _Tp>
386 struct __enable_if_not_native_iterator<_Tp, false> { };
387#endif
388
389 _GLIBCXX20_CONSTEXPRconstexpr
390 size_type
391 _M_check(size_type __pos, const char* __s) const
392 {
393 if (__pos > this->size())
394 __throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > "("%s: __pos (which is %zu) > " "this->size() (which is %zu)"
)
395 "this->size() (which is %zu)")("%s: __pos (which is %zu) > " "this->size() (which is %zu)"
)
,
396 __s, __pos, this->size());
397 return __pos;
398 }
399
400 _GLIBCXX20_CONSTEXPRconstexpr
401 void
402 _M_check_length(size_type __n1, size_type __n2, const char* __s) const
403 {
404 if (this->max_size() - (this->size() - __n1) < __n2)
405 __throw_length_error(__N(__s)(__s));
406 }
407
408
409 // NB: _M_limit doesn't check for a bad __pos value.
410 _GLIBCXX20_CONSTEXPRconstexpr
411 size_type
412 _M_limit(size_type __pos, size_type __off) const _GLIBCXX_NOEXCEPTnoexcept
413 {
414 const bool __testoff = __off < this->size() - __pos;
415 return __testoff ? __off : this->size() - __pos;
416 }
417
418 // True if _Rep and source do not overlap.
419 bool
420 _M_disjunct(const _CharT* __s) const _GLIBCXX_NOEXCEPTnoexcept
421 {
422 return (less<const _CharT*>()(__s, _M_data())
423 || less<const _CharT*>()(_M_data() + this->size(), __s));
424 }
425
426 // When __n = 1 way faster than the general multichar
427 // traits_type::copy/move/assign.
428 _GLIBCXX20_CONSTEXPRconstexpr
429 static void
430 _S_copy(_CharT* __d, const _CharT* __s, size_type __n)
431 {
432 if (__n == 1)
433 traits_type::assign(*__d, *__s);
434 else
435 traits_type::copy(__d, __s, __n);
436 }
437
438 _GLIBCXX20_CONSTEXPRconstexpr
439 static void
440 _S_move(_CharT* __d, const _CharT* __s, size_type __n)
441 {
442 if (__n == 1)
443 traits_type::assign(*__d, *__s);
444 else
445 traits_type::move(__d, __s, __n);
446 }
447
448 _GLIBCXX20_CONSTEXPRconstexpr
449 static void
450 _S_assign(_CharT* __d, size_type __n, _CharT __c)
451 {
452 if (__n == 1)
453 traits_type::assign(*__d, __c);
454 else
455 traits_type::assign(__d, __n, __c);
456 }
457
458 // _S_copy_chars is a separate template to permit specialization
459 // to optimize for the common case of pointers as iterators.
460 template<class _Iterator>
461 _GLIBCXX20_CONSTEXPRconstexpr
462 static void
463 _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2)
464 {
465 for (; __k1 != __k2; ++__k1, (void)++__p)
466 traits_type::assign(*__p, *__k1); // These types are off.
467 }
468
469 _GLIBCXX20_CONSTEXPRconstexpr
470 static void
471 _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2) _GLIBCXX_NOEXCEPTnoexcept
472 { _S_copy_chars(__p, __k1.base(), __k2.base()); }
473
474 _GLIBCXX20_CONSTEXPRconstexpr
475 static void
476 _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2)
477 _GLIBCXX_NOEXCEPTnoexcept
478 { _S_copy_chars(__p, __k1.base(), __k2.base()); }
479
480 _GLIBCXX20_CONSTEXPRconstexpr
481 static void
482 _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) _GLIBCXX_NOEXCEPTnoexcept
483 { _S_copy(__p, __k1, __k2 - __k1); }
484
485 _GLIBCXX20_CONSTEXPRconstexpr
486 static void
487 _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2)
488 _GLIBCXX_NOEXCEPTnoexcept
489 { _S_copy(__p, __k1, __k2 - __k1); }
490
491 _GLIBCXX20_CONSTEXPRconstexpr
492 static int
493 _S_compare(size_type __n1, size_type __n2) _GLIBCXX_NOEXCEPTnoexcept
494 {
495 const difference_type __d = difference_type(__n1 - __n2);
496
497 if (__d > __gnu_cxx::__numeric_traits<int>::__max)
498 return __gnu_cxx::__numeric_traits<int>::__max;
499 else if (__d < __gnu_cxx::__numeric_traits<int>::__min)
500 return __gnu_cxx::__numeric_traits<int>::__min;
501 else
502 return int(__d);
503 }
504
505 _GLIBCXX20_CONSTEXPRconstexpr
506 void
507 _M_assign(const basic_string&);
508
509 _GLIBCXX20_CONSTEXPRconstexpr
510 void
511 _M_mutate(size_type __pos, size_type __len1, const _CharT* __s,
512 size_type __len2);
513
514 _GLIBCXX20_CONSTEXPRconstexpr
515 void
516 _M_erase(size_type __pos, size_type __n);
517
518 public:
519 // Construct/copy/destroy:
520 // NB: We overload ctors in some cases instead of using default
521 // arguments, per 17.4.4.4 para. 2 item 2.
522
523 /**
524 * @brief Default constructor creates an empty string.
525 */
526 _GLIBCXX20_CONSTEXPRconstexpr
527 basic_string()
528 _GLIBCXX_NOEXCEPT_IF(is_nothrow_default_constructible<_Alloc>::value)noexcept(is_nothrow_default_constructible<_Alloc>::value
)
529 : _M_dataplus(_M_local_data())
530 {
531 _M_init_local_buf();
532 _M_set_length(0);
533 }
534
535 /**
536 * @brief Construct an empty string using allocator @a a.
537 */
538 _GLIBCXX20_CONSTEXPRconstexpr
539 explicit
540 basic_string(const _Alloc& __a) _GLIBCXX_NOEXCEPTnoexcept
541 : _M_dataplus(_M_local_data(), __a)
542 {
543 _M_init_local_buf();
544 _M_set_length(0);
545 }
546
547 /**
548 * @brief Construct string with copy of value of @a __str.
549 * @param __str Source string.
550 */
551 _GLIBCXX20_CONSTEXPRconstexpr
552 basic_string(const basic_string& __str)
553 : _M_dataplus(_M_local_data(),
554 _Alloc_traits::_S_select_on_copy(__str._M_get_allocator()))
555 {
556 _M_construct(__str._M_data(), __str._M_data() + __str.length(),
557 std::forward_iterator_tag());
558 }
559
560 // _GLIBCXX_RESOLVE_LIB_DEFECTS
561 // 2583. no way to supply an allocator for basic_string(str, pos)
562 /**
563 * @brief Construct string as copy of a substring.
564 * @param __str Source string.
565 * @param __pos Index of first character to copy from.
566 * @param __a Allocator to use.
567 */
568 _GLIBCXX20_CONSTEXPRconstexpr
569 basic_string(const basic_string& __str, size_type __pos,
570 const _Alloc& __a = _Alloc())
571 : _M_dataplus(_M_local_data(), __a)
572 {
573 const _CharT* __start = __str._M_data()
574 + __str._M_check(__pos, "basic_string::basic_string");
575 _M_construct(__start, __start + __str._M_limit(__pos, npos),
576 std::forward_iterator_tag());
577 }
578
579 /**
580 * @brief Construct string as copy of a substring.
581 * @param __str Source string.
582 * @param __pos Index of first character to copy from.
583 * @param __n Number of characters to copy.
584 */
585 _GLIBCXX20_CONSTEXPRconstexpr
586 basic_string(const basic_string& __str, size_type __pos,
587 size_type __n)
588 : _M_dataplus(_M_local_data())
589 {
590 const _CharT* __start = __str._M_data()
591 + __str._M_check(__pos, "basic_string::basic_string");
592 _M_construct(__start, __start + __str._M_limit(__pos, __n),
593 std::forward_iterator_tag());
594 }
595
596 /**
597 * @brief Construct string as copy of a substring.
598 * @param __str Source string.
599 * @param __pos Index of first character to copy from.
600 * @param __n Number of characters to copy.
601 * @param __a Allocator to use.
602 */
603 _GLIBCXX20_CONSTEXPRconstexpr
604 basic_string(const basic_string& __str, size_type __pos,
605 size_type __n, const _Alloc& __a)
606 : _M_dataplus(_M_local_data(), __a)
607 {
608 const _CharT* __start
609 = __str._M_data() + __str._M_check(__pos, "string::string");
610 _M_construct(__start, __start + __str._M_limit(__pos, __n),
611 std::forward_iterator_tag());
612 }
613
614 /**
615 * @brief Construct string initialized by a character %array.
616 * @param __s Source character %array.
617 * @param __n Number of characters to copy.
618 * @param __a Allocator to use (default is default allocator).
619 *
620 * NB: @a __s must have at least @a __n characters, &apos;\\0&apos;
621 * has no special meaning.
622 */
623 _GLIBCXX20_CONSTEXPRconstexpr
624 basic_string(const _CharT* __s, size_type __n,
625 const _Alloc& __a = _Alloc())
626 : _M_dataplus(_M_local_data(), __a)
627 {
628 // NB: Not required, but considered best practice.
629 if (__s == 0 && __n > 0)
630 std::__throw_logic_error(__N("basic_string: "("basic_string: " "construction from null is not valid")
631 "construction from null is not valid")("basic_string: " "construction from null is not valid"));
632 _M_construct(__s, __s + __n, std::forward_iterator_tag());
633 }
634
635 /**
636 * @brief Construct string as copy of a C string.
637 * @param __s Source C string.
638 * @param __a Allocator to use (default is default allocator).
639 */
640#if __cpp_deduction_guides201703L && ! defined _GLIBCXX_DEFINING_STRING_INSTANTIATIONS
641 // _GLIBCXX_RESOLVE_LIB_DEFECTS
642 // 3076. basic_string CTAD ambiguity
643 template<typename = _RequireAllocator<_Alloc>>
644#endif
645 _GLIBCXX20_CONSTEXPRconstexpr
646 basic_string(const _CharT* __s, const _Alloc& __a = _Alloc())
647 : _M_dataplus(_M_local_data(), __a)
648 {
649 // NB: Not required, but considered best practice.
650 if (__s == 0)
651 std::__throw_logic_error(__N("basic_string: "("basic_string: " "construction from null is not valid")
652 "construction from null is not valid")("basic_string: " "construction from null is not valid"));
653 const _CharT* __end = __s + traits_type::length(__s);
654 _M_construct(__s, __end, forward_iterator_tag());
655 }
656
657 /**
658 * @brief Construct string as multiple characters.
659 * @param __n Number of characters.
660 * @param __c Character to use.
661 * @param __a Allocator to use (default is default allocator).
662 */
663#if __cpp_deduction_guides201703L && ! defined _GLIBCXX_DEFINING_STRING_INSTANTIATIONS
664 // _GLIBCXX_RESOLVE_LIB_DEFECTS
665 // 3076. basic_string CTAD ambiguity
666 template<typename = _RequireAllocator<_Alloc>>
667#endif
668 _GLIBCXX20_CONSTEXPRconstexpr
669 basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc())
670 : _M_dataplus(_M_local_data(), __a)
671 { _M_construct(__n, __c); }
672
673#if __cplusplus202002L >= 201103L
674 /**
675 * @brief Move construct string.
676 * @param __str Source string.
677 *
678 * The newly-created string contains the exact contents of @a __str.
679 * @a __str is a valid, but unspecified string.
680 */
681 _GLIBCXX20_CONSTEXPRconstexpr
682 basic_string(basic_string&& __str) noexcept
683 : _M_dataplus(_M_local_data(), std::move(__str._M_get_allocator()))
684 {
685 if (__str._M_is_local())
686 {
687 _M_init_local_buf();
688 traits_type::copy(_M_local_buf, __str._M_local_buf,
689 __str.length() + 1);
690 }
691 else
692 {
693 _M_data(__str._M_data());
694 _M_capacity(__str._M_allocated_capacity);
695 }
696
697 // Must use _M_length() here not _M_set_length() because
698 // basic_stringbuf relies on writing into unallocated capacity so
699 // we mess up the contents if we put a '\0' in the string.
700 _M_length(__str.length());
701 __str._M_data(__str._M_use_local_data());
702 __str._M_set_length(0);
703 }
704
705 /**
706 * @brief Construct string from an initializer %list.
707 * @param __l std::initializer_list of characters.
708 * @param __a Allocator to use (default is default allocator).
709 */
710 _GLIBCXX20_CONSTEXPRconstexpr
711 basic_string(initializer_list<_CharT> __l, const _Alloc& __a = _Alloc())
712 : _M_dataplus(_M_local_data(), __a)
713 { _M_construct(__l.begin(), __l.end(), std::forward_iterator_tag()); }
714
715 _GLIBCXX20_CONSTEXPRconstexpr
716 basic_string(const basic_string& __str, const _Alloc& __a)
717 : _M_dataplus(_M_local_data(), __a)
718 { _M_construct(__str.begin(), __str.end(), std::forward_iterator_tag()); }
719
720 _GLIBCXX20_CONSTEXPRconstexpr
721 basic_string(basic_string&& __str, const _Alloc& __a)
722 noexcept(_Alloc_traits::_S_always_equal())
723 : _M_dataplus(_M_local_data(), __a)
724 {
725 if (__str._M_is_local())
726 {
727 _M_init_local_buf();
728 traits_type::copy(_M_local_buf, __str._M_local_buf,
729 __str.length() + 1);
730 _M_length(__str.length());
731 __str._M_set_length(0);
732 }
733 else if (_Alloc_traits::_S_always_equal()
734 || __str.get_allocator() == __a)
735 {
736 _M_data(__str._M_data());
737 _M_length(__str.length());
738 _M_capacity(__str._M_allocated_capacity);
739 __str._M_data(__str._M_use_local_data());
740 __str._M_set_length(0);
741 }
742 else
743 _M_construct(__str.begin(), __str.end(), std::forward_iterator_tag());
744 }
745#endif // C++11
746
747#if __cplusplus202002L >= 202100L
748 basic_string(nullptr_t) = delete;
749 basic_string& operator=(nullptr_t) = delete;
750#endif // C++23
751
752 /**
753 * @brief Construct string as copy of a range.
754 * @param __beg Start of range.
755 * @param __end End of range.
756 * @param __a Allocator to use (default is default allocator).
757 */
758#if __cplusplus202002L >= 201103L
759 template<typename _InputIterator,
760 typename = std::_RequireInputIter<_InputIterator>>
761#else
762 template<typename _InputIterator>
763#endif
764 _GLIBCXX20_CONSTEXPRconstexpr
765 basic_string(_InputIterator __beg, _InputIterator __end,
766 const _Alloc& __a = _Alloc())
767 : _M_dataplus(_M_local_data(), __a), _M_string_length(0)
768 {
769#if __cplusplus202002L >= 201103L
770 _M_construct(__beg, __end, std::__iterator_category(__beg));
771#else
772 typedef typename std::__is_integer<_InputIterator>::__type _Integral;
773 _M_construct_aux(__beg, __end, _Integral());
774#endif
775 }
776
777#if __cplusplus202002L >= 201703L
778 /**
779 * @brief Construct string from a substring of a string_view.
780 * @param __t Source object convertible to string view.
781 * @param __pos The index of the first character to copy from __t.
782 * @param __n The number of characters to copy from __t.
783 * @param __a Allocator to use.
784 */
785 template<typename _Tp,
786 typename = enable_if_t<is_convertible_v<const _Tp&, __sv_type>>>
787 _GLIBCXX20_CONSTEXPRconstexpr
788 basic_string(const _Tp& __t, size_type __pos, size_type __n,
789 const _Alloc& __a = _Alloc())
790 : basic_string(_S_to_string_view(__t).substr(__pos, __n), __a) { }
791
792 /**
793 * @brief Construct string from a string_view.
794 * @param __t Source object convertible to string view.
795 * @param __a Allocator to use (default is default allocator).
796 */
797 template<typename _Tp, typename = _If_sv<_Tp, void>>
798 _GLIBCXX20_CONSTEXPRconstexpr
799 explicit
800 basic_string(const _Tp& __t, const _Alloc& __a = _Alloc())
801 : basic_string(__sv_wrapper(_S_to_string_view(__t)), __a) { }
802#endif // C++17
803
804 /**
805 * @brief Destroy the string instance.
806 */
807 _GLIBCXX20_CONSTEXPRconstexpr
808 ~basic_string()
809 { _M_dispose(); }
810
811 /**
812 * @brief Assign the value of @a str to this string.
813 * @param __str Source string.
814 */
815 _GLIBCXX20_CONSTEXPRconstexpr
816 basic_string&
817 operator=(const basic_string& __str)
818 {
819 return this->assign(__str);
820 }
821
822 /**
823 * @brief Copy contents of @a s into this string.
824 * @param __s Source null-terminated string.
825 */
826 _GLIBCXX20_CONSTEXPRconstexpr
827 basic_string&
828 operator=(const _CharT* __s)
829 { return this->assign(__s); }
830
831 /**
832 * @brief Set value to string of length 1.
833 * @param __c Source character.
834 *
835 * Assigning to a character makes this string length 1 and
836 * (*this)[0] == @a c.
837 */
838 _GLIBCXX20_CONSTEXPRconstexpr
839 basic_string&
840 operator=(_CharT __c)
841 {
842 this->assign(1, __c);
843 return *this;
844 }
845
846#if __cplusplus202002L >= 201103L
847 /**
848 * @brief Move assign the value of @a str to this string.
849 * @param __str Source string.
850 *
851 * The contents of @a str are moved into this string (without copying).
852 * @a str is a valid, but unspecified string.
853 */
854 // _GLIBCXX_RESOLVE_LIB_DEFECTS
855 // 2063. Contradictory requirements for string move assignment
856 _GLIBCXX20_CONSTEXPRconstexpr
857 basic_string&
858 operator=(basic_string&& __str)
859 noexcept(_Alloc_traits::_S_nothrow_move())
860 {
861 const bool __equal_allocs = _Alloc_traits::_S_always_equal()
862 || _M_get_allocator() == __str._M_get_allocator();
863 if (!_M_is_local() && _Alloc_traits::_S_propagate_on_move_assign()
864 && !__equal_allocs)
865 {
866 // Destroy existing storage before replacing allocator.
867 _M_destroy(_M_allocated_capacity);
868 _M_data(_M_local_data());
869 _M_set_length(0);
870 }
871 // Replace allocator if POCMA is true.
872 std::__alloc_on_move(_M_get_allocator(), __str._M_get_allocator());
873
874 if (__str._M_is_local())
875 {
876 // We've always got room for a short string, just copy it
877 // (unless this is a self-move, because that would violate the
878 // char_traits::copy precondition that the ranges don't overlap).
879 if (__builtin_expect(std::__addressof(__str) != this, true))
880 {
881 if (__str.size())
882 this->_S_copy(_M_data(), __str._M_data(), __str.size());
883 _M_set_length(__str.size());
884 }
885 }
886 else if (_Alloc_traits::_S_propagate_on_move_assign() || __equal_allocs)
887 {
888 // Just move the allocated pointer, our allocator can free it.
889 pointer __data = nullptr;
890 size_type __capacity;
891 if (!_M_is_local())
892 {
893 if (__equal_allocs)
894 {
895 // __str can reuse our existing storage.
896 __data = _M_data();
897 __capacity = _M_allocated_capacity;
898 }
899 else // __str can't use it, so free it.
900 _M_destroy(_M_allocated_capacity);
901 }
902
903 _M_data(__str._M_data());
904 _M_length(__str.length());
905 _M_capacity(__str._M_allocated_capacity);
906 if (__data)
907 {
908 __str._M_data(__data);
909 __str._M_capacity(__capacity);
910 }
911 else
912 __str._M_data(__str._M_use_local_data());
913 }
914 else // Need to do a deep copy
915 assign(__str);
916 __str.clear();
917 return *this;
918 }
919
920 /**
921 * @brief Set value to string constructed from initializer %list.
922 * @param __l std::initializer_list.
923 */
924 _GLIBCXX20_CONSTEXPRconstexpr
925 basic_string&
926 operator=(initializer_list<_CharT> __l)
927 {
928 this->assign(__l.begin(), __l.size());
929 return *this;
930 }
931#endif // C++11
932
933#if __cplusplus202002L >= 201703L
934 /**
935 * @brief Set value to string constructed from a string_view.
936 * @param __svt An object convertible to string_view.
937 */
938 template<typename _Tp>
939 _GLIBCXX20_CONSTEXPRconstexpr
940 _If_sv<_Tp, basic_string&>
941 operator=(const _Tp& __svt)
942 { return this->assign(__svt); }
943
944 /**
945 * @brief Convert to a string_view.
946 * @return A string_view.
947 */
948 _GLIBCXX20_CONSTEXPRconstexpr
949 operator __sv_type() const noexcept
950 { return __sv_type(data(), size()); }
951#endif // C++17
952
953 // Iterators:
954 /**
955 * Returns a read/write iterator that points to the first character in
956 * the %string.
957 */
958 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
959 iterator
960 begin() _GLIBCXX_NOEXCEPTnoexcept
961 { return iterator(_M_data()); }
962
963 /**
964 * Returns a read-only (constant) iterator that points to the first
965 * character in the %string.
966 */
967 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
968 const_iterator
969 begin() const _GLIBCXX_NOEXCEPTnoexcept
970 { return const_iterator(_M_data()); }
971
972 /**
973 * Returns a read/write iterator that points one past the last
974 * character in the %string.
975 */
976 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
977 iterator
978 end() _GLIBCXX_NOEXCEPTnoexcept
979 { return iterator(_M_data() + this->size()); }
980
981 /**
982 * Returns a read-only (constant) iterator that points one past the
983 * last character in the %string.
984 */
985 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
986 const_iterator
987 end() const _GLIBCXX_NOEXCEPTnoexcept
988 { return const_iterator(_M_data() + this->size()); }
989
990 /**
991 * Returns a read/write reverse iterator that points to the last
992 * character in the %string. Iteration is done in reverse element
993 * order.
994 */
995 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
996 reverse_iterator
997 rbegin() _GLIBCXX_NOEXCEPTnoexcept
998 { return reverse_iterator(this->end()); }
999
1000 /**
1001 * Returns a read-only (constant) reverse iterator that points
1002 * to the last character in the %string. Iteration is done in
1003 * reverse element order.
1004 */
1005 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
1006 const_reverse_iterator
1007 rbegin() const _GLIBCXX_NOEXCEPTnoexcept
1008 { return const_reverse_iterator(this->end()); }
1009
1010 /**
1011 * Returns a read/write reverse iterator that points to one before the
1012 * first character in the %string. Iteration is done in reverse
1013 * element order.
1014 */
1015 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
1016 reverse_iterator
1017 rend() _GLIBCXX_NOEXCEPTnoexcept
1018 { return reverse_iterator(this->begin()); }
1019
1020 /**
1021 * Returns a read-only (constant) reverse iterator that points
1022 * to one before the first character in the %string. Iteration
1023 * is done in reverse element order.
1024 */
1025 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
1026 const_reverse_iterator
1027 rend() const _GLIBCXX_NOEXCEPTnoexcept
1028 { return const_reverse_iterator(this->begin()); }
1029
1030#if __cplusplus202002L >= 201103L
1031 /**
1032 * Returns a read-only (constant) iterator that points to the first
1033 * character in the %string.
1034 */
1035 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
1036 const_iterator
1037 cbegin() const noexcept
1038 { return const_iterator(this->_M_data()); }
1039
1040 /**
1041 * Returns a read-only (constant) iterator that points one past the
1042 * last character in the %string.
1043 */
1044 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
1045 const_iterator
1046 cend() const noexcept
1047 { return const_iterator(this->_M_data() + this->size()); }
1048
1049 /**
1050 * Returns a read-only (constant) reverse iterator that points
1051 * to the last character in the %string. Iteration is done in
1052 * reverse element order.
1053 */
1054 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
1055 const_reverse_iterator
1056 crbegin() const noexcept
1057 { return const_reverse_iterator(this->end()); }
1058
1059 /**
1060 * Returns a read-only (constant) reverse iterator that points
1061 * to one before the first character in the %string. Iteration
1062 * is done in reverse element order.
1063 */
1064 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
1065 const_reverse_iterator
1066 crend() const noexcept
1067 { return const_reverse_iterator(this->begin()); }
1068#endif
1069
1070 public:
1071 // Capacity:
1072 /// Returns the number of characters in the string, not including any
1073 /// null-termination.
1074 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
1075 size_type
1076 size() const _GLIBCXX_NOEXCEPTnoexcept
1077 { return _M_string_length; }
1078
1079 /// Returns the number of characters in the string, not including any
1080 /// null-termination.
1081 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
1082 size_type
1083 length() const _GLIBCXX_NOEXCEPTnoexcept
1084 { return _M_string_length; }
1085
1086 /// Returns the size() of the largest possible %string.
1087 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
1088 size_type
1089 max_size() const _GLIBCXX_NOEXCEPTnoexcept
1090 { return (_Alloc_traits::max_size(_M_get_allocator()) - 1) / 2; }
1091
1092 /**
1093 * @brief Resizes the %string to the specified number of characters.
1094 * @param __n Number of characters the %string should contain.
1095 * @param __c Character to fill any new elements.
1096 *
1097 * This function will %resize the %string to the specified
1098 * number of characters. If the number is smaller than the
1099 * %string's current size the %string is truncated, otherwise
1100 * the %string is extended and new elements are %set to @a __c.
1101 */
1102 _GLIBCXX20_CONSTEXPRconstexpr
1103 void
1104 resize(size_type __n, _CharT __c);
1105
1106 /**
1107 * @brief Resizes the %string to the specified number of characters.
1108 * @param __n Number of characters the %string should contain.
1109 *
1110 * This function will resize the %string to the specified length. If
1111 * the new size is smaller than the %string's current size the %string
1112 * is truncated, otherwise the %string is extended and new characters
1113 * are default-constructed. For basic types such as char, this means
1114 * setting them to 0.
1115 */
1116 _GLIBCXX20_CONSTEXPRconstexpr
1117 void
1118 resize(size_type __n)
1119 { this->resize(__n, _CharT()); }
1120
1121#if __cplusplus202002L >= 201103L
1122#pragma GCC diagnostic push
1123#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1124 /// A non-binding request to reduce capacity() to size().
1125 _GLIBCXX20_CONSTEXPRconstexpr
1126 void
1127 shrink_to_fit() noexcept
1128 { reserve(); }
1129#pragma GCC diagnostic pop
1130#endif
1131
1132#ifdef __glibcxx_string_resize_and_overwrite // C++ >= 23
1133 /** Resize the string and call a function to fill it.
1134 *
1135 * @param __n The maximum size requested.
1136 * @param __op A callable object that writes characters to the string.
1137 *
1138 * This is a low-level function that is easy to misuse, be careful.
1139 *
1140 * Calling `str.resize_and_overwrite(n, op)` will reserve at least `n`
1141 * characters in `str`, evaluate `n2 = std::move(op)(str.data(), n)`,
1142 * and finally set the string length to `n2` (adding a null terminator
1143 * at the end). The function object `op` is allowed to write to the
1144 * extra capacity added by the initial reserve operation, which is not
1145 * allowed if you just call `str.reserve(n)` yourself.
1146 *
1147 * This can be used to efficiently fill a `string` buffer without the
1148 * overhead of zero-initializing characters that will be overwritten
1149 * anyway.
1150 *
1151 * The callable `op` must not access the string directly (only through
1152 * the pointer passed as its first argument), must not write more than
1153 * `n` characters to the string, must return a value no greater than `n`,
1154 * and must ensure that all characters up to the returned length are
1155 * valid after it returns (i.e. there must be no uninitialized values
1156 * left in the string after the call, because accessing them would
1157 * have undefined behaviour). If `op` exits by throwing an exception
1158 * the behaviour is undefined.
1159 *
1160 * @since C++23
1161 */
1162 template<typename _Operation>
1163 constexpr void
1164 resize_and_overwrite(size_type __n, _Operation __op);
1165#endif
1166
1167#if __cplusplus202002L >= 201103L
1168 /// Non-standard version of resize_and_overwrite for C++11 and above.
1169 template<typename _Operation>
1170 _GLIBCXX20_CONSTEXPRconstexpr void
1171 __resize_and_overwrite(size_type __n, _Operation __op);
1172#endif
1173
1174 /**
1175 * Returns the total number of characters that the %string can hold
1176 * before needing to allocate more memory.
1177 */
1178 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
1179 size_type
1180 capacity() const _GLIBCXX_NOEXCEPTnoexcept
1181 {
1182 return _M_is_local() ? size_type(_S_local_capacity)
1183 : _M_allocated_capacity;
1184 }
1185
1186 /**
1187 * @brief Attempt to preallocate enough memory for specified number of
1188 * characters.
1189 * @param __res_arg Number of characters required.
1190 * @throw std::length_error If @a __res_arg exceeds @c max_size().
1191 *
1192 * This function attempts to reserve enough memory for the
1193 * %string to hold the specified number of characters. If the
1194 * number requested is more than max_size(), length_error is
1195 * thrown.
1196 *
1197 * The advantage of this function is that if optimal code is a
1198 * necessity and the user can determine the string length that will be
1199 * required, the user can reserve the memory in %advance, and thus
1200 * prevent a possible reallocation of memory and copying of %string
1201 * data.
1202 */
1203 _GLIBCXX20_CONSTEXPRconstexpr
1204 void
1205 reserve(size_type __res_arg);
1206
1207 /**
1208 * Equivalent to shrink_to_fit().
1209 */
1210#if __cplusplus202002L > 201703L
1211 [[deprecated("use shrink_to_fit() instead")]]
1212#endif
1213 _GLIBCXX20_CONSTEXPRconstexpr
1214 void
1215 reserve();
1216
1217 /**
1218 * Erases the string, making it empty.
1219 */
1220 _GLIBCXX20_CONSTEXPRconstexpr
1221 void
1222 clear() _GLIBCXX_NOEXCEPTnoexcept
1223 { _M_set_length(0); }
1224
1225 /**
1226 * Returns true if the %string is empty. Equivalent to
1227 * <code>*this == ""</code>.
1228 */
1229 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
1230 bool
1231 empty() const _GLIBCXX_NOEXCEPTnoexcept
1232 { return this->size() == 0; }
1233
1234 // Element access:
1235 /**
1236 * @brief Subscript access to the data contained in the %string.
1237 * @param __pos The index of the character to access.
1238 * @return Read-only (constant) reference to the character.
1239 *
1240 * This operator allows for easy, array-style, data access.
1241 * Note that data access with this operator is unchecked and
1242 * out_of_range lookups are not defined. (For checked lookups
1243 * see at().)
1244 */
1245 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
1246 const_reference
1247 operator[] (size_type __pos) const _GLIBCXX_NOEXCEPTnoexcept
1248 {
1249 __glibcxx_assert(__pos <= size())do { if (std::__is_constant_evaluated()) if (__builtin_expect
(!bool(__pos <= size()), false)) std::__glibcxx_assert_fail
(); } while (false)
;
1250 return _M_data()[__pos];
1251 }
1252
1253 /**
1254 * @brief Subscript access to the data contained in the %string.
1255 * @param __pos The index of the character to access.
1256 * @return Read/write reference to the character.
1257 *
1258 * This operator allows for easy, array-style, data access.
1259 * Note that data access with this operator is unchecked and
1260 * out_of_range lookups are not defined. (For checked lookups
1261 * see at().)
1262 */
1263 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
1264 reference
1265 operator[](size_type __pos)
1266 {
1267 // Allow pos == size() both in C++98 mode, as v3 extension,
1268 // and in C++11 mode.
1269 __glibcxx_assert(__pos <= size())do { if (std::__is_constant_evaluated()) if (__builtin_expect
(!bool(__pos <= size()), false)) std::__glibcxx_assert_fail
(); } while (false)
;
1270 // In pedantic mode be strict in C++98 mode.
1271 _GLIBCXX_DEBUG_PEDASSERT(__cplusplus >= 201103L || __pos < size());
1272 return _M_data()[__pos];
1273 }
1274
1275 /**
1276 * @brief Provides access to the data contained in the %string.
1277 * @param __n The index of the character to access.
1278 * @return Read-only (const) reference to the character.
1279 * @throw std::out_of_range If @a n is an invalid index.
1280 *
1281 * This function provides for safer data access. The parameter is
1282 * first checked that it is in the range of the string. The function
1283 * throws out_of_range if the check fails.
1284 */
1285 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
1286 const_reference
1287 at(size_type __n) const
1288 {
1289 if (__n >= this->size())
1290 __throw_out_of_range_fmt(__N("basic_string::at: __n "("basic_string::at: __n " "(which is %zu) >= this->size() "
"(which is %zu)")
1291 "(which is %zu) >= this->size() "("basic_string::at: __n " "(which is %zu) >= this->size() "
"(which is %zu)")
1292 "(which is %zu)")("basic_string::at: __n " "(which is %zu) >= this->size() "
"(which is %zu)")
,
1293 __n, this->size());
1294 return _M_data()[__n];
1295 }
1296
1297 /**
1298 * @brief Provides access to the data contained in the %string.
1299 * @param __n The index of the character to access.
1300 * @return Read/write reference to the character.
1301 * @throw std::out_of_range If @a n is an invalid index.
1302 *
1303 * This function provides for safer data access. The parameter is
1304 * first checked that it is in the range of the string. The function
1305 * throws out_of_range if the check fails.
1306 */
1307 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
1308 reference
1309 at(size_type __n)
1310 {
1311 if (__n >= size())
1312 __throw_out_of_range_fmt(__N("basic_string::at: __n "("basic_string::at: __n " "(which is %zu) >= this->size() "
"(which is %zu)")
1313 "(which is %zu) >= this->size() "("basic_string::at: __n " "(which is %zu) >= this->size() "
"(which is %zu)")
1314 "(which is %zu)")("basic_string::at: __n " "(which is %zu) >= this->size() "
"(which is %zu)")
,
1315 __n, this->size());
1316 return _M_data()[__n];
1317 }
1318
1319#if __cplusplus202002L >= 201103L
1320 /**
1321 * Returns a read/write reference to the data at the first
1322 * element of the %string.
1323 */
1324 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
1325 reference
1326 front() noexcept
1327 {
1328 __glibcxx_assert(!empty())do { if (std::__is_constant_evaluated()) if (__builtin_expect
(!bool(!empty()), false)) std::__glibcxx_assert_fail(); } while
(false)
;
1329 return operator[](0);
1330 }
1331
1332 /**
1333 * Returns a read-only (constant) reference to the data at the first
1334 * element of the %string.
1335 */
1336 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
1337 const_reference
1338 front() const noexcept
1339 {
1340 __glibcxx_assert(!empty())do { if (std::__is_constant_evaluated()) if (__builtin_expect
(!bool(!empty()), false)) std::__glibcxx_assert_fail(); } while
(false)
;
1341 return operator[](0);
1342 }
1343
1344 /**
1345 * Returns a read/write reference to the data at the last
1346 * element of the %string.
1347 */
1348 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
1349 reference
1350 back() noexcept
1351 {
1352 __glibcxx_assert(!empty())do { if (std::__is_constant_evaluated()) if (__builtin_expect
(!bool(!empty()), false)) std::__glibcxx_assert_fail(); } while
(false)
;
1353 return operator[](this->size() - 1);
1354 }
1355
1356 /**
1357 * Returns a read-only (constant) reference to the data at the
1358 * last element of the %string.
1359 */
1360 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
1361 const_reference
1362 back() const noexcept
1363 {
1364 __glibcxx_assert(!empty())do { if (std::__is_constant_evaluated()) if (__builtin_expect
(!bool(!empty()), false)) std::__glibcxx_assert_fail(); } while
(false)
;
1365 return operator[](this->size() - 1);
1366 }
1367#endif
1368
1369 // Modifiers:
1370 /**
1371 * @brief Append a string to this string.
1372 * @param __str The string to append.
1373 * @return Reference to this string.
1374 */
1375 _GLIBCXX20_CONSTEXPRconstexpr
1376 basic_string&
1377 operator+=(const basic_string& __str)
1378 { return this->append(__str); }
1379
1380 /**
1381 * @brief Append a C string.
1382 * @param __s The C string to append.
1383 * @return Reference to this string.
1384 */
1385 _GLIBCXX20_CONSTEXPRconstexpr
1386 basic_string&
1387 operator+=(const _CharT* __s)
1388 { return this->append(__s); }
1389
1390 /**
1391 * @brief Append a character.
1392 * @param __c The character to append.
1393 * @return Reference to this string.
1394 */
1395 _GLIBCXX20_CONSTEXPRconstexpr
1396 basic_string&
1397 operator+=(_CharT __c)
1398 {
1399 this->push_back(__c);
1400 return *this;
1401 }
1402
1403#if __cplusplus202002L >= 201103L
1404 /**
1405 * @brief Append an initializer_list of characters.
1406 * @param __l The initializer_list of characters to be appended.
1407 * @return Reference to this string.
1408 */
1409 _GLIBCXX20_CONSTEXPRconstexpr
1410 basic_string&
1411 operator+=(initializer_list<_CharT> __l)
1412 { return this->append(__l.begin(), __l.size()); }
1413#endif // C++11
1414
1415#if __cplusplus202002L >= 201703L
1416 /**
1417 * @brief Append a string_view.
1418 * @param __svt An object convertible to string_view to be appended.
1419 * @return Reference to this string.
1420 */
1421 template<typename _Tp>
1422 _GLIBCXX20_CONSTEXPRconstexpr
1423 _If_sv<_Tp, basic_string&>
1424 operator+=(const _Tp& __svt)
1425 { return this->append(__svt); }
1426#endif // C++17
1427
1428 /**
1429 * @brief Append a string to this string.
1430 * @param __str The string to append.
1431 * @return Reference to this string.
1432 */
1433 _GLIBCXX20_CONSTEXPRconstexpr
1434 basic_string&
1435 append(const basic_string& __str)
1436 { return this->append(__str._M_data(), __str.size()); }
1437
1438 /**
1439 * @brief Append a substring.
1440 * @param __str The string to append.
1441 * @param __pos Index of the first character of str to append.
1442 * @param __n The number of characters to append.
1443 * @return Reference to this string.
1444 * @throw std::out_of_range if @a __pos is not a valid index.
1445 *
1446 * This function appends @a __n characters from @a __str
1447 * starting at @a __pos to this string. If @a __n is is larger
1448 * than the number of available characters in @a __str, the
1449 * remainder of @a __str is appended.
1450 */
1451 _GLIBCXX20_CONSTEXPRconstexpr
1452 basic_string&
1453 append(const basic_string& __str, size_type __pos, size_type __n = npos)
1454 { return this->append(__str._M_data()
1455 + __str._M_check(__pos, "basic_string::append"),
1456 __str._M_limit(__pos, __n)); }
1457
1458 /**
1459 * @brief Append a C substring.
1460 * @param __s The C string to append.
1461 * @param __n The number of characters to append.
1462 * @return Reference to this string.
1463 */
1464 _GLIBCXX20_CONSTEXPRconstexpr
1465 basic_string&
1466 append(const _CharT* __s, size_type __n)
1467 {
1468 __glibcxx_requires_string_len(__s, __n);
1469 _M_check_length(size_type(0), __n, "basic_string::append");
1470 return _M_append(__s, __n);
1471 }
1472
1473 /**
1474 * @brief Append a C string.
1475 * @param __s The C string to append.
1476 * @return Reference to this string.
1477 */
1478 _GLIBCXX20_CONSTEXPRconstexpr
1479 basic_string&
1480 append(const _CharT* __s)
1481 {
1482 __glibcxx_requires_string(__s);
1483 const size_type __n = traits_type::length(__s);
1484 _M_check_length(size_type(0), __n, "basic_string::append");
1485 return _M_append(__s, __n);
1486 }
1487
1488 /**
1489 * @brief Append multiple characters.
1490 * @param __n The number of characters to append.
1491 * @param __c The character to use.
1492 * @return Reference to this string.
1493 *
1494 * Appends __n copies of __c to this string.
1495 */
1496 _GLIBCXX20_CONSTEXPRconstexpr
1497 basic_string&
1498 append(size_type __n, _CharT __c)
1499 { return _M_replace_aux(this->size(), size_type(0), __n, __c); }
1500
1501#if __cplusplus202002L >= 201103L
1502 /**
1503 * @brief Append an initializer_list of characters.
1504 * @param __l The initializer_list of characters to append.
1505 * @return Reference to this string.
1506 */
1507 _GLIBCXX20_CONSTEXPRconstexpr
1508 basic_string&
1509 append(initializer_list<_CharT> __l)
1510 { return this->append(__l.begin(), __l.size()); }
1511#endif // C++11
1512
1513 /**
1514 * @brief Append a range of characters.
1515 * @param __first Iterator referencing the first character to append.
1516 * @param __last Iterator marking the end of the range.
1517 * @return Reference to this string.
1518 *
1519 * Appends characters in the range [__first,__last) to this string.
1520 */
1521#if __cplusplus202002L >= 201103L
1522 template<class _InputIterator,
1523 typename = std::_RequireInputIter<_InputIterator>>
1524 _GLIBCXX20_CONSTEXPRconstexpr
1525#else
1526 template<class _InputIterator>
1527#endif
1528 basic_string&
1529 append(_InputIterator __first, _InputIterator __last)
1530 { return this->replace(end(), end(), __first, __last); }
1531
1532#if __cplusplus202002L >= 201703L
1533 /**
1534 * @brief Append a string_view.
1535 * @param __svt An object convertible to string_view to be appended.
1536 * @return Reference to this string.
1537 */
1538 template<typename _Tp>
1539 _GLIBCXX20_CONSTEXPRconstexpr
1540 _If_sv<_Tp, basic_string&>
1541 append(const _Tp& __svt)
1542 {
1543 __sv_type __sv = __svt;
1544 return this->append(__sv.data(), __sv.size());
1545 }
1546
1547 /**
1548 * @brief Append a range of characters from a string_view.
1549 * @param __svt An object convertible to string_view to be appended from.
1550 * @param __pos The position in the string_view to append from.
1551 * @param __n The number of characters to append from the string_view.
1552 * @return Reference to this string.
1553 */
1554 template<typename _Tp>
1555 _GLIBCXX20_CONSTEXPRconstexpr
1556 _If_sv<_Tp, basic_string&>
1557 append(const _Tp& __svt, size_type __pos, size_type __n = npos)
1558 {
1559 __sv_type __sv = __svt;
1560 return _M_append(__sv.data()
1561 + std::__sv_check(__sv.size(), __pos, "basic_string::append"),
1562 std::__sv_limit(__sv.size(), __pos, __n));
1563 }
1564#endif // C++17
1565
1566 /**
1567 * @brief Append a single character.
1568 * @param __c Character to append.
1569 */
1570 _GLIBCXX20_CONSTEXPRconstexpr
1571 void
1572 push_back(_CharT __c)
1573 {
1574 const size_type __size = this->size();
1575 if (__size + 1 > this->capacity())
1576 this->_M_mutate(__size, size_type(0), 0, size_type(1));
1577 traits_type::assign(this->_M_data()[__size], __c);
1578 this->_M_set_length(__size + 1);
1579 }
1580
1581 /**
1582 * @brief Set value to contents of another string.
1583 * @param __str Source string to use.
1584 * @return Reference to this string.
1585 */
1586 _GLIBCXX20_CONSTEXPRconstexpr
1587 basic_string&
1588 assign(const basic_string& __str)
1589 {
1590#if __cplusplus202002L >= 201103L
1591 if (_Alloc_traits::_S_propagate_on_copy_assign())
1592 {
1593 if (!_Alloc_traits::_S_always_equal() && !_M_is_local()
1594 && _M_get_allocator() != __str._M_get_allocator())
1595 {
1596 // Propagating allocator cannot free existing storage so must
1597 // deallocate it before replacing current allocator.
1598 if (__str.size() <= _S_local_capacity)
1599 {
1600 _M_destroy(_M_allocated_capacity);
1601 _M_data(_M_use_local_data());
1602 _M_set_length(0);
1603 }
1604 else
1605 {
1606 const auto __len = __str.size();
1607 auto __alloc = __str._M_get_allocator();
1608 // If this allocation throws there are no effects:
1609 auto __ptr = _S_allocate(__alloc, __len + 1);
1610 _M_destroy(_M_allocated_capacity);
1611 _M_data(__ptr);
1612 _M_capacity(__len);
1613 _M_set_length(__len);
1614 }
1615 }
1616 std::__alloc_on_copy(_M_get_allocator(), __str._M_get_allocator());
1617 }
1618#endif
1619 this->_M_assign(__str);
1620 return *this;
1621 }
1622
1623#if __cplusplus202002L >= 201103L
1624 /**
1625 * @brief Set value to contents of another string.
1626 * @param __str Source string to use.
1627 * @return Reference to this string.
1628 *
1629 * This function sets this string to the exact contents of @a __str.
1630 * @a __str is a valid, but unspecified string.
1631 */
1632 _GLIBCXX20_CONSTEXPRconstexpr
1633 basic_string&
1634 assign(basic_string&& __str)
1635 noexcept(_Alloc_traits::_S_nothrow_move())
1636 {
1637 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1638 // 2063. Contradictory requirements for string move assignment
1639 return *this = std::move(__str);
1640 }
1641#endif // C++11
1642
1643 /**
1644 * @brief Set value to a substring of a string.
1645 * @param __str The string to use.
1646 * @param __pos Index of the first character of str.
1647 * @param __n Number of characters to use.
1648 * @return Reference to this string.
1649 * @throw std::out_of_range if @a pos is not a valid index.
1650 *
1651 * This function sets this string to the substring of @a __str
1652 * consisting of @a __n characters at @a __pos. If @a __n is
1653 * is larger than the number of available characters in @a
1654 * __str, the remainder of @a __str is used.
1655 */
1656 _GLIBCXX20_CONSTEXPRconstexpr
1657 basic_string&
1658 assign(const basic_string& __str, size_type __pos, size_type __n = npos)
1659 { return _M_replace(size_type(0), this->size(), __str._M_data()
1660 + __str._M_check(__pos, "basic_string::assign"),
1661 __str._M_limit(__pos, __n)); }
1662
1663 /**
1664 * @brief Set value to a C substring.
1665 * @param __s The C string to use.
1666 * @param __n Number of characters to use.
1667 * @return Reference to this string.
1668 *
1669 * This function sets the value of this string to the first @a __n
1670 * characters of @a __s. If @a __n is is larger than the number of
1671 * available characters in @a __s, the remainder of @a __s is used.
1672 */
1673 _GLIBCXX20_CONSTEXPRconstexpr
1674 basic_string&
1675 assign(const _CharT* __s, size_type __n)
1676 {
1677 __glibcxx_requires_string_len(__s, __n);
1678 return _M_replace(size_type(0), this->size(), __s, __n);
1679 }
1680
1681 /**
1682 * @brief Set value to contents of a C string.
1683 * @param __s The C string to use.
1684 * @return Reference to this string.
1685 *
1686 * This function sets the value of this string to the value of @a __s.
1687 * The data is copied, so there is no dependence on @a __s once the
1688 * function returns.
1689 */
1690 _GLIBCXX20_CONSTEXPRconstexpr
1691 basic_string&
1692 assign(const _CharT* __s)
1693 {
1694 __glibcxx_requires_string(__s);
1695 return _M_replace(size_type(0), this->size(), __s,
1696 traits_type::length(__s));
1697 }
1698
1699 /**
1700 * @brief Set value to multiple characters.
1701 * @param __n Length of the resulting string.
1702 * @param __c The character to use.
1703 * @return Reference to this string.
1704 *
1705 * This function sets the value of this string to @a __n copies of
1706 * character @a __c.
1707 */
1708 _GLIBCXX20_CONSTEXPRconstexpr
1709 basic_string&
1710 assign(size_type __n, _CharT __c)
1711 { return _M_replace_aux(size_type(0), this->size(), __n, __c); }
1712
1713 /**
1714 * @brief Set value to a range of characters.
1715 * @param __first Iterator referencing the first character to append.
1716 * @param __last Iterator marking the end of the range.
1717 * @return Reference to this string.
1718 *
1719 * Sets value of string to characters in the range [__first,__last).
1720 */
1721#if __cplusplus202002L >= 201103L
1722#pragma GCC diagnostic push
1723#pragma GCC diagnostic ignored "-Wc++17-extensions"
1724 template<class _InputIterator,
1725 typename = std::_RequireInputIter<_InputIterator>>
1726 _GLIBCXX20_CONSTEXPRconstexpr
1727 basic_string&
1728 assign(_InputIterator __first, _InputIterator __last)
1729 {
1730#if __cplusplus202002L >= 202002L
1731 if constexpr (contiguous_iterator<_InputIterator>
1732 && is_same_v<iter_value_t<_InputIterator>, _CharT>)
1733#else
1734 if constexpr (__is_one_of<_InputIterator, const_iterator, iterator,
1735 const _CharT*, _CharT*>::value)
1736#endif
1737 {
1738 __glibcxx_requires_valid_range(__first, __last);
1739 return _M_replace(size_type(0), size(),
1740 std::__to_address(__first), __last - __first);
1741 }
1742 else
1743 return *this = basic_string(__first, __last, get_allocator());
1744 }
1745#pragma GCC diagnostic pop
1746#else
1747 template<class _InputIterator>
1748 basic_string&
1749 assign(_InputIterator __first, _InputIterator __last)
1750 { return this->replace(begin(), end(), __first, __last); }
1751#endif
1752
1753#if __cplusplus202002L >= 201103L
1754 /**
1755 * @brief Set value to an initializer_list of characters.
1756 * @param __l The initializer_list of characters to assign.
1757 * @return Reference to this string.
1758 */
1759 _GLIBCXX20_CONSTEXPRconstexpr
1760 basic_string&
1761 assign(initializer_list<_CharT> __l)
1762 {
1763 // The initializer_list array cannot alias the characters in *this
1764 // so we don't need to use replace to that case.
1765 const size_type __n = __l.size();
1766 if (__n > capacity())
1767 *this = basic_string(__l.begin(), __l.end(), get_allocator());
1768 else
1769 {
1770 if (__n)
1771 _S_copy(_M_data(), __l.begin(), __n);
1772 _M_set_length(__n);
1773 }
1774 return *this;
1775 }
1776#endif // C++11
1777
1778#if __cplusplus202002L >= 201703L
1779 /**
1780 * @brief Set value from a string_view.
1781 * @param __svt The source object convertible to string_view.
1782 * @return Reference to this string.
1783 */
1784 template<typename _Tp>
1785 _GLIBCXX20_CONSTEXPRconstexpr
1786 _If_sv<_Tp, basic_string&>
1787 assign(const _Tp& __svt)
1788 {
1789 __sv_type __sv = __svt;
1790 return this->assign(__sv.data(), __sv.size());
1791 }
1792
1793 /**
1794 * @brief Set value from a range of characters in a string_view.
1795 * @param __svt The source object convertible to string_view.
1796 * @param __pos The position in the string_view to assign from.
1797 * @param __n The number of characters to assign.
1798 * @return Reference to this string.
1799 */
1800 template<typename _Tp>
1801 _GLIBCXX20_CONSTEXPRconstexpr
1802 _If_sv<_Tp, basic_string&>
1803 assign(const _Tp& __svt, size_type __pos, size_type __n = npos)
1804 {
1805 __sv_type __sv = __svt;
1806 return _M_replace(size_type(0), this->size(),
1807 __sv.data()
1808 + std::__sv_check(__sv.size(), __pos, "basic_string::assign"),
1809 std::__sv_limit(__sv.size(), __pos, __n));
1810 }
1811#endif // C++17
1812
1813#if __cplusplus202002L >= 201103L
1814 /**
1815 * @brief Insert multiple characters.
1816 * @param __p Const_iterator referencing location in string to
1817 * insert at.
1818 * @param __n Number of characters to insert
1819 * @param __c The character to insert.
1820 * @return Iterator referencing the first inserted char.
1821 * @throw std::length_error If new length exceeds @c max_size().
1822 *
1823 * Inserts @a __n copies of character @a __c starting at the
1824 * position referenced by iterator @a __p. If adding
1825 * characters causes the length to exceed max_size(),
1826 * length_error is thrown. The value of the string doesn't
1827 * change if an error is thrown.
1828 */
1829 _GLIBCXX20_CONSTEXPRconstexpr
1830 iterator
1831 insert(const_iterator __p, size_type __n, _CharT __c)
1832 {
1833 _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end());
1834 const size_type __pos = __p - begin();
1835 this->replace(__p, __p, __n, __c);
1836 return iterator(this->_M_data() + __pos);
1837 }
1838#else
1839 /**
1840 * @brief Insert multiple characters.
1841 * @param __p Iterator referencing location in string to insert at.
1842 * @param __n Number of characters to insert
1843 * @param __c The character to insert.
1844 * @throw std::length_error If new length exceeds @c max_size().
1845 *
1846 * Inserts @a __n copies of character @a __c starting at the
1847 * position referenced by iterator @a __p. If adding
1848 * characters causes the length to exceed max_size(),
1849 * length_error is thrown. The value of the string doesn't
1850 * change if an error is thrown.
1851 */
1852 void
1853 insert(iterator __p, size_type __n, _CharT __c)
1854 { this->replace(__p, __p, __n, __c); }
1855#endif
1856
1857#if __cplusplus202002L >= 201103L
1858 /**
1859 * @brief Insert a range of characters.
1860 * @param __p Const_iterator referencing location in string to
1861 * insert at.
1862 * @param __beg Start of range.
1863 * @param __end End of range.
1864 * @return Iterator referencing the first inserted char.
1865 * @throw std::length_error If new length exceeds @c max_size().
1866 *
1867 * Inserts characters in range [beg,end). If adding characters
1868 * causes the length to exceed max_size(), length_error is
1869 * thrown. The value of the string doesn't change if an error
1870 * is thrown.
1871 */
1872 template<class _InputIterator,
1873 typename = std::_RequireInputIter<_InputIterator>>
1874 _GLIBCXX20_CONSTEXPRconstexpr
1875 iterator
1876 insert(const_iterator __p, _InputIterator __beg, _InputIterator __end)
1877 {
1878 _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end());
1879 const size_type __pos = __p - begin();
1880 this->replace(__p, __p, __beg, __end);
1881 return iterator(this->_M_data() + __pos);
1882 }
1883#else
1884 /**
1885 * @brief Insert a range of characters.
1886 * @param __p Iterator referencing location in string to insert at.
1887 * @param __beg Start of range.
1888 * @param __end End of range.
1889 * @throw std::length_error If new length exceeds @c max_size().
1890 *
1891 * Inserts characters in range [__beg,__end). If adding
1892 * characters causes the length to exceed max_size(),
1893 * length_error is thrown. The value of the string doesn't
1894 * change if an error is thrown.
1895 */
1896 template<class _InputIterator>
1897 void
1898 insert(iterator __p, _InputIterator __beg, _InputIterator __end)
1899 { this->replace(__p, __p, __beg, __end); }
1900#endif
1901
1902#if __cplusplus202002L >= 201103L
1903 /**
1904 * @brief Insert an initializer_list of characters.
1905 * @param __p Iterator referencing location in string to insert at.
1906 * @param __l The initializer_list of characters to insert.
1907 * @throw std::length_error If new length exceeds @c max_size().
1908 */
1909 _GLIBCXX20_CONSTEXPRconstexpr
1910 iterator
1911 insert(const_iterator __p, initializer_list<_CharT> __l)
1912 { return this->insert(__p, __l.begin(), __l.end()); }
1913
1914#ifdef _GLIBCXX_DEFINING_STRING_INSTANTIATIONS
1915 // See PR libstdc++/83328
1916 void
1917 insert(iterator __p, initializer_list<_CharT> __l)
1918 {
1919 _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end());
1920 this->insert(__p - begin(), __l.begin(), __l.size());
1921 }
1922#endif
1923#endif // C++11
1924
1925 /**
1926 * @brief Insert value of a string.
1927 * @param __pos1 Position in string to insert at.
1928 * @param __str The string to insert.
1929 * @return Reference to this string.
1930 * @throw std::length_error If new length exceeds @c max_size().
1931 *
1932 * Inserts value of @a __str starting at @a __pos1. If adding
1933 * characters causes the length to exceed max_size(),
1934 * length_error is thrown. The value of the string doesn't
1935 * change if an error is thrown.
1936 */
1937 _GLIBCXX20_CONSTEXPRconstexpr
1938 basic_string&
1939 insert(size_type __pos1, const basic_string& __str)
1940 { return this->replace(__pos1, size_type(0),
1941 __str._M_data(), __str.size()); }
1942
1943 /**
1944 * @brief Insert a substring.
1945 * @param __pos1 Position in string to insert at.
1946 * @param __str The string to insert.
1947 * @param __pos2 Start of characters in str to insert.
1948 * @param __n Number of characters to insert.
1949 * @return Reference to this string.
1950 * @throw std::length_error If new length exceeds @c max_size().
1951 * @throw std::out_of_range If @a pos1 > size() or
1952 * @a __pos2 > @a str.size().
1953 *
1954 * Starting at @a pos1, insert @a __n character of @a __str
1955 * beginning with @a __pos2. If adding characters causes the
1956 * length to exceed max_size(), length_error is thrown. If @a
1957 * __pos1 is beyond the end of this string or @a __pos2 is
1958 * beyond the end of @a __str, out_of_range is thrown. The
1959 * value of the string doesn't change if an error is thrown.
1960 */
1961 _GLIBCXX20_CONSTEXPRconstexpr
1962 basic_string&
1963 insert(size_type __pos1, const basic_string& __str,
1964 size_type __pos2, size_type __n = npos)
1965 { return this->replace(__pos1, size_type(0), __str._M_data()
1966 + __str._M_check(__pos2, "basic_string::insert"),
1967 __str._M_limit(__pos2, __n)); }
1968
1969 /**
1970 * @brief Insert a C substring.
1971 * @param __pos Position in string to insert at.
1972 * @param __s The C string to insert.
1973 * @param __n The number of characters to insert.
1974 * @return Reference to this string.
1975 * @throw std::length_error If new length exceeds @c max_size().
1976 * @throw std::out_of_range If @a __pos is beyond the end of this
1977 * string.
1978 *
1979 * Inserts the first @a __n characters of @a __s starting at @a
1980 * __pos. If adding characters causes the length to exceed
1981 * max_size(), length_error is thrown. If @a __pos is beyond
1982 * end(), out_of_range is thrown. The value of the string
1983 * doesn't change if an error is thrown.
1984 */
1985 _GLIBCXX20_CONSTEXPRconstexpr
1986 basic_string&
1987 insert(size_type __pos, const _CharT* __s, size_type __n)
1988 { return this->replace(__pos, size_type(0), __s, __n); }
1989
1990 /**
1991 * @brief Insert a C string.
1992 * @param __pos Position in string to insert at.
1993 * @param __s The C string to insert.
1994 * @return Reference to this string.
1995 * @throw std::length_error If new length exceeds @c max_size().
1996 * @throw std::out_of_range If @a pos is beyond the end of this
1997 * string.
1998 *
1999 * Inserts the first @a n characters of @a __s starting at @a __pos. If
2000 * adding characters causes the length to exceed max_size(),
2001 * length_error is thrown. If @a __pos is beyond end(), out_of_range is
2002 * thrown. The value of the string doesn't change if an error is
2003 * thrown.
2004 */
2005 _GLIBCXX20_CONSTEXPRconstexpr
2006 basic_string&
2007 insert(size_type __pos, const _CharT* __s)
2008 {
2009 __glibcxx_requires_string(__s);
2010 return this->replace(__pos, size_type(0), __s,
2011 traits_type::length(__s));
2012 }
2013
2014 /**
2015 * @brief Insert multiple characters.
2016 * @param __pos Index in string to insert at.
2017 * @param __n Number of characters to insert
2018 * @param __c The character to insert.
2019 * @return Reference to this string.
2020 * @throw std::length_error If new length exceeds @c max_size().
2021 * @throw std::out_of_range If @a __pos is beyond the end of this
2022 * string.
2023 *
2024 * Inserts @a __n copies of character @a __c starting at index
2025 * @a __pos. If adding characters causes the length to exceed
2026 * max_size(), length_error is thrown. If @a __pos > length(),
2027 * out_of_range is thrown. The value of the string doesn't
2028 * change if an error is thrown.
2029 */
2030 _GLIBCXX20_CONSTEXPRconstexpr
2031 basic_string&
2032 insert(size_type __pos, size_type __n, _CharT __c)
2033 { return _M_replace_aux(_M_check(__pos, "basic_string::insert"),
2034 size_type(0), __n, __c); }
2035
2036 /**
2037 * @brief Insert one character.
2038 * @param __p Iterator referencing position in string to insert at.
2039 * @param __c The character to insert.
2040 * @return Iterator referencing newly inserted char.
2041 * @throw std::length_error If new length exceeds @c max_size().
2042 *
2043 * Inserts character @a __c at position referenced by @a __p.
2044 * If adding character causes the length to exceed max_size(),
2045 * length_error is thrown. If @a __p is beyond end of string,
2046 * out_of_range is thrown. The value of the string doesn't
2047 * change if an error is thrown.
2048 */
2049 _GLIBCXX20_CONSTEXPRconstexpr
2050 iterator
2051 insert(__const_iterator __p, _CharT __c)
2052 {
2053 _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end());
2054 const size_type __pos = __p - begin();
2055 _M_replace_aux(__pos, size_type(0), size_type(1), __c);
2056 return iterator(_M_data() + __pos);
2057 }
2058
2059#if __cplusplus202002L >= 201703L
2060 /**
2061 * @brief Insert a string_view.
2062 * @param __pos Position in string to insert at.
2063 * @param __svt The object convertible to string_view to insert.
2064 * @return Reference to this string.
2065 */
2066 template<typename _Tp>
2067 _GLIBCXX20_CONSTEXPRconstexpr
2068 _If_sv<_Tp, basic_string&>
2069 insert(size_type __pos, const _Tp& __svt)
2070 {
2071 __sv_type __sv = __svt;
2072 return this->insert(__pos, __sv.data(), __sv.size());
2073 }
2074
2075 /**
2076 * @brief Insert a string_view.
2077 * @param __pos1 Position in string to insert at.
2078 * @param __svt The object convertible to string_view to insert from.
2079 * @param __pos2 Start of characters in str to insert.
2080 * @param __n The number of characters to insert.
2081 * @return Reference to this string.
2082 */
2083 template<typename _Tp>
2084 _GLIBCXX20_CONSTEXPRconstexpr
2085 _If_sv<_Tp, basic_string&>
2086 insert(size_type __pos1, const _Tp& __svt,
2087 size_type __pos2, size_type __n = npos)
2088 {
2089 __sv_type __sv = __svt;
2090 return this->replace(__pos1, size_type(0),
2091 __sv.data()
2092 + std::__sv_check(__sv.size(), __pos2, "basic_string::insert"),
2093 std::__sv_limit(__sv.size(), __pos2, __n));
2094 }
2095#endif // C++17
2096
2097 /**
2098 * @brief Remove characters.
2099 * @param __pos Index of first character to remove (default 0).
2100 * @param __n Number of characters to remove (default remainder).
2101 * @return Reference to this string.
2102 * @throw std::out_of_range If @a pos is beyond the end of this
2103 * string.
2104 *
2105 * Removes @a __n characters from this string starting at @a
2106 * __pos. The length of the string is reduced by @a __n. If
2107 * there are < @a __n characters to remove, the remainder of
2108 * the string is truncated. If @a __p is beyond end of string,
2109 * out_of_range is thrown. The value of the string doesn't
2110 * change if an error is thrown.
2111 */
2112 _GLIBCXX20_CONSTEXPRconstexpr
2113 basic_string&
2114 erase(size_type __pos = 0, size_type __n = npos)
2115 {
2116 _M_check(__pos, "basic_string::erase");
2117 if (__n == npos)
2118 this->_M_set_length(__pos);
2119 else if (__n != 0)
2120 this->_M_erase(__pos, _M_limit(__pos, __n));
2121 return *this;
2122 }
2123
2124 /**
2125 * @brief Remove one character.
2126 * @param __position Iterator referencing the character to remove.
2127 * @return iterator referencing same location after removal.
2128 *
2129 * Removes the character at @a __position from this string. The value
2130 * of the string doesn't change if an error is thrown.
2131 */
2132 _GLIBCXX20_CONSTEXPRconstexpr
2133 iterator
2134 erase(__const_iterator __position)
2135 {
2136 _GLIBCXX_DEBUG_PEDASSERT(__position >= begin()
2137 && __position < end());
2138 const size_type __pos = __position - begin();
2139 this->_M_erase(__pos, size_type(1));
2140 return iterator(_M_data() + __pos);
2141 }
2142
2143 /**
2144 * @brief Remove a range of characters.
2145 * @param __first Iterator referencing the first character to remove.
2146 * @param __last Iterator referencing the end of the range.
2147 * @return Iterator referencing location of first after removal.
2148 *
2149 * Removes the characters in the range [first,last) from this string.
2150 * The value of the string doesn't change if an error is thrown.
2151 */
2152 _GLIBCXX20_CONSTEXPRconstexpr
2153 iterator
2154 erase(__const_iterator __first, __const_iterator __last)
2155 {
2156 _GLIBCXX_DEBUG_PEDASSERT(__first >= begin() && __first <= __last
2157 && __last <= end());
2158 const size_type __pos = __first - begin();
2159 if (__last == end())
2160 this->_M_set_length(__pos);
2161 else
2162 this->_M_erase(__pos, __last - __first);
2163 return iterator(this->_M_data() + __pos);
2164 }
2165
2166#if __cplusplus202002L >= 201103L
2167 /**
2168 * @brief Remove the last character.
2169 *
2170 * The string must be non-empty.
2171 */
2172 _GLIBCXX20_CONSTEXPRconstexpr
2173 void
2174 pop_back() noexcept
2175 {
2176 __glibcxx_assert(!empty())do { if (std::__is_constant_evaluated()) if (__builtin_expect
(!bool(!empty()), false)) std::__glibcxx_assert_fail(); } while
(false)
;
2177 _M_erase(size() - 1, 1);
2178 }
2179#endif // C++11
2180
2181 /**
2182 * @brief Replace characters with value from another string.
2183 * @param __pos Index of first character to replace.
2184 * @param __n Number of characters to be replaced.
2185 * @param __str String to insert.
2186 * @return Reference to this string.
2187 * @throw std::out_of_range If @a pos is beyond the end of this
2188 * string.
2189 * @throw std::length_error If new length exceeds @c max_size().
2190 *
2191 * Removes the characters in the range [__pos,__pos+__n) from
2192 * this string. In place, the value of @a __str is inserted.
2193 * If @a __pos is beyond end of string, out_of_range is thrown.
2194 * If the length of the result exceeds max_size(), length_error
2195 * is thrown. The value of the string doesn't change if an
2196 * error is thrown.
2197 */
2198 _GLIBCXX20_CONSTEXPRconstexpr
2199 basic_string&
2200 replace(size_type __pos, size_type __n, const basic_string& __str)
2201 { return this->replace(__pos, __n, __str._M_data(), __str.size()); }
2202
2203 /**
2204 * @brief Replace characters with value from another string.
2205 * @param __pos1 Index of first character to replace.
2206 * @param __n1 Number of characters to be replaced.
2207 * @param __str String to insert.
2208 * @param __pos2 Index of first character of str to use.
2209 * @param __n2 Number of characters from str to use.
2210 * @return Reference to this string.
2211 * @throw std::out_of_range If @a __pos1 > size() or @a __pos2 >
2212 * __str.size().
2213 * @throw std::length_error If new length exceeds @c max_size().
2214 *
2215 * Removes the characters in the range [__pos1,__pos1 + n) from this
2216 * string. In place, the value of @a __str is inserted. If @a __pos is
2217 * beyond end of string, out_of_range is thrown. If the length of the
2218 * result exceeds max_size(), length_error is thrown. The value of the
2219 * string doesn't change if an error is thrown.
2220 */
2221 _GLIBCXX20_CONSTEXPRconstexpr
2222 basic_string&
2223 replace(size_type __pos1, size_type __n1, const basic_string& __str,
2224 size_type __pos2, size_type __n2 = npos)
2225 { return this->replace(__pos1, __n1, __str._M_data()
2226 + __str._M_check(__pos2, "basic_string::replace"),
2227 __str._M_limit(__pos2, __n2)); }
2228
2229 /**
2230 * @brief Replace characters with value of a C substring.
2231 * @param __pos Index of first character to replace.
2232 * @param __n1 Number of characters to be replaced.
2233 * @param __s C string to insert.
2234 * @param __n2 Number of characters from @a s to use.
2235 * @return Reference to this string.
2236 * @throw std::out_of_range If @a pos1 > size().
2237 * @throw std::length_error If new length exceeds @c max_size().
2238 *
2239 * Removes the characters in the range [__pos,__pos + __n1)
2240 * from this string. In place, the first @a __n2 characters of
2241 * @a __s are inserted, or all of @a __s if @a __n2 is too large. If
2242 * @a __pos is beyond end of string, out_of_range is thrown. If
2243 * the length of result exceeds max_size(), length_error is
2244 * thrown. The value of the string doesn't change if an error
2245 * is thrown.
2246 */
2247 _GLIBCXX20_CONSTEXPRconstexpr
2248 basic_string&
2249 replace(size_type __pos, size_type __n1, const _CharT* __s,
2250 size_type __n2)
2251 {
2252 __glibcxx_requires_string_len(__s, __n2);
2253 return _M_replace(_M_check(__pos, "basic_string::replace"),
2254 _M_limit(__pos, __n1), __s, __n2);
2255 }
2256
2257 /**
2258 * @brief Replace characters with value of a C string.
2259 * @param __pos Index of first character to replace.
2260 * @param __n1 Number of characters to be replaced.
2261 * @param __s C string to insert.
2262 * @return Reference to this string.
2263 * @throw std::out_of_range If @a pos > size().
2264 * @throw std::length_error If new length exceeds @c max_size().
2265 *
2266 * Removes the characters in the range [__pos,__pos + __n1)
2267 * from this string. In place, the characters of @a __s are
2268 * inserted. If @a __pos is beyond end of string, out_of_range
2269 * is thrown. If the length of result exceeds max_size(),
2270 * length_error is thrown. The value of the string doesn't
2271 * change if an error is thrown.
2272 */
2273 _GLIBCXX20_CONSTEXPRconstexpr
2274 basic_string&
2275 replace(size_type __pos, size_type __n1, const _CharT* __s)
2276 {
2277 __glibcxx_requires_string(__s);
2278 return this->replace(__pos, __n1, __s, traits_type::length(__s));
2279 }
2280
2281 /**
2282 * @brief Replace characters with multiple characters.
2283 * @param __pos Index of first character to replace.
2284 * @param __n1 Number of characters to be replaced.
2285 * @param __n2 Number of characters to insert.
2286 * @param __c Character to insert.
2287 * @return Reference to this string.
2288 * @throw std::out_of_range If @a __pos > size().
2289 * @throw std::length_error If new length exceeds @c max_size().
2290 *
2291 * Removes the characters in the range [pos,pos + n1) from this
2292 * string. In place, @a __n2 copies of @a __c are inserted.
2293 * If @a __pos is beyond end of string, out_of_range is thrown.
2294 * If the length of result exceeds max_size(), length_error is
2295 * thrown. The value of the string doesn't change if an error
2296 * is thrown.
2297 */
2298 _GLIBCXX20_CONSTEXPRconstexpr
2299 basic_string&
2300 replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
2301 { return _M_replace_aux(_M_check(__pos, "basic_string::replace"),
2302 _M_limit(__pos, __n1), __n2, __c); }
2303
2304 /**
2305 * @brief Replace range of characters with string.
2306 * @param __i1 Iterator referencing start of range to replace.
2307 * @param __i2 Iterator referencing end of range to replace.
2308 * @param __str String value to insert.
2309 * @return Reference to this string.
2310 * @throw std::length_error If new length exceeds @c max_size().
2311 *
2312 * Removes the characters in the range [__i1,__i2). In place,
2313 * the value of @a __str is inserted. If the length of result
2314 * exceeds max_size(), length_error is thrown. The value of
2315 * the string doesn't change if an error is thrown.
2316 */
2317 _GLIBCXX20_CONSTEXPRconstexpr
2318 basic_string&
2319 replace(__const_iterator __i1, __const_iterator __i2,
2320 const basic_string& __str)
2321 { return this->replace(__i1, __i2, __str._M_data(), __str.size()); }
2322
2323 /**
2324 * @brief Replace range of characters with C substring.
2325 * @param __i1 Iterator referencing start of range to replace.
2326 * @param __i2 Iterator referencing end of range to replace.
2327 * @param __s C string value to insert.
2328 * @param __n Number of characters from s to insert.
2329 * @return Reference to this string.
2330 * @throw std::length_error If new length exceeds @c max_size().
2331 *
2332 * Removes the characters in the range [__i1,__i2). In place,
2333 * the first @a __n characters of @a __s are inserted. If the
2334 * length of result exceeds max_size(), length_error is thrown.
2335 * The value of the string doesn't change if an error is
2336 * thrown.
2337 */
2338 _GLIBCXX20_CONSTEXPRconstexpr
2339 basic_string&
2340 replace(__const_iterator __i1, __const_iterator __i2,
2341 const _CharT* __s, size_type __n)
2342 {
2343 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2344 && __i2 <= end());
2345 return this->replace(__i1 - begin(), __i2 - __i1, __s, __n);
2346 }
2347
2348 /**
2349 * @brief Replace range of characters with C string.
2350 * @param __i1 Iterator referencing start of range to replace.
2351 * @param __i2 Iterator referencing end of range to replace.
2352 * @param __s C string value to insert.
2353 * @return Reference to this string.
2354 * @throw std::length_error If new length exceeds @c max_size().
2355 *
2356 * Removes the characters in the range [__i1,__i2). In place,
2357 * the characters of @a __s are inserted. If the length of
2358 * result exceeds max_size(), length_error is thrown. The
2359 * value of the string doesn't change if an error is thrown.
2360 */
2361 _GLIBCXX20_CONSTEXPRconstexpr
2362 basic_string&
2363 replace(__const_iterator __i1, __const_iterator __i2, const _CharT* __s)
2364 {
2365 __glibcxx_requires_string(__s);
2366 return this->replace(__i1, __i2, __s, traits_type::length(__s));
2367 }
2368
2369 /**
2370 * @brief Replace range of characters with multiple characters
2371 * @param __i1 Iterator referencing start of range to replace.
2372 * @param __i2 Iterator referencing end of range to replace.
2373 * @param __n Number of characters to insert.
2374 * @param __c Character to insert.
2375 * @return Reference to this string.
2376 * @throw std::length_error If new length exceeds @c max_size().
2377 *
2378 * Removes the characters in the range [__i1,__i2). In place,
2379 * @a __n copies of @a __c are inserted. If the length of
2380 * result exceeds max_size(), length_error is thrown. The
2381 * value of the string doesn't change if an error is thrown.
2382 */
2383 _GLIBCXX20_CONSTEXPRconstexpr
2384 basic_string&
2385 replace(__const_iterator __i1, __const_iterator __i2, size_type __n,
2386 _CharT __c)
2387 {
2388 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2389 && __i2 <= end());
2390 return _M_replace_aux(__i1 - begin(), __i2 - __i1, __n, __c);
2391 }
2392
2393 /**
2394 * @brief Replace range of characters with range.
2395 * @param __i1 Iterator referencing start of range to replace.
2396 * @param __i2 Iterator referencing end of range to replace.
2397 * @param __k1 Iterator referencing start of range to insert.
2398 * @param __k2 Iterator referencing end of range to insert.
2399 * @return Reference to this string.
2400 * @throw std::length_error If new length exceeds @c max_size().
2401 *
2402 * Removes the characters in the range [__i1,__i2). In place,
2403 * characters in the range [__k1,__k2) are inserted. If the
2404 * length of result exceeds max_size(), length_error is thrown.
2405 * The value of the string doesn't change if an error is
2406 * thrown.
2407 */
2408#if __cplusplus202002L >= 201103L
2409 template<class _InputIterator,
2410 typename = std::_RequireInputIter<_InputIterator>>
2411 _GLIBCXX20_CONSTEXPRconstexpr
2412 basic_string&
2413 replace(const_iterator __i1, const_iterator __i2,
2414 _InputIterator __k1, _InputIterator __k2)
2415 {
2416 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2417 && __i2 <= end());
2418 __glibcxx_requires_valid_range(__k1, __k2);
2419 return this->_M_replace_dispatch(__i1, __i2, __k1, __k2,
2420 std::__false_type());
2421 }
2422#else
2423 template<class _InputIterator>
2424#ifdef _GLIBCXX_DISAMBIGUATE_REPLACE_INST
2425 typename __enable_if_not_native_iterator<_InputIterator>::__type
2426#else
2427 basic_string&
2428#endif
2429 replace(iterator __i1, iterator __i2,
2430 _InputIterator __k1, _InputIterator __k2)
2431 {
2432 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2433 && __i2 <= end());
2434 __glibcxx_requires_valid_range(__k1, __k2);
2435 typedef typename std::__is_integer<_InputIterator>::__type _Integral;
2436 return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral());
2437 }
2438#endif
2439
2440 // Specializations for the common case of pointer and iterator:
2441 // useful to avoid the overhead of temporary buffering in _M_replace.
2442 _GLIBCXX20_CONSTEXPRconstexpr
2443 basic_string&
2444 replace(__const_iterator __i1, __const_iterator __i2,
2445 _CharT* __k1, _CharT* __k2)
2446 {
2447 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2448 && __i2 <= end());
2449 __glibcxx_requires_valid_range(__k1, __k2);
2450 return this->replace(__i1 - begin(), __i2 - __i1,
2451 __k1, __k2 - __k1);
2452 }
2453
2454 _GLIBCXX20_CONSTEXPRconstexpr
2455 basic_string&
2456 replace(__const_iterator __i1, __const_iterator __i2,
2457 const _CharT* __k1, const _CharT* __k2)
2458 {
2459 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2460 && __i2 <= end());
2461 __glibcxx_requires_valid_range(__k1, __k2);
2462 return this->replace(__i1 - begin(), __i2 - __i1,
2463 __k1, __k2 - __k1);
2464 }
2465
2466 _GLIBCXX20_CONSTEXPRconstexpr
2467 basic_string&
2468 replace(__const_iterator __i1, __const_iterator __i2,
2469 iterator __k1, iterator __k2)
2470 {
2471 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2472 && __i2 <= end());
2473 __glibcxx_requires_valid_range(__k1, __k2);
2474 return this->replace(__i1 - begin(), __i2 - __i1,
2475 __k1.base(), __k2 - __k1);
2476 }
2477
2478 _GLIBCXX20_CONSTEXPRconstexpr
2479 basic_string&
2480 replace(__const_iterator __i1, __const_iterator __i2,
2481 const_iterator __k1, const_iterator __k2)
2482 {
2483 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2484 && __i2 <= end());
2485 __glibcxx_requires_valid_range(__k1, __k2);
2486 return this->replace(__i1 - begin(), __i2 - __i1,
2487 __k1.base(), __k2 - __k1);
2488 }
2489
2490#if __cplusplus202002L >= 201103L
2491 /**
2492 * @brief Replace range of characters with initializer_list.
2493 * @param __i1 Iterator referencing start of range to replace.
2494 * @param __i2 Iterator referencing end of range to replace.
2495 * @param __l The initializer_list of characters to insert.
2496 * @return Reference to this string.
2497 * @throw std::length_error If new length exceeds @c max_size().
2498 *
2499 * Removes the characters in the range [__i1,__i2). In place,
2500 * characters in the range [__k1,__k2) are inserted. If the
2501 * length of result exceeds max_size(), length_error is thrown.
2502 * The value of the string doesn't change if an error is
2503 * thrown.
2504 */
2505 _GLIBCXX20_CONSTEXPRconstexpr
2506 basic_string& replace(const_iterator __i1, const_iterator __i2,
2507 initializer_list<_CharT> __l)
2508 { return this->replace(__i1, __i2, __l.begin(), __l.size()); }
2509#endif // C++11
2510
2511#if __cplusplus202002L >= 201703L
2512 /**
2513 * @brief Replace range of characters with string_view.
2514 * @param __pos The position to replace at.
2515 * @param __n The number of characters to replace.
2516 * @param __svt The object convertible to string_view to insert.
2517 * @return Reference to this string.
2518 */
2519 template<typename _Tp>
2520 _GLIBCXX20_CONSTEXPRconstexpr
2521 _If_sv<_Tp, basic_string&>
2522 replace(size_type __pos, size_type __n, const _Tp& __svt)
2523 {
2524 __sv_type __sv = __svt;
2525 return this->replace(__pos, __n, __sv.data(), __sv.size());
2526 }
2527
2528 /**
2529 * @brief Replace range of characters with string_view.
2530 * @param __pos1 The position to replace at.
2531 * @param __n1 The number of characters to replace.
2532 * @param __svt The object convertible to string_view to insert from.
2533 * @param __pos2 The position in the string_view to insert from.
2534 * @param __n2 The number of characters to insert.
2535 * @return Reference to this string.
2536 */
2537 template<typename _Tp>
2538 _GLIBCXX20_CONSTEXPRconstexpr
2539 _If_sv<_Tp, basic_string&>
2540 replace(size_type __pos1, size_type __n1, const _Tp& __svt,
2541 size_type __pos2, size_type __n2 = npos)
2542 {
2543 __sv_type __sv = __svt;
2544 return this->replace(__pos1, __n1,
2545 __sv.data()
2546 + std::__sv_check(__sv.size(), __pos2, "basic_string::replace"),
2547 std::__sv_limit(__sv.size(), __pos2, __n2));
2548 }
2549
2550 /**
2551 * @brief Replace range of characters with string_view.
2552 * @param __i1 An iterator referencing the start position
2553 to replace at.
2554 * @param __i2 An iterator referencing the end position
2555 for the replace.
2556 * @param __svt The object convertible to string_view to insert from.
2557 * @return Reference to this string.
2558 */
2559 template<typename _Tp>
2560 _GLIBCXX20_CONSTEXPRconstexpr
2561 _If_sv<_Tp, basic_string&>
2562 replace(const_iterator __i1, const_iterator __i2, const _Tp& __svt)
2563 {
2564 __sv_type __sv = __svt;
2565 return this->replace(__i1 - begin(), __i2 - __i1, __sv);
2566 }
2567#endif // C++17
2568
2569 private:
2570 template<class _Integer>
2571 _GLIBCXX20_CONSTEXPRconstexpr
2572 basic_string&
2573 _M_replace_dispatch(const_iterator __i1, const_iterator __i2,
2574 _Integer __n, _Integer __val, __true_type)
2575 { return _M_replace_aux(__i1 - begin(), __i2 - __i1, __n, __val); }
2576
2577 template<class _InputIterator>
2578 _GLIBCXX20_CONSTEXPRconstexpr
2579 basic_string&
2580 _M_replace_dispatch(const_iterator __i1, const_iterator __i2,
2581 _InputIterator __k1, _InputIterator __k2,
2582 __false_type);
2583
2584 _GLIBCXX20_CONSTEXPRconstexpr
2585 basic_string&
2586 _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
2587 _CharT __c);
2588
2589 __attribute__((__noinline__, __noclone__, __cold__)) void
2590 _M_replace_cold(pointer __p, size_type __len1, const _CharT* __s,
2591 const size_type __len2, const size_type __how_much);
2592
2593 _GLIBCXX20_CONSTEXPRconstexpr
2594 basic_string&
2595 _M_replace(size_type __pos, size_type __len1, const _CharT* __s,
2596 const size_type __len2);
2597
2598 _GLIBCXX20_CONSTEXPRconstexpr
2599 basic_string&
2600 _M_append(const _CharT* __s, size_type __n);
2601
2602 public:
2603
2604 /**
2605 * @brief Copy substring into C string.
2606 * @param __s C string to copy value into.
2607 * @param __n Number of characters to copy.
2608 * @param __pos Index of first character to copy.
2609 * @return Number of characters actually copied
2610 * @throw std::out_of_range If __pos > size().
2611 *
2612 * Copies up to @a __n characters starting at @a __pos into the
2613 * C string @a __s. If @a __pos is %greater than size(),
2614 * out_of_range is thrown.
2615 */
2616 _GLIBCXX20_CONSTEXPRconstexpr
2617 size_type
2618 copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
2619
2620 /**
2621 * @brief Swap contents with another string.
2622 * @param __s String to swap with.
2623 *
2624 * Exchanges the contents of this string with that of @a __s in constant
2625 * time.
2626 */
2627 _GLIBCXX20_CONSTEXPRconstexpr
2628 void
2629 swap(basic_string& __s) _GLIBCXX_NOEXCEPTnoexcept;
2630
2631 // String operations:
2632 /**
2633 * @brief Return const pointer to null-terminated contents.
2634 *
2635 * This is a handle to internal data. Do not modify or dire things may
2636 * happen.
2637 */
2638 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
2639 const _CharT*
2640 c_str() const _GLIBCXX_NOEXCEPTnoexcept
2641 { return _M_data(); }
2642
2643 /**
2644 * @brief Return const pointer to contents.
2645 *
2646 * This is a pointer to internal data. It is undefined to modify
2647 * the contents through the returned pointer. To get a pointer that
2648 * allows modifying the contents use @c &str[0] instead,
2649 * (or in C++17 the non-const @c str.data() overload).
2650 */
2651 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
2652 const _CharT*
2653 data() const _GLIBCXX_NOEXCEPTnoexcept
2654 { return _M_data(); }
2655
2656#if __cplusplus202002L >= 201703L
2657 /**
2658 * @brief Return non-const pointer to contents.
2659 *
2660 * This is a pointer to the character sequence held by the string.
2661 * Modifying the characters in the sequence is allowed.
2662 */
2663 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
2664 _CharT*
2665 data() noexcept
2666 { return _M_data(); }
2667#endif
2668
2669 /**
2670 * @brief Return copy of allocator used to construct this string.
2671 */
2672 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
2673 allocator_type
2674 get_allocator() const _GLIBCXX_NOEXCEPTnoexcept
2675 { return _M_get_allocator(); }
2676
2677 /**
2678 * @brief Find position of a C substring.
2679 * @param __s C string to locate.
2680 * @param __pos Index of character to search from.
2681 * @param __n Number of characters from @a s to search for.
2682 * @return Index of start of first occurrence.
2683 *
2684 * Starting from @a __pos, searches forward for the first @a
2685 * __n characters in @a __s within this string. If found,
2686 * returns the index where it begins. If not found, returns
2687 * npos.
2688 */
2689 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
2690 size_type
2691 find(const _CharT* __s, size_type __pos, size_type __n) const
2692 _GLIBCXX_NOEXCEPTnoexcept;
2693
2694 /**
2695 * @brief Find position of a string.
2696 * @param __str String to locate.
2697 * @param __pos Index of character to search from (default 0).
2698 * @return Index of start of first occurrence.
2699 *
2700 * Starting from @a __pos, searches forward for value of @a __str within
2701 * this string. If found, returns the index where it begins. If not
2702 * found, returns npos.
2703 */
2704 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
2705 size_type
2706 find(const basic_string& __str, size_type __pos = 0) const
2707 _GLIBCXX_NOEXCEPTnoexcept
2708 { return this->find(__str.data(), __pos, __str.size()); }
2709
2710#if __cplusplus202002L >= 201703L
2711 /**
2712 * @brief Find position of a string_view.
2713 * @param __svt The object convertible to string_view to locate.
2714 * @param __pos Index of character to search from (default 0).
2715 * @return Index of start of first occurrence.
2716 */
2717 template<typename _Tp>
2718 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
2719 _If_sv<_Tp, size_type>
2720 find(const _Tp& __svt, size_type __pos = 0) const
2721 noexcept(is_same<_Tp, __sv_type>::value)
2722 {
2723 __sv_type __sv = __svt;
2724 return this->find(__sv.data(), __pos, __sv.size());
2725 }
2726#endif // C++17
2727
2728 /**
2729 * @brief Find position of a C string.
2730 * @param __s C string to locate.
2731 * @param __pos Index of character to search from (default 0).
2732 * @return Index of start of first occurrence.
2733 *
2734 * Starting from @a __pos, searches forward for the value of @a
2735 * __s within this string. If found, returns the index where
2736 * it begins. If not found, returns npos.
2737 */
2738 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
2739 size_type
2740 find(const _CharT* __s, size_type __pos = 0) const _GLIBCXX_NOEXCEPTnoexcept
2741 {
2742 __glibcxx_requires_string(__s);
2743 return this->find(__s, __pos, traits_type::length(__s));
2744 }
2745
2746 /**
2747 * @brief Find position of a character.
2748 * @param __c Character to locate.
2749 * @param __pos Index of character to search from (default 0).
2750 * @return Index of first occurrence.
2751 *
2752 * Starting from @a __pos, searches forward for @a __c within
2753 * this string. If found, returns the index where it was
2754 * found. If not found, returns npos.
2755 */
2756 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
2757 size_type
2758 find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPTnoexcept;
2759
2760 /**
2761 * @brief Find last position of a string.
2762 * @param __str String to locate.
2763 * @param __pos Index of character to search back from (default end).
2764 * @return Index of start of last occurrence.
2765 *
2766 * Starting from @a __pos, searches backward for value of @a
2767 * __str within this string. If found, returns the index where
2768 * it begins. If not found, returns npos.
2769 */
2770 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
2771 size_type
2772 rfind(const basic_string& __str, size_type __pos = npos) const
2773 _GLIBCXX_NOEXCEPTnoexcept
2774 { return this->rfind(__str.data(), __pos, __str.size()); }
2775
2776#if __cplusplus202002L >= 201703L
2777 /**
2778 * @brief Find last position of a string_view.
2779 * @param __svt The object convertible to string_view to locate.
2780 * @param __pos Index of character to search back from (default end).
2781 * @return Index of start of last occurrence.
2782 */
2783 template<typename _Tp>
2784 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
2785 _If_sv<_Tp, size_type>
2786 rfind(const _Tp& __svt, size_type __pos = npos) const
2787 noexcept(is_same<_Tp, __sv_type>::value)
2788 {
2789 __sv_type __sv = __svt;
2790 return this->rfind(__sv.data(), __pos, __sv.size());
2791 }
2792#endif // C++17
2793
2794 /**
2795 * @brief Find last position of a C substring.
2796 * @param __s C string to locate.
2797 * @param __pos Index of character to search back from.
2798 * @param __n Number of characters from s to search for.
2799 * @return Index of start of last occurrence.
2800 *
2801 * Starting from @a __pos, searches backward for the first @a
2802 * __n characters in @a __s within this string. If found,
2803 * returns the index where it begins. If not found, returns
2804 * npos.
2805 */
2806 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
2807 size_type
2808 rfind(const _CharT* __s, size_type __pos, size_type __n) const
2809 _GLIBCXX_NOEXCEPTnoexcept;
2810
2811 /**
2812 * @brief Find last position of a C string.
2813 * @param __s C string to locate.
2814 * @param __pos Index of character to start search at (default end).
2815 * @return Index of start of last occurrence.
2816 *
2817 * Starting from @a __pos, searches backward for the value of
2818 * @a __s within this string. If found, returns the index
2819 * where it begins. If not found, returns npos.
2820 */
2821 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
2822 size_type
2823 rfind(const _CharT* __s, size_type __pos = npos) const
2824 {
2825 __glibcxx_requires_string(__s);
2826 return this->rfind(__s, __pos, traits_type::length(__s));
2827 }
2828
2829 /**
2830 * @brief Find last position of a character.
2831 * @param __c Character to locate.
2832 * @param __pos Index of character to search back from (default end).
2833 * @return Index of last occurrence.
2834 *
2835 * Starting from @a __pos, searches backward for @a __c within
2836 * this string. If found, returns the index where it was
2837 * found. If not found, returns npos.
2838 */
2839 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
2840 size_type
2841 rfind(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPTnoexcept;
2842
2843 /**
2844 * @brief Find position of a character of string.
2845 * @param __str String containing characters to locate.
2846 * @param __pos Index of character to search from (default 0).
2847 * @return Index of first occurrence.
2848 *
2849 * Starting from @a __pos, searches forward for one of the
2850 * characters of @a __str within this string. If found,
2851 * returns the index where it was found. If not found, returns
2852 * npos.
2853 */
2854 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
2855 size_type
2856 find_first_of(const basic_string& __str, size_type __pos = 0) const
2857 _GLIBCXX_NOEXCEPTnoexcept
2858 { return this->find_first_of(__str.data(), __pos, __str.size()); }
2859
2860#if __cplusplus202002L >= 201703L
2861 /**
2862 * @brief Find position of a character of a string_view.
2863 * @param __svt An object convertible to string_view containing
2864 * characters to locate.
2865 * @param __pos Index of character to search from (default 0).
2866 * @return Index of first occurrence.
2867 */
2868 template<typename _Tp>
2869 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
2870 _If_sv<_Tp, size_type>
2871 find_first_of(const _Tp& __svt, size_type __pos = 0) const
2872 noexcept(is_same<_Tp, __sv_type>::value)
2873 {
2874 __sv_type __sv = __svt;
2875 return this->find_first_of(__sv.data(), __pos, __sv.size());
2876 }
2877#endif // C++17
2878
2879 /**
2880 * @brief Find position of a character of C substring.
2881 * @param __s String containing characters to locate.
2882 * @param __pos Index of character to search from.
2883 * @param __n Number of characters from s to search for.
2884 * @return Index of first occurrence.
2885 *
2886 * Starting from @a __pos, searches forward for one of the
2887 * first @a __n characters of @a __s within this string. If
2888 * found, returns the index where it was found. If not found,
2889 * returns npos.
2890 */
2891 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
2892 size_type
2893 find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
2894 _GLIBCXX_NOEXCEPTnoexcept;
2895
2896 /**
2897 * @brief Find position of a character of C string.
2898 * @param __s String containing characters to locate.
2899 * @param __pos Index of character to search from (default 0).
2900 * @return Index of first occurrence.
2901 *
2902 * Starting from @a __pos, searches forward for one of the
2903 * characters of @a __s within this string. If found, returns
2904 * the index where it was found. If not found, returns npos.
2905 */
2906 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
2907 size_type
2908 find_first_of(const _CharT* __s, size_type __pos = 0) const
2909 _GLIBCXX_NOEXCEPTnoexcept
2910 {
2911 __glibcxx_requires_string(__s);
2912 return this->find_first_of(__s, __pos, traits_type::length(__s));
2913 }
2914
2915 /**
2916 * @brief Find position of a character.
2917 * @param __c Character to locate.
2918 * @param __pos Index of character to search from (default 0).
2919 * @return Index of first occurrence.
2920 *
2921 * Starting from @a __pos, searches forward for the character
2922 * @a __c within this string. If found, returns the index
2923 * where it was found. If not found, returns npos.
2924 *
2925 * Note: equivalent to find(__c, __pos).
2926 */
2927 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
2928 size_type
2929 find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPTnoexcept
2930 { return this->find(__c, __pos); }
2931
2932 /**
2933 * @brief Find last position of a character of string.
2934 * @param __str String containing characters to locate.
2935 * @param __pos Index of character to search back from (default end).
2936 * @return Index of last occurrence.
2937 *
2938 * Starting from @a __pos, searches backward for one of the
2939 * characters of @a __str within this string. If found,
2940 * returns the index where it was found. If not found, returns
2941 * npos.
2942 */
2943 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
2944 size_type
2945 find_last_of(const basic_string& __str, size_type __pos = npos) const
2946 _GLIBCXX_NOEXCEPTnoexcept
2947 { return this->find_last_of(__str.data(), __pos, __str.size()); }
2948
2949#if __cplusplus202002L >= 201703L
2950 /**
2951 * @brief Find last position of a character of string.
2952 * @param __svt An object convertible to string_view containing
2953 * characters to locate.
2954 * @param __pos Index of character to search back from (default end).
2955 * @return Index of last occurrence.
2956 */
2957 template<typename _Tp>
2958 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
2959 _If_sv<_Tp, size_type>
2960 find_last_of(const _Tp& __svt, size_type __pos = npos) const
2961 noexcept(is_same<_Tp, __sv_type>::value)
2962 {
2963 __sv_type __sv = __svt;
2964 return this->find_last_of(__sv.data(), __pos, __sv.size());
2965 }
2966#endif // C++17
2967
2968 /**
2969 * @brief Find last position of a character of C substring.
2970 * @param __s C string containing characters to locate.
2971 * @param __pos Index of character to search back from.
2972 * @param __n Number of characters from s to search for.
2973 * @return Index of last occurrence.
2974 *
2975 * Starting from @a __pos, searches backward for one of the
2976 * first @a __n characters of @a __s within this string. If
2977 * found, returns the index where it was found. If not found,
2978 * returns npos.
2979 */
2980 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
2981 size_type
2982 find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
2983 _GLIBCXX_NOEXCEPTnoexcept;
2984
2985 /**
2986 * @brief Find last position of a character of C string.
2987 * @param __s C string containing characters to locate.
2988 * @param __pos Index of character to search back from (default end).
2989 * @return Index of last occurrence.
2990 *
2991 * Starting from @a __pos, searches backward for one of the
2992 * characters of @a __s within this string. If found, returns
2993 * the index where it was found. If not found, returns npos.
2994 */
2995 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
2996 size_type
2997 find_last_of(const _CharT* __s, size_type __pos = npos) const
2998 _GLIBCXX_NOEXCEPTnoexcept
2999 {
3000 __glibcxx_requires_string(__s);
3001 return this->find_last_of(__s, __pos, traits_type::length(__s));
3002 }
3003
3004 /**
3005 * @brief Find last position of a character.
3006 * @param __c Character to locate.
3007 * @param __pos Index of character to search back from (default end).
3008 * @return Index of last occurrence.
3009 *
3010 * Starting from @a __pos, searches backward for @a __c within
3011 * this string. If found, returns the index where it was
3012 * found. If not found, returns npos.
3013 *
3014 * Note: equivalent to rfind(__c, __pos).
3015 */
3016 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3017 size_type
3018 find_last_of(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPTnoexcept
3019 { return this->rfind(__c, __pos); }
3020
3021 /**
3022 * @brief Find position of a character not in string.
3023 * @param __str String containing characters to avoid.
3024 * @param __pos Index of character to search from (default 0).
3025 * @return Index of first occurrence.
3026 *
3027 * Starting from @a __pos, searches forward for a character not contained
3028 * in @a __str within this string. If found, returns the index where it
3029 * was found. If not found, returns npos.
3030 */
3031 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3032 size_type
3033 find_first_not_of(const basic_string& __str, size_type __pos = 0) const
3034 _GLIBCXX_NOEXCEPTnoexcept
3035 { return this->find_first_not_of(__str.data(), __pos, __str.size()); }
3036
3037#if __cplusplus202002L >= 201703L
3038 /**
3039 * @brief Find position of a character not in a string_view.
3040 * @param __svt A object convertible to string_view containing
3041 * characters to avoid.
3042 * @param __pos Index of character to search from (default 0).
3043 * @return Index of first occurrence.
3044 */
3045 template<typename _Tp>
3046 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3047 _If_sv<_Tp, size_type>
3048 find_first_not_of(const _Tp& __svt, size_type __pos = 0) const
3049 noexcept(is_same<_Tp, __sv_type>::value)
3050 {
3051 __sv_type __sv = __svt;
3052 return this->find_first_not_of(__sv.data(), __pos, __sv.size());
3053 }
3054#endif // C++17
3055
3056 /**
3057 * @brief Find position of a character not in C substring.
3058 * @param __s C string containing characters to avoid.
3059 * @param __pos Index of character to search from.
3060 * @param __n Number of characters from __s to consider.
3061 * @return Index of first occurrence.
3062 *
3063 * Starting from @a __pos, searches forward for a character not
3064 * contained in the first @a __n characters of @a __s within
3065 * this string. If found, returns the index where it was
3066 * found. If not found, returns npos.
3067 */
3068 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3069 size_type
3070 find_first_not_of(const _CharT* __s, size_type __pos,
3071 size_type __n) const _GLIBCXX_NOEXCEPTnoexcept;
3072
3073 /**
3074 * @brief Find position of a character not in C string.
3075 * @param __s C string containing characters to avoid.
3076 * @param __pos Index of character to search from (default 0).
3077 * @return Index of first occurrence.
3078 *
3079 * Starting from @a __pos, searches forward for a character not
3080 * contained in @a __s within this string. If found, returns
3081 * the index where it was found. If not found, returns npos.
3082 */
3083 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3084 size_type
3085 find_first_not_of(const _CharT* __s, size_type __pos = 0) const
3086 _GLIBCXX_NOEXCEPTnoexcept
3087 {
3088 __glibcxx_requires_string(__s);
3089 return this->find_first_not_of(__s, __pos, traits_type::length(__s));
3090 }
3091
3092 /**
3093 * @brief Find position of a different character.
3094 * @param __c Character to avoid.
3095 * @param __pos Index of character to search from (default 0).
3096 * @return Index of first occurrence.
3097 *
3098 * Starting from @a __pos, searches forward for a character
3099 * other than @a __c within this string. If found, returns the
3100 * index where it was found. If not found, returns npos.
3101 */
3102 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3103 size_type
3104 find_first_not_of(_CharT __c, size_type __pos = 0) const
3105 _GLIBCXX_NOEXCEPTnoexcept;
3106
3107 /**
3108 * @brief Find last position of a character not in string.
3109 * @param __str String containing characters to avoid.
3110 * @param __pos Index of character to search back from (default end).
3111 * @return Index of last occurrence.
3112 *
3113 * Starting from @a __pos, searches backward for a character
3114 * not contained in @a __str within this string. If found,
3115 * returns the index where it was found. If not found, returns
3116 * npos.
3117 */
3118 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3119 size_type
3120 find_last_not_of(const basic_string& __str, size_type __pos = npos) const
3121 _GLIBCXX_NOEXCEPTnoexcept
3122 { return this->find_last_not_of(__str.data(), __pos, __str.size()); }
3123
3124#if __cplusplus202002L >= 201703L
3125 /**
3126 * @brief Find last position of a character not in a string_view.
3127 * @param __svt An object convertible to string_view containing
3128 * characters to avoid.
3129 * @param __pos Index of character to search back from (default end).
3130 * @return Index of last occurrence.
3131 */
3132 template<typename _Tp>
3133 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3134 _If_sv<_Tp, size_type>
3135 find_last_not_of(const _Tp& __svt, size_type __pos = npos) const
3136 noexcept(is_same<_Tp, __sv_type>::value)
3137 {
3138 __sv_type __sv = __svt;
3139 return this->find_last_not_of(__sv.data(), __pos, __sv.size());
3140 }
3141#endif // C++17
3142
3143 /**
3144 * @brief Find last position of a character not in C substring.
3145 * @param __s C string containing characters to avoid.
3146 * @param __pos Index of character to search back from.
3147 * @param __n Number of characters from s to consider.
3148 * @return Index of last occurrence.
3149 *
3150 * Starting from @a __pos, searches backward for a character not
3151 * contained in the first @a __n characters of @a __s within this string.
3152 * If found, returns the index where it was found. If not found,
3153 * returns npos.
3154 */
3155 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3156 size_type
3157 find_last_not_of(const _CharT* __s, size_type __pos,
3158 size_type __n) const _GLIBCXX_NOEXCEPTnoexcept;
3159 /**
3160 * @brief Find last position of a character not in C string.
3161 * @param __s C string containing characters to avoid.
3162 * @param __pos Index of character to search back from (default end).
3163 * @return Index of last occurrence.
3164 *
3165 * Starting from @a __pos, searches backward for a character
3166 * not contained in @a __s within this string. If found,
3167 * returns the index where it was found. If not found, returns
3168 * npos.
3169 */
3170 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3171 size_type
3172 find_last_not_of(const _CharT* __s, size_type __pos = npos) const
3173 _GLIBCXX_NOEXCEPTnoexcept
3174 {
3175 __glibcxx_requires_string(__s);
3176 return this->find_last_not_of(__s, __pos, traits_type::length(__s));
3177 }
3178
3179 /**
3180 * @brief Find last position of a different character.
3181 * @param __c Character to avoid.
3182 * @param __pos Index of character to search back from (default end).
3183 * @return Index of last occurrence.
3184 *
3185 * Starting from @a __pos, searches backward for a character other than
3186 * @a __c within this string. If found, returns the index where it was
3187 * found. If not found, returns npos.
3188 */
3189 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3190 size_type
3191 find_last_not_of(_CharT __c, size_type __pos = npos) const
3192 _GLIBCXX_NOEXCEPTnoexcept;
3193
3194 /**
3195 * @brief Get a substring.
3196 * @param __pos Index of first character (default 0).
3197 * @param __n Number of characters in substring (default remainder).
3198 * @return The new string.
3199 * @throw std::out_of_range If __pos > size().
3200 *
3201 * Construct and return a new string using the @a __n
3202 * characters starting at @a __pos. If the string is too
3203 * short, use the remainder of the characters. If @a __pos is
3204 * beyond the end of the string, out_of_range is thrown.
3205 */
3206 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3207 basic_string
3208 substr(size_type __pos = 0, size_type __n = npos) const
3209 { return basic_string(*this,
3210 _M_check(__pos, "basic_string::substr"), __n); }
3211
3212 /**
3213 * @brief Compare to a string.
3214 * @param __str String to compare against.
3215 * @return Integer < 0, 0, or > 0.
3216 *
3217 * Returns an integer < 0 if this string is ordered before @a
3218 * __str, 0 if their values are equivalent, or > 0 if this
3219 * string is ordered after @a __str. Determines the effective
3220 * length rlen of the strings to compare as the smallest of
3221 * size() and str.size(). The function then compares the two
3222 * strings by calling traits::compare(data(), str.data(),rlen).
3223 * If the result of the comparison is nonzero returns it,
3224 * otherwise the shorter one is ordered first.
3225 */
3226 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3227 int
3228 compare(const basic_string& __str) const
3229 {
3230 const size_type __size = this->size();
3231 const size_type __osize = __str.size();
3232 const size_type __len = std::min(__size, __osize);
3233
3234 int __r = traits_type::compare(_M_data(), __str.data(), __len);
3235 if (!__r)
3236 __r = _S_compare(__size, __osize);
3237 return __r;
3238 }
3239
3240#if __cplusplus202002L >= 201703L
3241 /**
3242 * @brief Compare to a string_view.
3243 * @param __svt An object convertible to string_view to compare against.
3244 * @return Integer < 0, 0, or > 0.
3245 */
3246 template<typename _Tp>
3247 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3248 _If_sv<_Tp, int>
3249 compare(const _Tp& __svt) const
3250 noexcept(is_same<_Tp, __sv_type>::value)
3251 {
3252 __sv_type __sv = __svt;
3253 const size_type __size = this->size();
3254 const size_type __osize = __sv.size();
3255 const size_type __len = std::min(__size, __osize);
3256
3257 int __r = traits_type::compare(_M_data(), __sv.data(), __len);
3258 if (!__r)
3259 __r = _S_compare(__size, __osize);
3260 return __r;
3261 }
3262
3263 /**
3264 * @brief Compare to a string_view.
3265 * @param __pos A position in the string to start comparing from.
3266 * @param __n The number of characters to compare.
3267 * @param __svt An object convertible to string_view to compare
3268 * against.
3269 * @return Integer < 0, 0, or > 0.
3270 */
3271 template<typename _Tp>
3272 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3273 _If_sv<_Tp, int>
3274 compare(size_type __pos, size_type __n, const _Tp& __svt) const
3275 noexcept(is_same<_Tp, __sv_type>::value)
3276 {
3277 __sv_type __sv = __svt;
3278 return __sv_type(*this).substr(__pos, __n).compare(__sv);
3279 }
3280
3281 /**
3282 * @brief Compare to a string_view.
3283 * @param __pos1 A position in the string to start comparing from.
3284 * @param __n1 The number of characters to compare.
3285 * @param __svt An object convertible to string_view to compare
3286 * against.
3287 * @param __pos2 A position in the string_view to start comparing from.
3288 * @param __n2 The number of characters to compare.
3289 * @return Integer < 0, 0, or > 0.
3290 */
3291 template<typename _Tp>
3292 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3293 _If_sv<_Tp, int>
3294 compare(size_type __pos1, size_type __n1, const _Tp& __svt,
3295 size_type __pos2, size_type __n2 = npos) const
3296 noexcept(is_same<_Tp, __sv_type>::value)
3297 {
3298 __sv_type __sv = __svt;
3299 return __sv_type(*this)
3300 .substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
3301 }
3302#endif // C++17
3303
3304 /**
3305 * @brief Compare substring to a string.
3306 * @param __pos Index of first character of substring.
3307 * @param __n Number of characters in substring.
3308 * @param __str String to compare against.
3309 * @return Integer < 0, 0, or > 0.
3310 *
3311 * Form the substring of this string from the @a __n characters
3312 * starting at @a __pos. Returns an integer < 0 if the
3313 * substring is ordered before @a __str, 0 if their values are
3314 * equivalent, or > 0 if the substring is ordered after @a
3315 * __str. Determines the effective length rlen of the strings
3316 * to compare as the smallest of the length of the substring
3317 * and @a __str.size(). The function then compares the two
3318 * strings by calling
3319 * traits::compare(substring.data(),str.data(),rlen). If the
3320 * result of the comparison is nonzero returns it, otherwise
3321 * the shorter one is ordered first.
3322 */
3323 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3324 int
3325 compare(size_type __pos, size_type __n, const basic_string& __str) const
3326 {
3327 _M_check(__pos, "basic_string::compare");
3328 __n = _M_limit(__pos, __n);
3329 const size_type __osize = __str.size();
3330 const size_type __len = std::min(__n, __osize);
3331 int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len);
3332 if (!__r)
3333 __r = _S_compare(__n, __osize);
3334 return __r;
3335 }
3336
3337 /**
3338 * @brief Compare substring to a substring.
3339 * @param __pos1 Index of first character of substring.
3340 * @param __n1 Number of characters in substring.
3341 * @param __str String to compare against.
3342 * @param __pos2 Index of first character of substring of str.
3343 * @param __n2 Number of characters in substring of str.
3344 * @return Integer < 0, 0, or > 0.
3345 *
3346 * Form the substring of this string from the @a __n1
3347 * characters starting at @a __pos1. Form the substring of @a
3348 * __str from the @a __n2 characters starting at @a __pos2.
3349 * Returns an integer < 0 if this substring is ordered before
3350 * the substring of @a __str, 0 if their values are equivalent,
3351 * or > 0 if this substring is ordered after the substring of
3352 * @a __str. Determines the effective length rlen of the
3353 * strings to compare as the smallest of the lengths of the
3354 * substrings. The function then compares the two strings by
3355 * calling
3356 * traits::compare(substring.data(),str.substr(pos2,n2).data(),rlen).
3357 * If the result of the comparison is nonzero returns it,
3358 * otherwise the shorter one is ordered first.
3359 */
3360 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3361 int
3362 compare(size_type __pos1, size_type __n1, const basic_string& __str,
3363 size_type __pos2, size_type __n2 = npos) const
3364 {
3365 _M_check(__pos1, "basic_string::compare");
3366 __str._M_check(__pos2, "basic_string::compare");
3367 __n1 = _M_limit(__pos1, __n1);
3368 __n2 = __str._M_limit(__pos2, __n2);
3369 const size_type __len = std::min(__n1, __n2);
3370 int __r = traits_type::compare(_M_data() + __pos1,
3371 __str.data() + __pos2, __len);
3372 if (!__r)
3373 __r = _S_compare(__n1, __n2);
3374 return __r;
3375 }
3376
3377 /**
3378 * @brief Compare to a C string.
3379 * @param __s C string to compare against.
3380 * @return Integer < 0, 0, or > 0.
3381 *
3382 * Returns an integer < 0 if this string is ordered before @a __s, 0 if
3383 * their values are equivalent, or > 0 if this string is ordered after
3384 * @a __s. Determines the effective length rlen of the strings to
3385 * compare as the smallest of size() and the length of a string
3386 * constructed from @a __s. The function then compares the two strings
3387 * by calling traits::compare(data(),s,rlen). If the result of the
3388 * comparison is nonzero returns it, otherwise the shorter one is
3389 * ordered first.
3390 */
3391 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3392 int
3393 compare(const _CharT* __s) const _GLIBCXX_NOEXCEPTnoexcept
3394 {
3395 __glibcxx_requires_string(__s);
3396 const size_type __size = this->size();
3397 const size_type __osize = traits_type::length(__s);
3398 const size_type __len = std::min(__size, __osize);
3399 int __r = traits_type::compare(_M_data(), __s, __len);
3400 if (!__r)
3401 __r = _S_compare(__size, __osize);
3402 return __r;
3403 }
3404
3405 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3406 // 5 String::compare specification questionable
3407 /**
3408 * @brief Compare substring to a C string.
3409 * @param __pos Index of first character of substring.
3410 * @param __n1 Number of characters in substring.
3411 * @param __s C string to compare against.
3412 * @return Integer < 0, 0, or > 0.
3413 *
3414 * Form the substring of this string from the @a __n1
3415 * characters starting at @a pos. Returns an integer < 0 if
3416 * the substring is ordered before @a __s, 0 if their values
3417 * are equivalent, or > 0 if the substring is ordered after @a
3418 * __s. Determines the effective length rlen of the strings to
3419 * compare as the smallest of the length of the substring and
3420 * the length of a string constructed from @a __s. The
3421 * function then compares the two string by calling
3422 * traits::compare(substring.data(),__s,rlen). If the result of
3423 * the comparison is nonzero returns it, otherwise the shorter
3424 * one is ordered first.
3425 */
3426 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3427 int
3428 compare(size_type __pos, size_type __n1, const _CharT* __s) const
3429 {
3430 __glibcxx_requires_string(__s);
3431 _M_check(__pos, "basic_string::compare");
3432 __n1 = _M_limit(__pos, __n1);
3433 const size_type __osize = traits_type::length(__s);
3434 const size_type __len = std::min(__n1, __osize);
3435 int __r = traits_type::compare(_M_data() + __pos, __s, __len);
3436 if (!__r)
3437 __r = _S_compare(__n1, __osize);
3438 return __r;
3439 }
3440
3441 /**
3442 * @brief Compare substring against a character %array.
3443 * @param __pos Index of first character of substring.
3444 * @param __n1 Number of characters in substring.
3445 * @param __s character %array to compare against.
3446 * @param __n2 Number of characters of s.
3447 * @return Integer < 0, 0, or > 0.
3448 *
3449 * Form the substring of this string from the @a __n1
3450 * characters starting at @a __pos. Form a string from the
3451 * first @a __n2 characters of @a __s. Returns an integer < 0
3452 * if this substring is ordered before the string from @a __s,
3453 * 0 if their values are equivalent, or > 0 if this substring
3454 * is ordered after the string from @a __s. Determines the
3455 * effective length rlen of the strings to compare as the
3456 * smallest of the length of the substring and @a __n2. The
3457 * function then compares the two strings by calling
3458 * traits::compare(substring.data(),s,rlen). If the result of
3459 * the comparison is nonzero returns it, otherwise the shorter
3460 * one is ordered first.
3461 *
3462 * NB: s must have at least n2 characters, &apos;\\0&apos; has
3463 * no special meaning.
3464 */
3465 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3466 int
3467 compare(size_type __pos, size_type __n1, const _CharT* __s,
3468 size_type __n2) const
3469 {
3470 __glibcxx_requires_string_len(__s, __n2);
3471 _M_check(__pos, "basic_string::compare");
3472 __n1 = _M_limit(__pos, __n1);
3473 const size_type __len = std::min(__n1, __n2);
3474 int __r = traits_type::compare(_M_data() + __pos, __s, __len);
3475 if (!__r)
3476 __r = _S_compare(__n1, __n2);
3477 return __r;
3478 }
3479
3480#if __cplusplus202002L >= 202002L
3481 [[nodiscard]]
3482 constexpr bool
3483 starts_with(basic_string_view<_CharT, _Traits> __x) const noexcept
3484 { return __sv_type(this->data(), this->size()).starts_with(__x); }
3485
3486 [[nodiscard]]
3487 constexpr bool
3488 starts_with(_CharT __x) const noexcept
3489 { return __sv_type(this->data(), this->size()).starts_with(__x); }
3490
3491 [[nodiscard, __gnu__::__nonnull__]]
3492 constexpr bool
3493 starts_with(const _CharT* __x) const noexcept
3494 { return __sv_type(this->data(), this->size()).starts_with(__x); }
3495
3496 [[nodiscard]]
3497 constexpr bool
3498 ends_with(basic_string_view<_CharT, _Traits> __x) const noexcept
3499 { return __sv_type(this->data(), this->size()).ends_with(__x); }
3500
3501 [[nodiscard]]
3502 constexpr bool
3503 ends_with(_CharT __x) const noexcept
3504 { return __sv_type(this->data(), this->size()).ends_with(__x); }
3505
3506 [[nodiscard, __gnu__::__nonnull__]]
3507 constexpr bool
3508 ends_with(const _CharT* __x) const noexcept
3509 { return __sv_type(this->data(), this->size()).ends_with(__x); }
3510#endif // C++20
3511
3512#if __cplusplus202002L > 202002L
3513 [[nodiscard]]
3514 constexpr bool
3515 contains(basic_string_view<_CharT, _Traits> __x) const noexcept
3516 { return __sv_type(this->data(), this->size()).contains(__x); }
3517
3518 [[nodiscard]]
3519 constexpr bool
3520 contains(_CharT __x) const noexcept
3521 { return __sv_type(this->data(), this->size()).contains(__x); }
3522
3523 [[nodiscard, __gnu__::__nonnull__]]
3524 constexpr bool
3525 contains(const _CharT* __x) const noexcept
3526 { return __sv_type(this->data(), this->size()).contains(__x); }
3527#endif // C++23
3528
3529 // Allow basic_stringbuf::__xfer_bufptrs to call _M_length:
3530 template<typename, typename, typename> friend class basic_stringbuf;
3531 };
3532_GLIBCXX_END_NAMESPACE_CXX11}
3533_GLIBCXX_END_NAMESPACE_VERSION
3534} // namespace std
3535#endif // _GLIBCXX_USE_CXX11_ABI
3536
3537namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
3538{
3539_GLIBCXX_BEGIN_NAMESPACE_VERSION
3540
3541#if __cpp_deduction_guides201703L >= 201606
3542_GLIBCXX_BEGIN_NAMESPACE_CXX11namespace __cxx11 {
3543 template<typename _InputIterator, typename _CharT
3544 = typename iterator_traits<_InputIterator>::value_type,
3545 typename _Allocator = allocator<_CharT>,
3546 typename = _RequireInputIter<_InputIterator>,
3547 typename = _RequireAllocator<_Allocator>>
3548 basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator())
3549 -> basic_string<_CharT, char_traits<_CharT>, _Allocator>;
3550
3551 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3552 // 3075. basic_string needs deduction guides from basic_string_view
3553 template<typename _CharT, typename _Traits,
3554 typename _Allocator = allocator<_CharT>,
3555 typename = _RequireAllocator<_Allocator>>
3556 basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _Allocator())
3557 -> basic_string<_CharT, _Traits, _Allocator>;
3558
3559 template<typename _CharT, typename _Traits,
3560 typename _Allocator = allocator<_CharT>,
3561 typename = _RequireAllocator<_Allocator>>
3562 basic_string(basic_string_view<_CharT, _Traits>,
3563 typename basic_string<_CharT, _Traits, _Allocator>::size_type,
3564 typename basic_string<_CharT, _Traits, _Allocator>::size_type,
3565 const _Allocator& = _Allocator())
3566 -> basic_string<_CharT, _Traits, _Allocator>;
3567_GLIBCXX_END_NAMESPACE_CXX11}
3568#endif
3569
3570 template<typename _Str>
3571 _GLIBCXX20_CONSTEXPRconstexpr
3572 inline _Str
3573 __str_concat(typename _Str::value_type const* __lhs,
3574 typename _Str::size_type __lhs_len,
3575 typename _Str::value_type const* __rhs,
3576 typename _Str::size_type __rhs_len,
3577 typename _Str::allocator_type const& __a)
3578 {
3579 typedef typename _Str::allocator_type allocator_type;
3580 typedef __gnu_cxx::__alloc_traits<allocator_type> _Alloc_traits;
3581 _Str __str(_Alloc_traits::_S_select_on_copy(__a));
3582 __str.reserve(__lhs_len + __rhs_len);
3583 __str.append(__lhs, __lhs_len);
3584 __str.append(__rhs, __rhs_len);
3585 return __str;
3586 }
3587
3588 // operator+
3589 /**
3590 * @brief Concatenate two strings.
3591 * @param __lhs First string.
3592 * @param __rhs Last string.
3593 * @return New string with value of @a __lhs followed by @a __rhs.
3594 */
3595 template<typename _CharT, typename _Traits, typename _Alloc>
3596 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3597 inline basic_string<_CharT, _Traits, _Alloc>
3598 operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
3599 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
3600 {
3601 typedef basic_string<_CharT, _Traits, _Alloc> _Str;
3602 return std::__str_concat<_Str>(__lhs.c_str(), __lhs.size(),
3603 __rhs.c_str(), __rhs.size(),
3604 __lhs.get_allocator());
3605 }
3606
3607 /**
3608 * @brief Concatenate C string and string.
3609 * @param __lhs First string.
3610 * @param __rhs Last string.
3611 * @return New string with value of @a __lhs followed by @a __rhs.
3612 */
3613 template<typename _CharT, typename _Traits, typename _Alloc>
3614 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3615 inline basic_string<_CharT,_Traits,_Alloc>
3616 operator+(const _CharT* __lhs,
3617 const basic_string<_CharT,_Traits,_Alloc>& __rhs)
3618 {
3619 __glibcxx_requires_string(__lhs);
3620 typedef basic_string<_CharT, _Traits, _Alloc> _Str;
3621 return std::__str_concat<_Str>(__lhs, _Traits::length(__lhs),
3622 __rhs.c_str(), __rhs.size(),
3623 __rhs.get_allocator());
3624 }
3625
3626 /**
3627 * @brief Concatenate character and string.
3628 * @param __lhs First string.
3629 * @param __rhs Last string.
3630 * @return New string with @a __lhs followed by @a __rhs.
3631 */
3632 template<typename _CharT, typename _Traits, typename _Alloc>
3633 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3634 inline basic_string<_CharT,_Traits,_Alloc>
3635 operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs)
3636 {
3637 typedef basic_string<_CharT, _Traits, _Alloc> _Str;
3638 return std::__str_concat<_Str>(__builtin_addressof(__lhs), 1,
3639 __rhs.c_str(), __rhs.size(),
3640 __rhs.get_allocator());
3641 }
3642
3643 /**
3644 * @brief Concatenate string and C string.
3645 * @param __lhs First string.
3646 * @param __rhs Last string.
3647 * @return New string with @a __lhs followed by @a __rhs.
3648 */
3649 template<typename _CharT, typename _Traits, typename _Alloc>
3650 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3651 inline basic_string<_CharT, _Traits, _Alloc>
3652 operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
3653 const _CharT* __rhs)
3654 {
3655 __glibcxx_requires_string(__rhs);
3656 typedef basic_string<_CharT, _Traits, _Alloc> _Str;
3657 return std::__str_concat<_Str>(__lhs.c_str(), __lhs.size(),
3658 __rhs, _Traits::length(__rhs),
3659 __lhs.get_allocator());
3660 }
3661 /**
3662 * @brief Concatenate string and character.
3663 * @param __lhs First string.
3664 * @param __rhs Last string.
3665 * @return New string with @a __lhs followed by @a __rhs.
3666 */
3667 template<typename _CharT, typename _Traits, typename _Alloc>
3668 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3669 inline basic_string<_CharT, _Traits, _Alloc>
3670 operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs)
3671 {
3672 typedef basic_string<_CharT, _Traits, _Alloc> _Str;
3673 return std::__str_concat<_Str>(__lhs.c_str(), __lhs.size(),
3674 __builtin_addressof(__rhs), 1,
3675 __lhs.get_allocator());
3676 }
3677
3678#if __cplusplus202002L >= 201103L
3679 template<typename _CharT, typename _Traits, typename _Alloc>
3680 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3681 inline basic_string<_CharT, _Traits, _Alloc>
3682 operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
3683 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
3684 { return std::move(__lhs.append(__rhs)); }
3685
3686 template<typename _CharT, typename _Traits, typename _Alloc>
3687 _GLIBCXX20_CONSTEXPRconstexpr
3688 inline basic_string<_CharT, _Traits, _Alloc>
3689 operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
3690 basic_string<_CharT, _Traits, _Alloc>&& __rhs)
3691 { return std::move(__rhs.insert(0, __lhs)); }
3692
3693 template<typename _CharT, typename _Traits, typename _Alloc>
3694 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3695 inline basic_string<_CharT, _Traits, _Alloc>
3696 operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
3697 basic_string<_CharT, _Traits, _Alloc>&& __rhs)
3698 {
3699#if _GLIBCXX_USE_CXX11_ABI1
3700 using _Alloc_traits = allocator_traits<_Alloc>;
3701 bool __use_rhs = false;
3702 if _GLIBCXX17_CONSTEXPRconstexpr (typename _Alloc_traits::is_always_equal{})
3703 __use_rhs = true;
3704 else if (__lhs.get_allocator() == __rhs.get_allocator())
3705 __use_rhs = true;
3706 if (__use_rhs)
3707#endif
3708 {
3709 const auto __size = __lhs.size() + __rhs.size();
3710 if (__size > __lhs.capacity() && __size <= __rhs.capacity())
3711 return std::move(__rhs.insert(0, __lhs));
3712 }
3713 return std::move(__lhs.append(__rhs));
3714 }
3715
3716 template<typename _CharT, typename _Traits, typename _Alloc>
3717 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3718 inline basic_string<_CharT, _Traits, _Alloc>
3719 operator+(const _CharT* __lhs,
3720 basic_string<_CharT, _Traits, _Alloc>&& __rhs)
3721 { return std::move(__rhs.insert(0, __lhs)); }
3722
3723 template<typename _CharT, typename _Traits, typename _Alloc>
3724 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3725 inline basic_string<_CharT, _Traits, _Alloc>
3726 operator+(_CharT __lhs,
3727 basic_string<_CharT, _Traits, _Alloc>&& __rhs)
3728 { return std::move(__rhs.insert(0, 1, __lhs)); }
3729
3730 template<typename _CharT, typename _Traits, typename _Alloc>
3731 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3732 inline basic_string<_CharT, _Traits, _Alloc>
3733 operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
3734 const _CharT* __rhs)
3735 { return std::move(__lhs.append(__rhs)); }
3736
3737 template<typename _CharT, typename _Traits, typename _Alloc>
3738 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3739 inline basic_string<_CharT, _Traits, _Alloc>
3740 operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
3741 _CharT __rhs)
3742 { return std::move(__lhs.append(1, __rhs)); }
3743#endif
3744
3745 // operator ==
3746 /**
3747 * @brief Test equivalence of two strings.
3748 * @param __lhs First string.
3749 * @param __rhs Second string.
3750 * @return True if @a __lhs.compare(@a __rhs) == 0. False otherwise.
3751 */
3752 template<typename _CharT, typename _Traits, typename _Alloc>
3753 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3754 inline bool
3755 operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
3756 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
3757 _GLIBCXX_NOEXCEPTnoexcept
3758 {
3759 return __lhs.size() == __rhs.size()
3760 && !_Traits::compare(__lhs.data(), __rhs.data(), __lhs.size());
3761 }
3762
3763 /**
3764 * @brief Test equivalence of string and C string.
3765 * @param __lhs String.
3766 * @param __rhs C string.
3767 * @return True if @a __lhs.compare(@a __rhs) == 0. False otherwise.
3768 */
3769 template<typename _CharT, typename _Traits, typename _Alloc>
3770 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPRconstexpr
3771 inline bool
3772 operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
3773 const _CharT* __rhs)
3774 {
3775 return __lhs.size() == _Traits::length(__rhs)
3776 && !_Traits::compare(__lhs.data(), __rhs, __lhs.size());
3777 }
3778
3779#if __cpp_lib_three_way_comparison201907L
3780 /**
3781 * @brief Three-way comparison of a string and a C string.
3782 * @param __lhs A string.
3783 * @param __rhs A null-terminated string.
3784 * @return A value indicating whether `__lhs` is less than, equal to,
3785 * greater than, or incomparable with `__rhs`.
3786 */
3787 template<typename _CharT, typename _Traits, typename _Alloc>
3788 [[nodiscard]]
3789 constexpr auto
3790 operator<=>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
3791 const basic_string<_CharT, _Traits, _Alloc>& __rhs) noexcept
3792 -> decltype(__detail::__char_traits_cmp_cat<_Traits>(0))
3793 { return __detail::__char_traits_cmp_cat<_Traits>(__lhs.compare(__rhs)); }
3794
3795 /**
3796 * @brief Three-way comparison of a string and a C string.
3797 * @param __lhs A string.
3798 * @param __rhs A null-terminated string.
3799 * @return A value indicating whether `__lhs` is less than, equal to,
3800 * greater than, or incomparable with `__rhs`.
3801 */
3802 template<typename _CharT, typename _Traits, typename _Alloc>
3803 [[nodiscard]]
3804 constexpr auto
3805 operator<=>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
3806 const _CharT* __rhs) noexcept
3807 -> decltype(__detail::__char_traits_cmp_cat<_Traits>(0))
3808 { return __detail::__char_traits_cmp_cat<_Traits>(__lhs.compare(__rhs)); }
3809#else
3810 /**
3811 * @brief Test equivalence of C string and string.
3812 * @param __lhs C string.
3813 * @param __rhs String.
3814 * @return True if @a __rhs.compare(@a __lhs) == 0. False otherwise.
3815 */
3816 template<typename _CharT, typename _Traits, typename _Alloc>
3817 _GLIBCXX_NODISCARD[[__nodiscard__]]
3818 inline bool
3819 operator==(const _CharT* __lhs,
3820 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
3821 { return __rhs == __lhs; }
3822
3823 // operator !=
3824 /**
3825 * @brief Test difference of two strings.
3826 * @param __lhs First string.
3827 * @param __rhs Second string.
3828 * @return True if @a __lhs.compare(@a __rhs) != 0. False otherwise.
3829 */
3830 template<typename _CharT, typename _Traits, typename _Alloc>
3831 _GLIBCXX_NODISCARD[[__nodiscard__]]
3832 inline bool
3833 operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
3834 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
3835 _GLIBCXX_NOEXCEPTnoexcept
3836 { return !(__lhs == __rhs); }
3837
3838 /**
3839 * @brief Test difference of C string and string.
3840 * @param __lhs C string.
3841 * @param __rhs String.
3842 * @return True if @a __rhs.compare(@a __lhs) != 0. False otherwise.
3843 */
3844 template<typename _CharT, typename _Traits, typename _Alloc>
3845 _GLIBCXX_NODISCARD[[__nodiscard__]]
3846 inline bool
3847 operator!=(const _CharT* __lhs,
3848 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
3849 { return !(__rhs == __lhs); }
3850
3851 /**
3852 * @brief Test difference of string and C string.
3853 * @param __lhs String.
3854 * @param __rhs C string.
3855 * @return True if @a __lhs.compare(@a __rhs) != 0. False otherwise.
3856 */
3857 template<typename _CharT, typename _Traits, typename _Alloc>
3858 _GLIBCXX_NODISCARD[[__nodiscard__]]
3859 inline bool
3860 operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
3861 const _CharT* __rhs)
3862 { return !(__lhs == __rhs); }
3863
3864 // operator <
3865 /**
3866 * @brief Test if string precedes string.
3867 * @param __lhs First string.
3868 * @param __rhs Second string.
3869 * @return True if @a __lhs precedes @a __rhs. False otherwise.
3870 */
3871 template<typename _CharT, typename _Traits, typename _Alloc>
3872 _GLIBCXX_NODISCARD[[__nodiscard__]]
3873 inline bool
3874 operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
3875 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
3876 _GLIBCXX_NOEXCEPTnoexcept
3877 { return __lhs.compare(__rhs) < 0; }
3878
3879 /**
3880 * @brief Test if string precedes C string.
3881 * @param __lhs String.
3882 * @param __rhs C string.
3883 * @return True if @a __lhs precedes @a __rhs. False otherwise.
3884 */
3885 template<typename _CharT, typename _Traits, typename _Alloc>
3886 _GLIBCXX_NODISCARD[[__nodiscard__]]
3887 inline bool
3888 operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
3889 const _CharT* __rhs)
3890 { return __lhs.compare(__rhs) < 0; }
3891
3892 /**
3893 * @brief Test if C string precedes string.
3894 * @param __lhs C string.
3895 * @param __rhs String.
3896 * @return True if @a __lhs precedes @a __rhs. False otherwise.
3897 */
3898 template<typename _CharT, typename _Traits, typename _Alloc>
3899 _GLIBCXX_NODISCARD[[__nodiscard__]]
3900 inline bool
3901 operator<(const _CharT* __lhs,
3902 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
3903 { return __rhs.compare(__lhs) > 0; }
3904
3905 // operator >
3906 /**
3907 * @brief Test if string follows string.
3908 * @param __lhs First string.
3909 * @param __rhs Second string.
3910 * @return True if @a __lhs follows @a __rhs. False otherwise.
3911 */
3912 template<typename _CharT, typename _Traits, typename _Alloc>
3913 _GLIBCXX_NODISCARD[[__nodiscard__]]
3914 inline bool
3915 operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
3916 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
3917 _GLIBCXX_NOEXCEPTnoexcept
3918 { return __lhs.compare(__rhs) > 0; }
3919
3920 /**
3921 * @brief Test if string follows C string.
3922 * @param __lhs String.
3923 * @param __rhs C string.
3924 * @return True if @a __lhs follows @a __rhs. False otherwise.
3925 */
3926 template<typename _CharT, typename _Traits, typename _Alloc>
3927 _GLIBCXX_NODISCARD[[__nodiscard__]]
3928 inline bool
3929 operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
3930 const _CharT* __rhs)
3931 { return __lhs.compare(__rhs) > 0; }
3932
3933 /**
3934 * @brief Test if C string follows string.
3935 * @param __lhs C string.
3936 * @param __rhs String.
3937 * @return True if @a __lhs follows @a __rhs. False otherwise.
3938 */
3939 template<typename _CharT, typename _Traits, typename _Alloc>
3940 _GLIBCXX_NODISCARD[[__nodiscard__]]
3941 inline bool
3942 operator>(const _CharT* __lhs,
3943 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
3944 { return __rhs.compare(__lhs) < 0; }
3945
3946 // operator <=
3947 /**
3948 * @brief Test if string doesn't follow string.
3949 * @param __lhs First string.
3950 * @param __rhs Second string.
3951 * @return True if @a __lhs doesn't follow @a __rhs. False otherwise.
3952 */
3953 template<typename _CharT, typename _Traits, typename _Alloc>
3954 _GLIBCXX_NODISCARD[[__nodiscard__]]
3955 inline bool
3956 operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
3957 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
3958 _GLIBCXX_NOEXCEPTnoexcept
3959 { return __lhs.compare(__rhs) <= 0; }
3960
3961 /**
3962 * @brief Test if string doesn't follow C string.
3963 * @param __lhs String.
3964 * @param __rhs C string.
3965 * @return True if @a __lhs doesn't follow @a __rhs. False otherwise.
3966 */
3967 template<typename _CharT, typename _Traits, typename _Alloc>
3968 _GLIBCXX_NODISCARD[[__nodiscard__]]
3969 inline bool
3970 operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
3971 const _CharT* __rhs)
3972 { return __lhs.compare(__rhs) <= 0; }
3973
3974 /**
3975 * @brief Test if C string doesn't follow string.
3976 * @param __lhs C string.
3977 * @param __rhs String.
3978 * @return True if @a __lhs doesn't follow @a __rhs. False otherwise.
3979 */
3980 template<typename _CharT, typename _Traits, typename _Alloc>
3981 _GLIBCXX_NODISCARD[[__nodiscard__]]
3982 inline bool
3983 operator<=(const _CharT* __lhs,
3984 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
3985 { return __rhs.compare(__lhs) >= 0; }
3986
3987 // operator >=
3988 /**
3989 * @brief Test if string doesn't precede string.
3990 * @param __lhs First string.
3991 * @param __rhs Second string.
3992 * @return True if @a __lhs doesn't precede @a __rhs. False otherwise.
3993 */
3994 template<typename _CharT, typename _Traits, typename _Alloc>
3995 _GLIBCXX_NODISCARD[[__nodiscard__]]
3996 inline bool
3997 operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
3998 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
3999 _GLIBCXX_NOEXCEPTnoexcept
4000 { return __lhs.compare(__rhs) >= 0; }
4001
4002 /**
4003 * @brief Test if string doesn't precede C string.
4004 * @param __lhs String.
4005 * @param __rhs C string.
4006 * @return True if @a __lhs doesn't precede @a __rhs. False otherwise.
4007 */
4008 template<typename _CharT, typename _Traits, typename _Alloc>
4009 _GLIBCXX_NODISCARD[[__nodiscard__]]
4010 inline bool
4011 operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
4012 const _CharT* __rhs)
4013 { return __lhs.compare(__rhs) >= 0; }
4014
4015 /**
4016 * @brief Test if C string doesn't precede string.
4017 * @param __lhs C string.
4018 * @param __rhs String.
4019 * @return True if @a __lhs doesn't precede @a __rhs. False otherwise.
4020 */
4021 template<typename _CharT, typename _Traits, typename _Alloc>
4022 _GLIBCXX_NODISCARD[[__nodiscard__]]
4023 inline bool
4024 operator>=(const _CharT* __lhs,
4025 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
4026 { return __rhs.compare(__lhs) <= 0; }
4027#endif // three-way comparison
4028
4029 /**
4030 * @brief Swap contents of two strings.
4031 * @param __lhs First string.
4032 * @param __rhs Second string.
4033 *
4034 * Exchanges the contents of @a __lhs and @a __rhs in constant time.
4035 */
4036 template<typename _CharT, typename _Traits, typename _Alloc>
4037 _GLIBCXX20_CONSTEXPRconstexpr
4038 inline void
4039 swap(basic_string<_CharT, _Traits, _Alloc>& __lhs,
4040 basic_string<_CharT, _Traits, _Alloc>& __rhs)
4041 _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs)))noexcept(noexcept(__lhs.swap(__rhs)))
4042 { __lhs.swap(__rhs); }
4043
4044
4045 /**
4046 * @brief Read stream into a string.
4047 * @param __is Input stream.
4048 * @param __str Buffer to store into.
4049 * @return Reference to the input stream.
4050 *
4051 * Stores characters from @a __is into @a __str until whitespace is
4052 * found, the end of the stream is encountered, or str.max_size()
4053 * is reached. If is.width() is non-zero, that is the limit on the
4054 * number of characters stored into @a __str. Any previous
4055 * contents of @a __str are erased.
4056 */
4057 template<typename _CharT, typename _Traits, typename _Alloc>
4058 basic_istream<_CharT, _Traits>&
4059 operator>>(basic_istream<_CharT, _Traits>& __is,
4060 basic_string<_CharT, _Traits, _Alloc>& __str);
4061
4062 template<>
4063 basic_istream<char>&
4064 operator>>(basic_istream<char>& __is, basic_string<char>& __str);
4065
4066 /**
4067 * @brief Write string to a stream.
4068 * @param __os Output stream.
4069 * @param __str String to write out.
4070 * @return Reference to the output stream.
4071 *
4072 * Output characters of @a __str into os following the same rules as for
4073 * writing a C string.
4074 */
4075 template<typename _CharT, typename _Traits, typename _Alloc>
4076 inline basic_ostream<_CharT, _Traits>&
4077 operator<<(basic_ostream<_CharT, _Traits>& __os,
4078 const basic_string<_CharT, _Traits, _Alloc>& __str)
4079 {
4080 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4081 // 586. string inserter not a formatted function
4082 return __ostream_insert(__os, __str.data(), __str.size());
4083 }
4084
4085 /**
4086 * @brief Read a line from stream into a string.
4087 * @param __is Input stream.
4088 * @param __str Buffer to store into.
4089 * @param __delim Character marking end of line.
4090 * @return Reference to the input stream.
4091 *
4092 * Stores characters from @a __is into @a __str until @a __delim is
4093 * found, the end of the stream is encountered, or str.max_size()
4094 * is reached. Any previous contents of @a __str are erased. If
4095 * @a __delim is encountered, it is extracted but not stored into
4096 * @a __str.
4097 */
4098 template<typename _CharT, typename _Traits, typename _Alloc>
4099 basic_istream<_CharT, _Traits>&
4100 getline(basic_istream<_CharT, _Traits>& __is,
4101 basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim);
4102
4103 /**
4104 * @brief Read a line from stream into a string.
4105 * @param __is Input stream.
4106 * @param __str Buffer to store into.
4107 * @return Reference to the input stream.
4108 *
4109 * Stores characters from is into @a __str until &apos;\n&apos; is
4110 * found, the end of the stream is encountered, or str.max_size()
4111 * is reached. Any previous contents of @a __str are erased. If
4112 * end of line is encountered, it is extracted but not stored into
4113 * @a __str.
4114 */
4115 template<typename _CharT, typename _Traits, typename _Alloc>
4116 inline basic_istream<_CharT, _Traits>&
4117 getline(basic_istream<_CharT, _Traits>& __is,
4118 basic_string<_CharT, _Traits, _Alloc>& __str)
4119 { return std::getline(__is, __str, __is.widen('\n')); }
4120
4121#if __cplusplus202002L >= 201103L
4122 /// Read a line from an rvalue stream into a string.
4123 template<typename _CharT, typename _Traits, typename _Alloc>
4124 inline basic_istream<_CharT, _Traits>&
4125 getline(basic_istream<_CharT, _Traits>&& __is,
4126 basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim)
4127 { return std::getline(__is, __str, __delim); }
4128
4129 /// Read a line from an rvalue stream into a string.
4130 template<typename _CharT, typename _Traits, typename _Alloc>
4131 inline basic_istream<_CharT, _Traits>&
4132 getline(basic_istream<_CharT, _Traits>&& __is,
4133 basic_string<_CharT, _Traits, _Alloc>& __str)
4134 { return std::getline(__is, __str); }
4135#endif
4136
4137 template<>
4138 basic_istream<char>&
4139 getline(basic_istream<char>& __in, basic_string<char>& __str,
4140 char __delim);
4141
4142#ifdef _GLIBCXX_USE_WCHAR_T1
4143 template<>
4144 basic_istream<wchar_t>&
4145 getline(basic_istream<wchar_t>& __in, basic_string<wchar_t>& __str,
4146 wchar_t __delim);
4147#endif
4148
4149_GLIBCXX_END_NAMESPACE_VERSION
4150} // namespace
4151
4152#if __cplusplus202002L >= 201103L
4153
4154#include <ext/string_conversions.h>
4155#include <bits/charconv.h>
4156
4157namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
4158{
4159_GLIBCXX_BEGIN_NAMESPACE_VERSION
4160_GLIBCXX_BEGIN_NAMESPACE_CXX11namespace __cxx11 {
4161
4162 // 21.4 Numeric Conversions [string.conversions].
4163 inline int
4164 stoi(const string& __str, size_t* __idx = 0, int __base = 10)
4165 { return __gnu_cxx::__stoa<long, int>(&std::strtol, "stoi", __str.c_str(),
4166 __idx, __base); }
4167
4168 inline long
4169 stol(const string& __str, size_t* __idx = 0, int __base = 10)
4170 { return __gnu_cxx::__stoa(&std::strtol, "stol", __str.c_str(),
4171 __idx, __base); }
4172
4173 inline unsigned long
4174 stoul(const string& __str, size_t* __idx = 0, int __base = 10)
4175 { return __gnu_cxx::__stoa(&std::strtoul, "stoul", __str.c_str(),
4176 __idx, __base); }
4177
4178#if _GLIBCXX_USE_C99_STDLIB1
4179 inline long long
4180 stoll(const string& __str, size_t* __idx = 0, int __base = 10)
4181 { return __gnu_cxx::__stoa(&std::strtoll, "stoll", __str.c_str(),
4182 __idx, __base); }
4183
4184 inline unsigned long long
4185 stoull(const string& __str, size_t* __idx = 0, int __base = 10)
4186 { return __gnu_cxx::__stoa(&std::strtoull, "stoull", __str.c_str(),
4187 __idx, __base); }
4188#elif __LONG_WIDTH__64 == __LONG_LONG_WIDTH__
4189 inline long long
4190 stoll(const string& __str, size_t* __idx = 0, int __base = 10)
4191 { return std::stol(__str, __idx, __base); }
4192
4193 inline unsigned long long
4194 stoull(const string& __str, size_t* __idx = 0, int __base = 10)
4195 { return std::stoul(__str, __idx, __base); }
4196#endif
4197
4198 inline double
4199 stod(const string& __str, size_t* __idx = 0)
4200 { return __gnu_cxx::__stoa(&std::strtod, "stod", __str.c_str(), __idx); }
4201
4202#if _GLIBCXX_HAVE_STRTOF1
4203 // NB: strtof vs strtod.
4204 inline float
4205 stof(const string& __str, size_t* __idx = 0)
4206 { return __gnu_cxx::__stoa(&std::strtof, "stof", __str.c_str(), __idx); }
4207#else
4208 inline float
4209 stof(const string& __str, size_t* __idx = 0)
4210 {
4211 double __d = std::stod(__str, __idx);
4212 if (__builtin_isfinite(__d) && __d != 0.0)
4213 {
4214 double __abs_d = __builtin_fabs(__d);
4215 if (__abs_d < __FLT_MIN__1.17549435e-38F || __abs_d > __FLT_MAX__3.40282347e+38F)
4216 {
4217 errno(*__errno_location ()) = ERANGE34;
4218 std::__throw_out_of_range("stof");
4219 }
4220 }
4221 return __d;
4222 }
4223#endif
4224
4225#if _GLIBCXX_HAVE_STRTOLD1 && ! _GLIBCXX_HAVE_BROKEN_STRTOLD
4226 inline long double
4227 stold(const string& __str, size_t* __idx = 0)
4228 { return __gnu_cxx::__stoa(&std::strtold, "stold", __str.c_str(), __idx); }
4229#elif __DBL_MANT_DIG__53 == __LDBL_MANT_DIG__64
4230 inline long double
4231 stold(const string& __str, size_t* __idx = 0)
4232 { return std::stod(__str, __idx); }
4233#endif
4234
4235 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4236 // DR 1261. Insufficent overloads for to_string / to_wstring
4237
4238 _GLIBCXX_NODISCARD[[__nodiscard__]]
4239 inline string
4240 to_string(int __val)
4241#if _GLIBCXX_USE_CXX11_ABI1 && (__CHAR_BIT__8 * __SIZEOF_INT__4) <= 32
4242 noexcept // any 32-bit value fits in the SSO buffer
4243#endif
4244 {
4245 const bool __neg = __val < 0;
4246 const unsigned __uval = __neg ? (unsigned)~__val + 1u : __val;
4247 const auto __len = __detail::__to_chars_len(__uval);
4248 string __str;
4249 __str.__resize_and_overwrite(__neg + __len, [=](char* __p, size_t __n) {
4250 __p[0] = '-';
4251 __detail::__to_chars_10_impl(__p + (int)__neg, __len, __uval);
4252 return __n;
4253 });
4254 return __str;
4255 }
4256
4257 _GLIBCXX_NODISCARD[[__nodiscard__]]
4258 inline string
4259 to_string(unsigned __val)
4260#if _GLIBCXX_USE_CXX11_ABI1 && (__CHAR_BIT__8 * __SIZEOF_INT__4) <= 32
4261 noexcept // any 32-bit value fits in the SSO buffer
4262#endif
4263 {
4264 const auto __len = __detail::__to_chars_len(__val);
4265 string __str;
4266 __str.__resize_and_overwrite(__len, [__val](char* __p, size_t __n) {
4267 __detail::__to_chars_10_impl(__p, __n, __val);
4268 return __n;
4269 });
4270 return __str;
4271 }
4272
4273 _GLIBCXX_NODISCARD[[__nodiscard__]]
4274 inline string
4275 to_string(long __val)
4276#if _GLIBCXX_USE_CXX11_ABI1 && (__CHAR_BIT__8 * __SIZEOF_LONG__8) <= 32
4277 noexcept // any 32-bit value fits in the SSO buffer
4278#endif
4279 {
4280 const bool __neg = __val < 0;
4281 const unsigned long __uval = __neg ? (unsigned long)~__val + 1ul : __val;
4282 const auto __len = __detail::__to_chars_len(__uval);
4283 string __str;
4284 __str.__resize_and_overwrite(__neg + __len, [=](char* __p, size_t __n) {
4285 __p[0] = '-';
4286 __detail::__to_chars_10_impl(__p + (int)__neg, __len, __uval);
4287 return __n;
4288 });
4289 return __str;
4290 }
4291
4292 _GLIBCXX_NODISCARD[[__nodiscard__]]
4293 inline string
4294 to_string(unsigned long __val)
4295#if _GLIBCXX_USE_CXX11_ABI1 && (__CHAR_BIT__8 * __SIZEOF_LONG__8) <= 32
4296 noexcept // any 32-bit value fits in the SSO buffer
4297#endif
4298 {
4299 const auto __len = __detail::__to_chars_len(__val);
4300 string __str;
4301 __str.__resize_and_overwrite(__len, [__val](char* __p, size_t __n) {
4302 __detail::__to_chars_10_impl(__p, __n, __val);
4303 return __n;
4304 });
4305 return __str;
4306 }
4307
4308 _GLIBCXX_NODISCARD[[__nodiscard__]]
4309 inline string
4310 to_string(long long __val)
4311 {
4312 const bool __neg = __val < 0;
4313 const unsigned long long __uval
4314 = __neg ? (unsigned long long)~__val + 1ull : __val;
4315 const auto __len = __detail::__to_chars_len(__uval);
4316 string __str;
4317 __str.__resize_and_overwrite(__neg + __len, [=](char* __p, size_t __n) {
4318 __p[0] = '-';
4319 __detail::__to_chars_10_impl(__p + (int)__neg, __len, __uval);
4320 return __n;
4321 });
4322 return __str;
4323 }
4324
4325 _GLIBCXX_NODISCARD[[__nodiscard__]]
4326 inline string
4327 to_string(unsigned long long __val)
4328 {
4329 const auto __len = __detail::__to_chars_len(__val);
4330 string __str;
4331 __str.__resize_and_overwrite(__len, [__val](char* __p, size_t __n) {
4332 __detail::__to_chars_10_impl(__p, __n, __val);
4333 return __n;
4334 });
4335 return __str;
4336 }
4337
4338#if __glibcxx_to_string >= 202306L // C++ >= 26
4339
4340 [[nodiscard]]
4341 inline string
4342 to_string(float __val)
4343 {
4344 string __str;
4345 size_t __len = 15;
4346 do {
4347 __str.resize_and_overwrite(__len,
4348 [__val, &__len] (char* __p, size_t __n) {
4349 auto [__end, __err] = std::to_chars(__p, __p + __n, __val);
4350 if (__err == errc{}) [[likely]]
4351 return __end - __p;
4352 __len *= 2;
4353 return __p - __p;;
4354 });
4355 } while (__str.empty());
4356 return __str;
4357 }
4358
4359 [[nodiscard]]
4360 inline string
4361 to_string(double __val)
4362 {
4363 string __str;
4364 size_t __len = 15;
4365 do {
4366 __str.resize_and_overwrite(__len,
4367 [__val, &__len] (char* __p, size_t __n) {
4368 auto [__end, __err] = std::to_chars(__p, __p + __n, __val);
4369 if (__err == errc{}) [[likely]]
4370 return __end - __p;
4371 __len *= 2;
4372 return __p - __p;;
4373 });
4374 } while (__str.empty());
4375 return __str;
4376 }
4377
4378 [[nodiscard]]
4379 inline string
4380 to_string(long double __val)
4381 {
4382 string __str;
4383 size_t __len = 15;
4384 do {
4385 __str.resize_and_overwrite(__len,
4386 [__val, &__len] (char* __p, size_t __n) {
4387 auto [__end, __err] = std::to_chars(__p, __p + __n, __val);
4388 if (__err == errc{}) [[likely]]
4389 return __end - __p;
4390 __len *= 2;
4391 return __p - __p;;
4392 });
4393 } while (__str.empty());
4394 return __str;
4395 }
4396#elif _GLIBCXX_USE_C99_STDIO1
4397 // NB: (v)snprintf vs sprintf.
4398
4399 _GLIBCXX_NODISCARD[[__nodiscard__]]
4400 inline string
4401 to_string(float __val)
4402 {
4403 const int __n =
4404 __gnu_cxx::__numeric_traits<float>::__max_exponent10 + 20;
4405 return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, __n,
4406 "%f", __val);
4407 }
4408
4409 _GLIBCXX_NODISCARD[[__nodiscard__]]
4410 inline string
4411 to_string(double __val)
4412 {
4413 const int __n =
4414 __gnu_cxx::__numeric_traits<double>::__max_exponent10 + 20;
4415 return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, __n,
4416 "%f", __val);
4417 }
4418
4419 _GLIBCXX_NODISCARD[[__nodiscard__]]
4420 inline string
4421 to_string(long double __val)
4422 {
4423 const int __n =
4424 __gnu_cxx::__numeric_traits<long double>::__max_exponent10 + 20;
4425 return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, __n,
4426 "%Lf", __val);
4427 }
4428#endif // _GLIBCXX_USE_C99_STDIO
4429
4430#if defined(_GLIBCXX_USE_WCHAR_T1) && _GLIBCXX_USE_C99_WCHAR1
4431 inline int
4432 stoi(const wstring& __str, size_t* __idx = 0, int __base = 10)
4433 { return __gnu_cxx::__stoa<long, int>(&std::wcstol, "stoi", __str.c_str(),
4434 __idx, __base); }
4435
4436 inline long
4437 stol(const wstring& __str, size_t* __idx = 0, int __base = 10)
4438 { return __gnu_cxx::__stoa(&std::wcstol, "stol", __str.c_str(),
4439 __idx, __base); }
4440
4441 inline unsigned long
4442 stoul(const wstring& __str, size_t* __idx = 0, int __base = 10)
4443 { return __gnu_cxx::__stoa(&std::wcstoul, "stoul", __str.c_str(),
4444 __idx, __base); }
4445
4446 inline long long
4447 stoll(const wstring& __str, size_t* __idx = 0, int __base = 10)
4448 { return __gnu_cxx::__stoa(&std::wcstoll, "stoll", __str.c_str(),
4449 __idx, __base); }
4450
4451 inline unsigned long long
4452 stoull(const wstring& __str, size_t* __idx = 0, int __base = 10)
4453 { return __gnu_cxx::__stoa(&std::wcstoull, "stoull", __str.c_str(),
4454 __idx, __base); }
4455
4456 // NB: wcstof vs wcstod.
4457 inline float
4458 stof(const wstring& __str, size_t* __idx = 0)
4459 { return __gnu_cxx::__stoa(&std::wcstof, "stof", __str.c_str(), __idx); }
4460
4461 inline double
4462 stod(const wstring& __str, size_t* __idx = 0)
4463 { return __gnu_cxx::__stoa(&std::wcstod, "stod", __str.c_str(), __idx); }
4464
4465 inline long double
4466 stold(const wstring& __str, size_t* __idx = 0)
4467 { return __gnu_cxx::__stoa(&std::wcstold, "stold", __str.c_str(), __idx); }
4468#endif
4469
4470#ifdef _GLIBCXX_USE_WCHAR_T1
4471#pragma GCC diagnostic push
4472#pragma GCC diagnostic ignored "-Wc++17-extensions"
4473 _GLIBCXX20_CONSTEXPRconstexpr
4474 inline void
4475 __to_wstring_numeric(const char* __s, int __len, wchar_t* __wout)
4476 {
4477 // This condition is true if exec-charset and wide-exec-charset share the
4478 // same values for the ASCII subset or the EBCDIC invariant character set.
4479 if constexpr (wchar_t('0') == L'0' && wchar_t('-') == L'-'
4480 && wchar_t('.') == L'.' && wchar_t('e') == L'e')
4481 {
4482 for (int __i = 0; __i < __len; ++__i)
4483 __wout[__i] = (wchar_t) __s[__i];
4484 }
4485 else
4486 {
4487 wchar_t __wc[256];
4488 for (int __i = '0'; __i <= '9'; ++__i)
4489 __wc[__i] = L'0' + __i;
4490 __wc['.'] = L'.';
4491 __wc['+'] = L'+';
4492 __wc['-'] = L'-';
4493 __wc['a'] = L'a';
4494 __wc['b'] = L'b';
4495 __wc['c'] = L'c';
4496 __wc['d'] = L'd';
4497 __wc['e'] = L'e';
4498 __wc['f'] = L'f';
4499 __wc['n'] = L'n'; // for "nan" and "inf"
4500 __wc['p'] = L'p'; // for hexfloats "0x1p1"
4501 __wc['x'] = L'x';
4502 __wc['A'] = L'A';
4503 __wc['B'] = L'B';
4504 __wc['C'] = L'C';
4505 __wc['D'] = L'D';
4506 __wc['E'] = L'E';
4507 __wc['F'] = L'F';
4508 __wc['N'] = L'N';
4509 __wc['P'] = L'P';
4510 __wc['X'] = L'X';
4511
4512 for (int __i = 0; __i < __len; ++__i)
4513 __wout[__i] = __wc[(int)__s[__i]];
4514 }
4515 }
4516
4517#if __glibcxx_constexpr_string201907L >= 201907L
4518 constexpr
4519#endif
4520 inline wstring
4521#if __cplusplus202002L >= 201703L
4522 __to_wstring_numeric(string_view __s)
4523#else
4524 __to_wstring_numeric(const string& __s)
4525#endif
4526 {
4527 if constexpr (wchar_t('0') == L'0' && wchar_t('-') == L'-'
4528 && wchar_t('.') == L'.' && wchar_t('e') == L'e')
4529 return wstring(__s.data(), __s.data() + __s.size());
4530 else
4531 {
4532 wstring __ws;
4533 auto __f = __s.data();
4534 __ws.__resize_and_overwrite(__s.size(),
4535 [__f] (wchar_t* __to, int __n) {
4536 std::__to_wstring_numeric(__f, __n, __to);
4537 return __n;
4538 });
4539 return __ws;
4540 }
4541 }
4542#pragma GCC diagnostic pop
4543
4544 _GLIBCXX_NODISCARD[[__nodiscard__]]
4545 inline wstring
4546 to_wstring(int __val)
4547 { return std::__to_wstring_numeric(std::to_string(__val)); }
4548
4549 _GLIBCXX_NODISCARD[[__nodiscard__]]
4550 inline wstring
4551 to_wstring(unsigned __val)
4552 { return std::__to_wstring_numeric(std::to_string(__val)); }
4553
4554 _GLIBCXX_NODISCARD[[__nodiscard__]]
4555 inline wstring
4556 to_wstring(long __val)
4557 { return std::__to_wstring_numeric(std::to_string(__val)); }
4558
4559 _GLIBCXX_NODISCARD[[__nodiscard__]]
4560 inline wstring
4561 to_wstring(unsigned long __val)
4562 { return std::__to_wstring_numeric(std::to_string(__val)); }
4563
4564 _GLIBCXX_NODISCARD[[__nodiscard__]]
4565 inline wstring
4566 to_wstring(long long __val)
4567 { return std::__to_wstring_numeric(std::to_string(__val)); }
4568
4569 _GLIBCXX_NODISCARD[[__nodiscard__]]
4570 inline wstring
4571 to_wstring(unsigned long long __val)
4572 { return std::__to_wstring_numeric(std::to_string(__val)); }
4573
4574#if __glibcxx_to_string || _GLIBCXX_USE_C99_STDIO1
4575 _GLIBCXX_NODISCARD[[__nodiscard__]]
4576 inline wstring
4577 to_wstring(float __val)
4578 { return std::__to_wstring_numeric(std::to_string(__val)); }
4579
4580 _GLIBCXX_NODISCARD[[__nodiscard__]]
4581 inline wstring
4582 to_wstring(double __val)
4583 { return std::__to_wstring_numeric(std::to_string(__val)); }
4584
4585 _GLIBCXX_NODISCARD[[__nodiscard__]]
4586 inline wstring
4587 to_wstring(long double __val)
4588 { return std::__to_wstring_numeric(std::to_string(__val)); }
4589#endif
4590#endif // _GLIBCXX_USE_WCHAR_T
4591
4592_GLIBCXX_END_NAMESPACE_CXX11}
4593_GLIBCXX_END_NAMESPACE_VERSION
4594} // namespace
4595
4596#endif /* C++11 */
4597
4598#if __cplusplus202002L >= 201103L
4599
4600#include <bits/functional_hash.h>
4601
4602namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
4603{
4604_GLIBCXX_BEGIN_NAMESPACE_VERSION
4605
4606 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4607 // 3705. Hashability shouldn't depend on basic_string's allocator
4608
4609 template<typename _CharT, typename _Alloc,
4610 typename _StrT = basic_string<_CharT, char_traits<_CharT>, _Alloc>>
4611 struct __str_hash_base
4612 : public __hash_base<size_t, _StrT>
4613 {
4614 [[__nodiscard__]]
4615 size_t
4616 operator()(const _StrT& __s) const noexcept
4617 { return _Hash_impl::hash(__s.data(), __s.length() * sizeof(_CharT)); }
4618 };
4619
4620#ifndef _GLIBCXX_COMPATIBILITY_CXX0X
4621 /// std::hash specialization for string.
4622 template<typename _Alloc>
4623 struct hash<basic_string<char, char_traits<char>, _Alloc>>
4624 : public __str_hash_base<char, _Alloc>
4625 { };
4626
4627 /// std::hash specialization for wstring.
4628 template<typename _Alloc>
4629 struct hash<basic_string<wchar_t, char_traits<wchar_t>, _Alloc>>
4630 : public __str_hash_base<wchar_t, _Alloc>
4631 { };
4632
4633 template<typename _Alloc>
4634 struct __is_fast_hash<hash<basic_string<wchar_t, char_traits<wchar_t>,
4635 _Alloc>>>
4636 : std::false_type
4637 { };
4638#endif /* _GLIBCXX_COMPATIBILITY_CXX0X */
4639
4640#ifdef _GLIBCXX_USE_CHAR8_T1
4641 /// std::hash specialization for u8string.
4642 template<typename _Alloc>
4643 struct hash<basic_string<char8_t, char_traits<char8_t>, _Alloc>>
4644 : public __str_hash_base<char8_t, _Alloc>
4645 { };
4646#endif
4647
4648 /// std::hash specialization for u16string.
4649 template<typename _Alloc>
4650 struct hash<basic_string<char16_t, char_traits<char16_t>, _Alloc>>
4651 : public __str_hash_base<char16_t, _Alloc>
4652 { };
4653
4654 /// std::hash specialization for u32string.
4655 template<typename _Alloc>
4656 struct hash<basic_string<char32_t, char_traits<char32_t>, _Alloc>>
4657 : public __str_hash_base<char32_t, _Alloc>
4658 { };
4659
4660#if ! _GLIBCXX_INLINE_VERSION0
4661 // PR libstdc++/105907 - __is_fast_hash affects unordered container ABI.
4662 template<> struct __is_fast_hash<hash<string>> : std::false_type { };
4663 template<> struct __is_fast_hash<hash<wstring>> : std::false_type { };
4664 template<> struct __is_fast_hash<hash<u16string>> : std::false_type { };
4665 template<> struct __is_fast_hash<hash<u32string>> : std::false_type { };
4666#ifdef _GLIBCXX_USE_CHAR8_T1
4667 template<> struct __is_fast_hash<hash<u8string>> : std::false_type { };
4668#endif
4669#else
4670 // For versioned namespace, assume every std::hash<basic_string<>> is slow.
4671 template<typename _CharT, typename _Traits, typename _Alloc>
4672 struct __is_fast_hash<hash<basic_string<_CharT, _Traits, _Alloc>>>
4673 : std::false_type
4674 { };
4675#endif
4676
4677#ifdef __glibcxx_string_udls201304L // C++ >= 14
4678 inline namespace literals
4679 {
4680 inline namespace string_literals
4681 {
4682#pragma GCC diagnostic push
4683#pragma GCC diagnostic ignored "-Wliteral-suffix"
4684
4685#if __glibcxx_constexpr_string201907L >= 201907L
4686# define _GLIBCXX_STRING_CONSTEXPR constexpr
4687#else
4688# define _GLIBCXX_STRING_CONSTEXPR
4689#endif
4690
4691 _GLIBCXX_DEFAULT_ABI_TAG__attribute ((__abi_tag__ ("cxx11"))) _GLIBCXX_STRING_CONSTEXPR
4692 inline basic_string<char>
4693 operator""s(const char* __str, size_t __len)
4694 { return basic_string<char>{__str, __len}; }
4695
4696 _GLIBCXX_DEFAULT_ABI_TAG__attribute ((__abi_tag__ ("cxx11"))) _GLIBCXX_STRING_CONSTEXPR
4697 inline basic_string<wchar_t>
4698 operator""s(const wchar_t* __str, size_t __len)
4699 { return basic_string<wchar_t>{__str, __len}; }
4700
4701#ifdef _GLIBCXX_USE_CHAR8_T1
4702 _GLIBCXX_DEFAULT_ABI_TAG__attribute ((__abi_tag__ ("cxx11"))) _GLIBCXX_STRING_CONSTEXPR
4703 inline basic_string<char8_t>
4704 operator""s(const char8_t* __str, size_t __len)
4705 { return basic_string<char8_t>{__str, __len}; }
4706#endif
4707
4708 _GLIBCXX_DEFAULT_ABI_TAG__attribute ((__abi_tag__ ("cxx11"))) _GLIBCXX_STRING_CONSTEXPR
4709 inline basic_string<char16_t>
4710 operator""s(const char16_t* __str, size_t __len)
4711 { return basic_string<char16_t>{__str, __len}; }
4712
4713 _GLIBCXX_DEFAULT_ABI_TAG__attribute ((__abi_tag__ ("cxx11"))) _GLIBCXX_STRING_CONSTEXPR
4714 inline basic_string<char32_t>
4715 operator""s(const char32_t* __str, size_t __len)
4716 { return basic_string<char32_t>{__str, __len}; }
4717
4718#undef _GLIBCXX_STRING_CONSTEXPR
4719#pragma GCC diagnostic pop
4720 } // inline namespace string_literals
4721 } // inline namespace literals
4722#endif // __glibcxx_string_udls
4723
4724#if __cplusplus202002L >= 201703L
4725 namespace __detail::__variant
4726 {
4727 template<typename> struct _Never_valueless_alt; // see <variant>
4728
4729 // Provide the strong exception-safety guarantee when emplacing a
4730 // basic_string into a variant, but only if moving the string cannot throw.
4731 template<typename _Tp, typename _Traits, typename _Alloc>
4732 struct _Never_valueless_alt<std::basic_string<_Tp, _Traits, _Alloc>>
4733 : __and_<
4734 is_nothrow_move_constructible<std::basic_string<_Tp, _Traits, _Alloc>>,
4735 is_nothrow_move_assignable<std::basic_string<_Tp, _Traits, _Alloc>>
4736 >::type
4737 { };
4738 } // namespace __detail::__variant
4739#endif // C++17
4740
4741_GLIBCXX_END_NAMESPACE_VERSION
4742} // namespace std
4743
4744#endif // C++11
4745
4746#endif /* _BASIC_STRING_H */