libstdc++: cow_string.h Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32#ifndef _COW_STRING_H

33#define _COW_STRING_H 1

34

35#if ! _GLIBCXX_USE_CXX11_ABI

36

37#include <ext/atomicity.h>

38

39namespace std _GLIBCXX_VISIBILITY(default)

40{

41_GLIBCXX_BEGIN_NAMESPACE_VERSION

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107 template<typename _CharT, typename _Traits, typename _Alloc>

109 {

111 rebind<_CharT>::other _CharT_alloc_type;

113

114

115 public:

116 typedef _Traits traits_type;

117 typedef typename _Traits::char_type value_type;

118 typedef _Alloc allocator_type;

119 typedef typename _CharT_alloc_traits::size_type size_type;

120 typedef typename _CharT_alloc_traits::difference_type difference_type;

121#if __cplusplus < 201103L

122 typedef typename _CharT_alloc_type::reference reference;

123 typedef typename _CharT_alloc_type::const_reference const_reference;

124#else

125 typedef value_type& reference;

126 typedef const value_type& const_reference;

127#endif

128 typedef typename _CharT_alloc_traits::pointer pointer;

129 typedef typename _CharT_alloc_traits::const_pointer const_pointer;

130 typedef __gnu_cxx::__normal_iterator<pointer, basic_string> iterator;

131 typedef __gnu_cxx::__normal_iterator<const_pointer, basic_string>

132 const_iterator;

135

136 protected:

137

138 typedef iterator __const_iterator;

139

140 private:

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155 struct _Rep_base

156 {

157 size_type _M_length;

158 size_type _M_capacity;

159 _Atomic_word _M_refcount;

160 };

161

162 struct _Rep : _Rep_base

163 {

164

166 rebind::other _Raw_bytes_alloc;

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181 static const size_type _S_max_size;

182 static const _CharT _S_terminal;

183

184

185

186 static size_type _S_empty_rep_storage[];

187

188 static _Rep&

189 _S_empty_rep() _GLIBCXX_NOEXCEPT

190 {

191

192

193

194 void* __p = reinterpret_cast<void*>(&_S_empty_rep_storage);

195 return *reinterpret_cast<_Rep*>(__p);

196 }

197

198 bool

199 _M_is_leaked() const _GLIBCXX_NOEXCEPT

200 {

201#if defined(__GTHREADS)

202

203

204

205

206 return __atomic_load_n(&this->_M_refcount, __ATOMIC_RELAXED) < 0;

207#else

208 return this->_M_refcount < 0;

209#endif

210 }

211

212 bool

213 _M_is_shared() const _GLIBCXX_NOEXCEPT

214 {

215#if defined(__GTHREADS)

216

217

218

219

220

221 if (!__gnu_cxx::__is_single_threaded())

222 return __atomic_load_n(&this->_M_refcount, __ATOMIC_ACQUIRE) > 0;

223#endif

224 return this->_M_refcount > 0;

225 }

226

227 void

228 _M_set_leaked() _GLIBCXX_NOEXCEPT

229 { this->_M_refcount = -1; }

230

231 void

232 _M_set_sharable() _GLIBCXX_NOEXCEPT

233 { this->_M_refcount = 0; }

234

235 void

236 _M_set_length_and_sharable(size_type __n) _GLIBCXX_NOEXCEPT

237 {

238#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0

239 if (__builtin_expect(this != &_S_empty_rep(), false))

240#endif

241 {

242 this->_M_set_sharable();

243 this->_M_length = __n;

244 traits_type::assign(this->_M_refdata()[__n], _S_terminal);

245

246

247 }

248 }

249

250 _CharT*

251 _M_refdata() throw()

252 { return reinterpret_cast<_CharT*>(this + 1); }

253

254 _CharT*

255 _M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2)

256 {

257 return (!_M_is_leaked() && __alloc1 == __alloc2)

258 ? _M_refcopy() : _M_clone(__alloc1);

259 }

260

261

262 static _Rep*

263 _S_create(size_type, size_type, const _Alloc&);

264

265 void

266 _M_dispose(const _Alloc& __a) _GLIBCXX_NOEXCEPT

267 {

268#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0

269 if (__builtin_expect(this != &_S_empty_rep(), false))

270#endif

271 {

272

273 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&this->_M_refcount);

274

275

276

277

278

279

280

281

282 if (__gnu_cxx::__exchange_and_add_dispatch(&this->_M_refcount,

283 -1) <= 0)

284 {

285 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&this->_M_refcount);

286 _M_destroy(__a);

287 }

288 }

289 }

290

291 void

292 _M_destroy(const _Alloc&) throw();

293

294 _CharT*

295 _M_refcopy() throw()

296 {

297#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0

298 if (__builtin_expect(this != &_S_empty_rep(), false))

299#endif

300 __gnu_cxx::__atomic_add_dispatch(&this->_M_refcount, 1);

301 return _M_refdata();

302 }

303

304 _CharT*

305 _M_clone(const _Alloc&, size_type __res = 0);

306 };

307

308

309 struct _Alloc_hider : _Alloc

310 {

311 _Alloc_hider(_CharT* __dat, const _Alloc& __a) _GLIBCXX_NOEXCEPT

312 : _Alloc(__a), _M_p(__dat) { }

313

314 _CharT* _M_p;

315 };

316

317 public:

318

319

320

321

322 static const size_type npos = static_cast<size_type>(-1);

323

324 private:

325

326 mutable _Alloc_hider _M_dataplus;

327

328 _CharT*

329 _M_data() const _GLIBCXX_NOEXCEPT

330 { return _M_dataplus._M_p; }

331

332 _CharT*

333 _M_data(_CharT* __p) _GLIBCXX_NOEXCEPT

334 { return (_M_dataplus._M_p = __p); }

335

336 _Rep*

337 _M_rep() const _GLIBCXX_NOEXCEPT

338 { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); }

339

340

341

342 iterator

343 _M_ibegin() const _GLIBCXX_NOEXCEPT

344 { return iterator(_M_data()); }

345

346 iterator

347 _M_iend() const _GLIBCXX_NOEXCEPT

348 { return iterator(_M_data() + this->size()); }

349

350 void

351 _M_leak()

352 {

353 if (!_M_rep()->_M_is_leaked())

354 _M_leak_hard();

355 }

356

357 size_type

358 _M_check(size_type __pos, const char* __s) const

359 {

360 if (__pos > this->size())

361 __throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > "

362 "this->size() (which is %zu)"),

363 __s, __pos, this->size());

364 return __pos;

365 }

366

367 void

368 _M_check_length(size_type __n1, size_type __n2, const char* __s) const

369 {

370 if (this->max_size() - (this->size() - __n1) < __n2)

371 __throw_length_error(__N(__s));

372 }

373

374

375 size_type

376 _M_limit(size_type __pos, size_type __off) const _GLIBCXX_NOEXCEPT

377 {

378 const bool __testoff = __off < this->size() - __pos;

379 return __testoff ? __off : this->size() - __pos;

380 }

381

382

383 bool

384 _M_disjunct(const _CharT* __s) const _GLIBCXX_NOEXCEPT

385 {

386 return (less<const _CharT*>()(__s, _M_data())

387 || less<const _CharT*>()(_M_data() + this->size(), __s));

388 }

389

390

391

392 static void

393 _M_copy(_CharT* __d, const _CharT* __s, size_type __n) _GLIBCXX_NOEXCEPT

394 {

395 if (__n == 1)

396 traits_type::assign(*__d, *__s);

397 else

398 traits_type::copy(__d, __s, __n);

399 }

400

401 static void

402 _M_move(_CharT* __d, const _CharT* __s, size_type __n) _GLIBCXX_NOEXCEPT

403 {

404 if (__n == 1)

405 traits_type::assign(*__d, *__s);

406 else

407 traits_type::move(__d, __s, __n);

408 }

409

410 static void

411 _M_assign(_CharT* __d, size_type __n, _CharT __c) _GLIBCXX_NOEXCEPT

412 {

413 if (__n == 1)

414 traits_type::assign(*__d, __c);

415 else

416 traits_type::assign(__d, __n, __c);

417 }

418

419

420

421 template<class _Iterator>

422 static void

423 _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2)

424 {

425 for (; __k1 != __k2; ++__k1, (void)++__p)

426 traits_type::assign(*__p, *__k1);

427 }

428

429 static void

430 _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2) _GLIBCXX_NOEXCEPT

431 { _S_copy_chars(__p, __k1.base(), __k2.base()); }

432

433 static void

434 _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2)

435 _GLIBCXX_NOEXCEPT

436 { _S_copy_chars(__p, __k1.base(), __k2.base()); }

437

438 static void

439 _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) _GLIBCXX_NOEXCEPT

440 { _M_copy(__p, __k1, __k2 - __k1); }

441

442 static void

443 _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2)

444 _GLIBCXX_NOEXCEPT

445 { _M_copy(__p, __k1, __k2 - __k1); }

446

447 static int

448 _S_compare(size_type __n1, size_type __n2) _GLIBCXX_NOEXCEPT

449 {

450 const difference_type __d = difference_type(__n1 - __n2);

451

452 if (__d > __gnu_cxx::__numeric_traits::__max)

453 return __gnu_cxx::__numeric_traits::__max;

454 else if (__d < __gnu_cxx::__numeric_traits::__min)

455 return __gnu_cxx::__numeric_traits::__min;

456 else

457 return int(__d);

458 }

459

460 void

461 _M_mutate(size_type __pos, size_type __len1, size_type __len2);

462

463 void

464 _M_leak_hard();

465

466 static _Rep&

467 _S_empty_rep() _GLIBCXX_NOEXCEPT

468 { return _Rep::_S_empty_rep(); }

469

470#if __cplusplus >= 201703L

471

472 typedef basic_string_view<_CharT, _Traits> __sv_type;

473

474 template<typename _Tp, typename _Res>

476 __and_<is_convertible<const _Tp&, __sv_type>,

477 __not_<is_convertible<const _Tp*, const basic_string*>>,

478 __not_<is_convertible<const _Tp&, const _CharT*>>>::value,

479 _Res>;

480

481

482 static __sv_type

483 _S_to_string_view(__sv_type __svt) noexcept

484 { return __svt; }

485

486

487

488

489

490 struct __sv_wrapper

491 {

492 explicit __sv_wrapper(__sv_type __sv) noexcept : _M_sv(__sv) { }

493 __sv_type _M_sv;

494 };

495

496

497

498

499

500

501

502 explicit

503 basic_string(__sv_wrapper __svw, const _Alloc& __a)

505#endif

506

507 public:

508

509

510

511

512

513

514

516#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0

517 _GLIBCXX_NOEXCEPT

518#endif

519#if __cpp_concepts && __glibcxx_type_trait_variable_templates

520 requires is_default_constructible_v<_Alloc>

521#endif

522#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0

523 : _M_dataplus(_S_empty_rep()._M_refdata(), _Alloc())

524#else

525 : _M_dataplus(_S_construct(size_type(), _CharT(), _Alloc()), _Alloc())

526#endif

527 { }

528

529

530

531

532 explicit

534 : _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a)

535 { }

536

537

538

539

540

541

543 : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(__str.get_allocator()),

546 { }

547

548

549

550

551

552

553

554

555

557 const _Alloc& __a = _Alloc());

558

559

560

561

562

563

564

566 size_type __n);

567

568

569

570

571

572

573

575 size_type __n, const _Alloc& __a);

576

577

578

579

580

581

582

583

584

585

587 const _Alloc& __a = _Alloc())

588 : _M_dataplus(_S_construct(__s, __s + __n, __a), __a)

589 { }

590

591

592

593

594

595

596#if __cpp_deduction_guides && ! defined _GLIBCXX_DEFINING_STRING_INSTANTIATIONS

597

598

599 template<typename = _RequireAllocator<_Alloc>>

600#endif

601 basic_string(const _CharT* __s, const _Alloc& __a = _Alloc())

602 : _M_dataplus(_S_construct(__s, __s ? __s + traits_type::length(__s) :

603 __s + npos, __a), __a)

604 { }

605

606

607

608

609

610

611

612 basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc())

613 : _M_dataplus(_S_construct(__n, __c, __a), __a)

614 { }

615

616#if __cplusplus >= 201103L

617

618

619

620

621

622

623

625 : _M_dataplus(std::move(__str._M_dataplus))

626 {

627#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0

628

629 __str._M_data(_S_empty_rep()._M_refdata());

630#else

631

632

633

634

635 if (_M_rep()->_M_is_shared())

636 __gnu_cxx::__atomic_add_dispatch(&_M_rep()->_M_refcount, 1);

637 else

638 _M_rep()->_M_refcount = 1;

639#endif

640 }

641

642

643

644

645

646

648 : _M_dataplus(_S_construct(__l.begin(), __l.end(), __a), __a)

649 { }

650

652 : _M_dataplus(__str._M_rep()->_M_grab(__a, __str.get_allocator()), __a)

653 { }

654

656 : _M_dataplus(__str._M_data(), __a)

657 {

659 {

660#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0

661 __str._M_data(_S_empty_rep()._M_refdata());

662#else

663 __str._M_data(_S_construct(size_type(), _CharT(), __a));

664#endif

665 }

666 else

667 _M_dataplus._M_p = _S_construct(__str.begin(), __str.end(), __a);

668 }

669#endif

670

671#if __cplusplus >= 202100L

674#endif

675

676

677

678

679

680

681

682 template<class _InputIterator>

684 const _Alloc& __a = _Alloc())

685 : _M_dataplus(_S_construct(__beg, __end, __a), __a)

686 { }

687

688#if __cplusplus >= 201703L

689

690

691

692

693

694

695

696 template<typename _Tp,

698 basic_string(const _Tp& __t, size_type __pos, size_type __n,

699 const _Alloc& __a = _Alloc())

701

702

703

704

705

706

707 template<typename _Tp, typename = _If_sv<_Tp, void>>

708 explicit

709 basic_string(const _Tp& __t, const _Alloc& __a = _Alloc())

710 : basic_string(__sv_wrapper(_S_to_string_view(__t)), __a) { }

711#endif

712

713

714

715

718

719

720

721

722

725 { return this->assign(__str); }

726

727

728

729

730

733 { return this->assign(__s); }

734

735

736

737

738

739

740

741

744 {

745 this->assign(1, __c);

746 return *this;

747 }

748

749#if __cplusplus >= 201103L

750

751

752

753

754

755

756

760 {

761

762 this->swap(__str);

763 return *this;

764 }

765

766

767

768

769

772 {

773 this->assign(__l.begin(), __l.size());

774 return *this;

775 }

776#endif

777

778#if __cplusplus >= 201703L

779

780

781

782

783 template<typename _Tp>

784 _If_sv<_Tp, basic_string&>

786 { return this->assign(__svt); }

787

788

789

790

791

794#endif

795

796

797

798

799

800

802 begin()

803 {

804 _M_leak();

805 return iterator(_M_data());

806 }

807

808

809

810

811

812 const_iterator

813 begin() const _GLIBCXX_NOEXCEPT

814 { return const_iterator(_M_data()); }

815

816

817

818

819

821 end()

822 {

823 _M_leak();

824 return iterator(_M_data() + this->size());

825 }

826

827

828

829

830

831 const_iterator

832 end() const _GLIBCXX_NOEXCEPT

833 { return const_iterator(_M_data() + this->size()); }

834

835

836

837

838

839

840 reverse_iterator

841 rbegin()

843

844

845

846

847

848

849 const_reverse_iterator

852

853

854

855

856

857

858 reverse_iterator

859 rend()

861

862

863

864

865

866

867 const_reverse_iterator

868 rend() const _GLIBCXX_NOEXCEPT

870

871#if __cplusplus >= 201103L

872

873

874

875

876 const_iterator

878 { return const_iterator(this->_M_data()); }

879

880

881

882

883

884 const_iterator

886 { return const_iterator(this->_M_data() + this->size()); }

887

888

889

890

891

892

893 const_reverse_iterator

896

897

898

899

900

901

902 const_reverse_iterator

905#endif

906

907 public:

908

909

910

911

912 size_type

913 size() const _GLIBCXX_NOEXCEPT

914 {

915#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 && __OPTIMIZE__

916 if (_S_empty_rep()._M_length != 0)

917 __builtin_unreachable();

918#endif

919 return _M_rep()->_M_length;

920 }

921

922

923

924 size_type

926 { return size(); }

927

928

929 size_type

931 { return _Rep::_S_max_size; }

932

933

934

935

936

937

938

939

940

941

942

943 void

944 resize(size_type __n, _CharT __c);

945

946

947

948

949

950

951

952

953

954

955

956 void

958 { this->resize(__n, _CharT()); }

959

960#if __cplusplus >= 201103L

961#pragma GCC diagnostic push

962#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

963

964 void

967#pragma GCC diagnostic pop

968#endif

969

970#ifdef __glibcxx_string_resize_and_overwrite

971

972

973

974

975

976

977

978

979

980

981

982

983

984

985

986

987

988

989

990

991

992

993

994

995

996

997

998

999

1000 template<typename _Operation>

1001 void

1002 resize_and_overwrite(size_type __n, _Operation __op);

1003#endif

1004

1005#if __cplusplus >= 201103L

1006

1007 template<typename _Operation>

1008 void

1010#endif

1011

1012

1013

1014

1015

1016 size_type

1018 { return _M_rep()->_M_capacity; }

1019

1020

1021

1022

1023

1024

1025

1026

1027

1028

1029

1030

1031

1032

1033

1034

1035

1036

1037 void

1039

1040

1041#if __cplusplus > 201703L

1042 [[deprecated("use shrink_to_fit() instead")]]

1043#endif

1044 void

1046

1047

1048

1049

1050#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0

1051 void

1053 {

1054 if (_M_rep()->_M_is_shared())

1055 {

1057 _M_data(_S_empty_rep()._M_refdata());

1058 }

1059 else

1060 _M_rep()->_M_set_length_and_sharable(0);

1061 }

1062#else

1063

1064 void

1066 { _M_mutate(0, this->size(), 0); }

1067#endif

1068

1069

1070

1071

1072

1073 _GLIBCXX_NODISCARD bool

1075 { return this->size() == 0; }

1076

1077

1078

1079

1080

1081

1082

1083

1084

1085

1086

1087

1088 const_reference

1089 operator[] (size_type __pos) const _GLIBCXX_NOEXCEPT

1090 {

1091 __glibcxx_assert(__pos <= size());

1092 return _M_data()[__pos];

1093 }

1094

1095

1096

1097

1098

1099

1100

1101

1102

1103

1104

1105 reference

1107 {

1108

1109

1110 __glibcxx_assert(__pos <= size());

1111

1112 _GLIBCXX_DEBUG_PEDASSERT(__cplusplus >= 201103L || __pos < size());

1113 _M_leak();

1114 return _M_data()[__pos];

1115 }

1116

1117

1118

1119

1120

1121

1122

1123

1124

1125

1126

1127 const_reference

1128 at(size_type __n) const

1129 {

1130 if (__n >= this->size())

1131 __throw_out_of_range_fmt(__N("basic_string::at: __n "

1132 "(which is %zu) >= this->size() "

1133 "(which is %zu)"),

1134 __n, this->size());

1135 return _M_data()[__n];

1136 }

1137

1138

1139

1140

1141

1142

1143

1144

1145

1146

1147

1148

1149 reference

1151 {

1152 if (__n >= size())

1153 __throw_out_of_range_fmt(__N("basic_string::at: __n "

1154 "(which is %zu) >= this->size() "

1155 "(which is %zu)"),

1156 __n, this->size());

1157 _M_leak();

1158 return _M_data()[__n];

1159 }

1160

1161#if __cplusplus >= 201103L

1162

1163

1164

1165

1166 reference

1168 {

1169 __glibcxx_assert(empty());

1171 }

1172

1173

1174

1175

1176

1177 const_reference

1179 {

1180 __glibcxx_assert(empty());

1182 }

1183

1184

1185

1186

1187

1188 reference

1190 {

1191 __glibcxx_assert(empty());

1193 }

1194

1195

1196

1197

1198

1199 const_reference

1201 {

1202 __glibcxx_assert(empty());

1204 }

1205#endif

1206

1207

1208

1209

1210

1211

1212

1215 { return this->append(__str); }

1216

1217

1218

1219

1220

1221

1224 { return this->append(__s); }

1225

1226

1227

1228

1229

1230

1233 {

1235 return *this;

1236 }

1237

1238#if __cplusplus >= 201103L

1239

1240

1241

1242

1243

1246 { return this->append(__l.begin(), __l.size()); }

1247#endif

1248

1249#if __cplusplus >= 201703L

1250

1251

1252

1253

1254

1255 template<typename _Tp>

1256 _If_sv<_Tp, basic_string&>

1258 { return this->append(__svt); }

1259#endif

1260

1261

1262

1263

1264

1265

1268

1269

1270

1271

1272

1273

1274

1275

1276

1277

1278

1279

1280

1281

1284

1285

1286

1287

1288

1289

1290

1292 append(const _CharT* __s, size_type __n);

1293

1294

1295

1296

1297

1298

1301 {

1302 __glibcxx_requires_string(__s);

1303 return this->append(__s, traits_type::length(__s));

1304 }

1305

1306

1307

1308

1309

1310

1311

1312

1313

1316

1317#if __cplusplus >= 201103L

1318

1319

1320

1321

1322

1325 { return this->append(__l.begin(), __l.size()); }

1326#endif

1327

1328

1329

1330

1331

1332

1333

1334

1335

1336 template<class _InputIterator>

1338 append(_InputIterator __first, _InputIterator __last)

1339 { return this->replace(_M_iend(), _M_iend(), __first, __last); }

1340

1341#if __cplusplus >= 201703L

1342

1343

1344

1345

1346

1347 template<typename _Tp>

1348 _If_sv<_Tp, basic_string&>

1350 {

1352 return this->append(__sv.data(), __sv.size());

1353 }

1354

1355

1356

1357

1358

1359

1360

1361

1362

1363 template<typename _Tp>

1364 _If_sv<_Tp, basic_string&>

1365 append(const _Tp& __svt, size_type __pos, size_type __n = npos)

1366 {

1368 return append(__sv.data()

1369 + std::__sv_check(__sv.size(), __pos, "basic_string::append"),

1370 std::__sv_limit(__sv.size(), __pos, __n));

1371 }

1372#endif

1373

1374

1375

1376

1377

1378 void

1380 {

1381 const size_type __len = 1 + this->size();

1382 if (__len > this->capacity() || _M_rep()->_M_is_shared())

1384 traits_type::assign(_M_data()[this->size()], __c);

1385 _M_rep()->_M_set_length_and_sharable(__len);

1386 }

1387

1388

1389

1390

1391

1392

1395

1396#if __cplusplus >= 201103L

1397

1398

1399

1400

1401

1402

1403

1404

1408 {

1409 this->swap(__str);

1410 return *this;

1411 }

1412#endif

1413

1414

1415

1416

1417

1418

1419

1420

1421

1422

1423

1424

1425

1426

1429 { return this->assign(__str._M_data()

1430 + __str._M_check(__pos, "basic_string::assign"),

1431 __str._M_limit(__pos, __n)); }

1432

1433

1434

1435

1436

1437

1438

1439

1440

1441

1442

1444 assign(const _CharT* __s, size_type __n);

1445

1446

1447

1448

1449

1450

1451

1452

1453

1454

1457 {

1458 __glibcxx_requires_string(__s);

1459 return this->assign(__s, traits_type::length(__s));

1460 }

1461

1462

1463

1464

1465

1466

1467

1468

1469

1470

1473 { return _M_replace_aux(size_type(0), this->size(), __n, __c); }

1474

1475

1476

1477

1478

1479

1480

1481

1482

1483 template<class _InputIterator>

1485 assign(_InputIterator __first, _InputIterator __last)

1486 { return this->replace(_M_ibegin(), _M_iend(), __first, __last); }

1487

1488#if __cplusplus >= 201103L

1489

1490

1491

1492

1493

1496 { return this->assign(__l.begin(), __l.size()); }

1497#endif

1498

1499#if __cplusplus >= 201703L

1500

1501

1502

1503

1504

1505 template<typename _Tp>

1506 _If_sv<_Tp, basic_string&>

1508 {

1510 return this->assign(__sv.data(), __sv.size());

1511 }

1512

1513

1514

1515

1516

1517

1518

1519

1520 template<typename _Tp>

1521 _If_sv<_Tp, basic_string&>

1522 assign(const _Tp& __svt, size_type __pos, size_type __n = npos)

1523 {

1525 return assign(__sv.data()

1526 + std::__sv_check(__sv.size(), __pos, "basic_string::assign"),

1527 std::__sv_limit(__sv.size(), __pos, __n));

1528 }

1529#endif

1530

1531

1532

1533

1534

1535

1536

1537

1538

1539

1540

1541

1542

1543

1544 void

1545 insert(iterator __p, size_type __n, _CharT __c)

1546 { this->replace(__p, __p, __n, __c); }

1547

1548

1549

1550

1551

1552

1553

1554

1555

1556

1557

1558

1559

1560 template<class _InputIterator>

1561 void

1562 insert(iterator __p, _InputIterator __beg, _InputIterator __end)

1563 { this->replace(__p, __p, __beg, __end); }

1564

1565#if __cplusplus >= 201103L

1566

1567

1568

1569

1570

1571

1572 void

1574 {

1575 _GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend());

1576 this->insert(__p - _M_ibegin(), __l.begin(), __l.size());

1577 }

1578#endif

1579

1580

1581

1582

1583

1584

1585

1586

1587

1588

1589

1590

1591

1594 { return this->insert(__pos1, __str, size_type(0), __str.size()); }

1595

1596

1597

1598

1599

1600

1601

1602

1603

1604

1605

1606

1607

1608

1609

1610

1611

1612

1613

1616 size_type __pos2, size_type __n = npos)

1617 { return this->insert(__pos1, __str._M_data()

1618 + __str._M_check(__pos2, "basic_string::insert"),

1619 __str._M_limit(__pos2, __n)); }

1620

1621

1622

1623

1624

1625

1626

1627

1628

1629

1630

1631

1632

1633

1634

1635

1636

1638 insert(size_type __pos, const _CharT* __s, size_type __n);

1639

1640

1641

1642

1643

1644

1645

1646

1647

1648

1649

1650

1651

1652

1653

1654

1656 insert(size_type __pos, const _CharT* __s)

1657 {

1658 __glibcxx_requires_string(__s);

1659 return this->insert(__pos, __s, traits_type::length(__s));

1660 }

1661

1662

1663

1664

1665

1666

1667

1668

1669

1670

1671

1672

1673

1674

1675

1676

1677

1679 insert(size_type __pos, size_type __n, _CharT __c)

1680 { return _M_replace_aux(_M_check(__pos, "basic_string::insert"),

1681 size_type(0), __n, __c); }

1682

1683

1684

1685

1686

1687

1688

1689

1690

1691

1692

1693

1694

1695

1698 {

1699 _GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend());

1700 const size_type __pos = __p - _M_ibegin();

1701 _M_replace_aux(__pos, size_type(0), size_type(1), __c);

1702 _M_rep()->_M_set_leaked();

1703 return iterator(_M_data() + __pos);

1704 }

1705

1706#if __cplusplus >= 201703L

1707

1708

1709

1710

1711

1712

1713 template<typename _Tp>

1714 _If_sv<_Tp, basic_string&>

1715 insert(size_type __pos, const _Tp& __svt)

1716 {

1718 return this->insert(__pos, __sv.data(), __sv.size());

1719 }

1720

1721

1722

1723

1724

1725

1726

1727

1728

1729 template<typename _Tp>

1730 _If_sv<_Tp, basic_string&>

1731 insert(size_type __pos1, const _Tp& __svt,

1732 size_type __pos2, size_type __n = npos)

1733 {

1735 return this->replace(__pos1, size_type(0), __sv.data()

1736 + std::__sv_check(__sv.size(), __pos2, "basic_string::insert"),

1737 std::__sv_limit(__sv.size(), __pos2, __n));

1738 }

1739#endif

1740

1741

1742

1743

1744

1745

1746

1747

1748

1749

1750

1751

1752

1753

1754

1755

1757 erase(size_type __pos = 0, size_type __n = npos)

1758 {

1759 _M_mutate(_M_check(__pos, "basic_string::erase"),

1760 _M_limit(__pos, __n), size_type(0));

1761 return *this;

1762 }

1763

1764

1765

1766

1767

1768

1769

1770

1771

1774 {

1775 _GLIBCXX_DEBUG_PEDASSERT(__position >= _M_ibegin()

1776 && __position < _M_iend());

1777 const size_type __pos = __position - _M_ibegin();

1778 _M_mutate(__pos, size_type(1), size_type(0));

1779 _M_rep()->_M_set_leaked();

1780 return iterator(_M_data() + __pos);

1781 }

1782

1783

1784

1785

1786

1787

1788

1789

1790

1791

1793 erase(iterator __first, iterator __last);

1794

1795#if __cplusplus >= 201103L

1796

1797

1798

1799

1800

1801 void

1802 pop_back()

1803 {

1804 __glibcxx_assert(empty());

1806 }

1807#endif

1808

1809

1810

1811

1812

1813

1814

1815

1816

1817

1818

1819

1820

1821

1822

1823

1824

1825

1828 { return this->replace(__pos, __n, __str._M_data(), __str.size()); }

1829

1830

1831

1832

1833

1834

1835

1836

1837

1838

1839

1840

1841

1842

1843

1844

1845

1846

1847

1850 size_type __pos2, size_type __n2 = npos)

1851 { return this->replace(__pos1, __n1, __str._M_data()

1852 + __str._M_check(__pos2, "basic_string::replace"),

1853 __str._M_limit(__pos2, __n2)); }

1854

1855

1856

1857

1858

1859

1860

1861

1862

1863

1864

1865

1866

1867

1868

1869

1870

1871

1872

1874 replace(size_type __pos, size_type __n1, const _CharT* __s,

1875 size_type __n2);

1876

1877

1878

1879

1880

1881

1882

1883

1884

1885

1886

1887

1888

1889

1890

1891

1892

1894 replace(size_type __pos, size_type __n1, const _CharT* __s)

1895 {

1896 __glibcxx_requires_string(__s);

1897 return this->replace(__pos, __n1, __s, traits_type::length(__s));

1898 }

1899

1900

1901

1902

1903

1904

1905

1906

1907

1908

1909

1910

1911

1912

1913

1914

1915

1916

1918 replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)

1919 { return _M_replace_aux(_M_check(__pos, "basic_string::replace"),

1920 _M_limit(__pos, __n1), __n2, __c); }

1921

1922

1923

1924

1925

1926

1927

1928

1929

1930

1931

1932

1933

1934

1937 { return this->replace(__i1, __i2, __str._M_data(), __str.size()); }

1938

1939

1940

1941

1942

1943

1944

1945

1946

1947

1948

1949

1950

1951

1952

1953

1955 replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n)

1956 {

1957 _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2

1958 && __i2 <= _M_iend());

1959 return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n);

1960 }

1961

1962

1963

1964

1965

1966

1967

1968

1969

1970

1971

1972

1973

1974

1976 replace(iterator __i1, iterator __i2, const _CharT* __s)

1977 {

1978 __glibcxx_requires_string(__s);

1979 return this->replace(__i1, __i2, __s, traits_type::length(__s));

1980 }

1981

1982

1983

1984

1985

1986

1987

1988

1989

1990

1991

1992

1993

1994

1995

1997 replace(iterator __i1, iterator __i2, size_type __n, _CharT __c)

1998 {

1999 _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2

2000 && __i2 <= _M_iend());

2001 return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __c);

2002 }

2003

2004

2005

2006

2007

2008

2009

2010

2011

2012

2013

2014

2015

2016

2017

2018

2019 template<class _InputIterator>

2022 _InputIterator __k1, _InputIterator __k2)

2023 {

2024 _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2

2025 && __i2 <= _M_iend());

2026 __glibcxx_requires_valid_range(__k1, __k2);

2027 typedef typename std::__is_integer<_InputIterator>::__type _Integral;

2028 return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral());

2029 }

2030

2031

2032

2035 {

2036 _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2

2037 && __i2 <= _M_iend());

2038 __glibcxx_requires_valid_range(__k1, __k2);

2039 return this->replace(__i1 - _M_ibegin(), __i2 - __i1,

2040 __k1, __k2 - __k1);

2041 }

2042

2044 replace(iterator __i1, iterator __i2,

2045 const _CharT* __k1, const _CharT* __k2)

2046 {

2047 _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2

2048 && __i2 <= _M_iend());

2049 __glibcxx_requires_valid_range(__k1, __k2);

2050 return this->replace(__i1 - _M_ibegin(), __i2 - __i1,

2051 __k1, __k2 - __k1);

2052 }

2053

2055 replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2)

2056 {

2057 _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2

2058 && __i2 <= _M_iend());

2059 __glibcxx_requires_valid_range(__k1, __k2);

2060 return this->replace(__i1 - _M_ibegin(), __i2 - __i1,

2061 __k1.base(), __k2 - __k1);

2062 }

2063

2065 replace(iterator __i1, iterator __i2,

2066 const_iterator __k1, const_iterator __k2)

2067 {

2068 _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2

2069 && __i2 <= _M_iend());

2070 __glibcxx_requires_valid_range(__k1, __k2);

2071 return this->replace(__i1 - _M_ibegin(), __i2 - __i1,

2072 __k1.base(), __k2 - __k1);

2073 }

2074

2075#if __cplusplus >= 201103L

2076

2077

2078

2079

2080

2081

2082

2083

2084

2085

2086

2087

2088

2089

2092 { return this->replace(__i1, __i2, __l.begin(), __l.end()); }

2093#endif

2094

2095#if __cplusplus >= 201703L

2096

2097

2098

2099

2100

2101

2102

2103 template<typename _Tp>

2104 _If_sv<_Tp, basic_string&>

2105 replace(size_type __pos, size_type __n, const _Tp& __svt)

2106 {

2108 return this->replace(__pos, __n, __sv.data(), __sv.size());

2109 }

2110

2111

2112

2113

2114

2115

2116

2117

2118

2119

2120 template<typename _Tp>

2121 _If_sv<_Tp, basic_string&>

2122 replace(size_type __pos1, size_type __n1, const _Tp& __svt,

2123 size_type __pos2, size_type __n2 = npos)

2124 {

2126 return this->replace(__pos1, __n1,

2127 __sv.data()

2128 + std::__sv_check(__sv.size(), __pos2, "basic_string::replace"),

2129 std::__sv_limit(__sv.size(), __pos2, __n2));

2130 }

2131

2132

2133

2134

2135

2136

2137

2138

2139

2140

2141 template<typename _Tp>

2142 _If_sv<_Tp, basic_string&>

2143 replace(const_iterator __i1, const_iterator __i2, const _Tp& __svt)

2144 {

2146 return this->replace(__i1 - begin(), __i2 - __i1, __sv);

2147 }

2148#endif

2149

2150 private:

2151 template<class _Integer>

2153 _M_replace_dispatch(iterator __i1, iterator __i2, _Integer __n,

2154 _Integer __val, __true_type)

2155 { return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __val); }

2156

2157 template<class _InputIterator>

2159 _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1,

2160 _InputIterator __k2, __false_type);

2161

2163 _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,

2164 _CharT __c);

2165

2167 _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s,

2168 size_type __n2);

2169

2170

2171

2172 template<class _InIterator>

2173 static _CharT*

2174 _S_construct_aux(_InIterator __beg, _InIterator __end,

2175 const _Alloc& __a, __false_type)

2176 {

2177 typedef typename iterator_traits<_InIterator>::iterator_category _Tag;

2178 return _S_construct(__beg, __end, __a, _Tag());

2179 }

2180

2181

2182

2183 template<class _Integer>

2184 static _CharT*

2185 _S_construct_aux(_Integer __beg, _Integer __end,

2186 const _Alloc& __a, __true_type)

2187 { return _S_construct_aux_2(static_cast<size_type>(__beg),

2188 __end, __a); }

2189

2190 static _CharT*

2191 _S_construct_aux_2(size_type __req, _CharT __c, const _Alloc& __a)

2192 { return _S_construct(__req, __c, __a); }

2193

2194 template<class _InIterator>

2195 static _CharT*

2196 _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a)

2197 {

2198 typedef typename std::__is_integer<_InIterator>::__type _Integral;

2199 return _S_construct_aux(__beg, __end, __a, _Integral());

2200 }

2201

2202

2203 template<class _InIterator>

2204 static _CharT*

2205 _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,

2206 input_iterator_tag);

2207

2208

2209

2210 template<class _FwdIterator>

2211 static _CharT*

2212 _S_construct(_FwdIterator __beg, _FwdIterator __end, const _Alloc& __a,

2213 forward_iterator_tag);

2214

2215 static _CharT*

2216 _S_construct(size_type __req, _CharT __c, const _Alloc& __a);

2217

2218 public:

2219

2220

2221

2222

2223

2224

2225

2226

2227

2228

2229

2230

2231

2232 size_type

2233 copy(_CharT* __s, size_type __n, size_type __pos = 0) const;

2234

2235

2236

2237

2238

2239

2240

2241

2242 void

2245

2246

2247

2248

2249

2250

2251

2252

2253 const _CharT*

2255 { return _M_data(); }

2256

2257

2258

2259

2260

2261

2262

2263

2264

2265 const _CharT*

2266 data() const _GLIBCXX_NOEXCEPT

2267 { return _M_data(); }

2268

2269#if __cplusplus >= 201703L

2270

2271

2272

2273

2274

2275

2276

2277

2278

2279

2280

2281 _CharT*

2283 {

2284 _M_leak();

2285 return _M_data();

2286 }

2287#endif

2288

2289

2290

2291

2292 allocator_type

2294 { return _M_dataplus; }

2295

2296

2297

2298

2299

2300

2301

2302

2303

2304

2305

2306

2307

2308 size_type

2309 find(const _CharT* __s, size_type __pos, size_type __n) const

2310 _GLIBCXX_NOEXCEPT;

2311

2312

2313

2314

2315

2316

2317

2318

2319

2320

2321

2322 size_type

2324 _GLIBCXX_NOEXCEPT

2325 { return this->find(__str.data(), __pos, __str.size()); }

2326

2327

2328

2329

2330

2331

2332

2333

2334

2335

2336

2337 size_type

2338 find(const _CharT* __s, size_type __pos = 0) const _GLIBCXX_NOEXCEPT

2339 {

2340 __glibcxx_requires_string(__s);

2341 return this->find(__s, __pos, traits_type::length(__s));

2342 }

2343

2344

2345

2346

2347

2348

2349

2350

2351

2352

2353

2354 size_type

2355 find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT;

2356

2357#if __cplusplus >= 201703L

2358

2359

2360

2361

2362

2363

2364 template<typename _Tp>

2365 _If_sv<_Tp, size_type>

2366 find(const _Tp& __svt, size_type __pos = 0) const

2368 {

2370 return this->find(__sv.data(), __pos, __sv.size());

2371 }

2372#endif

2373

2374

2375

2376

2377

2378

2379

2380

2381

2382

2383

2384 size_type

2386 _GLIBCXX_NOEXCEPT

2387 { return this->rfind(__str.data(), __pos, __str.size()); }

2388

2389

2390

2391

2392

2393

2394

2395

2396

2397

2398

2399

2400

2401 size_type

2402 rfind(const _CharT* __s, size_type __pos, size_type __n) const

2403 _GLIBCXX_NOEXCEPT;

2404

2405

2406

2407

2408

2409

2410

2411

2412

2413

2414

2415 size_type

2416 rfind(const _CharT* __s, size_type __pos = npos) const _GLIBCXX_NOEXCEPT

2417 {

2418 __glibcxx_requires_string(__s);

2419 return this->rfind(__s, __pos, traits_type::length(__s));

2420 }

2421

2422

2423

2424

2425

2426

2427

2428

2429

2430

2431

2432 size_type

2433 rfind(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT;

2434

2435#if __cplusplus >= 201703L

2436

2437

2438

2439

2440

2441

2442 template<typename _Tp>

2443 _If_sv<_Tp, size_type>

2444 rfind(const _Tp& __svt, size_type __pos = npos) const

2446 {

2448 return this->rfind(__sv.data(), __pos, __sv.size());

2449 }

2450#endif

2451

2452

2453

2454

2455

2456

2457

2458

2459

2460

2461

2462

2463 size_type

2465 _GLIBCXX_NOEXCEPT

2467

2468

2469

2470

2471

2472

2473

2474

2475

2476

2477

2478

2479

2480 size_type

2481 find_first_of(const _CharT* __s, size_type __pos, size_type __n) const

2482 _GLIBCXX_NOEXCEPT;

2483

2484

2485

2486

2487

2488

2489

2490

2491

2492

2493

2494 size_type

2496 _GLIBCXX_NOEXCEPT

2497 {

2498 __glibcxx_requires_string(__s);

2499 return this->find_first_of(__s, __pos, traits_type::length(__s));

2500 }

2501

2502

2503

2504

2505

2506

2507

2508

2509

2510

2511

2512

2513

2514 size_type

2515 find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT

2516 { return this->find(__c, __pos); }

2517

2518#if __cplusplus >= 201703L

2519

2520

2521

2522

2523

2524

2525

2526 template<typename _Tp>

2527 _If_sv<_Tp, size_type>

2530 {

2532 return this->find_first_of(__sv.data(), __pos, __sv.size());

2533 }

2534#endif

2535

2536

2537

2538

2539

2540

2541

2542

2543

2544

2545

2546

2547 size_type

2549 _GLIBCXX_NOEXCEPT

2551

2552

2553

2554

2555

2556

2557

2558

2559

2560

2561

2562

2563

2564 size_type

2565 find_last_of(const _CharT* __s, size_type __pos, size_type __n) const

2566 _GLIBCXX_NOEXCEPT;

2567

2568

2569

2570

2571

2572

2573

2574

2575

2576

2577

2578 size_type

2580 _GLIBCXX_NOEXCEPT

2581 {

2582 __glibcxx_requires_string(__s);

2583 return this->find_last_of(__s, __pos, traits_type::length(__s));

2584 }

2585

2586

2587

2588

2589

2590

2591

2592

2593

2594

2595

2596

2597

2598 size_type

2600 { return this->rfind(__c, __pos); }

2601

2602#if __cplusplus >= 201703L

2603

2604

2605

2606

2607

2608

2609

2610 template<typename _Tp>

2611 _If_sv<_Tp, size_type>

2614 {

2616 return this->find_last_of(__sv.data(), __pos, __sv.size());

2617 }

2618#endif

2619

2620

2621

2622

2623

2624

2625

2626

2627

2628

2629

2630 size_type

2632 _GLIBCXX_NOEXCEPT

2634

2635

2636

2637

2638

2639

2640

2641

2642

2643

2644

2645

2646

2647 size_type

2649 size_type __n) const _GLIBCXX_NOEXCEPT;

2650

2651

2652

2653

2654

2655

2656

2657

2658

2659

2660

2661 size_type

2663 _GLIBCXX_NOEXCEPT

2664 {

2665 __glibcxx_requires_string(__s);

2666 return this->find_first_not_of(__s, __pos, traits_type::length(__s));

2667 }

2668

2669

2670

2671

2672

2673

2674

2675

2676

2677

2678

2679 size_type

2681 _GLIBCXX_NOEXCEPT;

2682

2683#if __cplusplus >= 201703L

2684

2685

2686

2687

2688

2689

2690

2691 template<typename _Tp>

2692 _If_sv<_Tp, size_type>

2695 {

2697 return this->find_first_not_of(__sv.data(), __pos, __sv.size());

2698 }

2699#endif

2700

2701

2702

2703

2704

2705

2706

2707

2708

2709

2710

2711

2712 size_type

2714 _GLIBCXX_NOEXCEPT

2716

2717

2718

2719

2720

2721

2722

2723

2724

2725

2726

2727

2728

2729 size_type

2731 size_type __n) const _GLIBCXX_NOEXCEPT;

2732

2733

2734

2735

2736

2737

2738

2739

2740

2741

2742

2743 size_type

2745 _GLIBCXX_NOEXCEPT

2746 {

2747 __glibcxx_requires_string(__s);

2748 return this->find_last_not_of(__s, __pos, traits_type::length(__s));

2749 }

2750

2751

2752

2753

2754

2755

2756

2757

2758

2759

2760

2761 size_type

2763 _GLIBCXX_NOEXCEPT;

2764

2765#if __cplusplus >= 201703L

2766

2767

2768

2769

2770

2771

2772

2773 template<typename _Tp>

2774 _If_sv<_Tp, size_type>

2777 {

2779 return this->find_last_not_of(__sv.data(), __pos, __sv.size());

2780 }

2781#endif

2782

2783

2784

2785

2786

2787

2788

2789

2790

2791

2792

2793

2794

2796 substr(size_type __pos = 0, size_type __n = npos) const

2798 _M_check(__pos, "basic_string::substr"), __n); }

2799

2800

2801

2802

2803

2804

2805

2806

2807

2808

2809

2810

2811

2812

2813

2814 int

2816 {

2817 const size_type __size = this->size();

2818 const size_type __osize = __str.size();

2819 const size_type __len = std::min(__size, __osize);

2820

2821 int __r = traits_type::compare(_M_data(), __str.data(), __len);

2822 if (!__r)

2823 __r = _S_compare(__size, __osize);

2824 return __r;

2825 }

2826

2827#if __cplusplus >= 201703L

2828

2829

2830

2831

2832

2833 template<typename _Tp>

2834 _If_sv<_Tp, int>

2837 {

2839 const size_type __size = this->size();

2840 const size_type __osize = __sv.size();

2841 const size_type __len = std::min(__size, __osize);

2842

2843 int __r = traits_type::compare(_M_data(), __sv.data(), __len);

2844 if (!__r)

2845 __r = _S_compare(__size, __osize);

2846 return __r;

2847 }

2848

2849

2850

2851

2852

2853

2854

2855

2856

2857 template<typename _Tp>

2858 _If_sv<_Tp, int>

2859 compare(size_type __pos, size_type __n, const _Tp& __svt) const

2861 {

2863 return __sv_type(*this).substr(__pos, __n).compare(__sv);

2864 }

2865

2866

2867

2868

2869

2870

2871

2872

2873

2874

2875

2876 template<typename _Tp>

2877 _If_sv<_Tp, int>

2878 compare(size_type __pos1, size_type __n1, const _Tp& __svt,

2879 size_type __pos2, size_type __n2 = npos) const

2881 {

2884 .substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));

2885 }

2886#endif

2887

2888

2889

2890

2891

2892

2893

2894

2895

2896

2897

2898

2899

2900

2901

2902

2903

2904

2905

2906

2907 int

2909 {

2910 _M_check(__pos, "basic_string::compare");

2911 __n = _M_limit(__pos, __n);

2912 const size_type __osize = __str.size();

2913 const size_type __len = std::min(__n, __osize);

2914 int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len);

2915 if (!__r)

2916 __r = _S_compare(__n, __osize);

2917 return __r;

2918 }

2919

2920

2921

2922

2923

2924

2925

2926

2927

2928

2929

2930

2931

2932

2933

2934

2935

2936

2937

2938

2939

2940

2941

2942

2943 int

2945 size_type __pos2, size_type __n2 = npos) const

2946 {

2947 _M_check(__pos1, "basic_string::compare");

2948 __str._M_check(__pos2, "basic_string::compare");

2949 __n1 = _M_limit(__pos1, __n1);

2950 __n2 = __str._M_limit(__pos2, __n2);

2951 const size_type __len = std::min(__n1, __n2);

2952 int __r = traits_type::compare(_M_data() + __pos1,

2953 __str.data() + __pos2, __len);

2954 if (!__r)

2955 __r = _S_compare(__n1, __n2);

2956 return __r;

2957 }

2958

2959

2960

2961

2962

2963

2964

2965

2966

2967

2968

2969

2970

2971

2972

2973 int

2974 compare(const _CharT* __s) const _GLIBCXX_NOEXCEPT

2975 {

2976 __glibcxx_requires_string(__s);

2977 const size_type __size = this->size();

2978 const size_type __osize = traits_type::length(__s);

2979 const size_type __len = std::min(__size, __osize);

2980 int __r = traits_type::compare(_M_data(), __s, __len);

2981 if (!__r)

2982 __r = _S_compare(__size, __osize);

2983 return __r;

2984 }

2985

2986

2987

2988

2989

2990

2991

2992

2993

2994

2995

2996

2997

2998

2999

3000

3001

3002

3003

3004

3005

3006

3007 int

3008 compare(size_type __pos, size_type __n1, const _CharT* __s) const

3009 {

3010 __glibcxx_requires_string(__s);

3011 _M_check(__pos, "basic_string::compare");

3012 __n1 = _M_limit(__pos, __n1);

3013 const size_type __osize = traits_type::length(__s);

3014 const size_type __len = std::min(__n1, __osize);

3015 int __r = traits_type::compare(_M_data() + __pos, __s, __len);

3016 if (!__r)

3017 __r = _S_compare(__n1, __osize);

3018 return __r;

3019 }

3020

3021

3022

3023

3024

3025

3026

3027

3028

3029

3030

3031

3032

3033

3034

3035

3036

3037

3038

3039

3040

3041

3042

3043

3044

3045 int

3046 compare(size_type __pos, size_type __n1, const _CharT* __s,

3047 size_type __n2) const

3048 {

3049 __glibcxx_requires_string_len(__s, __n2);

3050 _M_check(__pos, "basic_string::compare");

3051 __n1 = _M_limit(__pos, __n1);

3052 const size_type __len = std::min(__n1, __n2);

3053 int __r = traits_type::compare(_M_data() + __pos, __s, __len);

3054 if (!__r)

3055 __r = _S_compare(__n1, __n2);

3056 return __r;

3057 }

3058

3059#if __cplusplus > 201703L

3060 bool

3062 { return __sv_type(this->data(), this->size()).starts_with(__x); }

3063

3064 bool

3065 starts_with(_CharT __x) const noexcept

3066 { return __sv_type(this->data(), this->size()).starts_with(__x); }

3067

3068 [[__gnu__::__nonnull__]]

3069 bool

3070 starts_with(const _CharT* __x) const noexcept

3071 { return __sv_type(this->data(), this->size()).starts_with(__x); }

3072

3073 bool

3074 ends_with(basic_string_view<_CharT, _Traits> __x) const noexcept

3075 { return __sv_type(this->data(), this->size()).ends_with(__x); }

3076

3077 bool

3078 ends_with(_CharT __x) const noexcept

3079 { return __sv_type(this->data(), this->size()).ends_with(__x); }

3080

3081 [[__gnu__::__nonnull__]]

3082 bool

3083 ends_with(const _CharT* __x) const noexcept

3084 { return __sv_type(this->data(), this->size()).ends_with(__x); }

3085#endif

3086

3087#if __cplusplus > 202011L

3088 bool

3089 contains(basic_string_view<_CharT, _Traits> __x) const noexcept

3090 { return __sv_type(this->data(), this->size()).contains(__x); }

3091

3092 bool

3093 contains(_CharT __x) const noexcept

3094 { return __sv_type(this->data(), this->size()).contains(__x); }

3095

3096 [[__gnu__::__nonnull__]]

3097 bool

3098 contains(const _CharT* __x) const noexcept

3099 { return __sv_type(this->data(), this->size()).contains(__x); }

3100#endif

3101

3102# ifdef _GLIBCXX_TM_TS_INTERNAL

3103 friend void

3104 ::_txnal_cow_string_C1_for_exceptions(void* that, const char* s,

3105 void* exc);

3106 friend const char*

3107 ::_txnal_cow_string_c_str(const void *that);

3108 friend void

3109 ::_txnal_cow_string_D1(void *that);

3110 friend void

3111 ::_txnal_cow_string_D1_commit(void *that);

3112# endif

3113 };

3114

3115 template<typename _CharT, typename _Traits, typename _Alloc>

3116 const typename basic_string<_CharT, _Traits, _Alloc>::size_type

3117 basic_string<_CharT, _Traits, _Alloc>::

3118 _Rep::_S_max_size = (((npos - sizeof(_Rep_base))/sizeof(_CharT)) - 1) / 4;

3119

3120 template<typename _CharT, typename _Traits, typename _Alloc>

3121 const _CharT

3122 basic_string<_CharT, _Traits, _Alloc>::

3123 _Rep::_S_terminal = _CharT();

3124

3125 template<typename _CharT, typename _Traits, typename _Alloc>

3126 const typename basic_string<_CharT, _Traits, _Alloc>::size_type

3128

3129

3130

3131 template<typename _CharT, typename _Traits, typename _Alloc>

3132 typename basic_string<_CharT, _Traits, _Alloc>::size_type

3133 basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_empty_rep_storage[

3134 (sizeof(_Rep_base) + sizeof(_CharT) + sizeof(size_type) - 1) /

3135 sizeof(size_type)];

3136

3137

3138

3139

3140

3141 template<typename _CharT, typename _Traits, typename _Alloc>

3142 template<typename _InIterator>

3143 _CharT*

3144 basic_string<_CharT, _Traits, _Alloc>::

3145 _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,

3146 input_iterator_tag)

3147 {

3148#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0

3149 if (__beg == __end && __a == _Alloc())

3150 return _S_empty_rep()._M_refdata();

3151#endif

3152

3153 _CharT __buf[128];

3154 size_type __len = 0;

3155 while (__beg != __end && __len < sizeof(__buf) / sizeof(_CharT))

3156 {

3157 __buf[__len++] = *__beg;

3158 ++__beg;

3159 }

3160 _Rep* __r = _Rep::_S_create(__len, size_type(0), __a);

3161 _M_copy(__r->_M_refdata(), __buf, __len);

3162 __try

3163 {

3164 while (__beg != __end)

3165 {

3166 if (__len == __r->_M_capacity)

3167 {

3168

3169 _Rep* __another = _Rep::_S_create(__len + 1, __len, __a);

3170 _M_copy(__another->_M_refdata(), __r->_M_refdata(), __len);

3171 __r->_M_destroy(__a);

3172 __r = __another;

3173 }

3174 __r->_M_refdata()[__len++] = *__beg;

3175 ++__beg;

3176 }

3177 }

3178 __catch(...)

3179 {

3180 __r->_M_destroy(__a);

3181 __throw_exception_again;

3182 }

3183 __r->_M_set_length_and_sharable(__len);

3184 return __r->_M_refdata();

3185 }

3186

3187 template<typename _CharT, typename _Traits, typename _Alloc>

3188 template <typename _InIterator>

3189 _CharT*

3190 basic_string<_CharT, _Traits, _Alloc>::

3191 _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,

3192 forward_iterator_tag)

3193 {

3194#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0

3195 if (__beg == __end && __a == _Alloc())

3196 return _S_empty_rep()._M_refdata();

3197#endif

3198

3199 if (__gnu_cxx::__is_null_pointer(__beg) && __beg != __end)

3200 __throw_logic_error(__N("basic_string::_S_construct null not valid"));

3201

3202 const size_type __dnew = static_cast<size_type>(std::distance(__beg,

3203 __end));

3204

3205 _Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a);

3206 __try

3207 { _S_copy_chars(__r->_M_refdata(), __beg, __end); }

3208 __catch(...)

3209 {

3210 __r->_M_destroy(__a);

3211 __throw_exception_again;

3212 }

3213 __r->_M_set_length_and_sharable(__dnew);

3214 return __r->_M_refdata();

3215 }

3216

3217 template<typename _CharT, typename _Traits, typename _Alloc>

3218 _CharT*

3219 basic_string<_CharT, _Traits, _Alloc>::

3220 _S_construct(size_type __n, _CharT __c, const _Alloc& __a)

3221 {

3222#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0

3223 if (__n == 0 && __a == _Alloc())

3224 return _S_empty_rep()._M_refdata();

3225#endif

3226

3227 _Rep* __r = _Rep::_S_create(__n, size_type(0), __a);

3228 if (__n)

3229 _M_assign(__r->_M_refdata(), __n, __c);

3230

3231 __r->_M_set_length_and_sharable(__n);

3232 return __r->_M_refdata();

3233 }

3234

3235 template<typename _CharT, typename _Traits, typename _Alloc>

3238 : _M_dataplus(_S_construct(__str._M_data()

3239 + __str._M_check(__pos,

3240 "basic_string::basic_string"),

3241 __str._M_data() + __str._M_limit(__pos, npos)

3242 + __pos, __a), __a)

3243 { }

3244

3245 template<typename _CharT, typename _Traits, typename _Alloc>

3248 : _M_dataplus(_S_construct(__str._M_data()

3249 + __str._M_check(__pos,

3250 "basic_string::basic_string"),

3251 __str._M_data() + __str._M_limit(__pos, __n)

3252 + __pos, _Alloc()), _Alloc())

3253 { }

3254

3255 template<typename _CharT, typename _Traits, typename _Alloc>

3258 size_type __n, const _Alloc& __a)

3259 : _M_dataplus(_S_construct(__str._M_data()

3260 + __str._M_check(__pos,

3261 "basic_string::basic_string"),

3262 __str._M_data() + __str._M_limit(__pos, __n)

3263 + __pos, __a), __a)

3264 { }

3265

3266 template<typename _CharT, typename _Traits, typename _Alloc>

3270 {

3271 if (_M_rep() != __str._M_rep())

3272 {

3273

3274 const allocator_type __a = this->get_allocator();

3275 _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator());

3276 _M_rep()->_M_dispose(__a);

3277 _M_data(__tmp);

3278 }

3279 return *this;

3280 }

3281

3282 template<typename _CharT, typename _Traits, typename _Alloc>

3285 assign(const _CharT* __s, size_type __n)

3286 {

3287 __glibcxx_requires_string_len(__s, __n);

3288 _M_check_length(this->size(), __n, "basic_string::assign");

3289 if (_M_disjunct(__s) || _M_rep()->_M_is_shared())

3290 return _M_replace_safe(size_type(0), this->size(), __s, __n);

3291 else

3292 {

3293

3294 const size_type __pos = __s - _M_data();

3295 if (__pos >= __n)

3296 _M_copy(_M_data(), __s, __n);

3297 else if (__pos)

3298 _M_move(_M_data(), __s, __n);

3299 _M_rep()->_M_set_length_and_sharable(__n);

3300 return *this;

3301 }

3302 }

3303

3304 template<typename _CharT, typename _Traits, typename _Alloc>

3307 append(size_type __n, _CharT __c)

3308 {

3309 if (__n)

3310 {

3311 _M_check_length(size_type(0), __n, "basic_string::append");

3312 const size_type __len = __n + this->size();

3313 if (__len > this->capacity() || _M_rep()->_M_is_shared())

3314 this->reserve(__len);

3315 _M_assign(_M_data() + this->size(), __n, __c);

3316 _M_rep()->_M_set_length_and_sharable(__len);

3317 }

3318 return *this;

3319 }

3320

3321 template<typename _CharT, typename _Traits, typename _Alloc>

3324 append(const _CharT* __s, size_type __n)

3325 {

3326 __glibcxx_requires_string_len(__s, __n);

3327 if (__n)

3328 {

3329 _M_check_length(size_type(0), __n, "basic_string::append");

3330 const size_type __len = __n + this->size();

3331 if (__len > this->capacity() || _M_rep()->_M_is_shared())

3332 {

3333 if (_M_disjunct(__s))

3334 this->reserve(__len);

3335 else

3336 {

3337 const size_type __off = __s - _M_data();

3338 this->reserve(__len);

3339 __s = _M_data() + __off;

3340 }

3341 }

3342 _M_copy(_M_data() + this->size(), __s, __n);

3343 _M_rep()->_M_set_length_and_sharable(__len);

3344 }

3345 return *this;

3346 }

3347

3348 template<typename _CharT, typename _Traits, typename _Alloc>

3352 {

3353 const size_type __size = __str.size();

3354 if (__size)

3355 {

3356 const size_type __len = __size + this->size();

3357 if (__len > this->capacity() || _M_rep()->_M_is_shared())

3358 this->reserve(__len);

3359 _M_copy(_M_data() + this->size(), __str._M_data(), __size);

3360 _M_rep()->_M_set_length_and_sharable(__len);

3361 }

3362 return *this;

3363 }

3364

3365 template<typename _CharT, typename _Traits, typename _Alloc>

3369 {

3370 __str._M_check(__pos, "basic_string::append");

3371 __n = __str._M_limit(__pos, __n);

3372 if (__n)

3373 {

3374 const size_type __len = __n + this->size();

3375 if (__len > this->capacity() || _M_rep()->_M_is_shared())

3376 this->reserve(__len);

3377 _M_copy(_M_data() + this->size(), __str._M_data() + __pos, __n);

3378 _M_rep()->_M_set_length_and_sharable(__len);

3379 }

3380 return *this;

3381 }

3382

3383 template<typename _CharT, typename _Traits, typename _Alloc>

3386 insert(size_type __pos, const _CharT* __s, size_type __n)

3387 {

3388 __glibcxx_requires_string_len(__s, __n);

3389 _M_check(__pos, "basic_string::insert");

3390 _M_check_length(size_type(0), __n, "basic_string::insert");

3391 if (_M_disjunct(__s) || _M_rep()->_M_is_shared())

3392 return _M_replace_safe(__pos, size_type(0), __s, __n);

3393 else

3394 {

3395

3396 const size_type __off = __s - _M_data();

3397 _M_mutate(__pos, 0, __n);

3398 __s = _M_data() + __off;

3399 _CharT* __p = _M_data() + __pos;

3400 if (__s + __n <= __p)

3401 _M_copy(__p, __s, __n);

3402 else if (__s >= __p)

3403 _M_copy(__p, __s + __n, __n);

3404 else

3405 {

3406 const size_type __nleft = __p - __s;

3407 _M_copy(__p, __s, __nleft);

3408 _M_copy(__p + __nleft, __p + __n, __n - __nleft);

3409 }

3410 return *this;

3411 }

3412 }

3413

3414 template<typename _CharT, typename _Traits, typename _Alloc>

3415 typename basic_string<_CharT, _Traits, _Alloc>::iterator

3417 erase(iterator __first, iterator __last)

3418 {

3419 _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last

3420 && __last <= _M_iend());

3421

3422

3423

3424

3425 const size_type __size = __last - __first;

3426 if (__size)

3427 {

3428 const size_type __pos = __first - _M_ibegin();

3429 _M_mutate(__pos, __size, size_type(0));

3430 _M_rep()->_M_set_leaked();

3431 return iterator(_M_data() + __pos);

3432 }

3433 else

3434 return __first;

3435 }

3436

3437 template<typename _CharT, typename _Traits, typename _Alloc>

3440 replace(size_type __pos, size_type __n1, const _CharT* __s,

3441 size_type __n2)

3442 {

3443 __glibcxx_requires_string_len(__s, __n2);

3444 _M_check(__pos, "basic_string::replace");

3445 __n1 = _M_limit(__pos, __n1);

3446 _M_check_length(__n1, __n2, "basic_string::replace");

3447 bool __left;

3448 if (_M_disjunct(__s) || _M_rep()->_M_is_shared())

3449 return _M_replace_safe(__pos, __n1, __s, __n2);

3450 else if ((__left = __s + __n2 <= _M_data() + __pos)

3451 || _M_data() + __pos + __n1 <= __s)

3452 {

3453

3454 size_type __off = __s - _M_data();

3455 __left ? __off : (__off += __n2 - __n1);

3456 _M_mutate(__pos, __n1, __n2);

3457 _M_copy(_M_data() + __pos, _M_data() + __off, __n2);

3458 return *this;

3459 }

3460 else

3461 {

3462

3464 return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2);

3465 }

3466 }

3467

3468 template<typename _CharT, typename _Traits, typename _Alloc>

3469 void

3471 _M_destroy(const _Alloc& __a) throw ()

3472 {

3473 const size_type __size = sizeof(_Rep_base)

3474 + (this->_M_capacity + 1) * sizeof(_CharT);

3475 _Raw_bytes_alloc(__a).deallocate(reinterpret_cast<char*>(this), __size);

3476 }

3477

3478 template<typename _CharT, typename _Traits, typename _Alloc>

3479 void

3480 basic_string<_CharT, _Traits, _Alloc>::

3481 _M_leak_hard()

3482 {

3483

3484

3485

3486

3487 if (this->empty())

3488 return;

3489

3490 if (_M_rep()->_M_is_shared())

3491 _M_mutate(0, 0, 0);

3492 _M_rep()->_M_set_leaked();

3493 }

3494

3495 template<typename _CharT, typename _Traits, typename _Alloc>

3496 void

3497 basic_string<_CharT, _Traits, _Alloc>::

3498 _M_mutate(size_type __pos, size_type __len1, size_type __len2)

3499 {

3500 const size_type __old_size = this->size();

3501 const size_type __new_size = __old_size + __len2 - __len1;

3502 const size_type __how_much = __old_size - __pos - __len1;

3503

3504 if (__new_size > this->capacity() || _M_rep()->_M_is_shared())

3505 {

3506

3507 const allocator_type __a = get_allocator();

3508 _Rep* __r = _Rep::_S_create(__new_size, this->capacity(), __a);

3509

3510 if (__pos)

3511 _M_copy(__r->_M_refdata(), _M_data(), __pos);

3512 if (__how_much)

3513 _M_copy(__r->_M_refdata() + __pos + __len2,

3514 _M_data() + __pos + __len1, __how_much);

3515

3516 _M_rep()->_M_dispose(__a);

3517 _M_data(__r->_M_refdata());

3518 }

3519 else if (__how_much && __len1 != __len2)

3520 {

3521

3522 _M_move(_M_data() + __pos + __len2,

3523 _M_data() + __pos + __len1, __how_much);

3524 }

3525 _M_rep()->_M_set_length_and_sharable(__new_size);

3526 }

3527

3528 template<typename _CharT, typename _Traits, typename _Alloc>

3529 void

3531 reserve(size_type __res)

3532 {

3533 const size_type __capacity = capacity();

3534

3535

3536

3537

3538

3539 if (__res <= __capacity)

3540 {

3541 if (!_M_rep()->_M_is_shared())

3542 return;

3543

3544

3545 __res = __capacity;

3546 }

3547

3548 const allocator_type __a = get_allocator();

3549 _CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size());

3550 _M_rep()->_M_dispose(__a);

3551 _M_data(__tmp);

3552 }

3553

3554 template<typename _CharT, typename _Traits, typename _Alloc>

3555 void

3559 {

3560 if (_M_rep()->_M_is_leaked())

3561 _M_rep()->_M_set_sharable();

3562 if (__s._M_rep()->_M_is_leaked())

3563 __s._M_rep()->_M_set_sharable();

3564 if (this->get_allocator() == __s.get_allocator())

3565 {

3566 _CharT* __tmp = _M_data();

3567 _M_data(__s._M_data());

3568 __s._M_data(__tmp);

3569 }

3570

3571 else

3572 {

3573 const basic_string __tmp1(_M_ibegin(), _M_iend(),

3574 __s.get_allocator());

3575 const basic_string __tmp2(__s._M_ibegin(), __s._M_iend(),

3576 this->get_allocator());

3577 *this = __tmp2;

3578 __s = __tmp1;

3579 }

3580 }

3581

3582 template<typename _CharT, typename _Traits, typename _Alloc>

3585 _S_create(size_type __capacity, size_type __old_capacity,

3586 const _Alloc& __alloc)

3587 {

3588

3589

3590 if (__capacity > _S_max_size)

3591 __throw_length_error(__N("basic_string::_S_create"));

3592

3593

3594

3595

3596

3597

3598

3599

3600

3601

3602

3603

3604

3605

3606

3607

3608

3609

3610

3611

3612

3613

3614

3615

3616 const size_type __pagesize = 4096;

3617 const size_type __malloc_header_size = 4 * sizeof(void*);

3618

3619

3620

3621

3622

3623

3624

3625 if (__capacity > __old_capacity && __capacity < 2 * __old_capacity)

3626 __capacity = 2 * __old_capacity;

3627

3628

3629

3630

3631 size_type __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);

3632

3633 const size_type __adj_size = __size + __malloc_header_size;

3634 if (__adj_size > __pagesize && __capacity > __old_capacity)

3635 {

3636 const size_type __extra = __pagesize - __adj_size % __pagesize;

3637 __capacity += __extra / sizeof(_CharT);

3638

3639 if (__capacity > _S_max_size)

3640 __capacity = _S_max_size;

3641 __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);

3642 }

3643

3644

3645

3646 void* __place = _Raw_bytes_alloc(__alloc).allocate(__size);

3647 _Rep *__p = new (__place) _Rep;

3648 __p->_M_capacity = __capacity;

3649

3650

3651

3652

3653

3654

3655

3656 __p->_M_set_sharable();

3657 return __p;

3658 }

3659

3660 template<typename _CharT, typename _Traits, typename _Alloc>

3661 _CharT*

3662 basic_string<_CharT, _Traits, _Alloc>::_Rep::

3663 _M_clone(const _Alloc& __alloc, size_type __res)

3664 {

3665

3666 const size_type __requested_cap = this->_M_length + __res;

3667 _Rep* __r = _Rep::_S_create(__requested_cap, this->_M_capacity,

3668 __alloc);

3669 if (this->_M_length)

3670 _M_copy(__r->_M_refdata(), _M_refdata(), this->_M_length);

3671

3672 __r->_M_set_length_and_sharable(this->_M_length);

3673 return __r->_M_refdata();

3674 }

3675

3676 template<typename _CharT, typename _Traits, typename _Alloc>

3677 void

3679 resize(size_type __n, _CharT __c)

3680 {

3681 const size_type __size = this->size();

3682 _M_check_length(__size, __n, "basic_string::resize");

3683 if (__size < __n)

3684 this->append(__n - __size, __c);

3685 else if (__n < __size)

3686 this->erase(__n);

3687

3688 }

3689

3690 template<typename _CharT, typename _Traits, typename _Alloc>

3691 template<typename _InputIterator>

3695 _InputIterator __k2, __false_type)

3696 {

3698 const size_type __n1 = __i2 - __i1;

3699 _M_check_length(__n1, __s.size(), "basic_string::_M_replace_dispatch");

3700 return _M_replace_safe(__i1 - _M_ibegin(), __n1, __s._M_data(),

3701 __s.size());

3702 }

3703

3704 template<typename _CharT, typename _Traits, typename _Alloc>

3705 basic_string<_CharT, _Traits, _Alloc>&

3706 basic_string<_CharT, _Traits, _Alloc>::

3707 _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,

3708 _CharT __c)

3709 {

3710 _M_check_length(__n1, __n2, "basic_string::_M_replace_aux");

3711 _M_mutate(__pos1, __n1, __n2);

3712 if (__n2)

3713 _M_assign(_M_data() + __pos1, __n2, __c);

3714 return *this;

3715 }

3716

3717 template<typename _CharT, typename _Traits, typename _Alloc>

3718 basic_string<_CharT, _Traits, _Alloc>&

3719 basic_string<_CharT, _Traits, _Alloc>::

3720 _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s,

3721 size_type __n2)

3722 {

3723 _M_mutate(__pos1, __n1, __n2);

3724 if (__n2)

3725 _M_copy(_M_data() + __pos1, __s, __n2);

3726 return *this;

3727 }

3728

3729 template<typename _CharT, typename _Traits, typename _Alloc>

3730 void

3733 {

3734#if __cpp_exceptions

3735 if (length() < capacity() || _M_rep()->_M_is_shared())

3736 try

3737 {

3738 const allocator_type __a = get_allocator();

3739 _CharT* __tmp = _M_rep()->_M_clone(__a);

3740 _M_rep()->_M_dispose(__a);

3741 _M_data(__tmp);

3742 }

3744 { throw; }

3745 catch (...)

3746 { }

3747#endif

3748 }

3749

3750 template<typename _CharT, typename _Traits, typename _Alloc>

3751 typename basic_string<_CharT, _Traits, _Alloc>::size_type

3753 copy(_CharT* __s, size_type __n, size_type __pos) const

3754 {

3755 _M_check(__pos, "basic_string::copy");

3756 __n = _M_limit(__pos, __n);

3757 __glibcxx_requires_string_len(__s, __n);

3758 if (__n)

3759 _M_copy(__s, _M_data() + __pos, __n);

3760

3761 return __n;

3762 }

3763

3764#ifdef __glibcxx_string_resize_and_overwrite

3765 template<typename _CharT, typename _Traits, typename _Alloc>

3766 template<typename _Operation>

3767 [[__gnu__::__always_inline__]]

3768 void

3771 { resize_and_overwrite<_Operation&>(__n, __op); }

3772#endif

3773

3774#if __cplusplus >= 201103L

3775 template<typename _CharT, typename _Traits, typename _Alloc>

3776 template<typename _Operation>

3777 void

3778 basic_string<_CharT, _Traits, _Alloc>::

3779#ifdef __glibcxx_string_resize_and_overwrite

3780 resize_and_overwrite(const size_type __n, _Operation __op)

3781#else

3782 __resize_and_overwrite(const size_type __n, _Operation __op)

3783#endif

3784 {

3785 const size_type __capacity = capacity();

3786 _CharT* __p;

3787 if (__n > __capacity || _M_rep()->_M_is_shared())

3788 this->reserve(__n);

3789 __p = _M_data();

3790 struct _Terminator {

3791 ~_Terminator() { _M_this->_M_rep()->_M_set_length_and_sharable(_M_r); }

3792 basic_string* _M_this;

3793 size_type _M_r;

3794 };

3795 _Terminator __term{this, 0};

3796 auto __r = std::move(__op)(__p + 0, __n + 0);

3797#ifdef __cpp_lib_concepts

3798 static_assert(ranges::__detail::__is_integer_like<decltype(__r)>);

3799#else

3800 static_assert(__gnu_cxx::__is_integer_nonstrict<decltype(__r)>::__value,

3801 "resize_and_overwrite operation must return an integer");

3802#endif

3803 _GLIBCXX_DEBUG_ASSERT(__r >= 0 && __r <= __n);

3804 __term._M_r = size_type(__r);

3805 if (__term._M_r > __n)

3806 __builtin_unreachable();

3807 }

3808#endif

3809

3810

3811_GLIBCXX_END_NAMESPACE_VERSION

3812}

3813#endif

3814#endif

typename enable_if< _Cond, _Tp >::type enable_if_t

Alias template for enable_if.

constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept

Convert a value to an rvalue.

constexpr const _Tp & min(const _Tp &, const _Tp &)

This does what you think it does.

ISO C++ entities toplevel namespace is std.

constexpr iterator_traits< _InputIterator >::difference_type distance(_InputIterator __first, _InputIterator __last)

A generalization of pointer arithmetic.

constexpr auto empty(const _Container &__cont) noexcept(noexcept(__cont.empty())) -> decltype(__cont.empty())

Return whether a container is empty.

constexpr auto size(const _Container &__cont) noexcept(noexcept(__cont.size())) -> decltype(__cont.size())

Return the size of a container.

Uniform interface to all allocator types.

Managing sequences of characters and character-like objects.

int compare(size_type __pos1, size_type __n1, const basic_string &__str, size_type __pos2, size_type __n2=npos) const

Compare substring to a substring.

const_reverse_iterator crbegin() const noexcept

void swap(basic_string &__s) noexcept(/*conditional */)

Swap contents with another string.

_If_sv< _Tp, basic_string & > operator=(const _Tp &__svt)

Set value to string constructed from a string_view.

basic_string & operator=(const _CharT *__s)

Copy contents of s into this string.

basic_string & append(const basic_string &__str, size_type __pos, size_type __n=npos)

Append a substring.

void push_back(_CharT __c)

Append a single character.

const_iterator cend() const noexcept

basic_string & operator+=(initializer_list< _CharT > __l)

Append an initializer_list of characters.

size_type find(const _CharT *__s, size_type __pos=0) const noexcept

Find position of a C string.

basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc &__a=_Alloc())

Construct string as copy of a range.

basic_string & replace(iterator __i1, iterator __i2, const _CharT *__s, size_type __n)

Replace range of characters with C substring.

basic_string & assign(initializer_list< _CharT > __l)

Set value to an initializer_list of characters.

size_type find_first_of(const basic_string &__str, size_type __pos=0) const noexcept

Find position of a character of string.

iterator erase(iterator __first, iterator __last)

Remove a range of characters.

_If_sv< _Tp, basic_string & > insert(size_type __pos1, const _Tp &__svt, size_type __pos2, size_type __n=npos)

Insert a string_view.

_If_sv< _Tp, int > compare(size_type __pos1, size_type __n1, const _Tp &__svt, size_type __pos2, size_type __n2=npos) const noexcept(is_same< _Tp, __sv_type >::value)

Compare to a string_view.

const _CharT * data() const noexcept

Return const pointer to contents.

basic_string(const _Alloc &__a)

Construct an empty string using allocator a.

size_type find_last_of(const _CharT *__s, size_type __pos=npos) const noexcept

Find last position of a character of C string.

_If_sv< _Tp, basic_string & > insert(size_type __pos, const _Tp &__svt)

Insert a string_view.

int compare(const _CharT *__s) const noexcept

Compare to a C string.

void insert(iterator __p, initializer_list< _CharT > __l)

Insert an initializer_list of characters.

basic_string & insert(size_type __pos1, const basic_string &__str)

Insert value of a string.

void __resize_and_overwrite(size_type __n, _Operation __op)

Non-standard version of resize_and_overwrite for C++11 and above.

size_type rfind(const _CharT *__s, size_type __pos=npos) const noexcept

Find last position of a C string.

basic_string substr(size_type __pos=0, size_type __n=npos) const

Get a substring.

iterator erase(iterator __position)

Remove one character.

size_type find(const _CharT *__s, size_type __pos, size_type __n) const noexcept

Find position of a C substring.

size_type find(const basic_string &__str, size_type __pos=0) const noexcept

Find position of a string.

basic_string & assign(const _CharT *__s, size_type __n)

Set value to a C substring.

size_type find_last_not_of(const basic_string &__str, size_type __pos=npos) const noexcept

Find last position of a character not in string.

int compare(size_type __pos, size_type __n, const basic_string &__str) const

Compare substring to a string.

basic_string(const basic_string &__str)

Construct string with copy of value of str.

int compare(const basic_string &__str) const

Compare to a string.

int compare(size_type __pos, size_type __n1, const _CharT *__s) const

Compare substring to a C string.

_If_sv< _Tp, size_type > find_last_not_of(const _Tp &__svt, size_type __pos=npos) const noexcept(is_same< _Tp, __sv_type >::value)

Find last position of a character not in a string_view.

int compare(size_type __pos, size_type __n1, const _CharT *__s, size_type __n2) const

Compare substring against a character array.

_If_sv< _Tp, basic_string & > replace(size_type __pos1, size_type __n1, const _Tp &__svt, size_type __pos2, size_type __n2=npos)

Replace range of characters with string_view.

_If_sv< _Tp, basic_string & > replace(const_iterator __i1, const_iterator __i2, const _Tp &__svt)

Replace range of characters with string_view.

basic_string & replace(iterator __i1, iterator __i2, const basic_string &__str)

Replace range of characters with string.

basic_string(const basic_string &__str, size_type __pos, const _Alloc &__a=_Alloc())

Construct string as copy of a substring.

basic_string(const basic_string &__str, size_type __pos, size_type __n)

Construct string as copy of a substring.

size_type find_first_not_of(const basic_string &__str, size_type __pos=0) const noexcept

Find position of a character not in string.

const_reference front() const noexcept

size_type find_last_not_of(const _CharT *__s, size_type __pos=npos) const noexcept

Find last position of a character not in C string.

void insert(iterator __p, size_type __n, _CharT __c)

Insert multiple characters.

basic_string & assign(const basic_string &__str)

Set value to contents of another string.

basic_string & append(size_type __n, _CharT __c)

Append multiple characters.

basic_string(const _Tp &__t, size_type __pos, size_type __n, const _Alloc &__a=_Alloc())

Construct string from a substring of a string_view.

_If_sv< _Tp, basic_string & > assign(const _Tp &__svt)

Set value from a string_view.

reverse_iterator rbegin()

basic_string & insert(size_type __pos1, const basic_string &__str, size_type __pos2, size_type __n=npos)

Insert a substring.

basic_string(initializer_list< _CharT > __l, const _Alloc &__a=_Alloc())

Construct string from an initializer list.

basic_string(const basic_string &__str, size_type __pos, size_type __n, const _Alloc &__a)

Construct string as copy of a substring.

basic_string(const _Tp &__t, const _Alloc &__a=_Alloc())

Construct string from a string_view.

basic_string & replace(size_type __pos, size_type __n1, const _CharT *__s, size_type __n2)

Replace characters with value of a C substring.

basic_string & replace(iterator __i1, iterator __i2, _InputIterator __k1, _InputIterator __k2)

Replace range of characters with range.

basic_string & assign(basic_string &&__str) noexcept(allocator_traits< _Alloc >::is_always_equal::value)

Set value to contents of another string.

_If_sv< _Tp, basic_string & > operator+=(const _Tp &__svt)

Append a string_view.

void pop_back()

Remove the last character.

basic_string(basic_string &&__str) noexcept

Move construct string.

size_type copy(_CharT *__s, size_type __n, size_type __pos=0) const

Copy substring into C string.

size_type length() const noexcept

Returns the number of characters in the string, not including any null-termination.

size_type find_last_of(const basic_string &__str, size_type __pos=npos) const noexcept

Find last position of a character of string.

basic_string & insert(size_type __pos, const _CharT *__s, size_type __n)

Insert a C substring.

basic_string & operator+=(const basic_string &__str)

Append a string to this string.

size_type size() const noexcept

Returns the number of characters in the string, not including any null-termination.

size_type rfind(const basic_string &__str, size_type __pos=npos) const noexcept

Find last position of a string.

basic_string & operator+=(const _CharT *__s)

Append a C string.

basic_string(size_type __n, _CharT __c, const _Alloc &__a=_Alloc())

Construct string as multiple characters.

void shrink_to_fit() noexcept

A non-binding request to reduce capacity() to size().

void resize(size_type __n, _CharT __c)

Resizes the string to the specified number of characters.

void reserve()

Equivalent to shrink_to_fit().

_CharT * data() noexcept(false)

Return non-const pointer to contents.

_If_sv< _Tp, int > compare(const _Tp &__svt) const noexcept(is_same< _Tp, __sv_type >::value)

Compare to a string_view.

const_reference at(size_type __n) const

Provides access to the data contained in the string.

const_reference back() const noexcept

const_reverse_iterator rend() const noexcept

const_iterator end() const noexcept

_If_sv< _Tp, size_type > find_first_of(const _Tp &__svt, size_type __pos=0) const noexcept(is_same< _Tp, __sv_type >::value)

Find position of a character of a string_view.

size_type find_last_of(_CharT __c, size_type __pos=npos) const noexcept

Find last position of a character.

_If_sv< _Tp, basic_string & > replace(size_type __pos, size_type __n, const _Tp &__svt)

Replace range of characters with string_view.

basic_string & append(const basic_string &__str)

Append a string to this string.

const_iterator begin() const noexcept

basic_string & operator=(basic_string &&__str) noexcept(/*conditional */)

Move assign the value of str to this string.

basic_string & replace(iterator __i1, iterator __i2, initializer_list< _CharT > __l)

Replace range of characters with initializer_list.

basic_string & operator+=(_CharT __c)

Append a character.

const_reverse_iterator crend() const noexcept

basic_string & operator=(const basic_string &__str)

Assign the value of str to this string.

basic_string & operator=(_CharT __c)

Set value to string of length 1.

void resize(size_type __n)

Resizes the string to the specified number of characters.

const_reverse_iterator rbegin() const noexcept

basic_string & assign(_InputIterator __first, _InputIterator __last)

Set value to a range of characters.

basic_string & append(initializer_list< _CharT > __l)

Append an initializer_list of characters.

basic_string & append(_InputIterator __first, _InputIterator __last)

Append a range of characters.

const_reference operator[](size_type __pos) const noexcept

Subscript access to the data contained in the string.

_If_sv< _Tp, basic_string & > assign(const _Tp &__svt, size_type __pos, size_type __n=npos)

Set value from a range of characters in a string_view.

basic_string(const _CharT *__s, const _Alloc &__a=_Alloc())

Construct string as copy of a C string.

size_type find_first_of(_CharT __c, size_type __pos=0) const noexcept

Find position of a character.

_If_sv< _Tp, basic_string & > append(const _Tp &__svt, size_type __pos, size_type __n=npos)

Append a range of characters from a string_view.

basic_string & assign(size_type __n, _CharT __c)

Set value to multiple characters.

basic_string & replace(iterator __i1, iterator __i2, const _CharT *__s)

Replace range of characters with C string.

bool empty() const noexcept

_If_sv< _Tp, basic_string & > append(const _Tp &__svt)

Append a string_view.

_If_sv< _Tp, size_type > find(const _Tp &__svt, size_type __pos=0) const noexcept(is_same< _Tp, __sv_type >::value)

Find position of a string_view.

basic_string & insert(size_type __pos, const _CharT *__s)

Insert a C string.

basic_string & assign(const basic_string &__str, size_type __pos, size_type __n=npos)

Set value to a substring of a string.

const _CharT * c_str() const noexcept

Return const pointer to null-terminated contents.

_If_sv< _Tp, int > compare(size_type __pos, size_type __n, const _Tp &__svt) const noexcept(is_same< _Tp, __sv_type >::value)

Compare to a string_view.

basic_string & replace(size_type __pos, size_type __n1, const _CharT *__s)

Replace characters with value of a C string.

static const size_type npos

Value returned by various member functions when they fail.

allocator_type get_allocator() const noexcept

Return copy of allocator used to construct this string.

basic_string & assign(const _CharT *__s)

Set value to contents of a C string.

basic_string & replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)

Replace characters with multiple characters.

const_iterator cbegin() const noexcept

basic_string & replace(iterator __i1, iterator __i2, size_type __n, _CharT __c)

Replace range of characters with multiple characters.

basic_string & operator=(initializer_list< _CharT > __l)

Set value to string constructed from initializer list.

~basic_string() noexcept

Destroy the string instance.

size_type capacity() const noexcept

basic_string() noexcept

Default constructor creates an empty string.

void insert(iterator __p, _InputIterator __beg, _InputIterator __end)

Insert a range of characters.

size_type find_first_of(const _CharT *__s, size_type __pos=0) const noexcept

Find position of a character of C string.

_If_sv< _Tp, size_type > find_first_not_of(const _Tp &__svt, size_type __pos=0) const noexcept(is_same< _Tp, __sv_type >::value)

Find position of a character not in a string_view.

_If_sv< _Tp, size_type > rfind(const _Tp &__svt, size_type __pos=npos) const noexcept(is_same< _Tp, __sv_type >::value)

Find last position of a string_view.

size_type max_size() const noexcept

Returns the size() of the largest possible string.

reference operator[](size_type __pos)

Subscript access to the data contained in the string.

basic_string & insert(size_type __pos, size_type __n, _CharT __c)

Insert multiple characters.

basic_string & erase(size_type __pos=0, size_type __n=npos)

Remove characters.

basic_string & replace(size_type __pos1, size_type __n1, const basic_string &__str, size_type __pos2, size_type __n2=npos)

Replace characters with value from another string.

basic_string & append(const _CharT *__s, size_type __n)

Append a C substring.

basic_string(const _CharT *__s, size_type __n, const _Alloc &__a=_Alloc())

Construct string initialized by a character array.

basic_string & append(const _CharT *__s)

Append a C string.

_If_sv< _Tp, size_type > find_last_of(const _Tp &__svt, size_type __pos=npos) const noexcept(is_same< _Tp, __sv_type >::value)

Find last position of a character of string.

basic_string & replace(size_type __pos, size_type __n, const basic_string &__str)

Replace characters with value from another string.

size_type find_first_not_of(const _CharT *__s, size_type __pos=0) const noexcept

Find position of a character not in C string.

reference at(size_type __n)

Provides access to the data contained in the string.

iterator insert(iterator __p, _CharT __c)

Insert one character.

Thrown as part of forced unwinding.

Uniform interface to C++98 and C++11 allocators.