Bug Summary

File:build/source/clang/lib/Tooling/Transformer/RewriteRule.cpp
Warning:line 362, column 5
Potential leak of memory pointed to by field '_M_pi'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name RewriteRule.cpp -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 -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/source/build-llvm/tools/clang/stage2-bins -resource-dir /usr/lib/llvm-17/lib/clang/17 -D CLANG_REPOSITORY_STRING="++20230510111145+7df43bdb42ae-1~exp1~20230510111303.1288" -D _DEBUG -D _GLIBCXX_ASSERTIONS -D _GNU_SOURCE -D _LIBCPP_ENABLE_ASSERTIONS -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I tools/clang/lib/Tooling/Transformer -I /build/source/clang/lib/Tooling/Transformer -I /build/source/clang/include -I tools/clang/include -I include -I /build/source/llvm/include -D _FORTIFY_SOURCE=2 -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-17/lib/clang/17/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fmacro-prefix-map=/build/source/= -fcoverage-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fcoverage-prefix-map=/build/source/= -source-date-epoch 1683717183 -O2 -Wno-unused-command-line-argument -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -Wno-misleading-indentation -std=c++17 -fdeprecated-macro -fdebug-compilation-dir=/build/source/build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/source/= -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2023-05-10-133810-16478-1 -x c++ /build/source/clang/lib/Tooling/Transformer/RewriteRule.cpp

/build/source/clang/lib/Tooling/Transformer/RewriteRule.cpp

1//===--- Transformer.cpp - Transformer library implementation ---*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "clang/Tooling/Transformer/RewriteRule.h"
10#include "clang/AST/ASTTypeTraits.h"
11#include "clang/AST/Stmt.h"
12#include "clang/ASTMatchers/ASTMatchFinder.h"
13#include "clang/ASTMatchers/ASTMatchers.h"
14#include "clang/Basic/SourceLocation.h"
15#include "clang/Tooling/Transformer/SourceCode.h"
16#include "llvm/ADT/StringRef.h"
17#include "llvm/Support/Errc.h"
18#include "llvm/Support/Error.h"
19#include <map>
20#include <string>
21#include <utility>
22#include <vector>
23
24using namespace clang;
25using namespace transformer;
26
27using ast_matchers::MatchFinder;
28using ast_matchers::internal::DynTypedMatcher;
29
30using MatchResult = MatchFinder::MatchResult;
31
32const char transformer::RootID[] = "___root___";
33
34static Expected<SmallVector<transformer::Edit, 1>>
35translateEdits(const MatchResult &Result, ArrayRef<ASTEdit> ASTEdits) {
36 SmallVector<transformer::Edit, 1> Edits;
37 for (const auto &E : ASTEdits) {
38 Expected<CharSourceRange> Range = E.TargetRange(Result);
39 if (!Range)
40 return Range.takeError();
41 std::optional<CharSourceRange> EditRange =
42 tooling::getFileRangeForEdit(*Range, *Result.Context);
43 // FIXME: let user specify whether to treat this case as an error or ignore
44 // it as is currently done. This behavior is problematic in that it hides
45 // failures from bad ranges. Also, the behavior here differs from
46 // `flatten`. Here, we abort (without error), whereas flatten, if it hits an
47 // empty list, does not abort. As a result, `editList({A,B})` is not
48 // equivalent to `flatten(edit(A), edit(B))`. The former will abort if `A`
49 // produces a bad range, whereas the latter will simply ignore A.
50 if (!EditRange)
51 return SmallVector<Edit, 0>();
52 transformer::Edit T;
53 T.Kind = E.Kind;
54 T.Range = *EditRange;
55 if (E.Replacement) {
56 auto Replacement = E.Replacement->eval(Result);
57 if (!Replacement)
58 return Replacement.takeError();
59 T.Replacement = std::move(*Replacement);
60 }
61 if (E.Note) {
62 auto Note = E.Note->eval(Result);
63 if (!Note)
64 return Note.takeError();
65 T.Note = std::move(*Note);
66 }
67 if (E.Metadata) {
68 auto Metadata = E.Metadata(Result);
69 if (!Metadata)
70 return Metadata.takeError();
71 T.Metadata = std::move(*Metadata);
72 }
73 Edits.push_back(std::move(T));
74 }
75 return Edits;
76}
77
78EditGenerator transformer::editList(SmallVector<ASTEdit, 1> Edits) {
79 return [Edits = std::move(Edits)](const MatchResult &Result) {
80 return translateEdits(Result, Edits);
81 };
82}
83
84EditGenerator transformer::edit(ASTEdit Edit) {
85 return [Edit = std::move(Edit)](const MatchResult &Result) {
86 return translateEdits(Result, {Edit});
87 };
88}
89
90EditGenerator transformer::noopEdit(RangeSelector Anchor) {
91 return [Anchor = std::move(Anchor)](const MatchResult &Result)
92 -> Expected<SmallVector<transformer::Edit, 1>> {
93 Expected<CharSourceRange> Range = Anchor(Result);
94 if (!Range)
95 return Range.takeError();
96 // In case the range is inside a macro expansion, map the location back to a
97 // "real" source location.
98 SourceLocation Begin =
99 Result.SourceManager->getSpellingLoc(Range->getBegin());
100 Edit E;
101 // Implicitly, leave `E.Replacement` as the empty string.
102 E.Kind = EditKind::Range;
103 E.Range = CharSourceRange::getCharRange(Begin, Begin);
104 return SmallVector<Edit, 1>{E};
105 };
106}
107
108EditGenerator
109transformer::flattenVector(SmallVector<EditGenerator, 2> Generators) {
110 if (Generators.size() == 1)
111 return std::move(Generators[0]);
112 return
113 [Gs = std::move(Generators)](
114 const MatchResult &Result) -> llvm::Expected<SmallVector<Edit, 1>> {
115 SmallVector<Edit, 1> AllEdits;
116 for (const auto &G : Gs) {
117 llvm::Expected<SmallVector<Edit, 1>> Edits = G(Result);
118 if (!Edits)
119 return Edits.takeError();
120 AllEdits.append(Edits->begin(), Edits->end());
121 }
122 return AllEdits;
123 };
124}
125
126ASTEdit transformer::changeTo(RangeSelector Target, TextGenerator Replacement) {
127 ASTEdit E;
128 E.TargetRange = std::move(Target);
129 E.Replacement = std::move(Replacement);
130 return E;
131}
132
133ASTEdit transformer::note(RangeSelector Anchor, TextGenerator Note) {
134 ASTEdit E;
135 E.TargetRange = transformer::before(Anchor);
136 E.Note = std::move(Note);
137 return E;
138}
139
140namespace {
141/// A \c TextGenerator that always returns a fixed string.
142class SimpleTextGenerator : public MatchComputation<std::string> {
143 std::string S;
144
145public:
146 SimpleTextGenerator(std::string S) : S(std::move(S)) {}
147 llvm::Error eval(const ast_matchers::MatchFinder::MatchResult &,
148 std::string *Result) const override {
149 Result->append(S);
150 return llvm::Error::success();
151 }
152 std::string toString() const override {
153 return (llvm::Twine("text(\"") + S + "\")").str();
154 }
155};
156} // namespace
157
158static TextGenerator makeText(std::string S) {
159 return std::make_shared<SimpleTextGenerator>(std::move(S));
5
Calling 'make_shared<(anonymous namespace)::SimpleTextGenerator, std::basic_string<char>>'
23
Returned allocated memory
160}
161
162ASTEdit transformer::remove(RangeSelector S) {
163 return change(std::move(S), makeText(""));
164}
165
166static std::string formatHeaderPath(StringRef Header, IncludeFormat Format) {
167 switch (Format) {
168 case transformer::IncludeFormat::Quoted:
169 return Header.str();
170 case transformer::IncludeFormat::Angled:
171 return ("<" + Header + ">").str();
172 }
173 llvm_unreachable("Unknown transformer::IncludeFormat enum")::llvm::llvm_unreachable_internal("Unknown transformer::IncludeFormat enum"
, "clang/lib/Tooling/Transformer/RewriteRule.cpp", 173)
;
174}
175
176ASTEdit transformer::addInclude(RangeSelector Target, StringRef Header,
177 IncludeFormat Format) {
178 ASTEdit E;
179 E.Kind = EditKind::AddInclude;
180 E.TargetRange = Target;
181 E.Replacement = makeText(formatHeaderPath(Header, Format));
4
Calling 'makeText'
24
Returned allocated memory
182 return E;
183}
184
185EditGenerator
186transformer::detail::makeEditGenerator(llvm::SmallVector<ASTEdit, 1> Edits) {
187 return editList(std::move(Edits));
188}
189
190EditGenerator transformer::detail::makeEditGenerator(ASTEdit Edit) {
191 return edit(std::move(Edit));
192}
193
194RewriteRule transformer::detail::makeRule(DynTypedMatcher M,
195 EditGenerator Edits) {
196 RewriteRule R;
197 R.Cases = {{std::move(M), std::move(Edits)}};
198 return R;
199}
200
201RewriteRule transformer::makeRule(ast_matchers::internal::DynTypedMatcher M,
202 std::initializer_list<ASTEdit> Edits) {
203 return detail::makeRule(std::move(M),
204 detail::makeEditGenerator(std::move(Edits)));
205}
206
207namespace {
208
209/// Unconditionally binds the given node set before trying `InnerMatcher` and
210/// keeps the bound nodes on a successful match.
211template <typename T>
212class BindingsMatcher : public ast_matchers::internal::MatcherInterface<T> {
213 ast_matchers::BoundNodes Nodes;
214 const ast_matchers::internal::Matcher<T> InnerMatcher;
215
216public:
217 explicit BindingsMatcher(ast_matchers::BoundNodes Nodes,
218 ast_matchers::internal::Matcher<T> InnerMatcher)
219 : Nodes(std::move(Nodes)), InnerMatcher(std::move(InnerMatcher)) {}
220
221 bool matches(
222 const T &Node, ast_matchers::internal::ASTMatchFinder *Finder,
223 ast_matchers::internal::BoundNodesTreeBuilder *Builder) const override {
224 ast_matchers::internal::BoundNodesTreeBuilder Result(*Builder);
225 for (const auto &N : Nodes.getMap())
226 Result.setBinding(N.first, N.second);
227 if (InnerMatcher.matches(Node, Finder, &Result)) {
228 *Builder = std::move(Result);
229 return true;
230 }
231 return false;
232 }
233};
234
235/// Matches nodes of type T that have at least one descendant node for which the
236/// given inner matcher matches. Will match for each descendant node that
237/// matches. Based on ForEachDescendantMatcher, but takes a dynamic matcher,
238/// instead of a static one, because it is used by RewriteRule, which carries
239/// (only top-level) dynamic matchers.
240template <typename T>
241class DynamicForEachDescendantMatcher
242 : public ast_matchers::internal::MatcherInterface<T> {
243 const DynTypedMatcher DescendantMatcher;
244
245public:
246 explicit DynamicForEachDescendantMatcher(DynTypedMatcher DescendantMatcher)
247 : DescendantMatcher(std::move(DescendantMatcher)) {}
248
249 bool matches(
250 const T &Node, ast_matchers::internal::ASTMatchFinder *Finder,
251 ast_matchers::internal::BoundNodesTreeBuilder *Builder) const override {
252 return Finder->matchesDescendantOf(
253 Node, this->DescendantMatcher, Builder,
254 ast_matchers::internal::ASTMatchFinder::BK_All);
255 }
256};
257
258template <typename T>
259ast_matchers::internal::Matcher<T>
260forEachDescendantDynamically(ast_matchers::BoundNodes Nodes,
261 DynTypedMatcher M) {
262 return ast_matchers::internal::makeMatcher(new BindingsMatcher<T>(
263 std::move(Nodes),
264 ast_matchers::internal::makeMatcher(
265 new DynamicForEachDescendantMatcher<T>(std::move(M)))));
266}
267
268class ApplyRuleCallback : public MatchFinder::MatchCallback {
269public:
270 ApplyRuleCallback(RewriteRule Rule) : Rule(std::move(Rule)) {}
271
272 template <typename T>
273 void registerMatchers(const ast_matchers::BoundNodes &Nodes,
274 MatchFinder *MF) {
275 for (auto &Matcher : transformer::detail::buildMatchers(Rule))
276 MF->addMatcher(forEachDescendantDynamically<T>(Nodes, Matcher), this);
277 }
278
279 void run(const MatchFinder::MatchResult &Result) override {
280 if (!Edits)
281 return;
282 size_t I = transformer::detail::findSelectedCase(Result, Rule);
283 auto Transformations = Rule.Cases[I].Edits(Result);
284 if (!Transformations) {
285 Edits = Transformations.takeError();
286 return;
287 }
288 Edits->append(Transformations->begin(), Transformations->end());
289 }
290
291 RewriteRule Rule;
292
293 // Initialize to a non-error state.
294 Expected<SmallVector<Edit, 1>> Edits = SmallVector<Edit, 1>();
295};
296} // namespace
297
298template <typename T>
299llvm::Expected<SmallVector<clang::transformer::Edit, 1>>
300rewriteDescendantsImpl(const T &Node, RewriteRule Rule,
301 const MatchResult &Result) {
302 ApplyRuleCallback Callback(std::move(Rule));
303 MatchFinder Finder;
304 Callback.registerMatchers<T>(Result.Nodes, &Finder);
305 Finder.match(Node, *Result.Context);
306 return std::move(Callback.Edits);
307}
308
309llvm::Expected<SmallVector<clang::transformer::Edit, 1>>
310transformer::detail::rewriteDescendants(const Decl &Node, RewriteRule Rule,
311 const MatchResult &Result) {
312 return rewriteDescendantsImpl(Node, std::move(Rule), Result);
313}
314
315llvm::Expected<SmallVector<clang::transformer::Edit, 1>>
316transformer::detail::rewriteDescendants(const Stmt &Node, RewriteRule Rule,
317 const MatchResult &Result) {
318 return rewriteDescendantsImpl(Node, std::move(Rule), Result);
319}
320
321llvm::Expected<SmallVector<clang::transformer::Edit, 1>>
322transformer::detail::rewriteDescendants(const TypeLoc &Node, RewriteRule Rule,
323 const MatchResult &Result) {
324 return rewriteDescendantsImpl(Node, std::move(Rule), Result);
325}
326
327llvm::Expected<SmallVector<clang::transformer::Edit, 1>>
328transformer::detail::rewriteDescendants(const DynTypedNode &DNode,
329 RewriteRule Rule,
330 const MatchResult &Result) {
331 if (const auto *Node = DNode.get<Decl>())
332 return rewriteDescendantsImpl(*Node, std::move(Rule), Result);
333 if (const auto *Node = DNode.get<Stmt>())
334 return rewriteDescendantsImpl(*Node, std::move(Rule), Result);
335 if (const auto *Node = DNode.get<TypeLoc>())
336 return rewriteDescendantsImpl(*Node, std::move(Rule), Result);
337
338 return llvm::make_error<llvm::StringError>(
339 llvm::errc::invalid_argument,
340 "type unsupported for recursive rewriting, Kind=" +
341 DNode.getNodeKind().asStringRef());
342}
343
344EditGenerator transformer::rewriteDescendants(std::string NodeId,
345 RewriteRule Rule) {
346 return [NodeId = std::move(NodeId),
347 Rule = std::move(Rule)](const MatchResult &Result)
348 -> llvm::Expected<SmallVector<clang::transformer::Edit, 1>> {
349 const ast_matchers::BoundNodes::IDToNodeMap &NodesMap =
350 Result.Nodes.getMap();
351 auto It = NodesMap.find(NodeId);
352 if (It == NodesMap.end())
353 return llvm::make_error<llvm::StringError>(llvm::errc::invalid_argument,
354 "ID not bound: " + NodeId);
355 return detail::rewriteDescendants(It->second, std::move(Rule), Result);
356 };
357}
358
359void transformer::addInclude(RewriteRuleBase &Rule, StringRef Header,
360 IncludeFormat Format) {
361 for (auto &Case : Rule.Cases)
1
Assuming '__begin1' is not equal to '__end1'
362 Case.Edits = flatten(std::move(Case.Edits), addInclude(Header, Format));
2
Calling 'addInclude'
26
Returned allocated memory
27
Potential leak of memory pointed to by field '_M_pi'
363}
364
365#ifndef NDEBUG
366// Filters for supported matcher kinds. FIXME: Explicitly list the allowed kinds
367// (all node matcher types except for `QualType` and `Type`), rather than just
368// banning `QualType` and `Type`.
369static bool hasValidKind(const DynTypedMatcher &M) {
370 return !M.canConvertTo<QualType>();
371}
372#endif
373
374// Binds each rule's matcher to a unique (and deterministic) tag based on
375// `TagBase` and the id paired with the case. All of the returned matchers have
376// their traversal kind explicitly set, either based on a pre-set kind or to the
377// provided `DefaultTraversalKind`.
378static std::vector<DynTypedMatcher> taggedMatchers(
379 StringRef TagBase,
380 const SmallVectorImpl<std::pair<size_t, RewriteRule::Case>> &Cases,
381 TraversalKind DefaultTraversalKind) {
382 std::vector<DynTypedMatcher> Matchers;
383 Matchers.reserve(Cases.size());
384 for (const auto &Case : Cases) {
385 std::string Tag = (TagBase + Twine(Case.first)).str();
386 // HACK: Many matchers are not bindable, so ensure that tryBind will work.
387 DynTypedMatcher BoundMatcher(Case.second.Matcher);
388 BoundMatcher.setAllowBind(true);
389 auto M = *BoundMatcher.tryBind(Tag);
390 Matchers.push_back(!M.getTraversalKind()
391 ? M.withTraversalKind(DefaultTraversalKind)
392 : std::move(M));
393 }
394 return Matchers;
395}
396
397// Simply gathers the contents of the various rules into a single rule. The
398// actual work to combine these into an ordered choice is deferred to matcher
399// registration.
400template <>
401RewriteRuleWith<void>
402transformer::applyFirst(ArrayRef<RewriteRuleWith<void>> Rules) {
403 RewriteRule R;
404 for (auto &Rule : Rules)
405 R.Cases.append(Rule.Cases.begin(), Rule.Cases.end());
406 return R;
407}
408
409std::vector<DynTypedMatcher>
410transformer::detail::buildMatchers(const RewriteRuleBase &Rule) {
411 // Map the cases into buckets of matchers -- one for each "root" AST kind,
412 // which guarantees that they can be combined in a single anyOf matcher. Each
413 // case is paired with an identifying number that is converted to a string id
414 // in `taggedMatchers`.
415 std::map<ASTNodeKind,
416 SmallVector<std::pair<size_t, RewriteRuleBase::Case>, 1>>
417 Buckets;
418 const SmallVectorImpl<RewriteRule::Case> &Cases = Rule.Cases;
419 for (int I = 0, N = Cases.size(); I < N; ++I) {
420 assert(hasValidKind(Cases[I].Matcher) &&(static_cast <bool> (hasValidKind(Cases[I].Matcher) &&
"Matcher must be non-(Qual)Type node matcher") ? void (0) : __assert_fail
("hasValidKind(Cases[I].Matcher) && \"Matcher must be non-(Qual)Type node matcher\""
, "clang/lib/Tooling/Transformer/RewriteRule.cpp", 421, __extension__
__PRETTY_FUNCTION__))
421 "Matcher must be non-(Qual)Type node matcher")(static_cast <bool> (hasValidKind(Cases[I].Matcher) &&
"Matcher must be non-(Qual)Type node matcher") ? void (0) : __assert_fail
("hasValidKind(Cases[I].Matcher) && \"Matcher must be non-(Qual)Type node matcher\""
, "clang/lib/Tooling/Transformer/RewriteRule.cpp", 421, __extension__
__PRETTY_FUNCTION__))
;
422 Buckets[Cases[I].Matcher.getSupportedKind()].emplace_back(I, Cases[I]);
423 }
424
425 // Each anyOf explicitly controls the traversal kind. The anyOf itself is set
426 // to `TK_AsIs` to ensure no nodes are skipped, thereby deferring to the kind
427 // of the branches. Then, each branch is either left as is, if the kind is
428 // already set, or explicitly set to `TK_AsIs`. We choose this setting because
429 // it is the default interpretation of matchers.
430 std::vector<DynTypedMatcher> Matchers;
431 for (const auto &Bucket : Buckets) {
432 DynTypedMatcher M = DynTypedMatcher::constructVariadic(
433 DynTypedMatcher::VO_AnyOf, Bucket.first,
434 taggedMatchers("Tag", Bucket.second, TK_AsIs));
435 M.setAllowBind(true);
436 // `tryBind` is guaranteed to succeed, because `AllowBind` was set to true.
437 Matchers.push_back(M.tryBind(RootID)->withTraversalKind(TK_AsIs));
438 }
439 return Matchers;
440}
441
442DynTypedMatcher transformer::detail::buildMatcher(const RewriteRuleBase &Rule) {
443 std::vector<DynTypedMatcher> Ms = buildMatchers(Rule);
444 assert(Ms.size() == 1 && "Cases must have compatible matchers.")(static_cast <bool> (Ms.size() == 1 && "Cases must have compatible matchers."
) ? void (0) : __assert_fail ("Ms.size() == 1 && \"Cases must have compatible matchers.\""
, "clang/lib/Tooling/Transformer/RewriteRule.cpp", 444, __extension__
__PRETTY_FUNCTION__))
;
445 return Ms[0];
446}
447
448SourceLocation transformer::detail::getRuleMatchLoc(const MatchResult &Result) {
449 auto &NodesMap = Result.Nodes.getMap();
450 auto Root = NodesMap.find(RootID);
451 assert(Root != NodesMap.end() && "Transformation failed: missing root node.")(static_cast <bool> (Root != NodesMap.end() && "Transformation failed: missing root node."
) ? void (0) : __assert_fail ("Root != NodesMap.end() && \"Transformation failed: missing root node.\""
, "clang/lib/Tooling/Transformer/RewriteRule.cpp", 451, __extension__
__PRETTY_FUNCTION__))
;
452 std::optional<CharSourceRange> RootRange = tooling::getFileRangeForEdit(
453 CharSourceRange::getTokenRange(Root->second.getSourceRange()),
454 *Result.Context);
455 if (RootRange)
456 return RootRange->getBegin();
457 // The match doesn't have a coherent range, so fall back to the expansion
458 // location as the "beginning" of the match.
459 return Result.SourceManager->getExpansionLoc(
460 Root->second.getSourceRange().getBegin());
461}
462
463// Finds the case that was "selected" -- that is, whose matcher triggered the
464// `MatchResult`.
465size_t transformer::detail::findSelectedCase(const MatchResult &Result,
466 const RewriteRuleBase &Rule) {
467 if (Rule.Cases.size() == 1)
468 return 0;
469
470 auto &NodesMap = Result.Nodes.getMap();
471 for (size_t i = 0, N = Rule.Cases.size(); i < N; ++i) {
472 std::string Tag = ("Tag" + Twine(i)).str();
473 if (NodesMap.find(Tag) != NodesMap.end())
474 return i;
475 }
476 llvm_unreachable("No tag found for this rule.")::llvm::llvm_unreachable_internal("No tag found for this rule."
, "clang/lib/Tooling/Transformer/RewriteRule.cpp", 476)
;
477}

/build/source/clang/include/clang/Tooling/Transformer/RewriteRule.h

1//===--- RewriteRule.h - RewriteRule class ----------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// Defines the RewriteRule class and related functions for creating,
11/// modifying and interpreting RewriteRules.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_TOOLING_TRANSFORMER_REWRITERULE_H
16#define LLVM_CLANG_TOOLING_TRANSFORMER_REWRITERULE_H
17
18#include "clang/ASTMatchers/ASTMatchFinder.h"
19#include "clang/ASTMatchers/ASTMatchers.h"
20#include "clang/ASTMatchers/ASTMatchersInternal.h"
21#include "clang/Tooling/Refactoring/AtomicChange.h"
22#include "clang/Tooling/Transformer/MatchConsumer.h"
23#include "clang/Tooling/Transformer/RangeSelector.h"
24#include "llvm/ADT/Any.h"
25#include "llvm/ADT/STLExtras.h"
26#include "llvm/ADT/SmallVector.h"
27#include "llvm/Support/Error.h"
28#include <functional>
29#include <string>
30#include <utility>
31
32namespace clang {
33namespace transformer {
34// Specifies how to interpret an edit.
35enum class EditKind {
36 // Edits a source range in the file.
37 Range,
38 // Inserts an include in the file. The `Replacement` field is the name of the
39 // newly included file.
40 AddInclude,
41};
42
43/// A concrete description of a source edit, represented by a character range in
44/// the source to be replaced and a corresponding replacement string.
45struct Edit {
46 EditKind Kind = EditKind::Range;
47 CharSourceRange Range;
48 std::string Replacement;
49 std::string Note;
50 llvm::Any Metadata;
51};
52
53/// Format of the path in an include directive -- angle brackets or quotes.
54enum class IncludeFormat {
55 Quoted,
56 Angled,
57};
58
59/// Maps a match result to a list of concrete edits (with possible
60/// failure). This type is a building block of rewrite rules, but users will
61/// generally work in terms of `ASTEdit`s (below) rather than directly in terms
62/// of `EditGenerator`.
63using EditGenerator = MatchConsumer<llvm::SmallVector<Edit, 1>>;
64
65template <typename T> using Generator = std::shared_ptr<MatchComputation<T>>;
66
67using TextGenerator = Generator<std::string>;
68
69using AnyGenerator = MatchConsumer<llvm::Any>;
70
71// Description of a source-code edit, expressed in terms of an AST node.
72// Includes: an ID for the (bound) node, a selector for source related to the
73// node, a replacement and, optionally, an explanation for the edit.
74//
75// * Target: the source code impacted by the rule. This identifies an AST node,
76// or part thereof (\c Part), whose source range indicates the extent of the
77// replacement applied by the replacement term. By default, the extent is the
78// node matched by the pattern term (\c NodePart::Node). Target's are typed
79// (\c Kind), which guides the determination of the node extent.
80//
81// * Replacement: a function that produces a replacement string for the target,
82// based on the match result.
83//
84// * Note: (optional) a note specifically for this edit, potentially referencing
85// elements of the match. This will be displayed to the user, where possible;
86// for example, in clang-tidy diagnostics. Use of notes should be rare --
87// explanations of the entire rewrite should be set in the rule
88// (`RewriteRule::Explanation`) instead. Notes serve the rare cases wherein
89// edit-specific diagnostics are required.
90//
91// `ASTEdit` should be built using the `change` convenience functions. For
92// example,
93// \code
94// changeTo(name(fun), cat("Frodo"))
95// \endcode
96// Or, if we use Stencil for the TextGenerator:
97// \code
98// using stencil::cat;
99// changeTo(statement(thenNode), cat("{", thenNode, "}"))
100// changeTo(callArgs(call), cat(x, ",", y))
101// \endcode
102// Or, if you are changing the node corresponding to the rule's matcher, you can
103// use the single-argument override of \c change:
104// \code
105// changeTo(cat("different_expr"))
106// \endcode
107struct ASTEdit {
108 EditKind Kind = EditKind::Range;
109 RangeSelector TargetRange;
110 TextGenerator Replacement;
111 TextGenerator Note;
112 // Not all transformations will want or need to attach metadata and therefore
113 // should not be required to do so.
114 AnyGenerator Metadata = [](const ast_matchers::MatchFinder::MatchResult &)
115 -> llvm::Expected<llvm::Any> {
116 return llvm::Expected<llvm::Any>(llvm::Any());
117 };
118};
119
120/// Generates a single (specified) edit.
121EditGenerator edit(ASTEdit E);
122
123/// Lifts a list of `ASTEdit`s into an `EditGenerator`.
124///
125/// The `EditGenerator` will return an empty vector if any of the edits apply to
126/// portions of the source that are ineligible for rewriting (certain
127/// interactions with macros, for example) and it will fail if any invariants
128/// are violated relating to bound nodes in the match. However, it does not
129/// fail in the case of conflicting edits -- conflict handling is left to
130/// clients. We recommend use of the \c AtomicChange or \c Replacements classes
131/// for assistance in detecting such conflicts.
132EditGenerator editList(llvm::SmallVector<ASTEdit, 1> Edits);
133
134/// Generates no edits.
135inline EditGenerator noEdits() { return editList({}); }
136
137/// Generates a single, no-op edit anchored at the start location of the
138/// specified range. A `noopEdit` may be preferred over `noEdits` to associate a
139/// diagnostic `Explanation` with the rule.
140EditGenerator noopEdit(RangeSelector Anchor);
141
142/// Generates a single, no-op edit with the associated note anchored at the
143/// start location of the specified range.
144ASTEdit note(RangeSelector Anchor, TextGenerator Note);
145
146/// Version of `ifBound` specialized to `ASTEdit`.
147inline EditGenerator ifBound(std::string ID, ASTEdit TrueEdit,
148 ASTEdit FalseEdit) {
149 return ifBound(std::move(ID), edit(std::move(TrueEdit)),
150 edit(std::move(FalseEdit)));
151}
152
153/// Version of `ifBound` that has no "False" branch. If the node is not bound,
154/// then no edits are produced.
155inline EditGenerator ifBound(std::string ID, ASTEdit TrueEdit) {
156 return ifBound(std::move(ID), edit(std::move(TrueEdit)), noEdits());
157}
158
159/// Flattens a list of generators into a single generator whose elements are the
160/// concatenation of the results of the argument generators.
161EditGenerator flattenVector(SmallVector<EditGenerator, 2> Generators);
162
163namespace detail {
164/// Helper function to construct an \c EditGenerator. Overloaded for common
165/// cases so that user doesn't need to specify which factory function to
166/// use. This pattern gives benefits similar to implicit constructors, while
167/// maintaing a higher degree of explicitness.
168inline EditGenerator injectEdits(ASTEdit E) { return edit(std::move(E)); }
169inline EditGenerator injectEdits(EditGenerator G) { return G; }
170} // namespace detail
171
172template <typename... Ts> EditGenerator flatten(Ts &&...Edits) {
173 return flattenVector({detail::injectEdits(std::forward<Ts>(Edits))...});
174}
175
176// Every rewrite rule is triggered by a match against some AST node.
177// Transformer guarantees that this ID is bound to the triggering node whenever
178// a rewrite rule is applied.
179extern const char RootID[];
180
181/// Replaces a portion of the source text with \p Replacement.
182ASTEdit changeTo(RangeSelector Target, TextGenerator Replacement);
183/// DEPRECATED: use \c changeTo.
184inline ASTEdit change(RangeSelector Target, TextGenerator Replacement) {
185 return changeTo(std::move(Target), std::move(Replacement));
186}
187
188/// Replaces the entirety of a RewriteRule's match with \p Replacement. For
189/// example, to replace a function call, one could write:
190/// \code
191/// makeRule(callExpr(callee(functionDecl(hasName("foo")))),
192/// changeTo(cat("bar()")))
193/// \endcode
194inline ASTEdit changeTo(TextGenerator Replacement) {
195 return changeTo(node(RootID), std::move(Replacement));
196}
197/// DEPRECATED: use \c changeTo.
198inline ASTEdit change(TextGenerator Replacement) {
199 return changeTo(std::move(Replacement));
200}
201
202/// Inserts \p Replacement before \p S, leaving the source selected by \S
203/// unchanged.
204inline ASTEdit insertBefore(RangeSelector S, TextGenerator Replacement) {
205 return changeTo(before(std::move(S)), std::move(Replacement));
206}
207
208/// Inserts \p Replacement after \p S, leaving the source selected by \S
209/// unchanged.
210inline ASTEdit insertAfter(RangeSelector S, TextGenerator Replacement) {
211 return changeTo(after(std::move(S)), std::move(Replacement));
212}
213
214/// Removes the source selected by \p S.
215ASTEdit remove(RangeSelector S);
216
217/// Adds an include directive for the given header to the file of `Target`. The
218/// particular location specified by `Target` is ignored.
219ASTEdit addInclude(RangeSelector Target, StringRef Header,
220 IncludeFormat Format = IncludeFormat::Quoted);
221
222/// Adds an include directive for the given header to the file associated with
223/// `RootID`. If `RootID` matches inside a macro expansion, will add the
224/// directive to the file in which the macro was expanded (as opposed to the
225/// file in which the macro is defined).
226inline ASTEdit addInclude(StringRef Header,
227 IncludeFormat Format = IncludeFormat::Quoted) {
228 return addInclude(expansion(node(RootID)), Header, Format);
3
Calling 'addInclude'
25
Returned allocated memory
229}
230
231// FIXME: If `Metadata` returns an `llvm::Expected<T>` the `AnyGenerator` will
232// construct an `llvm::Expected<llvm::Any>` where no error is present but the
233// `llvm::Any` holds the error. This is unlikely but potentially surprising.
234// Perhaps the `llvm::Expected` should be unwrapped, or perhaps this should be a
235// compile-time error. No solution here is perfect.
236//
237// Note: This function template accepts any type callable with a MatchResult
238// rather than a `std::function` because the return-type needs to be deduced. If
239// it accepted a `std::function<R(MatchResult)>`, lambdas or other callable
240// types would not be able to deduce `R`, and users would be forced to specify
241// explicitly the type they intended to return by wrapping the lambda at the
242// call-site.
243template <typename Callable>
244inline ASTEdit withMetadata(ASTEdit Edit, Callable Metadata) {
245 Edit.Metadata =
246 [Gen = std::move(Metadata)](
247 const ast_matchers::MatchFinder::MatchResult &R) -> llvm::Any {
248 return Gen(R);
249 };
250
251 return Edit;
252}
253
254/// Assuming that the inner range is enclosed by the outer range, creates
255/// precision edits to remove the parts of the outer range that are not included
256/// in the inner range.
257inline EditGenerator shrinkTo(RangeSelector outer, RangeSelector inner) {
258 return editList({remove(enclose(before(outer), before(inner))),
259 remove(enclose(after(inner), after(outer)))});
260}
261
262/// Description of a source-code transformation.
263//
264// A *rewrite rule* describes a transformation of source code. A simple rule
265// contains each of the following components:
266//
267// * Matcher: the pattern term, expressed as clang matchers (with Transformer
268// extensions).
269//
270// * Edits: a set of Edits to the source code, described with ASTEdits.
271//
272// However, rules can also consist of (sub)rules, where the first that matches
273// is applied and the rest are ignored. So, the above components together form
274// a logical "case" and a rule is a sequence of cases.
275//
276// Rule cases have an additional, implicit, component: the parameters. These are
277// portions of the pattern which are left unspecified, yet bound in the pattern
278// so that we can reference them in the edits.
279//
280// The \c Transformer class can be used to apply the rewrite rule and obtain the
281// corresponding replacements.
282struct RewriteRuleBase {
283 struct Case {
284 ast_matchers::internal::DynTypedMatcher Matcher;
285 EditGenerator Edits;
286 };
287 // We expect RewriteRules will most commonly include only one case.
288 SmallVector<Case, 1> Cases;
289};
290
291/// A source-code transformation with accompanying metadata.
292///
293/// When a case of the rule matches, the \c Transformer invokes the
294/// corresponding metadata generator and provides it alongside the edits.
295template <typename MetadataT> struct RewriteRuleWith : RewriteRuleBase {
296 SmallVector<Generator<MetadataT>, 1> Metadata;
297};
298
299template <> struct RewriteRuleWith<void> : RewriteRuleBase {};
300
301using RewriteRule = RewriteRuleWith<void>;
302
303namespace detail {
304
305RewriteRule makeRule(ast_matchers::internal::DynTypedMatcher M,
306 EditGenerator Edits);
307
308template <typename MetadataT>
309RewriteRuleWith<MetadataT> makeRule(ast_matchers::internal::DynTypedMatcher M,
310 EditGenerator Edits,
311 Generator<MetadataT> Metadata) {
312 RewriteRuleWith<MetadataT> R;
313 R.Cases = {{std::move(M), std::move(Edits)}};
314 R.Metadata = {std::move(Metadata)};
315 return R;
316}
317
318inline EditGenerator makeEditGenerator(EditGenerator Edits) { return Edits; }
319EditGenerator makeEditGenerator(llvm::SmallVector<ASTEdit, 1> Edits);
320EditGenerator makeEditGenerator(ASTEdit Edit);
321
322} // namespace detail
323
324/// Constructs a simple \c RewriteRule. \c Edits can be an \c EditGenerator,
325/// multiple \c ASTEdits, or a single \c ASTEdit.
326/// @{
327template <int &..., typename EditsT>
328RewriteRule makeRule(ast_matchers::internal::DynTypedMatcher M,
329 EditsT &&Edits) {
330 return detail::makeRule(
331 std::move(M), detail::makeEditGenerator(std::forward<EditsT>(Edits)));
332}
333
334RewriteRule makeRule(ast_matchers::internal::DynTypedMatcher M,
335 std::initializer_list<ASTEdit> Edits);
336/// @}
337
338/// Overloads of \c makeRule that also generate metadata when matching.
339/// @{
340template <typename MetadataT, int &..., typename EditsT>
341RewriteRuleWith<MetadataT> makeRule(ast_matchers::internal::DynTypedMatcher M,
342 EditsT &&Edits,
343 Generator<MetadataT> Metadata) {
344 return detail::makeRule(
345 std::move(M), detail::makeEditGenerator(std::forward<EditsT>(Edits)),
346 std::move(Metadata));
347}
348
349template <typename MetadataT>
350RewriteRuleWith<MetadataT> makeRule(ast_matchers::internal::DynTypedMatcher M,
351 std::initializer_list<ASTEdit> Edits,
352 Generator<MetadataT> Metadata) {
353 return detail::makeRule(std::move(M),
354 detail::makeEditGenerator(std::move(Edits)),
355 std::move(Metadata));
356}
357/// @}
358
359/// For every case in Rule, adds an include directive for the given header. The
360/// common use is assumed to be a rule with only one case. For example, to
361/// replace a function call and add headers corresponding to the new code, one
362/// could write:
363/// \code
364/// auto R = makeRule(callExpr(callee(functionDecl(hasName("foo")))),
365/// changeTo(cat("bar()")));
366/// addInclude(R, "path/to/bar_header.h");
367/// addInclude(R, "vector", IncludeFormat::Angled);
368/// \endcode
369void addInclude(RewriteRuleBase &Rule, llvm::StringRef Header,
370 IncludeFormat Format = IncludeFormat::Quoted);
371
372/// Applies the first rule whose pattern matches; other rules are ignored. If
373/// the matchers are independent then order doesn't matter. In that case,
374/// `applyFirst` is simply joining the set of rules into one.
375//
376// `applyFirst` is like an `anyOf` matcher with an edit action attached to each
377// of its cases. Anywhere you'd use `anyOf(m1.bind("id1"), m2.bind("id2"))` and
378// then dispatch on those ids in your code for control flow, `applyFirst` lifts
379// that behavior to the rule level. So, you can write `applyFirst({makeRule(m1,
380// action1), makeRule(m2, action2), ...});`
381//
382// For example, consider a type `T` with a deterministic serialization function,
383// `serialize()`. For performance reasons, we would like to make it
384// non-deterministic. Therefore, we want to drop the expectation that
385// `a.serialize() = b.serialize() iff a = b` (although we'll maintain
386// `deserialize(a.serialize()) = a`).
387//
388// We have three cases to consider (for some equality function, `eq`):
389// ```
390// eq(a.serialize(), b.serialize()) --> eq(a,b)
391// eq(a, b.serialize()) --> eq(deserialize(a), b)
392// eq(a.serialize(), b) --> eq(a, deserialize(b))
393// ```
394//
395// `applyFirst` allows us to specify each independently:
396// ```
397// auto eq_fun = functionDecl(...);
398// auto method_call = cxxMemberCallExpr(...);
399//
400// auto two_calls = callExpr(callee(eq_fun), hasArgument(0, method_call),
401// hasArgument(1, method_call));
402// auto left_call =
403// callExpr(callee(eq_fun), callExpr(hasArgument(0, method_call)));
404// auto right_call =
405// callExpr(callee(eq_fun), callExpr(hasArgument(1, method_call)));
406//
407// RewriteRule R = applyFirst({makeRule(two_calls, two_calls_action),
408// makeRule(left_call, left_call_action),
409// makeRule(right_call, right_call_action)});
410// ```
411/// @{
412template <typename MetadataT>
413RewriteRuleWith<MetadataT>
414applyFirst(ArrayRef<RewriteRuleWith<MetadataT>> Rules) {
415 RewriteRuleWith<MetadataT> R;
416 for (auto &Rule : Rules) {
417 assert(Rule.Cases.size() == Rule.Metadata.size() &&(static_cast <bool> (Rule.Cases.size() == Rule.Metadata
.size() && "mis-match in case and metadata array size"
) ? void (0) : __assert_fail ("Rule.Cases.size() == Rule.Metadata.size() && \"mis-match in case and metadata array size\""
, "clang/include/clang/Tooling/Transformer/RewriteRule.h", 418
, __extension__ __PRETTY_FUNCTION__))
418 "mis-match in case and metadata array size")(static_cast <bool> (Rule.Cases.size() == Rule.Metadata
.size() && "mis-match in case and metadata array size"
) ? void (0) : __assert_fail ("Rule.Cases.size() == Rule.Metadata.size() && \"mis-match in case and metadata array size\""
, "clang/include/clang/Tooling/Transformer/RewriteRule.h", 418
, __extension__ __PRETTY_FUNCTION__))
;
419 R.Cases.append(Rule.Cases.begin(), Rule.Cases.end());
420 R.Metadata.append(Rule.Metadata.begin(), Rule.Metadata.end());
421 }
422 return R;
423}
424
425template <>
426RewriteRuleWith<void> applyFirst(ArrayRef<RewriteRuleWith<void>> Rules);
427
428template <typename MetadataT>
429RewriteRuleWith<MetadataT>
430applyFirst(const std::vector<RewriteRuleWith<MetadataT>> &Rules) {
431 return applyFirst(llvm::ArrayRef(Rules));
432}
433
434template <typename MetadataT>
435RewriteRuleWith<MetadataT>
436applyFirst(std::initializer_list<RewriteRuleWith<MetadataT>> Rules) {
437 return applyFirst(llvm::ArrayRef(Rules.begin(), Rules.end()));
438}
439/// @}
440
441/// Converts a \c RewriteRuleWith<T> to a \c RewriteRule by stripping off the
442/// metadata generators.
443template <int &..., typename MetadataT>
444std::enable_if_t<!std::is_same<MetadataT, void>::value, RewriteRule>
445stripMetadata(RewriteRuleWith<MetadataT> Rule) {
446 RewriteRule R;
447 R.Cases = std::move(Rule.Cases);
448 return R;
449}
450
451/// Applies `Rule` to all descendants of the node bound to `NodeId`. `Rule` can
452/// refer to nodes bound by the calling rule. `Rule` is not applied to the node
453/// itself.
454///
455/// For example,
456/// ```
457/// auto InlineX =
458/// makeRule(declRefExpr(to(varDecl(hasName("x")))), changeTo(cat("3")));
459/// makeRule(functionDecl(hasName("f"), hasBody(stmt().bind("body"))).bind("f"),
460/// flatten(
461/// changeTo(name("f"), cat("newName")),
462/// rewriteDescendants("body", InlineX)));
463/// ```
464/// Here, we find the function `f`, change its name to `newName` and change all
465/// appearances of `x` in its body to `3`.
466EditGenerator rewriteDescendants(std::string NodeId, RewriteRule Rule);
467
468/// The following three functions are a low-level part of the RewriteRule
469/// API. We expose them for use in implementing the fixtures that interpret
470/// RewriteRule, like Transformer and TransfomerTidy, or for more advanced
471/// users.
472//
473// FIXME: These functions are really public, if advanced, elements of the
474// RewriteRule API. Recast them as such. Or, just declare these functions
475// public and well-supported and move them out of `detail`.
476namespace detail {
477/// The following overload set is a version of `rewriteDescendants` that
478/// operates directly on the AST, rather than generating a Transformer
479/// combinator. It applies `Rule` to all descendants of `Node`, although not
480/// `Node` itself. `Rule` can refer to nodes bound in `Result`.
481///
482/// For example, assuming that "body" is bound to a function body in MatchResult
483/// `Results`, this will produce edits to change all appearances of `x` in that
484/// body to `3`.
485/// ```
486/// auto InlineX =
487/// makeRule(declRefExpr(to(varDecl(hasName("x")))), changeTo(cat("3")));
488/// const auto *Node = Results.Nodes.getNodeAs<Stmt>("body");
489/// auto Edits = rewriteDescendants(*Node, InlineX, Results);
490/// ```
491/// @{
492llvm::Expected<SmallVector<Edit, 1>>
493rewriteDescendants(const Decl &Node, RewriteRule Rule,
494 const ast_matchers::MatchFinder::MatchResult &Result);
495
496llvm::Expected<SmallVector<Edit, 1>>
497rewriteDescendants(const Stmt &Node, RewriteRule Rule,
498 const ast_matchers::MatchFinder::MatchResult &Result);
499
500llvm::Expected<SmallVector<Edit, 1>>
501rewriteDescendants(const TypeLoc &Node, RewriteRule Rule,
502 const ast_matchers::MatchFinder::MatchResult &Result);
503
504llvm::Expected<SmallVector<Edit, 1>>
505rewriteDescendants(const DynTypedNode &Node, RewriteRule Rule,
506 const ast_matchers::MatchFinder::MatchResult &Result);
507/// @}
508
509/// Builds a single matcher for the rule, covering all of the rule's cases.
510/// Only supports Rules whose cases' matchers share the same base "kind"
511/// (`Stmt`, `Decl`, etc.) Deprecated: use `buildMatchers` instead, which
512/// supports mixing matchers of different kinds.
513ast_matchers::internal::DynTypedMatcher
514buildMatcher(const RewriteRuleBase &Rule);
515
516/// Builds a set of matchers that cover the rule.
517///
518/// One matcher is built for each distinct node matcher base kind: Stmt, Decl,
519/// etc. Node-matchers for `QualType` and `Type` are not permitted, since such
520/// nodes carry no source location information and are therefore not relevant
521/// for rewriting. If any such matchers are included, will return an empty
522/// vector.
523std::vector<ast_matchers::internal::DynTypedMatcher>
524buildMatchers(const RewriteRuleBase &Rule);
525
526/// Gets the beginning location of the source matched by a rewrite rule. If the
527/// match occurs within a macro expansion, returns the beginning of the
528/// expansion point. `Result` must come from the matching of a rewrite rule.
529SourceLocation
530getRuleMatchLoc(const ast_matchers::MatchFinder::MatchResult &Result);
531
532/// Returns the index of the \c Case of \c Rule that was selected in the match
533/// result. Assumes a matcher built with \c buildMatcher.
534size_t findSelectedCase(const ast_matchers::MatchFinder::MatchResult &Result,
535 const RewriteRuleBase &Rule);
536} // namespace detail
537} // namespace transformer
538} // namespace clang
539
540#endif // LLVM_CLANG_TOOLING_TRANSFORMER_REWRITERULE_H

/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr.h

1// shared_ptr and weak_ptr implementation -*- C++ -*-
2
3// Copyright (C) 2007-2020 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// GCC Note: Based on files from version 1.32.0 of the Boost library.
26
27// shared_count.hpp
28// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
29
30// shared_ptr.hpp
31// Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
32// Copyright (C) 2001, 2002, 2003 Peter Dimov
33
34// weak_ptr.hpp
35// Copyright (C) 2001, 2002, 2003 Peter Dimov
36
37// enable_shared_from_this.hpp
38// Copyright (C) 2002 Peter Dimov
39
40// Distributed under the Boost Software License, Version 1.0. (See
41// accompanying file LICENSE_1_0.txt or copy at
42// http://www.boost.org/LICENSE_1_0.txt)
43
44/** @file
45 * This is an internal header file, included by other library headers.
46 * Do not attempt to use it directly. @headername{memory}
47 */
48
49#ifndef _SHARED_PTR_H1
50#define _SHARED_PTR_H1 1
51
52#include <bits/shared_ptr_base.h>
53
54namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
55{
56_GLIBCXX_BEGIN_NAMESPACE_VERSION
57
58 /**
59 * @addtogroup pointer_abstractions
60 * @{
61 */
62
63 // 20.7.2.2.11 shared_ptr I/O
64
65 /// Write the stored pointer to an ostream.
66 /// @relates shared_ptr
67 template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
68 inline std::basic_ostream<_Ch, _Tr>&
69 operator<<(std::basic_ostream<_Ch, _Tr>& __os,
70 const __shared_ptr<_Tp, _Lp>& __p)
71 {
72 __os << __p.get();
73 return __os;
74 }
75
76 template<typename _Del, typename _Tp, _Lock_policy _Lp>
77 inline _Del*
78 get_deleter(const __shared_ptr<_Tp, _Lp>& __p) noexcept
79 {
80#if __cpp_rtti199711L
81 return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));
82#else
83 return 0;
84#endif
85 }
86
87 /// 20.7.2.2.10 shared_ptr get_deleter
88
89 /// If `__p` has a deleter of type `_Del`, return a pointer to it.
90 /// @relates shared_ptr
91 template<typename _Del, typename _Tp>
92 inline _Del*
93 get_deleter(const shared_ptr<_Tp>& __p) noexcept
94 {
95#if __cpp_rtti199711L
96 return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));
97#else
98 return 0;
99#endif
100 }
101
102 /**
103 * @brief A smart pointer with reference-counted copy semantics.
104 *
105 * A `shared_ptr` object is either empty or _owns_ a pointer passed
106 * to the constructor. Copies of a `shared_ptr` share ownership of
107 * the same pointer. When the last `shared_ptr` that owns the pointer
108 * is destroyed or reset, the owned pointer is freed (either by `delete`
109 * or by invoking a custom deleter that was passed to the constructor).
110 *
111 * A `shared_ptr` also stores another pointer, which is usually
112 * (but not always) the same pointer as it owns. The stored pointer
113 * can be retrieved by calling the `get()` member function.
114 *
115 * The equality and relational operators for `shared_ptr` only compare
116 * the stored pointer returned by `get()`, not the owned pointer.
117 * To test whether two `shared_ptr` objects share ownership of the same
118 * pointer see `std::shared_ptr::owner_before` and `std::owner_less`.
119 */
120 template<typename _Tp>
121 class shared_ptr : public __shared_ptr<_Tp>
122 {
123 template<typename... _Args>
124 using _Constructible = typename enable_if<
125 is_constructible<__shared_ptr<_Tp>, _Args...>::value
126 >::type;
127
128 template<typename _Arg>
129 using _Assignable = typename enable_if<
130 is_assignable<__shared_ptr<_Tp>&, _Arg>::value, shared_ptr&
131 >::type;
132
133 public:
134
135 /// The type pointed to by the stored pointer, remove_extent_t<_Tp>
136 using element_type = typename __shared_ptr<_Tp>::element_type;
137
138#if __cplusplus201703L >= 201703L
139# define __cpp_lib_shared_ptr_weak_type201606 201606
140 /// The corresponding weak_ptr type for this shared_ptr
141 using weak_type = weak_ptr<_Tp>;
142#endif
143 /**
144 * @brief Construct an empty %shared_ptr.
145 * @post use_count()==0 && get()==0
146 */
147 constexpr shared_ptr() noexcept : __shared_ptr<_Tp>() { }
148
149 shared_ptr(const shared_ptr&) noexcept = default; ///< Copy constructor
150
151 /**
152 * @brief Construct a %shared_ptr that owns the pointer @a __p.
153 * @param __p A pointer that is convertible to element_type*.
154 * @post use_count() == 1 && get() == __p
155 * @throw std::bad_alloc, in which case @c delete @a __p is called.
156 */
157 template<typename _Yp, typename = _Constructible<_Yp*>>
158 explicit
159 shared_ptr(_Yp* __p) : __shared_ptr<_Tp>(__p) { }
160
161 /**
162 * @brief Construct a %shared_ptr that owns the pointer @a __p
163 * and the deleter @a __d.
164 * @param __p A pointer.
165 * @param __d A deleter.
166 * @post use_count() == 1 && get() == __p
167 * @throw std::bad_alloc, in which case @a __d(__p) is called.
168 *
169 * Requirements: _Deleter's copy constructor and destructor must
170 * not throw
171 *
172 * __shared_ptr will release __p by calling __d(__p)
173 */
174 template<typename _Yp, typename _Deleter,
175 typename = _Constructible<_Yp*, _Deleter>>
176 shared_ptr(_Yp* __p, _Deleter __d)
177 : __shared_ptr<_Tp>(__p, std::move(__d)) { }
178
179 /**
180 * @brief Construct a %shared_ptr that owns a null pointer
181 * and the deleter @a __d.
182 * @param __p A null pointer constant.
183 * @param __d A deleter.
184 * @post use_count() == 1 && get() == __p
185 * @throw std::bad_alloc, in which case @a __d(__p) is called.
186 *
187 * Requirements: _Deleter's copy constructor and destructor must
188 * not throw
189 *
190 * The last owner will call __d(__p)
191 */
192 template<typename _Deleter>
193 shared_ptr(nullptr_t __p, _Deleter __d)
194 : __shared_ptr<_Tp>(__p, std::move(__d)) { }
195
196 /**
197 * @brief Construct a %shared_ptr that owns the pointer @a __p
198 * and the deleter @a __d.
199 * @param __p A pointer.
200 * @param __d A deleter.
201 * @param __a An allocator.
202 * @post use_count() == 1 && get() == __p
203 * @throw std::bad_alloc, in which case @a __d(__p) is called.
204 *
205 * Requirements: _Deleter's copy constructor and destructor must
206 * not throw _Alloc's copy constructor and destructor must not
207 * throw.
208 *
209 * __shared_ptr will release __p by calling __d(__p)
210 */
211 template<typename _Yp, typename _Deleter, typename _Alloc,
212 typename = _Constructible<_Yp*, _Deleter, _Alloc>>
213 shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a)
214 : __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { }
215
216 /**
217 * @brief Construct a %shared_ptr that owns a null pointer
218 * and the deleter @a __d.
219 * @param __p A null pointer constant.
220 * @param __d A deleter.
221 * @param __a An allocator.
222 * @post use_count() == 1 && get() == __p
223 * @throw std::bad_alloc, in which case @a __d(__p) is called.
224 *
225 * Requirements: _Deleter's copy constructor and destructor must
226 * not throw _Alloc's copy constructor and destructor must not
227 * throw.
228 *
229 * The last owner will call __d(__p)
230 */
231 template<typename _Deleter, typename _Alloc>
232 shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
233 : __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { }
234
235 // Aliasing constructor
236
237 /**
238 * @brief Constructs a `shared_ptr` instance that stores `__p`
239 * and shares ownership with `__r`.
240 * @param __r A `shared_ptr`.
241 * @param __p A pointer that will remain valid while `*__r` is valid.
242 * @post `get() == __p && use_count() == __r.use_count()`
243 *
244 * This can be used to construct a `shared_ptr` to a sub-object
245 * of an object managed by an existing `shared_ptr`. The complete
246 * object will remain valid while any `shared_ptr` owns it, even
247 * if they don't store a pointer to the complete object.
248 *
249 * @code
250 * shared_ptr<pair<int,int>> pii(new pair<int,int>());
251 * shared_ptr<int> pi(pii, &pii->first);
252 * assert(pii.use_count() == 2);
253 * @endcode
254 */
255 template<typename _Yp>
256 shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) noexcept
257 : __shared_ptr<_Tp>(__r, __p) { }
258
259#if __cplusplus201703L > 201703L
260 // _GLIBCXX_RESOLVE_LIB_DEFECTS
261 // 2996. Missing rvalue overloads for shared_ptr operations
262 /**
263 * @brief Constructs a `shared_ptr` instance that stores `__p`
264 * and shares ownership with `__r`.
265 * @param __r A `shared_ptr`.
266 * @param __p A pointer that will remain valid while `*__r` is valid.
267 * @post `get() == __p && !__r.use_count() && !__r.get()`
268 *
269 * This can be used to construct a `shared_ptr` to a sub-object
270 * of an object managed by an existing `shared_ptr`. The complete
271 * object will remain valid while any `shared_ptr` owns it, even
272 * if they don't store a pointer to the complete object.
273 *
274 * @code
275 * shared_ptr<pair<int,int>> pii(new pair<int,int>());
276 * shared_ptr<int> pi1(pii, &pii->first);
277 * assert(pii.use_count() == 2);
278 * shared_ptr<int> pi2(std::move(pii), &pii->second);
279 * assert(pii.use_count() == 0);
280 * @endcode
281 */
282 template<typename _Yp>
283 shared_ptr(shared_ptr<_Yp>&& __r, element_type* __p) noexcept
284 : __shared_ptr<_Tp>(std::move(__r), __p) { }
285#endif
286 /**
287 * @brief If @a __r is empty, constructs an empty %shared_ptr;
288 * otherwise construct a %shared_ptr that shares ownership
289 * with @a __r.
290 * @param __r A %shared_ptr.
291 * @post get() == __r.get() && use_count() == __r.use_count()
292 */
293 template<typename _Yp,
294 typename = _Constructible<const shared_ptr<_Yp>&>>
295 shared_ptr(const shared_ptr<_Yp>& __r) noexcept
296 : __shared_ptr<_Tp>(__r) { }
297
298 /**
299 * @brief Move-constructs a %shared_ptr instance from @a __r.
300 * @param __r A %shared_ptr rvalue.
301 * @post *this contains the old value of @a __r, @a __r is empty.
302 */
303 shared_ptr(shared_ptr&& __r) noexcept
304 : __shared_ptr<_Tp>(std::move(__r)) { }
305
306 /**
307 * @brief Move-constructs a %shared_ptr instance from @a __r.
308 * @param __r A %shared_ptr rvalue.
309 * @post *this contains the old value of @a __r, @a __r is empty.
310 */
311 template<typename _Yp, typename = _Constructible<shared_ptr<_Yp>>>
312 shared_ptr(shared_ptr<_Yp>&& __r) noexcept
313 : __shared_ptr<_Tp>(std::move(__r)) { }
314
315 /**
316 * @brief Constructs a %shared_ptr that shares ownership with @a __r
317 * and stores a copy of the pointer stored in @a __r.
318 * @param __r A weak_ptr.
319 * @post use_count() == __r.use_count()
320 * @throw bad_weak_ptr when __r.expired(),
321 * in which case the constructor has no effect.
322 */
323 template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>>
324 explicit shared_ptr(const weak_ptr<_Yp>& __r)
325 : __shared_ptr<_Tp>(__r) { }
326
327#if _GLIBCXX_USE_DEPRECATED1
328#pragma GCC diagnostic push
329#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
330 template<typename _Yp, typename = _Constructible<auto_ptr<_Yp>>>
331 shared_ptr(auto_ptr<_Yp>&& __r);
332#pragma GCC diagnostic pop
333#endif
334
335 // _GLIBCXX_RESOLVE_LIB_DEFECTS
336 // 2399. shared_ptr's constructor from unique_ptr should be constrained
337 template<typename _Yp, typename _Del,
338 typename = _Constructible<unique_ptr<_Yp, _Del>>>
339 shared_ptr(unique_ptr<_Yp, _Del>&& __r)
340 : __shared_ptr<_Tp>(std::move(__r)) { }
341
342#if __cplusplus201703L <= 201402L && _GLIBCXX_USE_DEPRECATED1
343 // This non-standard constructor exists to support conversions that
344 // were possible in C++11 and C++14 but are ill-formed in C++17.
345 // If an exception is thrown this constructor has no effect.
346 template<typename _Yp, typename _Del,
347 _Constructible<unique_ptr<_Yp, _Del>, __sp_array_delete>* = 0>
348 shared_ptr(unique_ptr<_Yp, _Del>&& __r)
349 : __shared_ptr<_Tp>(std::move(__r), __sp_array_delete()) { }
350#endif
351
352 /**
353 * @brief Construct an empty %shared_ptr.
354 * @post use_count() == 0 && get() == nullptr
355 */
356 constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }
357
358 shared_ptr& operator=(const shared_ptr&) noexcept = default;
359
360 template<typename _Yp>
361 _Assignable<const shared_ptr<_Yp>&>
362 operator=(const shared_ptr<_Yp>& __r) noexcept
363 {
364 this->__shared_ptr<_Tp>::operator=(__r);
365 return *this;
366 }
367
368#if _GLIBCXX_USE_DEPRECATED1
369#pragma GCC diagnostic push
370#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
371 template<typename _Yp>
372 _Assignable<auto_ptr<_Yp>>
373 operator=(auto_ptr<_Yp>&& __r)
374 {
375 this->__shared_ptr<_Tp>::operator=(std::move(__r));
376 return *this;
377 }
378#pragma GCC diagnostic pop
379#endif
380
381 shared_ptr&
382 operator=(shared_ptr&& __r) noexcept
383 {
384 this->__shared_ptr<_Tp>::operator=(std::move(__r));
385 return *this;
386 }
387
388 template<class _Yp>
389 _Assignable<shared_ptr<_Yp>>
390 operator=(shared_ptr<_Yp>&& __r) noexcept
391 {
392 this->__shared_ptr<_Tp>::operator=(std::move(__r));
393 return *this;
394 }
395
396 template<typename _Yp, typename _Del>
397 _Assignable<unique_ptr<_Yp, _Del>>
398 operator=(unique_ptr<_Yp, _Del>&& __r)
399 {
400 this->__shared_ptr<_Tp>::operator=(std::move(__r));
401 return *this;
402 }
403
404 private:
405 // This constructor is non-standard, it is used by allocate_shared.
406 template<typename _Alloc, typename... _Args>
407 shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args)
408 : __shared_ptr<_Tp>(__tag, std::forward<_Args>(__args)...)
8
Calling constructor for '__shared_ptr<(anonymous namespace)::SimpleTextGenerator, __gnu_cxx::_S_atomic>'
20
Returning from constructor for '__shared_ptr<(anonymous namespace)::SimpleTextGenerator, __gnu_cxx::_S_atomic>'
409 { }
410
411 template<typename _Yp, typename _Alloc, typename... _Args>
412 friend shared_ptr<_Yp>
413 allocate_shared(const _Alloc& __a, _Args&&... __args);
414
415 // This constructor is non-standard, it is used by weak_ptr::lock().
416 shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t)
417 : __shared_ptr<_Tp>(__r, std::nothrow) { }
418
419 friend class weak_ptr<_Tp>;
420 };
421
422#if __cpp_deduction_guides201703L >= 201606
423 template<typename _Tp>
424 shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>;
425 template<typename _Tp, typename _Del>
426 shared_ptr(unique_ptr<_Tp, _Del>) -> shared_ptr<_Tp>;
427#endif
428
429 // 20.7.2.2.7 shared_ptr comparisons
430
431 /// @relates shared_ptr @{
432
433 /// Equality operator for shared_ptr objects, compares the stored pointers
434 template<typename _Tp, typename _Up>
435 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
436 operator==(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
437 { return __a.get() == __b.get(); }
438
439 /// shared_ptr comparison with nullptr
440 template<typename _Tp>
441 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
442 operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
443 { return !__a; }
444
445#ifdef __cpp_lib_three_way_comparison
446 template<typename _Tp, typename _Up>
447 inline strong_ordering
448 operator<=>(const shared_ptr<_Tp>& __a,
449 const shared_ptr<_Up>& __b) noexcept
450 { return compare_three_way()(__a.get(), __b.get()); }
451
452 template<typename _Tp>
453 inline strong_ordering
454 operator<=>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
455 {
456 using pointer = typename shared_ptr<_Tp>::element_type*;
457 return compare_three_way()(__a.get(), static_cast<pointer>(nullptr));
458 }
459#else
460 /// shared_ptr comparison with nullptr
461 template<typename _Tp>
462 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
463 operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
464 { return !__a; }
465
466 /// Inequality operator for shared_ptr objects, compares the stored pointers
467 template<typename _Tp, typename _Up>
468 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
469 operator!=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
470 { return __a.get() != __b.get(); }
471
472 /// shared_ptr comparison with nullptr
473 template<typename _Tp>
474 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
475 operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
476 { return (bool)__a; }
477
478 /// shared_ptr comparison with nullptr
479 template<typename _Tp>
480 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
481 operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
482 { return (bool)__a; }
483
484 /// Relational operator for shared_ptr objects, compares the stored pointers
485 template<typename _Tp, typename _Up>
486 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
487 operator<(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
488 {
489 using _Tp_elt = typename shared_ptr<_Tp>::element_type;
490 using _Up_elt = typename shared_ptr<_Up>::element_type;
491 using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type;
492 return less<_Vp>()(__a.get(), __b.get());
493 }
494
495 /// shared_ptr comparison with nullptr
496 template<typename _Tp>
497 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
498 operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
499 {
500 using _Tp_elt = typename shared_ptr<_Tp>::element_type;
501 return less<_Tp_elt*>()(__a.get(), nullptr);
502 }
503
504 /// shared_ptr comparison with nullptr
505 template<typename _Tp>
506 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
507 operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
508 {
509 using _Tp_elt = typename shared_ptr<_Tp>::element_type;
510 return less<_Tp_elt*>()(nullptr, __a.get());
511 }
512
513 /// Relational operator for shared_ptr objects, compares the stored pointers
514 template<typename _Tp, typename _Up>
515 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
516 operator<=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
517 { return !(__b < __a); }
518
519 /// shared_ptr comparison with nullptr
520 template<typename _Tp>
521 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
522 operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
523 { return !(nullptr < __a); }
524
525 /// shared_ptr comparison with nullptr
526 template<typename _Tp>
527 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
528 operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
529 { return !(__a < nullptr); }
530
531 /// Relational operator for shared_ptr objects, compares the stored pointers
532 template<typename _Tp, typename _Up>
533 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
534 operator>(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
535 { return (__b < __a); }
536
537 /// shared_ptr comparison with nullptr
538 template<typename _Tp>
539 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
540 operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
541 { return nullptr < __a; }
542
543 /// shared_ptr comparison with nullptr
544 template<typename _Tp>
545 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
546 operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
547 { return __a < nullptr; }
548
549 /// Relational operator for shared_ptr objects, compares the stored pointers
550 template<typename _Tp, typename _Up>
551 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
552 operator>=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
553 { return !(__a < __b); }
554
555 /// shared_ptr comparison with nullptr
556 template<typename _Tp>
557 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
558 operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
559 { return !(__a < nullptr); }
560
561 /// shared_ptr comparison with nullptr
562 template<typename _Tp>
563 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
564 operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
565 { return !(nullptr < __a); }
566#endif
567
568 // 20.7.2.2.8 shared_ptr specialized algorithms.
569
570 /// Swap overload for shared_ptr
571 template<typename _Tp>
572 inline void
573 swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept
574 { __a.swap(__b); }
575
576 // 20.7.2.2.9 shared_ptr casts.
577
578 /// Convert type of `shared_ptr`, via `static_cast`
579 template<typename _Tp, typename _Up>
580 inline shared_ptr<_Tp>
581 static_pointer_cast(const shared_ptr<_Up>& __r) noexcept
582 {
583 using _Sp = shared_ptr<_Tp>;
584 return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get()));
585 }
586
587 /// Convert type of `shared_ptr`, via `const_cast`
588 template<typename _Tp, typename _Up>
589 inline shared_ptr<_Tp>
590 const_pointer_cast(const shared_ptr<_Up>& __r) noexcept
591 {
592 using _Sp = shared_ptr<_Tp>;
593 return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get()));
594 }
595
596 /// Convert type of `shared_ptr`, via `dynamic_cast`
597 template<typename _Tp, typename _Up>
598 inline shared_ptr<_Tp>
599 dynamic_pointer_cast(const shared_ptr<_Up>& __r) noexcept
600 {
601 using _Sp = shared_ptr<_Tp>;
602 if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))
603 return _Sp(__r, __p);
604 return _Sp();
605 }
606
607#if __cplusplus201703L >= 201703L
608 /// Convert type of `shared_ptr`, via `reinterpret_cast`
609 template<typename _Tp, typename _Up>
610 inline shared_ptr<_Tp>
611 reinterpret_pointer_cast(const shared_ptr<_Up>& __r) noexcept
612 {
613 using _Sp = shared_ptr<_Tp>;
614 return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get()));
615 }
616
617#if __cplusplus201703L > 201703L
618 // _GLIBCXX_RESOLVE_LIB_DEFECTS
619 // 2996. Missing rvalue overloads for shared_ptr operations
620
621 /// Convert type of `shared_ptr` rvalue, via `static_cast`
622 template<typename _Tp, typename _Up>
623 inline shared_ptr<_Tp>
624 static_pointer_cast(shared_ptr<_Up>&& __r) noexcept
625 {
626 using _Sp = shared_ptr<_Tp>;
627 return _Sp(std::move(__r),
628 static_cast<typename _Sp::element_type*>(__r.get()));
629 }
630
631 /// Convert type of `shared_ptr` rvalue, via `const_cast`
632 template<typename _Tp, typename _Up>
633 inline shared_ptr<_Tp>
634 const_pointer_cast(shared_ptr<_Up>&& __r) noexcept
635 {
636 using _Sp = shared_ptr<_Tp>;
637 return _Sp(std::move(__r),
638 const_cast<typename _Sp::element_type*>(__r.get()));
639 }
640
641 /// Convert type of `shared_ptr` rvalue, via `dynamic_cast`
642 template<typename _Tp, typename _Up>
643 inline shared_ptr<_Tp>
644 dynamic_pointer_cast(shared_ptr<_Up>&& __r) noexcept
645 {
646 using _Sp = shared_ptr<_Tp>;
647 if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))
648 return _Sp(std::move(__r), __p);
649 return _Sp();
650 }
651
652 /// Convert type of `shared_ptr` rvalue, via `reinterpret_cast`
653 template<typename _Tp, typename _Up>
654 inline shared_ptr<_Tp>
655 reinterpret_pointer_cast(shared_ptr<_Up>&& __r) noexcept
656 {
657 using _Sp = shared_ptr<_Tp>;
658 return _Sp(std::move(__r),
659 reinterpret_cast<typename _Sp::element_type*>(__r.get()));
660 }
661#endif // C++20
662#endif // C++17
663
664 // @}
665
666 /**
667 * @brief A non-owning observer for a pointer owned by a shared_ptr
668 *
669 * A weak_ptr provides a safe alternative to a raw pointer when you want
670 * a non-owning reference to an object that is managed by a shared_ptr.
671 *
672 * Unlike a raw pointer, a weak_ptr can be converted to a new shared_ptr
673 * that shares ownership with every other shared_ptr that already owns
674 * the pointer. In other words you can upgrade from a non-owning "weak"
675 * reference to an owning shared_ptr, without having access to any of
676 * the existing shared_ptr objects.
677 *
678 * Also unlike a raw pointer, a weak_ptr does not become "dangling" after
679 * the object it points to has been destroyed. Instead, a weak_ptr
680 * becomes _expired_ and can no longer be converted to a shared_ptr that
681 * owns the freed pointer, so you cannot accidentally access the pointed-to
682 * object after it has been destroyed.
683 */
684 template<typename _Tp>
685 class weak_ptr : public __weak_ptr<_Tp>
686 {
687 template<typename _Arg>
688 using _Constructible = typename enable_if<
689 is_constructible<__weak_ptr<_Tp>, _Arg>::value
690 >::type;
691
692 template<typename _Arg>
693 using _Assignable = typename enable_if<
694 is_assignable<__weak_ptr<_Tp>&, _Arg>::value, weak_ptr&
695 >::type;
696
697 public:
698 constexpr weak_ptr() noexcept = default;
699
700 template<typename _Yp,
701 typename = _Constructible<const shared_ptr<_Yp>&>>
702 weak_ptr(const shared_ptr<_Yp>& __r) noexcept
703 : __weak_ptr<_Tp>(__r) { }
704
705 weak_ptr(const weak_ptr&) noexcept = default;
706
707 template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>>
708 weak_ptr(const weak_ptr<_Yp>& __r) noexcept
709 : __weak_ptr<_Tp>(__r) { }
710
711 weak_ptr(weak_ptr&&) noexcept = default;
712
713 template<typename _Yp, typename = _Constructible<weak_ptr<_Yp>>>
714 weak_ptr(weak_ptr<_Yp>&& __r) noexcept
715 : __weak_ptr<_Tp>(std::move(__r)) { }
716
717 weak_ptr&
718 operator=(const weak_ptr& __r) noexcept = default;
719
720 template<typename _Yp>
721 _Assignable<const weak_ptr<_Yp>&>
722 operator=(const weak_ptr<_Yp>& __r) noexcept
723 {
724 this->__weak_ptr<_Tp>::operator=(__r);
725 return *this;
726 }
727
728 template<typename _Yp>
729 _Assignable<const shared_ptr<_Yp>&>
730 operator=(const shared_ptr<_Yp>& __r) noexcept
731 {
732 this->__weak_ptr<_Tp>::operator=(__r);
733 return *this;
734 }
735
736 weak_ptr&
737 operator=(weak_ptr&& __r) noexcept = default;
738
739 template<typename _Yp>
740 _Assignable<weak_ptr<_Yp>>
741 operator=(weak_ptr<_Yp>&& __r) noexcept
742 {
743 this->__weak_ptr<_Tp>::operator=(std::move(__r));
744 return *this;
745 }
746
747 shared_ptr<_Tp>
748 lock() const noexcept
749 { return shared_ptr<_Tp>(*this, std::nothrow); }
750 };
751
752#if __cpp_deduction_guides201703L >= 201606
753 template<typename _Tp>
754 weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>;
755#endif
756
757 // 20.7.2.3.6 weak_ptr specialized algorithms.
758 /// Swap overload for weak_ptr
759 /// @relates weak_ptr
760 template<typename _Tp>
761 inline void
762 swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept
763 { __a.swap(__b); }
764
765
766 /// Primary template owner_less
767 template<typename _Tp = void>
768 struct owner_less;
769
770 /// Void specialization of owner_less compares either shared_ptr or weak_ptr
771 template<>
772 struct owner_less<void> : _Sp_owner_less<void, void>
773 { };
774
775 /// Partial specialization of owner_less for shared_ptr.
776 template<typename _Tp>
777 struct owner_less<shared_ptr<_Tp>>
778 : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
779 { };
780
781 /// Partial specialization of owner_less for weak_ptr.
782 template<typename _Tp>
783 struct owner_less<weak_ptr<_Tp>>
784 : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
785 { };
786
787 /**
788 * @brief Base class allowing use of member function shared_from_this.
789 */
790 template<typename _Tp>
791 class enable_shared_from_this
792 {
793 protected:
794 constexpr enable_shared_from_this() noexcept { }
795
796 enable_shared_from_this(const enable_shared_from_this&) noexcept { }
797
798 enable_shared_from_this&
799 operator=(const enable_shared_from_this&) noexcept
800 { return *this; }
801
802 ~enable_shared_from_this() { }
803
804 public:
805 shared_ptr<_Tp>
806 shared_from_this()
807 { return shared_ptr<_Tp>(this->_M_weak_this); }
808
809 shared_ptr<const _Tp>
810 shared_from_this() const
811 { return shared_ptr<const _Tp>(this->_M_weak_this); }
812
813#if __cplusplus201703L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11
814#define __cpp_lib_enable_shared_from_this201603 201603
815 weak_ptr<_Tp>
816 weak_from_this() noexcept
817 { return this->_M_weak_this; }
818
819 weak_ptr<const _Tp>
820 weak_from_this() const noexcept
821 { return this->_M_weak_this; }
822#endif
823
824 private:
825 template<typename _Tp1>
826 void
827 _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept
828 { _M_weak_this._M_assign(__p, __n); }
829
830 // Found by ADL when this is an associated class.
831 friend const enable_shared_from_this*
832 __enable_shared_from_this_base(const __shared_count<>&,
833 const enable_shared_from_this* __p)
834 { return __p; }
835
836 template<typename, _Lock_policy>
837 friend class __shared_ptr;
838
839 mutable weak_ptr<_Tp> _M_weak_this;
840 };
841
842 /// @relates shared_ptr @{
843
844 /**
845 * @brief Create an object that is owned by a shared_ptr.
846 * @param __a An allocator.
847 * @param __args Arguments for the @a _Tp object's constructor.
848 * @return A shared_ptr that owns the newly created object.
849 * @throw An exception thrown from @a _Alloc::allocate or from the
850 * constructor of @a _Tp.
851 *
852 * A copy of @a __a will be used to allocate memory for the shared_ptr
853 * and the new object.
854 */
855 template<typename _Tp, typename _Alloc, typename... _Args>
856 inline shared_ptr<_Tp>
857 allocate_shared(const _Alloc& __a, _Args&&... __args)
858 {
859 return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a},
7
Calling constructor for 'shared_ptr<(anonymous namespace)::SimpleTextGenerator>'
21
Returning from constructor for 'shared_ptr<(anonymous namespace)::SimpleTextGenerator>'
860 std::forward<_Args>(__args)...);
861 }
862
863 /**
864 * @brief Create an object that is owned by a shared_ptr.
865 * @param __args Arguments for the @a _Tp object's constructor.
866 * @return A shared_ptr that owns the newly created object.
867 * @throw std::bad_alloc, or an exception thrown from the
868 * constructor of @a _Tp.
869 */
870 template<typename _Tp, typename... _Args>
871 inline shared_ptr<_Tp>
872 make_shared(_Args&&... __args)
873 {
874 typedef typename std::remove_cv<_Tp>::type _Tp_nc;
875 return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(),
6
Calling 'allocate_shared<(anonymous namespace)::SimpleTextGenerator, std::allocator<(anonymous namespace)::SimpleTextGenerator>, std::basic_string<char>>'
22
Returned allocated memory
876 std::forward<_Args>(__args)...);
877 }
878
879 /// std::hash specialization for shared_ptr.
880 template<typename _Tp>
881 struct hash<shared_ptr<_Tp>>
882 : public __hash_base<size_t, shared_ptr<_Tp>>
883 {
884 size_t
885 operator()(const shared_ptr<_Tp>& __s) const noexcept
886 {
887 return std::hash<typename shared_ptr<_Tp>::element_type*>()(__s.get());
888 }
889 };
890
891 // @} relates shared_ptr
892 // @} group pointer_abstractions
893
894#if __cplusplus201703L >= 201703L
895 namespace __detail::__variant
896 {
897 template<typename> struct _Never_valueless_alt; // see <variant>
898
899 // Provide the strong exception-safety guarantee when emplacing a
900 // shared_ptr into a variant.
901 template<typename _Tp>
902 struct _Never_valueless_alt<std::shared_ptr<_Tp>>
903 : std::true_type
904 { };
905
906 // Provide the strong exception-safety guarantee when emplacing a
907 // weak_ptr into a variant.
908 template<typename _Tp>
909 struct _Never_valueless_alt<std::weak_ptr<_Tp>>
910 : std::true_type
911 { };
912 } // namespace __detail::__variant
913#endif // C++17
914
915_GLIBCXX_END_NAMESPACE_VERSION
916} // namespace
917
918#endif // _SHARED_PTR_H

/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr_base.h

1// shared_ptr and weak_ptr implementation details -*- C++ -*-
2
3// Copyright (C) 2007-2020 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// GCC Note: Based on files from version 1.32.0 of the Boost library.
26
27// shared_count.hpp
28// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
29
30// shared_ptr.hpp
31// Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
32// Copyright (C) 2001, 2002, 2003 Peter Dimov
33
34// weak_ptr.hpp
35// Copyright (C) 2001, 2002, 2003 Peter Dimov
36
37// enable_shared_from_this.hpp
38// Copyright (C) 2002 Peter Dimov
39
40// Distributed under the Boost Software License, Version 1.0. (See
41// accompanying file LICENSE_1_0.txt or copy at
42// http://www.boost.org/LICENSE_1_0.txt)
43
44/** @file bits/shared_ptr_base.h
45 * This is an internal header file, included by other library headers.
46 * Do not attempt to use it directly. @headername{memory}
47 */
48
49#ifndef _SHARED_PTR_BASE_H1
50#define _SHARED_PTR_BASE_H1 1
51
52#include <typeinfo>
53#include <bits/allocated_ptr.h>
54#include <bits/refwrap.h>
55#include <bits/stl_function.h>
56#include <ext/aligned_buffer.h>
57#if __cplusplus201703L > 201703L
58# include <compare>
59#endif
60
61namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
62{
63_GLIBCXX_BEGIN_NAMESPACE_VERSION
64
65#if _GLIBCXX_USE_DEPRECATED1
66#pragma GCC diagnostic push
67#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
68 template<typename> class auto_ptr;
69#pragma GCC diagnostic pop
70#endif
71
72 /**
73 * @brief Exception possibly thrown by @c shared_ptr.
74 * @ingroup exceptions
75 */
76 class bad_weak_ptr : public std::exception
77 {
78 public:
79 virtual char const* what() const noexcept;
80
81 virtual ~bad_weak_ptr() noexcept;
82 };
83
84 // Substitute for bad_weak_ptr object in the case of -fno-exceptions.
85 inline void
86 __throw_bad_weak_ptr()
87 { _GLIBCXX_THROW_OR_ABORT(bad_weak_ptr())(__builtin_abort()); }
88
89 using __gnu_cxx::_Lock_policy;
90 using __gnu_cxx::__default_lock_policy;
91 using __gnu_cxx::_S_single;
92 using __gnu_cxx::_S_mutex;
93 using __gnu_cxx::_S_atomic;
94
95 // Empty helper class except when the template argument is _S_mutex.
96 template<_Lock_policy _Lp>
97 class _Mutex_base
98 {
99 protected:
100 // The atomic policy uses fully-fenced builtins, single doesn't care.
101 enum { _S_need_barriers = 0 };
102 };
103
104 template<>
105 class _Mutex_base<_S_mutex>
106 : public __gnu_cxx::__mutex
107 {
108 protected:
109 // This policy is used when atomic builtins are not available.
110 // The replacement atomic operations might not have the necessary
111 // memory barriers.
112 enum { _S_need_barriers = 1 };
113 };
114
115 template<_Lock_policy _Lp = __default_lock_policy>
116 class _Sp_counted_base
117 : public _Mutex_base<_Lp>
118 {
119 public:
120 _Sp_counted_base() noexcept
121 : _M_use_count(1), _M_weak_count(1) { }
122
123 virtual
124 ~_Sp_counted_base() noexcept
125 { }
126
127 // Called when _M_use_count drops to zero, to release the resources
128 // managed by *this.
129 virtual void
130 _M_dispose() noexcept = 0;
131
132 // Called when _M_weak_count drops to zero.
133 virtual void
134 _M_destroy() noexcept
135 { delete this; }
136
137 virtual void*
138 _M_get_deleter(const std::type_info&) noexcept = 0;
139
140 void
141 _M_add_ref_copy()
142 { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); }
143
144 void
145 _M_add_ref_lock();
146
147 bool
148 _M_add_ref_lock_nothrow();
149
150 void
151 _M_release() noexcept
152 {
153 // Be race-detector-friendly. For more info see bits/c++config.
154 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count);
155 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1)
156 {
157 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count);
158 _M_dispose();
159 // There must be a memory barrier between dispose() and destroy()
160 // to ensure that the effects of dispose() are observed in the
161 // thread that runs destroy().
162 // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html
163 if (_Mutex_base<_Lp>::_S_need_barriers)
164 {
165 __atomic_thread_fence (__ATOMIC_ACQ_REL4);
166 }
167
168 // Be race-detector-friendly. For more info see bits/c++config.
169 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
170 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
171 -1) == 1)
172 {
173 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
174 _M_destroy();
175 }
176 }
177 }
178
179 void
180 _M_weak_add_ref() noexcept
181 { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
182
183 void
184 _M_weak_release() noexcept
185 {
186 // Be race-detector-friendly. For more info see bits/c++config.
187 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
188 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
189 {
190 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
191 if (_Mutex_base<_Lp>::_S_need_barriers)
192 {
193 // See _M_release(),
194 // destroy() must observe results of dispose()
195 __atomic_thread_fence (__ATOMIC_ACQ_REL4);
196 }
197 _M_destroy();
198 }
199 }
200
201 long
202 _M_get_use_count() const noexcept
203 {
204 // No memory barrier is used here so there is no synchronization
205 // with other threads.
206 return __atomic_load_n(&_M_use_count, __ATOMIC_RELAXED0);
207 }
208
209 private:
210 _Sp_counted_base(_Sp_counted_base const&) = delete;
211 _Sp_counted_base& operator=(_Sp_counted_base const&) = delete;
212
213 _Atomic_word _M_use_count; // #shared
214 _Atomic_word _M_weak_count; // #weak + (#shared != 0)
215 };
216
217 template<>
218 inline void
219 _Sp_counted_base<_S_single>::
220 _M_add_ref_lock()
221 {
222 if (_M_use_count == 0)
223 __throw_bad_weak_ptr();
224 ++_M_use_count;
225 }
226
227 template<>
228 inline void
229 _Sp_counted_base<_S_mutex>::
230 _M_add_ref_lock()
231 {
232 __gnu_cxx::__scoped_lock sentry(*this);
233 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
234 {
235 _M_use_count = 0;
236 __throw_bad_weak_ptr();
237 }
238 }
239
240 template<>
241 inline void
242 _Sp_counted_base<_S_atomic>::
243 _M_add_ref_lock()
244 {
245 // Perform lock-free add-if-not-zero operation.
246 _Atomic_word __count = _M_get_use_count();
247 do
248 {
249 if (__count == 0)
250 __throw_bad_weak_ptr();
251 // Replace the current counter value with the old value + 1, as
252 // long as it's not changed meanwhile.
253 }
254 while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1,
255 true, __ATOMIC_ACQ_REL4,
256 __ATOMIC_RELAXED0));
257 }
258
259 template<>
260 inline bool
261 _Sp_counted_base<_S_single>::
262 _M_add_ref_lock_nothrow()
263 {
264 if (_M_use_count == 0)
265 return false;
266 ++_M_use_count;
267 return true;
268 }
269
270 template<>
271 inline bool
272 _Sp_counted_base<_S_mutex>::
273 _M_add_ref_lock_nothrow()
274 {
275 __gnu_cxx::__scoped_lock sentry(*this);
276 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
277 {
278 _M_use_count = 0;
279 return false;
280 }
281 return true;
282 }
283
284 template<>
285 inline bool
286 _Sp_counted_base<_S_atomic>::
287 _M_add_ref_lock_nothrow()
288 {
289 // Perform lock-free add-if-not-zero operation.
290 _Atomic_word __count = _M_get_use_count();
291 do
292 {
293 if (__count == 0)
294 return false;
295 // Replace the current counter value with the old value + 1, as
296 // long as it's not changed meanwhile.
297 }
298 while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1,
299 true, __ATOMIC_ACQ_REL4,
300 __ATOMIC_RELAXED0));
301 return true;
302 }
303
304 template<>
305 inline void
306 _Sp_counted_base<_S_single>::_M_add_ref_copy()
307 { ++_M_use_count; }
308
309 template<>
310 inline void
311 _Sp_counted_base<_S_single>::_M_release() noexcept
312 {
313 if (--_M_use_count == 0)
314 {
315 _M_dispose();
316 if (--_M_weak_count == 0)
317 _M_destroy();
318 }
319 }
320
321 template<>
322 inline void
323 _Sp_counted_base<_S_single>::_M_weak_add_ref() noexcept
324 { ++_M_weak_count; }
325
326 template<>
327 inline void
328 _Sp_counted_base<_S_single>::_M_weak_release() noexcept
329 {
330 if (--_M_weak_count == 0)
331 _M_destroy();
332 }
333
334 template<>
335 inline long
336 _Sp_counted_base<_S_single>::_M_get_use_count() const noexcept
337 { return _M_use_count; }
338
339
340 // Forward declarations.
341 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
342 class __shared_ptr;
343
344 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
345 class __weak_ptr;
346
347 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
348 class __enable_shared_from_this;
349
350 template<typename _Tp>
351 class shared_ptr;
352
353 template<typename _Tp>
354 class weak_ptr;
355
356 template<typename _Tp>
357 struct owner_less;
358
359 template<typename _Tp>
360 class enable_shared_from_this;
361
362 template<_Lock_policy _Lp = __default_lock_policy>
363 class __weak_count;
364
365 template<_Lock_policy _Lp = __default_lock_policy>
366 class __shared_count;
367
368
369 // Counted ptr with no deleter or allocator support
370 template<typename _Ptr, _Lock_policy _Lp>
371 class _Sp_counted_ptr final : public _Sp_counted_base<_Lp>
372 {
373 public:
374 explicit
375 _Sp_counted_ptr(_Ptr __p) noexcept
376 : _M_ptr(__p) { }
377
378 virtual void
379 _M_dispose() noexcept
380 { delete _M_ptr; }
381
382 virtual void
383 _M_destroy() noexcept
384 { delete this; }
385
386 virtual void*
387 _M_get_deleter(const std::type_info&) noexcept
388 { return nullptr; }
389
390 _Sp_counted_ptr(const _Sp_counted_ptr&) = delete;
391 _Sp_counted_ptr& operator=(const _Sp_counted_ptr&) = delete;
392
393 private:
394 _Ptr _M_ptr;
395 };
396
397 template<>
398 inline void
399 _Sp_counted_ptr<nullptr_t, _S_single>::_M_dispose() noexcept { }
400
401 template<>
402 inline void
403 _Sp_counted_ptr<nullptr_t, _S_mutex>::_M_dispose() noexcept { }
404
405 template<>
406 inline void
407 _Sp_counted_ptr<nullptr_t, _S_atomic>::_M_dispose() noexcept { }
408
409 template<int _Nm, typename _Tp,
410 bool __use_ebo = !__is_final(_Tp) && __is_empty(_Tp)>
411 struct _Sp_ebo_helper;
412
413 /// Specialization using EBO.
414 template<int _Nm, typename _Tp>
415 struct _Sp_ebo_helper<_Nm, _Tp, true> : private _Tp
416 {
417 explicit _Sp_ebo_helper(const _Tp& __tp) : _Tp(__tp) { }
418 explicit _Sp_ebo_helper(_Tp&& __tp) : _Tp(std::move(__tp)) { }
419
420 static _Tp&
421 _S_get(_Sp_ebo_helper& __eboh) { return static_cast<_Tp&>(__eboh); }
422 };
423
424 /// Specialization not using EBO.
425 template<int _Nm, typename _Tp>
426 struct _Sp_ebo_helper<_Nm, _Tp, false>
427 {
428 explicit _Sp_ebo_helper(const _Tp& __tp) : _M_tp(__tp) { }
429 explicit _Sp_ebo_helper(_Tp&& __tp) : _M_tp(std::move(__tp)) { }
430
431 static _Tp&
432 _S_get(_Sp_ebo_helper& __eboh)
433 { return __eboh._M_tp; }
434
435 private:
436 _Tp _M_tp;
437 };
438
439 // Support for custom deleter and/or allocator
440 template<typename _Ptr, typename _Deleter, typename _Alloc, _Lock_policy _Lp>
441 class _Sp_counted_deleter final : public _Sp_counted_base<_Lp>
442 {
443 class _Impl : _Sp_ebo_helper<0, _Deleter>, _Sp_ebo_helper<1, _Alloc>
444 {
445 typedef _Sp_ebo_helper<0, _Deleter> _Del_base;
446 typedef _Sp_ebo_helper<1, _Alloc> _Alloc_base;
447
448 public:
449 _Impl(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept
450 : _M_ptr(__p), _Del_base(std::move(__d)), _Alloc_base(__a)
451 { }
452
453 _Deleter& _M_del() noexcept { return _Del_base::_S_get(*this); }
454 _Alloc& _M_alloc() noexcept { return _Alloc_base::_S_get(*this); }
455
456 _Ptr _M_ptr;
457 };
458
459 public:
460 using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_deleter>;
461
462 // __d(__p) must not throw.
463 _Sp_counted_deleter(_Ptr __p, _Deleter __d) noexcept
464 : _M_impl(__p, std::move(__d), _Alloc()) { }
465
466 // __d(__p) must not throw.
467 _Sp_counted_deleter(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept
468 : _M_impl(__p, std::move(__d), __a) { }
469
470 ~_Sp_counted_deleter() noexcept { }
471
472 virtual void
473 _M_dispose() noexcept
474 { _M_impl._M_del()(_M_impl._M_ptr); }
475
476 virtual void
477 _M_destroy() noexcept
478 {
479 __allocator_type __a(_M_impl._M_alloc());
480 __allocated_ptr<__allocator_type> __guard_ptr{ __a, this };
481 this->~_Sp_counted_deleter();
482 }
483
484 virtual void*
485 _M_get_deleter(const std::type_info& __ti) noexcept
486 {
487#if __cpp_rtti199711L
488 // _GLIBCXX_RESOLVE_LIB_DEFECTS
489 // 2400. shared_ptr's get_deleter() should use addressof()
490 return __ti == typeid(_Deleter)
491 ? std::__addressof(_M_impl._M_del())
492 : nullptr;
493#else
494 return nullptr;
495#endif
496 }
497
498 private:
499 _Impl _M_impl;
500 };
501
502 // helpers for make_shared / allocate_shared
503
504 struct _Sp_make_shared_tag
505 {
506 private:
507 template<typename _Tp, typename _Alloc, _Lock_policy _Lp>
508 friend class _Sp_counted_ptr_inplace;
509
510 static const type_info&
511 _S_ti() noexcept _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
512 {
513 alignas(type_info) static constexpr char __tag[sizeof(type_info)] = { };
514 return reinterpret_cast<const type_info&>(__tag);
515 }
516
517 static bool _S_eq(const type_info&) noexcept;
518 };
519
520 template<typename _Alloc>
521 struct _Sp_alloc_shared_tag
522 {
523 const _Alloc& _M_a;
524 };
525
526 template<typename _Tp, typename _Alloc, _Lock_policy _Lp>
527 class _Sp_counted_ptr_inplace final : public _Sp_counted_base<_Lp>
528 {
529 class _Impl : _Sp_ebo_helper<0, _Alloc>
530 {
531 typedef _Sp_ebo_helper<0, _Alloc> _A_base;
532
533 public:
534 explicit _Impl(_Alloc __a) noexcept : _A_base(__a) { }
535
536 _Alloc& _M_alloc() noexcept { return _A_base::_S_get(*this); }
537
538 __gnu_cxx::__aligned_buffer<_Tp> _M_storage;
539 };
540
541 public:
542 using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_ptr_inplace>;
543
544 // Alloc parameter is not a reference so doesn't alias anything in __args
545 template<typename... _Args>
546 _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args)
547 : _M_impl(__a)
548 {
549 // _GLIBCXX_RESOLVE_LIB_DEFECTS
550 // 2070. allocate_shared should use allocator_traits<A>::construct
551 allocator_traits<_Alloc>::construct(__a, _M_ptr(),
552 std::forward<_Args>(__args)...); // might throw
553 }
554
555 ~_Sp_counted_ptr_inplace() noexcept { }
556
557 virtual void
558 _M_dispose() noexcept
559 {
560 allocator_traits<_Alloc>::destroy(_M_impl._M_alloc(), _M_ptr());
561 }
562
563 // Override because the allocator needs to know the dynamic type
564 virtual void
565 _M_destroy() noexcept
566 {
567 __allocator_type __a(_M_impl._M_alloc());
568 __allocated_ptr<__allocator_type> __guard_ptr{ __a, this };
569 this->~_Sp_counted_ptr_inplace();
570 }
571
572 private:
573 friend class __shared_count<_Lp>; // To be able to call _M_ptr().
574
575 // No longer used, but code compiled against old libstdc++ headers
576 // might still call it from __shared_ptr ctor to get the pointer out.
577 virtual void*
578 _M_get_deleter(const std::type_info& __ti) noexcept override
579 {
580 auto __ptr = const_cast<typename remove_cv<_Tp>::type*>(_M_ptr());
581 // Check for the fake type_info first, so we don't try to access it
582 // as a real type_info object. Otherwise, check if it's the real
583 // type_info for this class. With RTTI enabled we can check directly,
584 // or call a library function to do it.
585 if (&__ti == &_Sp_make_shared_tag::_S_ti()
586 ||
587#if __cpp_rtti199711L
588 __ti == typeid(_Sp_make_shared_tag)
589#else
590 _Sp_make_shared_tag::_S_eq(__ti)
591#endif
592 )
593 return __ptr;
594 return nullptr;
595 }
596
597 _Tp* _M_ptr() noexcept { return _M_impl._M_storage._M_ptr(); }
598
599 _Impl _M_impl;
600 };
601
602 // The default deleter for shared_ptr<T[]> and shared_ptr<T[N]>.
603 struct __sp_array_delete
604 {
605 template<typename _Yp>
606 void operator()(_Yp* __p) const { delete[] __p; }
607 };
608
609 template<_Lock_policy _Lp>
610 class __shared_count
611 {
612 template<typename _Tp>
613 struct __not_alloc_shared_tag { using type = void; };
614
615 template<typename _Tp>
616 struct __not_alloc_shared_tag<_Sp_alloc_shared_tag<_Tp>> { };
617
618 public:
619 constexpr __shared_count() noexcept : _M_pi(0)
620 { }
621
622 template<typename _Ptr>
623 explicit
624 __shared_count(_Ptr __p) : _M_pi(0)
625 {
626 __tryif (true)
627 {
628 _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p);
629 }
630 __catch(...)if (false)
631 {
632 delete __p;
633 __throw_exception_again;
634 }
635 }
636
637 template<typename _Ptr>
638 __shared_count(_Ptr __p, /* is_array = */ false_type)
639 : __shared_count(__p)
640 { }
641
642 template<typename _Ptr>
643 __shared_count(_Ptr __p, /* is_array = */ true_type)
644 : __shared_count(__p, __sp_array_delete{}, allocator<void>())
645 { }
646
647 template<typename _Ptr, typename _Deleter,
648 typename = typename __not_alloc_shared_tag<_Deleter>::type>
649 __shared_count(_Ptr __p, _Deleter __d)
650 : __shared_count(__p, std::move(__d), allocator<void>())
651 { }
652
653 template<typename _Ptr, typename _Deleter, typename _Alloc,
654 typename = typename __not_alloc_shared_tag<_Deleter>::type>
655 __shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0)
656 {
657 typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type;
658 __tryif (true)
659 {
660 typename _Sp_cd_type::__allocator_type __a2(__a);
661 auto __guard = std::__allocate_guarded(__a2);
662 _Sp_cd_type* __mem = __guard.get();
663 ::new (__mem) _Sp_cd_type(__p, std::move(__d), std::move(__a));
664 _M_pi = __mem;
665 __guard = nullptr;
666 }
667 __catch(...)if (false)
668 {
669 __d(__p); // Call _Deleter on __p.
670 __throw_exception_again;
671 }
672 }
673
674 template<typename _Tp, typename _Alloc, typename... _Args>
675 __shared_count(_Tp*& __p, _Sp_alloc_shared_tag<_Alloc> __a,
676 _Args&&... __args)
677 {
678 typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type;
679 typename _Sp_cp_type::__allocator_type __a2(__a._M_a);
680 auto __guard = std::__allocate_guarded(__a2);
10
Calling '__allocate_guarded<std::allocator<std::_Sp_counted_ptr_inplace<(anonymous namespace)::SimpleTextGenerator, std::allocator<(anonymous namespace)::SimpleTextGenerator>, __gnu_cxx::_S_atomic>>>'
18
Returned allocated memory
681 _Sp_cp_type* __mem = __guard.get();
682 auto __pi = ::new (__mem)
683 _Sp_cp_type(__a._M_a, std::forward<_Args>(__args)...);
684 __guard = nullptr;
685 _M_pi = __pi;
686 __p = __pi->_M_ptr();
687 }
688
689#if _GLIBCXX_USE_DEPRECATED1
690#pragma GCC diagnostic push
691#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
692 // Special case for auto_ptr<_Tp> to provide the strong guarantee.
693 template<typename _Tp>
694 explicit
695 __shared_count(std::auto_ptr<_Tp>&& __r);
696#pragma GCC diagnostic pop
697#endif
698
699 // Special case for unique_ptr<_Tp,_Del> to provide the strong guarantee.
700 template<typename _Tp, typename _Del>
701 explicit
702 __shared_count(std::unique_ptr<_Tp, _Del>&& __r) : _M_pi(0)
703 {
704 // _GLIBCXX_RESOLVE_LIB_DEFECTS
705 // 2415. Inconsistency between unique_ptr and shared_ptr
706 if (__r.get() == nullptr)
707 return;
708
709 using _Ptr = typename unique_ptr<_Tp, _Del>::pointer;
710 using _Del2 = typename conditional<is_reference<_Del>::value,
711 reference_wrapper<typename remove_reference<_Del>::type>,
712 _Del>::type;
713 using _Sp_cd_type
714 = _Sp_counted_deleter<_Ptr, _Del2, allocator<void>, _Lp>;
715 using _Alloc = allocator<_Sp_cd_type>;
716 using _Alloc_traits = allocator_traits<_Alloc>;
717 _Alloc __a;
718 _Sp_cd_type* __mem = _Alloc_traits::allocate(__a, 1);
719 _Alloc_traits::construct(__a, __mem, __r.release(),
720 __r.get_deleter()); // non-throwing
721 _M_pi = __mem;
722 }
723
724 // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
725 explicit __shared_count(const __weak_count<_Lp>& __r);
726
727 // Does not throw if __r._M_get_use_count() == 0, caller must check.
728 explicit __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t);
729
730 ~__shared_count() noexcept
731 {
732 if (_M_pi != nullptr)
733 _M_pi->_M_release();
734 }
735
736 __shared_count(const __shared_count& __r) noexcept
737 : _M_pi(__r._M_pi)
738 {
739 if (_M_pi != 0)
740 _M_pi->_M_add_ref_copy();
741 }
742
743 __shared_count&
744 operator=(const __shared_count& __r) noexcept
745 {
746 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
747 if (__tmp != _M_pi)
748 {
749 if (__tmp != 0)
750 __tmp->_M_add_ref_copy();
751 if (_M_pi != 0)
752 _M_pi->_M_release();
753 _M_pi = __tmp;
754 }
755 return *this;
756 }
757
758 void
759 _M_swap(__shared_count& __r) noexcept
760 {
761 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
762 __r._M_pi = _M_pi;
763 _M_pi = __tmp;
764 }
765
766 long
767 _M_get_use_count() const noexcept
768 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
769
770 bool
771 _M_unique() const noexcept
772 { return this->_M_get_use_count() == 1; }
773
774 void*
775 _M_get_deleter(const std::type_info& __ti) const noexcept
776 { return _M_pi ? _M_pi->_M_get_deleter(__ti) : nullptr; }
777
778 bool
779 _M_less(const __shared_count& __rhs) const noexcept
780 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
781
782 bool
783 _M_less(const __weak_count<_Lp>& __rhs) const noexcept
784 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
785
786 // Friend function injected into enclosing namespace and found by ADL
787 friend inline bool
788 operator==(const __shared_count& __a, const __shared_count& __b) noexcept
789 { return __a._M_pi == __b._M_pi; }
790
791 private:
792 friend class __weak_count<_Lp>;
793
794 _Sp_counted_base<_Lp>* _M_pi;
795 };
796
797
798 template<_Lock_policy _Lp>
799 class __weak_count
800 {
801 public:
802 constexpr __weak_count() noexcept : _M_pi(nullptr)
803 { }
804
805 __weak_count(const __shared_count<_Lp>& __r) noexcept
806 : _M_pi(__r._M_pi)
807 {
808 if (_M_pi != nullptr)
809 _M_pi->_M_weak_add_ref();
810 }
811
812 __weak_count(const __weak_count& __r) noexcept
813 : _M_pi(__r._M_pi)
814 {
815 if (_M_pi != nullptr)
816 _M_pi->_M_weak_add_ref();
817 }
818
819 __weak_count(__weak_count&& __r) noexcept
820 : _M_pi(__r._M_pi)
821 { __r._M_pi = nullptr; }
822
823 ~__weak_count() noexcept
824 {
825 if (_M_pi != nullptr)
826 _M_pi->_M_weak_release();
827 }
828
829 __weak_count&
830 operator=(const __shared_count<_Lp>& __r) noexcept
831 {
832 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
833 if (__tmp != nullptr)
834 __tmp->_M_weak_add_ref();
835 if (_M_pi != nullptr)
836 _M_pi->_M_weak_release();
837 _M_pi = __tmp;
838 return *this;
839 }
840
841 __weak_count&
842 operator=(const __weak_count& __r) noexcept
843 {
844 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
845 if (__tmp != nullptr)
846 __tmp->_M_weak_add_ref();
847 if (_M_pi != nullptr)
848 _M_pi->_M_weak_release();
849 _M_pi = __tmp;
850 return *this;
851 }
852
853 __weak_count&
854 operator=(__weak_count&& __r) noexcept
855 {
856 if (_M_pi != nullptr)
857 _M_pi->_M_weak_release();
858 _M_pi = __r._M_pi;
859 __r._M_pi = nullptr;
860 return *this;
861 }
862
863 void
864 _M_swap(__weak_count& __r) noexcept
865 {
866 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
867 __r._M_pi = _M_pi;
868 _M_pi = __tmp;
869 }
870
871 long
872 _M_get_use_count() const noexcept
873 { return _M_pi != nullptr ? _M_pi->_M_get_use_count() : 0; }
874
875 bool
876 _M_less(const __weak_count& __rhs) const noexcept
877 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
878
879 bool
880 _M_less(const __shared_count<_Lp>& __rhs) const noexcept
881 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
882
883 // Friend function injected into enclosing namespace and found by ADL
884 friend inline bool
885 operator==(const __weak_count& __a, const __weak_count& __b) noexcept
886 { return __a._M_pi == __b._M_pi; }
887
888 private:
889 friend class __shared_count<_Lp>;
890
891 _Sp_counted_base<_Lp>* _M_pi;
892 };
893
894 // Now that __weak_count is defined we can define this constructor:
895 template<_Lock_policy _Lp>
896 inline
897 __shared_count<_Lp>::__shared_count(const __weak_count<_Lp>& __r)
898 : _M_pi(__r._M_pi)
899 {
900 if (_M_pi != nullptr)
901 _M_pi->_M_add_ref_lock();
902 else
903 __throw_bad_weak_ptr();
904 }
905
906 // Now that __weak_count is defined we can define this constructor:
907 template<_Lock_policy _Lp>
908 inline
909 __shared_count<_Lp>::
910 __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t)
911 : _M_pi(__r._M_pi)
912 {
913 if (_M_pi != nullptr)
914 if (!_M_pi->_M_add_ref_lock_nothrow())
915 _M_pi = nullptr;
916 }
917
918#define __cpp_lib_shared_ptr_arrays201611L 201611L
919
920 // Helper traits for shared_ptr of array:
921
922 // A pointer type Y* is said to be compatible with a pointer type T* when
923 // either Y* is convertible to T* or Y is U[N] and T is U cv [].
924 template<typename _Yp_ptr, typename _Tp_ptr>
925 struct __sp_compatible_with
926 : false_type
927 { };
928
929 template<typename _Yp, typename _Tp>
930 struct __sp_compatible_with<_Yp*, _Tp*>
931 : is_convertible<_Yp*, _Tp*>::type
932 { };
933
934 template<typename _Up, size_t _Nm>
935 struct __sp_compatible_with<_Up(*)[_Nm], _Up(*)[]>
936 : true_type
937 { };
938
939 template<typename _Up, size_t _Nm>
940 struct __sp_compatible_with<_Up(*)[_Nm], const _Up(*)[]>
941 : true_type
942 { };
943
944 template<typename _Up, size_t _Nm>
945 struct __sp_compatible_with<_Up(*)[_Nm], volatile _Up(*)[]>
946 : true_type
947 { };
948
949 template<typename _Up, size_t _Nm>
950 struct __sp_compatible_with<_Up(*)[_Nm], const volatile _Up(*)[]>
951 : true_type
952 { };
953
954 // Test conversion from Y(*)[N] to U(*)[N] without forming invalid type Y[N].
955 template<typename _Up, size_t _Nm, typename _Yp, typename = void>
956 struct __sp_is_constructible_arrN
957 : false_type
958 { };
959
960 template<typename _Up, size_t _Nm, typename _Yp>
961 struct __sp_is_constructible_arrN<_Up, _Nm, _Yp, __void_t<_Yp[_Nm]>>
962 : is_convertible<_Yp(*)[_Nm], _Up(*)[_Nm]>::type
963 { };
964
965 // Test conversion from Y(*)[] to U(*)[] without forming invalid type Y[].
966 template<typename _Up, typename _Yp, typename = void>
967 struct __sp_is_constructible_arr
968 : false_type
969 { };
970
971 template<typename _Up, typename _Yp>
972 struct __sp_is_constructible_arr<_Up, _Yp, __void_t<_Yp[]>>
973 : is_convertible<_Yp(*)[], _Up(*)[]>::type
974 { };
975
976 // Trait to check if shared_ptr<T> can be constructed from Y*.
977 template<typename _Tp, typename _Yp>
978 struct __sp_is_constructible;
979
980 // When T is U[N], Y(*)[N] shall be convertible to T*;
981 template<typename _Up, size_t _Nm, typename _Yp>
982 struct __sp_is_constructible<_Up[_Nm], _Yp>
983 : __sp_is_constructible_arrN<_Up, _Nm, _Yp>::type
984 { };
985
986 // when T is U[], Y(*)[] shall be convertible to T*;
987 template<typename _Up, typename _Yp>
988 struct __sp_is_constructible<_Up[], _Yp>
989 : __sp_is_constructible_arr<_Up, _Yp>::type
990 { };
991
992 // otherwise, Y* shall be convertible to T*.
993 template<typename _Tp, typename _Yp>
994 struct __sp_is_constructible
995 : is_convertible<_Yp*, _Tp*>::type
996 { };
997
998
999 // Define operator* and operator-> for shared_ptr<T>.
1000 template<typename _Tp, _Lock_policy _Lp,
1001 bool = is_array<_Tp>::value, bool = is_void<_Tp>::value>
1002 class __shared_ptr_access
1003 {
1004 public:
1005 using element_type = _Tp;
1006
1007 element_type&
1008 operator*() const noexcept
1009 {
1010 __glibcxx_assert(_M_get() != nullptr)do { if (! (_M_get() != nullptr)) std::__replacement_assert("/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr_base.h"
, 1010, __PRETTY_FUNCTION__, "_M_get() != nullptr"); } while (
false)
;
1011 return *_M_get();
1012 }
1013
1014 element_type*
1015 operator->() const noexcept
1016 {
1017 _GLIBCXX_DEBUG_PEDASSERT(_M_get() != nullptr);
1018 return _M_get();
1019 }
1020
1021 private:
1022 element_type*
1023 _M_get() const noexcept
1024 { return static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get(); }
1025 };
1026
1027 // Define operator-> for shared_ptr<cv void>.
1028 template<typename _Tp, _Lock_policy _Lp>
1029 class __shared_ptr_access<_Tp, _Lp, false, true>
1030 {
1031 public:
1032 using element_type = _Tp;
1033
1034 element_type*
1035 operator->() const noexcept
1036 {
1037 auto __ptr = static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get();
1038 _GLIBCXX_DEBUG_PEDASSERT(__ptr != nullptr);
1039 return __ptr;
1040 }
1041 };
1042
1043 // Define operator[] for shared_ptr<T[]> and shared_ptr<T[N]>.
1044 template<typename _Tp, _Lock_policy _Lp>
1045 class __shared_ptr_access<_Tp, _Lp, true, false>
1046 {
1047 public:
1048 using element_type = typename remove_extent<_Tp>::type;
1049
1050#if __cplusplus201703L <= 201402L
1051 [[__deprecated__("shared_ptr<T[]>::operator* is absent from C++17")]]
1052 element_type&
1053 operator*() const noexcept
1054 {
1055 __glibcxx_assert(_M_get() != nullptr)do { if (! (_M_get() != nullptr)) std::__replacement_assert("/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr_base.h"
, 1055, __PRETTY_FUNCTION__, "_M_get() != nullptr"); } while (
false)
;
1056 return *_M_get();
1057 }
1058
1059 [[__deprecated__("shared_ptr<T[]>::operator-> is absent from C++17")]]
1060 element_type*
1061 operator->() const noexcept
1062 {
1063 _GLIBCXX_DEBUG_PEDASSERT(_M_get() != nullptr);
1064 return _M_get();
1065 }
1066#endif
1067
1068 element_type&
1069 operator[](ptrdiff_t __i) const
1070 {
1071 __glibcxx_assert(_M_get() != nullptr)do { if (! (_M_get() != nullptr)) std::__replacement_assert("/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr_base.h"
, 1071, __PRETTY_FUNCTION__, "_M_get() != nullptr"); } while (
false)
;
1072 __glibcxx_assert(!extent<_Tp>::value || __i < extent<_Tp>::value)do { if (! (!extent<_Tp>::value || __i < extent<_Tp
>::value)) std::__replacement_assert("/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr_base.h"
, 1072, __PRETTY_FUNCTION__, "!extent<_Tp>::value || __i < extent<_Tp>::value"
); } while (false)
;
1073 return _M_get()[__i];
1074 }
1075
1076 private:
1077 element_type*
1078 _M_get() const noexcept
1079 { return static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get(); }
1080 };
1081
1082 template<typename _Tp, _Lock_policy _Lp>
1083 class __shared_ptr
1084 : public __shared_ptr_access<_Tp, _Lp>
1085 {
1086 public:
1087 using element_type = typename remove_extent<_Tp>::type;
1088
1089 private:
1090 // Constraint for taking ownership of a pointer of type _Yp*:
1091 template<typename _Yp>
1092 using _SafeConv
1093 = typename enable_if<__sp_is_constructible<_Tp, _Yp>::value>::type;
1094
1095 // Constraint for construction from shared_ptr and weak_ptr:
1096 template<typename _Yp, typename _Res = void>
1097 using _Compatible = typename
1098 enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type;
1099
1100 // Constraint for assignment from shared_ptr and weak_ptr:
1101 template<typename _Yp>
1102 using _Assignable = _Compatible<_Yp, __shared_ptr&>;
1103
1104 // Constraint for construction from unique_ptr:
1105 template<typename _Yp, typename _Del, typename _Res = void,
1106 typename _Ptr = typename unique_ptr<_Yp, _Del>::pointer>
1107 using _UniqCompatible = typename enable_if<__and_<
1108 __sp_compatible_with<_Yp*, _Tp*>, is_convertible<_Ptr, element_type*>
1109 >::value, _Res>::type;
1110
1111 // Constraint for assignment from unique_ptr:
1112 template<typename _Yp, typename _Del>
1113 using _UniqAssignable = _UniqCompatible<_Yp, _Del, __shared_ptr&>;
1114
1115 public:
1116
1117#if __cplusplus201703L > 201402L
1118 using weak_type = __weak_ptr<_Tp, _Lp>;
1119#endif
1120
1121 constexpr __shared_ptr() noexcept
1122 : _M_ptr(0), _M_refcount()
1123 { }
1124
1125 template<typename _Yp, typename = _SafeConv<_Yp>>
1126 explicit
1127 __shared_ptr(_Yp* __p)
1128 : _M_ptr(__p), _M_refcount(__p, typename is_array<_Tp>::type())
1129 {
1130 static_assert( !is_void<_Yp>::value, "incomplete type" );
1131 static_assert( sizeof(_Yp) > 0, "incomplete type" );
1132 _M_enable_shared_from_this_with(__p);
1133 }
1134
1135 template<typename _Yp, typename _Deleter, typename = _SafeConv<_Yp>>
1136 __shared_ptr(_Yp* __p, _Deleter __d)
1137 : _M_ptr(__p), _M_refcount(__p, std::move(__d))
1138 {
1139 static_assert(__is_invocable<_Deleter&, _Yp*&>::value,
1140 "deleter expression d(p) is well-formed");
1141 _M_enable_shared_from_this_with(__p);
1142 }
1143
1144 template<typename _Yp, typename _Deleter, typename _Alloc,
1145 typename = _SafeConv<_Yp>>
1146 __shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a)
1147 : _M_ptr(__p), _M_refcount(__p, std::move(__d), std::move(__a))
1148 {
1149 static_assert(__is_invocable<_Deleter&, _Yp*&>::value,
1150 "deleter expression d(p) is well-formed");
1151 _M_enable_shared_from_this_with(__p);
1152 }
1153
1154 template<typename _Deleter>
1155 __shared_ptr(nullptr_t __p, _Deleter __d)
1156 : _M_ptr(0), _M_refcount(__p, std::move(__d))
1157 { }
1158
1159 template<typename _Deleter, typename _Alloc>
1160 __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
1161 : _M_ptr(0), _M_refcount(__p, std::move(__d), std::move(__a))
1162 { }
1163
1164 // Aliasing constructor
1165 template<typename _Yp>
1166 __shared_ptr(const __shared_ptr<_Yp, _Lp>& __r,
1167 element_type* __p) noexcept
1168 : _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws
1169 { }
1170
1171 // Aliasing constructor
1172 template<typename _Yp>
1173 __shared_ptr(__shared_ptr<_Yp, _Lp>&& __r,
1174 element_type* __p) noexcept
1175 : _M_ptr(__p), _M_refcount()
1176 {
1177 _M_refcount._M_swap(__r._M_refcount);
1178 __r._M_ptr = 0;
1179 }
1180
1181 __shared_ptr(const __shared_ptr&) noexcept = default;
1182 __shared_ptr& operator=(const __shared_ptr&) noexcept = default;
1183 ~__shared_ptr() = default;
1184
1185 template<typename _Yp, typename = _Compatible<_Yp>>
1186 __shared_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept
1187 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
1188 { }
1189
1190 __shared_ptr(__shared_ptr&& __r) noexcept
1191 : _M_ptr(__r._M_ptr), _M_refcount()
1192 {
1193 _M_refcount._M_swap(__r._M_refcount);
1194 __r._M_ptr = 0;
1195 }
1196
1197 template<typename _Yp, typename = _Compatible<_Yp>>
1198 __shared_ptr(__shared_ptr<_Yp, _Lp>&& __r) noexcept
1199 : _M_ptr(__r._M_ptr), _M_refcount()
1200 {
1201 _M_refcount._M_swap(__r._M_refcount);
1202 __r._M_ptr = 0;
1203 }
1204
1205 template<typename _Yp, typename = _Compatible<_Yp>>
1206 explicit __shared_ptr(const __weak_ptr<_Yp, _Lp>& __r)
1207 : _M_refcount(__r._M_refcount) // may throw
1208 {
1209 // It is now safe to copy __r._M_ptr, as
1210 // _M_refcount(__r._M_refcount) did not throw.
1211 _M_ptr = __r._M_ptr;
1212 }
1213
1214 // If an exception is thrown this constructor has no effect.
1215 template<typename _Yp, typename _Del,
1216 typename = _UniqCompatible<_Yp, _Del>>
1217 __shared_ptr(unique_ptr<_Yp, _Del>&& __r)
1218 : _M_ptr(__r.get()), _M_refcount()
1219 {
1220 auto __raw = __to_address(__r.get());
1221 _M_refcount = __shared_count<_Lp>(std::move(__r));
1222 _M_enable_shared_from_this_with(__raw);
1223 }
1224
1225#if __cplusplus201703L <= 201402L && _GLIBCXX_USE_DEPRECATED1
1226 protected:
1227 // If an exception is thrown this constructor has no effect.
1228 template<typename _Tp1, typename _Del,
1229 typename enable_if<__and_<
1230 __not_<is_array<_Tp>>, is_array<_Tp1>,
1231 is_convertible<typename unique_ptr<_Tp1, _Del>::pointer, _Tp*>
1232 >::value, bool>::type = true>
1233 __shared_ptr(unique_ptr<_Tp1, _Del>&& __r, __sp_array_delete)
1234 : _M_ptr(__r.get()), _M_refcount()
1235 {
1236 auto __raw = __to_address(__r.get());
1237 _M_refcount = __shared_count<_Lp>(std::move(__r));
1238 _M_enable_shared_from_this_with(__raw);
1239 }
1240 public:
1241#endif
1242
1243#if _GLIBCXX_USE_DEPRECATED1
1244#pragma GCC diagnostic push
1245#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1246 // Postcondition: use_count() == 1 and __r.get() == 0
1247 template<typename _Yp, typename = _Compatible<_Yp>>
1248 __shared_ptr(auto_ptr<_Yp>&& __r);
1249#pragma GCC diagnostic pop
1250#endif
1251
1252 constexpr __shared_ptr(nullptr_t) noexcept : __shared_ptr() { }
1253
1254 template<typename _Yp>
1255 _Assignable<_Yp>
1256 operator=(const __shared_ptr<_Yp, _Lp>& __r) noexcept
1257 {
1258 _M_ptr = __r._M_ptr;
1259 _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
1260 return *this;
1261 }
1262
1263#if _GLIBCXX_USE_DEPRECATED1
1264#pragma GCC diagnostic push
1265#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1266 template<typename _Yp>
1267 _Assignable<_Yp>
1268 operator=(auto_ptr<_Yp>&& __r)
1269 {
1270 __shared_ptr(std::move(__r)).swap(*this);
1271 return *this;
1272 }
1273#pragma GCC diagnostic pop
1274#endif
1275
1276 __shared_ptr&
1277 operator=(__shared_ptr&& __r) noexcept
1278 {
1279 __shared_ptr(std::move(__r)).swap(*this);
1280 return *this;
1281 }
1282
1283 template<class _Yp>
1284 _Assignable<_Yp>
1285 operator=(__shared_ptr<_Yp, _Lp>&& __r) noexcept
1286 {
1287 __shared_ptr(std::move(__r)).swap(*this);
1288 return *this;
1289 }
1290
1291 template<typename _Yp, typename _Del>
1292 _UniqAssignable<_Yp, _Del>
1293 operator=(unique_ptr<_Yp, _Del>&& __r)
1294 {
1295 __shared_ptr(std::move(__r)).swap(*this);
1296 return *this;
1297 }
1298
1299 void
1300 reset() noexcept
1301 { __shared_ptr().swap(*this); }
1302
1303 template<typename _Yp>
1304 _SafeConv<_Yp>
1305 reset(_Yp* __p) // _Yp must be complete.
1306 {
1307 // Catch self-reset errors.
1308 __glibcxx_assert(__p == 0 || __p != _M_ptr)do { if (! (__p == 0 || __p != _M_ptr)) std::__replacement_assert
("/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr_base.h"
, 1308, __PRETTY_FUNCTION__, "__p == 0 || __p != _M_ptr"); } while
(false)
;
1309 __shared_ptr(__p).swap(*this);
1310 }
1311
1312 template<typename _Yp, typename _Deleter>
1313 _SafeConv<_Yp>
1314 reset(_Yp* __p, _Deleter __d)
1315 { __shared_ptr(__p, std::move(__d)).swap(*this); }
1316
1317 template<typename _Yp, typename _Deleter, typename _Alloc>
1318 _SafeConv<_Yp>
1319 reset(_Yp* __p, _Deleter __d, _Alloc __a)
1320 { __shared_ptr(__p, std::move(__d), std::move(__a)).swap(*this); }
1321
1322 /// Return the stored pointer.
1323 element_type*
1324 get() const noexcept
1325 { return _M_ptr; }
1326
1327 /// Return true if the stored pointer is not null.
1328 explicit operator bool() const // never throws
1329 { return _M_ptr == 0 ? false : true; }
1330
1331 /// Return true if use_count() == 1.
1332 bool
1333 unique() const noexcept
1334 { return _M_refcount._M_unique(); }
1335
1336 /// If *this owns a pointer, return the number of owners, otherwise zero.
1337 long
1338 use_count() const noexcept
1339 { return _M_refcount._M_get_use_count(); }
1340
1341 /// Exchange both the owned pointer and the stored pointer.
1342 void
1343 swap(__shared_ptr<_Tp, _Lp>& __other) noexcept
1344 {
1345 std::swap(_M_ptr, __other._M_ptr);
1346 _M_refcount._M_swap(__other._M_refcount);
1347 }
1348
1349 /** @brief Define an ordering based on ownership.
1350 *
1351 * This function defines a strict weak ordering between two shared_ptr
1352 * or weak_ptr objects, such that one object is less than the other
1353 * unless they share ownership of the same pointer, or are both empty.
1354 * @{
1355 */
1356 template<typename _Tp1>
1357 bool
1358 owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const noexcept
1359 { return _M_refcount._M_less(__rhs._M_refcount); }
1360
1361 template<typename _Tp1>
1362 bool
1363 owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const noexcept
1364 { return _M_refcount._M_less(__rhs._M_refcount); }
1365 // @}
1366
1367 protected:
1368 // This constructor is non-standard, it is used by allocate_shared.
1369 template<typename _Alloc, typename... _Args>
1370 __shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args)
1371 : _M_ptr(), _M_refcount(_M_ptr, __tag, std::forward<_Args>(__args)...)
9
Calling constructor for '__shared_count<__gnu_cxx::_S_atomic>'
19
Returning from constructor for '__shared_count<__gnu_cxx::_S_atomic>'
1372 { _M_enable_shared_from_this_with(_M_ptr); }
1373
1374 template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc,
1375 typename... _Args>
1376 friend __shared_ptr<_Tp1, _Lp1>
1377 __allocate_shared(const _Alloc& __a, _Args&&... __args);
1378
1379 // This constructor is used by __weak_ptr::lock() and
1380 // shared_ptr::shared_ptr(const weak_ptr&, std::nothrow_t).
1381 __shared_ptr(const __weak_ptr<_Tp, _Lp>& __r, std::nothrow_t)
1382 : _M_refcount(__r._M_refcount, std::nothrow)
1383 {
1384 _M_ptr = _M_refcount._M_get_use_count() ? __r._M_ptr : nullptr;
1385 }
1386
1387 friend class __weak_ptr<_Tp, _Lp>;
1388
1389 private:
1390
1391 template<typename _Yp>
1392 using __esft_base_t = decltype(__enable_shared_from_this_base(
1393 std::declval<const __shared_count<_Lp>&>(),
1394 std::declval<_Yp*>()));
1395
1396 // Detect an accessible and unambiguous enable_shared_from_this base.
1397 template<typename _Yp, typename = void>
1398 struct __has_esft_base
1399 : false_type { };
1400
1401 template<typename _Yp>
1402 struct __has_esft_base<_Yp, __void_t<__esft_base_t<_Yp>>>
1403 : __not_<is_array<_Tp>> { }; // No enable shared_from_this for arrays
1404
1405 template<typename _Yp, typename _Yp2 = typename remove_cv<_Yp>::type>
1406 typename enable_if<__has_esft_base<_Yp2>::value>::type
1407 _M_enable_shared_from_this_with(_Yp* __p) noexcept
1408 {
1409 if (auto __base = __enable_shared_from_this_base(_M_refcount, __p))
1410 __base->_M_weak_assign(const_cast<_Yp2*>(__p), _M_refcount);
1411 }
1412
1413 template<typename _Yp, typename _Yp2 = typename remove_cv<_Yp>::type>
1414 typename enable_if<!__has_esft_base<_Yp2>::value>::type
1415 _M_enable_shared_from_this_with(_Yp*) noexcept
1416 { }
1417
1418 void*
1419 _M_get_deleter(const std::type_info& __ti) const noexcept
1420 { return _M_refcount._M_get_deleter(__ti); }
1421
1422 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
1423 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
1424
1425 template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
1426 friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept;
1427
1428 template<typename _Del, typename _Tp1>
1429 friend _Del* get_deleter(const shared_ptr<_Tp1>&) noexcept;
1430
1431 element_type* _M_ptr; // Contained pointer.
1432 __shared_count<_Lp> _M_refcount; // Reference counter.
1433 };
1434
1435
1436 // 20.7.2.2.7 shared_ptr comparisons
1437 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1438 inline bool
1439 operator==(const __shared_ptr<_Tp1, _Lp>& __a,
1440 const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1441 { return __a.get() == __b.get(); }
1442
1443 template<typename _Tp, _Lock_policy _Lp>
1444 inline bool
1445 operator==(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1446 { return !__a; }
1447
1448#ifdef __cpp_lib_three_way_comparison
1449 template<typename _Tp, typename _Up, _Lock_policy _Lp>
1450 inline strong_ordering
1451 operator<=>(const __shared_ptr<_Tp, _Lp>& __a,
1452 const __shared_ptr<_Up, _Lp>& __b) noexcept
1453 { return compare_three_way()(__a.get(), __b.get()); }
1454
1455 template<typename _Tp, _Lock_policy _Lp>
1456 inline strong_ordering
1457 operator<=>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1458 {
1459 using pointer = typename __shared_ptr<_Tp, _Lp>::element_type*;
1460 return compare_three_way()(__a.get(), static_cast<pointer>(nullptr));
1461 }
1462#else
1463 template<typename _Tp, _Lock_policy _Lp>
1464 inline bool
1465 operator==(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1466 { return !__a; }
1467
1468 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1469 inline bool
1470 operator!=(const __shared_ptr<_Tp1, _Lp>& __a,
1471 const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1472 { return __a.get() != __b.get(); }
1473
1474 template<typename _Tp, _Lock_policy _Lp>
1475 inline bool
1476 operator!=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1477 { return (bool)__a; }
1478
1479 template<typename _Tp, _Lock_policy _Lp>
1480 inline bool
1481 operator!=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1482 { return (bool)__a; }
1483
1484 template<typename _Tp, typename _Up, _Lock_policy _Lp>
1485 inline bool
1486 operator<(const __shared_ptr<_Tp, _Lp>& __a,
1487 const __shared_ptr<_Up, _Lp>& __b) noexcept
1488 {
1489 using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type;
1490 using _Up_elt = typename __shared_ptr<_Up, _Lp>::element_type;
1491 using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type;
1492 return less<_Vp>()(__a.get(), __b.get());
1493 }
1494
1495 template<typename _Tp, _Lock_policy _Lp>
1496 inline bool
1497 operator<(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1498 {
1499 using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type;
1500 return less<_Tp_elt*>()(__a.get(), nullptr);
1501 }
1502
1503 template<typename _Tp, _Lock_policy _Lp>
1504 inline bool
1505 operator<(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1506 {
1507 using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type;
1508 return less<_Tp_elt*>()(nullptr, __a.get());
1509 }
1510
1511 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1512 inline bool
1513 operator<=(const __shared_ptr<_Tp1, _Lp>& __a,
1514 const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1515 { return !(__b < __a); }
1516
1517 template<typename _Tp, _Lock_policy _Lp>
1518 inline bool
1519 operator<=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1520 { return !(nullptr < __a); }
1521
1522 template<typename _Tp, _Lock_policy _Lp>
1523 inline bool
1524 operator<=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1525 { return !(__a < nullptr); }
1526
1527 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1528 inline bool
1529 operator>(const __shared_ptr<_Tp1, _Lp>& __a,
1530 const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1531 { return (__b < __a); }
1532
1533 template<typename _Tp, _Lock_policy _Lp>
1534 inline bool
1535 operator>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1536 { return nullptr < __a; }
1537
1538 template<typename _Tp, _Lock_policy _Lp>
1539 inline bool
1540 operator>(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1541 { return __a < nullptr; }
1542
1543 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1544 inline bool
1545 operator>=(const __shared_ptr<_Tp1, _Lp>& __a,
1546 const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1547 { return !(__a < __b); }
1548
1549 template<typename _Tp, _Lock_policy _Lp>
1550 inline bool
1551 operator>=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1552 { return !(__a < nullptr); }
1553
1554 template<typename _Tp, _Lock_policy _Lp>
1555 inline bool
1556 operator>=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1557 { return !(nullptr < __a); }
1558#endif // three-way comparison
1559
1560 // 20.7.2.2.8 shared_ptr specialized algorithms.
1561 template<typename _Tp, _Lock_policy _Lp>
1562 inline void
1563 swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) noexcept
1564 { __a.swap(__b); }
1565
1566 // 20.7.2.2.9 shared_ptr casts
1567
1568 // The seemingly equivalent code:
1569 // shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))
1570 // will eventually result in undefined behaviour, attempting to
1571 // delete the same object twice.
1572 /// static_pointer_cast
1573 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
1574 inline __shared_ptr<_Tp, _Lp>
1575 static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1576 {
1577 using _Sp = __shared_ptr<_Tp, _Lp>;
1578 return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get()));
1579 }
1580
1581 // The seemingly equivalent code:
1582 // shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))
1583 // will eventually result in undefined behaviour, attempting to
1584 // delete the same object twice.
1585 /// const_pointer_cast
1586 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
1587 inline __shared_ptr<_Tp, _Lp>
1588 const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1589 {
1590 using _Sp = __shared_ptr<_Tp, _Lp>;
1591 return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get()));
1592 }
1593
1594 // The seemingly equivalent code:
1595 // shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))
1596 // will eventually result in undefined behaviour, attempting to
1597 // delete the same object twice.
1598 /// dynamic_pointer_cast
1599 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
1600 inline __shared_ptr<_Tp, _Lp>
1601 dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1602 {
1603 using _Sp = __shared_ptr<_Tp, _Lp>;
1604 if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))
1605 return _Sp(__r, __p);
1606 return _Sp();
1607 }
1608
1609#if __cplusplus201703L > 201402L
1610 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
1611 inline __shared_ptr<_Tp, _Lp>
1612 reinterpret_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1613 {
1614 using _Sp = __shared_ptr<_Tp, _Lp>;
1615 return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get()));
1616 }
1617#endif
1618
1619 template<typename _Tp, _Lock_policy _Lp>
1620 class __weak_ptr
1621 {
1622 template<typename _Yp, typename _Res = void>
1623 using _Compatible = typename
1624 enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type;
1625
1626 // Constraint for assignment from shared_ptr and weak_ptr:
1627 template<typename _Yp>
1628 using _Assignable = _Compatible<_Yp, __weak_ptr&>;
1629
1630 public:
1631 using element_type = typename remove_extent<_Tp>::type;
1632
1633 constexpr __weak_ptr() noexcept
1634 : _M_ptr(nullptr), _M_refcount()
1635 { }
1636
1637 __weak_ptr(const __weak_ptr&) noexcept = default;
1638
1639 ~__weak_ptr() = default;
1640
1641 // The "obvious" converting constructor implementation:
1642 //
1643 // template<typename _Tp1>
1644 // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
1645 // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
1646 // { }
1647 //
1648 // has a serious problem.
1649 //
1650 // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
1651 // conversion may require access to *__r._M_ptr (virtual inheritance).
1652 //
1653 // It is not possible to avoid spurious access violations since
1654 // in multithreaded programs __r._M_ptr may be invalidated at any point.
1655 template<typename _Yp, typename = _Compatible<_Yp>>
1656 __weak_ptr(const __weak_ptr<_Yp, _Lp>& __r) noexcept
1657 : _M_refcount(__r._M_refcount)
1658 { _M_ptr = __r.lock().get(); }
1659
1660 template<typename _Yp, typename = _Compatible<_Yp>>
1661 __weak_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept
1662 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
1663 { }
1664
1665 __weak_ptr(__weak_ptr&& __r) noexcept
1666 : _M_ptr(__r._M_ptr), _M_refcount(std::move(__r._M_refcount))
1667 { __r._M_ptr = nullptr; }
1668
1669 template<typename _Yp, typename = _Compatible<_Yp>>
1670 __weak_ptr(__weak_ptr<_Yp, _Lp>&& __r) noexcept
1671 : _M_ptr(__r.lock().get()), _M_refcount(std::move(__r._M_refcount))
1672 { __r._M_ptr = nullptr; }
1673
1674 __weak_ptr&
1675 operator=(const __weak_ptr& __r) noexcept = default;
1676
1677 template<typename _Yp>
1678 _Assignable<_Yp>
1679 operator=(const __weak_ptr<_Yp, _Lp>& __r) noexcept
1680 {
1681 _M_ptr = __r.lock().get();
1682 _M_refcount = __r._M_refcount;
1683 return *this;
1684 }
1685
1686 template<typename _Yp>
1687 _Assignable<_Yp>
1688 operator=(const __shared_ptr<_Yp, _Lp>& __r) noexcept
1689 {
1690 _M_ptr = __r._M_ptr;
1691 _M_refcount = __r._M_refcount;
1692 return *this;
1693 }
1694
1695 __weak_ptr&
1696 operator=(__weak_ptr&& __r) noexcept
1697 {
1698 _M_ptr = __r._M_ptr;
1699 _M_refcount = std::move(__r._M_refcount);
1700 __r._M_ptr = nullptr;
1701 return *this;
1702 }
1703
1704 template<typename _Yp>
1705 _Assignable<_Yp>
1706 operator=(__weak_ptr<_Yp, _Lp>&& __r) noexcept
1707 {
1708 _M_ptr = __r.lock().get();
1709 _M_refcount = std::move(__r._M_refcount);
1710 __r._M_ptr = nullptr;
1711 return *this;
1712 }
1713
1714 __shared_ptr<_Tp, _Lp>
1715 lock() const noexcept
1716 { return __shared_ptr<element_type, _Lp>(*this, std::nothrow); }
1717
1718 long
1719 use_count() const noexcept
1720 { return _M_refcount._M_get_use_count(); }
1721
1722 bool
1723 expired() const noexcept
1724 { return _M_refcount._M_get_use_count() == 0; }
1725
1726 template<typename _Tp1>
1727 bool
1728 owner_before(const __shared_ptr<_Tp1, _Lp>& __rhs) const noexcept
1729 { return _M_refcount._M_less(__rhs._M_refcount); }
1730
1731 template<typename _Tp1>
1732 bool
1733 owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const noexcept
1734 { return _M_refcount._M_less(__rhs._M_refcount); }
1735
1736 void
1737 reset() noexcept
1738 { __weak_ptr().swap(*this); }
1739
1740 void
1741 swap(__weak_ptr& __s) noexcept
1742 {
1743 std::swap(_M_ptr, __s._M_ptr);
1744 _M_refcount._M_swap(__s._M_refcount);
1745 }
1746
1747 private:
1748 // Used by __enable_shared_from_this.
1749 void
1750 _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) noexcept
1751 {
1752 if (use_count() == 0)
1753 {
1754 _M_ptr = __ptr;
1755 _M_refcount = __refcount;
1756 }
1757 }
1758
1759 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
1760 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
1761 friend class __enable_shared_from_this<_Tp, _Lp>;
1762 friend class enable_shared_from_this<_Tp>;
1763
1764 element_type* _M_ptr; // Contained pointer.
1765 __weak_count<_Lp> _M_refcount; // Reference counter.
1766 };
1767
1768 // 20.7.2.3.6 weak_ptr specialized algorithms.
1769 template<typename _Tp, _Lock_policy _Lp>
1770 inline void
1771 swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) noexcept
1772 { __a.swap(__b); }
1773
1774 template<typename _Tp, typename _Tp1>
1775 struct _Sp_owner_less : public binary_function<_Tp, _Tp, bool>
1776 {
1777 bool
1778 operator()(const _Tp& __lhs, const _Tp& __rhs) const noexcept
1779 { return __lhs.owner_before(__rhs); }
1780
1781 bool
1782 operator()(const _Tp& __lhs, const _Tp1& __rhs) const noexcept
1783 { return __lhs.owner_before(__rhs); }
1784
1785 bool
1786 operator()(const _Tp1& __lhs, const _Tp& __rhs) const noexcept
1787 { return __lhs.owner_before(__rhs); }
1788 };
1789
1790 template<>
1791 struct _Sp_owner_less<void, void>
1792 {
1793 template<typename _Tp, typename _Up>
1794 auto
1795 operator()(const _Tp& __lhs, const _Up& __rhs) const noexcept
1796 -> decltype(__lhs.owner_before(__rhs))
1797 { return __lhs.owner_before(__rhs); }
1798
1799 using is_transparent = void;
1800 };
1801
1802 template<typename _Tp, _Lock_policy _Lp>
1803 struct owner_less<__shared_ptr<_Tp, _Lp>>
1804 : public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>>
1805 { };
1806
1807 template<typename _Tp, _Lock_policy _Lp>
1808 struct owner_less<__weak_ptr<_Tp, _Lp>>
1809 : public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>>
1810 { };
1811
1812
1813 template<typename _Tp, _Lock_policy _Lp>
1814 class __enable_shared_from_this
1815 {
1816 protected:
1817 constexpr __enable_shared_from_this() noexcept { }
1818
1819 __enable_shared_from_this(const __enable_shared_from_this&) noexcept { }
1820
1821 __enable_shared_from_this&
1822 operator=(const __enable_shared_from_this&) noexcept
1823 { return *this; }
1824
1825 ~__enable_shared_from_this() { }
1826
1827 public:
1828 __shared_ptr<_Tp, _Lp>
1829 shared_from_this()
1830 { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
1831
1832 __shared_ptr<const _Tp, _Lp>
1833 shared_from_this() const
1834 { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
1835
1836#if __cplusplus201703L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11
1837 __weak_ptr<_Tp, _Lp>
1838 weak_from_this() noexcept
1839 { return this->_M_weak_this; }
1840
1841 __weak_ptr<const _Tp, _Lp>
1842 weak_from_this() const noexcept
1843 { return this->_M_weak_this; }
1844#endif
1845
1846 private:
1847 template<typename _Tp1>
1848 void
1849 _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const noexcept
1850 { _M_weak_this._M_assign(__p, __n); }
1851
1852 friend const __enable_shared_from_this*
1853 __enable_shared_from_this_base(const __shared_count<_Lp>&,
1854 const __enable_shared_from_this* __p)
1855 { return __p; }
1856
1857 template<typename, _Lock_policy>
1858 friend class __shared_ptr;
1859
1860 mutable __weak_ptr<_Tp, _Lp> _M_weak_this;
1861 };
1862
1863 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy,
1864 typename _Alloc, typename... _Args>
1865 inline __shared_ptr<_Tp, _Lp>
1866 __allocate_shared(const _Alloc& __a, _Args&&... __args)
1867 {
1868 return __shared_ptr<_Tp, _Lp>(_Sp_alloc_shared_tag<_Alloc>{__a},
1869 std::forward<_Args>(__args)...);
1870 }
1871
1872 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy,
1873 typename... _Args>
1874 inline __shared_ptr<_Tp, _Lp>
1875 __make_shared(_Args&&... __args)
1876 {
1877 typedef typename std::remove_const<_Tp>::type _Tp_nc;
1878 return std::__allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(),
1879 std::forward<_Args>(__args)...);
1880 }
1881
1882 /// std::hash specialization for __shared_ptr.
1883 template<typename _Tp, _Lock_policy _Lp>
1884 struct hash<__shared_ptr<_Tp, _Lp>>
1885 : public __hash_base<size_t, __shared_ptr<_Tp, _Lp>>
1886 {
1887 size_t
1888 operator()(const __shared_ptr<_Tp, _Lp>& __s) const noexcept
1889 {
1890 return hash<typename __shared_ptr<_Tp, _Lp>::element_type*>()(
1891 __s.get());
1892 }
1893 };
1894
1895_GLIBCXX_END_NAMESPACE_VERSION
1896} // namespace
1897
1898#endif // _SHARED_PTR_BASE_H

/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/allocated_ptr.h

1// Guarded Allocation -*- C++ -*-
2
3// Copyright (C) 2014-2020 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/allocated_ptr.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{memory}
28 */
29
30#ifndef _ALLOCATED_PTR_H1
31#define _ALLOCATED_PTR_H1 1
32
33#if __cplusplus201703L < 201103L
34# include <bits/c++0xwarning.h>
35#else
36# include <type_traits>
37# include <bits/ptr_traits.h>
38# include <bits/alloc_traits.h>
39
40namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
41{
42_GLIBCXX_BEGIN_NAMESPACE_VERSION
43
44 /// Non-standard RAII type for managing pointers obtained from allocators.
45 template<typename _Alloc>
46 struct __allocated_ptr
47 {
48 using pointer = typename allocator_traits<_Alloc>::pointer;
49 using value_type = typename allocator_traits<_Alloc>::value_type;
50
51 /// Take ownership of __ptr
52 __allocated_ptr(_Alloc& __a, pointer __ptr) noexcept
53 : _M_alloc(std::__addressof(__a)), _M_ptr(__ptr)
54 { }
55
56 /// Convert __ptr to allocator's pointer type and take ownership of it
57 template<typename _Ptr,
58 typename _Req = _Require<is_same<_Ptr, value_type*>>>
59 __allocated_ptr(_Alloc& __a, _Ptr __ptr)
60 : _M_alloc(std::__addressof(__a)),
61 _M_ptr(pointer_traits<pointer>::pointer_to(*__ptr))
62 { }
63
64 /// Transfer ownership of the owned pointer
65 __allocated_ptr(__allocated_ptr&& __gd) noexcept
66 : _M_alloc(__gd._M_alloc), _M_ptr(__gd._M_ptr)
67 { __gd._M_ptr = nullptr; }
68
69 /// Deallocate the owned pointer
70 ~__allocated_ptr()
71 {
72 if (_M_ptr != nullptr)
73 std::allocator_traits<_Alloc>::deallocate(*_M_alloc, _M_ptr, 1);
74 }
75
76 /// Release ownership of the owned pointer
77 __allocated_ptr&
78 operator=(std::nullptr_t) noexcept
79 {
80 _M_ptr = nullptr;
81 return *this;
82 }
83
84 /// Get the address that the owned pointer refers to.
85 value_type* get() { return std::__to_address(_M_ptr); }
86
87 private:
88 _Alloc* _M_alloc;
89 pointer _M_ptr;
90 };
91
92 /// Allocate space for a single object using __a
93 template<typename _Alloc>
94 __allocated_ptr<_Alloc>
95 __allocate_guarded(_Alloc& __a)
96 {
97 return { __a, std::allocator_traits<_Alloc>::allocate(__a, 1) };
11
Calling 'allocator_traits::allocate'
17
Returned allocated memory
98 }
99
100_GLIBCXX_END_NAMESPACE_VERSION
101} // namespace std
102
103#endif
104#endif

/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/alloc_traits.h

1// Allocator traits -*- C++ -*-
2
3// Copyright (C) 2011-2020 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/alloc_traits.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{memory}
28 */
29
30#ifndef _ALLOC_TRAITS_H1
31#define _ALLOC_TRAITS_H1 1
32
33#include <bits/stl_construct.h>
34#include <bits/memoryfwd.h>
35#if __cplusplus201703L >= 201103L
36# include <bits/allocator.h>
37# include <bits/ptr_traits.h>
38# include <ext/numeric_traits.h>
39#endif
40
41namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
42{
43_GLIBCXX_BEGIN_NAMESPACE_VERSION
44
45#if __cplusplus201703L >= 201103L
46#define __cpp_lib_allocator_traits_is_always_equal201411 201411
47
48 struct __allocator_traits_base
49 {
50 template<typename _Tp, typename _Up, typename = void>
51 struct __rebind : __replace_first_arg<_Tp, _Up> { };
52
53 template<typename _Tp, typename _Up>
54 struct __rebind<_Tp, _Up,
55 __void_t<typename _Tp::template rebind<_Up>::other>>
56 { using type = typename _Tp::template rebind<_Up>::other; };
57
58 protected:
59 template<typename _Tp>
60 using __pointer = typename _Tp::pointer;
61 template<typename _Tp>
62 using __c_pointer = typename _Tp::const_pointer;
63 template<typename _Tp>
64 using __v_pointer = typename _Tp::void_pointer;
65 template<typename _Tp>
66 using __cv_pointer = typename _Tp::const_void_pointer;
67 template<typename _Tp>
68 using __pocca = typename _Tp::propagate_on_container_copy_assignment;
69 template<typename _Tp>
70 using __pocma = typename _Tp::propagate_on_container_move_assignment;
71 template<typename _Tp>
72 using __pocs = typename _Tp::propagate_on_container_swap;
73 template<typename _Tp>
74 using __equal = typename _Tp::is_always_equal;
75 };
76
77 template<typename _Alloc, typename _Up>
78 using __alloc_rebind
79 = typename __allocator_traits_base::template __rebind<_Alloc, _Up>::type;
80
81 /**
82 * @brief Uniform interface to all allocator types.
83 * @ingroup allocators
84 */
85 template<typename _Alloc>
86 struct allocator_traits : __allocator_traits_base
87 {
88 /// The allocator type
89 typedef _Alloc allocator_type;
90 /// The allocated type
91 typedef typename _Alloc::value_type value_type;
92
93 /**
94 * @brief The allocator's pointer type.
95 *
96 * @c Alloc::pointer if that type exists, otherwise @c value_type*
97 */
98 using pointer = __detected_or_t<value_type*, __pointer, _Alloc>;
99
100 private:
101 // Select _Func<_Alloc> or pointer_traits<pointer>::rebind<_Tp>
102 template<template<typename> class _Func, typename _Tp, typename = void>
103 struct _Ptr
104 {
105 using type = typename pointer_traits<pointer>::template rebind<_Tp>;
106 };
107
108 template<template<typename> class _Func, typename _Tp>
109 struct _Ptr<_Func, _Tp, __void_t<_Func<_Alloc>>>
110 {
111 using type = _Func<_Alloc>;
112 };
113
114 // Select _A2::difference_type or pointer_traits<_Ptr>::difference_type
115 template<typename _A2, typename _PtrT, typename = void>
116 struct _Diff
117 { using type = typename pointer_traits<_PtrT>::difference_type; };
118
119 template<typename _A2, typename _PtrT>
120 struct _Diff<_A2, _PtrT, __void_t<typename _A2::difference_type>>
121 { using type = typename _A2::difference_type; };
122
123 // Select _A2::size_type or make_unsigned<_DiffT>::type
124 template<typename _A2, typename _DiffT, typename = void>
125 struct _Size : make_unsigned<_DiffT> { };
126
127 template<typename _A2, typename _DiffT>
128 struct _Size<_A2, _DiffT, __void_t<typename _A2::size_type>>
129 { using type = typename _A2::size_type; };
130
131 public:
132 /**
133 * @brief The allocator's const pointer type.
134 *
135 * @c Alloc::const_pointer if that type exists, otherwise
136 * <tt> pointer_traits<pointer>::rebind<const value_type> </tt>
137 */
138 using const_pointer = typename _Ptr<__c_pointer, const value_type>::type;
139
140 /**
141 * @brief The allocator's void pointer type.
142 *
143 * @c Alloc::void_pointer if that type exists, otherwise
144 * <tt> pointer_traits<pointer>::rebind<void> </tt>
145 */
146 using void_pointer = typename _Ptr<__v_pointer, void>::type;
147
148 /**
149 * @brief The allocator's const void pointer type.
150 *
151 * @c Alloc::const_void_pointer if that type exists, otherwise
152 * <tt> pointer_traits<pointer>::rebind<const void> </tt>
153 */
154 using const_void_pointer = typename _Ptr<__cv_pointer, const void>::type;
155
156 /**
157 * @brief The allocator's difference type
158 *
159 * @c Alloc::difference_type if that type exists, otherwise
160 * <tt> pointer_traits<pointer>::difference_type </tt>
161 */
162 using difference_type = typename _Diff<_Alloc, pointer>::type;
163
164 /**
165 * @brief The allocator's size type
166 *
167 * @c Alloc::size_type if that type exists, otherwise
168 * <tt> make_unsigned<difference_type>::type </tt>
169 */
170 using size_type = typename _Size<_Alloc, difference_type>::type;
171
172 /**
173 * @brief How the allocator is propagated on copy assignment
174 *
175 * @c Alloc::propagate_on_container_copy_assignment if that type exists,
176 * otherwise @c false_type
177 */
178 using propagate_on_container_copy_assignment
179 = __detected_or_t<false_type, __pocca, _Alloc>;
180
181 /**
182 * @brief How the allocator is propagated on move assignment
183 *
184 * @c Alloc::propagate_on_container_move_assignment if that type exists,
185 * otherwise @c false_type
186 */
187 using propagate_on_container_move_assignment
188 = __detected_or_t<false_type, __pocma, _Alloc>;
189
190 /**
191 * @brief How the allocator is propagated on swap
192 *
193 * @c Alloc::propagate_on_container_swap if that type exists,
194 * otherwise @c false_type
195 */
196 using propagate_on_container_swap
197 = __detected_or_t<false_type, __pocs, _Alloc>;
198
199 /**
200 * @brief Whether all instances of the allocator type compare equal.
201 *
202 * @c Alloc::is_always_equal if that type exists,
203 * otherwise @c is_empty<Alloc>::type
204 */
205 using is_always_equal
206 = __detected_or_t<typename is_empty<_Alloc>::type, __equal, _Alloc>;
207
208 template<typename _Tp>
209 using rebind_alloc = __alloc_rebind<_Alloc, _Tp>;
210 template<typename _Tp>
211 using rebind_traits = allocator_traits<rebind_alloc<_Tp>>;
212
213 private:
214 template<typename _Alloc2>
215 static constexpr auto
216 _S_allocate(_Alloc2& __a, size_type __n, const_void_pointer __hint, int)
217 -> decltype(__a.allocate(__n, __hint))
218 { return __a.allocate(__n, __hint); }
219
220 template<typename _Alloc2>
221 static constexpr pointer
222 _S_allocate(_Alloc2& __a, size_type __n, const_void_pointer, ...)
223 { return __a.allocate(__n); }
224
225 template<typename _Tp, typename... _Args>
226 struct __construct_helper
227 {
228 template<typename _Alloc2,
229 typename = decltype(std::declval<_Alloc2*>()->construct(
230 std::declval<_Tp*>(), std::declval<_Args>()...))>
231 static true_type __test(int);
232
233 template<typename>
234 static false_type __test(...);
235
236 using type = decltype(__test<_Alloc>(0));
237 };
238
239 template<typename _Tp, typename... _Args>
240 using __has_construct
241 = typename __construct_helper<_Tp, _Args...>::type;
242
243 template<typename _Tp, typename... _Args>
244 static _GLIBCXX14_CONSTEXPRconstexpr _Require<__has_construct<_Tp, _Args...>>
245 _S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
246 noexcept(noexcept(__a.construct(__p, std::forward<_Args>(__args)...)))
247 { __a.construct(__p, std::forward<_Args>(__args)...); }
248
249 template<typename _Tp, typename... _Args>
250 static _GLIBCXX14_CONSTEXPRconstexpr
251 _Require<__and_<__not_<__has_construct<_Tp, _Args...>>,
252 is_constructible<_Tp, _Args...>>>
253 _S_construct(_Alloc&, _Tp* __p, _Args&&... __args)
254 noexcept(std::is_nothrow_constructible<_Tp, _Args...>::value)
255 {
256#if __cplusplus201703L <= 201703L
257 ::new((void*)__p) _Tp(std::forward<_Args>(__args)...);
258#else
259 std::construct_at(__p, std::forward<_Args>(__args)...);
260#endif
261 }
262
263 template<typename _Alloc2, typename _Tp>
264 static _GLIBCXX14_CONSTEXPRconstexpr auto
265 _S_destroy(_Alloc2& __a, _Tp* __p, int)
266 noexcept(noexcept(__a.destroy(__p)))
267 -> decltype(__a.destroy(__p))
268 { __a.destroy(__p); }
269
270 template<typename _Alloc2, typename _Tp>
271 static _GLIBCXX14_CONSTEXPRconstexpr void
272 _S_destroy(_Alloc2&, _Tp* __p, ...)
273 noexcept(std::is_nothrow_destructible<_Tp>::value)
274 { std::_Destroy(__p); }
275
276 template<typename _Alloc2>
277 static constexpr auto
278 _S_max_size(_Alloc2& __a, int)
279 -> decltype(__a.max_size())
280 { return __a.max_size(); }
281
282 template<typename _Alloc2>
283 static constexpr size_type
284 _S_max_size(_Alloc2&, ...)
285 {
286 // _GLIBCXX_RESOLVE_LIB_DEFECTS
287 // 2466. allocator_traits::max_size() default behavior is incorrect
288 return __gnu_cxx::__numeric_traits<size_type>::__max
289 / sizeof(value_type);
290 }
291
292 template<typename _Alloc2>
293 static constexpr auto
294 _S_select(_Alloc2& __a, int)
295 -> decltype(__a.select_on_container_copy_construction())
296 { return __a.select_on_container_copy_construction(); }
297
298 template<typename _Alloc2>
299 static constexpr _Alloc2
300 _S_select(_Alloc2& __a, ...)
301 { return __a; }
302
303 public:
304
305 /**
306 * @brief Allocate memory.
307 * @param __a An allocator.
308 * @param __n The number of objects to allocate space for.
309 *
310 * Calls @c a.allocate(n)
311 */
312 _GLIBCXX_NODISCARD[[__nodiscard__]] static _GLIBCXX20_CONSTEXPR pointer
313 allocate(_Alloc& __a, size_type __n)
314 { return __a.allocate(__n); }
315
316 /**
317 * @brief Allocate memory.
318 * @param __a An allocator.
319 * @param __n The number of objects to allocate space for.
320 * @param __hint Aid to locality.
321 * @return Memory of suitable size and alignment for @a n objects
322 * of type @c value_type
323 *
324 * Returns <tt> a.allocate(n, hint) </tt> if that expression is
325 * well-formed, otherwise returns @c a.allocate(n)
326 */
327 _GLIBCXX_NODISCARD[[__nodiscard__]] static _GLIBCXX20_CONSTEXPR pointer
328 allocate(_Alloc& __a, size_type __n, const_void_pointer __hint)
329 { return _S_allocate(__a, __n, __hint, 0); }
330
331 /**
332 * @brief Deallocate memory.
333 * @param __a An allocator.
334 * @param __p Pointer to the memory to deallocate.
335 * @param __n The number of objects space was allocated for.
336 *
337 * Calls <tt> a.deallocate(p, n) </tt>
338 */
339 static _GLIBCXX20_CONSTEXPR void
340 deallocate(_Alloc& __a, pointer __p, size_type __n)
341 { __a.deallocate(__p, __n); }
342
343 /**
344 * @brief Construct an object of type @a _Tp
345 * @param __a An allocator.
346 * @param __p Pointer to memory of suitable size and alignment for Tp
347 * @param __args Constructor arguments.
348 *
349 * Calls <tt> __a.construct(__p, std::forward<Args>(__args)...) </tt>
350 * if that expression is well-formed, otherwise uses placement-new
351 * to construct an object of type @a _Tp at location @a __p from the
352 * arguments @a __args...
353 */
354 template<typename _Tp, typename... _Args>
355 static _GLIBCXX20_CONSTEXPR auto
356 construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
357 noexcept(noexcept(_S_construct(__a, __p,
358 std::forward<_Args>(__args)...)))
359 -> decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...))
360 { _S_construct(__a, __p, std::forward<_Args>(__args)...); }
361
362 /**
363 * @brief Destroy an object of type @a _Tp
364 * @param __a An allocator.
365 * @param __p Pointer to the object to destroy
366 *
367 * Calls @c __a.destroy(__p) if that expression is well-formed,
368 * otherwise calls @c __p->~_Tp()
369 */
370 template<typename _Tp>
371 static _GLIBCXX20_CONSTEXPR void
372 destroy(_Alloc& __a, _Tp* __p)
373 noexcept(noexcept(_S_destroy(__a, __p, 0)))
374 { _S_destroy(__a, __p, 0); }
375
376 /**
377 * @brief The maximum supported allocation size
378 * @param __a An allocator.
379 * @return @c __a.max_size() or @c numeric_limits<size_type>::max()
380 *
381 * Returns @c __a.max_size() if that expression is well-formed,
382 * otherwise returns @c numeric_limits<size_type>::max()
383 */
384 static _GLIBCXX20_CONSTEXPR size_type
385 max_size(const _Alloc& __a) noexcept
386 { return _S_max_size(__a, 0); }
387
388 /**
389 * @brief Obtain an allocator to use when copying a container.
390 * @param __rhs An allocator.
391 * @return @c __rhs.select_on_container_copy_construction() or @a __rhs
392 *
393 * Returns @c __rhs.select_on_container_copy_construction() if that
394 * expression is well-formed, otherwise returns @a __rhs
395 */
396 static _GLIBCXX20_CONSTEXPR _Alloc
397 select_on_container_copy_construction(const _Alloc& __rhs)
398 { return _S_select(__rhs, 0); }
399 };
400
401#if __cplusplus201703L > 201703L
402# define __cpp_lib_constexpr_dynamic_alloc 201907L
403#endif
404
405 /// Partial specialization for std::allocator.
406 template<typename _Tp>
407 struct allocator_traits<allocator<_Tp>>
408 {
409 /// The allocator type
410 using allocator_type = allocator<_Tp>;
411
412 /// The allocated type
413 using value_type = _Tp;
414
415 /// The allocator's pointer type.
416 using pointer = _Tp*;
417
418 /// The allocator's const pointer type.
419 using const_pointer = const _Tp*;
420
421 /// The allocator's void pointer type.
422 using void_pointer = void*;
423
424 /// The allocator's const void pointer type.
425 using const_void_pointer = const void*;
426
427 /// The allocator's difference type
428 using difference_type = std::ptrdiff_t;
429
430 /// The allocator's size type
431 using size_type = std::size_t;
432
433 /// How the allocator is propagated on copy assignment
434 using propagate_on_container_copy_assignment = false_type;
435
436 /// How the allocator is propagated on move assignment
437 using propagate_on_container_move_assignment = true_type;
438
439 /// How the allocator is propagated on swap
440 using propagate_on_container_swap = false_type;
441
442 /// Whether all instances of the allocator type compare equal.
443 using is_always_equal = true_type;
444
445 template<typename _Up>
446 using rebind_alloc = allocator<_Up>;
447
448 template<typename _Up>
449 using rebind_traits = allocator_traits<allocator<_Up>>;
450
451 /**
452 * @brief Allocate memory.
453 * @param __a An allocator.
454 * @param __n The number of objects to allocate space for.
455 *
456 * Calls @c a.allocate(n)
457 */
458 _GLIBCXX_NODISCARD[[__nodiscard__]] static _GLIBCXX20_CONSTEXPR pointer
459 allocate(allocator_type& __a, size_type __n)
460 { return __a.allocate(__n); }
12
Calling 'new_allocator::allocate'
16
Returned allocated memory
461
462 /**
463 * @brief Allocate memory.
464 * @param __a An allocator.
465 * @param __n The number of objects to allocate space for.
466 * @param __hint Aid to locality.
467 * @return Memory of suitable size and alignment for @a n objects
468 * of type @c value_type
469 *
470 * Returns <tt> a.allocate(n, hint) </tt>
471 */
472 _GLIBCXX_NODISCARD[[__nodiscard__]] static _GLIBCXX20_CONSTEXPR pointer
473 allocate(allocator_type& __a, size_type __n, const_void_pointer __hint)
474 {
475#if __cplusplus201703L <= 201703L
476 return __a.allocate(__n, __hint);
477#else
478 return __a.allocate(__n);
479#endif
480 }
481
482 /**
483 * @brief Deallocate memory.
484 * @param __a An allocator.
485 * @param __p Pointer to the memory to deallocate.
486 * @param __n The number of objects space was allocated for.
487 *
488 * Calls <tt> a.deallocate(p, n) </tt>
489 */
490 static _GLIBCXX20_CONSTEXPR void
491 deallocate(allocator_type& __a, pointer __p, size_type __n)
492 { __a.deallocate(__p, __n); }
493
494 /**
495 * @brief Construct an object of type `_Up`
496 * @param __a An allocator.
497 * @param __p Pointer to memory of suitable size and alignment for
498 * an object of type `_Up`.
499 * @param __args Constructor arguments.
500 *
501 * Calls `__a.construct(__p, std::forward<_Args>(__args)...)`
502 * in C++11, C++14 and C++17. Changed in C++20 to call
503 * `std::construct_at(__p, std::forward<_Args>(__args)...)` instead.
504 */
505 template<typename _Up, typename... _Args>
506 static _GLIBCXX20_CONSTEXPR void
507 construct(allocator_type& __a __attribute__((__unused__)), _Up* __p,
508 _Args&&... __args)
509 noexcept(std::is_nothrow_constructible<_Up, _Args...>::value)
510 {
511#if __cplusplus201703L <= 201703L
512 __a.construct(__p, std::forward<_Args>(__args)...);
513#else
514 std::construct_at(__p, std::forward<_Args>(__args)...);
515#endif
516 }
517
518 /**
519 * @brief Destroy an object of type @a _Up
520 * @param __a An allocator.
521 * @param __p Pointer to the object to destroy
522 *
523 * Calls @c __a.destroy(__p).
524 */
525 template<typename _Up>
526 static _GLIBCXX20_CONSTEXPR void
527 destroy(allocator_type& __a __attribute__((__unused__)), _Up* __p)
528 noexcept(is_nothrow_destructible<_Up>::value)
529 {
530#if __cplusplus201703L <= 201703L
531 __a.destroy(__p);
532#else
533 std::destroy_at(__p);
534#endif
535 }
536
537 /**
538 * @brief The maximum supported allocation size
539 * @param __a An allocator.
540 * @return @c __a.max_size()
541 */
542 static _GLIBCXX20_CONSTEXPR size_type
543 max_size(const allocator_type& __a __attribute__((__unused__))) noexcept
544 {
545#if __cplusplus201703L <= 201703L
546 return __a.max_size();
547#else
548 return size_t(-1) / sizeof(value_type);
549#endif
550 }
551
552 /**
553 * @brief Obtain an allocator to use when copying a container.
554 * @param __rhs An allocator.
555 * @return @c __rhs
556 */
557 static _GLIBCXX20_CONSTEXPR allocator_type
558 select_on_container_copy_construction(const allocator_type& __rhs)
559 { return __rhs; }
560 };
561
562#if __cplusplus201703L < 201703L
563 template<typename _Alloc>
564 inline void
565 __do_alloc_on_copy(_Alloc& __one, const _Alloc& __two, true_type)
566 { __one = __two; }
567
568 template<typename _Alloc>
569 inline void
570 __do_alloc_on_copy(_Alloc&, const _Alloc&, false_type)
571 { }
572#endif
573
574 template<typename _Alloc>
575 _GLIBCXX14_CONSTEXPRconstexpr inline void
576 __alloc_on_copy(_Alloc& __one, const _Alloc& __two)
577 {
578 typedef allocator_traits<_Alloc> __traits;
579 typedef typename __traits::propagate_on_container_copy_assignment __pocca;
580#if __cplusplus201703L >= 201703L
581 if constexpr (__pocca::value)
582 __one = __two;
583#else
584 __do_alloc_on_copy(__one, __two, __pocca());
585#endif
586 }
587
588 template<typename _Alloc>
589 constexpr _Alloc
590 __alloc_on_copy(const _Alloc& __a)
591 {
592 typedef allocator_traits<_Alloc> __traits;
593 return __traits::select_on_container_copy_construction(__a);
594 }
595
596#if __cplusplus201703L < 201703L
597 template<typename _Alloc>
598 inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two, true_type)
599 { __one = std::move(__two); }
600
601 template<typename _Alloc>
602 inline void __do_alloc_on_move(_Alloc&, _Alloc&, false_type)
603 { }
604#endif
605
606 template<typename _Alloc>
607 _GLIBCXX14_CONSTEXPRconstexpr inline void
608 __alloc_on_move(_Alloc& __one, _Alloc& __two)
609 {
610 typedef allocator_traits<_Alloc> __traits;
611 typedef typename __traits::propagate_on_container_move_assignment __pocma;
612#if __cplusplus201703L >= 201703L
613 if constexpr (__pocma::value)
614 __one = std::move(__two);
615#else
616 __do_alloc_on_move(__one, __two, __pocma());
617#endif
618 }
619
620#if __cplusplus201703L < 201703L
621 template<typename _Alloc>
622 inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two, true_type)
623 {
624 using std::swap;
625 swap(__one, __two);
626 }
627
628 template<typename _Alloc>
629 inline void __do_alloc_on_swap(_Alloc&, _Alloc&, false_type)
630 { }
631#endif
632
633 template<typename _Alloc>
634 _GLIBCXX14_CONSTEXPRconstexpr inline void
635 __alloc_on_swap(_Alloc& __one, _Alloc& __two)
636 {
637 typedef allocator_traits<_Alloc> __traits;
638 typedef typename __traits::propagate_on_container_swap __pocs;
639#if __cplusplus201703L >= 201703L
640 if constexpr (__pocs::value)
641 {
642 using std::swap;
643 swap(__one, __two);
644 }
645#else
646 __do_alloc_on_swap(__one, __two, __pocs());
647#endif
648 }
649
650 template<typename _Alloc, typename _Tp,
651 typename _ValueT = __remove_cvref_t<typename _Alloc::value_type>,
652 typename = void>
653 struct __is_alloc_insertable_impl
654 : false_type
655 { };
656
657 template<typename _Alloc, typename _Tp, typename _ValueT>
658 struct __is_alloc_insertable_impl<_Alloc, _Tp, _ValueT,
659 __void_t<decltype(allocator_traits<_Alloc>::construct(
660 std::declval<_Alloc&>(), std::declval<_ValueT*>(),
661 std::declval<_Tp>()))>>
662 : true_type
663 { };
664
665 // true if _Alloc::value_type is CopyInsertable into containers using _Alloc
666 // (might be wrong if _Alloc::construct exists but is not constrained,
667 // i.e. actually trying to use it would still be invalid. Use with caution.)
668 template<typename _Alloc>
669 struct __is_copy_insertable
670 : __is_alloc_insertable_impl<_Alloc,
671 typename _Alloc::value_type const&>::type
672 { };
673
674 // std::allocator<_Tp> just requires CopyConstructible
675 template<typename _Tp>
676 struct __is_copy_insertable<allocator<_Tp>>
677 : is_copy_constructible<_Tp>
678 { };
679
680 // true if _Alloc::value_type is MoveInsertable into containers using _Alloc
681 // (might be wrong if _Alloc::construct exists but is not constrained,
682 // i.e. actually trying to use it would still be invalid. Use with caution.)
683 template<typename _Alloc>
684 struct __is_move_insertable
685 : __is_alloc_insertable_impl<_Alloc, typename _Alloc::value_type>::type
686 { };
687
688 // std::allocator<_Tp> just requires MoveConstructible
689 template<typename _Tp>
690 struct __is_move_insertable<allocator<_Tp>>
691 : is_move_constructible<_Tp>
692 { };
693
694 // Trait to detect Allocator-like types.
695 template<typename _Alloc, typename = void>
696 struct __is_allocator : false_type { };
697
698 template<typename _Alloc>
699 struct __is_allocator<_Alloc,
700 __void_t<typename _Alloc::value_type,
701 decltype(std::declval<_Alloc&>().allocate(size_t{}))>>
702 : true_type { };
703
704 template<typename _Alloc>
705 using _RequireAllocator
706 = typename enable_if<__is_allocator<_Alloc>::value, _Alloc>::type;
707
708 template<typename _Alloc>
709 using _RequireNotAllocator
710 = typename enable_if<!__is_allocator<_Alloc>::value, _Alloc>::type;
711#endif // C++11
712
713 /**
714 * Destroy a range of objects using the supplied allocator. For
715 * non-default allocators we do not optimize away invocation of
716 * destroy() even if _Tp has a trivial destructor.
717 */
718
719 template<typename _ForwardIterator, typename _Allocator>
720 void
721 _Destroy(_ForwardIterator __first, _ForwardIterator __last,
722 _Allocator& __alloc)
723 {
724 for (; __first != __last; ++__first)
725#if __cplusplus201703L < 201103L
726 __alloc.destroy(std::__addressof(*__first));
727#else
728 allocator_traits<_Allocator>::destroy(__alloc,
729 std::__addressof(*__first));
730#endif
731 }
732
733 template<typename _ForwardIterator, typename _Tp>
734 inline void
735 _Destroy(_ForwardIterator __first, _ForwardIterator __last,
736 allocator<_Tp>&)
737 {
738 _Destroy(__first, __last);
739 }
740
741_GLIBCXX_END_NAMESPACE_VERSION
742} // namespace std
743#endif // _ALLOC_TRAITS_H

/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/ext/new_allocator.h

1// Allocator that wraps operator new -*- C++ -*-
2
3// Copyright (C) 2001-2020 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 ext/new_allocator.h
26 * This file is a GNU extension to the Standard C++ Library.
27 */
28
29#ifndef _NEW_ALLOCATOR_H1
30#define _NEW_ALLOCATOR_H1 1
31
32#include <bits/c++config.h>
33#include <new>
34#include <bits/functexcept.h>
35#include <bits/move.h>
36#if __cplusplus201703L >= 201103L
37#include <type_traits>
38#endif
39
40namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
41{
42_GLIBCXX_BEGIN_NAMESPACE_VERSION
43
44 /**
45 * @brief An allocator that uses global new, as per [20.4].
46 * @ingroup allocators
47 *
48 * This is precisely the allocator defined in the C++ Standard.
49 * - all allocation calls operator new
50 * - all deallocation calls operator delete
51 *
52 * @tparam _Tp Type of allocated object.
53 */
54 template<typename _Tp>
55 class new_allocator
56 {
57 public:
58 typedef _Tp value_type;
59 typedef std::size_t size_type;
60 typedef std::ptrdiff_t difference_type;
61#if __cplusplus201703L <= 201703L
62 typedef _Tp* pointer;
63 typedef const _Tp* const_pointer;
64 typedef _Tp& reference;
65 typedef const _Tp& const_reference;
66
67 template<typename _Tp1>
68 struct rebind
69 { typedef new_allocator<_Tp1> other; };
70#endif
71
72#if __cplusplus201703L >= 201103L
73 // _GLIBCXX_RESOLVE_LIB_DEFECTS
74 // 2103. propagate_on_container_move_assignment
75 typedef std::true_type propagate_on_container_move_assignment;
76#endif
77
78 _GLIBCXX20_CONSTEXPR
79 new_allocator() _GLIBCXX_USE_NOEXCEPTnoexcept { }
80
81 _GLIBCXX20_CONSTEXPR
82 new_allocator(const new_allocator&) _GLIBCXX_USE_NOEXCEPTnoexcept { }
83
84 template<typename _Tp1>
85 _GLIBCXX20_CONSTEXPR
86 new_allocator(const new_allocator<_Tp1>&) _GLIBCXX_USE_NOEXCEPTnoexcept { }
87
88#if __cplusplus201703L <= 201703L
89 ~new_allocator() _GLIBCXX_USE_NOEXCEPTnoexcept { }
90
91 pointer
92 address(reference __x) const _GLIBCXX_NOEXCEPTnoexcept
93 { return std::__addressof(__x); }
94
95 const_pointer
96 address(const_reference __x) const _GLIBCXX_NOEXCEPTnoexcept
97 { return std::__addressof(__x); }
98#endif
99
100 // NB: __n is permitted to be 0. The C++ standard says nothing
101 // about what the return value is when __n == 0.
102 _GLIBCXX_NODISCARD[[__nodiscard__]] _Tp*
103 allocate(size_type __n, const void* = static_cast<const void*>(0))
104 {
105 if (__n > this->_M_max_size())
13
Taking false branch
106 std::__throw_bad_alloc();
107
108#if __cpp_aligned_new201606L
109 if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__16UL)
14
Taking false branch
110 {
111 std::align_val_t __al = std::align_val_t(alignof(_Tp));
112 return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), __al));
113 }
114#endif
115 return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
15
Memory is allocated
116 }
117
118 // __p is not permitted to be a null pointer.
119 void
120 deallocate(_Tp* __p, size_type __t)
121 {
122#if __cpp_aligned_new201606L
123 if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__16UL)
124 {
125 ::operator delete(__p,
126# if __cpp_sized_deallocation
127 __t * sizeof(_Tp),
128# endif
129 std::align_val_t(alignof(_Tp)));
130 return;
131 }
132#endif
133 ::operator delete(__p
134#if __cpp_sized_deallocation
135 , __t * sizeof(_Tp)
136#endif
137 );
138 }
139
140#if __cplusplus201703L <= 201703L
141 size_type
142 max_size() const _GLIBCXX_USE_NOEXCEPTnoexcept
143 { return _M_max_size(); }
144
145#if __cplusplus201703L >= 201103L
146 template<typename _Up, typename... _Args>
147 void
148 construct(_Up* __p, _Args&&... __args)
149 noexcept(std::is_nothrow_constructible<_Up, _Args...>::value)
150 { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
151
152 template<typename _Up>
153 void
154 destroy(_Up* __p)
155 noexcept(std::is_nothrow_destructible<_Up>::value)
156 { __p->~_Up(); }
157#else
158 // _GLIBCXX_RESOLVE_LIB_DEFECTS
159 // 402. wrong new expression in [some_] allocator::construct
160 void
161 construct(pointer __p, const _Tp& __val)
162 { ::new((void *)__p) _Tp(__val); }
163
164 void
165 destroy(pointer __p) { __p->~_Tp(); }
166#endif
167#endif // ! C++20
168
169 template<typename _Up>
170 friend _GLIBCXX20_CONSTEXPR bool
171 operator==(const new_allocator&, const new_allocator<_Up>&)
172 _GLIBCXX_NOTHROWnoexcept
173 { return true; }
174
175#if __cpp_impl_three_way_comparison < 201907L
176 template<typename _Up>
177 friend _GLIBCXX20_CONSTEXPR bool
178 operator!=(const new_allocator&, const new_allocator<_Up>&)
179 _GLIBCXX_NOTHROWnoexcept
180 { return false; }
181#endif
182
183 private:
184 _GLIBCXX_CONSTEXPRconstexpr size_type
185 _M_max_size() const _GLIBCXX_USE_NOEXCEPTnoexcept
186 {
187#if __PTRDIFF_MAX__9223372036854775807L < __SIZE_MAX__18446744073709551615UL
188 return std::size_t(__PTRDIFF_MAX__9223372036854775807L) / sizeof(_Tp);
189#else
190 return std::size_t(-1) / sizeof(_Tp);
191#endif
192 }
193 };
194
195_GLIBCXX_END_NAMESPACE_VERSION
196} // namespace
197
198#endif

/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.h

1// Components for manipulating sequences of characters -*- C++ -*-
2
3// Copyright (C) 1997-2020 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/atomicity.h>
40#include <ext/alloc_traits.h>
41#include <debug/debug.h>
42
43#if __cplusplus201703L >= 201103L
44#include <initializer_list>
45#endif
46
47#if __cplusplus201703L >= 201703L
48# include <string_view>
49#endif
50
51
52namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
53{
54_GLIBCXX_BEGIN_NAMESPACE_VERSION
55
56#if _GLIBCXX_USE_CXX11_ABI1
57_GLIBCXX_BEGIN_NAMESPACE_CXX11namespace __cxx11 {
58 /**
59 * @class basic_string basic_string.h <string>
60 * @brief Managing sequences of characters and character-like objects.
61 *
62 * @ingroup strings
63 * @ingroup sequences
64 *
65 * @tparam _CharT Type of character
66 * @tparam _Traits Traits for character type, defaults to
67 * char_traits<_CharT>.
68 * @tparam _Alloc Allocator type, defaults to allocator<_CharT>.
69 *
70 * Meets the requirements of a <a href="tables.html#65">container</a>, a
71 * <a href="tables.html#66">reversible container</a>, and a
72 * <a href="tables.html#67">sequence</a>. Of the
73 * <a href="tables.html#68">optional sequence requirements</a>, only
74 * @c push_back, @c at, and @c %array access are supported.
75 */
76 template<typename _CharT, typename _Traits, typename _Alloc>
77 class basic_string
78 {
79 typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
80 rebind<_CharT>::other _Char_alloc_type;
81 typedef __gnu_cxx::__alloc_traits<_Char_alloc_type> _Alloc_traits;
82
83 // Types:
84 public:
85 typedef _Traits traits_type;
86 typedef typename _Traits::char_type value_type;
87 typedef _Char_alloc_type allocator_type;
88 typedef typename _Alloc_traits::size_type size_type;
89 typedef typename _Alloc_traits::difference_type difference_type;
90 typedef typename _Alloc_traits::reference reference;
91 typedef typename _Alloc_traits::const_reference const_reference;
92 typedef typename _Alloc_traits::pointer pointer;
93 typedef typename _Alloc_traits::const_pointer const_pointer;
94 typedef __gnu_cxx::__normal_iterator<pointer, basic_string> iterator;
95 typedef __gnu_cxx::__normal_iterator<const_pointer, basic_string>
96 const_iterator;
97 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
98 typedef std::reverse_iterator<iterator> reverse_iterator;
99
100 /// Value returned by various member functions when they fail.
101 static const size_type npos = static_cast<size_type>(-1);
102
103 protected:
104 // type used for positions in insert, erase etc.
105#if __cplusplus201703L < 201103L
106 typedef iterator __const_iterator;
107#else
108 typedef const_iterator __const_iterator;
109#endif
110
111 private:
112#if __cplusplus201703L >= 201703L
113 // A helper type for avoiding boiler-plate.
114 typedef basic_string_view<_CharT, _Traits> __sv_type;
115
116 template<typename _Tp, typename _Res>
117 using _If_sv = enable_if_t<
118 __and_<is_convertible<const _Tp&, __sv_type>,
119 __not_<is_convertible<const _Tp*, const basic_string*>>,
120 __not_<is_convertible<const _Tp&, const _CharT*>>>::value,
121 _Res>;
122
123 // Allows an implicit conversion to __sv_type.
124 static __sv_type
125 _S_to_string_view(__sv_type __svt) noexcept
126 { return __svt; }
127
128 // Wraps a string_view by explicit conversion and thus
129 // allows to add an internal constructor that does not
130 // participate in overload resolution when a string_view
131 // is provided.
132 struct __sv_wrapper
133 {
134 explicit __sv_wrapper(__sv_type __sv) noexcept : _M_sv(__sv) { }
135 __sv_type _M_sv;
136 };
137
138 /**
139 * @brief Only internally used: Construct string from a string view
140 * wrapper.
141 * @param __svw string view wrapper.
142 * @param __a Allocator to use.
143 */
144 explicit
145 basic_string(__sv_wrapper __svw, const _Alloc& __a)
146 : basic_string(__svw._M_sv.data(), __svw._M_sv.size(), __a) { }
147#endif
148
149 // Use empty-base optimization: http://www.cantrip.org/emptyopt.html
150 struct _Alloc_hider : allocator_type // TODO check __is_final
151 {
152#if __cplusplus201703L < 201103L
153 _Alloc_hider(pointer __dat, const _Alloc& __a = _Alloc())
154 : allocator_type(__a), _M_p(__dat) { }
155#else
156 _Alloc_hider(pointer __dat, const _Alloc& __a)
157 : allocator_type(__a), _M_p(__dat) { }
158
159 _Alloc_hider(pointer __dat, _Alloc&& __a = _Alloc())
160 : allocator_type(std::move(__a)), _M_p(__dat) { }
161#endif
162
163 pointer _M_p; // The actual data.
164 };
165
166 _Alloc_hider _M_dataplus;
167 size_type _M_string_length;
168
169 enum { _S_local_capacity = 15 / sizeof(_CharT) };
170
171 union
172 {
173 _CharT _M_local_buf[_S_local_capacity + 1];
174 size_type _M_allocated_capacity;
175 };
176
177 void
178 _M_data(pointer __p)
179 { _M_dataplus._M_p = __p; }
180
181 void
182 _M_length(size_type __length)
183 { _M_string_length = __length; }
184
185 pointer
186 _M_data() const
187 { return _M_dataplus._M_p; }
188
189 pointer
190 _M_local_data()
191 {
192#if __cplusplus201703L >= 201103L
193 return std::pointer_traits<pointer>::pointer_to(*_M_local_buf);
194#else
195 return pointer(_M_local_buf);
196#endif
197 }
198
199 const_pointer
200 _M_local_data() const
201 {
202#if __cplusplus201703L >= 201103L
203 return std::pointer_traits<const_pointer>::pointer_to(*_M_local_buf);
204#else
205 return const_pointer(_M_local_buf);
206#endif
207 }
208
209 void
210 _M_capacity(size_type __capacity)
211 { _M_allocated_capacity = __capacity; }
212
213 void
214 _M_set_length(size_type __n)
215 {
216 _M_length(__n);
217 traits_type::assign(_M_data()[__n], _CharT());
218 }
219
220 bool
221 _M_is_local() const
222 { return _M_data() == _M_local_data(); }
223
224 // Create & Destroy
225 pointer
226 _M_create(size_type&, size_type);
227
228 void
229 _M_dispose()
230 {
231 if (!_M_is_local())
232 _M_destroy(_M_allocated_capacity);
233 }
234
235 void
236 _M_destroy(size_type __size) throw()
237 { _Alloc_traits::deallocate(_M_get_allocator(), _M_data(), __size + 1); }
238
239 // _M_construct_aux is used to implement the 21.3.1 para 15 which
240 // requires special behaviour if _InIterator is an integral type
241 template<typename _InIterator>
242 void
243 _M_construct_aux(_InIterator __beg, _InIterator __end,
244 std::__false_type)
245 {
246 typedef typename iterator_traits<_InIterator>::iterator_category _Tag;
247 _M_construct(__beg, __end, _Tag());
248 }
249
250 // _GLIBCXX_RESOLVE_LIB_DEFECTS
251 // 438. Ambiguity in the "do the right thing" clause
252 template<typename _Integer>
253 void
254 _M_construct_aux(_Integer __beg, _Integer __end, std::__true_type)
255 { _M_construct_aux_2(static_cast<size_type>(__beg), __end); }
256
257 void
258 _M_construct_aux_2(size_type __req, _CharT __c)
259 { _M_construct(__req, __c); }
260
261 template<typename _InIterator>
262 void
263 _M_construct(_InIterator __beg, _InIterator __end)
264 {
265 typedef typename std::__is_integer<_InIterator>::__type _Integral;
266 _M_construct_aux(__beg, __end, _Integral());
267 }
268
269 // For Input Iterators, used in istreambuf_iterators, etc.
270 template<typename _InIterator>
271 void
272 _M_construct(_InIterator __beg, _InIterator __end,
273 std::input_iterator_tag);
274
275 // For forward_iterators up to random_access_iterators, used for
276 // string::iterator, _CharT*, etc.
277 template<typename _FwdIterator>
278 void
279 _M_construct(_FwdIterator __beg, _FwdIterator __end,
280 std::forward_iterator_tag);
281
282 void
283 _M_construct(size_type __req, _CharT __c);
284
285 allocator_type&
286 _M_get_allocator()
287 { return _M_dataplus; }
288
289 const allocator_type&
290 _M_get_allocator() const
291 { return _M_dataplus; }
292
293 private:
294
295#ifdef _GLIBCXX_DISAMBIGUATE_REPLACE_INST
296 // The explicit instantiations in misc-inst.cc require this due to
297 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64063
298 template<typename _Tp, bool _Requires =
299 !__are_same<_Tp, _CharT*>::__value
300 && !__are_same<_Tp, const _CharT*>::__value
301 && !__are_same<_Tp, iterator>::__value
302 && !__are_same<_Tp, const_iterator>::__value>
303 struct __enable_if_not_native_iterator
304 { typedef basic_string& __type; };
305 template<typename _Tp>
306 struct __enable_if_not_native_iterator<_Tp, false> { };
307#endif
308
309 size_type
310 _M_check(size_type __pos, const char* __s) const
311 {
312 if (__pos > this->size())
313 __throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > "("%s: __pos (which is %zu) > " "this->size() (which is %zu)"
)
314 "this->size() (which is %zu)")("%s: __pos (which is %zu) > " "this->size() (which is %zu)"
)
,
315 __s, __pos, this->size());
316 return __pos;
317 }
318
319 void
320 _M_check_length(size_type __n1, size_type __n2, const char* __s) const
321 {
322 if (this->max_size() - (this->size() - __n1) < __n2)
323 __throw_length_error(__N(__s)(__s));
324 }
325
326
327 // NB: _M_limit doesn't check for a bad __pos value.
328 size_type
329 _M_limit(size_type __pos, size_type __off) const _GLIBCXX_NOEXCEPTnoexcept
330 {
331 const bool __testoff = __off < this->size() - __pos;
332 return __testoff ? __off : this->size() - __pos;
333 }
334
335 // True if _Rep and source do not overlap.
336 bool
337 _M_disjunct(const _CharT* __s) const _GLIBCXX_NOEXCEPTnoexcept
338 {
339 return (less<const _CharT*>()(__s, _M_data())
340 || less<const _CharT*>()(_M_data() + this->size(), __s));
341 }
342
343 // When __n = 1 way faster than the general multichar
344 // traits_type::copy/move/assign.
345 static void
346 _S_copy(_CharT* __d, const _CharT* __s, size_type __n)
347 {
348 if (__n == 1)
349 traits_type::assign(*__d, *__s);
350 else
351 traits_type::copy(__d, __s, __n);
352 }
353
354 static void
355 _S_move(_CharT* __d, const _CharT* __s, size_type __n)
356 {
357 if (__n == 1)
358 traits_type::assign(*__d, *__s);
359 else
360 traits_type::move(__d, __s, __n);
361 }
362
363 static void
364 _S_assign(_CharT* __d, size_type __n, _CharT __c)
365 {
366 if (__n == 1)
367 traits_type::assign(*__d, __c);
368 else
369 traits_type::assign(__d, __n, __c);
370 }
371
372 // _S_copy_chars is a separate template to permit specialization
373 // to optimize for the common case of pointers as iterators.
374 template<class _Iterator>
375 static void
376 _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2)
377 {
378 for (; __k1 != __k2; ++__k1, (void)++__p)
379 traits_type::assign(*__p, *__k1); // These types are off.
380 }
381
382 static void
383 _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2) _GLIBCXX_NOEXCEPTnoexcept
384 { _S_copy_chars(__p, __k1.base(), __k2.base()); }
385
386 static void
387 _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2)
388 _GLIBCXX_NOEXCEPTnoexcept
389 { _S_copy_chars(__p, __k1.base(), __k2.base()); }
390
391 static void
392 _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) _GLIBCXX_NOEXCEPTnoexcept
393 { _S_copy(__p, __k1, __k2 - __k1); }
394
395 static void
396 _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2)
397 _GLIBCXX_NOEXCEPTnoexcept
398 { _S_copy(__p, __k1, __k2 - __k1); }
399
400 static int
401 _S_compare(size_type __n1, size_type __n2) _GLIBCXX_NOEXCEPTnoexcept
402 {
403 const difference_type __d = difference_type(__n1 - __n2);
404
405 if (__d > __gnu_cxx::__numeric_traits<int>::__max)
406 return __gnu_cxx::__numeric_traits<int>::__max;
407 else if (__d < __gnu_cxx::__numeric_traits<int>::__min)
408 return __gnu_cxx::__numeric_traits<int>::__min;
409 else
410 return int(__d);
411 }
412
413 void
414 _M_assign(const basic_string&);
415
416 void
417 _M_mutate(size_type __pos, size_type __len1, const _CharT* __s,
418 size_type __len2);
419
420 void
421 _M_erase(size_type __pos, size_type __n);
422
423 public:
424 // Construct/copy/destroy:
425 // NB: We overload ctors in some cases instead of using default
426 // arguments, per 17.4.4.4 para. 2 item 2.
427
428 /**
429 * @brief Default constructor creates an empty string.
430 */
431 basic_string()
432 _GLIBCXX_NOEXCEPT_IF(is_nothrow_default_constructible<_Alloc>::value)noexcept(is_nothrow_default_constructible<_Alloc>::value
)
433 : _M_dataplus(_M_local_data())
434 { _M_set_length(0); }
435
436 /**
437 * @brief Construct an empty string using allocator @a a.
438 */
439 explicit
440 basic_string(const _Alloc& __a) _GLIBCXX_NOEXCEPTnoexcept
441 : _M_dataplus(_M_local_data(), __a)
442 { _M_set_length(0); }
443
444 /**
445 * @brief Construct string with copy of value of @a __str.
446 * @param __str Source string.
447 */
448 basic_string(const basic_string& __str)
449 : _M_dataplus(_M_local_data(),
450 _Alloc_traits::_S_select_on_copy(__str._M_get_allocator()))
451 { _M_construct(__str._M_data(), __str._M_data() + __str.length()); }
452
453 // _GLIBCXX_RESOLVE_LIB_DEFECTS
454 // 2583. no way to supply an allocator for basic_string(str, pos)
455 /**
456 * @brief Construct string as copy of a substring.
457 * @param __str Source string.
458 * @param __pos Index of first character to copy from.
459 * @param __a Allocator to use.
460 */
461 basic_string(const basic_string& __str, size_type __pos,
462 const _Alloc& __a = _Alloc())
463 : _M_dataplus(_M_local_data(), __a)
464 {
465 const _CharT* __start = __str._M_data()
466 + __str._M_check(__pos, "basic_string::basic_string");
467 _M_construct(__start, __start + __str._M_limit(__pos, npos));
468 }
469
470 /**
471 * @brief Construct string as copy of a substring.
472 * @param __str Source string.
473 * @param __pos Index of first character to copy from.
474 * @param __n Number of characters to copy.
475 */
476 basic_string(const basic_string& __str, size_type __pos,
477 size_type __n)
478 : _M_dataplus(_M_local_data())
479 {
480 const _CharT* __start = __str._M_data()
481 + __str._M_check(__pos, "basic_string::basic_string");
482 _M_construct(__start, __start + __str._M_limit(__pos, __n));
483 }
484
485 /**
486 * @brief Construct string as copy of a substring.
487 * @param __str Source string.
488 * @param __pos Index of first character to copy from.
489 * @param __n Number of characters to copy.
490 * @param __a Allocator to use.
491 */
492 basic_string(const basic_string& __str, size_type __pos,
493 size_type __n, const _Alloc& __a)
494 : _M_dataplus(_M_local_data(), __a)
495 {
496 const _CharT* __start
497 = __str._M_data() + __str._M_check(__pos, "string::string");
498 _M_construct(__start, __start + __str._M_limit(__pos, __n));
499 }
500
501 /**
502 * @brief Construct string initialized by a character %array.
503 * @param __s Source character %array.
504 * @param __n Number of characters to copy.
505 * @param __a Allocator to use (default is default allocator).
506 *
507 * NB: @a __s must have at least @a __n characters, &apos;\\0&apos;
508 * has no special meaning.
509 */
510 basic_string(const _CharT* __s, size_type __n,
511 const _Alloc& __a = _Alloc())
512 : _M_dataplus(_M_local_data(), __a)
513 { _M_construct(__s, __s + __n); }
514
515 /**
516 * @brief Construct string as copy of a C string.
517 * @param __s Source C string.
518 * @param __a Allocator to use (default is default allocator).
519 */
520#if __cpp_deduction_guides201703L && ! defined _GLIBCXX_DEFINING_STRING_INSTANTIATIONS
521 // _GLIBCXX_RESOLVE_LIB_DEFECTS
522 // 3076. basic_string CTAD ambiguity
523 template<typename = _RequireAllocator<_Alloc>>
524#endif
525 basic_string(const _CharT* __s, const _Alloc& __a = _Alloc())
526 : _M_dataplus(_M_local_data(), __a)
527 { _M_construct(__s, __s ? __s + traits_type::length(__s) : __s+npos); }
528
529 /**
530 * @brief Construct string as multiple characters.
531 * @param __n Number of characters.
532 * @param __c Character to use.
533 * @param __a Allocator to use (default is default allocator).
534 */
535#if __cpp_deduction_guides201703L && ! defined _GLIBCXX_DEFINING_STRING_INSTANTIATIONS
536 // _GLIBCXX_RESOLVE_LIB_DEFECTS
537 // 3076. basic_string CTAD ambiguity
538 template<typename = _RequireAllocator<_Alloc>>
539#endif
540 basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc())
541 : _M_dataplus(_M_local_data(), __a)
542 { _M_construct(__n, __c); }
543
544#if __cplusplus201703L >= 201103L
545 /**
546 * @brief Move construct string.
547 * @param __str Source string.
548 *
549 * The newly-created string contains the exact contents of @a __str.
550 * @a __str is a valid, but unspecified string.
551 **/
552 basic_string(basic_string&& __str) noexcept
553 : _M_dataplus(_M_local_data(), std::move(__str._M_get_allocator()))
554 {
555 if (__str._M_is_local())
556 {
557 traits_type::copy(_M_local_buf, __str._M_local_buf,
558 _S_local_capacity + 1);
559 }
560 else
561 {
562 _M_data(__str._M_data());
563 _M_capacity(__str._M_allocated_capacity);
564 }
565
566 // Must use _M_length() here not _M_set_length() because
567 // basic_stringbuf relies on writing into unallocated capacity so
568 // we mess up the contents if we put a '\0' in the string.
569 _M_length(__str.length());
570 __str._M_data(__str._M_local_data());
571 __str._M_set_length(0);
572 }
573
574 /**
575 * @brief Construct string from an initializer %list.
576 * @param __l std::initializer_list of characters.
577 * @param __a Allocator to use (default is default allocator).
578 */
579 basic_string(initializer_list<_CharT> __l, const _Alloc& __a = _Alloc())
580 : _M_dataplus(_M_local_data(), __a)
581 { _M_construct(__l.begin(), __l.end()); }
582
583 basic_string(const basic_string& __str, const _Alloc& __a)
584 : _M_dataplus(_M_local_data(), __a)
585 { _M_construct(__str.begin(), __str.end()); }
586
587 basic_string(basic_string&& __str, const _Alloc& __a)
588 noexcept(_Alloc_traits::_S_always_equal())
589 : _M_dataplus(_M_local_data(), __a)
590 {
591 if (__str._M_is_local())
592 {
593 traits_type::copy(_M_local_buf, __str._M_local_buf,
594 _S_local_capacity + 1);
595 _M_length(__str.length());
596 __str._M_set_length(0);
597 }
598 else if (_Alloc_traits::_S_always_equal()
599 || __str.get_allocator() == __a)
600 {
601 _M_data(__str._M_data());
602 _M_length(__str.length());
603 _M_capacity(__str._M_allocated_capacity);
604 __str._M_data(__str._M_local_buf);
605 __str._M_set_length(0);
606 }
607 else
608 _M_construct(__str.begin(), __str.end());
609 }
610
611#endif // C++11
612
613 /**
614 * @brief Construct string as copy of a range.
615 * @param __beg Start of range.
616 * @param __end End of range.
617 * @param __a Allocator to use (default is default allocator).
618 */
619#if __cplusplus201703L >= 201103L
620 template<typename _InputIterator,
621 typename = std::_RequireInputIter<_InputIterator>>
622#else
623 template<typename _InputIterator>
624#endif
625 basic_string(_InputIterator __beg, _InputIterator __end,
626 const _Alloc& __a = _Alloc())
627 : _M_dataplus(_M_local_data(), __a)
628 { _M_construct(__beg, __end); }
629
630#if __cplusplus201703L >= 201703L
631 /**
632 * @brief Construct string from a substring of a string_view.
633 * @param __t Source object convertible to string view.
634 * @param __pos The index of the first character to copy from __t.
635 * @param __n The number of characters to copy from __t.
636 * @param __a Allocator to use.
637 */
638 template<typename _Tp, typename = _If_sv<_Tp, void>>
639 basic_string(const _Tp& __t, size_type __pos, size_type __n,
640 const _Alloc& __a = _Alloc())
641 : basic_string(_S_to_string_view(__t).substr(__pos, __n), __a) { }
642
643 /**
644 * @brief Construct string from a string_view.
645 * @param __t Source object convertible to string view.
646 * @param __a Allocator to use (default is default allocator).
647 */
648 template<typename _Tp, typename = _If_sv<_Tp, void>>
649 explicit
650 basic_string(const _Tp& __t, const _Alloc& __a = _Alloc())
651 : basic_string(__sv_wrapper(_S_to_string_view(__t)), __a) { }
652#endif // C++17
653
654 /**
655 * @brief Destroy the string instance.
656 */
657 ~basic_string()
658 { _M_dispose(); }
659
660 /**
661 * @brief Assign the value of @a str to this string.
662 * @param __str Source string.
663 */
664 basic_string&
665 operator=(const basic_string& __str)
666 {
667 return this->assign(__str);
668 }
669
670 /**
671 * @brief Copy contents of @a s into this string.
672 * @param __s Source null-terminated string.
673 */
674 basic_string&
675 operator=(const _CharT* __s)
676 { return this->assign(__s); }
677
678 /**
679 * @brief Set value to string of length 1.
680 * @param __c Source character.
681 *
682 * Assigning to a character makes this string length 1 and
683 * (*this)[0] == @a c.
684 */
685 basic_string&
686 operator=(_CharT __c)
687 {
688 this->assign(1, __c);
689 return *this;
690 }
691
692#if __cplusplus201703L >= 201103L
693 /**
694 * @brief Move assign the value of @a str to this string.
695 * @param __str Source string.
696 *
697 * The contents of @a str are moved into this string (without copying).
698 * @a str is a valid, but unspecified string.
699 **/
700 // _GLIBCXX_RESOLVE_LIB_DEFECTS
701 // 2063. Contradictory requirements for string move assignment
702 basic_string&
703 operator=(basic_string&& __str)
704 noexcept(_Alloc_traits::_S_nothrow_move())
705 {
706 if (!_M_is_local() && _Alloc_traits::_S_propagate_on_move_assign()
707 && !_Alloc_traits::_S_always_equal()
708 && _M_get_allocator() != __str._M_get_allocator())
709 {
710 // Destroy existing storage before replacing allocator.
711 _M_destroy(_M_allocated_capacity);
712 _M_data(_M_local_data());
713 _M_set_length(0);
714 }
715 // Replace allocator if POCMA is true.
716 std::__alloc_on_move(_M_get_allocator(), __str._M_get_allocator());
717
718 if (__str._M_is_local())
719 {
720 // We've always got room for a short string, just copy it.
721 if (__str.size())
722 this->_S_copy(_M_data(), __str._M_data(), __str.size());
723 _M_set_length(__str.size());
724 }
725 else if (_Alloc_traits::_S_propagate_on_move_assign()
726 || _Alloc_traits::_S_always_equal()
727 || _M_get_allocator() == __str._M_get_allocator())
728 {
729 // Just move the allocated pointer, our allocator can free it.
730 pointer __data = nullptr;
731 size_type __capacity;
732 if (!_M_is_local())
733 {
734 if (_Alloc_traits::_S_always_equal())
735 {
736 // __str can reuse our existing storage.
737 __data = _M_data();
738 __capacity = _M_allocated_capacity;
739 }
740 else // __str can't use it, so free it.
741 _M_destroy(_M_allocated_capacity);
742 }
743
744 _M_data(__str._M_data());
745 _M_length(__str.length());
746 _M_capacity(__str._M_allocated_capacity);
747 if (__data)
748 {
749 __str._M_data(__data);
750 __str._M_capacity(__capacity);
751 }
752 else
753 __str._M_data(__str._M_local_buf);
754 }
755 else // Need to do a deep copy
756 assign(__str);
757 __str.clear();
758 return *this;
759 }
760
761 /**
762 * @brief Set value to string constructed from initializer %list.
763 * @param __l std::initializer_list.
764 */
765 basic_string&
766 operator=(initializer_list<_CharT> __l)
767 {
768 this->assign(__l.begin(), __l.size());
769 return *this;
770 }
771#endif // C++11
772
773#if __cplusplus201703L >= 201703L
774 /**
775 * @brief Set value to string constructed from a string_view.
776 * @param __svt An object convertible to string_view.
777 */
778 template<typename _Tp>
779 _If_sv<_Tp, basic_string&>
780 operator=(const _Tp& __svt)
781 { return this->assign(__svt); }
782
783 /**
784 * @brief Convert to a string_view.
785 * @return A string_view.
786 */
787 operator __sv_type() const noexcept
788 { return __sv_type(data(), size()); }
789#endif // C++17
790
791 // Iterators:
792 /**
793 * Returns a read/write iterator that points to the first character in
794 * the %string.
795 */
796 iterator
797 begin() _GLIBCXX_NOEXCEPTnoexcept
798 { return iterator(_M_data()); }
799
800 /**
801 * Returns a read-only (constant) iterator that points to the first
802 * character in the %string.
803 */
804 const_iterator
805 begin() const _GLIBCXX_NOEXCEPTnoexcept
806 { return const_iterator(_M_data()); }
807
808 /**
809 * Returns a read/write iterator that points one past the last
810 * character in the %string.
811 */
812 iterator
813 end() _GLIBCXX_NOEXCEPTnoexcept
814 { return iterator(_M_data() + this->size()); }
815
816 /**
817 * Returns a read-only (constant) iterator that points one past the
818 * last character in the %string.
819 */
820 const_iterator
821 end() const _GLIBCXX_NOEXCEPTnoexcept
822 { return const_iterator(_M_data() + this->size()); }
823
824 /**
825 * Returns a read/write reverse iterator that points to the last
826 * character in the %string. Iteration is done in reverse element
827 * order.
828 */
829 reverse_iterator
830 rbegin() _GLIBCXX_NOEXCEPTnoexcept
831 { return reverse_iterator(this->end()); }
832
833 /**
834 * Returns a read-only (constant) reverse iterator that points
835 * to the last character in the %string. Iteration is done in
836 * reverse element order.
837 */
838 const_reverse_iterator
839 rbegin() const _GLIBCXX_NOEXCEPTnoexcept
840 { return const_reverse_iterator(this->end()); }
841
842 /**
843 * Returns a read/write reverse iterator that points to one before the
844 * first character in the %string. Iteration is done in reverse
845 * element order.
846 */
847 reverse_iterator
848 rend() _GLIBCXX_NOEXCEPTnoexcept
849 { return reverse_iterator(this->begin()); }
850
851 /**
852 * Returns a read-only (constant) reverse iterator that points
853 * to one before the first character in the %string. Iteration
854 * is done in reverse element order.
855 */
856 const_reverse_iterator
857 rend() const _GLIBCXX_NOEXCEPTnoexcept
858 { return const_reverse_iterator(this->begin()); }
859
860#if __cplusplus201703L >= 201103L
861 /**
862 * Returns a read-only (constant) iterator that points to the first
863 * character in the %string.
864 */
865 const_iterator
866 cbegin() const noexcept
867 { return const_iterator(this->_M_data()); }
868
869 /**
870 * Returns a read-only (constant) iterator that points one past the
871 * last character in the %string.
872 */
873 const_iterator
874 cend() const noexcept
875 { return const_iterator(this->_M_data() + this->size()); }
876
877 /**
878 * Returns a read-only (constant) reverse iterator that points
879 * to the last character in the %string. Iteration is done in
880 * reverse element order.
881 */
882 const_reverse_iterator
883 crbegin() const noexcept
884 { return const_reverse_iterator(this->end()); }
885
886 /**
887 * Returns a read-only (constant) reverse iterator that points
888 * to one before the first character in the %string. Iteration
889 * is done in reverse element order.
890 */
891 const_reverse_iterator
892 crend() const noexcept
893 { return const_reverse_iterator(this->begin()); }
894#endif
895
896 public:
897 // Capacity:
898 /// Returns the number of characters in the string, not including any
899 /// null-termination.
900 size_type
901 size() const _GLIBCXX_NOEXCEPTnoexcept
902 { return _M_string_length; }
903
904 /// Returns the number of characters in the string, not including any
905 /// null-termination.
906 size_type
907 length() const _GLIBCXX_NOEXCEPTnoexcept
908 { return _M_string_length; }
909
910 /// Returns the size() of the largest possible %string.
911 size_type
912 max_size() const _GLIBCXX_NOEXCEPTnoexcept
913 { return (_Alloc_traits::max_size(_M_get_allocator()) - 1) / 2; }
914
915 /**
916 * @brief Resizes the %string to the specified number of characters.
917 * @param __n Number of characters the %string should contain.
918 * @param __c Character to fill any new elements.
919 *
920 * This function will %resize the %string to the specified
921 * number of characters. If the number is smaller than the
922 * %string's current size the %string is truncated, otherwise
923 * the %string is extended and new elements are %set to @a __c.
924 */
925 void
926 resize(size_type __n, _CharT __c);
927
928 /**
929 * @brief Resizes the %string to the specified number of characters.
930 * @param __n Number of characters the %string should contain.
931 *
932 * This function will resize the %string to the specified length. If
933 * the new size is smaller than the %string's current size the %string
934 * is truncated, otherwise the %string is extended and new characters
935 * are default-constructed. For basic types such as char, this means
936 * setting them to 0.
937 */
938 void
939 resize(size_type __n)
940 { this->resize(__n, _CharT()); }
941
942#if __cplusplus201703L >= 201103L
943 /// A non-binding request to reduce capacity() to size().
944 void
945 shrink_to_fit() noexcept
946 {
947#if __cpp_exceptions
948 if (capacity() > size())
949 {
950 try
951 { reserve(0); }
952 catch(...)
953 { }
954 }
955#endif
956 }
957#endif
958
959 /**
960 * Returns the total number of characters that the %string can hold
961 * before needing to allocate more memory.
962 */
963 size_type
964 capacity() const _GLIBCXX_NOEXCEPTnoexcept
965 {
966 return _M_is_local() ? size_type(_S_local_capacity)
967 : _M_allocated_capacity;
968 }
969
970 /**
971 * @brief Attempt to preallocate enough memory for specified number of
972 * characters.
973 * @param __res_arg Number of characters required.
974 * @throw std::length_error If @a __res_arg exceeds @c max_size().
975 *
976 * This function attempts to reserve enough memory for the
977 * %string to hold the specified number of characters. If the
978 * number requested is more than max_size(), length_error is
979 * thrown.
980 *
981 * The advantage of this function is that if optimal code is a
982 * necessity and the user can determine the string length that will be
983 * required, the user can reserve the memory in %advance, and thus
984 * prevent a possible reallocation of memory and copying of %string
985 * data.
986 */
987 void
988 reserve(size_type __res_arg = 0);
989
990 /**
991 * Erases the string, making it empty.
992 */
993 void
994 clear() _GLIBCXX_NOEXCEPTnoexcept
995 { _M_set_length(0); }
996
997 /**
998 * Returns true if the %string is empty. Equivalent to
999 * <code>*this == ""</code>.
1000 */
1001 _GLIBCXX_NODISCARD[[__nodiscard__]] bool
1002 empty() const _GLIBCXX_NOEXCEPTnoexcept
1003 { return this->size() == 0; }
1004
1005 // Element access:
1006 /**
1007 * @brief Subscript access to the data contained in the %string.
1008 * @param __pos The index of the character to access.
1009 * @return Read-only (constant) reference to the character.
1010 *
1011 * This operator allows for easy, array-style, data access.
1012 * Note that data access with this operator is unchecked and
1013 * out_of_range lookups are not defined. (For checked lookups
1014 * see at().)
1015 */
1016 const_reference
1017 operator[] (size_type __pos) const _GLIBCXX_NOEXCEPTnoexcept
1018 {
1019 __glibcxx_assert(__pos <= size())do { if (! (__pos <= size())) std::__replacement_assert("/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.h"
, 1019, __PRETTY_FUNCTION__, "__pos <= size()"); } while (
false)
;
1020 return _M_data()[__pos];
1021 }
1022
1023 /**
1024 * @brief Subscript access to the data contained in the %string.
1025 * @param __pos The index of the character to access.
1026 * @return Read/write reference to the character.
1027 *
1028 * This operator allows for easy, array-style, data access.
1029 * Note that data access with this operator is unchecked and
1030 * out_of_range lookups are not defined. (For checked lookups
1031 * see at().)
1032 */
1033 reference
1034 operator[](size_type __pos)
1035 {
1036 // Allow pos == size() both in C++98 mode, as v3 extension,
1037 // and in C++11 mode.
1038 __glibcxx_assert(__pos <= size())do { if (! (__pos <= size())) std::__replacement_assert("/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.h"
, 1038, __PRETTY_FUNCTION__, "__pos <= size()"); } while (
false)
;
1039 // In pedantic mode be strict in C++98 mode.
1040 _GLIBCXX_DEBUG_PEDASSERT(__cplusplus >= 201103L || __pos < size());
1041 return _M_data()[__pos];
1042 }
1043
1044 /**
1045 * @brief Provides access to the data contained in the %string.
1046 * @param __n The index of the character to access.
1047 * @return Read-only (const) reference to the character.
1048 * @throw std::out_of_range If @a n is an invalid index.
1049 *
1050 * This function provides for safer data access. The parameter is
1051 * first checked that it is in the range of the string. The function
1052 * throws out_of_range if the check fails.
1053 */
1054 const_reference
1055 at(size_type __n) const
1056 {
1057 if (__n >= this->size())
1058 __throw_out_of_range_fmt(__N("basic_string::at: __n "("basic_string::at: __n " "(which is %zu) >= this->size() "
"(which is %zu)")
1059 "(which is %zu) >= this->size() "("basic_string::at: __n " "(which is %zu) >= this->size() "
"(which is %zu)")
1060 "(which is %zu)")("basic_string::at: __n " "(which is %zu) >= this->size() "
"(which is %zu)")
,
1061 __n, this->size());
1062 return _M_data()[__n];
1063 }
1064
1065 /**
1066 * @brief Provides access to the data contained in the %string.
1067 * @param __n The index of the character to access.
1068 * @return Read/write reference to the character.
1069 * @throw std::out_of_range If @a n is an invalid index.
1070 *
1071 * This function provides for safer data access. The parameter is
1072 * first checked that it is in the range of the string. The function
1073 * throws out_of_range if the check fails.
1074 */
1075 reference
1076 at(size_type __n)
1077 {
1078 if (__n >= size())
1079 __throw_out_of_range_fmt(__N("basic_string::at: __n "("basic_string::at: __n " "(which is %zu) >= this->size() "
"(which is %zu)")
1080 "(which is %zu) >= this->size() "("basic_string::at: __n " "(which is %zu) >= this->size() "
"(which is %zu)")
1081 "(which is %zu)")("basic_string::at: __n " "(which is %zu) >= this->size() "
"(which is %zu)")
,
1082 __n, this->size());
1083 return _M_data()[__n];
1084 }
1085
1086#if __cplusplus201703L >= 201103L
1087 /**
1088 * Returns a read/write reference to the data at the first
1089 * element of the %string.
1090 */
1091 reference
1092 front() noexcept
1093 {
1094 __glibcxx_assert(!empty())do { if (! (!empty())) std::__replacement_assert("/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.h"
, 1094, __PRETTY_FUNCTION__, "!empty()"); } while (false)
;
1095 return operator[](0);
1096 }
1097
1098 /**
1099 * Returns a read-only (constant) reference to the data at the first
1100 * element of the %string.
1101 */
1102 const_reference
1103 front() const noexcept
1104 {
1105 __glibcxx_assert(!empty())do { if (! (!empty())) std::__replacement_assert("/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.h"
, 1105, __PRETTY_FUNCTION__, "!empty()"); } while (false)
;
1106 return operator[](0);
1107 }
1108
1109 /**
1110 * Returns a read/write reference to the data at the last
1111 * element of the %string.
1112 */
1113 reference
1114 back() noexcept
1115 {
1116 __glibcxx_assert(!empty())do { if (! (!empty())) std::__replacement_assert("/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.h"
, 1116, __PRETTY_FUNCTION__, "!empty()"); } while (false)
;
1117 return operator[](this->size() - 1);
1118 }
1119
1120 /**
1121 * Returns a read-only (constant) reference to the data at the
1122 * last element of the %string.
1123 */
1124 const_reference
1125 back() const noexcept
1126 {
1127 __glibcxx_assert(!empty())do { if (! (!empty())) std::__replacement_assert("/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.h"
, 1127, __PRETTY_FUNCTION__, "!empty()"); } while (false)
;
1128 return operator[](this->size() - 1);
1129 }
1130#endif
1131
1132 // Modifiers:
1133 /**
1134 * @brief Append a string to this string.
1135 * @param __str The string to append.
1136 * @return Reference to this string.
1137 */
1138 basic_string&
1139 operator+=(const basic_string& __str)
1140 { return this->append(__str); }
1141
1142 /**
1143 * @brief Append a C string.
1144 * @param __s The C string to append.
1145 * @return Reference to this string.
1146 */
1147 basic_string&
1148 operator+=(const _CharT* __s)
1149 { return this->append(__s); }
1150
1151 /**
1152 * @brief Append a character.
1153 * @param __c The character to append.
1154 * @return Reference to this string.
1155 */
1156 basic_string&
1157 operator+=(_CharT __c)
1158 {
1159 this->push_back(__c);
1160 return *this;
1161 }
1162
1163#if __cplusplus201703L >= 201103L
1164 /**
1165 * @brief Append an initializer_list of characters.
1166 * @param __l The initializer_list of characters to be appended.
1167 * @return Reference to this string.
1168 */
1169 basic_string&
1170 operator+=(initializer_list<_CharT> __l)
1171 { return this->append(__l.begin(), __l.size()); }
1172#endif // C++11
1173
1174#if __cplusplus201703L >= 201703L
1175 /**
1176 * @brief Append a string_view.
1177 * @param __svt An object convertible to string_view to be appended.
1178 * @return Reference to this string.
1179 */
1180 template<typename _Tp>
1181 _If_sv<_Tp, basic_string&>
1182 operator+=(const _Tp& __svt)
1183 { return this->append(__svt); }
1184#endif // C++17
1185
1186 /**
1187 * @brief Append a string to this string.
1188 * @param __str The string to append.
1189 * @return Reference to this string.
1190 */
1191 basic_string&
1192 append(const basic_string& __str)
1193 { return _M_append(__str._M_data(), __str.size()); }
1194
1195 /**
1196 * @brief Append a substring.
1197 * @param __str The string to append.
1198 * @param __pos Index of the first character of str to append.
1199 * @param __n The number of characters to append.
1200 * @return Reference to this string.
1201 * @throw std::out_of_range if @a __pos is not a valid index.
1202 *
1203 * This function appends @a __n characters from @a __str
1204 * starting at @a __pos to this string. If @a __n is is larger
1205 * than the number of available characters in @a __str, the
1206 * remainder of @a __str is appended.
1207 */
1208 basic_string&
1209 append(const basic_string& __str, size_type __pos, size_type __n = npos)
1210 { return _M_append(__str._M_data()
1211 + __str._M_check(__pos, "basic_string::append"),
1212 __str._M_limit(__pos, __n)); }
1213
1214 /**
1215 * @brief Append a C substring.
1216 * @param __s The C string to append.
1217 * @param __n The number of characters to append.
1218 * @return Reference to this string.
1219 */
1220 basic_string&
1221 append(const _CharT* __s, size_type __n)
1222 {
1223 __glibcxx_requires_string_len(__s, __n);
1224 _M_check_length(size_type(0), __n, "basic_string::append");
1225 return _M_append(__s, __n);
1226 }
1227
1228 /**
1229 * @brief Append a C string.
1230 * @param __s The C string to append.
1231 * @return Reference to this string.
1232 */
1233 basic_string&
1234 append(const _CharT* __s)
1235 {
1236 __glibcxx_requires_string(__s);
1237 const size_type __n = traits_type::length(__s);
1238 _M_check_length(size_type(0), __n, "basic_string::append");
1239 return _M_append(__s, __n);
1240 }
1241
1242 /**
1243 * @brief Append multiple characters.
1244 * @param __n The number of characters to append.
1245 * @param __c The character to use.
1246 * @return Reference to this string.
1247 *
1248 * Appends __n copies of __c to this string.
1249 */
1250 basic_string&
1251 append(size_type __n, _CharT __c)
1252 { return _M_replace_aux(this->size(), size_type(0), __n, __c); }
1253
1254#if __cplusplus201703L >= 201103L
1255 /**
1256 * @brief Append an initializer_list of characters.
1257 * @param __l The initializer_list of characters to append.
1258 * @return Reference to this string.
1259 */
1260 basic_string&
1261 append(initializer_list<_CharT> __l)
1262 { return this->append(__l.begin(), __l.size()); }
1263#endif // C++11
1264
1265 /**
1266 * @brief Append a range of characters.
1267 * @param __first Iterator referencing the first character to append.
1268 * @param __last Iterator marking the end of the range.
1269 * @return Reference to this string.
1270 *
1271 * Appends characters in the range [__first,__last) to this string.
1272 */
1273#if __cplusplus201703L >= 201103L
1274 template<class _InputIterator,
1275 typename = std::_RequireInputIter<_InputIterator>>
1276#else
1277 template<class _InputIterator>
1278#endif
1279 basic_string&
1280 append(_InputIterator __first, _InputIterator __last)
1281 { return this->replace(end(), end(), __first, __last); }
1282
1283#if __cplusplus201703L >= 201703L
1284 /**
1285 * @brief Append a string_view.
1286 * @param __svt An object convertible to string_view to be appended.
1287 * @return Reference to this string.
1288 */
1289 template<typename _Tp>
1290 _If_sv<_Tp, basic_string&>
1291 append(const _Tp& __svt)
1292 {
1293 __sv_type __sv = __svt;
1294 return this->append(__sv.data(), __sv.size());
1295 }
1296
1297 /**
1298 * @brief Append a range of characters from a string_view.
1299 * @param __svt An object convertible to string_view to be appended from.
1300 * @param __pos The position in the string_view to append from.
1301 * @param __n The number of characters to append from the string_view.
1302 * @return Reference to this string.
1303 */
1304 template<typename _Tp>
1305 _If_sv<_Tp, basic_string&>
1306 append(const _Tp& __svt, size_type __pos, size_type __n = npos)
1307 {
1308 __sv_type __sv = __svt;
1309 return _M_append(__sv.data()
1310 + std::__sv_check(__sv.size(), __pos, "basic_string::append"),
1311 std::__sv_limit(__sv.size(), __pos, __n));
1312 }
1313#endif // C++17
1314
1315 /**
1316 * @brief Append a single character.
1317 * @param __c Character to append.
1318 */
1319 void
1320 push_back(_CharT __c)
1321 {
1322 const size_type __size = this->size();
1323 if (__size + 1 > this->capacity())
1324 this->_M_mutate(__size, size_type(0), 0, size_type(1));
1325 traits_type::assign(this->_M_data()[__size], __c);
1326 this->_M_set_length(__size + 1);
1327 }
1328
1329 /**
1330 * @brief Set value to contents of another string.
1331 * @param __str Source string to use.
1332 * @return Reference to this string.
1333 */
1334 basic_string&
1335 assign(const basic_string& __str)
1336 {
1337#if __cplusplus201703L >= 201103L
1338 if (_Alloc_traits::_S_propagate_on_copy_assign())
1339 {
1340 if (!_Alloc_traits::_S_always_equal() && !_M_is_local()
1341 && _M_get_allocator() != __str._M_get_allocator())
1342 {
1343 // Propagating allocator cannot free existing storage so must
1344 // deallocate it before replacing current allocator.
1345 if (__str.size() <= _S_local_capacity)
1346 {
1347 _M_destroy(_M_allocated_capacity);
1348 _M_data(_M_local_data());
1349 _M_set_length(0);
1350 }
1351 else
1352 {
1353 const auto __len = __str.size();
1354 auto __alloc = __str._M_get_allocator();
1355 // If this allocation throws there are no effects:
1356 auto __ptr = _Alloc_traits::allocate(__alloc, __len + 1);
1357 _M_destroy(_M_allocated_capacity);
1358 _M_data(__ptr);
1359 _M_capacity(__len);
1360 _M_set_length(__len);
1361 }
1362 }
1363 std::__alloc_on_copy(_M_get_allocator(), __str._M_get_allocator());
1364 }
1365#endif
1366 this->_M_assign(__str);
1367 return *this;
1368 }
1369
1370#if __cplusplus201703L >= 201103L
1371 /**
1372 * @brief Set value to contents of another string.
1373 * @param __str Source string to use.
1374 * @return Reference to this string.
1375 *
1376 * This function sets this string to the exact contents of @a __str.
1377 * @a __str is a valid, but unspecified string.
1378 */
1379 basic_string&
1380 assign(basic_string&& __str)
1381 noexcept(_Alloc_traits::_S_nothrow_move())
1382 {
1383 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1384 // 2063. Contradictory requirements for string move assignment
1385 return *this = std::move(__str);
1386 }
1387#endif // C++11
1388
1389 /**
1390 * @brief Set value to a substring of a string.
1391 * @param __str The string to use.
1392 * @param __pos Index of the first character of str.
1393 * @param __n Number of characters to use.
1394 * @return Reference to this string.
1395 * @throw std::out_of_range if @a pos is not a valid index.
1396 *
1397 * This function sets this string to the substring of @a __str
1398 * consisting of @a __n characters at @a __pos. If @a __n is
1399 * is larger than the number of available characters in @a
1400 * __str, the remainder of @a __str is used.
1401 */
1402 basic_string&
1403 assign(const basic_string& __str, size_type __pos, size_type __n = npos)
1404 { return _M_replace(size_type(0), this->size(), __str._M_data()
1405 + __str._M_check(__pos, "basic_string::assign"),
1406 __str._M_limit(__pos, __n)); }
1407
1408 /**
1409 * @brief Set value to a C substring.
1410 * @param __s The C string to use.
1411 * @param __n Number of characters to use.
1412 * @return Reference to this string.
1413 *
1414 * This function sets the value of this string to the first @a __n
1415 * characters of @a __s. If @a __n is is larger than the number of
1416 * available characters in @a __s, the remainder of @a __s is used.
1417 */
1418 basic_string&
1419 assign(const _CharT* __s, size_type __n)
1420 {
1421 __glibcxx_requires_string_len(__s, __n);
1422 return _M_replace(size_type(0), this->size(), __s, __n);
1423 }
1424
1425 /**
1426 * @brief Set value to contents of a C string.
1427 * @param __s The C string to use.
1428 * @return Reference to this string.
1429 *
1430 * This function sets the value of this string to the value of @a __s.
1431 * The data is copied, so there is no dependence on @a __s once the
1432 * function returns.
1433 */
1434 basic_string&
1435 assign(const _CharT* __s)
1436 {
1437 __glibcxx_requires_string(__s);
1438 return _M_replace(size_type(0), this->size(), __s,
1439 traits_type::length(__s));
1440 }
1441
1442 /**
1443 * @brief Set value to multiple characters.
1444 * @param __n Length of the resulting string.
1445 * @param __c The character to use.
1446 * @return Reference to this string.
1447 *
1448 * This function sets the value of this string to @a __n copies of
1449 * character @a __c.
1450 */
1451 basic_string&
1452 assign(size_type __n, _CharT __c)
1453 { return _M_replace_aux(size_type(0), this->size(), __n, __c); }
1454
1455 /**
1456 * @brief Set value to a range of characters.
1457 * @param __first Iterator referencing the first character to append.
1458 * @param __last Iterator marking the end of the range.
1459 * @return Reference to this string.
1460 *
1461 * Sets value of string to characters in the range [__first,__last).
1462 */
1463#if __cplusplus201703L >= 201103L
1464 template<class _InputIterator,
1465 typename = std::_RequireInputIter<_InputIterator>>
1466#else
1467 template<class _InputIterator>
1468#endif
1469 basic_string&
1470 assign(_InputIterator __first, _InputIterator __last)
1471 { return this->replace(begin(), end(), __first, __last); }
1472
1473#if __cplusplus201703L >= 201103L
1474 /**
1475 * @brief Set value to an initializer_list of characters.
1476 * @param __l The initializer_list of characters to assign.
1477 * @return Reference to this string.
1478 */
1479 basic_string&
1480 assign(initializer_list<_CharT> __l)
1481 { return this->assign(__l.begin(), __l.size()); }
1482#endif // C++11
1483
1484#if __cplusplus201703L >= 201703L
1485 /**
1486 * @brief Set value from a string_view.
1487 * @param __svt The source object convertible to string_view.
1488 * @return Reference to this string.
1489 */
1490 template<typename _Tp>
1491 _If_sv<_Tp, basic_string&>
1492 assign(const _Tp& __svt)
1493 {
1494 __sv_type __sv = __svt;
1495 return this->assign(__sv.data(), __sv.size());
1496 }
1497
1498 /**
1499 * @brief Set value from a range of characters in a string_view.
1500 * @param __svt The source object convertible to string_view.
1501 * @param __pos The position in the string_view to assign from.
1502 * @param __n The number of characters to assign.
1503 * @return Reference to this string.
1504 */
1505 template<typename _Tp>
1506 _If_sv<_Tp, basic_string&>
1507 assign(const _Tp& __svt, size_type __pos, size_type __n = npos)
1508 {
1509 __sv_type __sv = __svt;
1510 return _M_replace(size_type(0), this->size(),
1511 __sv.data()
1512 + std::__sv_check(__sv.size(), __pos, "basic_string::assign"),
1513 std::__sv_limit(__sv.size(), __pos, __n));
1514 }
1515#endif // C++17
1516
1517#if __cplusplus201703L >= 201103L
1518 /**
1519 * @brief Insert multiple characters.
1520 * @param __p Const_iterator referencing location in string to
1521 * insert at.
1522 * @param __n Number of characters to insert
1523 * @param __c The character to insert.
1524 * @return Iterator referencing the first inserted char.
1525 * @throw std::length_error If new length exceeds @c max_size().
1526 *
1527 * Inserts @a __n copies of character @a __c starting at the
1528 * position referenced by iterator @a __p. If adding
1529 * characters causes the length to exceed max_size(),
1530 * length_error is thrown. The value of the string doesn't
1531 * change if an error is thrown.
1532 */
1533 iterator
1534 insert(const_iterator __p, size_type __n, _CharT __c)
1535 {
1536 _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end());
1537 const size_type __pos = __p - begin();
1538 this->replace(__p, __p, __n, __c);
1539 return iterator(this->_M_data() + __pos);
1540 }
1541#else
1542 /**
1543 * @brief Insert multiple characters.
1544 * @param __p Iterator referencing location in string to insert at.
1545 * @param __n Number of characters to insert
1546 * @param __c The character to insert.
1547 * @throw std::length_error If new length exceeds @c max_size().
1548 *
1549 * Inserts @a __n copies of character @a __c starting at the
1550 * position referenced by iterator @a __p. If adding
1551 * characters causes the length to exceed max_size(),
1552 * length_error is thrown. The value of the string doesn't
1553 * change if an error is thrown.
1554 */
1555 void
1556 insert(iterator __p, size_type __n, _CharT __c)
1557 { this->replace(__p, __p, __n, __c); }
1558#endif
1559
1560#if __cplusplus201703L >= 201103L
1561 /**
1562 * @brief Insert a range of characters.
1563 * @param __p Const_iterator referencing location in string to
1564 * insert at.
1565 * @param __beg Start of range.
1566 * @param __end End of range.
1567 * @return Iterator referencing the first inserted char.
1568 * @throw std::length_error If new length exceeds @c max_size().
1569 *
1570 * Inserts characters in range [beg,end). If adding characters
1571 * causes the length to exceed max_size(), length_error is
1572 * thrown. The value of the string doesn't change if an error
1573 * is thrown.
1574 */
1575 template<class _InputIterator,
1576 typename = std::_RequireInputIter<_InputIterator>>
1577 iterator
1578 insert(const_iterator __p, _InputIterator __beg, _InputIterator __end)
1579 {
1580 _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end());
1581 const size_type __pos = __p - begin();
1582 this->replace(__p, __p, __beg, __end);
1583 return iterator(this->_M_data() + __pos);
1584 }
1585#else
1586 /**
1587 * @brief Insert a range of characters.
1588 * @param __p Iterator referencing location in string to insert at.
1589 * @param __beg Start of range.
1590 * @param __end End of range.
1591 * @throw std::length_error If new length exceeds @c max_size().
1592 *
1593 * Inserts characters in range [__beg,__end). If adding
1594 * characters causes the length to exceed max_size(),
1595 * length_error is thrown. The value of the string doesn't
1596 * change if an error is thrown.
1597 */
1598 template<class _InputIterator>
1599 void
1600 insert(iterator __p, _InputIterator __beg, _InputIterator __end)
1601 { this->replace(__p, __p, __beg, __end); }
1602#endif
1603
1604#if __cplusplus201703L >= 201103L
1605 /**
1606 * @brief Insert an initializer_list of characters.
1607 * @param __p Iterator referencing location in string to insert at.
1608 * @param __l The initializer_list of characters to insert.
1609 * @throw std::length_error If new length exceeds @c max_size().
1610 */
1611 iterator
1612 insert(const_iterator __p, initializer_list<_CharT> __l)
1613 { return this->insert(__p, __l.begin(), __l.end()); }
1614
1615#ifdef _GLIBCXX_DEFINING_STRING_INSTANTIATIONS
1616 // See PR libstdc++/83328
1617 void
1618 insert(iterator __p, initializer_list<_CharT> __l)
1619 {
1620 _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end());
1621 this->insert(__p - begin(), __l.begin(), __l.size());
1622 }
1623#endif
1624#endif // C++11
1625
1626 /**
1627 * @brief Insert value of a string.
1628 * @param __pos1 Position in string to insert at.
1629 * @param __str The string to insert.
1630 * @return Reference to this string.
1631 * @throw std::length_error If new length exceeds @c max_size().
1632 *
1633 * Inserts value of @a __str starting at @a __pos1. If adding
1634 * characters causes the length to exceed max_size(),
1635 * length_error is thrown. The value of the string doesn't
1636 * change if an error is thrown.
1637 */
1638 basic_string&
1639 insert(size_type __pos1, const basic_string& __str)
1640 { return this->replace(__pos1, size_type(0),
1641 __str._M_data(), __str.size()); }
1642
1643 /**
1644 * @brief Insert a substring.
1645 * @param __pos1 Position in string to insert at.
1646 * @param __str The string to insert.
1647 * @param __pos2 Start of characters in str to insert.
1648 * @param __n Number of characters to insert.
1649 * @return Reference to this string.
1650 * @throw std::length_error If new length exceeds @c max_size().
1651 * @throw std::out_of_range If @a pos1 > size() or
1652 * @a __pos2 > @a str.size().
1653 *
1654 * Starting at @a pos1, insert @a __n character of @a __str
1655 * beginning with @a __pos2. If adding characters causes the
1656 * length to exceed max_size(), length_error is thrown. If @a
1657 * __pos1 is beyond the end of this string or @a __pos2 is
1658 * beyond the end of @a __str, out_of_range is thrown. The
1659 * value of the string doesn't change if an error is thrown.
1660 */
1661 basic_string&
1662 insert(size_type __pos1, const basic_string& __str,
1663 size_type __pos2, size_type __n = npos)
1664 { return this->replace(__pos1, size_type(0), __str._M_data()
1665 + __str._M_check(__pos2, "basic_string::insert"),
1666 __str._M_limit(__pos2, __n)); }
1667
1668 /**
1669 * @brief Insert a C substring.
1670 * @param __pos Position in string to insert at.
1671 * @param __s The C string to insert.
1672 * @param __n The number of characters to insert.
1673 * @return Reference to this string.
1674 * @throw std::length_error If new length exceeds @c max_size().
1675 * @throw std::out_of_range If @a __pos is beyond the end of this
1676 * string.
1677 *
1678 * Inserts the first @a __n characters of @a __s starting at @a
1679 * __pos. If adding characters causes the length to exceed
1680 * max_size(), length_error is thrown. If @a __pos is beyond
1681 * end(), out_of_range is thrown. The value of the string
1682 * doesn't change if an error is thrown.
1683 */
1684 basic_string&
1685 insert(size_type __pos, const _CharT* __s, size_type __n)
1686 { return this->replace(__pos, size_type(0), __s, __n); }
1687
1688 /**
1689 * @brief Insert a C string.
1690 * @param __pos Position in string to insert at.
1691 * @param __s The C string to insert.
1692 * @return Reference to this string.
1693 * @throw std::length_error If new length exceeds @c max_size().
1694 * @throw std::out_of_range If @a pos is beyond the end of this
1695 * string.
1696 *
1697 * Inserts the first @a n characters of @a __s starting at @a __pos. If
1698 * adding characters causes the length to exceed max_size(),
1699 * length_error is thrown. If @a __pos is beyond end(), out_of_range is
1700 * thrown. The value of the string doesn't change if an error is
1701 * thrown.
1702 */
1703 basic_string&
1704 insert(size_type __pos, const _CharT* __s)
1705 {
1706 __glibcxx_requires_string(__s);
1707 return this->replace(__pos, size_type(0), __s,
1708 traits_type::length(__s));
1709 }
1710
1711 /**
1712 * @brief Insert multiple characters.
1713 * @param __pos Index in string to insert at.
1714 * @param __n Number of characters to insert
1715 * @param __c The character to insert.
1716 * @return Reference to this string.
1717 * @throw std::length_error If new length exceeds @c max_size().
1718 * @throw std::out_of_range If @a __pos is beyond the end of this
1719 * string.
1720 *
1721 * Inserts @a __n copies of character @a __c starting at index
1722 * @a __pos. If adding characters causes the length to exceed
1723 * max_size(), length_error is thrown. If @a __pos > length(),
1724 * out_of_range is thrown. The value of the string doesn't
1725 * change if an error is thrown.
1726 */
1727 basic_string&
1728 insert(size_type __pos, size_type __n, _CharT __c)
1729 { return _M_replace_aux(_M_check(__pos, "basic_string::insert"),
1730 size_type(0), __n, __c); }
1731
1732 /**
1733 * @brief Insert one character.
1734 * @param __p Iterator referencing position in string to insert at.
1735 * @param __c The character to insert.
1736 * @return Iterator referencing newly inserted char.
1737 * @throw std::length_error If new length exceeds @c max_size().
1738 *
1739 * Inserts character @a __c at position referenced by @a __p.
1740 * If adding character causes the length to exceed max_size(),
1741 * length_error is thrown. If @a __p is beyond end of string,
1742 * out_of_range is thrown. The value of the string doesn't
1743 * change if an error is thrown.
1744 */
1745 iterator
1746 insert(__const_iterator __p, _CharT __c)
1747 {
1748 _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end());
1749 const size_type __pos = __p - begin();
1750 _M_replace_aux(__pos, size_type(0), size_type(1), __c);
1751 return iterator(_M_data() + __pos);
1752 }
1753
1754#if __cplusplus201703L >= 201703L
1755 /**
1756 * @brief Insert a string_view.
1757 * @param __pos Position in string to insert at.
1758 * @param __svt The object convertible to string_view to insert.
1759 * @return Reference to this string.
1760 */
1761 template<typename _Tp>
1762 _If_sv<_Tp, basic_string&>
1763 insert(size_type __pos, const _Tp& __svt)
1764 {
1765 __sv_type __sv = __svt;
1766 return this->insert(__pos, __sv.data(), __sv.size());
1767 }
1768
1769 /**
1770 * @brief Insert a string_view.
1771 * @param __pos1 Position in string to insert at.
1772 * @param __svt The object convertible to string_view to insert from.
1773 * @param __pos2 Start of characters in str to insert.
1774 * @param __n The number of characters to insert.
1775 * @return Reference to this string.
1776 */
1777 template<typename _Tp>
1778 _If_sv<_Tp, basic_string&>
1779 insert(size_type __pos1, const _Tp& __svt,
1780 size_type __pos2, size_type __n = npos)
1781 {
1782 __sv_type __sv = __svt;
1783 return this->replace(__pos1, size_type(0),
1784 __sv.data()
1785 + std::__sv_check(__sv.size(), __pos2, "basic_string::insert"),
1786 std::__sv_limit(__sv.size(), __pos2, __n));
1787 }
1788#endif // C++17
1789
1790 /**
1791 * @brief Remove characters.
1792 * @param __pos Index of first character to remove (default 0).
1793 * @param __n Number of characters to remove (default remainder).
1794 * @return Reference to this string.
1795 * @throw std::out_of_range If @a pos is beyond the end of this
1796 * string.
1797 *
1798 * Removes @a __n characters from this string starting at @a
1799 * __pos. The length of the string is reduced by @a __n. If
1800 * there are < @a __n characters to remove, the remainder of
1801 * the string is truncated. If @a __p is beyond end of string,
1802 * out_of_range is thrown. The value of the string doesn't
1803 * change if an error is thrown.
1804 */
1805 basic_string&
1806 erase(size_type __pos = 0, size_type __n = npos)
1807 {
1808 _M_check(__pos, "basic_string::erase");
1809 if (__n == npos)
1810 this->_M_set_length(__pos);
1811 else if (__n != 0)
1812 this->_M_erase(__pos, _M_limit(__pos, __n));
1813 return *this;
1814 }
1815
1816 /**
1817 * @brief Remove one character.
1818 * @param __position Iterator referencing the character to remove.
1819 * @return iterator referencing same location after removal.
1820 *
1821 * Removes the character at @a __position from this string. The value
1822 * of the string doesn't change if an error is thrown.
1823 */
1824 iterator
1825 erase(__const_iterator __position)
1826 {
1827 _GLIBCXX_DEBUG_PEDASSERT(__position >= begin()
1828 && __position < end());
1829 const size_type __pos = __position - begin();
1830 this->_M_erase(__pos, size_type(1));
1831 return iterator(_M_data() + __pos);
1832 }
1833
1834 /**
1835 * @brief Remove a range of characters.
1836 * @param __first Iterator referencing the first character to remove.
1837 * @param __last Iterator referencing the end of the range.
1838 * @return Iterator referencing location of first after removal.
1839 *
1840 * Removes the characters in the range [first,last) from this string.
1841 * The value of the string doesn't change if an error is thrown.
1842 */
1843 iterator
1844 erase(__const_iterator __first, __const_iterator __last)
1845 {
1846 _GLIBCXX_DEBUG_PEDASSERT(__first >= begin() && __first <= __last
1847 && __last <= end());
1848 const size_type __pos = __first - begin();
1849 if (__last == end())
1850 this->_M_set_length(__pos);
1851 else
1852 this->_M_erase(__pos, __last - __first);
1853 return iterator(this->_M_data() + __pos);
1854 }
1855
1856#if __cplusplus201703L >= 201103L
1857 /**
1858 * @brief Remove the last character.
1859 *
1860 * The string must be non-empty.
1861 */
1862 void
1863 pop_back() noexcept
1864 {
1865 __glibcxx_assert(!empty())do { if (! (!empty())) std::__replacement_assert("/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.h"
, 1865, __PRETTY_FUNCTION__, "!empty()"); } while (false)
;
1866 _M_erase(size() - 1, 1);
1867 }
1868#endif // C++11
1869
1870 /**
1871 * @brief Replace characters with value from another string.
1872 * @param __pos Index of first character to replace.
1873 * @param __n Number of characters to be replaced.
1874 * @param __str String to insert.
1875 * @return Reference to this string.
1876 * @throw std::out_of_range If @a pos is beyond the end of this
1877 * string.
1878 * @throw std::length_error If new length exceeds @c max_size().
1879 *
1880 * Removes the characters in the range [__pos,__pos+__n) from
1881 * this string. In place, the value of @a __str is inserted.
1882 * If @a __pos is beyond end of string, out_of_range is thrown.
1883 * If the length of the result exceeds max_size(), length_error
1884 * is thrown. The value of the string doesn't change if an
1885 * error is thrown.
1886 */
1887 basic_string&
1888 replace(size_type __pos, size_type __n, const basic_string& __str)
1889 { return this->replace(__pos, __n, __str._M_data(), __str.size()); }
1890
1891 /**
1892 * @brief Replace characters with value from another string.
1893 * @param __pos1 Index of first character to replace.
1894 * @param __n1 Number of characters to be replaced.
1895 * @param __str String to insert.
1896 * @param __pos2 Index of first character of str to use.
1897 * @param __n2 Number of characters from str to use.
1898 * @return Reference to this string.
1899 * @throw std::out_of_range If @a __pos1 > size() or @a __pos2 >
1900 * __str.size().
1901 * @throw std::length_error If new length exceeds @c max_size().
1902 *
1903 * Removes the characters in the range [__pos1,__pos1 + n) from this
1904 * string. In place, the value of @a __str is inserted. If @a __pos is
1905 * beyond end of string, out_of_range is thrown. If the length of the
1906 * result exceeds max_size(), length_error is thrown. The value of the
1907 * string doesn't change if an error is thrown.
1908 */
1909 basic_string&
1910 replace(size_type __pos1, size_type __n1, const basic_string& __str,
1911 size_type __pos2, size_type __n2 = npos)
1912 { return this->replace(__pos1, __n1, __str._M_data()
1913 + __str._M_check(__pos2, "basic_string::replace"),
1914 __str._M_limit(__pos2, __n2)); }
1915
1916 /**
1917 * @brief Replace characters with value of a C substring.
1918 * @param __pos Index of first character to replace.
1919 * @param __n1 Number of characters to be replaced.
1920 * @param __s C string to insert.
1921 * @param __n2 Number of characters from @a s to use.
1922 * @return Reference to this string.
1923 * @throw std::out_of_range If @a pos1 > size().
1924 * @throw std::length_error If new length exceeds @c max_size().
1925 *
1926 * Removes the characters in the range [__pos,__pos + __n1)
1927 * from this string. In place, the first @a __n2 characters of
1928 * @a __s are inserted, or all of @a __s if @a __n2 is too large. If
1929 * @a __pos is beyond end of string, out_of_range is thrown. If
1930 * the length of result exceeds max_size(), length_error is
1931 * thrown. The value of the string doesn't change if an error
1932 * is thrown.
1933 */
1934 basic_string&
1935 replace(size_type __pos, size_type __n1, const _CharT* __s,
1936 size_type __n2)
1937 {
1938 __glibcxx_requires_string_len(__s, __n2);
1939 return _M_replace(_M_check(__pos, "basic_string::replace"),
1940 _M_limit(__pos, __n1), __s, __n2);
1941 }
1942
1943 /**
1944 * @brief Replace characters with value of a C string.
1945 * @param __pos Index of first character to replace.
1946 * @param __n1 Number of characters to be replaced.
1947 * @param __s C string to insert.
1948 * @return Reference to this string.
1949 * @throw std::out_of_range If @a pos > size().
1950 * @throw std::length_error If new length exceeds @c max_size().
1951 *
1952 * Removes the characters in the range [__pos,__pos + __n1)
1953 * from this string. In place, the characters of @a __s are
1954 * inserted. If @a __pos is beyond end of string, out_of_range
1955 * is thrown. If the length of result exceeds max_size(),
1956 * length_error is thrown. The value of the string doesn't
1957 * change if an error is thrown.
1958 */
1959 basic_string&
1960 replace(size_type __pos, size_type __n1, const _CharT* __s)
1961 {
1962 __glibcxx_requires_string(__s);
1963 return this->replace(__pos, __n1, __s, traits_type::length(__s));
1964 }
1965
1966 /**
1967 * @brief Replace characters with multiple characters.
1968 * @param __pos Index of first character to replace.
1969 * @param __n1 Number of characters to be replaced.
1970 * @param __n2 Number of characters to insert.
1971 * @param __c Character to insert.
1972 * @return Reference to this string.
1973 * @throw std::out_of_range If @a __pos > size().
1974 * @throw std::length_error If new length exceeds @c max_size().
1975 *
1976 * Removes the characters in the range [pos,pos + n1) from this
1977 * string. In place, @a __n2 copies of @a __c are inserted.
1978 * If @a __pos is beyond end of string, out_of_range is thrown.
1979 * If the length of result exceeds max_size(), length_error is
1980 * thrown. The value of the string doesn't change if an error
1981 * is thrown.
1982 */
1983 basic_string&
1984 replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
1985 { return _M_replace_aux(_M_check(__pos, "basic_string::replace"),
1986 _M_limit(__pos, __n1), __n2, __c); }
1987
1988 /**
1989 * @brief Replace range of characters with string.
1990 * @param __i1 Iterator referencing start of range to replace.
1991 * @param __i2 Iterator referencing end of range to replace.
1992 * @param __str String value to insert.
1993 * @return Reference to this string.
1994 * @throw std::length_error If new length exceeds @c max_size().
1995 *
1996 * Removes the characters in the range [__i1,__i2). In place,
1997 * the value of @a __str is inserted. If the length of result
1998 * exceeds max_size(), length_error is thrown. The value of
1999 * the string doesn't change if an error is thrown.
2000 */
2001 basic_string&
2002 replace(__const_iterator __i1, __const_iterator __i2,
2003 const basic_string& __str)
2004 { return this->replace(__i1, __i2, __str._M_data(), __str.size()); }
2005
2006 /**
2007 * @brief Replace range of characters with C substring.
2008 * @param __i1 Iterator referencing start of range to replace.
2009 * @param __i2 Iterator referencing end of range to replace.
2010 * @param __s C string value to insert.
2011 * @param __n Number of characters from s to insert.
2012 * @return Reference to this string.
2013 * @throw std::length_error If new length exceeds @c max_size().
2014 *
2015 * Removes the characters in the range [__i1,__i2). In place,
2016 * the first @a __n characters of @a __s are inserted. If the
2017 * length of result exceeds max_size(), length_error is thrown.
2018 * The value of the string doesn't change if an error is
2019 * thrown.
2020 */
2021 basic_string&
2022 replace(__const_iterator __i1, __const_iterator __i2,
2023 const _CharT* __s, size_type __n)
2024 {
2025 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2026 && __i2 <= end());
2027 return this->replace(__i1 - begin(), __i2 - __i1, __s, __n);
2028 }
2029
2030 /**
2031 * @brief Replace range of characters with C string.
2032 * @param __i1 Iterator referencing start of range to replace.
2033 * @param __i2 Iterator referencing end of range to replace.
2034 * @param __s C string value to insert.
2035 * @return Reference to this string.
2036 * @throw std::length_error If new length exceeds @c max_size().
2037 *
2038 * Removes the characters in the range [__i1,__i2). In place,
2039 * the characters of @a __s are inserted. If the length of
2040 * result exceeds max_size(), length_error is thrown. The
2041 * value of the string doesn't change if an error is thrown.
2042 */
2043 basic_string&
2044 replace(__const_iterator __i1, __const_iterator __i2, const _CharT* __s)
2045 {
2046 __glibcxx_requires_string(__s);
2047 return this->replace(__i1, __i2, __s, traits_type::length(__s));
2048 }
2049
2050 /**
2051 * @brief Replace range of characters with multiple characters
2052 * @param __i1 Iterator referencing start of range to replace.
2053 * @param __i2 Iterator referencing end of range to replace.
2054 * @param __n Number of characters to insert.
2055 * @param __c Character to insert.
2056 * @return Reference to this string.
2057 * @throw std::length_error If new length exceeds @c max_size().
2058 *
2059 * Removes the characters in the range [__i1,__i2). In place,
2060 * @a __n copies of @a __c are inserted. If the length of
2061 * result exceeds max_size(), length_error is thrown. The
2062 * value of the string doesn't change if an error is thrown.
2063 */
2064 basic_string&
2065 replace(__const_iterator __i1, __const_iterator __i2, size_type __n,
2066 _CharT __c)
2067 {
2068 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2069 && __i2 <= end());
2070 return _M_replace_aux(__i1 - begin(), __i2 - __i1, __n, __c);
2071 }
2072
2073 /**
2074 * @brief Replace range of characters with range.
2075 * @param __i1 Iterator referencing start of range to replace.
2076 * @param __i2 Iterator referencing end of range to replace.
2077 * @param __k1 Iterator referencing start of range to insert.
2078 * @param __k2 Iterator referencing end of range to insert.
2079 * @return Reference to this string.
2080 * @throw std::length_error If new length exceeds @c max_size().
2081 *
2082 * Removes the characters in the range [__i1,__i2). In place,
2083 * characters in the range [__k1,__k2) are inserted. If the
2084 * length of result exceeds max_size(), length_error is thrown.
2085 * The value of the string doesn't change if an error is
2086 * thrown.
2087 */
2088#if __cplusplus201703L >= 201103L
2089 template<class _InputIterator,
2090 typename = std::_RequireInputIter<_InputIterator>>
2091 basic_string&
2092 replace(const_iterator __i1, const_iterator __i2,
2093 _InputIterator __k1, _InputIterator __k2)
2094 {
2095 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2096 && __i2 <= end());
2097 __glibcxx_requires_valid_range(__k1, __k2);
2098 return this->_M_replace_dispatch(__i1, __i2, __k1, __k2,
2099 std::__false_type());
2100 }
2101#else
2102 template<class _InputIterator>
2103#ifdef _GLIBCXX_DISAMBIGUATE_REPLACE_INST
2104 typename __enable_if_not_native_iterator<_InputIterator>::__type
2105#else
2106 basic_string&
2107#endif
2108 replace(iterator __i1, iterator __i2,
2109 _InputIterator __k1, _InputIterator __k2)
2110 {
2111 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2112 && __i2 <= end());
2113 __glibcxx_requires_valid_range(__k1, __k2);
2114 typedef typename std::__is_integer<_InputIterator>::__type _Integral;
2115 return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral());
2116 }
2117#endif
2118
2119 // Specializations for the common case of pointer and iterator:
2120 // useful to avoid the overhead of temporary buffering in _M_replace.
2121 basic_string&
2122 replace(__const_iterator __i1, __const_iterator __i2,
2123 _CharT* __k1, _CharT* __k2)
2124 {
2125 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2126 && __i2 <= end());
2127 __glibcxx_requires_valid_range(__k1, __k2);
2128 return this->replace(__i1 - begin(), __i2 - __i1,
2129 __k1, __k2 - __k1);
2130 }
2131
2132 basic_string&
2133 replace(__const_iterator __i1, __const_iterator __i2,
2134 const _CharT* __k1, const _CharT* __k2)
2135 {
2136 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2137 && __i2 <= end());
2138 __glibcxx_requires_valid_range(__k1, __k2);
2139 return this->replace(__i1 - begin(), __i2 - __i1,
2140 __k1, __k2 - __k1);
2141 }
2142
2143 basic_string&
2144 replace(__const_iterator __i1, __const_iterator __i2,
2145 iterator __k1, iterator __k2)
2146 {
2147 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2148 && __i2 <= end());
2149 __glibcxx_requires_valid_range(__k1, __k2);
2150 return this->replace(__i1 - begin(), __i2 - __i1,
2151 __k1.base(), __k2 - __k1);
2152 }
2153
2154 basic_string&
2155 replace(__const_iterator __i1, __const_iterator __i2,
2156 const_iterator __k1, const_iterator __k2)
2157 {
2158 _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2
2159 && __i2 <= end());
2160 __glibcxx_requires_valid_range(__k1, __k2);
2161 return this->replace(__i1 - begin(), __i2 - __i1,
2162 __k1.base(), __k2 - __k1);
2163 }
2164
2165#if __cplusplus201703L >= 201103L
2166 /**
2167 * @brief Replace range of characters with initializer_list.
2168 * @param __i1 Iterator referencing start of range to replace.
2169 * @param __i2 Iterator referencing end of range to replace.
2170 * @param __l The initializer_list of characters to insert.
2171 * @return Reference to this string.
2172 * @throw std::length_error If new length exceeds @c max_size().
2173 *
2174 * Removes the characters in the range [__i1,__i2). In place,
2175 * characters in the range [__k1,__k2) are inserted. If the
2176 * length of result exceeds max_size(), length_error is thrown.
2177 * The value of the string doesn't change if an error is
2178 * thrown.
2179 */
2180 basic_string& replace(const_iterator __i1, const_iterator __i2,
2181 initializer_list<_CharT> __l)
2182 { return this->replace(__i1, __i2, __l.begin(), __l.size()); }
2183#endif // C++11
2184
2185#if __cplusplus201703L >= 201703L
2186 /**
2187 * @brief Replace range of characters with string_view.
2188 * @param __pos The position to replace at.
2189 * @param __n The number of characters to replace.
2190 * @param __svt The object convertible to string_view to insert.
2191 * @return Reference to this string.
2192 */
2193 template<typename _Tp>
2194 _If_sv<_Tp, basic_string&>
2195 replace(size_type __pos, size_type __n, const _Tp& __svt)
2196 {
2197 __sv_type __sv = __svt;
2198 return this->replace(__pos, __n, __sv.data(), __sv.size());
2199 }
2200
2201 /**
2202 * @brief Replace range of characters with string_view.
2203 * @param __pos1 The position to replace at.
2204 * @param __n1 The number of characters to replace.
2205 * @param __svt The object convertible to string_view to insert from.
2206 * @param __pos2 The position in the string_view to insert from.
2207 * @param __n2 The number of characters to insert.
2208 * @return Reference to this string.
2209 */
2210 template<typename _Tp>
2211 _If_sv<_Tp, basic_string&>
2212 replace(size_type __pos1, size_type __n1, const _Tp& __svt,
2213 size_type __pos2, size_type __n2 = npos)
2214 {
2215 __sv_type __sv = __svt;
2216 return this->replace(__pos1, __n1,
2217 __sv.data()
2218 + std::__sv_check(__sv.size(), __pos2, "basic_string::replace"),
2219 std::__sv_limit(__sv.size(), __pos2, __n2));
2220 }
2221
2222 /**
2223 * @brief Replace range of characters with string_view.
2224 * @param __i1 An iterator referencing the start position
2225 to replace at.
2226 * @param __i2 An iterator referencing the end position
2227 for the replace.
2228 * @param __svt The object convertible to string_view to insert from.
2229 * @return Reference to this string.
2230 */
2231 template<typename _Tp>
2232 _If_sv<_Tp, basic_string&>
2233 replace(const_iterator __i1, const_iterator __i2, const _Tp& __svt)
2234 {
2235 __sv_type __sv = __svt;
2236 return this->replace(__i1 - begin(), __i2 - __i1, __sv);
2237 }
2238#endif // C++17
2239
2240 private:
2241 template<class _Integer>
2242 basic_string&
2243 _M_replace_dispatch(const_iterator __i1, const_iterator __i2,
2244 _Integer __n, _Integer __val, __true_type)
2245 { return _M_replace_aux(__i1 - begin(), __i2 - __i1, __n, __val); }
2246
2247 template<class _InputIterator>
2248 basic_string&
2249 _M_replace_dispatch(const_iterator __i1, const_iterator __i2,
2250 _InputIterator __k1, _InputIterator __k2,
2251 __false_type);
2252
2253 basic_string&
2254 _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
2255 _CharT __c);
2256
2257 basic_string&
2258 _M_replace(size_type __pos, size_type __len1, const _CharT* __s,
2259 const size_type __len2);
2260
2261 basic_string&
2262 _M_append(const _CharT* __s, size_type __n);
2263
2264 public:
2265
2266 /**
2267 * @brief Copy substring into C string.
2268 * @param __s C string to copy value into.
2269 * @param __n Number of characters to copy.
2270 * @param __pos Index of first character to copy.
2271 * @return Number of characters actually copied
2272 * @throw std::out_of_range If __pos > size().
2273 *
2274 * Copies up to @a __n characters starting at @a __pos into the
2275 * C string @a __s. If @a __pos is %greater than size(),
2276 * out_of_range is thrown.
2277 */
2278 size_type
2279 copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
2280
2281 /**
2282 * @brief Swap contents with another string.
2283 * @param __s String to swap with.
2284 *
2285 * Exchanges the contents of this string with that of @a __s in constant
2286 * time.
2287 */
2288 void
2289 swap(basic_string& __s) _GLIBCXX_NOEXCEPTnoexcept;
2290
2291 // String operations:
2292 /**
2293 * @brief Return const pointer to null-terminated contents.
2294 *
2295 * This is a handle to internal data. Do not modify or dire things may
2296 * happen.
2297 */
2298 const _CharT*
2299 c_str() const _GLIBCXX_NOEXCEPTnoexcept
2300 { return _M_data(); }
2301
2302 /**
2303 * @brief Return const pointer to contents.
2304 *
2305 * This is a pointer to internal data. It is undefined to modify
2306 * the contents through the returned pointer. To get a pointer that
2307 * allows modifying the contents use @c &str[0] instead,
2308 * (or in C++17 the non-const @c str.data() overload).
2309 */
2310 const _CharT*
2311 data() const _GLIBCXX_NOEXCEPTnoexcept
2312 { return _M_data(); }
2313
2314#if __cplusplus201703L >= 201703L
2315 /**
2316 * @brief Return non-const pointer to contents.
2317 *
2318 * This is a pointer to the character sequence held by the string.
2319 * Modifying the characters in the sequence is allowed.
2320 */
2321 _CharT*
2322 data() noexcept
2323 { return _M_data(); }
2324#endif
2325
2326 /**
2327 * @brief Return copy of allocator used to construct this string.
2328 */
2329 allocator_type
2330 get_allocator() const _GLIBCXX_NOEXCEPTnoexcept
2331 { return _M_get_allocator(); }
2332
2333 /**
2334 * @brief Find position of a C substring.
2335 * @param __s C string to locate.
2336 * @param __pos Index of character to search from.
2337 * @param __n Number of characters from @a s to search for.
2338 * @return Index of start of first occurrence.
2339 *
2340 * Starting from @a __pos, searches forward for the first @a
2341 * __n characters in @a __s within this string. If found,
2342 * returns the index where it begins. If not found, returns
2343 * npos.
2344 */
2345 size_type
2346 find(const _CharT* __s, size_type __pos, size_type __n) const
2347 _GLIBCXX_NOEXCEPTnoexcept;
2348
2349 /**
2350 * @brief Find position of a string.
2351 * @param __str String to locate.
2352 * @param __pos Index of character to search from (default 0).
2353 * @return Index of start of first occurrence.
2354 *
2355 * Starting from @a __pos, searches forward for value of @a __str within
2356 * this string. If found, returns the index where it begins. If not
2357 * found, returns npos.
2358 */
2359 size_type
2360 find(const basic_string& __str, size_type __pos = 0) const
2361 _GLIBCXX_NOEXCEPTnoexcept
2362 { return this->find(__str.data(), __pos, __str.size()); }
2363
2364#if __cplusplus201703L >= 201703L
2365 /**
2366 * @brief Find position of a string_view.
2367 * @param __svt The object convertible to string_view to locate.
2368 * @param __pos Index of character to search from (default 0).
2369 * @return Index of start of first occurrence.
2370 */
2371 template<typename _Tp>
2372 _If_sv<_Tp, size_type>
2373 find(const _Tp& __svt, size_type __pos = 0) const
2374 noexcept(is_same<_Tp, __sv_type>::value)
2375 {
2376 __sv_type __sv = __svt;
2377 return this->find(__sv.data(), __pos, __sv.size());
2378 }
2379#endif // C++17
2380
2381 /**
2382 * @brief Find position of a C string.
2383 * @param __s C string to locate.
2384 * @param __pos Index of character to search from (default 0).
2385 * @return Index of start of first occurrence.
2386 *
2387 * Starting from @a __pos, searches forward for the value of @a
2388 * __s within this string. If found, returns the index where
2389 * it begins. If not found, returns npos.
2390 */
2391 size_type
2392 find(const _CharT* __s, size_type __pos = 0) const _GLIBCXX_NOEXCEPTnoexcept
2393 {
2394 __glibcxx_requires_string(__s);
2395 return this->find(__s, __pos, traits_type::length(__s));
2396 }
2397
2398 /**
2399 * @brief Find position of a character.
2400 * @param __c Character to locate.
2401 * @param __pos Index of character to search from (default 0).
2402 * @return Index of first occurrence.
2403 *
2404 * Starting from @a __pos, searches forward for @a __c within
2405 * this string. If found, returns the index where it was
2406 * found. If not found, returns npos.
2407 */
2408 size_type
2409 find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPTnoexcept;
2410
2411 /**
2412 * @brief Find last position of a string.
2413 * @param __str String to locate.
2414 * @param __pos Index of character to search back from (default end).
2415 * @return Index of start of last occurrence.
2416 *
2417 * Starting from @a __pos, searches backward for value of @a
2418 * __str within this string. If found, returns the index where
2419 * it begins. If not found, returns npos.
2420 */
2421 size_type
2422 rfind(const basic_string& __str, size_type __pos = npos) const
2423 _GLIBCXX_NOEXCEPTnoexcept
2424 { return this->rfind(__str.data(), __pos, __str.size()); }
2425
2426#if __cplusplus201703L >= 201703L
2427 /**
2428 * @brief Find last position of a string_view.
2429 * @param __svt The object convertible to string_view to locate.
2430 * @param __pos Index of character to search back from (default end).
2431 * @return Index of start of last occurrence.
2432 */
2433 template<typename _Tp>
2434 _If_sv<_Tp, size_type>
2435 rfind(const _Tp& __svt, size_type __pos = npos) const
2436 noexcept(is_same<_Tp, __sv_type>::value)
2437 {
2438 __sv_type __sv = __svt;
2439 return this->rfind(__sv.data(), __pos, __sv.size());
2440 }
2441#endif // C++17
2442
2443 /**
2444 * @brief Find last position of a C substring.
2445 * @param __s C string to locate.
2446 * @param __pos Index of character to search back from.
2447 * @param __n Number of characters from s to search for.
2448 * @return Index of start of last occurrence.
2449 *
2450 * Starting from @a __pos, searches backward for the first @a
2451 * __n characters in @a __s within this string. If found,
2452 * returns the index where it begins. If not found, returns
2453 * npos.
2454 */
2455 size_type
2456 rfind(const _CharT* __s, size_type __pos, size_type __n) const
2457 _GLIBCXX_NOEXCEPTnoexcept;
2458
2459 /**
2460 * @brief Find last position of a C string.
2461 * @param __s C string to locate.
2462 * @param __pos Index of character to start search at (default end).
2463 * @return Index of start of last occurrence.
2464 *
2465 * Starting from @a __pos, searches backward for the value of
2466 * @a __s within this string. If found, returns the index
2467 * where it begins. If not found, returns npos.
2468 */
2469 size_type
2470 rfind(const _CharT* __s, size_type __pos = npos) const
2471 {
2472 __glibcxx_requires_string(__s);
2473 return this->rfind(__s, __pos, traits_type::length(__s));
2474 }
2475
2476 /**
2477 * @brief Find last position of a character.
2478 * @param __c Character to locate.
2479 * @param __pos Index of character to search back from (default end).
2480 * @return Index of last occurrence.
2481 *
2482 * Starting from @a __pos, searches backward for @a __c within
2483 * this string. If found, returns the index where it was
2484 * found. If not found, returns npos.
2485 */
2486 size_type
2487 rfind(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPTnoexcept;
2488
2489 /**
2490 * @brief Find position of a character of string.
2491 * @param __str String containing characters to locate.
2492 * @param __pos Index of character to search from (default 0).
2493 * @return Index of first occurrence.
2494 *
2495 * Starting from @a __pos, searches forward for one of the
2496 * characters of @a __str within this string. If found,
2497 * returns the index where it was found. If not found, returns
2498 * npos.
2499 */
2500 size_type
2501 find_first_of(const basic_string& __str, size_type __pos = 0) const
2502 _GLIBCXX_NOEXCEPTnoexcept
2503 { return this->find_first_of(__str.data(), __pos, __str.size()); }
2504
2505#if __cplusplus201703L >= 201703L
2506 /**
2507 * @brief Find position of a character of a string_view.
2508 * @param __svt An object convertible to string_view containing
2509 * characters to locate.
2510 * @param __pos Index of character to search from (default 0).
2511 * @return Index of first occurrence.
2512 */
2513 template<typename _Tp>
2514 _If_sv<_Tp, size_type>
2515 find_first_of(const _Tp& __svt, size_type __pos = 0) const
2516 noexcept(is_same<_Tp, __sv_type>::value)
2517 {
2518 __sv_type __sv = __svt;
2519 return this->find_first_of(__sv.data(), __pos, __sv.size());
2520 }
2521#endif // C++17
2522
2523 /**
2524 * @brief Find position of a character of C substring.
2525 * @param __s String containing characters to locate.
2526 * @param __pos Index of character to search from.
2527 * @param __n Number of characters from s to search for.
2528 * @return Index of first occurrence.
2529 *
2530 * Starting from @a __pos, searches forward for one of the
2531 * first @a __n characters of @a __s within this string. If
2532 * found, returns the index where it was found. If not found,
2533 * returns npos.
2534 */
2535 size_type
2536 find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
2537 _GLIBCXX_NOEXCEPTnoexcept;
2538
2539 /**
2540 * @brief Find position of a character of C string.
2541 * @param __s String containing characters to locate.
2542 * @param __pos Index of character to search from (default 0).
2543 * @return Index of first occurrence.
2544 *
2545 * Starting from @a __pos, searches forward for one of the
2546 * characters of @a __s within this string. If found, returns
2547 * the index where it was found. If not found, returns npos.
2548 */
2549 size_type
2550 find_first_of(const _CharT* __s, size_type __pos = 0) const
2551 _GLIBCXX_NOEXCEPTnoexcept
2552 {
2553 __glibcxx_requires_string(__s);
2554 return this->find_first_of(__s, __pos, traits_type::length(__s));
2555 }
2556
2557 /**
2558 * @brief Find position of a character.
2559 * @param __c Character to locate.
2560 * @param __pos Index of character to search from (default 0).
2561 * @return Index of first occurrence.
2562 *
2563 * Starting from @a __pos, searches forward for the character
2564 * @a __c within this string. If found, returns the index
2565 * where it was found. If not found, returns npos.
2566 *
2567 * Note: equivalent to find(__c, __pos).
2568 */
2569 size_type
2570 find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPTnoexcept
2571 { return this->find(__c, __pos); }
2572
2573 /**
2574 * @brief Find last position of a character of string.
2575 * @param __str String containing characters to locate.
2576 * @param __pos Index of character to search back from (default end).
2577 * @return Index of last occurrence.
2578 *
2579 * Starting from @a __pos, searches backward for one of the
2580 * characters of @a __str within this string. If found,
2581 * returns the index where it was found. If not found, returns
2582 * npos.
2583 */
2584 size_type
2585 find_last_of(const basic_string& __str, size_type __pos = npos) const
2586 _GLIBCXX_NOEXCEPTnoexcept
2587 { return this->find_last_of(__str.data(), __pos, __str.size()); }
2588
2589#if __cplusplus201703L >= 201703L
2590 /**
2591 * @brief Find last position of a character of string.
2592 * @param __svt An object convertible to string_view containing
2593 * characters to locate.
2594 * @param __pos Index of character to search back from (default end).
2595 * @return Index of last occurrence.
2596 */
2597 template<typename _Tp>
2598 _If_sv<_Tp, size_type>
2599 find_last_of(const _Tp& __svt, size_type __pos = npos) const
2600 noexcept(is_same<_Tp, __sv_type>::value)
2601 {
2602 __sv_type __sv = __svt;
2603 return this->find_last_of(__sv.data(), __pos, __sv.size());
2604 }
2605#endif // C++17
2606
2607 /**
2608 * @brief Find last position of a character of C substring.
2609 * @param __s C string containing characters to locate.
2610 * @param __pos Index of character to search back from.
2611 * @param __n Number of characters from s to search for.
2612 * @return Index of last occurrence.
2613 *
2614 * Starting from @a __pos, searches backward for one of the
2615 * first @a __n characters of @a __s within this string. If
2616 * found, returns the index where it was found. If not found,
2617 * returns npos.
2618 */
2619 size_type
2620 find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
2621 _GLIBCXX_NOEXCEPTnoexcept;
2622
2623 /**
2624 * @brief Find last position of a character of C string.
2625 * @param __s C string containing characters to locate.
2626 * @param __pos Index of character to search back from (default end).
2627 * @return Index of last occurrence.
2628 *
2629 * Starting from @a __pos, searches backward for one of the
2630 * characters of @a __s within this string. If found, returns
2631 * the index where it was found. If not found, returns npos.
2632 */
2633 size_type
2634 find_last_of(const _CharT* __s, size_type __pos = npos) const
2635 _GLIBCXX_NOEXCEPTnoexcept
2636 {
2637 __glibcxx_requires_string(__s);
2638 return this->find_last_of(__s, __pos, traits_type::length(__s));
2639 }
2640
2641 /**
2642 * @brief Find last position of a character.
2643 * @param __c Character to locate.
2644 * @param __pos Index of character to search back from (default end).
2645 * @return Index of last occurrence.
2646 *
2647 * Starting from @a __pos, searches backward for @a __c within
2648 * this string. If found, returns the index where it was
2649 * found. If not found, returns npos.
2650 *
2651 * Note: equivalent to rfind(__c, __pos).
2652 */
2653 size_type
2654 find_last_of(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPTnoexcept
2655 { return this->rfind(__c, __pos); }
2656
2657 /**
2658 * @brief Find position of a character not in string.
2659 * @param __str String containing characters to avoid.
2660 * @param __pos Index of character to search from (default 0).
2661 * @return Index of first occurrence.
2662 *
2663 * Starting from @a __pos, searches forward for a character not contained
2664 * in @a __str within this string. If found, returns the index where it
2665 * was found. If not found, returns npos.
2666 */
2667 size_type
2668 find_first_not_of(const basic_string& __str, size_type __pos = 0) const
2669 _GLIBCXX_NOEXCEPTnoexcept
2670 { return this->find_first_not_of(__str.data(), __pos, __str.size()); }
2671
2672#if __cplusplus201703L >= 201703L
2673 /**
2674 * @brief Find position of a character not in a string_view.
2675 * @param __svt A object convertible to string_view containing
2676 * characters to avoid.
2677 * @param __pos Index of character to search from (default 0).
2678 * @return Index of first occurrence.
2679 */
2680 template<typename _Tp>
2681 _If_sv<_Tp, size_type>
2682 find_first_not_of(const _Tp& __svt, size_type __pos = 0) const
2683 noexcept(is_same<_Tp, __sv_type>::value)
2684 {
2685 __sv_type __sv = __svt;
2686 return this->find_first_not_of(__sv.data(), __pos, __sv.size());
2687 }
2688#endif // C++17
2689
2690 /**
2691 * @brief Find position of a character not in C substring.
2692 * @param __s C string containing characters to avoid.
2693 * @param __pos Index of character to search from.
2694 * @param __n Number of characters from __s to consider.
2695 * @return Index of first occurrence.
2696 *
2697 * Starting from @a __pos, searches forward for a character not
2698 * contained in the first @a __n characters of @a __s within
2699 * this string. If found, returns the index where it was
2700 * found. If not found, returns npos.
2701 */
2702 size_type
2703 find_first_not_of(const _CharT* __s, size_type __pos,
2704 size_type __n) const _GLIBCXX_NOEXCEPTnoexcept;
2705
2706 /**
2707 * @brief Find position of a character not in C string.
2708 * @param __s C string containing characters to avoid.
2709 * @param __pos Index of character to search from (default 0).
2710 * @return Index of first occurrence.
2711 *
2712 * Starting from @a __pos, searches forward for a character not
2713 * contained in @a __s within this string. If found, returns
2714 * the index where it was found. If not found, returns npos.
2715 */
2716 size_type
2717 find_first_not_of(const _CharT* __s, size_type __pos = 0) const
2718 _GLIBCXX_NOEXCEPTnoexcept
2719 {
2720 __glibcxx_requires_string(__s);
2721 return this->find_first_not_of(__s, __pos, traits_type::length(__s));
2722 }
2723
2724 /**
2725 * @brief Find position of a different character.
2726 * @param __c Character to avoid.
2727 * @param __pos Index of character to search from (default 0).
2728 * @return Index of first occurrence.
2729 *
2730 * Starting from @a __pos, searches forward for a character
2731 * other than @a __c within this string. If found, returns the
2732 * index where it was found. If not found, returns npos.
2733 */
2734 size_type
2735 find_first_not_of(_CharT __c, size_type __pos = 0) const
2736 _GLIBCXX_NOEXCEPTnoexcept;
2737
2738 /**
2739 * @brief Find last position of a character not in string.
2740 * @param __str String containing characters to avoid.
2741 * @param __pos Index of character to search back from (default end).
2742 * @return Index of last occurrence.
2743 *
2744 * Starting from @a __pos, searches backward for a character
2745 * not contained in @a __str within this string. If found,
2746 * returns the index where it was found. If not found, returns
2747 * npos.
2748 */
2749 size_type
2750 find_last_not_of(const basic_string& __str, size_type __pos = npos) const
2751 _GLIBCXX_NOEXCEPTnoexcept
2752 { return this->find_last_not_of(__str.data(), __pos, __str.size()); }
2753
2754#if __cplusplus201703L >= 201703L
2755 /**
2756 * @brief Find last position of a character not in a string_view.
2757 * @param __svt An object convertible to string_view containing
2758 * characters to avoid.
2759 * @param __pos Index of character to search back from (default end).
2760 * @return Index of last occurrence.
2761 */
2762 template<typename _Tp>
2763 _If_sv<_Tp, size_type>
2764 find_last_not_of(const _Tp& __svt, size_type __pos = npos) const
2765 noexcept(is_same<_Tp, __sv_type>::value)
2766 {
2767 __sv_type __sv = __svt;
2768 return this->find_last_not_of(__sv.data(), __pos, __sv.size());
2769 }
2770#endif // C++17
2771
2772 /**
2773 * @brief Find last position of a character not in C substring.
2774 * @param __s C string containing characters to avoid.
2775 * @param __pos Index of character to search back from.
2776 * @param __n Number of characters from s to consider.
2777 * @return Index of last occurrence.
2778 *
2779 * Starting from @a __pos, searches backward for a character not
2780 * contained in the first @a __n characters of @a __s within this string.
2781 * If found, returns the index where it was found. If not found,
2782 * returns npos.
2783 */
2784 size_type
2785 find_last_not_of(const _CharT* __s, size_type __pos,
2786 size_type __n) const _GLIBCXX_NOEXCEPTnoexcept;
2787 /**
2788 * @brief Find last position of a character not in C string.
2789 * @param __s C string containing characters to avoid.
2790 * @param __pos Index of character to search back from (default end).
2791 * @return Index of last occurrence.
2792 *
2793 * Starting from @a __pos, searches backward for a character
2794 * not contained in @a __s within this string. If found,
2795 * returns the index where it was found. If not found, returns
2796 * npos.
2797 */
2798 size_type
2799 find_last_not_of(const _CharT* __s, size_type __pos = npos) const
2800 _GLIBCXX_NOEXCEPTnoexcept
2801 {
2802 __glibcxx_requires_string(__s);
2803 return this->find_last_not_of(__s, __pos, traits_type::length(__s));
2804 }
2805
2806 /**
2807 * @brief Find last position of a different character.
2808 * @param __c Character to avoid.
2809 * @param __pos Index of character to search back from (default end).
2810 * @return Index of last occurrence.
2811 *
2812 * Starting from @a __pos, searches backward for a character other than
2813 * @a __c within this string. If found, returns the index where it was
2814 * found. If not found, returns npos.
2815 */
2816 size_type
2817 find_last_not_of(_CharT __c, size_type __pos = npos) const
2818 _GLIBCXX_NOEXCEPTnoexcept;
2819
2820 /**
2821 * @brief Get a substring.
2822 * @param __pos Index of first character (default 0).
2823 * @param __n Number of characters in substring (default remainder).
2824 * @return The new string.
2825 * @throw std::out_of_range If __pos > size().
2826 *
2827 * Construct and return a new string using the @a __n
2828 * characters starting at @a __pos. If the string is too
2829 * short, use the remainder of the characters. If @a __pos is
2830 * beyond the end of the string, out_of_range is thrown.
2831 */
2832 basic_string
2833 substr(size_type __pos = 0, size_type __n = npos) const
2834 { return basic_string(*this,
2835 _M_check(__pos, "basic_string::substr"), __n); }
2836
2837 /**
2838 * @brief Compare to a string.
2839 * @param __str String to compare against.
2840 * @return Integer < 0, 0, or > 0.
2841 *
2842 * Returns an integer < 0 if this string is ordered before @a
2843 * __str, 0 if their values are equivalent, or > 0 if this
2844 * string is ordered after @a __str. Determines the effective
2845 * length rlen of the strings to compare as the smallest of
2846 * size() and str.size(). The function then compares the two
2847 * strings by calling traits::compare(data(), str.data(),rlen).
2848 * If the result of the comparison is nonzero returns it,
2849 * otherwise the shorter one is ordered first.
2850 */
2851 int
2852 compare(const basic_string& __str) const
2853 {
2854 const size_type __size = this->size();
2855 const size_type __osize = __str.size();
2856 const size_type __len = std::min(__size, __osize);
2857
2858 int __r = traits_type::compare(_M_data(), __str.data(), __len);
2859 if (!__r)
2860 __r = _S_compare(__size, __osize);
2861 return __r;
2862 }
2863
2864#if __cplusplus201703L >= 201703L
2865 /**
2866 * @brief Compare to a string_view.
2867 * @param __svt An object convertible to string_view to compare against.
2868 * @return Integer < 0, 0, or > 0.
2869 */
2870 template<typename _Tp>
2871 _If_sv<_Tp, int>
2872 compare(const _Tp& __svt) const
2873 noexcept(is_same<_Tp, __sv_type>::value)
2874 {
2875 __sv_type __sv = __svt;
2876 const size_type __size = this->size();
2877 const size_type __osize = __sv.size();
2878 const size_type __len = std::min(__size, __osize);
2879
2880 int __r = traits_type::compare(_M_data(), __sv.data(), __len);
2881 if (!__r)
2882 __r = _S_compare(__size, __osize);
2883 return __r;
2884 }
2885
2886 /**
2887 * @brief Compare to a string_view.
2888 * @param __pos A position in the string to start comparing from.
2889 * @param __n The number of characters to compare.
2890 * @param __svt An object convertible to string_view to compare
2891 * against.
2892 * @return Integer < 0, 0, or > 0.
2893 */
2894 template<typename _Tp>
2895 _If_sv<_Tp, int>
2896 compare(size_type __pos, size_type __n, const _Tp& __svt) const
2897 noexcept(is_same<_Tp, __sv_type>::value)
2898 {
2899 __sv_type __sv = __svt;
2900 return __sv_type(*this).substr(__pos, __n).compare(__sv);
2901 }
2902
2903 /**
2904 * @brief Compare to a string_view.
2905 * @param __pos1 A position in the string to start comparing from.
2906 * @param __n1 The number of characters to compare.
2907 * @param __svt An object convertible to string_view to compare
2908 * against.
2909 * @param __pos2 A position in the string_view to start comparing from.
2910 * @param __n2 The number of characters to compare.
2911 * @return Integer < 0, 0, or > 0.
2912 */
2913 template<typename _Tp>
2914 _If_sv<_Tp, int>
2915 compare(size_type __pos1, size_type __n1, const _Tp& __svt,
2916 size_type __pos2, size_type __n2 = npos) const
2917 noexcept(is_same<_Tp, __sv_type>::value)
2918 {
2919 __sv_type __sv = __svt;
2920 return __sv_type(*this)
2921 .substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
2922 }
2923#endif // C++17
2924
2925 /**
2926 * @brief Compare substring to a string.
2927 * @param __pos Index of first character of substring.
2928 * @param __n Number of characters in substring.
2929 * @param __str String to compare against.
2930 * @return Integer < 0, 0, or > 0.
2931 *
2932 * Form the substring of this string from the @a __n characters
2933 * starting at @a __pos. Returns an integer < 0 if the
2934 * substring is ordered before @a __str, 0 if their values are
2935 * equivalent, or > 0 if the substring is ordered after @a
2936 * __str. Determines the effective length rlen of the strings
2937 * to compare as the smallest of the length of the substring
2938 * and @a __str.size(). The function then compares the two
2939 * strings by calling
2940 * traits::compare(substring.data(),str.data(),rlen). If the
2941 * result of the comparison is nonzero returns it, otherwise
2942 * the shorter one is ordered first.
2943 */
2944 int
2945 compare(size_type __pos, size_type __n, const basic_string& __str) const;
2946
2947 /**
2948 * @brief Compare substring to a substring.
2949 * @param __pos1 Index of first character of substring.
2950 * @param __n1 Number of characters in substring.
2951 * @param __str String to compare against.
2952 * @param __pos2 Index of first character of substring of str.
2953 * @param __n2 Number of characters in substring of str.
2954 * @return Integer < 0, 0, or > 0.
2955 *
2956 * Form the substring of this string from the @a __n1
2957 * characters starting at @a __pos1. Form the substring of @a
2958 * __str from the @a __n2 characters starting at @a __pos2.
2959 * Returns an integer < 0 if this substring is ordered before
2960 * the substring of @a __str, 0 if their values are equivalent,
2961 * or > 0 if this substring is ordered after the substring of
2962 * @a __str. Determines the effective length rlen of the
2963 * strings to compare as the smallest of the lengths of the
2964 * substrings. The function then compares the two strings by
2965 * calling
2966 * traits::compare(substring.data(),str.substr(pos2,n2).data(),rlen).
2967 * If the result of the comparison is nonzero returns it,
2968 * otherwise the shorter one is ordered first.
2969 */
2970 int
2971 compare(size_type __pos1, size_type __n1, const basic_string& __str,
2972 size_type __pos2, size_type __n2 = npos) const;
2973
2974 /**
2975 * @brief Compare to a C string.
2976 * @param __s C string to compare against.
2977 * @return Integer < 0, 0, or > 0.
2978 *
2979 * Returns an integer < 0 if this string is ordered before @a __s, 0 if
2980 * their values are equivalent, or > 0 if this string is ordered after
2981 * @a __s. Determines the effective length rlen of the strings to
2982 * compare as the smallest of size() and the length of a string
2983 * constructed from @a __s. The function then compares the two strings
2984 * by calling traits::compare(data(),s,rlen). If the result of the
2985 * comparison is nonzero returns it, otherwise the shorter one is
2986 * ordered first.
2987 */
2988 int
2989 compare(const _CharT* __s) const _GLIBCXX_NOEXCEPTnoexcept;
2990
2991 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2992 // 5 String::compare specification questionable
2993 /**
2994 * @brief Compare substring to a C string.
2995 * @param __pos Index of first character of substring.
2996 * @param __n1 Number of characters in substring.
2997 * @param __s C string to compare against.
2998 * @return Integer < 0, 0, or > 0.
2999 *
3000 * Form the substring of this string from the @a __n1
3001 * characters starting at @a pos. Returns an integer < 0 if
3002 * the substring is ordered before @a __s, 0 if their values
3003 * are equivalent, or > 0 if the substring is ordered after @a
3004 * __s. Determines the effective length rlen of the strings to
3005 * compare as the smallest of the length of the substring and
3006 * the length of a string constructed from @a __s. The
3007 * function then compares the two string by calling
3008 * traits::compare(substring.data(),__s,rlen). If the result of
3009 * the comparison is nonzero returns it, otherwise the shorter
3010 * one is ordered first.
3011 */
3012 int
3013 compare(size_type __pos, size_type __n1, const _CharT* __s) const;
3014
3015 /**
3016 * @brief Compare substring against a character %array.
3017 * @param __pos Index of first character of substring.
3018 * @param __n1 Number of characters in substring.
3019 * @param __s character %array to compare against.
3020 * @param __n2 Number of characters of s.
3021 * @return Integer < 0, 0, or > 0.
3022 *
3023 * Form the substring of this string from the @a __n1
3024 * characters starting at @a __pos. Form a string from the
3025 * first @a __n2 characters of @a __s. Returns an integer < 0
3026 * if this substring is ordered before the string from @a __s,
3027 * 0 if their values are equivalent, or > 0 if this substring
3028 * is ordered after the string from @a __s. Determines the
3029 * effective length rlen of the strings to compare as the
3030 * smallest of the length of the substring and @a __n2. The
3031 * function then compares the two strings by calling
3032 * traits::compare(substring.data(),s,rlen). If the result of
3033 * the comparison is nonzero returns it, otherwise the shorter
3034 * one is ordered first.
3035 *
3036 * NB: s must have at least n2 characters, &apos;\\0&apos; has
3037 * no special meaning.
3038 */
3039 int
3040 compare(size_type __pos, size_type __n1, const _CharT* __s,
3041 size_type __n2) const;
3042
3043#if __cplusplus201703L > 201703L
3044 bool
3045 starts_with(basic_string_view<_CharT, _Traits> __x) const noexcept
3046 { return __sv_type(this->data(), this->size()).starts_with(__x); }
3047
3048 bool
3049 starts_with(_CharT __x) const noexcept
3050 { return __sv_type(this->data(), this->size()).starts_with(__x); }
3051
3052 bool
3053 starts_with(const _CharT* __x) const noexcept
3054 { return __sv_type(this->data(), this->size()).starts_with(__x); }
3055
3056 bool
3057 ends_with(basic_string_view<_CharT, _Traits> __x) const noexcept
3058 { return __sv_type(this->data(), this->size()).ends_with(__x); }
3059
3060 bool
3061 ends_with(_CharT __x) const noexcept
3062 { return __sv_type(this->data(), this->size()).ends_with(__x); }
3063
3064 bool
3065 ends_with(const _CharT* __x) const noexcept
3066 { return __sv_type(this->data(), this->size()).ends_with(__x); }
3067#endif // C++20
3068
3069 // Allow basic_stringbuf::__xfer_bufptrs to call _M_length:
3070 template<typename, typename, typename> friend class basic_stringbuf;
3071 };
3072_GLIBCXX_END_NAMESPACE_CXX11}
3073#else // !_GLIBCXX_USE_CXX11_ABI
3074 // Reference-counted COW string implentation
3075
3076 /**
3077 * @class basic_string basic_string.h <string>
3078 * @brief Managing sequences of characters and character-like objects.
3079 *
3080 * @ingroup strings
3081 * @ingroup sequences
3082 *
3083 * @tparam _CharT Type of character
3084 * @tparam _Traits Traits for character type, defaults to
3085 * char_traits<_CharT>.
3086 * @tparam _Alloc Allocator type, defaults to allocator<_CharT>.
3087 *
3088 * Meets the requirements of a <a href="tables.html#65">container</a>, a
3089 * <a href="tables.html#66">reversible container</a>, and a
3090 * <a href="tables.html#67">sequence</a>. Of the
3091 * <a href="tables.html#68">optional sequence requirements</a>, only
3092 * @c push_back, @c at, and @c %array access are supported.
3093 *
3094 * @doctodo
3095 *
3096 *
3097 * Documentation? What's that?
3098 * Nathan Myers <ncm@cantrip.org>.
3099 *
3100 * A string looks like this:
3101 *
3102 * @code
3103 * [_Rep]
3104 * _M_length
3105 * [basic_string<char_type>] _M_capacity
3106 * _M_dataplus _M_refcount
3107 * _M_p ----------------> unnamed array of char_type
3108 * @endcode
3109 *
3110 * Where the _M_p points to the first character in the string, and
3111 * you cast it to a pointer-to-_Rep and subtract 1 to get a
3112 * pointer to the header.
3113 *
3114 * This approach has the enormous advantage that a string object
3115 * requires only one allocation. All the ugliness is confined
3116 * within a single %pair of inline functions, which each compile to
3117 * a single @a add instruction: _Rep::_M_data(), and
3118 * string::_M_rep(); and the allocation function which gets a
3119 * block of raw bytes and with room enough and constructs a _Rep
3120 * object at the front.
3121 *
3122 * The reason you want _M_data pointing to the character %array and
3123 * not the _Rep is so that the debugger can see the string
3124 * contents. (Probably we should add a non-inline member to get
3125 * the _Rep for the debugger to use, so users can check the actual
3126 * string length.)
3127 *
3128 * Note that the _Rep object is a POD so that you can have a
3129 * static <em>empty string</em> _Rep object already @a constructed before
3130 * static constructors have run. The reference-count encoding is
3131 * chosen so that a 0 indicates one reference, so you never try to
3132 * destroy the empty-string _Rep object.
3133 *
3134 * All but the last paragraph is considered pretty conventional
3135 * for a C++ string implementation.
3136 */
3137 // 21.3 Template class basic_string
3138 template<typename _CharT, typename _Traits, typename _Alloc>
3139 class basic_string
3140 {
3141 typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
3142 rebind<_CharT>::other _CharT_alloc_type;
3143 typedef __gnu_cxx::__alloc_traits<_CharT_alloc_type> _CharT_alloc_traits;
3144
3145 // Types:
3146 public:
3147 typedef _Traits traits_type;
3148 typedef typename _Traits::char_type value_type;
3149 typedef _Alloc allocator_type;
3150 typedef typename _CharT_alloc_type::size_type size_type;
3151 typedef typename _CharT_alloc_type::difference_type difference_type;
3152#if __cplusplus201703L < 201103L
3153 typedef typename _CharT_alloc_type::reference reference;
3154 typedef typename _CharT_alloc_type::const_reference const_reference;
3155#else
3156 typedef value_type& reference;
3157 typedef const value_type& const_reference;
3158#endif
3159 typedef typename _CharT_alloc_traits::pointer pointer;
3160 typedef typename _CharT_alloc_traits::const_pointer const_pointer;
3161 typedef __gnu_cxx::__normal_iterator<pointer, basic_string> iterator;
3162 typedef __gnu_cxx::__normal_iterator<const_pointer, basic_string>
3163 const_iterator;
3164 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
3165 typedef std::reverse_iterator<iterator> reverse_iterator;
3166
3167 protected:
3168 // type used for positions in insert, erase etc.
3169 typedef iterator __const_iterator;
3170
3171 private:
3172 // _Rep: string representation
3173 // Invariants:
3174 // 1. String really contains _M_length + 1 characters: due to 21.3.4
3175 // must be kept null-terminated.
3176 // 2. _M_capacity >= _M_length
3177 // Allocated memory is always (_M_capacity + 1) * sizeof(_CharT).
3178 // 3. _M_refcount has three states:
3179 // -1: leaked, one reference, no ref-copies allowed, non-const.
3180 // 0: one reference, non-const.
3181 // n>0: n + 1 references, operations require a lock, const.
3182 // 4. All fields==0 is an empty string, given the extra storage
3183 // beyond-the-end for a null terminator; thus, the shared
3184 // empty string representation needs no constructor.
3185
3186 struct _Rep_base
3187 {
3188 size_type _M_length;
3189 size_type _M_capacity;
3190 _Atomic_word _M_refcount;
3191 };
3192
3193 struct _Rep : _Rep_base
3194 {
3195 // Types:
3196 typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
3197 rebind<char>::other _Raw_bytes_alloc;
3198
3199 // (Public) Data members:
3200
3201 // The maximum number of individual char_type elements of an
3202 // individual string is determined by _S_max_size. This is the
3203 // value that will be returned by max_size(). (Whereas npos
3204 // is the maximum number of bytes the allocator can allocate.)
3205 // If one was to divvy up the theoretical largest size string,
3206 // with a terminating character and m _CharT elements, it'd
3207 // look like this:
3208 // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT)
3209 // Solving for m:
3210 // m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1
3211 // In addition, this implementation quarters this amount.
3212 static const size_type _S_max_size;
3213 static const _CharT _S_terminal;
3214
3215 // The following storage is init'd to 0 by the linker, resulting
3216 // (carefully) in an empty string with one reference.
3217 static size_type _S_empty_rep_storage[];
3218
3219 static _Rep&
3220 _S_empty_rep() _GLIBCXX_NOEXCEPTnoexcept
3221 {
3222 // NB: Mild hack to avoid strict-aliasing warnings. Note that
3223 // _S_empty_rep_storage is never modified and the punning should
3224 // be reasonably safe in this case.
3225 void* __p = reinterpret_cast<void*>(&_S_empty_rep_storage);
3226 return *reinterpret_cast<_Rep*>(__p);
3227 }
3228
3229 bool
3230 _M_is_leaked() const _GLIBCXX_NOEXCEPTnoexcept
3231 {
3232#if defined(__GTHREADS1)
3233 // _M_refcount is mutated concurrently by _M_refcopy/_M_dispose,
3234 // so we need to use an atomic load. However, _M_is_leaked
3235 // predicate does not change concurrently (i.e. the string is either
3236 // leaked or not), so a relaxed load is enough.
3237 return __atomic_load_n(&this->_M_refcount, __ATOMIC_RELAXED0) < 0;
3238#else
3239 return this->_M_refcount < 0;
3240#endif
3241 }
3242
3243 bool
3244 _M_is_shared() const _GLIBCXX_NOEXCEPTnoexcept
3245 {
3246#if defined(__GTHREADS1)
3247 // _M_refcount is mutated concurrently by _M_refcopy/_M_dispose,
3248 // so we need to use an atomic load. Another thread can drop last
3249 // but one reference concurrently with this check, so we need this
3250 // load to be acquire to synchronize with release fetch_and_add in
3251 // _M_dispose.
3252 return __atomic_load_n(&this->_M_refcount, __ATOMIC_ACQUIRE2) > 0;
3253#else
3254 return this->_M_refcount > 0;
3255#endif
3256 }
3257
3258 void
3259 _M_set_leaked() _GLIBCXX_NOEXCEPTnoexcept
3260 { this->_M_refcount = -1; }
3261
3262 void
3263 _M_set_sharable() _GLIBCXX_NOEXCEPTnoexcept
3264 { this->_M_refcount = 0; }
3265
3266 void
3267 _M_set_length_and_sharable(size_type __n) _GLIBCXX_NOEXCEPTnoexcept
3268 {
3269#if _GLIBCXX_FULLY_DYNAMIC_STRING0 == 0
3270 if (__builtin_expect(this != &_S_empty_rep(), false))
3271#endif
3272 {
3273 this->_M_set_sharable(); // One reference.
3274 this->_M_length = __n;
3275 traits_type::assign(this->_M_refdata()[__n], _S_terminal);
3276 // grrr. (per 21.3.4)
3277 // You cannot leave those LWG people alone for a second.
3278 }
3279 }
3280
3281 _CharT*
3282 _M_refdata() throw()
3283 { return reinterpret_cast<_CharT*>(this + 1); }
3284
3285 _CharT*
3286 _M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2)
3287 {
3288 return (!_M_is_leaked() && __alloc1 == __alloc2)
3289 ? _M_refcopy() : _M_clone(__alloc1);
3290 }
3291
3292 // Create & Destroy
3293 static _Rep*
3294 _S_create(size_type, size_type, const _Alloc&);
3295
3296 void
3297 _M_dispose(const _Alloc& __a) _GLIBCXX_NOEXCEPTnoexcept
3298 {
3299#if _GLIBCXX_FULLY_DYNAMIC_STRING0 == 0
3300 if (__builtin_expect(this != &_S_empty_rep(), false))
3301#endif
3302 {
3303 // Be race-detector-friendly. For more info see bits/c++config.
3304 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&this->_M_refcount);
3305 // Decrement of _M_refcount is acq_rel, because:
3306 // - all but last decrements need to release to synchronize with
3307 // the last decrement that will delete the object.
3308 // - the last decrement needs to acquire to synchronize with
3309 // all the previous decrements.
3310 // - last but one decrement needs to release to synchronize with
3311 // the acquire load in _M_is_shared that will conclude that
3312 // the object is not shared anymore.
3313 if (__gnu_cxx::__exchange_and_add_dispatch(&this->_M_refcount,
3314 -1) <= 0)
3315 {
3316 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&this->_M_refcount);
3317 _M_destroy(__a);
3318 }
3319 }
3320 } // XXX MT
3321
3322 void
3323 _M_destroy(const _Alloc&) throw();
3324
3325 _CharT*
3326 _M_refcopy() throw()
3327 {
3328#if _GLIBCXX_FULLY_DYNAMIC_STRING0 == 0
3329 if (__builtin_expect(this != &_S_empty_rep(), false))
3330#endif
3331 __gnu_cxx::__atomic_add_dispatch(&this->_M_refcount, 1);
3332 return _M_refdata();
3333 } // XXX MT
3334
3335 _CharT*
3336 _M_clone(const _Alloc&, size_type __res = 0);
3337 };
3338
3339 // Use empty-base optimization: http://www.cantrip.org/emptyopt.html
3340 struct _Alloc_hider : _Alloc
3341 {
3342 _Alloc_hider(_CharT* __dat, const _Alloc& __a) _GLIBCXX_NOEXCEPTnoexcept
3343 : _Alloc(__a), _M_p(__dat) { }
3344
3345 _CharT* _M_p; // The actual data.
3346 };
3347
3348 public:
3349 // Data Members (public):
3350 // NB: This is an unsigned type, and thus represents the maximum
3351 // size that the allocator can hold.
3352 /// Value returned by various member functions when they fail.
3353 static const size_type npos = static_cast<size_type>(-1);
3354
3355 private:
3356 // Data Members (private):
3357 mutable _Alloc_hider _M_dataplus;
3358
3359 _CharT*
3360 _M_data() const _GLIBCXX_NOEXCEPTnoexcept
3361 { return _M_dataplus._M_p; }
3362
3363 _CharT*
3364 _M_data(_CharT* __p) _GLIBCXX_NOEXCEPTnoexcept
3365 { return (_M_dataplus._M_p = __p); }
3366
3367 _Rep*
3368 _M_rep() const _GLIBCXX_NOEXCEPTnoexcept
3369 { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); }
3370
3371 // For the internal use we have functions similar to `begin'/`end'
3372 // but they do not call _M_leak.
3373 iterator
3374 _M_ibegin() const _GLIBCXX_NOEXCEPTnoexcept
3375 { return iterator(_M_data()); }
3376
3377 iterator
3378 _M_iend() const _GLIBCXX_NOEXCEPTnoexcept
3379 { return iterator(_M_data() + this->size()); }
3380
3381 void
3382 _M_leak() // for use in begin() & non-const op[]
3383 {
3384 if (!_M_rep()->_M_is_leaked())
3385 _M_leak_hard();
3386 }
3387
3388 size_type
3389 _M_check(size_type __pos, const char* __s) const
3390 {
3391 if (__pos > this->size())
3392 __throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > "("%s: __pos (which is %zu) > " "this->size() (which is %zu)"
)
3393 "this->size() (which is %zu)")("%s: __pos (which is %zu) > " "this->size() (which is %zu)"
)
,
3394 __s, __pos, this->size());
3395 return __pos;
3396 }
3397
3398 void
3399 _M_check_length(size_type __n1, size_type __n2, const char* __s) const
3400 {
3401 if (this->max_size() - (this->size() - __n1) < __n2)
3402 __throw_length_error(__N(__s)(__s));
3403 }
3404
3405 // NB: _M_limit doesn't check for a bad __pos value.
3406 size_type
3407 _M_limit(size_type __pos, size_type __off) const _GLIBCXX_NOEXCEPTnoexcept
3408 {
3409 const bool __testoff = __off < this->size() - __pos;
3410 return __testoff ? __off : this->size() - __pos;
3411 }
3412
3413 // True if _Rep and source do not overlap.
3414 bool
3415 _M_disjunct(const _CharT* __s) const _GLIBCXX_NOEXCEPTnoexcept
3416 {
3417 return (less<const _CharT*>()(__s, _M_data())
3418 || less<const _CharT*>()(_M_data() + this->size(), __s));
3419 }
3420
3421 // When __n = 1 way faster than the general multichar
3422 // traits_type::copy/move/assign.
3423 static void
3424 _M_copy(_CharT* __d, const _CharT* __s, size_type __n) _GLIBCXX_NOEXCEPTnoexcept
3425 {
3426 if (__n == 1)
3427 traits_type::assign(*__d, *__s);
3428 else
3429 traits_type::copy(__d, __s, __n);
3430 }
3431
3432 static void
3433 _M_move(_CharT* __d, const _CharT* __s, size_type __n) _GLIBCXX_NOEXCEPTnoexcept
3434 {
3435 if (__n == 1)
3436 traits_type::assign(*__d, *__s);
3437 else
3438 traits_type::move(__d, __s, __n);
3439 }
3440
3441 static void
3442 _M_assign(_CharT* __d, size_type __n, _CharT __c) _GLIBCXX_NOEXCEPTnoexcept
3443 {
3444 if (__n == 1)
3445 traits_type::assign(*__d, __c);
3446 else
3447 traits_type::assign(__d, __n, __c);
3448 }
3449
3450 // _S_copy_chars is a separate template to permit specialization
3451 // to optimize for the common case of pointers as iterators.
3452 template<class _Iterator>
3453 static void
3454 _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2)
3455 {
3456 for (; __k1 != __k2; ++__k1, (void)++__p)
3457 traits_type::assign(*__p, *__k1); // These types are off.
3458 }
3459
3460 static void
3461 _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2) _GLIBCXX_NOEXCEPTnoexcept
3462 { _S_copy_chars(__p, __k1.base(), __k2.base()); }
3463
3464 static void
3465 _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2)
3466 _GLIBCXX_NOEXCEPTnoexcept
3467 { _S_copy_chars(__p, __k1.base(), __k2.base()); }
3468
3469 static void
3470 _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) _GLIBCXX_NOEXCEPTnoexcept
3471 { _M_copy(__p, __k1, __k2 - __k1); }
3472
3473 static void
3474 _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2)
3475 _GLIBCXX_NOEXCEPTnoexcept
3476 { _M_copy(__p, __k1, __k2 - __k1); }
3477
3478 static int
3479 _S_compare(size_type __n1, size_type __n2) _GLIBCXX_NOEXCEPTnoexcept
3480 {
3481 const difference_type __d = difference_type(__n1 - __n2);
3482
3483 if (__d > __gnu_cxx::__numeric_traits<int>::__max)
3484 return __gnu_cxx::__numeric_traits<int>::__max;
3485 else if (__d < __gnu_cxx::__numeric_traits<int>::__min)
3486 return __gnu_cxx::__numeric_traits<int>::__min;
3487 else
3488 return int(__d);
3489 }
3490
3491 void
3492 _M_mutate(size_type __pos, size_type __len1, size_type __len2);
3493
3494 void
3495 _M_leak_hard();
3496
3497 static _Rep&
3498 _S_empty_rep() _GLIBCXX_NOEXCEPTnoexcept
3499 { return _Rep::_S_empty_rep(); }
3500
3501#if __cplusplus201703L >= 201703L
3502 // A helper type for avoiding boiler-plate.
3503 typedef basic_string_view<_CharT, _Traits> __sv_type;
3504
3505 template<typename _Tp, typename _Res>
3506 using _If_sv = enable_if_t<
3507 __and_<is_convertible<const _Tp&, __sv_type>,
3508 __not_<is_convertible<const _Tp*, const basic_string*>>,
3509 __not_<is_convertible<const _Tp&, const _CharT*>>>::value,
3510 _Res>;
3511
3512 // Allows an implicit conversion to __sv_type.
3513 static __sv_type
3514 _S_to_string_view(__sv_type __svt) noexcept
3515 { return __svt; }
3516
3517 // Wraps a string_view by explicit conversion and thus
3518 // allows to add an internal constructor that does not
3519 // participate in overload resolution when a string_view
3520 // is provided.
3521 struct __sv_wrapper
3522 {
3523 explicit __sv_wrapper(__sv_type __sv) noexcept : _M_sv(__sv) { }
3524 __sv_type _M_sv;
3525 };
3526
3527 /**
3528 * @brief Only internally used: Construct string from a string view
3529 * wrapper.
3530 * @param __svw string view wrapper.
3531 * @param __a Allocator to use.
3532 */
3533 explicit
3534 basic_string(__sv_wrapper __svw, const _Alloc& __a)
3535 : basic_string(__svw._M_sv.data(), __svw._M_sv.size(), __a) { }
3536#endif
3537
3538 public:
3539 // Construct/copy/destroy:
3540 // NB: We overload ctors in some cases instead of using default
3541 // arguments, per 17.4.4.4 para. 2 item 2.
3542
3543 /**
3544 * @brief Default constructor creates an empty string.
3545 */
3546 basic_string()
3547#if _GLIBCXX_FULLY_DYNAMIC_STRING0 == 0
3548 _GLIBCXX_NOEXCEPTnoexcept
3549 : _M_dataplus(_S_empty_rep()._M_refdata(), _Alloc())
3550#else
3551 : _M_dataplus(_S_construct(size_type(), _CharT(), _Alloc()), _Alloc())
3552#endif
3553 { }
3554
3555 /**
3556 * @brief Construct an empty string using allocator @a a.
3557 */
3558 explicit
3559 basic_string(const _Alloc& __a);
3560
3561 // NB: per LWG issue 42, semantics different from IS:
3562 /**
3563 * @brief Construct string with copy of value of @a str.
3564 * @param __str Source string.
3565 */
3566 basic_string(const basic_string& __str);
3567
3568 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3569 // 2583. no way to supply an allocator for basic_string(str, pos)
3570 /**
3571 * @brief Construct string as copy of a substring.
3572 * @param __str Source string.
3573 * @param __pos Index of first character to copy from.
3574 * @param __a Allocator to use.
3575 */
3576 basic_string(const basic_string& __str, size_type __pos,
3577 const _Alloc& __a = _Alloc());
3578
3579 /**
3580 * @brief Construct string as copy of a substring.
3581 * @param __str Source string.
3582 * @param __pos Index of first character to copy from.
3583 * @param __n Number of characters to copy.
3584 */
3585 basic_string(const basic_string& __str, size_type __pos,
3586 size_type __n);
3587 /**
3588 * @brief Construct string as copy of a substring.
3589 * @param __str Source string.
3590 * @param __pos Index of first character to copy from.
3591 * @param __n Number of characters to copy.
3592 * @param __a Allocator to use.
3593 */
3594 basic_string(const basic_string& __str, size_type __pos,
3595 size_type __n, const _Alloc& __a);
3596
3597 /**
3598 * @brief Construct string initialized by a character %array.
3599 * @param __s Source character %array.
3600 * @param __n Number of characters to copy.
3601 * @param __a Allocator to use (default is default allocator).
3602 *
3603 * NB: @a __s must have at least @a __n characters, &apos;\\0&apos;
3604 * has no special meaning.
3605 */
3606 basic_string(const _CharT* __s, size_type __n,
3607 const _Alloc& __a = _Alloc());
3608
3609 /**
3610 * @brief Construct string as copy of a C string.
3611 * @param __s Source C string.
3612 * @param __a Allocator to use (default is default allocator).
3613 */
3614#if __cpp_deduction_guides201703L && ! defined _GLIBCXX_DEFINING_STRING_INSTANTIATIONS
3615 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3616 // 3076. basic_string CTAD ambiguity
3617 template<typename = _RequireAllocator<_Alloc>>
3618#endif
3619 basic_string(const _CharT* __s, const _Alloc& __a = _Alloc())
3620 : _M_dataplus(_S_construct(__s, __s ? __s + traits_type::length(__s) :
3621 __s + npos, __a), __a)
3622 { }
3623
3624 /**
3625 * @brief Construct string as multiple characters.
3626 * @param __n Number of characters.
3627 * @param __c Character to use.
3628 * @param __a Allocator to use (default is default allocator).
3629 */
3630 basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc());
3631
3632#if __cplusplus201703L >= 201103L
3633 /**
3634 * @brief Move construct string.
3635 * @param __str Source string.
3636 *
3637 * The newly-created string contains the exact contents of @a __str.
3638 * @a __str is a valid, but unspecified string.
3639 **/
3640 basic_string(basic_string&& __str)
3641#if _GLIBCXX_FULLY_DYNAMIC_STRING0 == 0
3642 noexcept // FIXME C++11: should always be noexcept.
3643#endif
3644 : _M_dataplus(std::move(__str._M_dataplus))
3645 {
3646#if _GLIBCXX_FULLY_DYNAMIC_STRING0 == 0
3647 __str._M_data(_S_empty_rep()._M_refdata());
3648#else
3649 __str._M_data(_S_construct(size_type(), _CharT(), get_allocator()));
3650#endif
3651 }
3652
3653 /**
3654 * @brief Construct string from an initializer %list.
3655 * @param __l std::initializer_list of characters.
3656 * @param __a Allocator to use (default is default allocator).
3657 */
3658 basic_string(initializer_list<_CharT> __l, const _Alloc& __a = _Alloc());
3659
3660 basic_string(const basic_string& __str, const _Alloc& __a)
3661 : _M_dataplus(__str._M_rep()->_M_grab(__a, __str.get_allocator()), __a)
3662 { }
3663
3664 basic_string(basic_string&& __str, const _Alloc& __a)
3665 : _M_dataplus(__str._M_data(), __a)
3666 {
3667 if (__a == __str.get_allocator())
3668 {
3669#if _GLIBCXX_FULLY_DYNAMIC_STRING0 == 0
3670 __str._M_data(_S_empty_rep()._M_refdata());
3671#else
3672 __str._M_data(_S_construct(size_type(), _CharT(), __a));
3673#endif
3674 }
3675 else
3676 _M_dataplus._M_p = _S_construct(__str.begin(), __str.end(), __a);
3677 }
3678#endif // C++11
3679
3680 /**
3681 * @brief Construct string as copy of a range.
3682 * @param __beg Start of range.
3683 * @param __end End of range.
3684 * @param __a Allocator to use (default is default allocator).
3685 */
3686 template<class _InputIterator>
3687 basic_string(_InputIterator __beg, _InputIterator __end,
3688 const _Alloc& __a = _Alloc());
3689
3690#if __cplusplus201703L >= 201703L
3691 /**
3692 * @brief Construct string from a substring of a string_view.
3693 * @param __t Source object convertible to string view.
3694 * @param __pos The index of the first character to copy from __t.
3695 * @param __n The number of characters to copy from __t.
3696 * @param __a Allocator to use.
3697 */
3698 template<typename _Tp, typename = _If_sv<_Tp, void>>
3699 basic_string(const _Tp& __t, size_type __pos, size_type __n,
3700 const _Alloc& __a = _Alloc())
3701 : basic_string(_S_to_string_view(__t).substr(__pos, __n), __a) { }
3702
3703 /**
3704 * @brief Construct string from a string_view.
3705 * @param __t Source object convertible to string view.
3706 * @param __a Allocator to use (default is default allocator).
3707 */
3708 template<typename _Tp, typename = _If_sv<_Tp, void>>
3709 explicit
3710 basic_string(const _Tp& __t, const _Alloc& __a = _Alloc())
3711 : basic_string(__sv_wrapper(_S_to_string_view(__t)), __a) { }
3712#endif // C++17
3713
3714 /**
3715 * @brief Destroy the string instance.
3716 */
3717 ~basic_string() _GLIBCXX_NOEXCEPTnoexcept
3718 { _M_rep()->_M_dispose(this->get_allocator()); }
3719
3720 /**
3721 * @brief Assign the value of @a str to this string.
3722 * @param __str Source string.
3723 */
3724 basic_string&
3725 operator=(const basic_string& __str)
3726 { return this->assign(__str); }
3727
3728 /**
3729 * @brief Copy contents of @a s into this string.
3730 * @param __s Source null-terminated string.
3731 */
3732 basic_string&
3733 operator=(const _CharT* __s)
3734 { return this->assign(__s); }
3735
3736 /**
3737 * @brief Set value to string of length 1.
3738 * @param __c Source character.
3739 *
3740 * Assigning to a character makes this string length 1 and
3741 * (*this)[0] == @a c.
3742 */
3743 basic_string&
3744 operator=(_CharT __c)
3745 {
3746 this->assign(1, __c);
3747 return *this;
3748 }
3749
3750#if __cplusplus201703L >= 201103L
3751 /**
3752 * @brief Move assign the value of @a str to this string.
3753 * @param __str Source string.
3754 *
3755 * The contents of @a str are moved into this string (without copying).
3756 * @a str is a valid, but unspecified string.
3757 **/
3758 basic_string&
3759 operator=(basic_string&& __str)
3760 _GLIBCXX_NOEXCEPT_IF(allocator_traits<_Alloc>::is_always_equal::value)noexcept(allocator_traits<_Alloc>::is_always_equal::value
)
3761 {
3762 // NB: DR 1204.
3763 this->swap(__str);
3764 return *this;
3765 }
3766
3767 /**
3768 * @brief Set value to string constructed from initializer %list.
3769 * @param __l std::initializer_list.
3770 */
3771 basic_string&
3772 operator=(initializer_list<_CharT> __l)
3773 {
3774 this->assign(__l.begin(), __l.size());
3775 return *this;
3776 }
3777#endif // C++11
3778
3779#if __cplusplus201703L >= 201703L
3780 /**
3781 * @brief Set value to string constructed from a string_view.
3782 * @param __svt An object convertible to string_view.
3783 */
3784 template<typename _Tp>
3785 _If_sv<_Tp, basic_string&>
3786 operator=(const _Tp& __svt)
3787 { return this->assign(__svt); }
3788
3789 /**
3790 * @brief Convert to a string_view.
3791 * @return A string_view.
3792 */
3793 operator __sv_type() const noexcept
3794 { return __sv_type(data(), size()); }
3795#endif // C++17
3796
3797 // Iterators:
3798 /**
3799 * Returns a read/write iterator that points to the first character in
3800 * the %string. Unshares the string.
3801 */
3802 iterator
3803 begin() // FIXME C++11: should be noexcept.
3804 {
3805 _M_leak();
3806 return iterator(_M_data());
3807 }
3808
3809 /**
3810 * Returns a read-only (constant) iterator that points to the first
3811 * character in the %string.
3812 */
3813 const_iterator
3814 begin() const _GLIBCXX_NOEXCEPTnoexcept
3815 { return const_iterator(_M_data()); }
3816
3817 /**
3818 * Returns a read/write iterator that points one past the last
3819 * character in the %string. Unshares the string.
3820 */
3821 iterator
3822 end() // FIXME C++11: should be noexcept.
3823 {
3824 _M_leak();
3825 return iterator(_M_data() + this->size());
3826 }
3827
3828 /**
3829 * Returns a read-only (constant) iterator that points one past the
3830 * last character in the %string.
3831 */
3832 const_iterator
3833 end() const _GLIBCXX_NOEXCEPTnoexcept
3834 { return const_iterator(_M_data() + this->size()); }
3835
3836 /**
3837 * Returns a read/write reverse iterator that points to the last
3838 * character in the %string. Iteration is done in reverse element
3839 * order. Unshares the string.
3840 */
3841 reverse_iterator
3842 rbegin() // FIXME C++11: should be noexcept.
3843 { return reverse_iterator(this->end()); }
3844
3845 /**
3846 * Returns a read-only (constant) reverse iterator that points
3847 * to the last character in the %string. Iteration is done in
3848 * reverse element order.
3849 */
3850 const_reverse_iterator
3851 rbegin() const _GLIBCXX_NOEXCEPTnoexcept
3852 { return const_reverse_iterator(this->end()); }
3853
3854 /**
3855 * Returns a read/write reverse iterator that points to one before the
3856 * first character in the %string. Iteration is done in reverse
3857 * element order. Unshares the string.
3858 */
3859 reverse_iterator
3860 rend() // FIXME C++11: should be noexcept.
3861 { return reverse_iterator(this->begin()); }
3862
3863 /**
3864 * Returns a read-only (constant) reverse iterator that points
3865 * to one before the first character in the %string. Iteration
3866 * is done in reverse element order.
3867 */
3868 const_reverse_iterator
3869 rend() const _GLIBCXX_NOEXCEPTnoexcept
3870 { return const_reverse_iterator(this->begin()); }
3871
3872#if __cplusplus201703L >= 201103L
3873 /**
3874 * Returns a read-only (constant) iterator that points to the first
3875 * character in the %string.
3876 */
3877 const_iterator
3878 cbegin() const noexcept
3879 { return const_iterator(this->_M_data()); }
3880
3881 /**
3882 * Returns a read-only (constant) iterator that points one past the
3883 * last character in the %string.
3884 */
3885 const_iterator
3886 cend() const noexcept
3887 { return const_iterator(this->_M_data() + this->size()); }
3888
3889 /**
3890 * Returns a read-only (constant) reverse iterator that points
3891 * to the last character in the %string. Iteration is done in
3892 * reverse element order.
3893 */
3894 const_reverse_iterator
3895 crbegin() const noexcept
3896 { return const_reverse_iterator(this->end()); }
3897
3898 /**
3899 * Returns a read-only (constant) reverse iterator that points
3900 * to one before the first character in the %string. Iteration
3901 * is done in reverse element order.
3902 */
3903 const_reverse_iterator
3904 crend() const noexcept
3905 { return const_reverse_iterator(this->begin()); }
3906#endif
3907
3908 public:
3909 // Capacity:
3910 /// Returns the number of characters in the string, not including any
3911 /// null-termination.
3912 size_type
3913 size() const _GLIBCXX_NOEXCEPTnoexcept
3914 { return _M_rep()->_M_length; }
3915
3916 /// Returns the number of characters in the string, not including any
3917 /// null-termination.
3918 size_type
3919 length() const _GLIBCXX_NOEXCEPTnoexcept
3920 { return _M_rep()->_M_length; }
3921
3922 /// Returns the size() of the largest possible %string.
3923 size_type
3924 max_size() const _GLIBCXX_NOEXCEPTnoexcept
3925 { return _Rep::_S_max_size; }
3926
3927 /**
3928 * @brief Resizes the %string to the specified number of characters.
3929 * @param __n Number of characters the %string should contain.
3930 * @param __c Character to fill any new elements.
3931 *
3932 * This function will %resize the %string to the specified
3933 * number of characters. If the number is smaller than the
3934 * %string's current size the %string is truncated, otherwise
3935 * the %string is extended and new elements are %set to @a __c.
3936 */
3937 void
3938 resize(size_type __n, _CharT __c);
3939
3940 /**
3941 * @brief Resizes the %string to the specified number of characters.
3942 * @param __n Number of characters the %string should contain.
3943 *
3944 * This function will resize the %string to the specified length. If
3945 * the new size is smaller than the %string's current size the %string
3946 * is truncated, otherwise the %string is extended and new characters
3947 * are default-constructed. For basic types such as char, this means
3948 * setting them to 0.
3949 */
3950 void
3951 resize(size_type __n)
3952 { this->resize(__n, _CharT()); }
3953
3954#if __cplusplus201703L >= 201103L
3955 /// A non-binding request to reduce capacity() to size().
3956 void
3957 shrink_to_fit() _GLIBCXX_NOEXCEPTnoexcept
3958 {
3959#if __cpp_exceptions
3960 if (capacity() > size())
3961 {
3962 try
3963 { reserve(0); }
3964 catch(...)
3965 { }
3966 }
3967#endif
3968 }
3969#endif
3970
3971 /**
3972 * Returns the total number of characters that the %string can hold
3973 * before needing to allocate more memory.
3974 */
3975 size_type
3976 capacity() const _GLIBCXX_NOEXCEPTnoexcept
3977 { return _M_rep()->_M_capacity; }
3978
3979 /**
3980 * @brief Attempt to preallocate enough memory for specified number of
3981 * characters.
3982 * @param __res_arg Number of characters required.
3983 * @throw std::length_error If @a __res_arg exceeds @c max_size().
3984 *
3985 * This function attempts to reserve enough memory for the
3986 * %string to hold the specified number of characters. If the
3987 * number requested is more than max_size(), length_error is
3988 * thrown.
3989 *
3990 * The advantage of this function is that if optimal code is a
3991 * necessity and the user can determine the string length that will be
3992 * required, the user can reserve the memory in %advance, and thus
3993 * prevent a possible reallocation of memory and copying of %string
3994 * data.
3995 */
3996 void
3997 reserve(size_type __res_arg = 0);
3998
3999 /**
4000 * Erases the string, making it empty.
4001 */
4002#if _GLIBCXX_FULLY_DYNAMIC_STRING0 == 0
4003 void
4004 clear() _GLIBCXX_NOEXCEPTnoexcept
4005 {
4006 if (_M_rep()->_M_is_shared())
4007 {
4008 _M_rep()->_M_dispose(this->get_allocator());
4009 _M_data(_S_empty_rep()._M_refdata());
4010 }
4011 else
4012 _M_rep()->_M_set_length_and_sharable(0);
4013 }
4014#else
4015 // PR 56166: this should not throw.
4016 void
4017 clear()
4018 { _M_mutate(0, this->size(), 0); }
4019#endif
4020
4021 /**
4022 * Returns true if the %string is empty. Equivalent to
4023 * <code>*this == ""</code>.
4024 */
4025 _GLIBCXX_NODISCARD[[__nodiscard__]] bool
4026 empty() const _GLIBCXX_NOEXCEPTnoexcept
4027 { return this->size() == 0; }
4028
4029 // Element access:
4030 /**
4031 * @brief Subscript access to the data contained in the %string.
4032 * @param __pos The index of the character to access.
4033 * @return Read-only (constant) reference to the character.
4034 *
4035 * This operator allows for easy, array-style, data access.
4036 * Note that data access with this operator is unchecked and
4037 * out_of_range lookups are not defined. (For checked lookups
4038 * see at().)
4039 */
4040 const_reference
4041 operator[] (size_type __pos) const _GLIBCXX_NOEXCEPTnoexcept
4042 {
4043 __glibcxx_assert(__pos <= size())do { if (! (__pos <= size())) std::__replacement_assert("/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.h"
, 4043, __PRETTY_FUNCTION__, "__pos <= size()"); } while (
false)
;
4044 return _M_data()[__pos];
4045 }
4046
4047 /**
4048 * @brief Subscript access to the data contained in the %string.
4049 * @param __pos The index of the character to access.
4050 * @return Read/write reference to the character.
4051 *
4052 * This operator allows for easy, array-style, data access.
4053 * Note that data access with this operator is unchecked and
4054 * out_of_range lookups are not defined. (For checked lookups
4055 * see at().) Unshares the string.
4056 */
4057 reference
4058 operator[](size_type __pos)
4059 {
4060 // Allow pos == size() both in C++98 mode, as v3 extension,
4061 // and in C++11 mode.
4062 __glibcxx_assert(__pos <= size())do { if (! (__pos <= size())) std::__replacement_assert("/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.h"
, 4062, __PRETTY_FUNCTION__, "__pos <= size()"); } while (
false)
;
4063 // In pedantic mode be strict in C++98 mode.
4064 _GLIBCXX_DEBUG_PEDASSERT(__cplusplus >= 201103L || __pos < size());
4065 _M_leak();
4066 return _M_data()[__pos];
4067 }
4068
4069 /**
4070 * @brief Provides access to the data contained in the %string.
4071 * @param __n The index of the character to access.
4072 * @return Read-only (const) reference to the character.
4073 * @throw std::out_of_range If @a n is an invalid index.
4074 *
4075 * This function provides for safer data access. The parameter is
4076 * first checked that it is in the range of the string. The function
4077 * throws out_of_range if the check fails.
4078 */
4079 const_reference
4080 at(size_type __n) const
4081 {
4082 if (__n >= this->size())
4083 __throw_out_of_range_fmt(__N("basic_string::at: __n "("basic_string::at: __n " "(which is %zu) >= this->size() "
"(which is %zu)")
4084 "(which is %zu) >= this->size() "("basic_string::at: __n " "(which is %zu) >= this->size() "
"(which is %zu)")
4085 "(which is %zu)")("basic_string::at: __n " "(which is %zu) >= this->size() "
"(which is %zu)")
,
4086 __n, this->size());
4087 return _M_data()[__n];
4088 }
4089
4090 /**
4091 * @brief Provides access to the data contained in the %string.
4092 * @param __n The index of the character to access.
4093 * @return Read/write reference to the character.
4094 * @throw std::out_of_range If @a n is an invalid index.
4095 *
4096 * This function provides for safer data access. The parameter is
4097 * first checked that it is in the range of the string. The function
4098 * throws out_of_range if the check fails. Success results in
4099 * unsharing the string.
4100 */
4101 reference
4102 at(size_type __n)
4103 {
4104 if (__n >= size())
4105 __throw_out_of_range_fmt(__N("basic_string::at: __n "("basic_string::at: __n " "(which is %zu) >= this->size() "
"(which is %zu)")
4106 "(which is %zu) >= this->size() "("basic_string::at: __n " "(which is %zu) >= this->size() "
"(which is %zu)")
4107 "(which is %zu)")("basic_string::at: __n " "(which is %zu) >= this->size() "
"(which is %zu)")
,
4108 __n, this->size());
4109 _M_leak();
4110 return _M_data()[__n];
4111 }
4112
4113#if __cplusplus201703L >= 201103L
4114 /**
4115 * Returns a read/write reference to the data at the first
4116 * element of the %string.
4117 */
4118 reference
4119 front()
4120 {
4121 __glibcxx_assert(!empty())do { if (! (!empty())) std::__replacement_assert("/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.h"
, 4121, __PRETTY_FUNCTION__, "!empty()"); } while (false)
;
4122 return operator[](0);
4123 }
4124
4125 /**
4126 * Returns a read-only (constant) reference to the data at the first
4127 * element of the %string.
4128 */
4129 const_reference
4130 front() const noexcept
4131 {
4132 __glibcxx_assert(!empty())do { if (! (!empty())) std::__replacement_assert("/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.h"
, 4132, __PRETTY_FUNCTION__, "!empty()"); } while (false)
;
4133 return operator[](0);
4134 }
4135
4136 /**
4137 * Returns a read/write reference to the data at the last
4138 * element of the %string.
4139 */
4140 reference
4141 back()
4142 {
4143 __glibcxx_assert(!empty())do { if (! (!empty())) std::__replacement_assert("/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.h"
, 4143, __PRETTY_FUNCTION__, "!empty()"); } while (false)
;
4144 return operator[](this->size() - 1);
4145 }
4146
4147 /**
4148 * Returns a read-only (constant) reference to the data at the
4149 * last element of the %string.
4150 */
4151 const_reference
4152 back() const noexcept
4153 {
4154 __glibcxx_assert(!empty())do { if (! (!empty())) std::__replacement_assert("/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.h"
, 4154, __PRETTY_FUNCTION__, "!empty()"); } while (false)
;
4155 return operator[](this->size() - 1);
4156 }
4157#endif
4158
4159 // Modifiers:
4160 /**
4161 * @brief Append a string to this string.
4162 * @param __str The string to append.
4163 * @return Reference to this string.
4164 */
4165 basic_string&
4166 operator+=(const basic_string& __str)
4167 { return this->append(__str); }
4168
4169 /**
4170 * @brief Append a C string.
4171 * @param __s The C string to append.
4172 * @return Reference to this string.
4173 */
4174 basic_string&
4175 operator+=(const _CharT* __s)
4176 { return this->append(__s); }
4177
4178 /**
4179 * @brief Append a character.
4180 * @param __c The character to append.
4181 * @return Reference to this string.
4182 */
4183 basic_string&
4184 operator+=(_CharT __c)
4185 {
4186 this->push_back(__c);
4187 return *this;
4188 }
4189
4190#if __cplusplus201703L >= 201103L
4191 /**
4192 * @brief Append an initializer_list of characters.
4193 * @param __l The initializer_list of characters to be appended.
4194 * @return Reference to this string.
4195 */
4196 basic_string&
4197 operator+=(initializer_list<_CharT> __l)
4198 { return this->append(__l.begin(), __l.size()); }
4199#endif // C++11
4200
4201#if __cplusplus201703L >= 201703L
4202 /**
4203 * @brief Append a string_view.
4204 * @param __svt The object convertible to string_view to be appended.
4205 * @return Reference to this string.
4206 */
4207 template<typename _Tp>
4208 _If_sv<_Tp, basic_string&>
4209 operator+=(const _Tp& __svt)
4210 { return this->append(__svt); }
4211#endif // C++17
4212
4213 /**
4214 * @brief Append a string to this string.
4215 * @param __str The string to append.
4216 * @return Reference to this string.
4217 */
4218 basic_string&
4219 append(const basic_string& __str);
4220
4221 /**
4222 * @brief Append a substring.
4223 * @param __str The string to append.
4224 * @param __pos Index of the first character of str to append.
4225 * @param __n The number of characters to append.
4226 * @return Reference to this string.
4227 * @throw std::out_of_range if @a __pos is not a valid index.
4228 *
4229 * This function appends @a __n characters from @a __str
4230 * starting at @a __pos to this string. If @a __n is is larger
4231 * than the number of available characters in @a __str, the
4232 * remainder of @a __str is appended.
4233 */
4234 basic_string&
4235 append(const basic_string& __str, size_type __pos, size_type __n = npos);
4236
4237 /**
4238 * @brief Append a C substring.
4239 * @param __s The C string to append.
4240 * @param __n The number of characters to append.
4241 * @return Reference to this string.
4242 */
4243 basic_string&
4244 append(const _CharT* __s, size_type __n);
4245
4246 /**
4247 * @brief Append a C string.
4248 * @param __s The C string to append.
4249 * @return Reference to this string.
4250 */
4251 basic_string&
4252 append(const _CharT* __s)
4253 {
4254 __glibcxx_requires_string(__s);
4255 return this->append(__s, traits_type::length(__s));
4256 }
4257
4258 /**
4259 * @brief Append multiple characters.
4260 * @param __n The number of characters to append.
4261 * @param __c The character to use.
4262 * @return Reference to this string.
4263 *
4264 * Appends __n copies of __c to this string.
4265 */
4266 basic_string&
4267 append(size_type __n, _CharT __c);
4268
4269#if __cplusplus201703L >= 201103L
4270 /**
4271 * @brief Append an initializer_list of characters.
4272 * @param __l The initializer_list of characters to append.
4273 * @return Reference to this string.
4274 */
4275 basic_string&
4276 append(initializer_list<_CharT> __l)
4277 { return this->append(__l.begin(), __l.size()); }
4278#endif // C++11
4279
4280 /**
4281 * @brief Append a range of characters.
4282 * @param __first Iterator referencing the first character to append.
4283 * @param __last Iterator marking the end of the range.
4284 * @return Reference to this string.
4285 *
4286 * Appends characters in the range [__first,__last) to this string.
4287 */
4288 template<class _InputIterator>
4289 basic_string&
4290 append(_InputIterator __first, _InputIterator __last)
4291 { return this->replace(_M_iend(), _M_iend(), __first, __last); }
4292
4293#if __cplusplus201703L >= 201703L
4294 /**
4295 * @brief Append a string_view.
4296 * @param __svt The object convertible to string_view to be appended.
4297 * @return Reference to this string.
4298 */
4299 template<typename _Tp>
4300 _If_sv<_Tp, basic_string&>
4301 append(const _Tp& __svt)
4302 {
4303 __sv_type __sv = __svt;
4304 return this->append(__sv.data(), __sv.size());
4305 }
4306
4307 /**
4308 * @brief Append a range of characters from a string_view.
4309 * @param __svt The object convertible to string_view to be appended
4310 * from.
4311 * @param __pos The position in the string_view to append from.
4312 * @param __n The number of characters to append from the string_view.
4313 * @return Reference to this string.
4314 */
4315 template<typename _Tp>
4316 _If_sv<_Tp, basic_string&>
4317 append(const _Tp& __svt, size_type __pos, size_type __n = npos)
4318 {
4319 __sv_type __sv = __svt;
4320 return append(__sv.data()
4321 + std::__sv_check(__sv.size(), __pos, "basic_string::append"),
4322 std::__sv_limit(__sv.size(), __pos, __n));
4323 }
4324#endif // C++17
4325
4326 /**
4327 * @brief Append a single character.
4328 * @param __c Character to append.
4329 */
4330 void
4331 push_back(_CharT __c)
4332 {
4333 const size_type __len = 1 + this->size();
4334 if (__len > this->capacity() || _M_rep()->_M_is_shared())
4335 this->reserve(__len);
4336 traits_type::assign(_M_data()[this->size()], __c);
4337 _M_rep()->_M_set_length_and_sharable(__len);
4338 }
4339
4340 /**
4341 * @brief Set value to contents of another string.
4342 * @param __str Source string to use.
4343 * @return Reference to this string.
4344 */
4345 basic_string&
4346 assign(const basic_string& __str);
4347
4348#if __cplusplus201703L >= 201103L
4349 /**
4350 * @brief Set value to contents of another string.
4351 * @param __str Source string to use.
4352 * @return Reference to this string.
4353 *
4354 * This function sets this string to the exact contents of @a __str.
4355 * @a __str is a valid, but unspecified string.
4356 */
4357 basic_string&
4358 assign(basic_string&& __str)
4359 noexcept(allocator_traits<_Alloc>::is_always_equal::value)
4360 {
4361 this->swap(__str);
4362 return *this;
4363 }
4364#endif // C++11
4365
4366 /**
4367 * @brief Set value to a substring of a string.
4368 * @param __str The string to use.
4369 * @param __pos Index of the first character of str.
4370 * @param __n Number of characters to use.
4371 * @return Reference to this string.
4372 * @throw std::out_of_range if @a pos is not a valid index.
4373 *
4374 * This function sets this string to the substring of @a __str
4375 * consisting of @a __n characters at @a __pos. If @a __n is
4376 * is larger than the number of available characters in @a
4377 * __str, the remainder of @a __str is used.
4378 */
4379 basic_string&
4380 assign(const basic_string& __str, size_type __pos, size_type __n = npos)
4381 { return this->assign(__str._M_data()
4382 + __str._M_check(__pos, "basic_string::assign"),
4383 __str._M_limit(__pos, __n)); }
4384
4385 /**
4386 * @brief Set value to a C substring.
4387 * @param __s The C string to use.
4388 * @param __n Number of characters to use.
4389 * @return Reference to this string.
4390 *
4391 * This function sets the value of this string to the first @a __n
4392 * characters of @a __s. If @a __n is is larger than the number of
4393 * available characters in @a __s, the remainder of @a __s is used.
4394 */
4395 basic_string&
4396 assign(const _CharT* __s, size_type __n);
4397
4398 /**
4399 * @brief Set value to contents of a C string.
4400 * @param __s The C string to use.
4401 * @return Reference to this string.
4402 *
4403 * This function sets the value of this string to the value of @a __s.
4404 * The data is copied, so there is no dependence on @a __s once the
4405 * function returns.
4406 */
4407 basic_string&
4408 assign(const _CharT* __s)
4409 {
4410 __glibcxx_requires_string(__s);
4411 return this->assign(__s, traits_type::length(__s));
4412 }
4413
4414 /**
4415 * @brief Set value to multiple characters.
4416 * @param __n Length of the resulting string.
4417 * @param __c The character to use.
4418 * @return Reference to this string.
4419 *
4420 * This function sets the value of this string to @a __n copies of
4421 * character @a __c.
4422 */
4423 basic_string&
4424 assign(size_type __n, _CharT __c)
4425 { return _M_replace_aux(size_type(0), this->size(), __n, __c); }
4426
4427 /**
4428 * @brief Set value to a range of characters.
4429 * @param __first Iterator referencing the first character to append.
4430 * @param __last Iterator marking the end of the range.
4431 * @return Reference to this string.
4432 *
4433 * Sets value of string to characters in the range [__first,__last).
4434 */
4435 template<class _InputIterator>
4436 basic_string&
4437 assign(_InputIterator __first, _InputIterator __last)
4438 { return this->replace(_M_ibegin(), _M_iend(), __first, __last); }
4439
4440#if __cplusplus201703L >= 201103L
4441 /**
4442 * @brief Set value to an initializer_list of characters.
4443 * @param __l The initializer_list of characters to assign.
4444 * @return Reference to this string.
4445 */
4446 basic_string&
4447 assign(initializer_list<_CharT> __l)
4448 { return this->assign(__l.begin(), __l.size()); }
4449#endif // C++11
4450
4451#if __cplusplus201703L >= 201703L
4452 /**
4453 * @brief Set value from a string_view.
4454 * @param __svt The source object convertible to string_view.
4455 * @return Reference to this string.
4456 */
4457 template<typename _Tp>
4458 _If_sv<_Tp, basic_string&>
4459 assign(const _Tp& __svt)
4460 {
4461 __sv_type __sv = __svt;
4462 return this->assign(__sv.data(), __sv.size());
4463 }
4464
4465 /**
4466 * @brief Set value from a range of characters in a string_view.
4467 * @param __svt The source object convertible to string_view.
4468 * @param __pos The position in the string_view to assign from.
4469 * @param __n The number of characters to assign.
4470 * @return Reference to this string.
4471 */
4472 template<typename _Tp>
4473 _If_sv<_Tp, basic_string&>
4474 assign(const _Tp& __svt, size_type __pos, size_type __n = npos)
4475 {
4476 __sv_type __sv = __svt;
4477 return assign(__sv.data()
4478 + std::__sv_check(__sv.size(), __pos, "basic_string::assign"),
4479 std::__sv_limit(__sv.size(), __pos, __n));
4480 }
4481#endif // C++17
4482
4483 /**
4484 * @brief Insert multiple characters.
4485 * @param __p Iterator referencing location in string to insert at.
4486 * @param __n Number of characters to insert
4487 * @param __c The character to insert.
4488 * @throw std::length_error If new length exceeds @c max_size().
4489 *
4490 * Inserts @a __n copies of character @a __c starting at the
4491 * position referenced by iterator @a __p. If adding
4492 * characters causes the length to exceed max_size(),
4493 * length_error is thrown. The value of the string doesn't
4494 * change if an error is thrown.
4495 */
4496 void
4497 insert(iterator __p, size_type __n, _CharT __c)
4498 { this->replace(__p, __p, __n, __c); }
4499
4500 /**
4501 * @brief Insert a range of characters.
4502 * @param __p Iterator referencing location in string to insert at.
4503 * @param __beg Start of range.
4504 * @param __end End of range.
4505 * @throw std::length_error If new length exceeds @c max_size().
4506 *
4507 * Inserts characters in range [__beg,__end). If adding
4508 * characters causes the length to exceed max_size(),
4509 * length_error is thrown. The value of the string doesn't
4510 * change if an error is thrown.
4511 */
4512 template<class _InputIterator>
4513 void
4514 insert(iterator __p, _InputIterator __beg, _InputIterator __end)
4515 { this->replace(__p, __p, __beg, __end); }
4516
4517#if __cplusplus201703L >= 201103L
4518 /**
4519 * @brief Insert an initializer_list of characters.
4520 * @param __p Iterator referencing location in string to insert at.
4521 * @param __l The initializer_list of characters to insert.
4522 * @throw std::length_error If new length exceeds @c max_size().
4523 */
4524 void
4525 insert(iterator __p, initializer_list<_CharT> __l)
4526 {
4527 _GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend());
4528 this->insert(__p - _M_ibegin(), __l.begin(), __l.size());
4529 }
4530#endif // C++11
4531
4532 /**
4533 * @brief Insert value of a string.
4534 * @param __pos1 Position in string to insert at.
4535 * @param __str The string to insert.
4536 * @return Reference to this string.
4537 * @throw std::length_error If new length exceeds @c max_size().
4538 *
4539 * Inserts value of @a __str starting at @a __pos1. If adding
4540 * characters causes the length to exceed max_size(),
4541 * length_error is thrown. The value of the string doesn't
4542 * change if an error is thrown.
4543 */
4544 basic_string&
4545 insert(size_type __pos1, const basic_string& __str)
4546 { return this->insert(__pos1, __str, size_type(0), __str.size()); }
4547
4548 /**
4549 * @brief Insert a substring.
4550 * @param __pos1 Position in string to insert at.
4551 * @param __str The string to insert.
4552 * @param __pos2 Start of characters in str to insert.
4553 * @param __n Number of characters to insert.
4554 * @return Reference to this string.
4555 * @throw std::length_error If new length exceeds @c max_size().
4556 * @throw std::out_of_range If @a pos1 > size() or
4557 * @a __pos2 > @a str.size().
4558 *
4559 * Starting at @a pos1, insert @a __n character of @a __str
4560 * beginning with @a __pos2. If adding characters causes the
4561 * length to exceed max_size(), length_error is thrown. If @a
4562 * __pos1 is beyond the end of this string or @a __pos2 is
4563 * beyond the end of @a __str, out_of_range is thrown. The
4564 * value of the string doesn't change if an error is thrown.
4565 */
4566 basic_string&
4567 insert(size_type __pos1, const basic_string& __str,
4568 size_type __pos2, size_type __n = npos)
4569 { return this->insert(__pos1, __str._M_data()
4570 + __str._M_check(__pos2, "basic_string::insert"),
4571 __str._M_limit(__pos2, __n)); }
4572
4573 /**
4574 * @brief Insert a C substring.
4575 * @param __pos Position in string to insert at.
4576 * @param __s The C string to insert.
4577 * @param __n The number of characters to insert.
4578 * @return Reference to this string.
4579 * @throw std::length_error If new length exceeds @c max_size().
4580 * @throw std::out_of_range If @a __pos is beyond the end of this
4581 * string.
4582 *
4583 * Inserts the first @a __n characters of @a __s starting at @a
4584 * __pos. If adding characters causes the length to exceed
4585 * max_size(), length_error is thrown. If @a __pos is beyond
4586 * end(), out_of_range is thrown. The value of the string
4587 * doesn't change if an error is thrown.
4588 */
4589 basic_string&
4590 insert(size_type __pos, const _CharT* __s, size_type __n);
4591
4592 /**
4593 * @brief Insert a C string.
4594 * @param __pos Position in string to insert at.
4595 * @param __s The C string to insert.
4596 * @return Reference to this string.
4597 * @throw std::length_error If new length exceeds @c max_size().
4598 * @throw std::out_of_range If @a pos is beyond the end of this
4599 * string.
4600 *
4601 * Inserts the first @a n characters of @a __s starting at @a __pos. If
4602 * adding characters causes the length to exceed max_size(),
4603 * length_error is thrown. If @a __pos is beyond end(), out_of_range is
4604 * thrown. The value of the string doesn't change if an error is
4605 * thrown.
4606 */
4607 basic_string&
4608 insert(size_type __pos, const _CharT* __s)
4609 {
4610 __glibcxx_requires_string(__s);
4611 return this->insert(__pos, __s, traits_type::length(__s));
4612 }
4613
4614 /**
4615 * @brief Insert multiple characters.
4616 * @param __pos Index in string to insert at.
4617 * @param __n Number of characters to insert
4618 * @param __c The character to insert.
4619 * @return Reference to this string.
4620 * @throw std::length_error If new length exceeds @c max_size().
4621 * @throw std::out_of_range If @a __pos is beyond the end of this
4622 * string.
4623 *
4624 * Inserts @a __n copies of character @a __c starting at index
4625 * @a __pos. If adding characters causes the length to exceed
4626 * max_size(), length_error is thrown. If @a __pos > length(),
4627 * out_of_range is thrown. The value of the string doesn't
4628 * change if an error is thrown.
4629 */
4630 basic_string&
4631 insert(size_type __pos, size_type __n, _CharT __c)
4632 { return _M_replace_aux(_M_check(__pos, "basic_string::insert"),
4633 size_type(0), __n, __c); }
4634
4635 /**
4636 * @brief Insert one character.
4637 * @param __p Iterator referencing position in string to insert at.
4638 * @param __c The character to insert.
4639 * @return Iterator referencing newly inserted char.
4640 * @throw std::length_error If new length exceeds @c max_size().
4641 *
4642 * Inserts character @a __c at position referenced by @a __p.
4643 * If adding character causes the length to exceed max_size(),
4644 * length_error is thrown. If @a __p is beyond end of string,
4645 * out_of_range is thrown. The value of the string doesn't
4646 * change if an error is thrown.
4647 */
4648 iterator
4649 insert(iterator __p, _CharT __c)
4650 {
4651 _GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend());
4652 const size_type __pos = __p - _M_ibegin();
4653 _M_replace_aux(__pos, size_type(0), size_type(1), __c);
4654 _M_rep()->_M_set_leaked();
4655 return iterator(_M_data() + __pos);
4656 }
4657
4658#if __cplusplus201703L >= 201703L
4659 /**
4660 * @brief Insert a string_view.
4661 * @param __pos Position in string to insert at.
4662 * @param __svt The object convertible to string_view to insert.
4663 * @return Reference to this string.
4664 */
4665 template<typename _Tp>
4666 _If_sv<_Tp, basic_string&>
4667 insert(size_type __pos, const _Tp& __svt)
4668 {
4669 __sv_type __sv = __svt;
4670 return this->insert(__pos, __sv.data(), __sv.size());
4671 }
4672
4673 /**
4674 * @brief Insert a string_view.
4675 * @param __pos Position in string to insert at.
4676 * @param __svt The object convertible to string_view to insert from.
4677 * @param __pos Position in string_view to insert
4678 * from.
4679 * @param __n The number of characters to insert.
4680 * @return Reference to this string.
4681 */
4682 template<typename _Tp>
4683 _If_sv<_Tp, basic_string&>
4684 insert(size_type __pos1, const _Tp& __svt,
4685 size_type __pos2, size_type __n = npos)
4686 {
4687 __sv_type __sv = __svt;
4688 return this->replace(__pos1, size_type(0), __sv.data()
4689 + std::__sv_check(__sv.size(), __pos2, "basic_string::insert"),
4690 std::__sv_limit(__sv.size(), __pos2, __n));
4691 }
4692#endif // C++17
4693
4694 /**
4695 * @brief Remove characters.
4696 * @param __pos Index of first character to remove (default 0).
4697 * @param __n Number of characters to remove (default remainder).
4698 * @return Reference to this string.
4699 * @throw std::out_of_range If @a pos is beyond the end of this
4700 * string.
4701 *
4702 * Removes @a __n characters from this string starting at @a
4703 * __pos. The length of the string is reduced by @a __n. If
4704 * there are < @a __n characters to remove, the remainder of
4705 * the string is truncated. If @a __p is beyond end of string,
4706 * out_of_range is thrown. The value of the string doesn't
4707 * change if an error is thrown.
4708 */
4709 basic_string&
4710 erase(size_type __pos = 0, size_type __n = npos)
4711 {
4712 _M_mutate(_M_check(__pos, "basic_string::erase"),
4713 _M_limit(__pos, __n), size_type(0));
4714 return *this;
4715 }
4716
4717 /**
4718 * @brief Remove one character.
4719 * @param __position Iterator referencing the character to remove.
4720 * @return iterator referencing same location after removal.
4721 *
4722 * Removes the character at @a __position from this string. The value
4723 * of the string doesn't change if an error is thrown.
4724 */
4725 iterator
4726 erase(iterator __position)
4727 {
4728 _GLIBCXX_DEBUG_PEDASSERT(__position >= _M_ibegin()
4729 && __position < _M_iend());
4730 const size_type __pos = __position - _M_ibegin();
4731 _M_mutate(__pos, size_type(1), size_type(0));
4732 _M_rep()->_M_set_leaked();
4733 return iterator(_M_data() + __pos);
4734 }
4735
4736 /**
4737 * @brief Remove a range of characters.
4738 * @param __first Iterator referencing the first character to remove.
4739 * @param __last Iterator referencing the end of the range.
4740 * @return Iterator referencing location of first after removal.
4741 *
4742 * Removes the characters in the range [first,last) from this string.
4743 * The value of the string doesn't change if an error is thrown.
4744 */
4745 iterator
4746 erase(iterator __first, iterator __last);
4747
4748#if __cplusplus201703L >= 201103L
4749 /**
4750 * @brief Remove the last character.
4751 *
4752 * The string must be non-empty.
4753 */
4754 void
4755 pop_back() // FIXME C++11: should be noexcept.
4756 {
4757 __glibcxx_assert(!empty())do { if (! (!empty())) std::__replacement_assert("/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.h"
, 4757, __PRETTY_FUNCTION__, "!empty()"); } while (false)
;
4758 erase(size() - 1, 1);
4759 }
4760#endif // C++11
4761
4762 /**
4763 * @brief Replace characters with value from another string.
4764 * @param __pos Index of first character to replace.
4765 * @param __n Number of characters to be replaced.
4766 * @param __str String to insert.
4767 * @return Reference to this string.
4768 * @throw std::out_of_range If @a pos is beyond the end of this
4769 * string.
4770 * @throw std::length_error If new length exceeds @c max_size().
4771 *
4772 * Removes the characters in the range [__pos,__pos+__n) from
4773 * this string. In place, the value of @a __str is inserted.
4774 * If @a __pos is beyond end of string, out_of_range is thrown.
4775 * If the length of the result exceeds max_size(), length_error
4776 * is thrown. The value of the string doesn't change if an
4777 * error is thrown.
4778 */
4779 basic_string&
4780 replace(size_type __pos, size_type __n, const basic_string& __str)
4781 { return this->replace(__pos, __n, __str._M_data(), __str.size()); }
4782
4783 /**
4784 * @brief Replace characters with value from another string.
4785 * @param __pos1 Index of first character to replace.
4786 * @param __n1 Number of characters to be replaced.
4787 * @param __str String to insert.
4788 * @param __pos2 Index of first character of str to use.
4789 * @param __n2 Number of characters from str to use.
4790 * @return Reference to this string.
4791 * @throw std::out_of_range If @a __pos1 > size() or @a __pos2 >
4792 * __str.size().
4793 * @throw std::length_error If new length exceeds @c max_size().
4794 *
4795 * Removes the characters in the range [__pos1,__pos1 + n) from this
4796 * string. In place, the value of @a __str is inserted. If @a __pos is
4797 * beyond end of string, out_of_range is thrown. If the length of the
4798 * result exceeds max_size(), length_error is thrown. The value of the
4799 * string doesn't change if an error is thrown.
4800 */
4801 basic_string&
4802 replace(size_type __pos1, size_type __n1, const basic_string& __str,
4803 size_type __pos2, size_type __n2 = npos)
4804 { return this->replace(__pos1, __n1, __str._M_data()
4805 + __str._M_check(__pos2, "basic_string::replace"),
4806 __str._M_limit(__pos2, __n2)); }
4807
4808 /**
4809 * @brief Replace characters with value of a C substring.
4810 * @param __pos Index of first character to replace.
4811 * @param __n1 Number of characters to be replaced.
4812 * @param __s C string to insert.
4813 * @param __n2 Number of characters from @a s to use.
4814 * @return Reference to this string.
4815 * @throw std::out_of_range If @a pos1 > size().
4816 * @throw std::length_error If new length exceeds @c max_size().
4817 *
4818 * Removes the characters in the range [__pos,__pos + __n1)
4819 * from this string. In place, the first @a __n2 characters of
4820 * @a __s are inserted, or all of @a __s if @a __n2 is too large. If
4821 * @a __pos is beyond end of string, out_of_range is thrown. If
4822 * the length of result exceeds max_size(), length_error is
4823 * thrown. The value of the string doesn't change if an error
4824 * is thrown.
4825 */
4826 basic_string&
4827 replace(size_type __pos, size_type __n1, const _CharT* __s,
4828 size_type __n2);
4829
4830 /**
4831 * @brief Replace characters with value of a C string.
4832 * @param __pos Index of first character to replace.
4833 * @param __n1 Number of characters to be replaced.
4834 * @param __s C string to insert.
4835 * @return Reference to this string.
4836 * @throw std::out_of_range If @a pos > size().
4837 * @throw std::length_error If new length exceeds @c max_size().
4838 *
4839 * Removes the characters in the range [__pos,__pos + __n1)
4840 * from this string. In place, the characters of @a __s are
4841 * inserted. If @a __pos is beyond end of string, out_of_range
4842 * is thrown. If the length of result exceeds max_size(),
4843 * length_error is thrown. The value of the string doesn't
4844 * change if an error is thrown.
4845 */
4846 basic_string&
4847 replace(size_type __pos, size_type __n1, const _CharT* __s)
4848 {
4849 __glibcxx_requires_string(__s);
4850 return this->replace(__pos, __n1, __s, traits_type::length(__s));
4851 }
4852
4853 /**
4854 * @brief Replace characters with multiple characters.
4855 * @param __pos Index of first character to replace.
4856 * @param __n1 Number of characters to be replaced.
4857 * @param __n2 Number of characters to insert.
4858 * @param __c Character to insert.
4859 * @return Reference to this string.
4860 * @throw std::out_of_range If @a __pos > size().
4861 * @throw std::length_error If new length exceeds @c max_size().
4862 *
4863 * Removes the characters in the range [pos,pos + n1) from this
4864 * string. In place, @a __n2 copies of @a __c are inserted.
4865 * If @a __pos is beyond end of string, out_of_range is thrown.
4866 * If the length of result exceeds max_size(), length_error is
4867 * thrown. The value of the string doesn't change if an error
4868 * is thrown.
4869 */
4870 basic_string&
4871 replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
4872 { return _M_replace_aux(_M_check(__pos, "basic_string::replace"),
4873 _M_limit(__pos, __n1), __n2, __c); }
4874
4875 /**
4876 * @brief Replace range of characters with string.
4877 * @param __i1 Iterator referencing start of range to replace.
4878 * @param __i2 Iterator referencing end of range to replace.
4879 * @param __str String value to insert.
4880 * @return Reference to this string.
4881 * @throw std::length_error If new length exceeds @c max_size().
4882 *
4883 * Removes the characters in the range [__i1,__i2). In place,
4884 * the value of @a __str is inserted. If the length of result
4885 * exceeds max_size(), length_error is thrown. The value of
4886 * the string doesn't change if an error is thrown.
4887 */
4888 basic_string&
4889 replace(iterator __i1, iterator __i2, const basic_string& __str)
4890 { return this->replace(__i1, __i2, __str._M_data(), __str.size()); }
4891
4892 /**
4893 * @brief Replace range of characters with C substring.
4894 * @param __i1 Iterator referencing start of range to replace.
4895 * @param __i2 Iterator referencing end of range to replace.
4896 * @param __s C string value to insert.
4897 * @param __n Number of characters from s to insert.
4898 * @return Reference to this string.
4899 * @throw std::length_error If new length exceeds @c max_size().
4900 *
4901 * Removes the characters in the range [__i1,__i2). In place,
4902 * the first @a __n characters of @a __s are inserted. If the
4903 * length of result exceeds max_size(), length_error is thrown.
4904 * The value of the string doesn't change if an error is
4905 * thrown.
4906 */
4907 basic_string&
4908 replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n)
4909 {
4910 _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
4911 && __i2 <= _M_iend());
4912 return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n);
4913 }
4914
4915 /**
4916 * @brief Replace range of characters with C string.
4917 * @param __i1 Iterator referencing start of range to replace.
4918 * @param __i2 Iterator referencing end of range to replace.
4919 * @param __s C string value to insert.
4920 * @return Reference to this string.
4921 * @throw std::length_error If new length exceeds @c max_size().
4922 *
4923 * Removes the characters in the range [__i1,__i2). In place,
4924 * the characters of @a __s are inserted. If the length of
4925 * result exceeds max_size(), length_error is thrown. The
4926 * value of the string doesn't change if an error is thrown.
4927 */
4928 basic_string&
4929 replace(iterator __i1, iterator __i2, const _CharT* __s)
4930 {
4931 __glibcxx_requires_string(__s);
4932 return this->replace(__i1, __i2, __s, traits_type::length(__s));
4933 }
4934
4935 /**
4936 * @brief Replace range of characters with multiple characters
4937 * @param __i1 Iterator referencing start of range to replace.
4938 * @param __i2 Iterator referencing end of range to replace.
4939 * @param __n Number of characters to insert.
4940 * @param __c Character to insert.
4941 * @return Reference to this string.
4942 * @throw std::length_error If new length exceeds @c max_size().
4943 *
4944 * Removes the characters in the range [__i1,__i2). In place,
4945 * @a __n copies of @a __c are inserted. If the length of
4946 * result exceeds max_size(), length_error is thrown. The
4947 * value of the string doesn't change if an error is thrown.
4948 */
4949 basic_string&
4950 replace(iterator __i1, iterator __i2, size_type __n, _CharT __c)
4951 {
4952 _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
4953 && __i2 <= _M_iend());
4954 return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __c);
4955 }
4956
4957 /**
4958 * @brief Replace range of characters with range.
4959 * @param __i1 Iterator referencing start of range to replace.
4960 * @param __i2 Iterator referencing end of range to replace.
4961 * @param __k1 Iterator referencing start of range to insert.
4962 * @param __k2 Iterator referencing end of range to insert.
4963 * @return Reference to this string.
4964 * @throw std::length_error If new length exceeds @c max_size().
4965 *
4966 * Removes the characters in the range [__i1,__i2). In place,
4967 * characters in the range [__k1,__k2) are inserted. If the
4968 * length of result exceeds max_size(), length_error is thrown.
4969 * The value of the string doesn't change if an error is
4970 * thrown.
4971 */
4972 template<class _InputIterator>
4973 basic_string&
4974 replace(iterator __i1, iterator __i2,
4975 _InputIterator __k1, _InputIterator __k2)
4976 {
4977 _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
4978 && __i2 <= _M_iend());
4979 __glibcxx_requires_valid_range(__k1, __k2);
4980 typedef typename std::__is_integer<_InputIterator>::__type _Integral;
4981 return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral());
4982 }
4983
4984 // Specializations for the common case of pointer and iterator:
4985 // useful to avoid the overhead of temporary buffering in _M_replace.
4986 basic_string&
4987 replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2)
4988 {
4989 _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
4990 && __i2 <= _M_iend());
4991 __glibcxx_requires_valid_range(__k1, __k2);
4992 return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
4993 __k1, __k2 - __k1);
4994 }
4995
4996 basic_string&
4997 replace(iterator __i1, iterator __i2,
4998 const _CharT* __k1, const _CharT* __k2)
4999 {
5000 _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
5001 && __i2 <= _M_iend());
5002 __glibcxx_requires_valid_range(__k1, __k2);
5003 return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
5004 __k1, __k2 - __k1);
5005 }
5006
5007 basic_string&
5008 replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2)
5009 {
5010 _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
5011 && __i2 <= _M_iend());
5012 __glibcxx_requires_valid_range(__k1, __k2);
5013 return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
5014 __k1.base(), __k2 - __k1);
5015 }
5016
5017 basic_string&
5018 replace(iterator __i1, iterator __i2,
5019 const_iterator __k1, const_iterator __k2)
5020 {
5021 _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
5022 && __i2 <= _M_iend());
5023 __glibcxx_requires_valid_range(__k1, __k2);
5024 return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
5025 __k1.base(), __k2 - __k1);
5026 }
5027
5028#if __cplusplus201703L >= 201103L
5029 /**
5030 * @brief Replace range of characters with initializer_list.
5031 * @param __i1 Iterator referencing start of range to replace.
5032 * @param __i2 Iterator referencing end of range to replace.
5033 * @param __l The initializer_list of characters to insert.
5034 * @return Reference to this string.
5035 * @throw std::length_error If new length exceeds @c max_size().
5036 *
5037 * Removes the characters in the range [__i1,__i2). In place,
5038 * characters in the range [__k1,__k2) are inserted. If the
5039 * length of result exceeds max_size(), length_error is thrown.
5040 * The value of the string doesn't change if an error is
5041 * thrown.
5042 */
5043 basic_string& replace(iterator __i1, iterator __i2,
5044 initializer_list<_CharT> __l)
5045 { return this->replace(__i1, __i2, __l.begin(), __l.end()); }
5046#endif // C++11
5047
5048#if __cplusplus201703L >= 201703L
5049 /**
5050 * @brief Replace range of characters with string_view.
5051 * @param __pos The position to replace at.
5052 * @param __n The number of characters to replace.
5053 * @param __svt The object convertible to string_view to insert.
5054 * @return Reference to this string.
5055 */
5056 template<typename _Tp>
5057 _If_sv<_Tp, basic_string&>
5058 replace(size_type __pos, size_type __n, const _Tp& __svt)
5059 {
5060 __sv_type __sv = __svt;
5061 return this->replace(__pos, __n, __sv.data(), __sv.size());
5062 }
5063
5064 /**
5065 * @brief Replace range of characters with string_view.
5066 * @param __pos1 The position to replace at.
5067 * @param __n1 The number of characters to replace.
5068 * @param __svt The object convertible to string_view to insert from.
5069 * @param __pos2 The position in the string_view to insert from.
5070 * @param __n2 The number of characters to insert.
5071 * @return Reference to this string.
5072 */
5073 template<typename _Tp>
5074 _If_sv<_Tp, basic_string&>
5075 replace(size_type __pos1, size_type __n1, const _Tp& __svt,
5076 size_type __pos2, size_type __n2 = npos)
5077 {
5078 __sv_type __sv = __svt;
5079 return this->replace(__pos1, __n1,
5080 __sv.data()
5081 + std::__sv_check(__sv.size(), __pos2, "basic_string::replace"),
5082 std::__sv_limit(__sv.size(), __pos2, __n2));
5083 }
5084
5085 /**
5086 * @brief Replace range of characters with string_view.
5087 * @param __i1 An iterator referencing the start position
5088 to replace at.
5089 * @param __i2 An iterator referencing the end position
5090 for the replace.
5091 * @param __svt The object convertible to string_view to insert from.
5092 * @return Reference to this string.
5093 */
5094 template<typename _Tp>
5095 _If_sv<_Tp, basic_string&>
5096 replace(const_iterator __i1, const_iterator __i2, const _Tp& __svt)
5097 {
5098 __sv_type __sv = __svt;
5099 return this->replace(__i1 - begin(), __i2 - __i1, __sv);
5100 }
5101#endif // C++17
5102
5103 private:
5104 template<class _Integer>
5105 basic_string&
5106 _M_replace_dispatch(iterator __i1, iterator __i2, _Integer __n,
5107 _Integer __val, __true_type)
5108 { return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __val); }
5109
5110 template<class _InputIterator>
5111 basic_string&
5112 _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1,
5113 _InputIterator __k2, __false_type);
5114
5115 basic_string&
5116 _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
5117 _CharT __c);
5118
5119 basic_string&
5120 _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s,
5121 size_type __n2);
5122
5123 // _S_construct_aux is used to implement the 21.3.1 para 15 which
5124 // requires special behaviour if _InIter is an integral type
5125 template<class _InIterator>
5126 static _CharT*
5127 _S_construct_aux(_InIterator __beg, _InIterator __end,
5128 const _Alloc& __a, __false_type)
5129 {
5130 typedef typename iterator_traits<_InIterator>::iterator_category _Tag;
5131 return _S_construct(__beg, __end, __a, _Tag());
5132 }
5133
5134 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5135 // 438. Ambiguity in the "do the right thing" clause
5136 template<class _Integer>
5137 static _CharT*
5138 _S_construct_aux(_Integer __beg, _Integer __end,
5139 const _Alloc& __a, __true_type)
5140 { return _S_construct_aux_2(static_cast<size_type>(__beg),
5141 __end, __a); }
5142
5143 static _CharT*
5144 _S_construct_aux_2(size_type __req, _CharT __c, const _Alloc& __a)
5145 { return _S_construct(__req, __c, __a); }
5146
5147 template<class _InIterator>
5148 static _CharT*
5149 _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a)
5150 {
5151 typedef typename std::__is_integer<_InIterator>::__type _Integral;
5152 return _S_construct_aux(__beg, __end, __a, _Integral());
5153 }
5154
5155 // For Input Iterators, used in istreambuf_iterators, etc.
5156 template<class _InIterator>
5157 static _CharT*
5158 _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,
5159 input_iterator_tag);
5160
5161 // For forward_iterators up to random_access_iterators, used for
5162 // string::iterator, _CharT*, etc.
5163 template<class _FwdIterator>
5164 static _CharT*
5165 _S_construct(_FwdIterator __beg, _FwdIterator __end, const _Alloc& __a,
5166 forward_iterator_tag);
5167
5168 static _CharT*
5169 _S_construct(size_type __req, _CharT __c, const _Alloc& __a);
5170
5171 public:
5172
5173 /**
5174 * @brief Copy substring into C string.
5175 * @param __s C string to copy value into.
5176 * @param __n Number of characters to copy.
5177 * @param __pos Index of first character to copy.
5178 * @return Number of characters actually copied
5179 * @throw std::out_of_range If __pos > size().
5180 *
5181 * Copies up to @a __n characters starting at @a __pos into the
5182 * C string @a __s. If @a __pos is %greater than size(),
5183 * out_of_range is thrown.
5184 */
5185 size_type
5186 copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
5187
5188 /**
5189 * @brief Swap contents with another string.
5190 * @param __s String to swap with.
5191 *
5192 * Exchanges the contents of this string with that of @a __s in constant
5193 * time.
5194 */
5195 void
5196 swap(basic_string& __s)
5197 _GLIBCXX_NOEXCEPT_IF(allocator_traits<_Alloc>::is_always_equal::value)noexcept(allocator_traits<_Alloc>::is_always_equal::value
)
;
5198
5199 // String operations:
5200 /**
5201 * @brief Return const pointer to null-terminated contents.
5202 *
5203 * This is a handle to internal data. Do not modify or dire things may
5204 * happen.
5205 */
5206 const _CharT*
5207 c_str() const _GLIBCXX_NOEXCEPTnoexcept
5208 { return _M_data(); }
5209
5210 /**
5211 * @brief Return const pointer to contents.
5212 *
5213 * This is a pointer to internal data. It is undefined to modify
5214 * the contents through the returned pointer. To get a pointer that
5215 * allows modifying the contents use @c &str[0] instead,
5216 * (or in C++17 the non-const @c str.data() overload).
5217 */
5218 const _CharT*
5219 data() const _GLIBCXX_NOEXCEPTnoexcept
5220 { return _M_data(); }
5221
5222#if __cplusplus201703L >= 201703L
5223 /**
5224 * @brief Return non-const pointer to contents.
5225 *
5226 * This is a pointer to the character sequence held by the string.
5227 * Modifying the characters in the sequence is allowed.
5228 */
5229 _CharT*
5230 data() noexcept
5231 {
5232 _M_leak();
5233 return _M_data();
5234 }
5235#endif
5236
5237 /**
5238 * @brief Return copy of allocator used to construct this string.
5239 */
5240 allocator_type
5241 get_allocator() const _GLIBCXX_NOEXCEPTnoexcept
5242 { return _M_dataplus; }
5243
5244 /**
5245 * @brief Find position of a C substring.
5246 * @param __s C string to locate.
5247 * @param __pos Index of character to search from.
5248 * @param __n Number of characters from @a s to search for.
5249 * @return Index of start of first occurrence.
5250 *
5251 * Starting from @a __pos, searches forward for the first @a
5252 * __n characters in @a __s within this string. If found,
5253 * returns the index where it begins. If not found, returns
5254 * npos.
5255 */
5256 size_type
5257 find(const _CharT* __s, size_type __pos, size_type __n) const
5258 _GLIBCXX_NOEXCEPTnoexcept;
5259
5260 /**
5261 * @brief Find position of a string.
5262 * @param __str String to locate.
5263 * @param __pos Index of character to search from (default 0).
5264 * @return Index of start of first occurrence.
5265 *
5266 * Starting from @a __pos, searches forward for value of @a __str within
5267 * this string. If found, returns the index where it begins. If not
5268 * found, returns npos.
5269 */
5270 size_type
5271 find(const basic_string& __str, size_type __pos = 0) const
5272 _GLIBCXX_NOEXCEPTnoexcept
5273 { return this->find(__str.data(), __pos, __str.size()); }
5274
5275 /**
5276 * @brief Find position of a C string.
5277 * @param __s C string to locate.
5278 * @param __pos Index of character to search from (default 0).
5279 * @return Index of start of first occurrence.
5280 *
5281 * Starting from @a __pos, searches forward for the value of @a
5282 * __s within this string. If found, returns the index where
5283 * it begins. If not found, returns npos.
5284 */
5285 size_type
5286 find(const _CharT* __s, size_type __pos = 0) const _GLIBCXX_NOEXCEPTnoexcept
5287 {
5288 __glibcxx_requires_string(__s);
5289 return this->find(__s, __pos, traits_type::length(__s));
5290 }
5291
5292 /**
5293 * @brief Find position of a character.
5294 * @param __c Character to locate.
5295 * @param __pos Index of character to search from (default 0).
5296 * @return Index of first occurrence.
5297 *
5298 * Starting from @a __pos, searches forward for @a __c within
5299 * this string. If found, returns the index where it was
5300 * found. If not found, returns npos.
5301 */
5302 size_type
5303 find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPTnoexcept;
5304
5305#if __cplusplus201703L >= 201703L
5306 /**
5307 * @brief Find position of a string_view.
5308 * @param __svt The object convertible to string_view to locate.
5309 * @param __pos Index of character to search from (default 0).
5310 * @return Index of start of first occurrence.
5311 */
5312 template<typename _Tp>
5313 _If_sv<_Tp, size_type>
5314 find(const _Tp& __svt, size_type __pos = 0) const
5315 noexcept(is_same<_Tp, __sv_type>::value)
5316 {
5317 __sv_type __sv = __svt;
5318 return this->find(__sv.data(), __pos, __sv.size());
5319 }
5320#endif // C++17
5321
5322 /**
5323 * @brief Find last position of a string.
5324 * @param __str String to locate.
5325 * @param __pos Index of character to search back from (default end).
5326 * @return Index of start of last occurrence.
5327 *
5328 * Starting from @a __pos, searches backward for value of @a
5329 * __str within this string. If found, returns the index where
5330 * it begins. If not found, returns npos.
5331 */
5332 size_type
5333 rfind(const basic_string& __str, size_type __pos = npos) const
5334 _GLIBCXX_NOEXCEPTnoexcept
5335 { return this->rfind(__str.data(), __pos, __str.size()); }
5336
5337 /**
5338 * @brief Find last position of a C substring.
5339 * @param __s C string to locate.
5340 * @param __pos Index of character to search back from.
5341 * @param __n Number of characters from s to search for.
5342 * @return Index of start of last occurrence.
5343 *
5344 * Starting from @a __pos, searches backward for the first @a
5345 * __n characters in @a __s within this string. If found,
5346 * returns the index where it begins. If not found, returns
5347 * npos.
5348 */
5349 size_type
5350 rfind(const _CharT* __s, size_type __pos, size_type __n) const
5351 _GLIBCXX_NOEXCEPTnoexcept;
5352
5353 /**
5354 * @brief Find last position of a C string.
5355 * @param __s C string to locate.
5356 * @param __pos Index of character to start search at (default end).
5357 * @return Index of start of last occurrence.
5358 *
5359 * Starting from @a __pos, searches backward for the value of
5360 * @a __s within this string. If found, returns the index
5361 * where it begins. If not found, returns npos.
5362 */
5363 size_type
5364 rfind(const _CharT* __s, size_type __pos = npos) const _GLIBCXX_NOEXCEPTnoexcept
5365 {
5366 __glibcxx_requires_string(__s);
5367 return this->rfind(__s, __pos, traits_type::length(__s));
5368 }
5369
5370 /**
5371 * @brief Find last position of a character.
5372 * @param __c Character to locate.
5373 * @param __pos Index of character to search back from (default end).
5374 * @return Index of last occurrence.
5375 *
5376 * Starting from @a __pos, searches backward for @a __c within
5377 * this string. If found, returns the index where it was
5378 * found. If not found, returns npos.
5379 */
5380 size_type
5381 rfind(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPTnoexcept;
5382
5383#if __cplusplus201703L >= 201703L
5384 /**
5385 * @brief Find last position of a string_view.
5386 * @param __svt The object convertible to string_view to locate.
5387 * @param __pos Index of character to search back from (default end).
5388 * @return Index of start of last occurrence.
5389 */
5390 template<typename _Tp>
5391 _If_sv<_Tp, size_type>
5392 rfind(const _Tp& __svt, size_type __pos = npos) const
5393 noexcept(is_same<_Tp, __sv_type>::value)
5394 {
5395 __sv_type __sv = __svt;
5396 return this->rfind(__sv.data(), __pos, __sv.size());
5397 }
5398#endif // C++17
5399
5400 /**
5401 * @brief Find position of a character of string.
5402 * @param __str String containing characters to locate.
5403 * @param __pos Index of character to search from (default 0).
5404 * @return Index of first occurrence.
5405 *
5406 * Starting from @a __pos, searches forward for one of the
5407 * characters of @a __str within this string. If found,
5408 * returns the index where it was found. If not found, returns
5409 * npos.
5410 */
5411 size_type
5412 find_first_of(const basic_string& __str, size_type __pos = 0) const
5413 _GLIBCXX_NOEXCEPTnoexcept
5414 { return this->find_first_of(__str.data(), __pos, __str.size()); }
5415
5416 /**
5417 * @brief Find position of a character of C substring.
5418 * @param __s String containing characters to locate.
5419 * @param __pos Index of character to search from.
5420 * @param __n Number of characters from s to search for.
5421 * @return Index of first occurrence.
5422 *
5423 * Starting from @a __pos, searches forward for one of the
5424 * first @a __n characters of @a __s within this string. If
5425 * found, returns the index where it was found. If not found,
5426 * returns npos.
5427 */
5428 size_type
5429 find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
5430 _GLIBCXX_NOEXCEPTnoexcept;
5431
5432 /**
5433 * @brief Find position of a character of C string.
5434 * @param __s String containing characters to locate.
5435 * @param __pos Index of character to search from (default 0).
5436 * @return Index of first occurrence.
5437 *
5438 * Starting from @a __pos, searches forward for one of the
5439 * characters of @a __s within this string. If found, returns
5440 * the index where it was found. If not found, returns npos.
5441 */
5442 size_type
5443 find_first_of(const _CharT* __s, size_type __pos = 0) const
5444 _GLIBCXX_NOEXCEPTnoexcept
5445 {
5446 __glibcxx_requires_string(__s);
5447 return this->find_first_of(__s, __pos, traits_type::length(__s));
5448 }
5449
5450 /**
5451 * @brief Find position of a character.
5452 * @param __c Character to locate.
5453 * @param __pos Index of character to search from (default 0).
5454 * @return Index of first occurrence.
5455 *
5456 * Starting from @a __pos, searches forward for the character
5457 * @a __c within this string. If found, returns the index
5458 * where it was found. If not found, returns npos.
5459 *
5460 * Note: equivalent to find(__c, __pos).
5461 */
5462 size_type
5463 find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPTnoexcept
5464 { return this->find(__c, __pos); }
5465
5466#if __cplusplus201703L >= 201703L
5467 /**
5468 * @brief Find position of a character of a string_view.
5469 * @param __svt An object convertible to string_view containing
5470 * characters to locate.
5471 * @param __pos Index of character to search from (default 0).
5472 * @return Index of first occurrence.
5473 */
5474 template<typename _Tp>
5475 _If_sv<_Tp, size_type>
5476 find_first_of(const _Tp& __svt, size_type __pos = 0) const
5477 noexcept(is_same<_Tp, __sv_type>::value)
5478 {
5479 __sv_type __sv = __svt;
5480 return this->find_first_of(__sv.data(), __pos, __sv.size());
5481 }
5482#endif // C++17
5483
5484 /**
5485 * @brief Find last position of a character of string.
5486 * @param __str String containing characters to locate.
5487 * @param __pos Index of character to search back from (default end).
5488 * @return Index of last occurrence.
5489 *
5490 * Starting from @a __pos, searches backward for one of the
5491 * characters of @a __str within this string. If found,
5492 * returns the index where it was found. If not found, returns
5493 * npos.
5494 */
5495 size_type
5496 find_last_of(const basic_string& __str, size_type __pos = npos) const
5497 _GLIBCXX_NOEXCEPTnoexcept
5498 { return this->find_last_of(__str.data(), __pos, __str.size()); }
5499
5500 /**
5501 * @brief Find last position of a character of C substring.
5502 * @param __s C string containing characters to locate.
5503 * @param __pos Index of character to search back from.
5504 * @param __n Number of characters from s to search for.
5505 * @return Index of last occurrence.
5506 *
5507 * Starting from @a __pos, searches backward for one of the
5508 * first @a __n characters of @a __s within this string. If
5509 * found, returns the index where it was found. If not found,
5510 * returns npos.
5511 */
5512 size_type
5513 find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
5514 _GLIBCXX_NOEXCEPTnoexcept;
5515
5516 /**
5517 * @brief Find last position of a character of C string.
5518 * @param __s C string containing characters to locate.
5519 * @param __pos Index of character to search back from (default end).
5520 * @return Index of last occurrence.
5521 *
5522 * Starting from @a __pos, searches backward for one of the
5523 * characters of @a __s within this string. If found, returns
5524 * the index where it was found. If not found, returns npos.
5525 */
5526 size_type
5527 find_last_of(const _CharT* __s, size_type __pos = npos) const
5528 _GLIBCXX_NOEXCEPTnoexcept
5529 {
5530 __glibcxx_requires_string(__s);
5531 return this->find_last_of(__s, __pos, traits_type::length(__s));
5532 }
5533
5534 /**
5535 * @brief Find last position of a character.
5536 * @param __c Character to locate.
5537 * @param __pos Index of character to search back from (default end).
5538 * @return Index of last occurrence.
5539 *
5540 * Starting from @a __pos, searches backward for @a __c within
5541 * this string. If found, returns the index where it was
5542 * found. If not found, returns npos.
5543 *
5544 * Note: equivalent to rfind(__c, __pos).
5545 */
5546 size_type
5547 find_last_of(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPTnoexcept
5548 { return this->rfind(__c, __pos); }
5549
5550#if __cplusplus201703L >= 201703L
5551 /**
5552 * @brief Find last position of a character of string.
5553 * @param __svt An object convertible to string_view containing
5554 * characters to locate.
5555 * @param __pos Index of character to search back from (default end).
5556 * @return Index of last occurrence.
5557 */
5558 template<typename _Tp>
5559 _If_sv<_Tp, size_type>
5560 find_last_of(const _Tp& __svt, size_type __pos = npos) const
5561 noexcept(is_same<_Tp, __sv_type>::value)
5562 {
5563 __sv_type __sv = __svt;
5564 return this->find_last_of(__sv.data(), __pos, __sv.size());
5565 }
5566#endif // C++17
5567
5568 /**
5569 * @brief Find position of a character not in string.
5570 * @param __str String containing characters to avoid.
5571 * @param __pos Index of character to search from (default 0).
5572 * @return Index of first occurrence.
5573 *
5574 * Starting from @a __pos, searches forward for a character not contained
5575 * in @a __str within this string. If found, returns the index where it
5576 * was found. If not found, returns npos.
5577 */
5578 size_type
5579 find_first_not_of(const basic_string& __str, size_type __pos = 0) const
5580 _GLIBCXX_NOEXCEPTnoexcept
5581 { return this->find_first_not_of(__str.data(), __pos, __str.size()); }
5582
5583 /**
5584 * @brief Find position of a character not in C substring.
5585 * @param __s C string containing characters to avoid.
5586 * @param __pos Index of character to search from.
5587 * @param __n Number of characters from __s to consider.
5588 * @return Index of first occurrence.
5589 *
5590 * Starting from @a __pos, searches forward for a character not
5591 * contained in the first @a __n characters of @a __s within
5592 * this string. If found, returns the index where it was
5593 * found. If not found, returns npos.
5594 */
5595 size_type
5596 find_first_not_of(const _CharT* __s, size_type __pos,
5597 size_type __n) const _GLIBCXX_NOEXCEPTnoexcept;
5598
5599 /**
5600 * @brief Find position of a character not in C string.
5601 * @param __s C string containing characters to avoid.
5602 * @param __pos Index of character to search from (default 0).
5603 * @return Index of first occurrence.
5604 *
5605 * Starting from @a __pos, searches forward for a character not
5606 * contained in @a __s within this string. If found, returns
5607 * the index where it was found. If not found, returns npos.
5608 */
5609 size_type
5610 find_first_not_of(const _CharT* __s, size_type __pos = 0) const
5611 _GLIBCXX_NOEXCEPTnoexcept
5612 {
5613 __glibcxx_requires_string(__s);
5614 return this->find_first_not_of(__s, __pos, traits_type::length(__s));
5615 }
5616
5617 /**
5618 * @brief Find position of a different character.
5619 * @param __c Character to avoid.
5620 * @param __pos Index of character to search from (default 0).
5621 * @return Index of first occurrence.
5622 *
5623 * Starting from @a __pos, searches forward for a character
5624 * other than @a __c within this string. If found, returns the
5625 * index where it was found. If not found, returns npos.
5626 */
5627 size_type
5628 find_first_not_of(_CharT __c, size_type __pos = 0) const
5629 _GLIBCXX_NOEXCEPTnoexcept;
5630
5631#if __cplusplus201703L >= 201703L
5632 /**
5633 * @brief Find position of a character not in a string_view.
5634 * @param __svt An object convertible to string_view containing
5635 * characters to avoid.
5636 * @param __pos Index of character to search from (default 0).
5637 * @return Index of first occurrence.
5638 */
5639 template<typename _Tp>
5640 _If_sv<_Tp, size_type>
5641 find_first_not_of(const _Tp& __svt, size_type __pos = 0) const
5642 noexcept(is_same<_Tp, __sv_type>::value)
5643 {
5644 __sv_type __sv = __svt;
5645 return this->find_first_not_of(__sv.data(), __pos, __sv.size());
5646 }
5647#endif // C++17
5648
5649 /**
5650 * @brief Find last position of a character not in string.
5651 * @param __str String containing characters to avoid.
5652 * @param __pos Index of character to search back from (default end).
5653 * @return Index of last occurrence.
5654 *
5655 * Starting from @a __pos, searches backward for a character
5656 * not contained in @a __str within this string. If found,
5657 * returns the index where it was found. If not found, returns
5658 * npos.
5659 */
5660 size_type
5661 find_last_not_of(const basic_string& __str, size_type __pos = npos) const
5662 _GLIBCXX_NOEXCEPTnoexcept
5663 { return this->find_last_not_of(__str.data(), __pos, __str.size()); }
5664
5665 /**
5666 * @brief Find last position of a character not in C substring.
5667 * @param __s C string containing characters to avoid.
5668 * @param __pos Index of character to search back from.
5669 * @param __n Number of characters from s to consider.
5670 * @return Index of last occurrence.
5671 *
5672 * Starting from @a __pos, searches backward for a character not
5673 * contained in the first @a __n characters of @a __s within this string.
5674 * If found, returns the index where it was found. If not found,
5675 * returns npos.
5676 */
5677 size_type
5678 find_last_not_of(const _CharT* __s, size_type __pos,
5679 size_type __n) const _GLIBCXX_NOEXCEPTnoexcept;
5680 /**
5681 * @brief Find last position of a character not in C string.
5682 * @param __s C string containing characters to avoid.
5683 * @param __pos Index of character to search back from (default end).
5684 * @return Index of last occurrence.
5685 *
5686 * Starting from @a __pos, searches backward for a character
5687 * not contained in @a __s within this string. If found,
5688 * returns the index where it was found. If not found, returns
5689 * npos.
5690 */
5691 size_type
5692 find_last_not_of(const _CharT* __s, size_type __pos = npos) const
5693 _GLIBCXX_NOEXCEPTnoexcept
5694 {
5695 __glibcxx_requires_string(__s);
5696 return this->find_last_not_of(__s, __pos, traits_type::length(__s));
5697 }
5698
5699 /**
5700 * @brief Find last position of a different character.
5701 * @param __c Character to avoid.
5702 * @param __pos Index of character to search back from (default end).
5703 * @return Index of last occurrence.
5704 *
5705 * Starting from @a __pos, searches backward for a character other than
5706 * @a __c within this string. If found, returns the index where it was
5707 * found. If not found, returns npos.
5708 */
5709 size_type
5710 find_last_not_of(_CharT __c, size_type __pos = npos) const
5711 _GLIBCXX_NOEXCEPTnoexcept;
5712
5713#if __cplusplus201703L >= 201703L
5714 /**
5715 * @brief Find last position of a character not in a string_view.
5716 * @param __svt An object convertible to string_view containing
5717 * characters to avoid.
5718 * @param __pos Index of character to search back from (default end).
5719 * @return Index of last occurrence.
5720 */
5721 template<typename _Tp>
5722 _If_sv<_Tp, size_type>
5723 find_last_not_of(const _Tp& __svt, size_type __pos = npos) const
5724 noexcept(is_same<_Tp, __sv_type>::value)
5725 {
5726 __sv_type __sv = __svt;
5727 return this->find_last_not_of(__sv.data(), __pos, __sv.size());
5728 }
5729#endif // C++17
5730
5731 /**
5732 * @brief Get a substring.
5733 * @param __pos Index of first character (default 0).
5734 * @param __n Number of characters in substring (default remainder).
5735 * @return The new string.
5736 * @throw std::out_of_range If __pos > size().
5737 *
5738 * Construct and return a new string using the @a __n
5739 * characters starting at @a __pos. If the string is too
5740 * short, use the remainder of the characters. If @a __pos is
5741 * beyond the end of the string, out_of_range is thrown.
5742 */
5743 basic_string
5744 substr(size_type __pos = 0, size_type __n = npos) const
5745 { return basic_string(*this,
5746 _M_check(__pos, "basic_string::substr"), __n); }
5747
5748 /**
5749 * @brief Compare to a string.
5750 * @param __str String to compare against.
5751 * @return Integer < 0, 0, or > 0.
5752 *
5753 * Returns an integer < 0 if this string is ordered before @a
5754 * __str, 0 if their values are equivalent, or > 0 if this
5755 * string is ordered after @a __str. Determines the effective
5756 * length rlen of the strings to compare as the smallest of
5757 * size() and str.size(). The function then compares the two
5758 * strings by calling traits::compare(data(), str.data(),rlen).
5759 * If the result of the comparison is nonzero returns it,
5760 * otherwise the shorter one is ordered first.
5761 */
5762 int
5763 compare(const basic_string& __str) const
5764 {
5765 const size_type __size = this->size();
5766 const size_type __osize = __str.size();
5767 const size_type __len = std::min(__size, __osize);
5768
5769 int __r = traits_type::compare(_M_data(), __str.data(), __len);
5770 if (!__r)
5771 __r = _S_compare(__size, __osize);
5772 return __r;
5773 }
5774
5775#if __cplusplus201703L >= 201703L
5776 /**
5777 * @brief Compare to a string_view.
5778 * @param __svt An object convertible to string_view to compare against.
5779 * @return Integer < 0, 0, or > 0.
5780 */
5781 template<typename _Tp>
5782 _If_sv<_Tp, int>
5783 compare(const _Tp& __svt) const
5784 noexcept(is_same<_Tp, __sv_type>::value)
5785 {
5786 __sv_type __sv = __svt;
5787 const size_type __size = this->size();
5788 const size_type __osize = __sv.size();
5789 const size_type __len = std::min(__size, __osize);
5790
5791 int __r = traits_type::compare(_M_data(), __sv.data(), __len);
5792 if (!__r)
5793 __r = _S_compare(__size, __osize);
5794 return __r;
5795 }
5796
5797 /**
5798 * @brief Compare to a string_view.
5799 * @param __pos A position in the string to start comparing from.
5800 * @param __n The number of characters to compare.
5801 * @param __svt An object convertible to string_view to compare
5802 * against.
5803 * @return Integer < 0, 0, or > 0.
5804 */
5805 template<typename _Tp>
5806 _If_sv<_Tp, int>
5807 compare(size_type __pos, size_type __n, const _Tp& __svt) const
5808 noexcept(is_same<_Tp, __sv_type>::value)
5809 {
5810 __sv_type __sv = __svt;
5811 return __sv_type(*this).substr(__pos, __n).compare(__sv);
5812 }
5813
5814 /**
5815 * @brief Compare to a string_view.
5816 * @param __pos1 A position in the string to start comparing from.
5817 * @param __n1 The number of characters to compare.
5818 * @param __svt An object convertible to string_view to compare
5819 * against.
5820 * @param __pos2 A position in the string_view to start comparing from.
5821 * @param __n2 The number of characters to compare.
5822 * @return Integer < 0, 0, or > 0.
5823 */
5824 template<typename _Tp>
5825 _If_sv<_Tp, int>
5826 compare(size_type __pos1, size_type __n1, const _Tp& __svt,
5827 size_type __pos2, size_type __n2 = npos) const
5828 noexcept(is_same<_Tp, __sv_type>::value)
5829 {
5830 __sv_type __sv = __svt;
5831 return __sv_type(*this)
5832 .substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
5833 }
5834#endif // C++17
5835
5836 /**
5837 * @brief Compare substring to a string.
5838 * @param __pos Index of first character of substring.
5839 * @param __n Number of characters in substring.
5840 * @param __str String to compare against.
5841 * @return Integer < 0, 0, or > 0.
5842 *
5843 * Form the substring of this string from the @a __n characters
5844 * starting at @a __pos. Returns an integer < 0 if the
5845 * substring is ordered before @a __str, 0 if their values are
5846 * equivalent, or > 0 if the substring is ordered after @a
5847 * __str. Determines the effective length rlen of the strings
5848 * to compare as the smallest of the length of the substring
5849 * and @a __str.size(). The function then compares the two
5850 * strings by calling
5851 * traits::compare(substring.data(),str.data(),rlen). If the
5852 * result of the comparison is nonzero returns it, otherwise
5853 * the shorter one is ordered first.
5854 */
5855 int
5856 compare(size_type __pos, size_type __n, const basic_string& __str) const;
5857
5858 /**
5859 * @brief Compare substring to a substring.
5860 * @param __pos1 Index of first character of substring.
5861 * @param __n1 Number of characters in substring.
5862 * @param __str String to compare against.
5863 * @param __pos2 Index of first character of substring of str.
5864 * @param __n2 Number of characters in substring of str.
5865 * @return Integer < 0, 0, or > 0.
5866 *
5867 * Form the substring of this string from the @a __n1
5868 * characters starting at @a __pos1. Form the substring of @a
5869 * __str from the @a __n2 characters starting at @a __pos2.
5870 * Returns an integer < 0 if this substring is ordered before
5871 * the substring of @a __str, 0 if their values are equivalent,
5872 * or > 0 if this substring is ordered after the substring of
5873 * @a __str. Determines the effective length rlen of the
5874 * strings to compare as the smallest of the lengths of the
5875 * substrings. The function then compares the two strings by
5876 * calling
5877 * traits::compare(substring.data(),str.substr(pos2,n2).data(),rlen).
5878 * If the result of the comparison is nonzero returns it,
5879 * otherwise the shorter one is ordered first.
5880 */
5881 int
5882 compare(size_type __pos1, size_type __n1, const basic_string& __str,
5883 size_type __pos2, size_type __n2 = npos) const;
5884
5885 /**
5886 * @brief Compare to a C string.
5887 * @param __s C string to compare against.
5888 * @return Integer < 0, 0, or > 0.
5889 *
5890 * Returns an integer < 0 if this string is ordered before @a __s, 0 if
5891 * their values are equivalent, or > 0 if this string is ordered after
5892 * @a __s. Determines the effective length rlen of the strings to
5893 * compare as the smallest of size() and the length of a string
5894 * constructed from @a __s. The function then compares the two strings
5895 * by calling traits::compare(data(),s,rlen). If the result of the
5896 * comparison is nonzero returns it, otherwise the shorter one is
5897 * ordered first.
5898 */
5899 int
5900 compare(const _CharT* __s) const _GLIBCXX_NOEXCEPTnoexcept;
5901
5902 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5903 // 5 String::compare specification questionable
5904 /**
5905 * @brief Compare substring to a C string.
5906 * @param __pos Index of first character of substring.
5907 * @param __n1 Number of characters in substring.
5908 * @param __s C string to compare against.
5909 * @return Integer < 0, 0, or > 0.
5910 *
5911 * Form the substring of this string from the @a __n1
5912 * characters starting at @a pos. Returns an integer < 0 if
5913 * the substring is ordered before @a __s, 0 if their values
5914 * are equivalent, or > 0 if the substring is ordered after @a
5915 * __s. Determines the effective length rlen of the strings to
5916 * compare as the smallest of the length of the substring and
5917 * the length of a string constructed from @a __s. The
5918 * function then compares the two string by calling
5919 * traits::compare(substring.data(),__s,rlen). If the result of
5920 * the comparison is nonzero returns it, otherwise the shorter
5921 * one is ordered first.
5922 */
5923 int
5924 compare(size_type __pos, size_type __n1, const _CharT* __s) const;
5925
5926 /**
5927 * @brief Compare substring against a character %array.
5928 * @param __pos Index of first character of substring.
5929 * @param __n1 Number of characters in substring.
5930 * @param __s character %array to compare against.
5931 * @param __n2 Number of characters of s.
5932 * @return Integer < 0, 0, or > 0.
5933 *
5934 * Form the substring of this string from the @a __n1
5935 * characters starting at @a __pos. Form a string from the
5936 * first @a __n2 characters of @a __s. Returns an integer < 0
5937 * if this substring is ordered before the string from @a __s,
5938 * 0 if their values are equivalent, or > 0 if this substring
5939 * is ordered after the string from @a __s. Determines the
5940 * effective length rlen of the strings to compare as the
5941 * smallest of the length of the substring and @a __n2. The
5942 * function then compares the two strings by calling
5943 * traits::compare(substring.data(),s,rlen). If the result of
5944 * the comparison is nonzero returns it, otherwise the shorter
5945 * one is ordered first.
5946 *
5947 * NB: s must have at least n2 characters, &apos;\\0&apos; has
5948 * no special meaning.
5949 */
5950 int
5951 compare(size_type __pos, size_type __n1, const _CharT* __s,
5952 size_type __n2) const;
5953
5954#if __cplusplus201703L > 201703L
5955 bool
5956 starts_with(basic_string_view<_CharT, _Traits> __x) const noexcept
5957 { return __sv_type(this->data(), this->size()).starts_with(__x); }
5958
5959 bool
5960 starts_with(_CharT __x) const noexcept
5961 { return __sv_type(this->data(), this->size()).starts_with(__x); }
5962
5963 bool
5964 starts_with(const _CharT* __x) const noexcept
5965 { return __sv_type(this->data(), this->size()).starts_with(__x); }
5966
5967 bool
5968 ends_with(basic_string_view<_CharT, _Traits> __x) const noexcept
5969 { return __sv_type(this->data(), this->size()).ends_with(__x); }
5970
5971 bool
5972 ends_with(_CharT __x) const noexcept
5973 { return __sv_type(this->data(), this->size()).ends_with(__x); }
5974
5975 bool
5976 ends_with(const _CharT* __x) const noexcept
5977 { return __sv_type(this->data(), this->size()).ends_with(__x); }
5978#endif // C++20
5979
5980# ifdef _GLIBCXX_TM_TS_INTERNAL
5981 friend void
5982 ::_txnal_cow_string_C1_for_exceptions(void* that, const char* s,
5983 void* exc);
5984 friend const char*
5985 ::_txnal_cow_string_c_str(const void *that);
5986 friend void
5987 ::_txnal_cow_string_D1(void *that);
5988 friend void
5989 ::_txnal_cow_string_D1_commit(void *that);
5990# endif
5991 };
5992#endif // !_GLIBCXX_USE_CXX11_ABI
5993
5994#if __cpp_deduction_guides201703L >= 201606
5995_GLIBCXX_BEGIN_NAMESPACE_CXX11namespace __cxx11 {
5996 template<typename _InputIterator, typename _CharT
5997 = typename iterator_traits<_InputIterator>::value_type,
5998 typename _Allocator = allocator<_CharT>,
5999 typename = _RequireInputIter<_InputIterator>,
6000 typename = _RequireAllocator<_Allocator>>
6001 basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator())
6002 -> basic_string<_CharT, char_traits<_CharT>, _Allocator>;
6003
6004 // _GLIBCXX_RESOLVE_LIB_DEFECTS
6005 // 3075. basic_string needs deduction guides from basic_string_view
6006 template<typename _CharT, typename _Traits,
6007 typename _Allocator = allocator<_CharT>,
6008 typename = _RequireAllocator<_Allocator>>
6009 basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _Allocator())
6010 -> basic_string<_CharT, _Traits, _Allocator>;
6011
6012 template<typename _CharT, typename _Traits,
6013 typename _Allocator = allocator<_CharT>,
6014 typename = _RequireAllocator<_Allocator>>
6015 basic_string(basic_string_view<_CharT, _Traits>,
6016 typename basic_string<_CharT, _Traits, _Allocator>::size_type,
6017 typename basic_string<_CharT, _Traits, _Allocator>::size_type,
6018 const _Allocator& = _Allocator())
6019 -> basic_string<_CharT, _Traits, _Allocator>;
6020_GLIBCXX_END_NAMESPACE_CXX11}
6021#endif
6022
6023 // operator+
6024 /**
6025 * @brief Concatenate two strings.
6026 * @param __lhs First string.
6027 * @param __rhs Last string.
6028 * @return New string with value of @a __lhs followed by @a __rhs.
6029 */
6030 template<typename _CharT, typename _Traits, typename _Alloc>
6031 basic_string<_CharT, _Traits, _Alloc>
6032 operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
6033 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
6034 {
6035 basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
6036 __str.append(__rhs);
6037 return __str;
6038 }
6039
6040 /**
6041 * @brief Concatenate C string and string.
6042 * @param __lhs First string.
6043 * @param __rhs Last string.
6044 * @return New string with value of @a __lhs followed by @a __rhs.
6045 */
6046 template<typename _CharT, typename _Traits, typename _Alloc>
6047 basic_string<_CharT,_Traits,_Alloc>
6048 operator+(const _CharT* __lhs,
6049 const basic_string<_CharT,_Traits,_Alloc>& __rhs);
6050
6051 /**
6052 * @brief Concatenate character and string.
6053 * @param __lhs First string.
6054 * @param __rhs Last string.
6055 * @return New string with @a __lhs followed by @a __rhs.
6056 */
6057 template<typename _CharT, typename _Traits, typename _Alloc>
6058 basic_string<_CharT,_Traits,_Alloc>
6059 operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs);
6060
6061 /**
6062 * @brief Concatenate string and C string.
6063 * @param __lhs First string.
6064 * @param __rhs Last string.
6065 * @return New string with @a __lhs followed by @a __rhs.
6066 */
6067 template<typename _CharT, typename _Traits, typename _Alloc>
6068 inline basic_string<_CharT, _Traits, _Alloc>
6069 operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
6070 const _CharT* __rhs)
6071 {
6072 basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
6073 __str.append(__rhs);
6074 return __str;
6075 }
6076
6077 /**
6078 * @brief Concatenate string and character.
6079 * @param __lhs First string.
6080 * @param __rhs Last string.
6081 * @return New string with @a __lhs followed by @a __rhs.
6082 */
6083 template<typename _CharT, typename _Traits, typename _Alloc>
6084 inline basic_string<_CharT, _Traits, _Alloc>
6085 operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs)
6086 {
6087 typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
6088 typedef typename __string_type::size_type __size_type;
6089 __string_type __str(__lhs);
6090 __str.append(__size_type(1), __rhs);
6091 return __str;
6092 }
6093
6094#if __cplusplus201703L >= 201103L
6095 template<typename _CharT, typename _Traits, typename _Alloc>
6096 inline basic_string<_CharT, _Traits, _Alloc>
6097 operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
6098 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
6099 { return std::move(__lhs.append(__rhs)); }
6100
6101 template<typename _CharT, typename _Traits, typename _Alloc>
6102 inline basic_string<_CharT, _Traits, _Alloc>
6103 operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
6104 basic_string<_CharT, _Traits, _Alloc>&& __rhs)
6105 { return std::move(__rhs.insert(0, __lhs)); }
6106
6107 template<typename _CharT, typename _Traits, typename _Alloc>
6108 inline basic_string<_CharT, _Traits, _Alloc>
6109 operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
6110 basic_string<_CharT, _Traits, _Alloc>&& __rhs)
6111 {
6112#if _GLIBCXX_USE_CXX11_ABI1
6113 using _Alloc_traits = allocator_traits<_Alloc>;
6114 bool __use_rhs = false;
6115 if _GLIBCXX17_CONSTEXPRconstexpr (typename _Alloc_traits::is_always_equal{})
6116 __use_rhs = true;
6117 else if (__lhs.get_allocator() == __rhs.get_allocator())
6118 __use_rhs = true;
6119 if (__use_rhs)
6120#endif
6121 {
6122 const auto __size = __lhs.size() + __rhs.size();
6123 if (__size > __lhs.capacity() && __size <= __rhs.capacity())
6124 return std::move(__rhs.insert(0, __lhs));
6125 }
6126 return std::move(__lhs.append(__rhs));
6127 }
6128
6129 template<typename _CharT, typename _Traits, typename _Alloc>
6130 inline basic_string<_CharT, _Traits, _Alloc>
6131 operator+(const _CharT* __lhs,
6132 basic_string<_CharT, _Traits, _Alloc>&& __rhs)
6133 { return std::move(__rhs.insert(0, __lhs)); }
6134
6135 template<typename _CharT, typename _Traits, typename _Alloc>
6136 inline basic_string<_CharT, _Traits, _Alloc>
6137 operator+(_CharT __lhs,
6138 basic_string<_CharT, _Traits, _Alloc>&& __rhs)
6139 { return std::move(__rhs.insert(0, 1, __lhs)); }
6140
6141 template<typename _CharT, typename _Traits, typename _Alloc>
6142 inline basic_string<_CharT, _Traits, _Alloc>
6143 operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
6144 const _CharT* __rhs)
6145 { return std::move(__lhs.append(__rhs)); }
6146
6147 template<typename _CharT, typename _Traits, typename _Alloc>
6148 inline basic_string<_CharT, _Traits, _Alloc>
6149 operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
6150 _CharT __rhs)
6151 { return std::move(__lhs.append(1, __rhs)); }
6152#endif
6153
6154 // operator ==
6155 /**
6156 * @brief Test equivalence of two strings.
6157 * @param __lhs First string.
6158 * @param __rhs Second string.
6159 * @return True if @a __lhs.compare(@a __rhs) == 0. False otherwise.
6160 */
6161 template<typename _CharT, typename _Traits, typename _Alloc>
6162 inline bool
6163 operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
6164 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
6165 _GLIBCXX_NOEXCEPTnoexcept
6166 { return __lhs.compare(__rhs) == 0; }
6167
6168 template<typename _CharT>
6169 inline
6170 typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, bool>::__type
6171 operator==(const basic_string<_CharT>& __lhs,
6172 const basic_string<_CharT>& __rhs) _GLIBCXX_NOEXCEPTnoexcept
6173 { return (__lhs.size() == __rhs.size()
6174 && !std::char_traits<_CharT>::compare(__lhs.data(), __rhs.data(),
6175 __lhs.size())); }
6176
6177 /**
6178 * @brief Test equivalence of string and C string.
6179 * @param __lhs String.
6180 * @param __rhs C string.
6181 * @return True if @a __lhs.compare(@a __rhs) == 0. False otherwise.
6182 */
6183 template<typename _CharT, typename _Traits, typename _Alloc>
6184 inline bool
6185 operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
6186 const _CharT* __rhs)
6187 { return __lhs.compare(__rhs) == 0; }
6188
6189#if __cpp_lib_three_way_comparison
6190 /**
6191 * @brief Three-way comparison of a string and a C string.
6192 * @param __lhs A string.
6193 * @param __rhs A null-terminated string.
6194 * @return A value indicating whether `__lhs` is less than, equal to,
6195 * greater than, or incomparable with `__rhs`.
6196 */
6197 template<typename _CharT, typename _Traits, typename _Alloc>
6198 inline auto
6199 operator<=>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
6200 const basic_string<_CharT, _Traits, _Alloc>& __rhs) noexcept
6201 -> decltype(__detail::__char_traits_cmp_cat<_Traits>(0))
6202 { return __detail::__char_traits_cmp_cat<_Traits>(__lhs.compare(__rhs)); }
6203
6204 /**
6205 * @brief Three-way comparison of a string and a C string.
6206 * @param __lhs A string.
6207 * @param __rhs A null-terminated string.
6208 * @return A value indicating whether `__lhs` is less than, equal to,
6209 * greater than, or incomparable with `__rhs`.
6210 */
6211 template<typename _CharT, typename _Traits, typename _Alloc>
6212 inline auto
6213 operator<=>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
6214 const _CharT* __rhs) noexcept
6215 -> decltype(__detail::__char_traits_cmp_cat<_Traits>(0))
6216 { return __detail::__char_traits_cmp_cat<_Traits>(__lhs.compare(__rhs)); }
6217#else
6218 /**
6219 * @brief Test equivalence of C string and string.
6220 * @param __lhs C string.
6221 * @param __rhs String.
6222 * @return True if @a __rhs.compare(@a __lhs) == 0. False otherwise.
6223 */
6224 template<typename _CharT, typename _Traits, typename _Alloc>
6225 inline bool
6226 operator==(const _CharT* __lhs,
6227 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
6228 { return __rhs.compare(__lhs) == 0; }
6229
6230 // operator !=
6231 /**
6232 * @brief Test difference of two strings.
6233 * @param __lhs First string.
6234 * @param __rhs Second string.
6235 * @return True if @a __lhs.compare(@a __rhs) != 0. False otherwise.
6236 */
6237 template<typename _CharT, typename _Traits, typename _Alloc>
6238 inline bool
6239 operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
6240 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
6241 _GLIBCXX_NOEXCEPTnoexcept
6242 { return !(__lhs == __rhs); }
6243
6244 /**
6245 * @brief Test difference of C string and string.
6246 * @param __lhs C string.
6247 * @param __rhs String.
6248 * @return True if @a __rhs.compare(@a __lhs) != 0. False otherwise.
6249 */
6250 template<typename _CharT, typename _Traits, typename _Alloc>
6251 inline bool
6252 operator!=(const _CharT* __lhs,
6253 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
6254 { return !(__lhs == __rhs); }
6255
6256 /**
6257 * @brief Test difference of string and C string.
6258 * @param __lhs String.
6259 * @param __rhs C string.
6260 * @return True if @a __lhs.compare(@a __rhs) != 0. False otherwise.
6261 */
6262 template<typename _CharT, typename _Traits, typename _Alloc>
6263 inline bool
6264 operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
6265 const _CharT* __rhs)
6266 { return !(__lhs == __rhs); }
6267
6268 // operator <
6269 /**
6270 * @brief Test if string precedes string.
6271 * @param __lhs First string.
6272 * @param __rhs Second string.
6273 * @return True if @a __lhs precedes @a __rhs. False otherwise.
6274 */
6275 template<typename _CharT, typename _Traits, typename _Alloc>
6276 inline bool
6277 operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
6278 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
6279 _GLIBCXX_NOEXCEPTnoexcept
6280 { return __lhs.compare(__rhs) < 0; }
6281
6282 /**
6283 * @brief Test if string precedes C string.
6284 * @param __lhs String.
6285 * @param __rhs C string.
6286 * @return True if @a __lhs precedes @a __rhs. False otherwise.
6287 */
6288 template<typename _CharT, typename _Traits, typename _Alloc>
6289 inline bool
6290 operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
6291 const _CharT* __rhs)
6292 { return __lhs.compare(__rhs) < 0; }
6293
6294 /**
6295 * @brief Test if C string precedes string.
6296 * @param __lhs C string.
6297 * @param __rhs String.
6298 * @return True if @a __lhs precedes @a __rhs. False otherwise.
6299 */
6300 template<typename _CharT, typename _Traits, typename _Alloc>
6301 inline bool
6302 operator<(const _CharT* __lhs,
6303 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
6304 { return __rhs.compare(__lhs) > 0; }
6305
6306 // operator >
6307 /**
6308 * @brief Test if string follows string.
6309 * @param __lhs First string.
6310 * @param __rhs Second string.
6311 * @return True if @a __lhs follows @a __rhs. False otherwise.
6312 */
6313 template<typename _CharT, typename _Traits, typename _Alloc>
6314 inline bool
6315 operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
6316 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
6317 _GLIBCXX_NOEXCEPTnoexcept
6318 { return __lhs.compare(__rhs) > 0; }
6319
6320 /**
6321 * @brief Test if string follows C string.
6322 * @param __lhs String.
6323 * @param __rhs C string.
6324 * @return True if @a __lhs follows @a __rhs. False otherwise.
6325 */
6326 template<typename _CharT, typename _Traits, typename _Alloc>
6327 inline bool
6328 operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
6329 const _CharT* __rhs)
6330 { return __lhs.compare(__rhs) > 0; }
6331
6332 /**
6333 * @brief Test if C string follows string.
6334 * @param __lhs C string.
6335 * @param __rhs String.
6336 * @return True if @a __lhs follows @a __rhs. False otherwise.
6337 */
6338 template<typename _CharT, typename _Traits, typename _Alloc>
6339 inline bool
6340 operator>(const _CharT* __lhs,
6341 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
6342 { return __rhs.compare(__lhs) < 0; }
6343
6344 // operator <=
6345 /**
6346 * @brief Test if string doesn't follow string.
6347 * @param __lhs First string.
6348 * @param __rhs Second string.
6349 * @return True if @a __lhs doesn't follow @a __rhs. False otherwise.
6350 */
6351 template<typename _CharT, typename _Traits, typename _Alloc>
6352 inline bool
6353 operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
6354 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
6355 _GLIBCXX_NOEXCEPTnoexcept
6356 { return __lhs.compare(__rhs) <= 0; }
6357
6358 /**
6359 * @brief Test if string doesn't follow C string.
6360 * @param __lhs String.
6361 * @param __rhs C string.
6362 * @return True if @a __lhs doesn't follow @a __rhs. False otherwise.
6363 */
6364 template<typename _CharT, typename _Traits, typename _Alloc>
6365 inline bool
6366 operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
6367 const _CharT* __rhs)
6368 { return __lhs.compare(__rhs) <= 0; }
6369
6370 /**
6371 * @brief Test if C string doesn't follow string.
6372 * @param __lhs C string.
6373 * @param __rhs String.
6374 * @return True if @a __lhs doesn't follow @a __rhs. False otherwise.
6375 */
6376 template<typename _CharT, typename _Traits, typename _Alloc>
6377 inline bool
6378 operator<=(const _CharT* __lhs,
6379 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
6380 { return __rhs.compare(__lhs) >= 0; }
6381
6382 // operator >=
6383 /**
6384 * @brief Test if string doesn't precede string.
6385 * @param __lhs First string.
6386 * @param __rhs Second string.
6387 * @return True if @a __lhs doesn't precede @a __rhs. False otherwise.
6388 */
6389 template<typename _CharT, typename _Traits, typename _Alloc>
6390 inline bool
6391 operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
6392 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
6393 _GLIBCXX_NOEXCEPTnoexcept
6394 { return __lhs.compare(__rhs) >= 0; }
6395
6396 /**
6397 * @brief Test if string doesn't precede C string.
6398 * @param __lhs String.
6399 * @param __rhs C string.
6400 * @return True if @a __lhs doesn't precede @a __rhs. False otherwise.
6401 */
6402 template<typename _CharT, typename _Traits, typename _Alloc>
6403 inline bool
6404 operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
6405 const _CharT* __rhs)
6406 { return __lhs.compare(__rhs) >= 0; }
6407
6408 /**
6409 * @brief Test if C string doesn't precede string.
6410 * @param __lhs C string.
6411 * @param __rhs String.
6412 * @return True if @a __lhs doesn't precede @a __rhs. False otherwise.
6413 */
6414 template<typename _CharT, typename _Traits, typename _Alloc>
6415 inline bool
6416 operator>=(const _CharT* __lhs,
6417 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
6418 { return __rhs.compare(__lhs) <= 0; }
6419#endif // three-way comparison
6420
6421 /**
6422 * @brief Swap contents of two strings.
6423 * @param __lhs First string.
6424 * @param __rhs Second string.
6425 *
6426 * Exchanges the contents of @a __lhs and @a __rhs in constant time.
6427 */
6428 template<typename _CharT, typename _Traits, typename _Alloc>
6429 inline void
6430 swap(basic_string<_CharT, _Traits, _Alloc>& __lhs,
6431 basic_string<_CharT, _Traits, _Alloc>& __rhs)
6432 _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs)))noexcept(noexcept(__lhs.swap(__rhs)))
6433 { __lhs.swap(__rhs); }
6434
6435
6436 /**
6437 * @brief Read stream into a string.
6438 * @param __is Input stream.
6439 * @param __str Buffer to store into.
6440 * @return Reference to the input stream.
6441 *
6442 * Stores characters from @a __is into @a __str until whitespace is
6443 * found, the end of the stream is encountered, or str.max_size()
6444 * is reached. If is.width() is non-zero, that is the limit on the
6445 * number of characters stored into @a __str. Any previous
6446 * contents of @a __str are erased.
6447 */
6448 template<typename _CharT, typename _Traits, typename _Alloc>
6449 basic_istream<_CharT, _Traits>&
6450 operator>>(basic_istream<_CharT, _Traits>& __is,
6451 basic_string<_CharT, _Traits, _Alloc>& __str);
6452
6453 template<>
6454 basic_istream<char>&
6455 operator>>(basic_istream<char>& __is, basic_string<char>& __str);
6456
6457 /**
6458 * @brief Write string to a stream.
6459 * @param __os Output stream.
6460 * @param __str String to write out.
6461 * @return Reference to the output stream.
6462 *
6463 * Output characters of @a __str into os following the same rules as for
6464 * writing a C string.
6465 */
6466 template<typename _CharT, typename _Traits, typename _Alloc>
6467 inline basic_ostream<_CharT, _Traits>&
6468 operator<<(basic_ostream<_CharT, _Traits>& __os,
6469 const basic_string<_CharT, _Traits, _Alloc>& __str)
6470 {
6471 // _GLIBCXX_RESOLVE_LIB_DEFECTS
6472 // 586. string inserter not a formatted function
6473 return __ostream_insert(__os, __str.data(), __str.size());
6474 }
6475
6476 /**
6477 * @brief Read a line from stream into a string.
6478 * @param __is Input stream.
6479 * @param __str Buffer to store into.
6480 * @param __delim Character marking end of line.
6481 * @return Reference to the input stream.
6482 *
6483 * Stores characters from @a __is into @a __str until @a __delim is
6484 * found, the end of the stream is encountered, or str.max_size()
6485 * is reached. Any previous contents of @a __str are erased. If
6486 * @a __delim is encountered, it is extracted but not stored into
6487 * @a __str.
6488 */
6489 template<typename _CharT, typename _Traits, typename _Alloc>
6490 basic_istream<_CharT, _Traits>&
6491 getline(basic_istream<_CharT, _Traits>& __is,
6492 basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim);
6493
6494 /**
6495 * @brief Read a line from stream into a string.
6496 * @param __is Input stream.
6497 * @param __str Buffer to store into.
6498 * @return Reference to the input stream.
6499 *
6500 * Stores characters from is into @a __str until &apos;\n&apos; is
6501 * found, the end of the stream is encountered, or str.max_size()
6502 * is reached. Any previous contents of @a __str are erased. If
6503 * end of line is encountered, it is extracted but not stored into
6504 * @a __str.
6505 */
6506 template<typename _CharT, typename _Traits, typename _Alloc>
6507 inline basic_istream<_CharT, _Traits>&
6508 getline(basic_istream<_CharT, _Traits>& __is,
6509 basic_string<_CharT, _Traits, _Alloc>& __str)
6510 { return std::getline(__is, __str, __is.widen('\n')); }
6511
6512#if __cplusplus201703L >= 201103L
6513 /// Read a line from an rvalue stream into a string.
6514 template<typename _CharT, typename _Traits, typename _Alloc>
6515 inline basic_istream<_CharT, _Traits>&
6516 getline(basic_istream<_CharT, _Traits>&& __is,
6517 basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim)
6518 { return std::getline(__is, __str, __delim); }
6519
6520 /// Read a line from an rvalue stream into a string.
6521 template<typename _CharT, typename _Traits, typename _Alloc>
6522 inline basic_istream<_CharT, _Traits>&
6523 getline(basic_istream<_CharT, _Traits>&& __is,
6524 basic_string<_CharT, _Traits, _Alloc>& __str)
6525 { return std::getline(__is, __str); }
6526#endif
6527
6528 template<>
6529 basic_istream<char>&
6530 getline(basic_istream<char>& __in, basic_string<char>& __str,
6531 char __delim);
6532
6533#ifdef _GLIBCXX_USE_WCHAR_T1
6534 template<>
6535 basic_istream<wchar_t>&
6536 getline(basic_istream<wchar_t>& __in, basic_string<wchar_t>& __str,
6537 wchar_t __delim);
6538#endif
6539
6540_GLIBCXX_END_NAMESPACE_VERSION
6541} // namespace
6542
6543#if __cplusplus201703L >= 201103L
6544
6545#include <ext/string_conversions.h>
6546#include <bits/charconv.h>
6547
6548namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
6549{
6550_GLIBCXX_BEGIN_NAMESPACE_VERSION
6551_GLIBCXX_BEGIN_NAMESPACE_CXX11namespace __cxx11 {
6552
6553#if _GLIBCXX_USE_C99_STDLIB1
6554 // 21.4 Numeric Conversions [string.conversions].
6555 inline int
6556 stoi(const string& __str, size_t* __idx = 0, int __base = 10)
6557 { return __gnu_cxx::__stoa<long, int>(&std::strtol, "stoi", __str.c_str(),
6558 __idx, __base); }
6559
6560 inline long
6561 stol(const string& __str, size_t* __idx = 0, int __base = 10)
6562 { return __gnu_cxx::__stoa(&std::strtol, "stol", __str.c_str(),
6563 __idx, __base); }
6564
6565 inline unsigned long
6566 stoul(const string& __str, size_t* __idx = 0, int __base = 10)
6567 { return __gnu_cxx::__stoa(&std::strtoul, "stoul", __str.c_str(),
6568 __idx, __base); }
6569
6570 inline long long
6571 stoll(const string& __str, size_t* __idx = 0, int __base = 10)
6572 { return __gnu_cxx::__stoa(&std::strtoll, "stoll", __str.c_str(),
6573 __idx, __base); }
6574
6575 inline unsigned long long
6576 stoull(const string& __str, size_t* __idx = 0, int __base = 10)
6577 { return __gnu_cxx::__stoa(&std::strtoull, "stoull", __str.c_str(),
6578 __idx, __base); }
6579
6580 // NB: strtof vs strtod.
6581 inline float
6582 stof(const string& __str, size_t* __idx = 0)
6583 { return __gnu_cxx::__stoa(&std::strtof, "stof", __str.c_str(), __idx); }
6584
6585 inline double
6586 stod(const string& __str, size_t* __idx = 0)
6587 { return __gnu_cxx::__stoa(&std::strtod, "stod", __str.c_str(), __idx); }
6588
6589 inline long double
6590 stold(const string& __str, size_t* __idx = 0)
6591 { return __gnu_cxx::__stoa(&std::strtold, "stold", __str.c_str(), __idx); }
6592#endif // _GLIBCXX_USE_C99_STDLIB
6593
6594 // DR 1261. Insufficent overloads for to_string / to_wstring
6595
6596 inline string
6597 to_string(int __val)
6598 {
6599 const bool __neg = __val < 0;
6600 const unsigned __uval = __neg ? (unsigned)~__val + 1u : __val;
6601 const auto __len = __detail::__to_chars_len(__uval);
6602 string __str(__neg + __len, '-');
6603 __detail::__to_chars_10_impl(&__str[__neg], __len, __uval);
6604 return __str;
6605 }
6606
6607 inline string
6608 to_string(unsigned __val)
6609 {
6610 string __str(__detail::__to_chars_len(__val), '\0');
6611 __detail::__to_chars_10_impl(&__str[0], __str.size(), __val);
6612 return __str;
6613 }
6614
6615 inline string
6616 to_string(long __val)
6617 {
6618 const bool __neg = __val < 0;
6619 const unsigned long __uval = __neg ? (unsigned long)~__val + 1ul : __val;
6620 const auto __len = __detail::__to_chars_len(__uval);
6621 string __str(__neg + __len, '-');
6622 __detail::__to_chars_10_impl(&__str[__neg], __len, __uval);
6623 return __str;
6624 }
6625
6626 inline string
6627 to_string(unsigned long __val)
6628 {
6629 string __str(__detail::__to_chars_len(__val), '\0');
6630 __detail::__to_chars_10_impl(&__str[0], __str.size(), __val);
6631 return __str;
6632 }
6633
6634 inline string
6635 to_string(long long __val)
6636 {
6637 const bool __neg = __val < 0;
6638 const unsigned long long __uval
6639 = __neg ? (unsigned long long)~__val + 1ull : __val;
6640 const auto __len = __detail::__to_chars_len(__uval);
6641 string __str(__neg + __len, '-');
6642 __detail::__to_chars_10_impl(&__str[__neg], __len, __uval);
6643 return __str;
6644 }
6645
6646 inline string
6647 to_string(unsigned long long __val)
6648 {
6649 string __str(__detail::__to_chars_len(__val), '\0');
6650 __detail::__to_chars_10_impl(&__str[0], __str.size(), __val);
6651 return __str;
6652 }
6653
6654#if _GLIBCXX_USE_C99_STDIO1
6655 // NB: (v)snprintf vs sprintf.
6656
6657 inline string
6658 to_string(float __val)
6659 {
6660 const int __n =
6661 __gnu_cxx::__numeric_traits<float>::__max_exponent10 + 20;
6662 return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, __n,
6663 "%f", __val);
6664 }
6665
6666 inline string
6667 to_string(double __val)
6668 {
6669 const int __n =
6670 __gnu_cxx::__numeric_traits<double>::__max_exponent10 + 20;
6671 return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, __n,
6672 "%f", __val);
6673 }
6674
6675 inline string
6676 to_string(long double __val)
6677 {
6678 const int __n =
6679 __gnu_cxx::__numeric_traits<long double>::__max_exponent10 + 20;
6680 return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, __n,
6681 "%Lf", __val);
6682 }
6683#endif // _GLIBCXX_USE_C99_STDIO
6684
6685#if defined(_GLIBCXX_USE_WCHAR_T1) && _GLIBCXX_USE_C99_WCHAR1
6686 inline int
6687 stoi(const wstring& __str, size_t* __idx = 0, int __base = 10)
6688 { return __gnu_cxx::__stoa<long, int>(&std::wcstol, "stoi", __str.c_str(),
6689 __idx, __base); }
6690
6691 inline long
6692 stol(const wstring& __str, size_t* __idx = 0, int __base = 10)
6693 { return __gnu_cxx::__stoa(&std::wcstol, "stol", __str.c_str(),
6694 __idx, __base); }
6695
6696 inline unsigned long
6697 stoul(const wstring& __str, size_t* __idx = 0, int __base = 10)
6698 { return __gnu_cxx::__stoa(&std::wcstoul, "stoul", __str.c_str(),
6699 __idx, __base); }
6700
6701 inline long long
6702 stoll(const wstring& __str, size_t* __idx = 0, int __base = 10)
6703 { return __gnu_cxx::__stoa(&std::wcstoll, "stoll", __str.c_str(),
6704 __idx, __base); }
6705
6706 inline unsigned long long
6707 stoull(const wstring& __str, size_t* __idx = 0, int __base = 10)
6708 { return __gnu_cxx::__stoa(&std::wcstoull, "stoull", __str.c_str(),
6709 __idx, __base); }
6710
6711 // NB: wcstof vs wcstod.
6712 inline float
6713 stof(const wstring& __str, size_t* __idx = 0)
6714 { return __gnu_cxx::__stoa(&std::wcstof, "stof", __str.c_str(), __idx); }
6715
6716 inline double
6717 stod(const wstring& __str, size_t* __idx = 0)
6718 { return __gnu_cxx::__stoa(&std::wcstod, "stod", __str.c_str(), __idx); }
6719
6720 inline long double
6721 stold(const wstring& __str, size_t* __idx = 0)
6722 { return __gnu_cxx::__stoa(&std::wcstold, "stold", __str.c_str(), __idx); }
6723
6724#ifndef _GLIBCXX_HAVE_BROKEN_VSWPRINTF
6725 // DR 1261.
6726 inline wstring
6727 to_wstring(int __val)
6728 { return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf, 4 * sizeof(int),
6729 L"%d", __val); }
6730
6731 inline wstring
6732 to_wstring(unsigned __val)
6733 { return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf,
6734 4 * sizeof(unsigned),
6735 L"%u", __val); }
6736
6737 inline wstring
6738 to_wstring(long __val)
6739 { return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf, 4 * sizeof(long),
6740 L"%ld", __val); }
6741
6742 inline wstring
6743 to_wstring(unsigned long __val)
6744 { return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf,
6745 4 * sizeof(unsigned long),
6746 L"%lu", __val); }
6747
6748 inline wstring
6749 to_wstring(long long __val)
6750 { return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf,
6751 4 * sizeof(long long),
6752 L"%lld", __val); }
6753
6754 inline wstring
6755 to_wstring(unsigned long long __val)
6756 { return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf,
6757 4 * sizeof(unsigned long long),
6758 L"%llu", __val); }
6759
6760 inline wstring
6761 to_wstring(float __val)
6762 {
6763 const int __n =
6764 __gnu_cxx::__numeric_traits<float>::__max_exponent10 + 20;
6765 return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf, __n,
6766 L"%f", __val);
6767 }
6768
6769 inline wstring
6770 to_wstring(double __val)
6771 {
6772 const int __n =
6773 __gnu_cxx::__numeric_traits<double>::__max_exponent10 + 20;
6774 return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf, __n,
6775 L"%f", __val);
6776 }
6777
6778 inline wstring
6779 to_wstring(long double __val)
6780 {
6781 const int __n =
6782 __gnu_cxx::__numeric_traits<long double>::__max_exponent10 + 20;
6783 return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf, __n,
6784 L"%Lf", __val);
6785 }
6786#endif // _GLIBCXX_HAVE_BROKEN_VSWPRINTF
6787#endif // _GLIBCXX_USE_WCHAR_T && _GLIBCXX_USE_C99_WCHAR
6788
6789_GLIBCXX_END_NAMESPACE_CXX11}
6790_GLIBCXX_END_NAMESPACE_VERSION
6791} // namespace
6792
6793#endif /* C++11 */
6794
6795#if __cplusplus201703L >= 201103L
6796
6797#include <bits/functional_hash.h>
6798
6799namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
6800{
6801_GLIBCXX_BEGIN_NAMESPACE_VERSION
6802
6803 // DR 1182.
6804
6805#ifndef _GLIBCXX_COMPATIBILITY_CXX0X
6806 /// std::hash specialization for string.
6807 template<>
6808 struct hash<string>
6809 : public __hash_base<size_t, string>
6810 {
6811 size_t
6812 operator()(const string& __s) const noexcept
6813 { return std::_Hash_impl::hash(__s.data(), __s.length()); }
6814 };
6815
6816 template<>
6817 struct __is_fast_hash<hash<string>> : std::false_type
6818 { };
6819
6820#ifdef _GLIBCXX_USE_WCHAR_T1
6821 /// std::hash specialization for wstring.
6822 template<>
6823 struct hash<wstring>
6824 : public __hash_base<size_t, wstring>
6825 {
6826 size_t
6827 operator()(const wstring& __s) const noexcept
6828 { return std::_Hash_impl::hash(__s.data(),
6829 __s.length() * sizeof(wchar_t)); }
6830 };
6831
6832 template<>
6833 struct __is_fast_hash<hash<wstring>> : std::false_type
6834 { };
6835#endif
6836#endif /* _GLIBCXX_COMPATIBILITY_CXX0X */
6837
6838#ifdef _GLIBCXX_USE_CHAR8_T
6839 /// std::hash specialization for u8string.
6840 template<>
6841 struct hash<u8string>
6842 : public __hash_base<size_t, u8string>
6843 {
6844 size_t
6845 operator()(const u8string& __s) const noexcept
6846 { return std::_Hash_impl::hash(__s.data(),
6847 __s.length() * sizeof(char8_t)); }
6848 };
6849
6850 template<>
6851 struct __is_fast_hash<hash<u8string>> : std::false_type
6852 { };
6853#endif
6854
6855 /// std::hash specialization for u16string.
6856 template<>
6857 struct hash<u16string>
6858 : public __hash_base<size_t, u16string>
6859 {
6860 size_t
6861 operator()(const u16string& __s) const noexcept
6862 { return std::_Hash_impl::hash(__s.data(),
6863 __s.length() * sizeof(char16_t)); }
6864 };
6865
6866 template<>
6867 struct __is_fast_hash<hash<u16string>> : std::false_type
6868 { };
6869
6870 /// std::hash specialization for u32string.
6871 template<>
6872 struct hash<u32string>
6873 : public __hash_base<size_t, u32string>
6874 {
6875 size_t
6876 operator()(const u32string& __s) const noexcept
6877 { return std::_Hash_impl::hash(__s.data(),
6878 __s.length() * sizeof(char32_t)); }
6879 };
6880
6881 template<>
6882 struct __is_fast_hash<hash<u32string>> : std::false_type
6883 { };
6884
6885#if __cplusplus201703L >= 201402L
6886
6887#define __cpp_lib_string_udls201304 201304
6888
6889 inline namespace literals
6890 {
6891 inline namespace string_literals
6892 {
6893#pragma GCC diagnostic push
6894#pragma GCC diagnostic ignored "-Wliteral-suffix"
6895 _GLIBCXX_DEFAULT_ABI_TAG__attribute ((__abi_tag__ ("cxx11")))
6896 inline basic_string<char>
6897 operator""s(const char* __str, size_t __len)
6898 { return basic_string<char>{__str, __len}; }
6899
6900#ifdef _GLIBCXX_USE_WCHAR_T1
6901 _GLIBCXX_DEFAULT_ABI_TAG__attribute ((__abi_tag__ ("cxx11")))
6902 inline basic_string<wchar_t>
6903 operator""s(const wchar_t* __str, size_t __len)
6904 { return basic_string<wchar_t>{__str, __len}; }
6905#endif
6906
6907#ifdef _GLIBCXX_USE_CHAR8_T
6908 _GLIBCXX_DEFAULT_ABI_TAG__attribute ((__abi_tag__ ("cxx11")))
6909 inline basic_string<char8_t>
6910 operator""s(const char8_t* __str, size_t __len)
6911 { return basic_string<char8_t>{__str, __len}; }
6912#endif
6913
6914 _GLIBCXX_DEFAULT_ABI_TAG__attribute ((__abi_tag__ ("cxx11")))
6915 inline basic_string<char16_t>
6916 operator""s(const char16_t* __str, size_t __len)
6917 { return basic_string<char16_t>{__str, __len}; }
6918
6919 _GLIBCXX_DEFAULT_ABI_TAG__attribute ((__abi_tag__ ("cxx11")))
6920 inline basic_string<char32_t>
6921 operator""s(const char32_t* __str, size_t __len)
6922 { return basic_string<char32_t>{__str, __len}; }
6923
6924#pragma GCC diagnostic pop
6925 } // inline namespace string_literals
6926 } // inline namespace literals
6927
6928#if __cplusplus201703L >= 201703L
6929 namespace __detail::__variant
6930 {
6931 template<typename> struct _Never_valueless_alt; // see <variant>
6932
6933 // Provide the strong exception-safety guarantee when emplacing a
6934 // basic_string into a variant, but only if moving the string cannot throw.
6935 template<typename _Tp, typename _Traits, typename _Alloc>
6936 struct _Never_valueless_alt<std::basic_string<_Tp, _Traits, _Alloc>>
6937 : __and_<
6938 is_nothrow_move_constructible<std::basic_string<_Tp, _Traits, _Alloc>>,
6939 is_nothrow_move_assignable<std::basic_string<_Tp, _Traits, _Alloc>>
6940 >::type
6941 { };
6942 } // namespace __detail::__variant
6943#endif // C++17
6944#endif // C++14
6945
6946_GLIBCXX_END_NAMESPACE_VERSION
6947} // namespace std
6948
6949#endif // C++11
6950
6951#endif /* _BASIC_STRING_H */