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 26 template <class Range> 27 concept HasReplaceWithRange = 28 requires(std::string& c, Range&& range) { c.replace_with_range(c.end(), c.end(), std::forward<Range>(range)); }; 29 30 constexpr 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 45 using StrBuffer = Buffer<char, 256>; 46 47 struct 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 63 constexpr TestCaseReplacement EmptyString_End_EmptyCut_EmptyRange{ 64 .initial = "", .from = 0, .to = 0, .input = "", .expected = ""}; 65 66 constexpr TestCaseReplacement EmptyString_End_EmptyCut_OneElementRange{ 67 .initial = "", .from = 0, .to = 0, .input = "a", .expected = "a"}; 68 69 constexpr TestCaseReplacement EmptyString_End_EmptyCut_MidRange{ 70 .initial = "", .from = 0, .to = 0, .input = "aeiou", .expected = "aeiou"}; 71 72 constexpr 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 81 constexpr TestCaseReplacement OneElementString_Begin_EmptyCut_EmptyRange{ 82 .initial = "B", .from = 0, .to = 0, .input = "", .expected = "B"}; 83 84 constexpr TestCaseReplacement OneElementString_Begin_EmptyCut_OneElementRange{ 85 .initial = "B", .from = 0, .to = 0, .input = "a", .expected = "aB"}; 86 87 constexpr TestCaseReplacement OneElementString_Begin_EmptyCut_MidRange{ 88 .initial = "B", .from = 0, .to = 0, .input = "aeiou", .expected = "aeiouB"}; 89 90 constexpr TestCaseReplacement OneElementString_Begin_EmptyCut_LongRange{ 91 .initial = "B", 92 .from = 0, 93 .to = 0, 94 .input = "abcdefghijklmnopqrstuvwxyz0123456789", 95 .expected = "abcdefghijklmnopqrstuvwxyz0123456789B"}; 96 97 constexpr TestCaseReplacement OneElementString_Begin_OneElementCut_EmptyRange{ 98 .initial = "B", .from = 0, .to = 1, .input = "", .expected = ""}; 99 100 constexpr TestCaseReplacement OneElementString_Begin_OneElementCut_OneElementRange{ 101 .initial = "B", .from = 0, .to = 1, .input = "a", .expected = "a"}; 102 103 constexpr TestCaseReplacement OneElementString_Begin_OneElementCut_MidRange{ 104 .initial = "B", .from = 0, .to = 1, .input = "aeiou", .expected = "aeiou"}; 105 106 constexpr TestCaseReplacement OneElementString_Begin_OneElementCut_LongRange{ 107 .initial = "B", 108 .from = 0, 109 .to = 1, 110 .input = "abcdefghijklmnopqrstuvwxyz0123456789", 111 .expected = "abcdefghijklmnopqrstuvwxyz0123456789"}; 112 113 constexpr TestCaseReplacement OneElementString_End_EmptyCut_EmptyRange{ 114 .initial = "B", .from = 1, .to = 1, .input = "", .expected = "B"}; 115 116 constexpr TestCaseReplacement OneElementString_End_EmptyCut_OneElementRange{ 117 .initial = "B", .from = 1, .to = 1, .input = "a", .expected = "Ba"}; 118 119 constexpr TestCaseReplacement OneElementString_End_EmptyCut_MidRange{ 120 .initial = "B", .from = 1, .to = 1, .input = "aeiou", .expected = "Baeiou"}; 121 122 constexpr 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 133 constexpr TestCaseReplacement ShortString_Begin_EmptyCut_EmptyRange{ 134 .initial = "_BCDFGHJ_", .from = 0, .to = 0, .input = "", .expected = "_BCDFGHJ_"}; 135 136 constexpr TestCaseReplacement ShortString_Begin_EmptyCut_OneElementRange{ 137 .initial = "_BCDFGHJ_", .from = 0, .to = 0, .input = "a", .expected = "a_BCDFGHJ_"}; 138 139 constexpr TestCaseReplacement ShortString_Begin_EmptyCut_MidRange{ 140 .initial = "_BCDFGHJ_", .from = 0, .to = 0, .input = "aeiou", .expected = "aeiou_BCDFGHJ_"}; 141 142 constexpr TestCaseReplacement ShortString_Begin_EmptyCut_LongRange{ 143 .initial = "_BCDFGHJ_", 144 .from = 0, 145 .to = 0, 146 .input = "abcdefghijklmnopqrstuvwxyz0123456789", 147 .expected = "abcdefghijklmnopqrstuvwxyz0123456789_BCDFGHJ_"}; 148 149 constexpr TestCaseReplacement ShortString_Begin_OneElementCut_EmptyRange{ 150 .initial = "_BCDFGHJ_", .from = 0, .to = 1, .input = "", .expected = "BCDFGHJ_"}; 151 152 constexpr TestCaseReplacement ShortString_Begin_OneElementCut_OneElementRange{ 153 .initial = "_BCDFGHJ_", .from = 0, .to = 1, .input = "a", .expected = "aBCDFGHJ_"}; 154 155 constexpr TestCaseReplacement ShortString_Begin_OneElementCut_MidRange{ 156 .initial = "_BCDFGHJ_", .from = 0, .to = 1, .input = "aeiou", .expected = "aeiouBCDFGHJ_"}; 157 158 constexpr TestCaseReplacement ShortString_Begin_OneElementCut_LongRange{ 159 .initial = "_BCDFGHJ_", 160 .from = 0, 161 .to = 1, 162 .input = "abcdefghijklmnopqrstuvwxyz0123456789", 163 .expected = "abcdefghijklmnopqrstuvwxyz0123456789BCDFGHJ_"}; 164 165 constexpr TestCaseReplacement ShortString_Begin_MidSizedCut_EmptyRange{ 166 .initial = "_BCDFGHJ_", .from = 0, .to = 3, .input = "", .expected = "DFGHJ_"}; 167 168 constexpr TestCaseReplacement ShortString_Begin_MidSizedCut_OneElementRange{ 169 .initial = "_BCDFGHJ_", .from = 0, .to = 3, .input = "a", .expected = "aDFGHJ_"}; 170 171 constexpr 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. 175 constexpr TestCaseReplacement ShortString_Begin_MidSizedCut_LongRange{ 176 .initial = "_BCDFGHJ_", 177 .from = 0, 178 .to = 3, 179 .input = "abcdefghijklmnopqrstuvwxyz0123456789", 180 .expected = "abcdefghijklmnopqrstuvwxyz0123456789DFGHJ_"}; 181 182 constexpr TestCaseReplacement ShortString_Begin_CutToEnd_EmptyRange{ 183 .initial = "_BCDFGHJ_", .from = 0, .to = 9, .input = "", .expected = ""}; 184 185 constexpr TestCaseReplacement ShortString_Begin_CutToEnd_OneElementRange{ 186 .initial = "_BCDFGHJ_", .from = 0, .to = 9, .input = "a", .expected = "a"}; 187 188 constexpr 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. 192 constexpr 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 201 constexpr TestCaseReplacement ShortString_Mid_EmptyCut_EmptyRange{ 202 .initial = "_BCDFGHJ_", .from = 4, .to = 4, .input = "", .expected = "_BCDFGHJ_"}; 203 204 constexpr TestCaseReplacement ShortString_Mid_EmptyCut_OneElementRange{ 205 .initial = "_BCDFGHJ_", .from = 4, .to = 4, .input = "a", .expected = "_BCDaFGHJ_"}; 206 207 constexpr TestCaseReplacement ShortString_Mid_EmptyCut_MidRange{ 208 .initial = "_BCDFGHJ_", .from = 4, .to = 4, .input = "aeiou", .expected = "_BCDaeiouFGHJ_"}; 209 210 constexpr TestCaseReplacement ShortString_Mid_EmptyCut_LongRange{ 211 .initial = "_BCDFGHJ_", 212 .from = 4, 213 .to = 4, 214 .input = "abcdefghijklmnopqrstuvwxyz0123456789", 215 .expected = "_BCDabcdefghijklmnopqrstuvwxyz0123456789FGHJ_"}; 216 217 constexpr TestCaseReplacement ShortString_Mid_OneElementCut_EmptyRange{ 218 .initial = "_BCDFGHJ_", .from = 4, .to = 5, .input = "", .expected = "_BCDGHJ_"}; 219 220 constexpr TestCaseReplacement ShortString_Mid_OneElementCut_OneElementRange{ 221 .initial = "_BCDFGHJ_", .from = 4, .to = 5, .input = "a", .expected = "_BCDaGHJ_"}; 222 223 constexpr TestCaseReplacement ShortString_Mid_OneElementCut_MidRange{ 224 .initial = "_BCDFGHJ_", .from = 4, .to = 5, .input = "aeiou", .expected = "_BCDaeiouGHJ_"}; 225 226 constexpr TestCaseReplacement ShortString_Mid_OneElementCut_LongRange{ 227 .initial = "_BCDFGHJ_", 228 .from = 4, 229 .to = 5, 230 .input = "abcdefghijklmnopqrstuvwxyz0123456789", 231 .expected = "_BCDabcdefghijklmnopqrstuvwxyz0123456789GHJ_"}; 232 233 constexpr TestCaseReplacement ShortString_Mid_MidSizedCut_EmptyRange{ 234 .initial = "_BCDFGHJ_", .from = 4, .to = 7, .input = "", .expected = "_BCDJ_"}; 235 236 constexpr TestCaseReplacement ShortString_Mid_MidSizedCut_OneElementRange{ 237 .initial = "_BCDFGHJ_", .from = 4, .to = 7, .input = "a", .expected = "_BCDaJ_"}; 238 239 constexpr TestCaseReplacement ShortString_Mid_MidSizedCut_MidRange{ 240 .initial = "_BCDFGHJ_", .from = 4, .to = 7, .input = "aeiou", .expected = "_BCDaeiouJ_"}; 241 242 constexpr TestCaseReplacement ShortString_Mid_MidSizedCut_LongRange{ 243 .initial = "_BCDFGHJ_", 244 .from = 4, 245 .to = 7, 246 .input = "abcdefghijklmnopqrstuvwxyz0123456789", 247 .expected = "_BCDabcdefghijklmnopqrstuvwxyz0123456789J_"}; 248 249 constexpr TestCaseReplacement ShortString_Mid_CutToEnd_EmptyRange{ 250 .initial = "_BCDFGHJ_", .from = 4, .to = 9, .input = "", .expected = "_BCD"}; 251 252 constexpr TestCaseReplacement ShortString_Mid_CutToEnd_OneElementRange{ 253 .initial = "_BCDFGHJ_", .from = 4, .to = 9, .input = "a", .expected = "_BCDa"}; 254 255 constexpr TestCaseReplacement ShortString_Mid_CutToEnd_MidRange{ 256 .initial = "_BCDFGHJ_", .from = 4, .to = 9, .input = "aeiou", .expected = "_BCDaeiou"}; 257 258 constexpr 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 267 constexpr TestCaseReplacement ShortString_End_EmptyCut_EmptyRange{ 268 .initial = "_BCDFGHJ_", .from = 9, .to = 9, .input = "", .expected = "_BCDFGHJ_"}; 269 270 constexpr TestCaseReplacement ShortString_End_EmptyCut_OneElementRange{ 271 .initial = "_BCDFGHJ_", .from = 9, .to = 9, .input = "a", .expected = "_BCDFGHJ_a"}; 272 273 constexpr TestCaseReplacement ShortString_End_EmptyCut_MidRange{ 274 .initial = "_BCDFGHJ_", .from = 9, .to = 9, .input = "aeiou", .expected = "_BCDFGHJ_aeiou"}; 275 276 constexpr 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 287 constexpr TestCaseReplacement LongString_Begin_EmptyCut_EmptyRange{ 288 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 289 .from = 0, 290 .to = 0, 291 .input = "", 292 .expected = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"}; 293 294 constexpr TestCaseReplacement LongString_Begin_EmptyCut_OneElementRange{ 295 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 296 .from = 0, 297 .to = 0, 298 .input = "a", 299 .expected = "a_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"}; 300 301 constexpr TestCaseReplacement LongString_Begin_EmptyCut_MidRange{ 302 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 303 .from = 0, 304 .to = 0, 305 .input = "aeiou", 306 .expected = "aeiou_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"}; 307 308 constexpr TestCaseReplacement LongString_Begin_EmptyCut_LongRange{ 309 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 310 .from = 0, 311 .to = 0, 312 .input = "abcdefghijklmnopqrstuvwxyz0123456789", 313 .expected = "abcdefghijklmnopqrstuvwxyz0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"}; 314 315 constexpr 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 327 constexpr TestCaseReplacement LongString_Begin_OneElementCut_EmptyRange{ 328 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 329 .from = 0, 330 .to = 1, 331 .input = "", 332 .expected = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"}; 333 334 constexpr TestCaseReplacement LongString_Begin_OneElementCut_OneElementRange{ 335 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 336 .from = 0, 337 .to = 1, 338 .input = "a", 339 .expected = "aABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"}; 340 341 constexpr TestCaseReplacement LongString_Begin_OneElementCut_MidRange{ 342 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 343 .from = 0, 344 .to = 1, 345 .input = "aeiou", 346 .expected = "aeiouABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"}; 347 348 constexpr TestCaseReplacement LongString_Begin_OneElementCut_LongRange{ 349 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 350 .from = 0, 351 .to = 1, 352 .input = "abcdefghijklmnopqrstuvwxyz0123456789", 353 .expected = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"}; 354 355 constexpr 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 367 constexpr TestCaseReplacement LongString_Begin_MidSizedCut_EmptyRange{ 368 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 369 .from = 0, 370 .to = 3, 371 .input = "", 372 .expected = "CDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"}; 373 374 constexpr TestCaseReplacement LongString_Begin_MidSizedCut_OneElementRange{ 375 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 376 .from = 0, 377 .to = 3, 378 .input = "a", 379 .expected = "aCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"}; 380 381 constexpr TestCaseReplacement LongString_Begin_MidSizedCut_MidRange{ 382 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 383 .from = 0, 384 .to = 3, 385 .input = "aeiou", 386 .expected = "aeiouCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"}; 387 388 constexpr TestCaseReplacement LongString_Begin_MidSizedCut_LongRange{ 389 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 390 .from = 0, 391 .to = 3, 392 .input = "abcdefghijklmnopqrstuvwxyz0123456789", 393 .expected = "abcdefghijklmnopqrstuvwxyz0123456789CDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"}; 394 395 constexpr 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 407 constexpr TestCaseReplacement LongString_Begin_CutToEnd_EmptyRange{ 408 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", .from = 0, .to = 38, .input = "", .expected = ""}; 409 410 constexpr TestCaseReplacement LongString_Begin_CutToEnd_OneElementRange{ 411 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", .from = 0, .to = 38, .input = "a", .expected = "a"}; 412 413 constexpr TestCaseReplacement LongString_Begin_CutToEnd_MidRange{ 414 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", .from = 0, .to = 38, .input = "aeiou", .expected = "aeiou"}; 415 416 constexpr TestCaseReplacement LongString_Begin_CutToEnd_LongRange{ 417 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 418 .from = 0, 419 .to = 38, 420 .input = "abcdefghijklmnopqrstuvwxyz0123456789", 421 .expected = "abcdefghijklmnopqrstuvwxyz0123456789"}; 422 423 constexpr 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 436 constexpr TestCaseReplacement LongString_Mid_EmptyCut_EmptyRange{ 437 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 438 .from = 18, 439 .to = 18, 440 .input = "", 441 .expected = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"}; 442 443 constexpr TestCaseReplacement LongString_Mid_EmptyCut_OneElementRange{ 444 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 445 .from = 18, 446 .to = 18, 447 .input = "a", 448 .expected = "_ABCDEFGHIJKLMNOPQaRSTUVWXYZ0123456789_"}; 449 450 constexpr TestCaseReplacement LongString_Mid_EmptyCut_MidRange{ 451 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 452 .from = 18, 453 .to = 18, 454 .input = "aeiou", 455 .expected = "_ABCDEFGHIJKLMNOPQaeiouRSTUVWXYZ0123456789_"}; 456 457 constexpr TestCaseReplacement LongString_Mid_EmptyCut_LongRange{ 458 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 459 .from = 18, 460 .to = 18, 461 .input = "abcdefghijklmnopqrstuvwxyz0123456789", 462 .expected = "_ABCDEFGHIJKLMNOPQabcdefghijklmnopqrstuvwxyz0123456789RSTUVWXYZ0123456789_"}; 463 464 constexpr 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 478 constexpr TestCaseReplacement LongString_Mid_OneElementCut_EmptyRange{ 479 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 480 .from = 18, 481 .to = 19, 482 .input = "", 483 .expected = "_ABCDEFGHIJKLMNOPQSTUVWXYZ0123456789_"}; 484 485 constexpr TestCaseReplacement LongString_Mid_OneElementCut_OneElementRange{ 486 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 487 .from = 18, 488 .to = 19, 489 .input = "a", 490 .expected = "_ABCDEFGHIJKLMNOPQaSTUVWXYZ0123456789_"}; 491 492 constexpr TestCaseReplacement LongString_Mid_OneElementCut_MidRange{ 493 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 494 .from = 18, 495 .to = 19, 496 .input = "aeiou", 497 .expected = "_ABCDEFGHIJKLMNOPQaeiouSTUVWXYZ0123456789_"}; 498 499 constexpr TestCaseReplacement LongString_Mid_OneElementCut_LongRange{ 500 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 501 .from = 18, 502 .to = 19, 503 .input = "abcdefghijklmnopqrstuvwxyz0123456789", 504 .expected = "_ABCDEFGHIJKLMNOPQabcdefghijklmnopqrstuvwxyz0123456789STUVWXYZ0123456789_"}; 505 506 constexpr 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 520 constexpr TestCaseReplacement LongString_Mid_MidSizedCut_EmptyRange{ 521 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 522 .from = 18, 523 .to = 21, 524 .input = "", 525 .expected = "_ABCDEFGHIJKLMNOPQUVWXYZ0123456789_"}; 526 527 constexpr TestCaseReplacement LongString_Mid_MidSizedCut_OneElementRange{ 528 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 529 .from = 18, 530 .to = 21, 531 .input = "a", 532 .expected = "_ABCDEFGHIJKLMNOPQaUVWXYZ0123456789_"}; 533 534 constexpr TestCaseReplacement LongString_Mid_MidSizedCut_MidRange{ 535 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 536 .from = 18, 537 .to = 21, 538 .input = "aeiou", 539 .expected = "_ABCDEFGHIJKLMNOPQaeiouUVWXYZ0123456789_"}; 540 541 constexpr TestCaseReplacement LongString_Mid_MidSizedCut_LongRange{ 542 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 543 .from = 18, 544 .to = 21, 545 .input = "abcdefghijklmnopqrstuvwxyz0123456789", 546 .expected = "_ABCDEFGHIJKLMNOPQabcdefghijklmnopqrstuvwxyz0123456789UVWXYZ0123456789_"}; 547 548 constexpr 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 562 constexpr TestCaseReplacement LongString_Mid_CutToEnd_EmptyRange{ 563 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 564 .from = 18, 565 .to = 38, 566 .input = "", 567 .expected = "_ABCDEFGHIJKLMNOPQ"}; 568 569 constexpr TestCaseReplacement LongString_Mid_CutToEnd_OneElementRange{ 570 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 571 .from = 18, 572 .to = 38, 573 .input = "a", 574 .expected = "_ABCDEFGHIJKLMNOPQa"}; 575 576 constexpr TestCaseReplacement LongString_Mid_CutToEnd_MidRange{ 577 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 578 .from = 18, 579 .to = 38, 580 .input = "aeiou", 581 .expected = "_ABCDEFGHIJKLMNOPQaeiou"}; 582 583 constexpr TestCaseReplacement LongString_Mid_CutToEnd_LongRange{ 584 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 585 .from = 18, 586 .to = 38, 587 .input = "abcdefghijklmnopqrstuvwxyz0123456789", 588 .expected = "_ABCDEFGHIJKLMNOPQabcdefghijklmnopqrstuvwxyz0123456789"}; 589 590 constexpr 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 604 constexpr TestCaseReplacement LongString_End_EmptyCut_EmptyRange{ 605 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 606 .from = 38, 607 .to = 38, 608 .input = "", 609 .expected = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"}; 610 611 constexpr TestCaseReplacement LongString_End_EmptyCut_OneElementRange{ 612 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 613 .from = 38, 614 .to = 38, 615 .input = "a", 616 .expected = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_a"}; 617 618 constexpr TestCaseReplacement LongString_End_EmptyCut_MidRange{ 619 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 620 .from = 38, 621 .to = 38, 622 .input = "aeiou", 623 .expected = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_aeiou"}; 624 625 constexpr TestCaseReplacement LongString_End_EmptyCut_LongRange{ 626 .initial = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", 627 .from = 38, 628 .to = 38, 629 .input = "abcdefghijklmnopqrstuvwxyz0123456789", 630 .expected = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_abcdefghijklmnopqrstuvwxyz0123456789"}; 631 632 constexpr 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 644 template <class Iter, class Sent, class Alloc> 645 constexpr 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 884 constexpr 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 912 constexpr bool test_constexpr() { 913 for_all_iterators_and_allocators_constexpr<char, const char*>([]<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. 925 int main(int, char**) { 926 static_assert(test_constraints_replace_with_range()); 927 928 for_all_iterators_and_allocators<char, const char*>([]<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