1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9// FIXME: This takes over an hour to compile, disable for now.
10// UNSUPPORTED: LIBCXX-AMDGPU-FIXME
11// UNSUPPORTED: LIBCXX-NVPTX-FIXME
12
13// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
14// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=10000000
15// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-ops-limit): -fconstexpr-ops-limit=70000000
16
17// template<container-compatible-range<charT> R>
18// constexpr basic_string& replace_with_range(const_iterator i1, const_iterator i2, R&& rg); // C++23
19
20#include <string>
21#include <utility>
22
23#include "../../../../containers/sequences/insert_range_sequence_containers.h"
24#include "test_macros.h"
25
26template <class Range>
27concept HasReplaceWithRange =
28 requires(std::string& c, Range&& range) { c.replace_with_range(c.end(), c.end(), std::forward<Range>(range)); };
29
30constexpr bool test_constraints_replace_with_range() {
31 // Input range with the same value type.
32 static_assert(HasReplaceWithRange<InputRange<char>>);
33 // Input range with a convertible value type.
34 static_assert(HasReplaceWithRange<InputRange<unsigned char>>);
35 // Input range with a non-convertible value type.
36 static_assert(!HasReplaceWithRange<InputRange<Empty>>);
37 // Not an input range.
38 static_assert(!HasReplaceWithRange<InputRangeNotDerivedFrom>);
39 static_assert(!HasReplaceWithRange<InputRangeNotIndirectlyReadable>);
40 static_assert(!HasReplaceWithRange<InputRangeNotInputOrOutputIterator>);
41
42 return true;
43}
44
45using StrBuffer = Buffer<char, 256>;
46
47struct TestCaseReplacement {
48 StrBuffer initial;
49 std::size_t from = 0;
50 std::size_t to = 0;
51 StrBuffer input;
52 StrBuffer expected;
53};
54
55// Permutation matrix:
56// - initial string: empty / one-element / n elements;
57// - cut starts from: beginning / middle / end;
58// - cut size: empty / one-element / several elements / until the end;
59// - input range: empty / one-element / middle-sized / longer than SSO / longer than the current string capacity.
60
61// Empty string.
62
63constexpr TestCaseReplacement EmptyString_End_EmptyCut_EmptyRange{
64 .initial = "", .from = 0, .to = 0, .input = "", .expected = ""};
65
66constexpr TestCaseReplacement EmptyString_End_EmptyCut_OneElementRange{
67 .initial = "", .from = 0, .to = 0, .input = "a", .expected = "a"};
68
69constexpr TestCaseReplacement EmptyString_End_EmptyCut_MidRange{
70 .initial = "", .from = 0, .to = 0, .input = "aeiou", .expected = "aeiou"};
71
72constexpr TestCaseReplacement EmptyString_End_EmptyCut_LongRange{
73 .initial = "",
74 .from = 0,
75 .to = 0,
76 .input = "abcdefghijklmnopqrstuvwxyz0123456789",
77 .expected = "abcdefghijklmnopqrstuvwxyz0123456789"};
78
79// One-element string.
80
81constexpr TestCaseReplacement OneElementString_Begin_EmptyCut_EmptyRange{
82 .initial = "B", .from = 0, .to = 0, .input = "", .expected = "B"};
83
84constexpr TestCaseReplacement OneElementString_Begin_EmptyCut_OneElementRange{
85 .initial = "B", .from = 0, .to = 0, .input = "a", .expected = "aB"};
86
87constexpr TestCaseReplacement OneElementString_Begin_EmptyCut_MidRange{
88 .initial = "B", .from = 0, .to = 0, .input = "aeiou", .expected = "aeiouB"};
89
90constexpr TestCaseReplacement OneElementString_Begin_EmptyCut_LongRange{
91 .initial = "B",
92 .from = 0,
93 .to = 0,
94 .input = "abcdefghijklmnopqrstuvwxyz0123456789",
95 .expected = "abcdefghijklmnopqrstuvwxyz0123456789B"};
96
97constexpr TestCaseReplacement OneElementString_Begin_OneElementCut_EmptyRange{
98 .initial = "B", .from = 0, .to = 1, .input = "", .expected = ""};
99
100constexpr TestCaseReplacement OneElementString_Begin_OneElementCut_OneElementRange{
101 .initial = "B", .from = 0, .to = 1, .input = "a", .expected = "a"};
102
103constexpr TestCaseReplacement OneElementString_Begin_OneElementCut_MidRange{
104 .initial = "B", .from = 0, .to = 1, .input = "aeiou", .expected = "aeiou"};
105
106constexpr TestCaseReplacement OneElementString_Begin_OneElementCut_LongRange{
107 .initial = "B",
108 .from = 0,
109 .to = 1,
110 .input = "abcdefghijklmnopqrstuvwxyz0123456789",
111 .expected = "abcdefghijklmnopqrstuvwxyz0123456789"};
112
113constexpr TestCaseReplacement OneElementString_End_EmptyCut_EmptyRange{
114 .initial = "B", .from = 1, .to = 1, .input = "", .expected = "B"};
115
116constexpr TestCaseReplacement OneElementString_End_EmptyCut_OneElementRange{
117 .initial = "B", .from = 1, .to = 1, .input = "a", .expected = "Ba"};
118
119constexpr TestCaseReplacement OneElementString_End_EmptyCut_MidRange{
120 .initial = "B", .from = 1, .to = 1, .input = "aeiou", .expected = "Baeiou"};
121
122constexpr TestCaseReplacement OneElementString_End_EmptyCut_LongRange{
123 .initial = "B",
124 .from = 1,
125 .to = 1,
126 .input = "abcdefghijklmnopqrstuvwxyz0123456789",
127 .expected = "Babcdefghijklmnopqrstuvwxyz0123456789"};
128
129// Short string (using SSO).
130
131// Replace at the beginning.
132
133constexpr TestCaseReplacement ShortString_Begin_EmptyCut_EmptyRange{
134 .initial = "_BCDFGHJ_", .from = 0, .to = 0, .input = "", .expected = "_BCDFGHJ_"};
135
136constexpr TestCaseReplacement ShortString_Begin_EmptyCut_OneElementRange{
137 .initial = "_BCDFGHJ_", .from = 0, .to = 0, .input = "a", .expected = "a_BCDFGHJ_"};
138
139constexpr TestCaseReplacement ShortString_Begin_EmptyCut_MidRange{
140 .initial = "_BCDFGHJ_", .from = 0, .to = 0, .input = "aeiou", .expected = "aeiou_BCDFGHJ_"};
141
142constexpr TestCaseReplacement ShortString_Begin_EmptyCut_LongRange{
143 .initial = "_BCDFGHJ_",
144 .from = 0,
145 .to = 0,
146 .input = "abcdefghijklmnopqrstuvwxyz0123456789",
147 .expected = "abcdefghijklmnopqrstuvwxyz0123456789_BCDFGHJ_"};
148
149constexpr TestCaseReplacement ShortString_Begin_OneElementCut_EmptyRange{
150 .initial = "_BCDFGHJ_", .from = 0, .to = 1, .input = "", .expected = "BCDFGHJ_"};
151
152constexpr TestCaseReplacement ShortString_Begin_OneElementCut_OneElementRange{
153 .initial = "_BCDFGHJ_", .from = 0, .to = 1, .input = "a", .expected = "aBCDFGHJ_"};
154
155constexpr TestCaseReplacement ShortString_Begin_OneElementCut_MidRange{
156 .initial = "_BCDFGHJ_", .from = 0, .to = 1, .input = "aeiou", .expected = "aeiouBCDFGHJ_"};
157
158constexpr TestCaseReplacement ShortString_Begin_OneElementCut_LongRange{
159 .initial = "_BCDFGHJ_",
160 .from = 0,
161 .to = 1,
162 .input = "abcdefghijklmnopqrstuvwxyz0123456789",
163 .expected = "abcdefghijklmnopqrstuvwxyz0123456789BCDFGHJ_"};
164
165constexpr TestCaseReplacement ShortString_Begin_MidSizedCut_EmptyRange{
166 .initial = "_BCDFGHJ_", .from = 0, .to = 3, .input = "", .expected = "DFGHJ_"};
167
168constexpr TestCaseReplacement ShortString_Begin_MidSizedCut_OneElementRange{
169 .initial = "_BCDFGHJ_", .from = 0, .to = 3, .input = "a", .expected = "aDFGHJ_"};
170
171constexpr TestCaseReplacement ShortString_Begin_MidSizedCut_MidRange{
172 .initial = "_BCDFGHJ_", .from = 0, .to = 3, .input = "aeiou", .expected = "aeiouDFGHJ_"};
173
174// Note: this test case switches from SSO to non-SSO.
175constexpr TestCaseReplacement ShortString_Begin_MidSizedCut_LongRange{
176 .initial = "_BCDFGHJ_",
177 .from = 0,
178 .to = 3,
179 .input = "abcdefghijklmnopqrstuvwxyz0123456789",
180 .expected = "abcdefghijklmnopqrstuvwxyz0123456789DFGHJ_"};
181
182constexpr TestCaseReplacement ShortString_Begin_CutToEnd_EmptyRange{
183 .initial = "_BCDFGHJ_", .from = 0, .to = 9, .input = "", .expected = ""};
184
185constexpr TestCaseReplacement ShortString_Begin_CutToEnd_OneElementRange{
186 .initial = "_BCDFGHJ_", .from = 0, .to = 9, .input = "a", .expected = "a"};
187
188constexpr TestCaseReplacement ShortString_Begin_CutToEnd_MidRange{
189 .initial = "_BCDFGHJ_", .from = 0, .to = 9, .input = "aeiou", .expected = "aeiou"};
190
191// Note: this test case switches from SSO to non-SSO.
192constexpr TestCaseReplacement ShortString_Begin_CutToEnd_LongRange{
193 .initial = "_BCDFGHJ_",
194 .from = 0,
195 .to = 9,
196 .input = "abcdefghijklmnopqrstuvwxyz0123456789",
197 .expected = "abcdefghijklmnopqrstuvwxyz0123456789"};
198
199// Replace in the middle.
200
201constexpr TestCaseReplacement ShortString_Mid_EmptyCut_EmptyRange{
202 .initial = "_BCDFGHJ_", .from = 4, .to = 4, .input = "", .expected = "_BCDFGHJ_"};
203
204constexpr TestCaseReplacement ShortString_Mid_EmptyCut_OneElementRange{
205 .initial = "_BCDFGHJ_", .from = 4, .to = 4, .input = "a", .expected = "_BCDaFGHJ_"};
206
207constexpr TestCaseReplacement ShortString_Mid_EmptyCut_MidRange{
208 .initial = "_BCDFGHJ_", .from = 4, .to = 4, .input = "aeiou", .expected = "_BCDaeiouFGHJ_"};
209
210constexpr TestCaseReplacement ShortString_Mid_EmptyCut_LongRange{
211 .initial = "_BCDFGHJ_",
212 .from = 4,
213 .to = 4,
214 .input = "abcdefghijklmnopqrstuvwxyz0123456789",
215 .expected = "_BCDabcdefghijklmnopqrstuvwxyz0123456789FGHJ_"};
216
217constexpr TestCaseReplacement ShortString_Mid_OneElementCut_EmptyRange{
218 .initial = "_BCDFGHJ_", .from = 4, .to = 5, .input = "", .expected = "_BCDGHJ_"};
219
220constexpr TestCaseReplacement ShortString_Mid_OneElementCut_OneElementRange{
221 .initial = "_BCDFGHJ_", .from = 4, .to = 5, .input = "a", .expected = "_BCDaGHJ_"};
222
223constexpr TestCaseReplacement ShortString_Mid_OneElementCut_MidRange{
224 .initial = "_BCDFGHJ_", .from = 4, .to = 5, .input = "aeiou", .expected = "_BCDaeiouGHJ_"};
225
226constexpr TestCaseReplacement ShortString_Mid_OneElementCut_LongRange{
227 .initial = "_BCDFGHJ_",
228 .from = 4,
229 .to = 5,
230 .input = "abcdefghijklmnopqrstuvwxyz0123456789",
231 .expected = "_BCDabcdefghijklmnopqrstuvwxyz0123456789GHJ_"};
232
233constexpr TestCaseReplacement ShortString_Mid_MidSizedCut_EmptyRange{
234 .initial = "_BCDFGHJ_", .from = 4, .to = 7, .input = "", .expected = "_BCDJ_"};
235
236constexpr TestCaseReplacement ShortString_Mid_MidSizedCut_OneElementRange{
237 .initial = "_BCDFGHJ_", .from = 4, .to = 7, .input = "a", .expected = "_BCDaJ_"};
238
239constexpr TestCaseReplacement ShortString_Mid_MidSizedCut_MidRange{
240 .initial = "_BCDFGHJ_", .from = 4, .to = 7, .input = "aeiou", .expected = "_BCDaeiouJ_"};
241
242constexpr TestCaseReplacement ShortString_Mid_MidSizedCut_LongRange{
243 .initial = "_BCDFGHJ_",
244 .from = 4,
245 .to = 7,
246 .input = "abcdefghijklmnopqrstuvwxyz0123456789",
247 .expected = "_BCDabcdefghijklmnopqrstuvwxyz0123456789J_"};
248
249constexpr TestCaseReplacement ShortString_Mid_CutToEnd_EmptyRange{
250 .initial = "_BCDFGHJ_", .from = 4, .to = 9, .input = "", .expected = "_BCD"};
251
252constexpr TestCaseReplacement ShortString_Mid_CutToEnd_OneElementRange{
253 .initial = "_BCDFGHJ_", .from = 4, .to = 9, .input = "a", .expected = "_BCDa"};
254
255constexpr TestCaseReplacement ShortString_Mid_CutToEnd_MidRange{
256 .initial = "_BCDFGHJ_", .from = 4, .to = 9, .input = "aeiou", .expected = "_BCDaeiou"};
257
258constexpr TestCaseReplacement ShortString_Mid_CutToEnd_LongRange{
259 .initial = "_BCDFGHJ_",
260 .from = 4,
261 .to = 9,
262 .input = "abcdefghijklmnopqrstuvwxyz0123456789",
263 .expected = "_BCDabcdefghijklmnopqrstuvwxyz0123456789"};
264
265// Replace at the end.
266
267constexpr TestCaseReplacement ShortString_End_EmptyCut_EmptyRange{
268 .initial = "_BCDFGHJ_", .from = 9, .to = 9, .input = "", .expected = "_BCDFGHJ_"};
269
270constexpr TestCaseReplacement ShortString_End_EmptyCut_OneElementRange{
271 .initial = "_BCDFGHJ_", .from = 9, .to = 9, .input = "a", .expected = "_BCDFGHJ_a"};
272
273constexpr TestCaseReplacement ShortString_End_EmptyCut_MidRange{
274 .initial = "_BCDFGHJ_", .from = 9, .to = 9, .input = "aeiou", .expected = "_BCDFGHJ_aeiou"};
275
276constexpr TestCaseReplacement ShortString_End_EmptyCut_LongRange{
277 .initial = "_BCDFGHJ_",
278 .from = 9,
279 .to = 9,
280 .input = "abcdefghijklmnopqrstuvwxyz0123456789",
281 .expected = "_BCDFGHJ_abcdefghijklmnopqrstuvwxyz0123456789"};
282
283// Long string (no SSO).
284
285// Replace at the beginning.
286
287constexpr TestCaseReplacement LongString_Begin_EmptyCut_EmptyRange{
288 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
289 .from = 0,
290 .to = 0,
291 .input = "",
292 .expected = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"};
293
294constexpr TestCaseReplacement LongString_Begin_EmptyCut_OneElementRange{
295 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
296 .from = 0,
297 .to = 0,
298 .input = "a",
299 .expected = "a_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"};
300
301constexpr TestCaseReplacement LongString_Begin_EmptyCut_MidRange{
302 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
303 .from = 0,
304 .to = 0,
305 .input = "aeiou",
306 .expected = "aeiou_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"};
307
308constexpr TestCaseReplacement LongString_Begin_EmptyCut_LongRange{
309 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
310 .from = 0,
311 .to = 0,
312 .input = "abcdefghijklmnopqrstuvwxyz0123456789",
313 .expected = "abcdefghijklmnopqrstuvwxyz0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"};
314
315constexpr TestCaseReplacement LongString_Begin_EmptyCut_LongerThanCapacityRange{
316 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
317 .from = 0,
318 .to = 0,
319 .input = "abcdefghijklmnopqrstuvwxyz0123456789_"
320 "abcdefghijklmnopqrstuvwxyz0123456789_"
321 "abcdefghijklmnopqrstuvwxyz0123456789",
322 .expected = "abcdefghijklmnopqrstuvwxyz0123456789_"
323 "abcdefghijklmnopqrstuvwxyz0123456789_"
324 "abcdefghijklmnopqrstuvwxyz0123456789"
325 "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"};
326
327constexpr TestCaseReplacement LongString_Begin_OneElementCut_EmptyRange{
328 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
329 .from = 0,
330 .to = 1,
331 .input = "",
332 .expected = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"};
333
334constexpr TestCaseReplacement LongString_Begin_OneElementCut_OneElementRange{
335 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
336 .from = 0,
337 .to = 1,
338 .input = "a",
339 .expected = "aABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"};
340
341constexpr TestCaseReplacement LongString_Begin_OneElementCut_MidRange{
342 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
343 .from = 0,
344 .to = 1,
345 .input = "aeiou",
346 .expected = "aeiouABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"};
347
348constexpr TestCaseReplacement LongString_Begin_OneElementCut_LongRange{
349 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
350 .from = 0,
351 .to = 1,
352 .input = "abcdefghijklmnopqrstuvwxyz0123456789",
353 .expected = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"};
354
355constexpr TestCaseReplacement LongString_Begin_OneElementCut_LongerThanCapacityRange{
356 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
357 .from = 0,
358 .to = 1,
359 .input = "abcdefghijklmnopqrstuvwxyz0123456789_"
360 "abcdefghijklmnopqrstuvwxyz0123456789_"
361 "abcdefghijklmnopqrstuvwxyz0123456789",
362 .expected = "abcdefghijklmnopqrstuvwxyz0123456789_"
363 "abcdefghijklmnopqrstuvwxyz0123456789_"
364 "abcdefghijklmnopqrstuvwxyz0123456789"
365 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"};
366
367constexpr TestCaseReplacement LongString_Begin_MidSizedCut_EmptyRange{
368 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
369 .from = 0,
370 .to = 3,
371 .input = "",
372 .expected = "CDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"};
373
374constexpr TestCaseReplacement LongString_Begin_MidSizedCut_OneElementRange{
375 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
376 .from = 0,
377 .to = 3,
378 .input = "a",
379 .expected = "aCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"};
380
381constexpr TestCaseReplacement LongString_Begin_MidSizedCut_MidRange{
382 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
383 .from = 0,
384 .to = 3,
385 .input = "aeiou",
386 .expected = "aeiouCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"};
387
388constexpr TestCaseReplacement LongString_Begin_MidSizedCut_LongRange{
389 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
390 .from = 0,
391 .to = 3,
392 .input = "abcdefghijklmnopqrstuvwxyz0123456789",
393 .expected = "abcdefghijklmnopqrstuvwxyz0123456789CDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"};
394
395constexpr TestCaseReplacement LongString_Begin_MidSizedCut_LongerThanCapacityRange{
396 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
397 .from = 0,
398 .to = 3,
399 .input = "abcdefghijklmnopqrstuvwxyz0123456789_"
400 "abcdefghijklmnopqrstuvwxyz0123456789_"
401 "abcdefghijklmnopqrstuvwxyz0123456789",
402 .expected = "abcdefghijklmnopqrstuvwxyz0123456789_"
403 "abcdefghijklmnopqrstuvwxyz0123456789_"
404 "abcdefghijklmnopqrstuvwxyz0123456789"
405 "CDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"};
406
407constexpr TestCaseReplacement LongString_Begin_CutToEnd_EmptyRange{
408 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", .from = 0, .to = 38, .input = "", .expected = ""};
409
410constexpr TestCaseReplacement LongString_Begin_CutToEnd_OneElementRange{
411 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", .from = 0, .to = 38, .input = "a", .expected = "a"};
412
413constexpr TestCaseReplacement LongString_Begin_CutToEnd_MidRange{
414 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", .from = 0, .to = 38, .input = "aeiou", .expected = "aeiou"};
415
416constexpr TestCaseReplacement LongString_Begin_CutToEnd_LongRange{
417 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
418 .from = 0,
419 .to = 38,
420 .input = "abcdefghijklmnopqrstuvwxyz0123456789",
421 .expected = "abcdefghijklmnopqrstuvwxyz0123456789"};
422
423constexpr TestCaseReplacement LongString_Begin_CutToEnd_LongerThanCapacityRange{
424 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
425 .from = 0,
426 .to = 38,
427 .input = "abcdefghijklmnopqrstuvwxyz0123456789_"
428 "abcdefghijklmnopqrstuvwxyz0123456789_"
429 "abcdefghijklmnopqrstuvwxyz0123456789",
430 .expected = "abcdefghijklmnopqrstuvwxyz0123456789_"
431 "abcdefghijklmnopqrstuvwxyz0123456789_"
432 "abcdefghijklmnopqrstuvwxyz0123456789"};
433
434// Replace in the middle.
435
436constexpr TestCaseReplacement LongString_Mid_EmptyCut_EmptyRange{
437 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
438 .from = 18,
439 .to = 18,
440 .input = "",
441 .expected = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"};
442
443constexpr TestCaseReplacement LongString_Mid_EmptyCut_OneElementRange{
444 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
445 .from = 18,
446 .to = 18,
447 .input = "a",
448 .expected = "_ABCDEFGHIJKLMNOPQaRSTUVWXYZ0123456789_"};
449
450constexpr TestCaseReplacement LongString_Mid_EmptyCut_MidRange{
451 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
452 .from = 18,
453 .to = 18,
454 .input = "aeiou",
455 .expected = "_ABCDEFGHIJKLMNOPQaeiouRSTUVWXYZ0123456789_"};
456
457constexpr TestCaseReplacement LongString_Mid_EmptyCut_LongRange{
458 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
459 .from = 18,
460 .to = 18,
461 .input = "abcdefghijklmnopqrstuvwxyz0123456789",
462 .expected = "_ABCDEFGHIJKLMNOPQabcdefghijklmnopqrstuvwxyz0123456789RSTUVWXYZ0123456789_"};
463
464constexpr TestCaseReplacement LongString_Mid_EmptyCut_LongerThanCapacityRange{
465 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
466 .from = 18,
467 .to = 18,
468 .input = "abcdefghijklmnopqrstuvwxyz0123456789_"
469 "abcdefghijklmnopqrstuvwxyz0123456789_"
470 "abcdefghijklmnopqrstuvwxyz0123456789",
471 .expected =
472 "_ABCDEFGHIJKLMNOPQ"
473 "abcdefghijklmnopqrstuvwxyz0123456789_"
474 "abcdefghijklmnopqrstuvwxyz0123456789_"
475 "abcdefghijklmnopqrstuvwxyz0123456789"
476 "RSTUVWXYZ0123456789_"};
477
478constexpr TestCaseReplacement LongString_Mid_OneElementCut_EmptyRange{
479 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
480 .from = 18,
481 .to = 19,
482 .input = "",
483 .expected = "_ABCDEFGHIJKLMNOPQSTUVWXYZ0123456789_"};
484
485constexpr TestCaseReplacement LongString_Mid_OneElementCut_OneElementRange{
486 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
487 .from = 18,
488 .to = 19,
489 .input = "a",
490 .expected = "_ABCDEFGHIJKLMNOPQaSTUVWXYZ0123456789_"};
491
492constexpr TestCaseReplacement LongString_Mid_OneElementCut_MidRange{
493 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
494 .from = 18,
495 .to = 19,
496 .input = "aeiou",
497 .expected = "_ABCDEFGHIJKLMNOPQaeiouSTUVWXYZ0123456789_"};
498
499constexpr TestCaseReplacement LongString_Mid_OneElementCut_LongRange{
500 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
501 .from = 18,
502 .to = 19,
503 .input = "abcdefghijklmnopqrstuvwxyz0123456789",
504 .expected = "_ABCDEFGHIJKLMNOPQabcdefghijklmnopqrstuvwxyz0123456789STUVWXYZ0123456789_"};
505
506constexpr TestCaseReplacement LongString_Mid_OneElementCut_LongerThanCapacityRange{
507 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
508 .from = 18,
509 .to = 19,
510 .input = "abcdefghijklmnopqrstuvwxyz0123456789_"
511 "abcdefghijklmnopqrstuvwxyz0123456789_"
512 "abcdefghijklmnopqrstuvwxyz0123456789",
513 .expected =
514 "_ABCDEFGHIJKLMNOPQ"
515 "abcdefghijklmnopqrstuvwxyz0123456789_"
516 "abcdefghijklmnopqrstuvwxyz0123456789_"
517 "abcdefghijklmnopqrstuvwxyz0123456789"
518 "STUVWXYZ0123456789_"};
519
520constexpr TestCaseReplacement LongString_Mid_MidSizedCut_EmptyRange{
521 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
522 .from = 18,
523 .to = 21,
524 .input = "",
525 .expected = "_ABCDEFGHIJKLMNOPQUVWXYZ0123456789_"};
526
527constexpr TestCaseReplacement LongString_Mid_MidSizedCut_OneElementRange{
528 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
529 .from = 18,
530 .to = 21,
531 .input = "a",
532 .expected = "_ABCDEFGHIJKLMNOPQaUVWXYZ0123456789_"};
533
534constexpr TestCaseReplacement LongString_Mid_MidSizedCut_MidRange{
535 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
536 .from = 18,
537 .to = 21,
538 .input = "aeiou",
539 .expected = "_ABCDEFGHIJKLMNOPQaeiouUVWXYZ0123456789_"};
540
541constexpr TestCaseReplacement LongString_Mid_MidSizedCut_LongRange{
542 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
543 .from = 18,
544 .to = 21,
545 .input = "abcdefghijklmnopqrstuvwxyz0123456789",
546 .expected = "_ABCDEFGHIJKLMNOPQabcdefghijklmnopqrstuvwxyz0123456789UVWXYZ0123456789_"};
547
548constexpr TestCaseReplacement LongString_Mid_MidSizedCut_LongerThanCapacityRange{
549 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
550 .from = 18,
551 .to = 21,
552 .input = "abcdefghijklmnopqrstuvwxyz0123456789_"
553 "abcdefghijklmnopqrstuvwxyz0123456789_"
554 "abcdefghijklmnopqrstuvwxyz0123456789",
555 .expected =
556 "_ABCDEFGHIJKLMNOPQ"
557 "abcdefghijklmnopqrstuvwxyz0123456789_"
558 "abcdefghijklmnopqrstuvwxyz0123456789_"
559 "abcdefghijklmnopqrstuvwxyz0123456789"
560 "UVWXYZ0123456789_"};
561
562constexpr TestCaseReplacement LongString_Mid_CutToEnd_EmptyRange{
563 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
564 .from = 18,
565 .to = 38,
566 .input = "",
567 .expected = "_ABCDEFGHIJKLMNOPQ"};
568
569constexpr TestCaseReplacement LongString_Mid_CutToEnd_OneElementRange{
570 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
571 .from = 18,
572 .to = 38,
573 .input = "a",
574 .expected = "_ABCDEFGHIJKLMNOPQa"};
575
576constexpr TestCaseReplacement LongString_Mid_CutToEnd_MidRange{
577 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
578 .from = 18,
579 .to = 38,
580 .input = "aeiou",
581 .expected = "_ABCDEFGHIJKLMNOPQaeiou"};
582
583constexpr TestCaseReplacement LongString_Mid_CutToEnd_LongRange{
584 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
585 .from = 18,
586 .to = 38,
587 .input = "abcdefghijklmnopqrstuvwxyz0123456789",
588 .expected = "_ABCDEFGHIJKLMNOPQabcdefghijklmnopqrstuvwxyz0123456789"};
589
590constexpr TestCaseReplacement LongString_Mid_CutToEnd_LongerThanCapacityRange{
591 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
592 .from = 18,
593 .to = 38,
594 .input = "abcdefghijklmnopqrstuvwxyz0123456789_"
595 "abcdefghijklmnopqrstuvwxyz0123456789_"
596 "abcdefghijklmnopqrstuvwxyz0123456789",
597 .expected = "_ABCDEFGHIJKLMNOPQ"
598 "abcdefghijklmnopqrstuvwxyz0123456789_"
599 "abcdefghijklmnopqrstuvwxyz0123456789_"
600 "abcdefghijklmnopqrstuvwxyz0123456789"};
601
602// Replace at the end.
603
604constexpr TestCaseReplacement LongString_End_EmptyCut_EmptyRange{
605 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
606 .from = 38,
607 .to = 38,
608 .input = "",
609 .expected = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"};
610
611constexpr TestCaseReplacement LongString_End_EmptyCut_OneElementRange{
612 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
613 .from = 38,
614 .to = 38,
615 .input = "a",
616 .expected = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_a"};
617
618constexpr TestCaseReplacement LongString_End_EmptyCut_MidRange{
619 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
620 .from = 38,
621 .to = 38,
622 .input = "aeiou",
623 .expected = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_aeiou"};
624
625constexpr TestCaseReplacement LongString_End_EmptyCut_LongRange{
626 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
627 .from = 38,
628 .to = 38,
629 .input = "abcdefghijklmnopqrstuvwxyz0123456789",
630 .expected = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_abcdefghijklmnopqrstuvwxyz0123456789"};
631
632constexpr TestCaseReplacement LongString_End_EmptyCut_LongerThanCapacityRange{
633 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
634 .from = 38,
635 .to = 38,
636 .input = "abcdefghijklmnopqrstuvwxyz0123456789_"
637 "abcdefghijklmnopqrstuvwxyz0123456789_"
638 "abcdefghijklmnopqrstuvwxyz0123456789",
639 .expected = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"
640 "abcdefghijklmnopqrstuvwxyz0123456789_"
641 "abcdefghijklmnopqrstuvwxyz0123456789_"
642 "abcdefghijklmnopqrstuvwxyz0123456789"};
643
644template <class Iter, class Sent, class Alloc>
645constexpr void test_string_replace_with_range() {
646 auto test = [&](const TestCaseReplacement& test_case) {
647 using Container = std::basic_string<char, std::char_traits<char>, Alloc>;
648
649 auto get_pos = [](auto& c, auto index) { return std::ranges::next(c.begin(), index); };
650 Container c(test_case.initial.begin(), test_case.initial.end());
651 auto in = wrap_input<Iter, Sent>(test_case.input);
652 auto from = get_pos(c, test_case.from);
653 auto to = get_pos(c, test_case.to);
654
655 Container& result = c.replace_with_range(from, to, in);
656 assert(&result == &c);
657 LIBCPP_ASSERT(c.__invariants());
658 return std::ranges::equal(c, test_case.expected);
659 };
660
661 { // Empty string.
662 // empty_str.replace_with_range(end, end, empty_range)
663 assert(test(EmptyString_End_EmptyCut_EmptyRange));
664 // empty_str.replace_with_range(end, end, one_element_range)
665 assert(test(EmptyString_End_EmptyCut_OneElementRange));
666 // empty_str.replace_with_range(end, end, mid_range)
667 assert(test(EmptyString_End_EmptyCut_MidRange));
668 // empty_str.replace_with_range(end, end, long_range)
669 assert(test(EmptyString_End_EmptyCut_LongRange));
670 }
671
672 { // One-element string.
673 // one_element_str.replace_with_range(begin, begin, empty_range)
674 assert(test(OneElementString_Begin_EmptyCut_EmptyRange));
675 // one_element_str.replace_with_range(begin, begin, one_element_range)
676 assert(test(OneElementString_Begin_EmptyCut_OneElementRange));
677 // one_element_str.replace_with_range(begin, begin, mid_range)
678 assert(test(OneElementString_Begin_EmptyCut_MidRange));
679 // one_element_str.replace_with_range(begin, begin, long_range)
680 assert(test(OneElementString_Begin_EmptyCut_LongRange));
681 // one_element_str.replace_with_range(begin, begin + 1, empty_range)
682 assert(test(OneElementString_Begin_OneElementCut_EmptyRange));
683 // one_element_str.replace_with_range(begin, begin + 1, one_element_range)
684 assert(test(OneElementString_Begin_OneElementCut_OneElementRange));
685 // one_element_str.replace_with_range(begin, begin + 1, mid_range)
686 assert(test(OneElementString_Begin_OneElementCut_MidRange));
687 // one_element_str.replace_with_range(begin, begin + 1, long_range)
688 assert(test(OneElementString_Begin_OneElementCut_LongRange));
689 // one_element_str.replace_with_range(end, end, empty_range)
690 assert(test(OneElementString_End_EmptyCut_EmptyRange));
691 // one_element_str.replace_with_range(end, end, one_element_range)
692 assert(test(OneElementString_End_EmptyCut_OneElementRange));
693 // one_element_str.replace_with_range(end, end, mid_range)
694 assert(test(OneElementString_End_EmptyCut_MidRange));
695 // one_element_str.replace_with_range(end, end, long_range)
696 assert(test(OneElementString_End_EmptyCut_LongRange));
697 }
698
699 { // Short string.
700 // Replace at the beginning.
701
702 // short_str.replace_with_range(begin, begin, empty_range)
703 assert(test(ShortString_Begin_EmptyCut_EmptyRange));
704 // short_str.replace_with_range(begin, begin, one_element_range)
705 assert(test(ShortString_Begin_EmptyCut_OneElementRange));
706 // short_str.replace_with_range(begin, begin, mid_range)
707 assert(test(ShortString_Begin_EmptyCut_MidRange));
708 // short_str.replace_with_range(begin, begin, long_range)
709 assert(test(ShortString_Begin_EmptyCut_LongRange));
710 // short_str.replace_with_range(begin, begin + 1, empty_range)
711 assert(test(ShortString_Begin_OneElementCut_EmptyRange));
712 // short_str.replace_with_range(begin, begin + 1, one_element_range)
713 assert(test(ShortString_Begin_OneElementCut_OneElementRange));
714 // short_str.replace_with_range(begin, begin + 1, mid_range)
715 assert(test(ShortString_Begin_OneElementCut_MidRange));
716 // short_str.replace_with_range(begin, begin + 1, long_range)
717 assert(test(ShortString_Begin_OneElementCut_LongRange));
718 // short_str.replace_with_range(begin, begin + 3, empty_range)
719 assert(test(ShortString_Begin_MidSizedCut_EmptyRange));
720 // short_str.replace_with_range(begin, begin + 3, one_element_range)
721 assert(test(ShortString_Begin_MidSizedCut_OneElementRange));
722 // short_str.replace_with_range(begin, begin + 3, mid_range)
723 assert(test(ShortString_Begin_MidSizedCut_MidRange));
724 // short_str.replace_with_range(begin, begin + 3, long_range)
725 assert(test(ShortString_Begin_MidSizedCut_LongRange));
726 // short_str.replace_with_range(begin, end, empty_range)
727 assert(test(ShortString_Begin_CutToEnd_EmptyRange));
728 // short_str.replace_with_range(begin, end, one_element_range)
729 assert(test(ShortString_Begin_CutToEnd_OneElementRange));
730 // short_str.replace_with_range(begin, end, mid_range)
731 assert(test(ShortString_Begin_CutToEnd_MidRange));
732 // short_str.replace_with_range(begin, end, long_range)
733 assert(test(ShortString_Begin_CutToEnd_LongRange));
734
735 // Replace in the middle.
736
737 // short_str.replace_with_range(mid, mid, empty_range)
738 assert(test(ShortString_Mid_EmptyCut_EmptyRange));
739 // short_str.replace_with_range(mid, mid, one_element_range)
740 assert(test(ShortString_Mid_EmptyCut_OneElementRange));
741 // short_str.replace_with_range(mid, mid, mid_range)
742 assert(test(ShortString_Mid_EmptyCut_MidRange));
743 // short_str.replace_with_range(mid, mid, long_range)
744 assert(test(ShortString_Mid_EmptyCut_LongRange));
745 // short_str.replace_with_range(mid, mid + 1, empty_range)
746 assert(test(ShortString_Mid_OneElementCut_EmptyRange));
747 // short_str.replace_with_range(mid, mid + 1, one_element_range)
748 assert(test(ShortString_Mid_OneElementCut_OneElementRange));
749 // short_str.replace_with_range(mid, mid + 1, mid_range)
750 assert(test(ShortString_Mid_OneElementCut_MidRange));
751 // short_str.replace_with_range(mid, mid + 1, long_range)
752 assert(test(ShortString_Mid_OneElementCut_LongRange));
753 // short_str.replace_with_range(mid, mid + 3, empty_range)
754 assert(test(ShortString_Mid_MidSizedCut_EmptyRange));
755 // short_str.replace_with_range(mid, mid + 3, one_element_range)
756 assert(test(ShortString_Mid_MidSizedCut_OneElementRange));
757 // short_str.replace_with_range(mid, mid + 3, mid_range)
758 assert(test(ShortString_Mid_MidSizedCut_MidRange));
759 // short_str.replace_with_range(mid, mid + 3, long_range)
760 assert(test(ShortString_Mid_MidSizedCut_LongRange));
761 // short_str.replace_with_range(mid, end, empty_range)
762 assert(test(ShortString_Mid_CutToEnd_EmptyRange));
763 // short_str.replace_with_range(mid, end, one_element_range)
764 assert(test(ShortString_Mid_CutToEnd_OneElementRange));
765 // short_str.replace_with_range(mid, end, mid_range)
766 assert(test(ShortString_Mid_CutToEnd_MidRange));
767 // short_str.replace_with_range(mid, end, long_range)
768 assert(test(ShortString_Mid_CutToEnd_LongRange));
769
770 // Replace at the end.
771
772 // short_str.replace_with_range(end, end, empty_range)
773 assert(test(ShortString_End_EmptyCut_EmptyRange));
774 // short_str.replace_with_range(end, end, one_element_range)
775 assert(test(ShortString_End_EmptyCut_OneElementRange));
776 // short_str.replace_with_range(end, end, mid_range)
777 assert(test(ShortString_End_EmptyCut_MidRange));
778 // short_str.replace_with_range(end, end, long_range)
779 assert(test(ShortString_End_EmptyCut_LongRange));
780 }
781
782 { // Long string.
783 // Replace at the beginning.
784
785 // long_str.replace_with_range(begin, begin, empty_range)
786 assert(test(LongString_Begin_EmptyCut_EmptyRange));
787 // long_str.replace_with_range(begin, begin, one_element_range)
788 assert(test(LongString_Begin_EmptyCut_OneElementRange));
789 // long_str.replace_with_range(begin, begin, mid_range)
790 assert(test(LongString_Begin_EmptyCut_MidRange));
791 // long_str.replace_with_range(begin, begin, long_range)
792 assert(test(LongString_Begin_EmptyCut_LongRange));
793 // long_str.replace_with_range(begin, begin, longer_than_capacity_range)
794 assert(test(LongString_Begin_EmptyCut_LongerThanCapacityRange));
795 // long_str.replace_with_range(begin, begin + 1, empty_range)
796 assert(test(LongString_Begin_OneElementCut_EmptyRange));
797 // long_str.replace_with_range(begin, begin + 1, one_element_range)
798 assert(test(LongString_Begin_OneElementCut_OneElementRange));
799 // long_str.replace_with_range(begin, begin + 1, mid_range)
800 assert(test(LongString_Begin_OneElementCut_MidRange));
801 // long_str.replace_with_range(begin, begin + 1, long_range)
802 assert(test(LongString_Begin_OneElementCut_LongRange));
803 // long_str.replace_with_range(begin, begin + 1, longer_than_capacity_range)
804 assert(test(LongString_Begin_OneElementCut_LongerThanCapacityRange));
805 // long_str.replace_with_range(begin, begin + 3, empty_range)
806 assert(test(LongString_Begin_MidSizedCut_EmptyRange));
807 // long_str.replace_with_range(begin, begin + 3, one_element_range)
808 assert(test(LongString_Begin_MidSizedCut_OneElementRange));
809 // long_str.replace_with_range(begin, begin + 3, mid_range)
810 assert(test(LongString_Begin_MidSizedCut_MidRange));
811 // long_str.replace_with_range(begin, begin + 3, long_range)
812 assert(test(LongString_Begin_MidSizedCut_LongRange));
813 // long_str.replace_with_range(begin, begin + 3, longer_than_capacity_range)
814 assert(test(LongString_Begin_MidSizedCut_LongerThanCapacityRange));
815 // long_str.replace_with_range(begin, end, empty_range)
816 assert(test(LongString_Begin_CutToEnd_EmptyRange));
817 // long_str.replace_with_range(begin, end, one_element_range)
818 assert(test(LongString_Begin_CutToEnd_OneElementRange));
819 // long_str.replace_with_range(begin, end, mid_range)
820 assert(test(LongString_Begin_CutToEnd_MidRange));
821 // long_str.replace_with_range(begin, end, long_range)
822 assert(test(LongString_Begin_CutToEnd_LongRange));
823 // long_str.replace_with_range(begin, end, longer_than_capacity_range)
824 assert(test(LongString_Begin_CutToEnd_LongerThanCapacityRange));
825
826 // Replace in the middle.
827
828 // long_str.replace_with_range(mid, mid, empty_range)
829 assert(test(LongString_Mid_EmptyCut_EmptyRange));
830 // long_str.replace_with_range(mid, mid, one_element_range)
831 assert(test(LongString_Mid_EmptyCut_OneElementRange));
832 // long_str.replace_with_range(mid, mid, mid_range)
833 assert(test(LongString_Mid_EmptyCut_MidRange));
834 // long_str.replace_with_range(mid, mid, long_range)
835 assert(test(LongString_Mid_EmptyCut_LongRange));
836 // long_str.replace_with_range(mid, mid, longer_than_capacity_range)
837 assert(test(LongString_Mid_EmptyCut_LongerThanCapacityRange));
838 // long_str.replace_with_range(mid, mid + 1, empty_range)
839 assert(test(LongString_Mid_OneElementCut_EmptyRange));
840 // long_str.replace_with_range(mid, mid + 1, one_element_range)
841 assert(test(LongString_Mid_OneElementCut_OneElementRange));
842 // long_str.replace_with_range(mid, mid + 1, mid_range)
843 assert(test(LongString_Mid_OneElementCut_MidRange));
844 // long_str.replace_with_range(mid, mid + 1, long_range)
845 assert(test(LongString_Mid_OneElementCut_LongRange));
846 // long_str.replace_with_range(mid, mid + 1, longer_than_capacity_range)
847 assert(test(LongString_Mid_OneElementCut_LongerThanCapacityRange));
848 // long_str.replace_with_range(mid, mid + 3, empty_range)
849 assert(test(LongString_Mid_MidSizedCut_EmptyRange));
850 // long_str.replace_with_range(mid, mid + 3, one_element_range)
851 assert(test(LongString_Mid_MidSizedCut_OneElementRange));
852 // long_str.replace_with_range(mid, mid + 3, mid_range)
853 assert(test(LongString_Mid_MidSizedCut_MidRange));
854 // long_str.replace_with_range(mid, mid + 3, long_range)
855 assert(test(LongString_Mid_MidSizedCut_LongRange));
856 // long_str.replace_with_range(mid, mid + 3, longer_than_capacity_range)
857 assert(test(LongString_Mid_MidSizedCut_LongerThanCapacityRange));
858 // long_str.replace_with_range(mid, end, empty_range)
859 assert(test(LongString_Mid_CutToEnd_EmptyRange));
860 // long_str.replace_with_range(mid, end, one_element_range)
861 assert(test(LongString_Mid_CutToEnd_OneElementRange));
862 // long_str.replace_with_range(mid, end, mid_range)
863 assert(test(LongString_Mid_CutToEnd_MidRange));
864 // long_str.replace_with_range(mid, end, long_range)
865 assert(test(LongString_Mid_CutToEnd_LongRange));
866 // long_str.replace_with_range(mid, end, longer_than_capacity_range)
867 assert(test(LongString_Mid_CutToEnd_LongerThanCapacityRange));
868
869 // Replace at the end.
870
871 // long_str.replace_with_range(end, end, empty_range)
872 assert(test(LongString_End_EmptyCut_EmptyRange));
873 // long_str.replace_with_range(end, end, one_element_range)
874 assert(test(LongString_End_EmptyCut_OneElementRange));
875 // long_str.replace_with_range(end, end, mid_range)
876 assert(test(LongString_End_EmptyCut_MidRange));
877 // long_str.replace_with_range(end, end, long_range)
878 assert(test(LongString_End_EmptyCut_LongRange));
879 // long_str.replace_with_range(end, end, longer_than_capacity_range)
880 assert(test(LongString_End_EmptyCut_LongerThanCapacityRange));
881 }
882}
883
884constexpr void test_string_replace_with_range_rvalue_range() {
885 // Make sure that the input range can be passed by both an lvalue and an rvalue reference and regardless of constness.
886
887 { // Lvalue.
888 std::string in = "abc";
889 std::string c = "123";
890 c.replace_with_range(c.begin(), c.end(), in);
891 }
892
893 { // Const lvalue.
894 const std::string in = "abc";
895 std::string c = "123";
896 c.replace_with_range(c.begin(), c.end(), in);
897 }
898
899 { // Rvalue.
900 std::string in = "abc";
901 std::string c = "123";
902 c.replace_with_range(c.begin(), c.end(), std::move(in));
903 }
904
905 { // Const rvalue.
906 const std::string in = "abc";
907 std::string c = "123";
908 c.replace_with_range(c.begin(), c.end(), std::move(in));
909 }
910}
911
912constexpr bool test_constexpr() {
913 for_all_iterators_and_allocators_constexpr<char, const char*>(f: []<class Iter, class Sent, class Alloc>() {
914 test_string_replace_with_range<Iter, Sent, Alloc>();
915 });
916 test_string_replace_with_range_rvalue_range();
917
918 return true;
919}
920
921// Tested cases:
922// - different kinds of replacements (varying the size of the initial string, the cut point and the cut size, and the
923// size of the input range);
924// - an exception is thrown when allocating new elements.
925int main(int, char**) {
926 static_assert(test_constraints_replace_with_range());
927
928 for_all_iterators_and_allocators<char, const char*>(f: []<class Iter, class Sent, class Alloc>() {
929 test_string_replace_with_range<Iter, Sent, Alloc>();
930 });
931 test_string_replace_with_range_rvalue_range();
932 static_assert(test_constexpr());
933
934 // Note: `test_string_replace_with_range_exception_safety_throwing_copy` doesn't apply because copying chars cannot
935 // throw.
936 {
937#if !defined(TEST_HAS_NO_EXCEPTIONS)
938 // Note: the input string must be long enough to prevent SSO, otherwise the allocator won't be used.
939 std::string in(64, 'a');
940
941 try {
942 ThrowingAllocator<char> alloc;
943
944 globalMemCounter.reset();
945 std::basic_string<char, std::char_traits<char>, ThrowingAllocator<char>> c(alloc);
946 c.replace_with_range(c.end(), c.end(), in);
947 assert(false); // The function call above should throw.
948
949 } catch (int) {
950 assert(globalMemCounter.new_called == globalMemCounter.delete_called);
951 }
952#endif
953 }
954
955 return 0;
956}
957

source code of libcxx/test/std/strings/basic.string/string.modifiers/string_replace/replace_with_range.pass.cpp