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
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
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
843
844
845
846
847
848
849 const_reverse_iterator
852
853
854
855
856
857
858 reverse_iterator
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
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(());
1171 }
1172
1173
1174
1175
1176
1177 const_reference
1179 {
1180 __glibcxx_assert(());
1182 }
1183
1184
1185
1186
1187
1188 reference
1190 {
1191 __glibcxx_assert(());
1193 }
1194
1195
1196
1197
1198
1199 const_reference
1201 {
1202 __glibcxx_assert(());
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
1803 {
1804 __glibcxx_assert(());
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.