Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
21.string.insert.cpp
Go to the documentation of this file.
1
27#include <string> // for string
28#include <stdexcept> // for out_of_range, length_error
29#include <cstddef> // for size_t
30
31#include <rw_strings.h> // for StringIds
32#include <rw_alg_test.h> // for InputIter
33#include <rw_driver.h> // for rw_test()
34#include <rw_allocator.h> // for UserAlloc
35#include <rw_char.h> // for rw_expand()
36#include <rw_new.h> // for bad_alloc, replacement operator new
37
38
40// for convenience and brevity
41#define Insert(sig) StringIds::insert_ ## sig
42
43static const char* const exceptions[] = {
44 "unknown exception", "out_of_range", "length_error",
45 "bad_alloc", "exception"
46};
47
48
50// used to exercise
51// insert (size_type, const value_type*)
52static const StringTestCase
53size_cptr_test_cases [] = {
54
55#undef TEST
56#define TEST(str, off, arg, res, bthrow) { \
57 __LINE__, off, -1, -1, -1, -1, str, sizeof str - 1, \
58 arg, sizeof arg - 1, res, sizeof res - 1, bthrow \
59 }
60
61 // +----------------------------------------- controlled sequence
62 // | +------------------------ insert() pos argument
63 // | | +--------------------- sequence to be inserted
64 // | | | +--------- expected result sequence
65 // | | | | +- exception info
66 // | | | | | 0 - no exception
67 // | | | | | 1 - out_of_range
68 // | | | | | 2 - length_error
69 // | | | | | -1 - exc. safety
70 // | | | | |
71 // | | | | +-------------+
72 // V V V V V
73 TEST ("ab", 0, "c", "cab", 0),
74
75 TEST ("", 0, "", "", 0),
76 TEST ("", 0, "abc", "abc", 0),
77
78 TEST ("<U0>", 0, "", "<U0>", 0),
79 TEST ("", 0, "<U0>", "", 0),
80
81 TEST ("abc", 0, "", "abc", 0),
82 TEST ("abc", 1, "", "abc", 0),
83 TEST ("abc", 3, "", "abc", 0),
84
85 TEST ("<U0>", 0, "a", "a<U0>", 0),
86 TEST ("<U0>", 1, "a", "<U0>a", 0),
87 TEST ("<U0>", 0, "<U0>", "<U0>", 0),
88 TEST ("<U0>", 1, "<U0>@2", "<U0>", 0),
89
90 TEST ("cde", 0, "ab", "abcde", 0),
91 TEST ("cde", 1, "ab", "cabde", 0),
92 TEST ("cde", 2, "ab", "cdabe", 0),
93 TEST ("cde", 3, "ab", "cdeab", 0),
94
95 TEST ("<U0>ab<U0>@2c", 0, "<U0>e<U0>", "<U0>ab<U0>@2c", 0),
96 TEST ("a<U0>b<U0>@2c", 2, "e<U0>e", "a<U0>eb<U0>@2c", 0),
97 TEST ("a<U0>bc<U0>@2", 6, "e<U0>e", "a<U0>bc<U0>@2e", 0),
98
99 TEST ("", 0, 0, "", 0),
100 TEST ("abc", 0, 0, "abcabc", 0),
101 TEST ("abc", 2, 0, "ababcc", 0),
102 TEST ("a<U0>bc<U0>@2", 0, 0, "aa<U0>bc<U0>@2", 0),
103 TEST ("a<U0>bc<U0>@2", 6, 0, "a<U0>bc<U0>@2a", 0),
104 TEST ("x@4096", 5, 0, "x@8192", 0),
105
106 TEST ("", 0, "x@4096", "x@4096", 0),
107 TEST ("x@4096", 0, "", "x@4096", 0),
108 TEST ("x@4096", 2, "a@100", "xxa@100x@4094", 0),
109 TEST ("a@102", 2, "x@4096", "aax@4096a@100", 0),
110
111 TEST ("x@10", 1, "x@118", "x@128", 0),
112 TEST ("x@128", 128, "x@79", "x@207", 0),
113 TEST ("x@207", 0, "x@127", "x@334", 0),
114 TEST ("x@334", 1, "x@206", "x@540", 0),
115 TEST ("x@540", 539, "x@333", "x@873", 0),
116 TEST ("x@539", 539, "x@873", "x@1412", 0),
117 TEST ("x@872", 0, "x@1412", "x@2284", 0),
118 TEST ("x@1411", 207, "x@2284", "x@3695", 0),
119 TEST ("x@1412", 0, "x@2284", "x@3696", 0),
120
121 TEST ("<U0>", 2, "", "", 1),
122 TEST ("a", 2, "", "", 1),
123 TEST ("x@4096", 4106, "", "", 1),
124
125 TEST ("last", 4, "test", "lasttest", 0)
126};
127
128
130// used to exercise
131// insert (size_type, const basic_string&)
132static const StringTestCase
133size_cstr_test_cases [] = {
134
135#undef TEST
136#define TEST(str, off, arg, res, bthrow) { \
137 __LINE__, off, -1, -1, -1, -1, str, sizeof str - 1, \
138 arg, sizeof arg - 1, res, sizeof res - 1, bthrow \
139 }
140
141 // +----------------------------------------- controlled sequence
142 // | +------------------------ insert() pos argument
143 // | | +--------------------- sequence to be inserted
144 // | | | +--------- expected result sequence
145 // | | | | +- exception info
146 // | | | | | 0 - no exception
147 // | | | | | 1 - out_of_range
148 // | | | | | 2 - length_error
149 // | | | | | -1 - exc. safety
150 // | | | | |
151 // | | | | -+------------+
152 // V V V V V
153 TEST ("ab", 0, "c", "cab", 0),
154
155 TEST ("", 0, "", "", 0),
156 TEST ("", 0, "abc", "abc", 0),
157
158 TEST ("<U0>", 0, "", "<U0>", 0),
159 TEST ("", 0, "<U0>", "<U0>", 0),
160
161 TEST ("abc", 0, "", "abc", 0),
162 TEST ("abc", 1, "", "abc", 0),
163 TEST ("abc", 3, "", "abc", 0),
164
165 TEST ("<U0>", 0, "a", "a<U0>", 0),
166 TEST ("<U0>", 1, "a", "<U0>a", 0),
167 TEST ("<U0>", 0, "<U0>", "<U0>@2", 0),
168 TEST ("<U0>", 1, "<U0>@2", "<U0>@3", 0),
169
170 TEST ("cde", 0, "ab", "abcde", 0),
171 TEST ("cde", 1, "ab", "cabde", 0),
172 TEST ("cde", 2, "ab", "cdabe", 0),
173 TEST ("cde", 3, "ab", "cdeab", 0),
174
175 TEST ("<U0>ab<U0>@2c", 0, "<U0>e<U0>", "<U0>e<U0>@2ab<U0>@2c", 0),
176 TEST ("a<U0>b<U0>@2c", 2, "e<U0>e", "a<U0>e<U0>eb<U0>@2c", 0),
177 TEST ("a<U0>bc<U0>@2", 6, "e<U0>@2e<U0>", "a<U0>bc<U0>@2e<U0>@2e<U0>", 0),
178
179 TEST ("abc", 0, 0, "abcabc", 0),
180 TEST ("abc", 2, 0, "ababcc", 0),
181 TEST ("a<U0>bc<U0>@2", 0, 0, "a<U0>bc<U0>@2a<U0>bc<U0>@2", 0),
182 TEST ("a<U0>bc<U0>@2", 6, 0, "a<U0>bc<U0>@2a<U0>bc<U0>@2", 0),
183 TEST ("x@4096", 5, 0, "x@8192", 0),
184
185 TEST ("", 0, "x@4096", "x@4096", 0),
186 TEST ("x@4096", 0, "", "x@4096", 0),
187 TEST ("x@4096", 2, "a@100", "xxa@100x@4094", 0),
188 TEST ("a@102", 2, "x@4096", "aax@4096a@100", 0),
189
190 TEST ("x@10", 1, "x@118", "x@128", 0),
191 TEST ("x@128", 128, "x@79", "x@207", 0),
192 TEST ("x@207", 0, "x@127", "x@334", 0),
193 TEST ("x@334", 1, "x@206", "x@540", 0),
194 TEST ("x@540", 539, "x@333", "x@873", 0),
195 TEST ("x@539", 539, "x@873", "x@1412", 0),
196 TEST ("x@872", 0, "x@1412", "x@2284", 0),
197 TEST ("x@1411", 207, "x@2284", "x@3695", 0),
198 TEST ("x@1412", 0, "x@2284", "x@3696", 0),
199
200 TEST ("<U0>", 2, "", "", 1),
201 TEST ("a", 2, "", "", 1),
202 TEST ("x@4096", 4106, "", "", 1),
203
204 TEST ("last", 4, "test", "lasttest", 0)
205};
206
207
209// exrcises
210// insert (size_type, basic_string&, size_type, size_type)
211// insert (iterator, InputIterator, InputIterator)
212static const StringTestCase
213iter_range_test_cases [] = {
214
215// range_test_cases serves a double duty
216#define size_cstr_size_size_test_cases iter_range_test_cases
217
218#undef TEST
219#define TEST(str, off, arg, off2, size2, res, bthrow) { \
220 __LINE__, off, -1, off2, size2, -1, str, sizeof str - 1, \
221 arg, sizeof arg - 1, res, sizeof res - 1, bthrow \
222 }
223
224 // +----------------------------------------- controlled sequence
225 // | +------------------------ insert() pos argument
226 // | | +--------------------- sequence to be inserted
227 // | | | +-------- insert() off2 argument
228 // | | | | +----- insert() num argument
229 // | | | | | +-- expected result sequence
230 // | | | | | | +--- exception info
231 // | | | | | | | 0 - no exception
232 // | | | | | | | 1 - out_of_range
233 // | | | | | | | 2 - length_error
234 // | | | | | | | -1 - exc. safety
235 // | | | | | | |
236 // | | | | | | +----------------+
237 // V V V V V V V
238 TEST ("ab", 0, "c", 0, 1, "cab", 0),
239
240 TEST ("", 0, "", 0, 0, "", 0),
241 TEST ("", 0, "abc", 1, 1, "b", 0),
242 TEST ("", 0, "<U0>", 0, 1, "<U0>", 0),
243
244 TEST ("<U0>", 0, "", 0, 0, "<U0>", 0),
245 TEST ("<U0>", 1, "", 0, 0, "<U0>", 0),
246
247 TEST ("abc", 0, "", 0, 0, "abc", 0),
248 TEST ("abc", 1, "", 0, 0, "abc", 0),
249 TEST ("abc", 3, "", 0, 0, "abc", 0),
250
251 TEST ("<U0>", 0, "a", 0, 1, "a<U0>", 0),
252 TEST ("<U0>", 1, "a", 0, 1, "<U0>a", 0),
253 TEST ("<U0>", 0, "<U0>@2", 1, 1, "<U0>@2", 0),
254 TEST ("<U0>", 1, "<U0>@2", 0, 2, "<U0>@3", 0),
255 TEST ("<U0>", 1, "<U0>@2", 1, 5, "<U0>@2", 0),
256
257 TEST ("cde", 0, "ab", 0, 2, "abcde", 0),
258 TEST ("cde", 1, "ab", 0, 1, "cade", 0),
259 TEST ("cde", 2, "ab", 1, 5, "cdbe", 0),
260 TEST ("cde", 3, "ab", 1, 1, "cdeb", 0),
261
262 TEST ("ab", 0, "c<U0>e", 0, 3, "c<U0>eab", 0),
263 TEST ("ab", 1, "c<U0>e", 1, 2, "a<U0>eb", 0),
264 TEST ("ab", 2, "c<U0>e", 0, 2, "abc<U0>", 0),
265
266 TEST ("<U0>e<U0>", 1, "<U0>ab<U0>@2c", 0, 9, "<U0>@2ab<U0>@2ce<U0>",0),
267 TEST ("<U0>e<U0>", 1, "<U0>ab<U0>@2c", 0, 3, "<U0>@2abe<U0>", 0),
268 TEST ("a<U0>b<U0>@2c", 3, "<U0>e<U0>", 0, 3, "a<U0>b<U0>e<U0>@3c", 0),
269 TEST ("a<U0>b<U0>@2c", 2, "<U0>@2e<U0>", 0, 2, "a<U0>@3b<U0>@2c", 0),
270 TEST ("<U0>ab<U0>@2c", 0, "<U0>e<U0>", 2, 1, "<U0>@2ab<U0>@2c", 0),
271 TEST ("a<U0>bc<U0>@2", 6, "<U0>e", 0, 2, "a<U0>bc<U0>@3e", 0),
272
273 TEST ("abc", 0, 0, 1, 1, "babc", 0),
274 TEST ("abc", 2, 0, 0, 2, "ababc", 0),
275 TEST ("a<U0>bc<U0>@2", 0, 0, 4, 2, "<U0>@2a<U0>bc<U0>@2", 0),
276 TEST ("a<U0>bc<U0>@2", 6, 0, 1, 3, "a<U0>bc<U0>@3bc", 0),
277 TEST ("abcdef", 0, 0, 1, 2, "bcabcdef", 0),
278
279 TEST ("", 0, "x@4096", 0, 4096, "x@4096", 0),
280 TEST ("x@4096", 0, "", 0, 0, "x@4096", 0),
281 TEST ("a@1000", 0, "b@1000", 0, 999, "b@999a@1000", 0),
282 TEST ("a@1000", 1, "b@1001", 0, 1000, "ab@1000a@999", 0),
283 TEST ("a@1000", 2, "b@1002", 0, 1001, "aab@1001a@998", 0),
284 TEST ("a@1000", 998, "b@1000", 1, 999, "a@998b@999aa", 0),
285 TEST ("a@1000", 999, "b@1001", 2, 1000, "a@999b@999a", 0),
286 TEST ("a@1000", 2, "b@1002", 999, 1001, "aabbba@998", 0),
287
288 TEST ("x@10", 1, "x@118", 0, 118, "x@128", 0),
289 TEST ("x@128", 0, "x@129", 50, 79, "x@207", 0),
290 TEST ("x@207", 207, "x@127", 0, 127, "x@334", 0),
291 TEST ("x@207", 128, "x@207", 10, 127, "x@334", 0),
292 TEST ("x@334", 334, "x@208", 2, 206, "x@540", 0),
293 TEST ("x@540", 0, "x@336", 3, 333, "x@873", 0),
294 TEST ("x@539", 538, "x@873", 0, 873, "x@1412", 0),
295 TEST ("x@873", 540, "x@540", 1, 539, "x@1412", 0),
296 TEST ("x@872", 0, "x@1412", 0, 1412, "x@2284", 0),
297 TEST ("x@1411", 1411, "x@2288", 4, 2284, "x@3695", 0),
298 TEST ("x@1411", 872, "x@3695", 128, 2284, "x@3695", 0),
299 TEST ("x@1412", 0, "x@2284", 0, 2284, "x@3696", 0),
300
301 TEST ("<U0>", 2, "", 0, 0, "<U0>", 1),
302 TEST ("", 0, "<U0>", 2, 0, "", 2),
303
304 TEST ("a", 2, "", 0, 0, "a", 1),
305 TEST ("", 0, "a", 2, 0, "", 2),
306
307 TEST ("x@4096", 4106, "", 0, 0, "x@4096", 1),
308 TEST ("", 0, "x@4096", 4106, 0, "", 2),
309
310 TEST ("last", 4, "test", 0, 4, "lasttest", 0)
311};
312
313
315// used to exercise
316// insert (size_type, const value_type*, size_type)
317static const StringTestCase
318size_cptr_size_test_cases [] = {
319
320#undef TEST
321#define TEST(str, off, arg, size2, res, bthrow) { \
322 __LINE__, off, -1, -1, size2, -1, str, sizeof str - 1, \
323 arg, sizeof arg - 1, res, sizeof res - 1, bthrow }
324
325 // +----------------------------------------- controlled sequence
326 // | +------------------------ insert() pos argument
327 // | | +--------------------- sequence to be inserted
328 // | | | +-------- insert() num argument
329 // | | | | +----- expected result sequence
330 // | | | | | +--- exception info
331 // | | | | | | 0 - no exception
332 // | | | | | | 1 - out_of_range
333 // | | | | | | 2 - length_error
334 // | | | | | | -1 - exc. safety
335 // | | | | | |
336 // | | | | | +-----------+
337 // V V V V V V
338 TEST ("ab", 0, "c", 1, "cab", 0),
339
340 TEST ("", 0, "", 0, "", 0),
341 TEST ("", 0, "abc", 1, "a", 0),
342
343 TEST ("<U0>", 0, "", 0, "<U0>", 0),
344 TEST ("<U0>", 1, "", 0, "<U0>", 0),
345 TEST ("", 0, "<U0>", 1, "<U0>", 0),
346
347 TEST ("<U0>", 0, "a", 0, "<U0>", 0),
348 TEST ("<U0>", 1, "a", 1, "<U0>a", 0),
349 TEST ("<U0>", 0, "<U0>@2", 1, "<U0>@2", 0),
350 TEST ("<U0>", 1, "<U0>@2", 2, "<U0>@3", 0),
351
352 TEST ("cde", 0, "ab", 2, "abcde", 0),
353 TEST ("cde", 1, "ab", 1, "cade", 0),
354 TEST ("cde", 3, "ab", 1, "cdea", 0),
355 TEST ("cde", 2, "ab", 2, "cdabe", 0),
356
357 TEST ("<U0>e<U0>", 3, "a<U0>b<U0>@2c", 0, "<U0>e<U0>", 0),
358 TEST ("<U0>e<U0>", 3, "<U0>ab<U0>@2c", 3, "<U0>e<U0>@2ab", 0),
359
360 TEST ("a<U0>b<U0>@2c", 3, "<U0>e<U0>", 3, "a<U0>b<U0>e<U0>@3c", 0),
361 TEST ("a<U0>b<U0>@2c", 2, "<U0>@2e<U0>", 2, "a<U0>@3b<U0>@2c", 0),
362 TEST ("<U0>ab<U0>@2c", 0, "<U0>e<U0>", 1, "<U0>@2ab<U0>@2c", 0),
363 TEST ("a<U0>bc<U0>@2", 6, "<U0>e", 2, "a<U0>bc<U0>@3e", 0),
364
365 TEST ("abc", 0, 0, 1, "aabc", 0),
366 TEST ("abc", 2, 0, 2, "ababc", 0),
367 TEST ("<U0>abc<U0>@2", 0, 0, 1, "<U0>@2abc<U0>@2", 0),
368 TEST ("a<U0>bc<U0>@2", 6, 0, 3, "a<U0>bc<U0>@2a<U0>b", 0),
369 TEST ("a@4096", 0, 0, 1111, "a@5207", 0),
370 TEST ("b@4096", 1, 0, 2222, "b@6318", 0),
371
372 TEST ("x@4096", 1, "<U0>", 1, "x<U0>x@4095", 0),
373 TEST ("x@4096", 0, "<U0>", 1, "<U0>x@4096", 0),
374 TEST ("x@4096", 4096, "<U0>", 1, "x@4096<U0>", 0),
375 TEST ("x@4096", 0, "ab", 2, "abx@4096", 0),
376 TEST ("x@4096", 4095, "ab", 1, "x@4095ax", 0),
377 TEST ("x@4096", 4094, "<U0>@2", 2, "x@4094<U0>@2xx", 0),
378
379 TEST ("", 0, "x@4096", 4096, "x@4096", 0),
380 TEST ("x@4096", 0, "", 0, "x@4096", 0),
381
382 TEST ("", 0, "x@873", 540, "x@540", 0),
383 TEST ("x@10", 1, "x@118", 118, "x@128", 0),
384 TEST ("x@128", 128, "x@79", 79, "x@207", 0),
385 TEST ("x@207", 0, "x@127", 127, "x@334", 0),
386 TEST ("x@207", 207, "x@207", 127, "x@334", 0),
387 TEST ("x@334", 128, "x@206", 206, "x@540", 0),
388 TEST ("x@540", 540, "x@333", 333, "x@873", 0),
389 TEST ("x@539", 0, "x@873", 873, "x@1412", 0),
390 TEST ("x@873", 5, "x@540", 539, "x@1412", 0),
391 TEST ("x@872", 0, "x@1412", 1412, "x@2284", 0),
392 TEST ("x@1411", 1411, "x@2284", 2284, "x@3695", 0),
393 TEST ("x@1411", 873, "x@3695", 2284, "x@3695", 0),
394 TEST ("x@1412", 0, "x@2284", 2284, "x@3696", 0),
395 TEST ("", 0, "x@3696", 3696, "x@3696", 0),
396
397 TEST ("<U0>", 2, "", 0, "", 1),
398 TEST ("a", 2, "", 0, "", 1),
399 TEST ("x@4096", 4106, "", 0, "", 1),
400
401 TEST ("last", 4, "test", 4, "lasttest", 0)
402};
403
404
406// exrecises
407// insert (size_type, size_type, value_type)
408// insert (iterator, size_type, value_type)
409static const StringTestCase
410iter_size_val_test_cases [] = {
411
412// size_val_test_cases serves a double duty
413#define size_size_val_test_cases iter_size_val_test_cases
414
415#undef TEST
416#define TEST(str, off, size2, val, res, bthrow) { \
417 __LINE__, off, -1, -1, size2, val, str, sizeof str - 1, \
418 0, 0, res, sizeof res - 1, bthrow \
419 }
420
421 // +---------------------------------------- controlled sequence
422 // | +----------------------- insert() pos argument
423 // | | +-------------------- insert() size2 argument
424 // | | | +------------- character to be inserted
425 // | | | | +--------- expected result sequence
426 // | | | | | +- exception info
427 // | | | | | | 0 - no exception
428 // | | | | | | 1 - out_of_range
429 // | | | | | | 2 - length_error
430 // | | | | | | -1 - exc. safety
431 // | | | | | |
432 // | | | | | +---------+
433 // V V V V V V
434 TEST ("ab", 0, 1, 'c', "cab", 0),
435
436 TEST ("", 0, 0, ' ', "", 0),
437 TEST ("", 0, 1, 'b', "b", 0),
438
439 TEST ("<U0>", 0, 0, ' ', "<U0>", 0),
440 TEST ("<U0>", 1, 0, ' ', "<U0>", 0),
441 TEST ("", 0, 2, '\0', "<U0>@2", 0),
442
443 TEST ("<U0>", 0, 1, 'a', "a<U0>", 0),
444 TEST ("<U0>", 1, 1, 'a', "<U0>a", 0),
445 TEST ("<U0>", 0, 1, '\0', "<U0>@2", 0),
446 TEST ("<U0>", 1, 2, '\0', "<U0>@3", 0),
447 TEST ("<U0>", 1, 0, '\0', "<U0>", 0),
448
449 TEST ("cde", 0, 2, 'a', "aacde", 0),
450 TEST ("cde", 1, 1, 'a', "cade", 0),
451 TEST ("cde", 3, 3, 'a', "cdeaaa", 0),
452 TEST ("cde", 2, 3, 'a', "cdaaae", 0),
453
454 TEST ("ab", 0, 2, '\0', "<U0>@2ab", 0),
455 TEST ("ab", 1, 1, '\0', "a<U0>b", 0),
456 TEST ("ab", 2, 2, '\0', "ab<U0>@2", 0),
457
458 TEST ("a<U0>b<U0>@2c", 3, 2, '\0', "a<U0>b<U0>@3<U0>c", 0),
459 TEST ("a<U0>b<U0>@2c", 2, 1, '\0', "a<U0>@2b<U0>@2c", 0),
460 TEST ("<U0>ab<U0>@2c", 0, 3, '\0', "<U0>@3<U0>ab<U0>@2c", 0),
461 TEST ("a<U0>bc<U0>@2", 6, 2, 'a', "a<U0>bc<U0>@2aa", 0),
462
463 TEST ("", 0, 4106, 'x', "x@4106", 0),
464 TEST ("x@4096", 0, 2, 'a', "aax@4096", 0),
465
466 TEST ("x@4096", 0, 2, 'a', "aax@4096", 0),
467 TEST ("x@4096", 1, 2, 'a', "xaax@4095", 0),
468 TEST ("x@4096", 1, 1, '\0', "x<U0>x@4095", 0),
469
470 TEST ("x@127", 0, 1, 'x', "x@128", 0),
471 TEST ("x@200", 128, 7, 'x', "x@207", 0),
472 TEST ("x@331", 331, 3, 'x', "x@334", 0),
473 TEST ("x@539", 0, 1, 'x', "x@540", 0),
474 TEST ("x@539", 0, 873, 'x', "x@1412", 0),
475 TEST ("x@873", 873, 1411, 'x', "x@2284", 0),
476 TEST ("x@3694", 128, 1, 'x', "x@3695", 0),
477 TEST ("x@540", 0, 1, 'x', "x@541", 0),
478 TEST ("", 0, 3695, 'x', "x@3695", 0),
479
480 TEST ("a", 0, 4095, 'x', "x@4095a", 0),
481 TEST ("x@4096", 0, 2047, 'b', "b@2047x@4096", 0),
482 TEST ("x@4096", 2047, 2048, 'x', "x@6144", 0),
483
484 TEST ("last", 4, 4, 't', "lasttttt", 0)
485};
486
487
489// used to exercise
490// insert (iterator, value_type)
491static const StringTestCase
492iter_val_test_cases [] = {
493
494#undef TEST
495#define TEST(str, off, val, res, bthrow) \
496 { __LINE__, off, -1, -1, -1, val, str, sizeof str - 1, 0, \
497 0, res, sizeof res - 1, bthrow }
498
499 // +----------------------------------------- controlled sequence
500 // | +------------------------ insert() pos argument
501 // | | +------------------- character to be inserted
502 // | | | +--------------- expected result sequence
503 // | | | | +--- exception info
504 // | | | | | 0 - no exception
505 // | | | | | 1 - out_of_range
506 // | | | | | 2 - length_error
507 // | | | | | -1 - exc. safety
508 // | | | | |
509 // | | | | |
510 // V V V V V
511 TEST ("ab", 0, 'c', "cab", 0),
512
513 TEST ("", 0, 'b', "b", 0),
514 TEST ("", 0, '\0', "<U0>", 0),
515
516 TEST ("<U0>", 0, 'a', "a<U0>", 0),
517 TEST ("<U0>", 1, 'a', "<U0>a", 0),
518 TEST ("<U0>", 0, '\0', "<U0>@2", 0),
519 TEST ("<U0>", 1, '\0', "<U0>@2", 0),
520
521 TEST ("cde", 0, 'a', "acde", 0),
522 TEST ("cde", 1, 'a', "cade", 0),
523 TEST ("cde", 2, 'a', "cdae", 0),
524 TEST ("cde", 3, 'a', "cdea", 0),
525
526 TEST ("a<U0>b<U0>@2c", 3, '\0', "a<U0>b<U0>@3c", 0),
527 TEST ("<U0>ab<U0>@2c", 0, '\0', "<U0>@2ab<U0>@2c", 0),
528 TEST ("a<U0>bc<U0>@2", 6, 'a', "a<U0>bc<U0>@2a", 0),
529
530 TEST ("x@4096", 0, 'a', "ax@4096", 0),
531 TEST ("x@4096", 1, 'a', "xax@4095", 0),
532 TEST ("x@4096", 1, '\0', "x<U0>x@4095", 0),
533
534 TEST ("x@127", 0, 'x', "x@128", 0),
535 TEST ("x@206", 1, 'x', "x@207", 0),
536 TEST ("x@333", 333, 'x', "x@334", 0),
537 TEST ("x@539", 128, 'x', "x@540", 0),
538 TEST ("x@1411", 0, 'x', "x@1412", 0),
539 TEST ("x@2283", 10, 'x', "x@2284", 0),
540 TEST ("x@3694", 3694, 'x', "x@3695", 0),
541 TEST ("x@540", 538, 'x', "x@541", 0),
542
543 TEST ("last", 4, 't', "lastt", 0)
544};
545
546
548// invokes specializations of the member function template
549// on the required iterator categories
550template <class String, class Iterator>
551struct InsertRange: RangeBase<String> {
552
553 typedef typename String::iterator StringIter;
554 typedef typename String::value_type StringChar;
555
557
558 virtual String&
560 const StringTestCaseData<StringChar>& tdata) const {
561
562 const StringTestCase &tcase = tdata.tcase_;
563
564 // create a pair of iterators into the string object being modified
565 const StringIter first1 (str.begin () + tdata.off1_);
566
567 const String &cstr = str;
568
569 // when (0 == tcase.arg) exercise self-referential modification
570 // (i.e., replacing a range of elements with a subrange of its
571 // own elements)
572 const StringChar* const beg =
573 (tcase.arg ? tdata.arg_ : cstr.data ()) + tdata.off2_;
574
575 const StringChar* const end = beg + tdata.ext2_;
576
577 const Iterator first2 (beg, beg, end);
578 const Iterator last2 (end, beg, end);
579
580 str.insert (first1, first2, last2);
581 return str;
582 }
583};
584
585
586// invokes possible overloads of the member function template
587// on common RandomAccessIterator types
588template <class String, class Iterator>
589struct InsertRangeOverload: RangeBase<String>
590{
591 typedef typename String::iterator StringIter;
592 typedef typename String::value_type StringChar;
593
595
596 virtual String&
598 const StringTestCaseData<StringChar>& tdata) const {
599
600 const StringTestCase &tcase = tdata.tcase_;
601
602 // create a pair of iterators into the string object being modified
603 const StringIter first1 (str.begin () + tdata.off1_);
604
605 bool reverse_iter = StringIds::ReverseIterator == tdata.func_.iter_id_
607
608 const std::size_t srclen_ = tcase.arg ? tdata.arglen_ : str.size ();
609
610 const std::size_t off =
611 reverse_iter ? srclen_ - tdata.off2_ - tdata.ext2_ : tdata.off2_;
612 const std::size_t ext = tdata.ext2_;
613
614 if (0 == tcase.arg) {
615 // exercise self-referential modification (i.e., replacing
616 // a range of elements with a subrange of its own elements)
617
618 const Iterator first2 (this->begin (str, (Iterator*)0) + off);
619 const Iterator last2 (first2 + ext);
620
621 str.insert (first1, first2, last2);
622 return str;
623 }
624
625 String str_arg (tdata.arg_, tdata.arglen_);
626
627 const Iterator first2 (this->begin (str_arg, (Iterator*)0) + off);
628 const Iterator last2 (first2 + ext);
629
630 str.insert (first1, first2, last2);
631 return str;
632 }
633};
634
635
637template <class charT, class Traits, class Allocator>
639 std::basic_string <charT, Traits, Allocator> > &rng,
640 const StringTestCaseData<charT> &tdata)
641{
642 typedef std::basic_string <charT, Traits, Allocator> String;
643 typedef typename String::iterator StringIter;
644 typedef typename UserTraits<charT>::MemFun TraitsFunc;
645
646 const StringFunc &func = tdata.func_;
647 const StringTestCase &tcase = tdata.tcase_;
648
649 // construct the string object to be modified
650 // and the (possibly unused) argument string
651 /* const */ String str (tdata.str_, tdata.strlen_);
652 const String arg (tdata.arg_, tdata.arglen_);
653
654 // save the state of the string object before the call
655 // to detect wxception safety violations (changes to
656 // the state of the object after an exception)
657 const StringState str_state (rw_get_string_state (str));
658
659 std::ptrdiff_t exp_off = Insert (iter_val) == func.which_ ? tcase.off : 0;
660
661 // compute the offset and the extent (the number of elements)
662 // of the first range into the string object being modified
663 const std::size_t size1 = tdata.strlen_;
664 const std::size_t off1 =
665 std::size_t (tcase.off) < size1 ? std::size_t (tcase.off) : size1;
666
667 const charT* const arg_ptr = tcase.arg ? arg.c_str () : str.c_str ();
668 const String& arg_str = tcase.arg ? arg : str;
669 const charT arg_val = make_char (char (tcase.val), (charT*)0);
670
671 std::size_t total_length_calls = 0;
672 std::size_t n_length_calls = 0;
673 std::size_t* const rg_calls = rw_get_call_counters ((Traits*)0, (charT*)0);
674
675 if (rg_calls)
676 total_length_calls = rg_calls [TraitsFunc::length];
677
678 rwt_free_store* const pst = rwt_get_free_store (0);
679 SharedAlloc* const pal = SharedAlloc::instance ();
680
681 // iterate for`throw_after' starting at the next call to operator new,
682 // forcing each call to throw an exception, until the function finally
683 // succeeds (i.e, no exception is thrown)
684 std::size_t throw_count;
685 for (throw_count = 0; ; ++throw_count) {
686
687 // (name of) expected and caught exception
688 const char* expected = 0;
689 const char* caught = 0;
690
691#ifndef _RWSTD_NO_EXCEPTIONS
692
693 const bool use_iters =
695
696 if (1 == tcase.bthrow && !use_iters)
697 expected = exceptions [1]; // out_of_range
698 else if ( 2 == tcase.bthrow
699 && Insert (size_cstr_size_size) == func.which_)
700 expected = exceptions [1]; // out_of_range
701 else if (3 == tcase.bthrow && !use_iters)
702 expected = exceptions [2]; // length_error
703 else if (0 == tcase.bthrow) {
704 // by default excercise the exception safety of the function
705 // by iteratively inducing an exception at each call to operator
706 // new or Allocator::allocate() until the call succeeds
707 expected = exceptions [3]; // bad_alloc
708 *pst->throw_at_calls_ [0] = pst->new_calls_ [0] + throw_count + 1;
709 pal->throw_at_calls_ [pal->m_allocate] =
710 pal->throw_at_calls_ [pal->m_allocate] + throw_count + 1;
711 }
712 else {
713 // exceptions disabled for this test case
714 }
715
716#else // if defined (_RWSTD_NO_EXCEPTIONS)
717
718 if (tcase.bthrow)
719 return;
720
721#endif // _RWSTD_NO_EXCEPTIONS
722
723 // pointer to the returned reference
724 const String* ret_ptr = 0;
725
726 // start checking for memory leaks
727 rw_check_leaks (str.get_allocator ());
728
729 try {
730 switch (func.which_) {
731
732 case Insert (size_cptr):
733 ret_ptr = &str.insert (tcase.off, arg_ptr);
734 if (rg_calls)
735 n_length_calls = rg_calls [TraitsFunc::length];
736 break;
737
738 case Insert (size_cstr):
739 ret_ptr = &str.insert (tcase.off, arg_str);
740 break;
741
742 case Insert (size_cptr_size):
743 ret_ptr = &str.insert (tcase.off, arg_ptr, tcase.size2);
744 break;
745
746 case Insert (size_cstr_size_size):
747 ret_ptr =
748 &str.insert (tcase.off, arg_str, tcase.off2, tcase.size2);
749 break;
750
751 case Insert (size_size_val):
752 ret_ptr = &str.insert (tcase.off, tcase.size2, arg_val);
753 break;
754
755 case Insert (iter_size_val): {
756 const StringIter it (str.begin () + off1);
757 str.insert (it, tcase.size2, arg_val);
758 ret_ptr = &str; // function returns void
759 break;
760 }
761
762 case Insert (iter_val): {
763 StringIter it (str.begin () + off1);
764 it = str.insert (it, arg_val);
765 ret_ptr = &str + (it - str.begin ());
766 break;
767 }
768
769 case Insert (iter_range): {
770 ret_ptr = &rng (str, tdata); // function returns void
771 break;
772 }
773
774 default:
775 RW_ASSERT (!"logic error: unknown insert overload");
776 return;
777 }
778
779 // verify that the reference returned from the function
780 // refers to the modified string object (i.e., *this
781 // within the function)
782 const std::ptrdiff_t ret_off = ret_ptr - &str;
783
784 // verify the returned value
785 rw_assert (exp_off == ret_off, 0, tcase.line,
786 "line %d. %{$FUNCALL} %{?}== begin() + %td, got %td%{;}"
787 "%{?}returned invalid reference, offset is %td%{;}",
788 __LINE__, Insert (iter_val) == func.which_,
789 exp_off, ret_off,
790 Insert (iter_val) != func.which_, ret_off);
791
792 // for convenience
793 static const int cwidth = sizeof (charT);
794
795 // verfiy that strings length are equal
796 rw_assert (tdata.reslen_ == str.size (), 0, tcase.line,
797 "line %d. %{$FUNCALL} expected %{/*.*Gs} with length "
798 "%zu, got %{/*.*Gs} with length %zu", __LINE__,
799 cwidth, int (tdata.reslen_), tdata.res_, tdata.reslen_,
800 cwidth, int (str.size ()), str.c_str (), str.size ());
801
802 if (tdata.reslen_ == str.size ()) {
803 // if the result length matches the expected length
804 // (and only then), also verify that the modified
805 // string matches the expected result
806 const std::size_t match =
807 rw_match (tcase.res, str.c_str(), str.size ());
808
809 rw_assert (match == tdata.reslen_, 0, tcase.line,
810 "line %d. %{$FUNCALL} expected %{/*.*Gs}, "
811 "got %{/*.*Gs}, difference at offset %zu",
812 __LINE__, cwidth, int (tdata.reslen_), tdata.res_,
813 cwidth, int (str.size ()), str.c_str (), match);
814 }
815
816 // verify that Traits::length was used
817 if (Insert (size_cptr) == func.which_ && rg_calls) {
818 rw_assert (n_length_calls - total_length_calls > 0,
819 0, tcase.line, "line %d. %{$FUNCALL} doesn't "
820 "use traits::length()", __LINE__);
821 }
822 }
823
824#ifndef _RWSTD_NO_EXCEPTIONS
825
826 catch (const std::out_of_range &ex) {
827 caught = exceptions [1];
828 rw_assert (caught == expected, 0, tcase.line,
829 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
830 "unexpectedly%{;} caught std::%s(%#s)",
831 __LINE__, 0 != expected, expected, caught, ex.what ());
832 }
833 catch (const std::length_error &ex) {
834 caught = exceptions [2];
835 rw_assert (caught == expected, 0, tcase.line,
836 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
837 "unexpectedly%{;} caught std::%s(%#s)",
838 __LINE__, 0 != expected, expected, caught, ex.what ());
839 }
840 catch (const std::bad_alloc &ex) {
841 caught = exceptions [3];
842 rw_assert (0 == tcase.bthrow, 0, tcase.line,
843 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
844 "unexpectedly%{;} caught std::%s(%#s)",
845 __LINE__, 0 != expected, expected, caught, ex.what ());
846 }
847 catch (const std::exception &ex) {
848 caught = exceptions [4];
849 rw_assert (0, 0, tcase.line,
850 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
851 "unexpectedly%{;} caught std::%s(%#s)",
852 __LINE__, 0 != expected, expected, caught, ex.what ());
853 }
854 catch (...) {
855 caught = exceptions [0];
856 rw_assert (0, 0, tcase.line,
857 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
858 "unexpectedly%{;} caught %s",
859 __LINE__, 0 != expected, expected, caught);
860 }
861
862#endif // _RWSTD_NO_EXCEPTIONS
863
864 // FIXME: verify the number of blocks the function call
865 // is expected to allocate and detect any memory leaks
866 rw_check_leaks (str.get_allocator (), tcase.line,
867 std::size_t (-1), std::size_t (-1));
868
869 if (caught) {
870 // verify that an exception thrown during allocation
871 // didn't cause a change in the state of the object
873 __LINE__, tcase.line, caught);
874
875 if (0 == tcase.bthrow) {
876 // allow this call to operator new to succeed and try
877 // to make the next one to fail during the next call
878 // to the same function again
879 continue;
880 }
881 }
882 else if (0 < tcase.bthrow) {
883 rw_assert (caught == expected, 0, tcase.line,
884 "line %d. %{$FUNCALL} %{?}expected %s, caught %s"
885 "%{:}unexpectedly caught %s%{;}",
886 __LINE__, 0 != expected, expected, caught, caught);
887 }
888
889 break;
890 }
891
892#ifndef _RWSTD_NO_REPLACEABLE_NEW_DELETE
893
894 // verify that if exceptions are enabled and when capacity changes
895 // at least one exception is thrown
896 const std::size_t expect_throws = str_state.capacity_ < str.capacity ();
897
898#else // if defined (_RWSTD_NO_REPLACEABLE_NEW_DELETE)
899
900 const std::size_t expect_throws =
901 (StringIds::UserAlloc == func.alloc_id_)
902 ? str_state.capacity_ < str.capacity (): 0;
903
904#endif // _RWSTD_NO_REPLACEABLE_NEW_DELETE
905
906 // verify number of exceptions thrown
907 // for range version the allocation may take place several times
908 if (Insert (iter_range) != func.which_)
909 rw_assert (expect_throws == throw_count, 0, tcase.line,
910 "line %d: %{$FUNCALL}: expected exactly 1 %s exception "
911 "while changing capacity from %zu to %zu, got %zu",
912 __LINE__, exceptions [3],
913 str_state.capacity_, str.capacity (), throw_count);
914 else
915 rw_assert (expect_throws <= throw_count, 0, tcase.line,
916 "line %d: %{$FUNCALL}: expected at least 1 %s exception "
917 "while changing capacity from %zu to %zu, got %zu",
918 __LINE__, exceptions [3],
919 str_state.capacity_, str.capacity (), throw_count);
920
921 // disable bad_alloc exceptions
922 *pst->throw_at_calls_ [0] = 0;
923 pal->throw_at_calls_ [pal->m_allocate] = 0;
924}
925
926
928template <class charT, class Traits, class Allocator>
930 const StringTestCaseData<charT> &tdata)
931{
932 typedef std::basic_string<charT, Traits, Allocator> String;
933
934 if (tdata.func_.which_ == Insert (iter_range)) {
935
936 switch (tdata.func_.iter_id_) {
937
938 // exercise possible overloads of the member function template
939 // on common RandomAccessIterator types
940#undef TEST
941#define TEST(Iterator) do { \
942 typedef typename String::Iterator Iter; \
943 static const \
944 InsertRangeOverload<String, Iter> rng; \
945 test_insert ((charT*)0, (Traits*)0, (Allocator*)0, rng, tdata); \
946 } while (0)
947
948 case StringIds::Pointer: TEST (pointer); break;
949 case StringIds::ConstPointer: TEST (const_pointer); break;
950 case StringIds::Iterator: TEST (iterator); break;
951 case StringIds::ConstIterator: TEST (const_iterator); break;
952
953 case StringIds::ReverseIterator: TEST (reverse_iterator); break;
954 case StringIds::ConstReverseIterator: TEST (const_reverse_iterator);
955 break;
956
957 // exercise specializations of the member function template
958 // on the required iterator categories
959#undef TEST
960#define TEST(Iterator) do { \
961 typedef Iterator<charT> Iter; \
962 static const \
963 InsertRange<String, Iter> rng; \
964 test_insert ((charT*)0, (Traits*)0, (Allocator*)0, rng, tdata); \
965 } while (0)
966
967 case StringIds::Input: TEST (InputIter); break;
968 case StringIds::Forward: TEST (ConstFwdIter); break;
969 case StringIds::Bidir: TEST (ConstBidirIter); break;
971
972 default:
973 rw_error (0, 0, __LINE__, "bad iterator id");
974 }
975 }
976 else {
977 // exercise ordinary overloads of the member function
978 static const RangeBase<String> rng;
979 test_insert ((charT*)0, (Traits*)0, (Allocator*)0, rng, tdata);
980 }
981}
982
983
986
987int main (int argc, char** argv)
988{
989 static const StringTest
990 tests [] = {
991
992#undef TEST
993#define TEST(sig) { \
994 Insert (sig), sig ## _test_cases, \
995 sizeof sig ## _test_cases / sizeof *sig ## _test_cases \
996 }
997
998 TEST (size_cptr),
999 TEST (size_cstr),
1000 TEST (size_cptr_size),
1001 TEST (size_cstr_size_size),
1002 TEST (size_size_val),
1003 TEST (iter_val),
1004 TEST (iter_size_val),
1005 TEST (iter_range)
1006 };
1007
1008 const std::size_t test_count = sizeof tests / sizeof *tests;
1009
1010 const int status =
1011 rw_run_string_test (argc, argv, __FILE__,
1012 "lib.string.insert",
1013 test_insert_func_array, tests, test_count);
1014
1015 return status;
1016}
#define off
Definition 17.names.cpp:507
#define charT
Definition 17.names.cpp:456
#define TEST(str, off, arg, res, bthrow)
#define Insert(sig)
void test_insert()
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 ContIter begin(List &cont, ContIter *)
String::value_type StringChar
virtual List & operator()(List &lst, const ContainerTestCaseData< ListVal > &tdata) const
String::iterator StringIter
virtual List & operator()(List &lst, const ContainerTestCaseData< ListVal > &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