Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
21.string.replace.cpp
Go to the documentation of this file.
1
29#include <string> // for string
30#include <stdexcept> // for out_of_range, length_error
31#include <cstddef> // for ptrdiff_t, size_t
32
33#include <rw_strings.h>
34#include <rw_alg_test.h> // for InputIter
35#include <rw_driver.h> // for rw_test()
36#include <rw_allocator.h> // for UserAlloc
37#include <rw_new.h> // for bad_alloc, replacement operator new
38
39
41// for convenience and brevity
42#define Replace(sig) StringIds::replace_ ## sig
43
44static const char* const exceptions[] = {
45 "unknown exception", "out_of_range", "length_error",
46 "bad_alloc", "exception"
47};
48
49
51// exercises:
52// replace (size_type, size_type, const value_type*)
53// replace (iterator, iterator, const value_type*)
54static const StringTestCase
55iter_iter_cptr_test_cases [] = {
56
57// iter_iter_cptr_test_cases serves a double duty
58#define size_size_cptr_test_cases iter_iter_cptr_test_cases
59
60#undef TEST
61#define TEST(str, off, size, arg, res, bthrow) { \
62 __LINE__, off, size, -1, -1, -1, \
63 str, sizeof str - 1, \
64 arg, sizeof arg - 1, res, sizeof res - 1, bthrow \
65 }
66
67 // +------------------------------------------ controlled sequence
68 // | +----------------------------- replace() pos1 argument
69 // | | +-------------------------- replace() n1 argument
70 // | | | +----------------------- sequence to be inserted
71 // | | | | +----------- expected result sequence
72 // | | | | | +-- exception info
73 // | | | | | | -1 - no exceptions
74 // | | | | | | 0 - exception safety
75 // | | | | | | 1,2 - out_of_range
76 // | | | | | | 3 - length_error
77 // | | | | | |
78 // | | | | | +-------+
79 // | | | | | |
80 // V V V V V V
81 TEST ("ab", 0, 0, "c", "cab", 0),
82
83 TEST ("", 0, 0, "", "", 0),
84 TEST ("", 0, 0, "abc", "abc", 0),
85
86 TEST ("ab", 0, 2, "", "", 0),
87 TEST ("ab", 0, 1, "", "b", 0),
88
89 TEST ("<U0>", 0, 1, "", "", 0),
90 TEST ("<U0>", 0, 1, "a", "a", 0),
91 TEST ("<U0>", 0, 1, "<U0>@2", "", 0),
92
93 TEST ("ah", 0, 1, "bcdefg", "bcdefgh", 0),
94 TEST ("ah", 1, 1, "bcdefg", "abcdefg", 0),
95 TEST ("ah", 0, 2, "bcdefg", "bcdefg", 0),
96
97 TEST ("abc", 0, 2, "cc", "ccc", 0),
98 TEST ("abc", 1, 2, "cc", "acc", 0),
99
100 TEST ("abc", 0, 3, "defgh", "defgh", 0),
101 TEST ("abc", 2, 1, "defgh", "abdefgh", 0),
102 TEST ("abc", 2, 1, "de<U0>gh", "abde", 0),
103 TEST ("abc", 2, 1, "", "ab", 0),
104 TEST ("abc", 1, 1, "defgh", "adefghc", 0),
105
106 TEST ("abc", 0, 0, "ee", "eeabc", 0),
107 TEST ("abc", 0, 0, "<U0>@2e<U0>", "abc", 0),
108 TEST ("abc", 2, 0, "ee", "abeec", 0),
109 TEST ("abc", 1, 0, "ee", "aeebc", 0),
110 TEST ("abc", 1, 0, "e<U0>@2", "aebc", 0),
111
112 TEST ("a<U0>b<U0>@2c", 0, 3, "", "<U0>@2c", 0),
113 TEST ("a<U0>b<U0>@2c", 0, 3, "<U0>e", "<U0>@2c", 0),
114
115 TEST ("<U0>ab<U0>@2c", 0, 0, "e<U0>", "e<U0>ab<U0>@2c", 0),
116 TEST ("a<U0>b<U0>c<U0>", 6, 0, "e<U0>", "a<U0>b<U0>c<U0>e", 0),
117 TEST ("<U0>ab<U0>@2c", 5, 0, "e<U0>", "<U0>ab<U0>@2ec", 0),
118
119 TEST ("x@4096", 0, 4095, "ab", "abx", 0),
120 TEST ("<U0>@4096", 1, 4094, "abc", "<U0>abc<U0>", 0),
121 TEST ("x@4096", 1, 4094, "ab", "xabx", 0),
122 TEST ("x@4096", 0, 4094, "ab", "abxx", 0),
123 TEST ("x@4096", 1, 4093, "", "xxx", 0),
124
125 TEST ("x@20", 1, 10, "x@118", "x@128", 0),
126 TEST ("x@128", 128, 0, "x@79", "x@207", 0),
127 TEST ("x@207", 0, 0, "x@127", "x@334", 0),
128 TEST ("x@334", 1, 1, "x@207", "x@540", 0),
129 TEST ("x@540", 0, 539, "x@334", "x@335", 0),
130 TEST ("x@539", 539, 0, "x@873", "x@1412", 0),
131 TEST ("x@3695", 0, 2283, "", "x@1412", 0),
132 TEST ("x@1412", 207, 1, "x@2284", "x@3695", 0),
133 TEST ("x@207", 0, 207, "x@2284", "x@2284", 0),
134
135 TEST ("", 0, 0, "x@4096", "x@4096", 0),
136 TEST ("a", 0, 1, "x@4096", "x@4096", 0),
137 TEST ("x@4096", 0, 4095, "x@4096", "x@4097", 0),
138 TEST ("<U0>ab<U0>@2c", 0, 6, "x@4096", "x@4096", 0),
139
140 TEST ("<U0>", 2, 0, "", "<U0>", 1),
141 TEST ("a", 10, 0, "", "a", 1),
142 TEST ("x@4096", 4106, 0, "", "x@4096", 1),
143
144 TEST ("", 0, 0, "x@4096", "x@4096", 0),
145
146 // self-referential replacement
147 TEST ("", 0, 0, 0, "", 0),
148 TEST ("abc", 0, 3, 0, "abc", 0),
149 TEST ("abc", 1, 1, 0, "aabcc", 0),
150 TEST ("a<U0>b<U0>c<U0>", 2, 3, 0, "a<U0>a<U0>", 0),
151 TEST ("a<U0>b<U0>c<U0>", 0, 0, 0, "aa<U0>b<U0>c<U0>", 0),
152 TEST ("a<U0>b<U0>c<U0>", 6, 0, 0, "a<U0>b<U0>c<U0>a", 0),
153 TEST ("<U0>ab<U0>c<U0>", 3, 3, 0, "<U0>ab", 0),
154 TEST ("x@4096", 0, 4095, 0, "x@4097", 0),
155
156 TEST ("last", 4, 0, "test", "lasttest", 0)
157};
158
159
161// exercises:
162// replace (size_type, size_type, const basic_string&)
163// replace (iterator, iterator, const basic_string&)
164static const StringTestCase
165iter_iter_cstr_test_cases [] = {
166
167// iter_iter_cstr_test_cases serves a double duty
168#define size_size_cstr_test_cases iter_iter_cstr_test_cases
169
170#undef TEST
171#define TEST(s, off, size, arg, res, bthrow) { \
172 __LINE__, off, size, -1, -1, -1, \
173 s, sizeof s - 1, \
174 arg, sizeof arg - 1, res, sizeof res - 1, bthrow \
175 }
176
177 // +------------------------------------------- controlled sequence
178 // | +----------------------------- replace() pos1 argument
179 // | | +-------------------------- replace() n1 argument
180 // | | | +----------------------- sequence to be inserted
181 // | | | | +----------- expected result sequence
182 // | | | | | +-- exception info
183 // | | | | | | -1 - no exceptions
184 // | | | | | | 0 - exception safety
185 // | | | | | | 1,2 - out_of_range
186 // | | | | | | 3 - length_error
187 // | | | | | |
188 // | | | | | +-----------+
189 // | | | | | |
190 // V V V V V V
191 TEST ("ab", 0, 0, "c", "cab", 0),
192
193 TEST ("", 0, 0, "", "", 0),
194 TEST ("", 0, 0, "<U0>", "<U0>", 0),
195 TEST ("", 0, 0, "abc", "abc", 0),
196
197 TEST ("ab", 0, 2, "", "", 0),
198 TEST ("ab", 0, 1, "", "b", 0),
199 TEST ("ab", 1, 1, "<U0>", "a<U0>", 0),
200
201 TEST ("<U0>", 0, 1, "", "", 0),
202 TEST ("<U0>", 0, 1, "a", "a", 0),
203 TEST ("<U0>", 0, 1, "<U0>@2", "<U0>@2", 0),
204
205 TEST ("ah", 0, 1, "bcdefg", "bcdefgh", 0),
206 TEST ("ah", 1, 1, "bcdefg", "abcdefg", 0),
207 TEST ("ah", 0, 2, "bcdefg", "bcdefg", 0),
208
209 TEST ("abc", 0, 2, "cc", "ccc", 0),
210 TEST ("abc", 1, 2, "cc", "acc", 0),
211
212 TEST ("abc", 0, 3, "defgh", "defgh", 0),
213 TEST ("abc", 2, 1, "defgh", "abdefgh", 0),
214 TEST ("abc", 2, 1, "de<U0>gh", "abde<U0>gh", 0),
215 TEST ("abc", 2, 1, "", "ab", 0),
216 TEST ("abc", 1, 1, "defgh", "adefghc", 0),
217
218 TEST ("abc", 0, 0, "ee", "eeabc", 0),
219 TEST ("abc", 0, 0, "<U0>@2e<U0>", "<U0>@2e<U0>abc", 0),
220 TEST ("abc", 2, 0, "ee", "abeec", 0),
221 TEST ("abc", 1, 0, "ee", "aeebc", 0),
222 TEST ("abc", 1, 0, "e<U0>@2", "ae<U0>@2bc", 0),
223
224 TEST ("a<U0>b<U0>@2c", 0, 3, "", "<U0>@2c", 0),
225 TEST ("a<U0>b<U0>@2c", 0, 3, "<U0>e", "<U0>e<U0>@2c", 0),
226
227 TEST ("a<U0>b<U0>@2c", 2, 3, "<U0>e", "a<U0>@2ec", 0),
228 TEST ("a<U0>b<U0>@2c", 0, 3, "<U0>@2e<U0>", "<U0>@2e<U0>@3c", 0),
229 TEST ("<U0>ab<U0>@2c", 1, 2, "<U0>e<U0>@2", "<U0>@2e<U0>@4c", 0),
230
231 TEST ("<U0>ab<U0>@2c", 0, 0, "<U0>e", "<U0>e<U0>ab<U0>@2c", 0),
232 TEST ("a<U0>b<U0>c<U0>", 6, 0, "e<U0>", "a<U0>b<U0>c<U0>e<U0>", 0),
233 TEST ("<U0>ab<U0>@2c", 5, 0, "<U0>e", "<U0>ab<U0>@3ec", 0),
234
235 TEST ("x@4096", 0, 4095, "ab", "abx", 0),
236 TEST ("x@4096", 1, 4094, "ab", "xabx", 0),
237 TEST ("x@4096", 0, 4094, "ab", "abxx", 0),
238 TEST ("x@4096", 1, 4093, "", "xxx", 0),
239 TEST ("x@4096", 1, 4092, "<U0>@2", "x<U0>@2xxx", 0),
240
241 TEST ("x@20", 1, 10, "x@118", "x@128", 0),
242 TEST ("x@128", 128, 0, "x@79", "x@207", 0),
243 TEST ("x@207", 0, 0, "x@127", "x@334", 0),
244 TEST ("x@334", 1, 1, "x@207", "x@540", 0),
245 TEST ("x@540", 0, 539, "x@334", "x@335", 0),
246 TEST ("x@539", 539, 0, "x@873", "x@1412", 0),
247 TEST ("x@3695", 0, 2283, "", "x@1412", 0),
248 TEST ("x@1412", 207, 1, "x@2284", "x@3695", 0),
249 TEST ("x@207", 0, 207, "x@2284", "x@2284", 0),
250
251 TEST ("", 0, 0, "x@4096", "x@4096", 0),
252 TEST ("a", 0, 1, "x@4096", "x@4096", 0),
253 TEST ("x@4096", 0, 4095, "x@4096", "x@4097", 0),
254 TEST ("<U0>ab<U0>@2c", 0, 6, "x@4096", "x@4096", 0),
255
256 TEST ("<U0>", 2, 0, "", "<U0>", 1),
257 TEST ("a", 10, 0, "", "a", 1),
258 TEST ("x@4096", 4106, 0, "", "x@4096", 1),
259 TEST ("", 0, 0, "x@4096", "x@4096", 0),
260
261 // self-referential replacement
262 TEST ("abc", 0, 3, 0, "abc", 0),
263 TEST ("abc", 1, 1, 0, "aabcc", 0),
264 TEST ("a<U0>b<U0>c<U0>", 2, 3, 0, "a<U0>a<U0>b<U0>c<U0>@2", 0),
265 TEST ("a<U0>b<U0>c<U0>", 0, 0, 0, "a<U0>b<U0>c<U0>a<U0>b<U0>c<U0>", 0),
266 TEST ("a<U0>b<U0>c<U0>", 6, 0, 0, "a<U0>b<U0>c<U0>a<U0>b<U0>c<U0>", 0),
267 TEST ("<U0>ab<U0>c<U0>", 3, 3, 0, "<U0>ab<U0>ab<U0>c<U0>", 0),
268 TEST ("x@4096", 0, 4095, 0, "x@4097", 0),
269
270 TEST ("last", 4, 0, "test", "lasttest", 0)
271};
272
273
275// exercises:
276// replace (size_type, size_type, const value_type*, size_type)
277// replace (iterator, iterator, const value_type*, size_type)
278static const StringTestCase
279iter_iter_cptr_size_test_cases [] = {
280
281// iter_iter_cptr_size_test_cases serves a double duty
282#define size_size_cptr_size_test_cases iter_iter_cptr_size_test_cases
283
284#undef TEST
285#define TEST(str, off, size, arg, count, res, bthrow) { \
286 __LINE__, off, size, -1, count, -1, \
287 str, sizeof str - 1, \
288 arg, sizeof arg - 1, res, sizeof res - 1, bthrow \
289 }
290
291 // +------------------------------------------ controlled sequence
292 // | +----------------------------- replace() pos1 argument
293 // | | +-------------------------- replace() n1 argument
294 // | | | +----------------------- sequence to be inserted
295 // | | | | +---------- replace() n2 argument
296 // | | | | | +------- expected result sequence
297 // | | | | | | +- exception info
298 // | | | | | | | -1 - no exceptions
299 // | | | | | | | 0 - exception safety
300 // | | | | | | | 1,2 - out_of_range
301 // | | | | | | | 3 - length_error
302 // | | | | | | |
303 // | | | | | | +------------+
304 // | | | | | | |
305 // V V V V V V V
306 TEST ("ab", 0, 0, "c", 1, "cab", 0),
307
308 TEST ("", 0, 0, "", 0, "", 0),
309 TEST ("", 0, 0, "abc", 3, "abc", 0),
310
311 TEST ("ab", 0, 2, "", 0, "", 0),
312 TEST ("ab", 0, 1, "", 0, "b", 0),
313
314 TEST ("<U0>", 0, 1, "", 0, "", 0),
315 TEST ("<U0>", 0, 1, "a", 1, "a", 0),
316 TEST ("<U0>", 0, 1, "<U0>@2", 2, "<U0>@2", 0),
317
318 TEST ("ah", 0, 1, "bcdefg", 3, "bcdh", 0),
319 TEST ("ah", 1, 1, "bcdefg", 3, "abcd", 0),
320 TEST ("ah", 0, 2, "bcdefg", 5, "bcdef", 0),
321
322 TEST ("abc", 0, 2, "cc", 2, "ccc", 0),
323 TEST ("abc", 1, 2, "cc", 2, "acc", 0),
324 TEST ("abc", 2, 1, "defgh", 1, "abd", 0),
325 TEST ("abc", 2, 1, "de<U0>gh", 3, "abde<U0>", 0),
326 TEST ("abc", 2, 1, "", 0, "ab", 0),
327
328 TEST ("abc", 0, 0, "ee", 2, "eeabc", 0),
329 TEST ("abc", 0, 0, "<U0>@2e<U0>", 4, "<U0>@2e<U0>abc",0),
330 TEST ("abc", 2, 0, "ee", 2, "abeec", 0),
331 TEST ("abc", 1, 0, "ee", 1, "aebc", 0),
332
333 TEST ("a<U0>b<U0>@2c", 0, 3, "", 0, "<U0>@2c", 0),
334 TEST ("a<U0>b<U0>@2c", 0, 3, "e<U0>", 2, "e<U0>@3c", 0),
335 TEST ("a<U0>b<U0>@2c", 2, 3, "e<U0>", 1, "a<U0>ec", 0),
336 TEST ("a<U0>b<U0>@2c", 2, 3, "<U0>e", 2, "a<U0>@2ec", 0),
337 TEST ("<U0>ab<U0>@2c", 2, 3, "<U0>e", 2, "<U0>a<U0>ec", 0),
338 TEST ("a<U0>b<U0>@2c", 0, 6, "e<U0>", 2, "e<U0>", 0),
339
340 TEST ("x@4096", 1, 4095, "<U0>", 1, "x<U0>", 0),
341 TEST ("x@4096", 0, 4095, "ab", 2, "abx", 0),
342 TEST ("x@4096", 1, 4094, "ab", 1, "xax", 0),
343 TEST ("x@4096", 0, 4094, "ab", 2, "abxx", 0),
344 TEST ("x@4096", 1, 4093, "", 0, "xxx", 0),
345 TEST ("x@4096", 1, 4092, "<U0>@2", 2, "x<U0>@2xxx", 0),
346
347 TEST ("", 0, 0, "x@873", 540, "x@540", 0),
348 TEST ("x@20", 1, 10, "x@118", 118, "x@128", 0),
349 TEST ("x@128", 128, 0, "x@79", 79, "x@207", 0),
350 TEST ("x@207", 0, 0, "x@127", 127, "x@334", 0),
351 TEST ("x@207", 207, 207, "x@207", 127, "x@334", 0),
352 TEST ("x@334", 0, 207, "x@545", 540, "x@667", 0),
353 TEST ("x@539", 0, 539, "x@873", 873, "x@873", 0),
354 TEST ("x@878", 5, 5, "x@540", 539, "x@1412", 0),
355 TEST ("x@872", 0, 0, "x@1412", 1412, "x@2284", 0),
356 TEST ("x@1411", 1411, 0, "x@2284", 2284, "x@3695", 0),
357 TEST ("x@1411", 873, 538, "x@3695", 2822, "x@3695", 0),
358 TEST ("x@1412", 0, 0, "x@2284", 2284, "x@3696", 0),
359 TEST ("", 0, 0, "x@3696", 3696, "x@3696", 0),
360
361 TEST ("a", 0, 1, "x@4096", 4095, "x@4095", 0),
362 TEST ("x@4096", 0, 4095, "y@4096", 4095, "y@4095x", 0),
363 TEST ("x@4096", 0, 2047, "x@4096", 2047, "x@4096", 0),
364
365 TEST ("x@4096", 2047, 2048, "x@4096", 2048, "x@4096", 0),
366
367 TEST ("<U0>", 2, 0, "", 0, "<U0>", 1),
368 TEST ("a", 10, 0, "", 0, "a", 1),
369 TEST ("x@4096", 4106, 0, "", 0, "x@4096", 1),
370
371 TEST ("a", 0, 1, "x@4096", 4095, "x@4095", 0),
372
373 // self-referential replacement
374 TEST ("a", 0, 0, 0 /* self */, 1, "aa", 0),
375 TEST ("a", 0, 1, 0 /* self */, 1, "a", 0),
376 TEST ("a", 1, 0, 0 /* self */, 1, "aa", 0),
377 TEST ("abc", 0, 3, 0 /* self */, 2, "ab", 0),
378 TEST ("abc", 1, 1, 0 /* self */, 3, "aabcc", 0),
379 TEST ("a<U0>b<U0>c<U0>", 2, 3, 0, 6, "a<U0>a<U0>b<U0>c<U0>@2", 0),
380 TEST ("a<U0>b<U0>c<U0>", 0, 0, 0, 4, "a<U0>b<U0>a<U0>b<U0>c<U0>", 0),
381 TEST ("<U0>ab<U0>c<U0>", 6, 0, 0 /* self */, 1, "<U0>ab<U0>c<U0>@2", 0),
382 TEST ("<U0>ab<U0>c<U0>", 3, 3, 0 /* self */, 2, "<U0>ab<U0>a", 0),
383 TEST ("a@4096", 0, 1, 0 /* self */, 1111, "a@5206", 0),
384 TEST ("b@4096", 1, 2, 0 /* self */, 2222, "b@6316", 0),
385 TEST ("x@4096", 0, 4095, 0 /* self */, 4095, "x@4096", 0),
386 TEST ("x@4096", 0, 4095, 0 /* self */, 1, "xx", 0),
387
388 TEST ("last", 4, 0, "test", 4, "lasttest", 0)
389};
390
391
393// exercises:
394// replace (size_type, size_type, basic_string&, size_type, size_type)
395// replace (iterator, Iterator, InputIterator, InputIterator)
396static const StringTestCase
397iter_iter_range_test_cases [] = {
398
399// iter_iter_range_test_cases serves a double duty
400#define size_size_cstr_size_size_test_cases iter_iter_range_test_cases
401
402#undef TEST
403#define TEST(str, off, size, arg, off2, size2, res, bthrow) { \
404 __LINE__, off, size, off2, size2, -1, \
405 str, sizeof str - 1, \
406 arg, sizeof arg - 1, res, sizeof res - 1, bthrow \
407 }
408
409 // +------------------------------------------- controlled sequence
410 // | +------------------------------ replace() pos argument
411 // | | +-------------------------- replace() n1 argument
412 // | | | +----------------------- sequence to be inserted
413 // | | | | +----------- replace() pos2 argument
414 // | | | | | +------- replace() n2 argument
415 // | | | | | | +---- expected result sequence
416 // | | | | | | | +-- exception info:
417 // | | | | | | | | -1 - no exceptions
418 // | | | | | | | | 0 - exception safety
419 // | | | | | | | | 1, 2 - out_of_range
420 // | | | | | | | | 3 - length_error
421 // | | | | | | | |
422 // | | | | | | | +-----------------+
423 // | | | | | | | |
424 // V V V V V V V V
425 TEST ("", 0, 0, "", 0, 0, "", 0),
426 TEST ("", 0, 0, "", 0, -1, "", 0),
427 TEST ("", 0, 0, "", 0, 1, "", 0),
428
429 TEST ("", 0, 1, "", 0, 0, "", 0),
430 TEST ("", 0, 1, "", 0, 1, "", 0),
431 TEST ("", 0, 1, "", 0, -1, "", 0),
432
433 TEST ("", 0, -1, "", 0, 0, "", 0),
434 TEST ("", 0, -1, "", 0, 1, "", 0),
435 TEST ("", 0, -1, "", 0, -1, "", 0),
436
437 TEST ("1", 0, 0, "", 0, 0, "1", 0),
438 TEST ("2", 0, 0, "", 0, -1, "2", 0),
439 TEST ("3", 0, 0, "", 0, 1, "3", 0),
440
441 TEST ("4", 0, 1, "", 0, 0, "", 0),
442 TEST ("5", 0, 1, "", 0, 1, "", 0),
443 TEST ("6", 0, 1, "", 0, -1, "", 0),
444
445 TEST ("7", 0, -1, "", 0, 0, "", 0),
446 TEST ("8", 0, -1, "", 0, 1, "", 0),
447 TEST ("9", 0, -1, "", 0, -1, "", 0),
448
449 TEST ("1", 0, 0, "9", 0, 0, "1", 0),
450 TEST ("2", 0, 0, "8", 0, -1, "82", 0),
451 TEST ("3", 0, 0, "7", 0, 1, "73", 0),
452
453 TEST ("4", 0, 1, "6", 0, 0, "", 0),
454 TEST ("5", 0, 1, "5", 0, 1, "5", 0),
455 TEST ("6", 0, 1, "4", 0, -1, "4", 0),
456
457 TEST ("7", 0, -1, "3", 0, 0, "", 0),
458 TEST ("8", 0, -1, "2", 0, 1, "2", 0),
459 TEST ("9", 0, -1, "1", 0, -1, "1", 0),
460
461 TEST ("", 0, 0, "abc", 0, 3, "abc", 0),
462
463 TEST ("ab", 0, 0, "c", 0, 1, "cab", 0),
464 TEST ("ab", 0, 2, "", 0, 0, "", 0),
465 TEST ("ab", 0, 1, "", 0, 0, "b", 0),
466
467 TEST ("<U0>", 0, 1, "", 0, 0, "", 0),
468 TEST ("<U0>", 0, 1, "a", 0, 1, "a", 0),
469 TEST ("<U0>", 0, 1, "<U0>@2", 1, 1, "<U0>", 0),
470 TEST ("<U0>", 0, 1, "<U0>@2", 0, 2, "<U0>@2", 0),
471
472 TEST ("ah", 0, 1, "bcdefg", 0, 3, "bcdh", 0),
473 TEST ("ah", 1, 1, "bcdefg", 0, 3, "abcd", 0),
474 TEST ("ah", 0, 1, "bcdefg", 1, 3, "cdeh", 0),
475 TEST ("ah", 1, 1, "bcdefg", 1, 3, "acde", 0),
476 TEST ("ah", 0, 1, "bcdefg", 0, 6, "bcdefgh", 0),
477 TEST ("ah", 1, 1, "bcdefg", 0, 6, "abcdefg", 0),
478
479 TEST ("abc", 0, 2, "cc", 0, 2, "ccc", 0),
480 TEST ("abc", 1, 2, "cc", 0, 2, "acc", 0),
481
482 TEST ("abc", 0, 3, "d", 0, 1, "d", 0),
483 TEST ("abc", 0, 3, "def", 0, 3, "def", 0),
484 TEST ("abc", 0, 3, "defgh", 0, 5, "defgh", 0),
485 TEST ("abc", 2, 1, "defgh", 4, 1, "abh", 0),
486 TEST ("abc", 2, 1, "de<U0>gh", 2, 1, "ab<U0>", 0),
487 TEST ("abc", 2, 1, "", 0, 0, "ab", 0),
488
489 TEST ("abc", 1, 1, "defgh", 1, 2, "aefc", 0),
490 TEST ("abc", 0, 0, "ee", 0, 2, "eeabc", 0),
491 TEST ("abc", 0, 0, "<U0>@2e<U0>", 0, 4, "<U0>@2e<U0>abc",0),
492 TEST ("abc", 2, 0, "ee", 0, 2, "abeec", 0),
493 TEST ("abc", 2, 1, "<U0>e<U0>@2", 0, 4, "ab<U0>e<U0>@2", 0),
494 TEST ("abc", 1, 0, "ee", 0, 2, "aeebc", 0),
495 TEST ("abc", 1, 0, "<U0>e<U0>@2", 0, 4, "a<U0>e<U0>@2bc", 0),
496
497 TEST ("a<U0>b<U0>@2c", 0, 3, "", 0, 0, "<U0>@2c", 0),
498 TEST ("<U0>ab<U0>@2c", 0, 3, "", 0, 0, "<U0>@2c", 0),
499 TEST ("a<U0>b<U0>@2c", 0, 3, "<U0>e", 0, 2, "<U0>e<U0>@2c", 0),
500
501 TEST ("a<U0>b<U0>@2c", 2, 3, "<U0>e", 0, 2, "a<U0>@2ec", 0),
502 TEST ("a<U0>b<U0>@2c", 2, 3, "<U0>e", 1, 1, "a<U0>ec", 0),
503 TEST ("<U0>ab<U0>@2c", 2, 3, "<U0>e", 0, 2, "<U0>a<U0>ec", 0),
504 TEST ("<U0>ab<U0>@2c", 2, 3, "<U0>e<U0>@2", 1, 3, "<U0>ae<U0>@2c", 0),
505
506 TEST ("a<U0>b<U0>@2c", 0, 6, "<U0>e", 0, 2, "<U0>e", 0),
507 TEST ("a<U0>b<U0>@2c", 0, 6, "<U0>e", 0, 1, "<U0>", 0),
508
509 TEST ("<U0>ab<U0>@2c", 0, 0, "<U0>e", 0, 2, "<U0>e<U0>ab<U0>@2c", 0),
510 TEST ("a<U0>b<U0>c<U0>", 6, 0, "e<U0>", 0, 2, "a<U0>b<U0>c<U0>e<U0>", 0),
511 TEST ("<U0>ab<U0>@2c", 5, 0, "<U0>e", 0, 2, "<U0>ab<U0>@3ec", 0),
512
514 // very long strings
515 TEST ("a", 0, 0, "b", 0, -1, "ba", 0),
516 TEST ("a@0", 0, 0, "b@0", 0, -1, "", 0),
517 TEST ("a@0", 0, 0, "b@1", 0, -1, "b", 0),
518 TEST ("a@1", 0, 0, "b@0", 0, -1, "a", 0),
519 TEST ("a@1", 0, 0, "b@1", 0, -1, "ba", 0),
520 TEST ("a@2", 0, 0, "b@2", 0, -1, "bbaa", 0),
521
522 TEST ("a@1000", 0, 0, "b@1000", 0, -1, "b@1000a@1000", 0),
523 TEST ("a@1000", 0, 1, "b@1001", 0, -1, "b@1001a@999", 0),
524 TEST ("a@1000", 0, 2, "b@1002", 0, -1, "b@1002a@998", 0),
525 TEST ("a@1000", 1, 998, "b@1003", 0, -1, "ab@1003a", 0),
526 TEST ("a@1000", 2, 996, "b@1004", 0, -1, "aab@1004aa", 0),
527 TEST ("a@1000", 500, 250, "b@1005", 0, -1, "a@500b@1005a@250", 0),
528 TEST ("a@1000", 998, 1, "b@1006", 0, -1, "a@998b@1006a", 0),
529 TEST ("a@2000", 1000, -1, "b", 0, -1, "a@1000b", 0),
530 TEST ("a@2000", 1000, 999, "bb", 0, -1, "a@1000bba", 0),
531
532 TEST ("x@4096", 0, 4095, "ab", 0, 2, "abx", 0),
533 TEST ("x@4096", 1, 4094, "ab", 0, 2, "xabx", 0),
534 TEST ("x@4096", 0, 4094, "ab", 0, 2, "abxx", 0),
535 TEST ("x@4096", 1, 4093, "", 0, 0, "xxx", 0),
536 TEST ("x@4096", 1, 4092, "<U0>@2", 0, 2, "x<U0>@2xxx", 0),
537
538 TEST ("a", 0, 1, "x@4096", 0, 4095, "x@4095", 0),
539 TEST ("x@4096", 0, 4095, "x@4096", 0, 4095, "x@4096", 0),
540 TEST ("x@4096", 0, 2047, "x@4096", 0, 2047, "x@4096", 0),
541
542 TEST ("", 0, 0, "x@334", 0, 207, "x@207", 0),
543 TEST ("x@20", 1, 10, "x@118", 0, 118, "x@128", 0),
544 TEST ("x@128", 0, 0, "x@129", 50, 79, "x@207", 0),
545 TEST ("x@207", 207, 0, "x@127", 0, 127, "x@334", 0),
546 TEST ("x@208", 128, 1, "x@207", 10, 127, "x@334", 0),
547 TEST ("x@335", 334, 1, "x@208", 2, 206, "x@540", 0),
548 TEST ("x@540", 0, 0, "x@336", 3, 333, "x@873", 0),
549 TEST ("x@334", 0, 334, "x@873", 0, 873, "x@873", 0),
550 TEST ("x@873", 0, 873, "x@541", 1, 540, "x@540", 0),
551 TEST ("x@872", 0, 0, "x@1412", 0, 1412, "x@2284", 0),
552 TEST ("x@1411", 1411, 0, "x@2288", 4, 2284, "x@3695", 0),
553 TEST ("x@873", 540,333, "x@3695",3695, 0, "x@540", 0),
554 TEST ("x@1412", 0, 1412, "x@3696", 0,3695, "x@3695", 0),
555
556 TEST ("x@4096", 2047, 2048, "x@4096", 0, 2048, "x@4096", 0),
557
558 TEST ("<U0>", 2, 0, "", 0, 0, "<U0>", 1),
559 TEST ("<U0>", 0, 0, "<U0>", 2, 0, "<U0>", 2),
560
561 TEST ("a", 10, 0, "", 0, 0, "a", 1),
562 TEST ("a", 0, 0, "a", 10, 0, "a", 2),
563
564 TEST ("x@4096", 4106, 0, "", 0, 0, "x@4096", 1),
565 TEST ("x@4096", 0, 0, "x@4096", 4106, 0, "x@4096", 2),
566
567 TEST ("a", 0, 1, "x@4096", 0, 4095, "x@4095", 0),
568
570 // self-referential replacement
571 TEST ("", 0, 0, 0, 0, 0, "", 0),
572 TEST ("", 0, 0, 0, 0, 1, "", 0),
573 TEST ("", 0, 0, 0, 0, -1, "", 0),
574
575 TEST ("", 0, 1, 0, 0, 0, "", 0),
576 TEST ("", 0, 1, 0, 0, 1, "", 0),
577 TEST ("", 0, 1, 0, 0, -1, "", 0),
578
579 TEST ("", 0, -1, 0, 0, 0, "", 0),
580 TEST ("", 0, -1, 0, 0, 1, "", 0),
581 TEST ("", 0, -1, 0, 0, -1, "", 0),
582
583 TEST ("1", 0, 0, 0, 0, 0, "1", 0),
584 TEST ("2", 0, 0, 0, 0, -1, "22", 0),
585 TEST ("3", 0, 0, 0, 0, 1, "33", 0),
586
587 TEST ("4", 0, 1, 0, 0, 0, "", 0),
588 TEST ("5", 0, 1, 0, 0, 1, "5", 0),
589 TEST ("6", 0, 1, 0, 0, -1, "6", 0),
590
591 TEST ("7", 0, -1, 0, 0, 0, "", 0),
592 TEST ("8", 0, -1, 0, 0, 1, "8", 0),
593 TEST ("9", 0, -1, 0, 0, -1, "9", 0),
594
595 TEST ("x@4096", 0, 0, 0, 0, 0, "x@4096", 0),
596 TEST ("x@4096", 0, 1, 0, 0, 1, "x@4096", 0),
597 TEST ("x@4096", 0, 2, 0, 0, 2, "x@4096", 0),
598 TEST ("x@4096", 0, -1, 0, 0, -1, "x@4096", 0),
599
600 TEST ("abc", 0, 0, 0, 1, 1, "babc", 0),
601 TEST ("abc", 2, 0, 0, 0, 2, "ababc", 0),
602 TEST ("a<U0>bc<U0>@2", 0, 0, 0, 4, 2, "<U0>@2a<U0>bc<U0>@2", 0),
603 TEST ("a<U0>bc<U0>@2", 6, 0, 0, 1, 3, "a<U0>bc<U0>@3bc", 0),
604 TEST ("abcdef", 0, 0, 0, 1, 2, "bcabcdef", 0),
605
606 TEST ("last", 4, 0, "test", 0, 4, "lasttest", 0)
607};
608
609
611// exercises:
612// replace (size_type, size_type, value_type, size_type)
613// replace (iterator, iterator, size_type, value_type)
614static const StringTestCase
615iter_iter_size_val_test_cases [] = {
616
617// iter_iter_size_val_test_cases serves a double duty
618#define size_size_size_val_test_cases iter_iter_size_val_test_cases
619
620#undef TEST
621#define TEST(str, off, size, count, val, res, bthrow) { \
622 __LINE__, off, size, -1, count, val, \
623 str, sizeof str - 1, \
624 0, 0, res, sizeof res - 1, bthrow \
625 }
626
627 // +------------------------------------------ controlled sequence
628 // | +----------------------------- replace() pos1 argument
629 // | | +-------------------------- replace() n1 argument
630 // | | | +----------------------- replace() count argument
631 // | | | | +------------------- character to be inserted
632 // | | | | | +-------------- expected result sequence
633 // | | | | | | +------ exception info
634 // | | | | | | | -1 - no exceptions
635 // | | | | | | | 0 - exception safety
636 // | | | | | | | 1,2 - out_of_range
637 // | | | | | | | 3 - length_error
638 // | | | | | | |
639 // | | | | | | +--------+
640 // | | | | | | |
641 // V V V V V V V
642 TEST ("ab", 0, 0, 1, 'c', "cab", 0),
643
644 TEST ("", 0, 0, 0, 'c', "", 0),
645 TEST ("", 0, 0, 3, 'c', "ccc", 0),
646
647 TEST ("ab", 0, 2, 0, 'c', "", 0),
648 TEST ("ab", 0, 1, 0, 'c', "b", 0),
649
650 TEST ("<U0>", 0, 1, 0, ' ', "", 0),
651 TEST ("<U0>", 0, 1, 1, 'a', "a", 0),
652 TEST ("<U0>", 0, 1, 1, '\0', "<U0>", 0),
653 TEST ("<U0>", 0, 1, 2, '\0', "<U0>@2", 0),
654
655 TEST ("ah", 0, 1, 1, 'c', "ch", 0),
656 TEST ("ah", 1, 1, 1, 'c', "ac", 0),
657 TEST ("ah", 0, 1, 4, 'c', "cccch", 0),
658 TEST ("ah", 1, 1, 4, 'c', "acccc", 0),
659
660 TEST ("abc", 0, 2, 2, 'c', "ccc", 0),
661 TEST ("abc", 1, 2, 2, 'c', "acc", 0),
662
663 TEST ("abc", 0, 3, 1, 'c', "c", 0),
664 TEST ("abc", 0, 3, 5, 'c', "ccccc", 0),
665 TEST ("abc", 2, 1, 1, 'c', "abc", 0),
666 TEST ("abc", 2, 1, 0, 'c', "ab", 0),
667
668 TEST ("abc", 1, 1, 5, 'c', "acccccc", 0),
669 TEST ("abc", 0, 0, 2, 'c', "ccabc", 0),
670 TEST ("abc", 0, 0, 3, '\0', "<U0>@3abc", 0),
671 TEST ("abc", 2, 0, 2, 'e', "abeec", 0),
672 TEST ("abc", 2, 0, 3, '\0', "ab<U0>@3c", 0),
673 TEST ("abc", 1, 0, 1, '\0', "a<U0>bc", 0),
674
675 TEST ("a<U0>b<U0>@2c", 0, 3, 1, '\0', "<U0>@3c", 0),
676 TEST ("a<U0>b<U0>@2c", 2, 3, 2, '\0', "a<U0>@3c", 0),
677 TEST ("a<U0>b<U0>@2c", 2, 2, 1, '\0', "a<U0>@3c", 0),
678 TEST ("<U0>ab<U0>@2c", 2, 3, 0, '\0', "<U0>ac", 0),
679 TEST ("<U0>ab<U0>@2c", 2, 1, 2, '\0', "<U0>a<U0>@4c", 0),
680
681 TEST ("a<U0>b<U0>@2c", 0, 6, 2, '\0', "<U0>@2", 0),
682
683 TEST ("<U0>ab<U0>@2c", 0, 0, 2, '\0', "<U0>@3ab<U0>@2c", 0),
684 TEST ("a<U0>b<U0>c<U0>", 6, 0, 2, '\0', "a<U0>b<U0>c<U0>@3", 0),
685 TEST ("<U0>ab<U0>@2c", 5, 0, 1, '\0', "<U0>ab<U0>@3c", 0),
686
687 TEST ("x@4096", 0, 4095, 2, 'a', "aax", 0),
688 TEST ("x@4096", 1, 4094, 2, 'a', "xaax", 0),
689 TEST ("x@4096", 0, 4094, 2, 'a', "aaxx", 0),
690 TEST ("x@4096", 1, 4093, 0, 'a', "xxx", 0),
691 TEST ("x@4096", 1, 4092, 1, '\0', "x<U0>xxx", 0),
692
693 TEST ("x@127", 0, 0, 1, 'x', "x@128", 0),
694 TEST ("x@200", 128, 7, 14, 'x', "x@207", 0),
695 TEST ("x@331", 331, 1, 3, 'x', "x@334", 0),
696 TEST ("x@539", 539, 0, 1, 'x', "x@540", 0),
697 TEST ("x@539", 0, 0,873, 'x', "x@1412", 0),
698 TEST ("x@873", 873, 0, 1411, 'x', "x@2284", 0),
699 TEST ("x@3694", 128, 1, 2, 'x', "x@3695", 0),
700 TEST ("x@539", 537, 2, 3, 'a', "x@537aaa", 0),
701 TEST ("", 0, 0, 3695, 'x', "x@3695", 0),
702
703 TEST ("a", 0, 1, 4095, 'x', "x@4095", 0),
704 TEST ("x@4096", 0, 4095, 4095, 'a', "a@4095x", 0),
705 TEST ("x@4096", 0, 2047, 2047, 'b', "b@2047x@2049", 0),
706
707 TEST ("x@4096", 2047, 2048, 2048, 'x', "x@4096", 0),
708
709 TEST ("<U0>", 2, 0, 0, ' ', "<U0>", 1),
710 TEST ("a", 10, 0, 0, ' ', "a", 1),
711 TEST ("x@4096", 4106, 0, 0, ' ', "x@4096", 1),
712
713 TEST ("a", 0, 1, 4095, 'x', "x@4095", 0),
714
715 TEST ("last", 4, 0, 4, 't', "lasttttt", 0)
716};
717
718
720// invokes specializations of the member function template
721// on the required iterator categories
722template <class String, class Iterator>
723struct ReplaceRange: RangeBase<String> {
724
725 typedef typename String::iterator StringIter;
726 typedef typename String::value_type StringChar;
727
729
730 virtual String&
732 const StringTestCaseData<StringChar>& tdata) const {
733
734 const StringTestCase &tcase = tdata.tcase_;
735
736 // create a pair of iterators into the string object being modified
737 const StringIter first1 (str.begin () + tdata.off1_);
738 const StringIter last1 (first1 + tdata.ext1_);
739
740 const String &cstr = str;
741
742 // when (0 == tcase.arg) exercise self-referential modification
743 // (i.e., replacing a range of elements with a subrange of its
744 // own elements)
745 const StringChar* const beg =
746 (tcase.arg ? tdata.arg_ : cstr.data ()) + tdata.off2_;
747
748 const StringChar* const end = beg + tdata.ext2_;
749
750 const Iterator first2 (beg, beg, end);
751 const Iterator last2 (end, beg, end);
752
753 return str.replace (first1, last1, first2, last2);
754 }
755};
756
757
758// invokes possible overloads of the member function template
759// on common RandomAccessIterator types
760template <class String, class Iterator>
762{
763 typedef typename String::iterator StringIter;
764 typedef typename String::value_type StringChar;
765
767
768 virtual String&
770 const StringTestCaseData<StringChar>& tdata) const {
771
772 const StringTestCase &tcase = tdata.tcase_;
773
774 // create a pair of iterators into the string object being modified
775 const StringIter first1 (str.begin () + tdata.off1_);
776 const StringIter last1 (first1 + tdata.ext1_);
777
778 bool reverse_iter = StringIds::ReverseIterator == tdata.func_.iter_id_
780
781 const std::size_t srclen_ = tcase.arg ? tdata.arglen_ : str.size ();
782
783 const std::size_t off =
784 reverse_iter ? srclen_ - tdata.off2_ - tdata.ext2_ : tdata.off2_;
785 const std::size_t ext = tdata.ext2_;
786
787 if (0 == tcase.arg) {
788 // exercise self-referential modification (i.e., replacing
789 // a range of elements with a subrange of its own elements)
790
791 const Iterator first2 (this->begin (str, (Iterator*)0) + off);
792 const Iterator last2 (first2 + ext);
793
794 return str.replace (first1, last1, first2, last2);
795 }
796
797 String str_arg (tdata.arg_, tdata.arglen_);
798
799 const Iterator first2 (this->begin (str_arg, (Iterator*)0) + off);
800 const Iterator last2 (first2 + ext);
801
802 return str.replace (first1, last1, first2, last2);
803 }
804};
805
806
808template <class charT, class Traits, class Allocator>
810 std::basic_string <charT, Traits, Allocator> > &rng,
811 const StringTestCaseData<charT> &tdata)
812{
813 typedef std::basic_string <charT, Traits, Allocator> String;
814 typedef typename String::iterator StringIter;
815 typedef typename UserTraits<charT>::MemFun TraitsFunc;
816
817 const StringFunc &func = tdata.func_;
818 const StringTestCase &tcase = tdata.tcase_;
819
820 // construct the string object to be modified
821 // and the (possibly unused) argument string
822 /* const */ String str (tdata.str_, tdata.strlen_);
823 const String arg (tdata.arg_, tdata.arglen_);
824
825 // save the state of the string object before the call
826 // to detect wxception safety violations (changes to
827 // the state of the object after an exception)
828 const StringState str_state (rw_get_string_state (str));
829
830 // create a pair of iterators into the string object being
831 // modified (used only by the iterator overloads)
832 const StringIter first (str.begin () + tdata.off1_);
833 const StringIter last (first + tdata.ext1_);
834
835 // offset and extent function arguments
836 const std::size_t arg_off = std::size_t (tcase.off);
837 const std::size_t arg_size = std::size_t (tcase.size);
838 const std::size_t arg_off2 = std::size_t (tcase.off2);
839 const std::size_t arg_size2 =
840 0 <= tcase.size2 ? tcase.size2 : str.max_size () + 1;
841
842 // string function argument
843 const charT* const arg_ptr = tcase.arg ? arg.data () : str.data ();
844 const String& arg_str = tcase.arg ? arg : str;
845 const charT arg_val = make_char (char (tcase.val), (charT*)0);
846
847 // get a pointer to the Traits::length() function call counter
848 // or 0 when no such counter exists (i.e., when Traits is not
849 // UserTraits)
850 std::size_t* length_calls =
851 Replace (size_size_cptr) == func.which_
852 || Replace (iter_iter_cptr) == func.which_ ?
853 rw_get_call_counters ((Traits*)0, (charT*)0) : 0;
854
855 if (length_calls) {
856 length_calls += TraitsFunc::length;
857 *length_calls = 0;
858 }
859
860 rwt_free_store* const pst = rwt_get_free_store (0);
861 SharedAlloc* const pal = SharedAlloc::instance ();
862
863 // out_of_range is only generated from size_type overloads
864 // of replace() and not from the iterator equivalents of
865 // the same functions
866 const bool use_iters =
868
869 // iterate for`throw_count' starting at the next call to operator new,
870 // forcing each call to throw an exception, until the function finally
871 // succeeds (i.e, no exception is thrown)
872 std::size_t throw_count;
873 for (throw_count = 0; ; ++throw_count) {
874
875 // (name of) expected and caught exception
876 const char* expected = 0;
877 const char* caught = 0;
878
879#ifndef _RWSTD_NO_EXCEPTIONS
880
881 if (1 == tcase.bthrow && !use_iters)
882 expected = exceptions [1]; // out_of_range
883 else if (2 == tcase.bthrow && !use_iters)
884 expected = exceptions [1]; // out_of_range
885 else if (3 == tcase.bthrow && !use_iters)
886 expected = exceptions [2]; // length_error
887 else if (0 == tcase.bthrow) {
888 // by default excercise the exception safety of the function
889 // by iteratively inducing an exception at each call to operator
890 // new or Allocator::allocate() until the call succeeds
891 expected = exceptions [3]; // bad_alloc
892 *pst->throw_at_calls_ [0] = pst->new_calls_ [0] + throw_count + 1;
893 pal->throw_at_calls_ [pal->m_allocate] =
894 pal->throw_at_calls_ [pal->m_allocate] + throw_count + 1;
895 }
896 else {
897 // exceptions disabled for this test case
898 }
899
900#else // if defined (_RWSTD_NO_EXCEPTIONS)
901
902 if (tcase.bthrow)
903 return;
904
905#endif // _RWSTD_NO_EXCEPTIONS
906
907 // pointer to the returned reference
908 const String* ret_ptr = 0;
909
910 // start checking for memory leaks
911 rw_check_leaks (str.get_allocator ());
912
913 try {
914 switch (func.which_) {
915 case Replace (size_size_cptr):
916 ret_ptr = &str.replace (arg_off, arg_size, arg_ptr);
917 break;
918
919 case Replace (size_size_cstr):
920 ret_ptr = &str.replace (arg_off, arg_size, arg_str);
921 break;
922
923 case Replace (size_size_cptr_size):
924 ret_ptr = &str.replace (arg_off, arg_size, arg_ptr, arg_size2);
925 break;
926
927 case Replace (size_size_cstr_size_size):
928 ret_ptr = &str.replace (arg_off, arg_size, arg_str,
929 arg_off2, arg_size2);
930 break;
931
932 case Replace (size_size_size_val):
933 ret_ptr = &str.replace (arg_off, arg_size, arg_size2, arg_val);
934 break;
935
936 case Replace (iter_iter_cptr):
937 ret_ptr = &str.replace (first, last, arg_ptr);
938 break;
939
940 case Replace (iter_iter_cstr):
941 ret_ptr = &str.replace (first, last, arg_str);
942 break;
943
944 case Replace (iter_iter_cptr_size):
945 ret_ptr = &str.replace (first, last, arg_ptr, arg_size2);
946 break;
947
948 case Replace (iter_iter_size_val):
949 ret_ptr = &str.replace (first, last, arg_size2, arg_val);
950 break;
951
952 case Replace (iter_iter_range):
953 ret_ptr = &rng (str, tdata);
954 break;
955
956 default:
957 RW_ASSERT (!"logic error: unknown replace overload");
958 }
959
960 // verify that the reference returned from the function
961 // refers to the modified string object (i.e., *this
962 // within the function)
963 const std::ptrdiff_t ret_off = ret_ptr - &str;
964
965 // verify the returned value
966 rw_assert (0 == ret_off, 0, tcase.line,
967 "line %d. %{$FUNCALL} returned invalid reference, "
968 "offset is %td", __LINE__, ret_off);
969
970 // for convenience
971 static const int cwidth = sizeof (charT);
972
973 // verfiy that the length of the resulting string
974 rw_assert (tdata.reslen_ == str.size (), 0, tcase.line,
975 "line %d. %{$FUNCALL} expected %{/*.*Gs} with "
976 "length %zu, got %{/*.*Gs} with length %zu",
977 __LINE__,
978 cwidth, int (tdata.reslen_), tdata.res_,
979 tdata.reslen_, cwidth, int (str.size ()), str.data (),
980 str.size ());
981
982 if (tdata.reslen_ == str.size ()) {
983 // if the result length matches the expected length
984 // (and only then), also verify that the modified
985 // string matches the expected result
986 const std::size_t match =
987 rw_match (tcase.res, str.data (), str.size ());
988
989 rw_assert (match == tdata.reslen_, 0, tcase.line,
990 "line %d. %{$FUNCALL} expected %{/*.*Gs}, "
991 "got %{/*.*Gs}, difference at offset %zu",
992 __LINE__,
993 cwidth, int (tdata.reslen_), tdata.res_,
994 cwidth, int (str.size ()),str.data (), match);
995 }
996
997 // verify that Traits::length() was used
998 if (length_calls) {
999 rw_assert (0 < *length_calls,
1000 0, tcase.line, "line %d. %{$FUNCALL} doesn't "
1001 "use traits_type::length()", __LINE__);
1002 }
1003 }
1004
1005#ifndef _RWSTD_NO_EXCEPTIONS
1006
1007 catch (const std::out_of_range &ex) {
1008 caught = exceptions [1];
1009 rw_assert (caught == expected, 0, tcase.line,
1010 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
1011 "unexpectedly%{;} caught std::%s(%#s)",
1012 __LINE__, 0 != expected, expected, caught, ex.what ());
1013 }
1014 catch (const std::length_error &ex) {
1015 caught = exceptions [2];
1016 rw_assert (caught == expected, 0, tcase.line,
1017 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
1018 "unexpectedly%{;} caught std::%s(%#s)",
1019 __LINE__, 0 != expected, expected, caught, ex.what ());
1020 }
1021 catch (const std::bad_alloc &ex) {
1022 caught = exceptions [3];
1023 rw_assert (0 == tcase.bthrow, 0, tcase.line,
1024 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
1025 "unexpectedly%{;} caught std::%s(%#s)",
1026 __LINE__, 0 != expected, expected, caught, ex.what ());
1027 }
1028 catch (const std::exception &ex) {
1029 caught = exceptions [4];
1030 rw_assert (0, 0, tcase.line,
1031 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
1032 "unexpectedly%{;} caught std::%s(%#s)",
1033 __LINE__, 0 != expected, expected, caught, ex.what ());
1034 }
1035 catch (...) {
1036 caught = exceptions [0];
1037 rw_assert (0, 0, tcase.line,
1038 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
1039 "unexpectedly%{;} caught %s",
1040 __LINE__, 0 != expected, expected, caught);
1041 }
1042
1043#endif // _RWSTD_NO_EXCEPTIONS
1044
1045 // FIXME: verify the number of blocks the function call
1046 // is expected to allocate and detect any memory leaks
1047 rw_check_leaks (str.get_allocator (), tcase.line,
1048 std::size_t (-1), std::size_t (-1));
1049
1050 if (caught) {
1051 // verify that the exception didn't cause a change
1052 // in the state of the object
1054 __LINE__, tcase.line, caught);
1055
1056 if (0 == tcase.bthrow) {
1057 // allow this call to operator new to succeed and try
1058 // to make the next one to fail during the next call
1059 // to the same function again
1060 continue;
1061 }
1062 }
1063 else if (0 < tcase.bthrow) {
1064 rw_assert (caught == expected, 0, tcase.line,
1065 "line %d. %{$FUNCALL} %{?}expected %s, caught %s"
1066 "%{:}unexpectedly caught %s%{;}",
1067 __LINE__, 0 != expected, expected, caught, caught);
1068 }
1069
1070 break;
1071 }
1072
1073#ifndef _RWSTD_NO_REPLACEABLE_NEW_DELETE
1074
1075 // verify that if exceptions are enabled and when capacity changes
1076 // at least one exception is thrown
1077 const std::size_t expect_throws = str_state.capacity_ < str.capacity ();
1078
1079#else // if defined (_RWSTD_NO_REPLACEABLE_NEW_DELETE)
1080
1081 const std::size_t expect_throws = StringIds::UserAlloc == func.alloc_id_ ?
1082 str_state.capacity_ < str.capacity () : 0;
1083
1084#endif // _RWSTD_NO_REPLACEABLE_NEW_DELETE
1085
1086 // verify number of exceptions thrown
1087 // for range version the allocation may take place several times
1088 if (Replace (iter_iter_range) != func.which_)
1089 rw_assert (expect_throws == throw_count, 0, tcase.line,
1090 "line %d: %{$FUNCALL}: expected exactly 1 %s exception "
1091 "while changing capacity from %zu to %zu, got %zu",
1092 __LINE__, exceptions [3],
1093 str_state.capacity_, str.capacity (), throw_count);
1094 else
1095 rw_assert (expect_throws <= throw_count, 0, tcase.line,
1096 "line %d: %{$FUNCALL}: expected at least 1 %s exception "
1097 "while changing capacity from %zu to %zu, got %zu",
1098 __LINE__, exceptions [3],
1099 str_state.capacity_, str.capacity (), throw_count);
1100
1101 // disable bad_alloc exceptions
1102 *pst->throw_at_calls_ [0] = 0;
1103 pal->throw_at_calls_ [pal->m_allocate] = 0;
1104}
1105
1106
1108template <class charT, class Traits, class Allocator>
1110 const StringTestCaseData<charT> &tdata)
1111{
1112 typedef std::basic_string<charT, Traits, Allocator> String;
1113
1114 if (tdata.func_.which_ == Replace (iter_iter_range)) {
1115
1116 switch (tdata.func_.iter_id_) {
1117
1118 // exercise possible overloads of the member function template
1119 // on common RandomAccessIterator types
1120#undef TEST
1121#define TEST(Iterator) do { \
1122 typedef typename String::Iterator Iter; \
1123 static const \
1124 ReplaceRangeOverload<String, Iter> rng; \
1125 test_replace ((charT*)0, (Traits*)0, (Allocator*)0, rng, tdata); \
1126 } while (0)
1127
1128 case StringIds::Pointer: TEST (pointer); break;
1129 case StringIds::ConstPointer: TEST (const_pointer); break;
1130 case StringIds::Iterator: TEST (iterator); break;
1131 case StringIds::ConstIterator: TEST (const_iterator); break;
1132
1133 case StringIds::ReverseIterator: TEST (reverse_iterator); break;
1134 case StringIds::ConstReverseIterator: TEST (const_reverse_iterator);
1135 break;
1136
1137 // exercise specializations of the member function template
1138 // on the required iterator categories
1139#undef TEST
1140#define TEST(Iterator) do { \
1141 typedef Iterator<charT> Iter; \
1142 static const \
1143 ReplaceRange<String, Iter> rng; \
1144 test_replace ((charT*)0, (Traits*)0, (Allocator*)0, rng, tdata); \
1145 } while (0)
1146
1147 case StringIds::Input: TEST (InputIter); break;
1148 case StringIds::Forward: TEST (ConstFwdIter); break;
1149 case StringIds::Bidir: TEST (ConstBidirIter); break;
1151
1152 default:
1153 rw_error (0, 0, __LINE__, "bad iterator id");
1154 }
1155 }
1156 else {
1157 // exercise ordinary overloads of the member function
1158 static const RangeBase<String> rng;
1159 test_replace ((charT*)0, (Traits*)0, (Allocator*)0, rng, tdata);
1160 }
1161}
1162
1163
1166
1167int main (int argc, char** argv)
1168{
1169 static const StringTest
1170 tests [] = {
1171
1172#undef TEST
1173#define TEST(sig) { \
1174 Replace (sig), sig ## _test_cases, \
1175 sizeof sig ## _test_cases / sizeof *sig ## _test_cases, \
1176 }
1177
1178 TEST (size_size_cptr),
1179 TEST (size_size_cstr),
1180 TEST (size_size_cptr_size),
1181 TEST (size_size_cstr_size_size),
1182 TEST (size_size_size_val),
1183 TEST (iter_iter_cptr),
1184 TEST (iter_iter_cstr),
1185 TEST (iter_iter_cptr_size),
1186 TEST (iter_iter_size_val),
1187 TEST (iter_iter_range)
1188 };
1189
1190 const std::size_t test_count = sizeof tests / sizeof *tests;
1191
1192 const int status =
1193 rw_run_string_test (argc, argv, __FILE__,
1194 "lib.string.replace",
1195 test_replace_func_array, tests, test_count);
1196
1197 return status;
1198}
#define last
Definition 17.names.cpp:487
#define off
Definition 17.names.cpp:507
#define charT
Definition 17.names.cpp:456
#define TEST(str, off, size, arg, res, bthrow)
void test_replace(charT *, Traits *, Allocator *, const RangeBase< std::basic_string< charT, Traits, Allocator > > &rng, const StringTestCaseData< charT > &tdata)
#define Replace(sig)
std::char_traits< S > Traits
const int end
#define main
int caught
const StringTestCase & tcase_
Definition rw_strings.h:692
const charT *const arg_
Definition rw_strings.h:688
const charT *const res_
Definition rw_strings.h:689
const StringFunc & func_
Definition rw_strings.h:691
const charT *const str_
Definition rw_strings.h:687
const char * str
Definition exec.cpp:170
_TEST_EXPORT void rw_check_leaks(const SharedAlloc *=0, int=0, _RWSTD_SIZE_T=0, _RWSTD_SIZE_T=_RWSTD_SIZE_MAX)
UserChar make_char(char c, UserChar *)
Definition rw_char.h:74
_RWSTD_SIZE_T * rw_get_call_counters(std::char_traits< charT > *, charT *)
Definition rw_char.h:495
_TEST_EXPORT _RWSTD_SIZE_T rw_match(const char *, const char *, _RWSTD_SIZE_T=_RWSTD_SIZE_MAX)
_TEST_EXPORT int rw_assert(int, const char *, int, const char *,...)
Definition driver.cpp:1630
_TEST_EXPORT int rw_error(int, const char *, int, const char *,...)
Definition driver.cpp:1613
_TEST_EXPORT rwt_free_store * rwt_get_free_store(rwt_free_store *)
Definition new.cpp:597
StringState rw_get_string_state(const String &str)
Definition rw_strings.h:752
_TEST_EXPORT int rw_run_string_test(int, char **, const char *, const char *, StringTestFunc *, const StringTest *, _RWSTD_SIZE_T)
#define DEFINE_STRING_TEST_FUNCTIONS(fname)
Definition rw_strings.h:909
#define RW_ASSERT(expr)
static StringPtr begin(String &str, StringPtr *)
Definition rw_strings.h:781
virtual String & operator()(String &str, const StringTestCaseData< StringChar > &tdata) const
String::value_type StringChar
String::iterator StringIter
virtual String & operator()(String &str, const StringTestCaseData< StringChar > &tdata) const
String::value_type StringChar
String::iterator StringIter
static SharedAlloc * instance(SharedAlloc *=0)
_RWSTD_SIZE_T throw_at_calls_[n_funs]
StringIds::OverloadId which_
Definition rw_strings.h:577
StringIds::IteratorId iter_id_
Definition rw_strings.h:576
static ArgId arg_type(OverloadId id, int argno)
Definition rw_strings.h:559
_RWSTD_SIZE_T capacity_
Definition rw_strings.h:741
int assert_equal(const StringState &, int, int, const char *) const
const char * arg
Definition rw_strings.h:599
const char * res
Definition rw_strings.h:602
_RWSTD_SIZE_T * throw_at_calls_[2]
Definition rw_new.h:83
_RWSTD_SIZE_T new_calls_[2]
Definition rw_new.h:47
int arg
Definition locale.cpp:2806