Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
21.string.assign.cpp
Go to the documentation of this file.
1
27#include <string> // for string
28#include <cstddef> // for size_t
29#include <stdexcept> // for out_of_range, length_error
30
31#include <rw_strings.h> // for StringMembers
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 Assign(sig) StringIds::assign_ ## 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// assign (const value_type*)
52static const StringTestCase
53cptr_test_cases [] = {
54
55#undef TEST
56#define TEST(str, arg, res, bthrow) { \
57 __LINE__, -1, -1, -1, -1, -1, \
58 str, sizeof str - 1, \
59 arg, sizeof arg - 1, res, sizeof res - 1, bthrow \
60 }
61
62 // +------------------------------------------ controlled sequence
63 // | +------------------------ sequence to be assigned
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
73 TEST ("ab", "c", "c", 0),
74
75 TEST ("", "", "", 0),
76 TEST ("", "<U0>", "", 0),
77 TEST ("", "abc", "abc", 0),
78 TEST ("abc", "", "", 0),
79
80 TEST ("<U0>", "", "", 0),
81 TEST ("<U0>", "a", "a", 0),
82 TEST ("<U0>", "<U0>@2", "", 0),
83
84 TEST ("<U0>@2ab", "cdefghij", "cdefghij", 0),
85 TEST ("a<U0>@2b", "cdefghij", "cdefghij", 0),
86 TEST ("ab<U0>@2", "cdefghij", "cdefghij", 0),
87 TEST ("a<U0>b<U0>@2c", "e<U0>", "e", 0),
88 TEST ("<U0>ab<U0>@2c", "e<U0>", "e", 0),
89
90 TEST ("", "x@4096", "x@4096", 0),
91 TEST ("x@4096", "", "", 0),
92 TEST ("a@4096", "b@4096", "b@4096", 0),
93
94 TEST ("", "x@207", "x@207", 0),
95 TEST ("x@128", "x@207", "x@207", 0),
96 TEST ("x@540", "x@207", "x@207", 0),
97 TEST ("", "x@1412", "x@1412", 0),
98 TEST ("x@128", "x@1412", "x@1412", 0),
99 TEST ("x@3695", "x@1412", "x@1412", 0),
100 TEST ("x@872", "x@873", "x@873", 0),
101 TEST ("x@873", "x@3695", "x@3695", 0),
102
103 TEST ("", 0, "", 0),
104 TEST ("abc", 0, "abc", 0),
105 TEST ("a<U0>@2bc", 0, "a", 0),
106 TEST ("<U0>@2abc", 0, "", 0),
107 TEST ("abc<U0>@2", 0, "abc", 0),
108 TEST ("x@4096", 0, "x@4096", 0),
109
110 TEST ("last", "test", "test", 0)
111};
112
113
115// used to exercise:
116// assign (const basic_string&)
117static const StringTestCase
118cstr_test_cases [] = {
119
120#undef TEST
121#define TEST(s, arg, res, bthrow) { \
122 __LINE__, -1, -1, -1, -1, -1, \
123 s, sizeof s - 1, \
124 arg, sizeof arg - 1, res, sizeof res - 1, bthrow \
125 }
126
127 // +------------------------------------------ controlled sequence
128 // | +------------------------ sequence to be assigned
129 // | | +---------- expected result sequence
130 // | | | +- exception info:
131 // | | | | 0 - no exception
132 // | | | | 1 - out_of_range
133 // | | | | 2 - length_error
134 // | | | | -1 - exc. safety
135 // | | | |
136 // | | | +-----+
137 // | | | |
138 // V V V V
139 TEST ("ab", "c", "c", 0),
140
141 TEST ("", "", "", 0),
142 TEST ("", "<U0>", "<U0>", 0),
143 TEST ("", "abc", "abc", 0),
144 TEST ("abc", "", "", 0),
145
146 TEST ("<U0>", "", "", 0),
147 TEST ("<U0>", "a", "a", 0),
148 TEST ("<U0>", "<U0>@2", "<U0>@2", 0),
149
150 TEST ("ab", "c<U0>e", "c<U0>e", 0),
151
152 TEST ("<U0>@2ab", "cdefghij", "cdefghij", 0),
153 TEST ("a<U0>@2b", "cdefghij", "cdefghij", 0),
154 TEST ("ab<U0>@2", "cdefghij", "cdefghij", 0),
155 TEST ("a<U0>b<U0>@2c", "e<U0>", "e<U0>", 0),
156 TEST ("<U0>ab<U0>@2c", "e<U0>", "e<U0>", 0),
157 TEST ("ab<U0>@2c<U0>", "<U0>e", "<U0>e", 0),
158
159 TEST ("e<U0>", "a<U0>b<U0>@2c", "a<U0>b<U0>@2c", 0),
160 TEST ("e<U0>@2", "<U0>ab<U0>@2c", "<U0>ab<U0>@2c", 0),
161 TEST ("<U0>e", "ab<U0>@2c<U0>", "ab<U0>@2c<U0>", 0),
162
163 TEST ("", "x@4096", "x@4096", 0),
164 TEST ("x@4096", "", "", 0),
165 TEST ("a@4096", "b@4096", "b@4096", 0),
166
167 TEST ("", "x@207", "x@207", 0),
168 TEST ("x@128", "x@207", "x@207", 0),
169 TEST ("x@540", "x@207", "x@207", 0),
170 TEST ("", "x@1412", "x@1412", 0),
171 TEST ("x@128", "x@1412", "x@1412", 0),
172 TEST ("x@3695", "x@1412", "x@1412", 0),
173 TEST ("x@872", "x@873", "x@873", 0),
174 TEST ("x@873", "x@3695", "x@3695", 0),
175
176 TEST ("", 0, "", 0),
177 TEST ("abc", 0, "abc", 0),
178 TEST ("a<U0>@2bc", 0, "a<U0>@2bc", 0),
179 TEST ("<U0>@2abc", 0, "<U0>@2abc", 0),
180 TEST ("abc<U0>@2", 0, "abc<U0>@2", 0),
181 TEST ("x@4096", 0, "x@4096", 0),
182
183 TEST ("last", "test", "test", 0)
184};
185
186
188// used to exercise:
189// assign (const value_type*, size_type)
190static const StringTestCase
191cptr_size_test_cases [] = {
192
193#undef TEST
194#define TEST(str, arg, size, res, bthrow) { \
195 __LINE__, -1, size, -1, -1, -1, \
196 str, sizeof str - 1, \
197 arg, sizeof arg - 1, res, sizeof res - 1, bthrow \
198 }
199
200 // +------------------------------------------ controlled sequence
201 // | +------------------------- sequence to be assigned
202 // | | +------------ assign() n argument
203 // | | | +-------- expected result sequence
204 // | | | | +-- exception info
205 // | | | | | 0 - no exception
206 // | | | | | 1 - out_of_range
207 // | | | | | 2 - length_error
208 // | | | | | -1 - exc. safety
209 // | | | | |
210 // | | | | +----------+
211 // V V V V V
212 TEST ("ab", "c", 1, "c", 0),
213
214 TEST ("", "", 0, "", 0),
215 TEST ("", "abc", 1, "a", 0),
216 TEST ("", "<U0>", 1, "<U0>", 0),
217
218 TEST ("<U0>", "", 0, "", 0),
219 TEST ("<U0>", "a", 0, "", 0),
220 TEST ("<U0>", "a", 1, "a", 0),
221 TEST ("<U0>", "<U0>@2", 1, "<U0>", 0),
222 TEST ("<U0>", "<U0>@2", 2, "<U0>@2", 0),
223
224 TEST ("cde", "ab", 2, "ab", 0),
225 TEST ("cde", "ab", 1, "a", 0),
226
227 TEST ("<U0>e<U0>", "a<U0>b<U0>@2c", 0, "", 0),
228 TEST ("<U0>e<U0>", "<U0>ab<U0>@2c", 3, "<U0>ab", 0),
229 TEST ("<U0>e<U0>", "a<U0>b<U0>@2c", 6, "a<U0>b<U0>@2c", 0),
230
231 TEST ("a<U0>b<U0>@2c", "<U0>e<U0>", 3, "<U0>e<U0>", 0),
232 TEST ("a<U0>b<U0>@2c", "<U0>@2e<U0>", 2, "<U0>@2", 0),
233 TEST ("<U0>ab<U0>@2c", "<U0>e<U0>", 1, "<U0>", 0),
234 TEST ("a<U0>bc<U0>@2", "<U0>e", 2, "<U0>e", 0),
235
236 TEST ("", 0, 0, "", 0),
237 TEST ("abc", 0, 0, "", 0),
238 TEST ("abc", 0, 1, "a", 0),
239 TEST ("abc", 0, 2, "ab", 0),
240 TEST ("a<U0>bc", 0, 2, "a<U0>", 0),
241 TEST ("<U0>abc<U0>@2", 0, 1, "<U0>", 0),
242 TEST ("a<U0>bc<U0>@2", 0, 3, "a<U0>b", 0),
243 TEST ("a<U0>bc<U0>@2", 0, 6, "a<U0>bc<U0>@2", 0),
244 TEST ("x@4096", 0, 2048, "x@2048", 0),
245
246 TEST ("", "x@4096", 4096, "x@4096", 0),
247 TEST ("abcd", "x@4096", 0, "", 0),
248 TEST ("x@4096", "x@4096", 0, "", 0),
249 TEST ("x@4096", "x@4096", 1, "x", 0),
250 TEST ("x@4096", "", 0, "", 0),
251 TEST ("a@4096", "b@4096", 2048, "b@2048", 0),
252
253 TEST ("", "x@207", 207, "x@207", 0),
254 TEST ("x@128", "x@334", 207, "x@207", 0),
255 TEST ("x@540", "x@207", 128, "x@128", 0),
256 TEST ("", "x@1412", 873, "x@873", 0),
257 TEST ("x@128", "x@1412", 1412, "x@1412", 0),
258 TEST ("x@3695", "x@1412", 540, "x@540", 0),
259 TEST ("x@872", "x@873", 873, "x@873", 0),
260 TEST ("x@873", "x@3695", 2284, "x@2284", 0),
261
262 TEST ("", "", -1, "", 2),
263
264 TEST ("last", "test", 4, "test", 0)
265};
266
267
269// used to exercise:
270// assign (const basic_string&, size_type, size_type)
271// assign (InputIterator, InputIterator)
272static const StringTestCase
273range_test_cases [] = {
274
275// range_test_cases serves a double duty
276#define cstr_size_size_test_cases range_test_cases
277
278#undef TEST
279#define TEST(str, arg, off, size, res, bthrow) { \
280 __LINE__, -1, -1, off, size, -1, \
281 str, sizeof str - 1, \
282 arg, sizeof arg - 1, res, sizeof res - 1, bthrow \
283 }
284
285 // +------------------------------------------ controlled sequence
286 // | +------------------------- sequence to be inserted
287 // | | +------------ assign() pos argument
288 // | | | +--------- assign() n argument
289 // | | | | +------ expected result sequence
290 // | | | | | +--- exception info
291 // | | | | | | 0 - no exception
292 // | | | | | | 1 - out_of_range
293 // | | | | | | 2 - length_error
294 // | | | | | | -1 - exc. safety
295 // | | | | | |
296 // | | | | | +---------------+
297 // V V V V V V
298 TEST ("ab", "c", 0, 1, "c", 0),
299
300 TEST ("", "", 0, 0, "", 0),
301 TEST ("", "abc", 1, 1, "b", 0),
302 TEST ("", "<U0>", 0, 1, "<U0>", 0),
303
304 TEST ("<U0>", "", 0, 0, "", 0),
305
306 TEST ("abc", "", 0, 0, "", 0),
307
308 TEST ("<U0>", "a", 0, 1, "a", 0),
309 TEST ("<U0>", "<U0>@2", 1, 1, "<U0>", 0),
310 TEST ("<U0>", "<U0>@2", 0, 2, "<U0>@2", 0),
311 TEST ("<U0>", "<U0>@2", 1, 5, "<U0>", 0),
312
313 TEST ("cde", "ab", 0, 2, "ab", 0),
314 TEST ("cde", "ab", 0, 1, "a", 0),
315 TEST ("cde", "ab", 1, 5, "b", 0),
316
317 TEST ("ab", "c<U0>e", 0, 3, "c<U0>e", 0),
318 TEST ("ab", "c<U0>e", 1, 2, "<U0>e", 0),
319 TEST ("ab", "c<U0>e", 0, 2, "c<U0>", 0),
320
321 TEST ("<U0>e<U0>", "<U0>ab<U0>@2c", 0, 9, "<U0>ab<U0>@2c", 0),
322 TEST ("<U0>e<U0>", "<U0>ab<U0>@2c", 0, 3, "<U0>ab", 0),
323 TEST ("a<U0>b<U0>@2c", "<U0>e<U0>", 0, 3, "<U0>e<U0>", 0),
324 TEST ("a<U0>b<U0>@2c", "<U0>@2e<U0>", 0, 2, "<U0>@2", 0),
325 TEST ("<U0>ab<U0>@2c", "<U0>e<U0>", 2, 1, "<U0>", 0),
326 TEST ("<U0>ab<U0>@2c", "<U0>e<U0>", 2, 9, "<U0>", 0),
327 TEST ("a<U0>bc<U0>@2", "<U0>e", 0, 2, "<U0>e", 0),
328
329 TEST ("", 0, 0, 0, "", 0),
330 TEST ("abc", 0, 1, 0, "", 0),
331 TEST ("abc", 0, 1, 1, "b", 0),
332 TEST ("abc", 0, 0, 2, "ab", 0),
333 TEST ("a<U0>bc<U0>@2", 0, 4, 2, "<U0>@2", 0),
334 TEST ("a<U0>bc<U0>@2", 0, 1, 3, "<U0>bc", 0),
335 TEST ("a<U0>bc<U0>@2", 0, 0, 9, "a<U0>bc<U0>@2", 0),
336 TEST ("abcdef", 0, 1, 2, "bc", 0),
337 TEST ("x@4096", 0, 1, 2, "xx", 0),
338
339 TEST ("x@4096", "", 0, 0, "", 0),
340 TEST ("", "x@4096", 9, 2, "xx", 0),
341 TEST ("", "x@4096", 9, 0, "", 0),
342 TEST ("abc", "x@4096", 2, 1, "x", 0),
343 TEST ("x@4096", "x@4096", 2, 3, "xxx", 0),
344 TEST ("", "x@4096", 0, 4096, "x@4096", 0),
345 TEST ("", "x@4096", 100, 2000, "x@2000", 0),
346
347 TEST ("", "x@207", 0, 207, "x@207", 0),
348 TEST ("x@128", "x@334", 10, 207, "x@207", 0),
349 TEST ("x@540", "x@207", 50, 128, "x@128", 0),
350 TEST ("", "x@1412", 128, 873, "x@873", 0),
351 TEST ("x@128", "x@1412", 0, 1412, "x@1412", 0),
352 TEST ("x@3695", "x@1412", 207, 540, "x@540", 0),
353 TEST ("x@872", "x@874", 1, 873, "x@873", 0),
354 TEST ("x@873", "x@3695", 10, 2284, "x@2284", 0),
355
356 TEST ("", "<U0>", 2, 0, "", 1),
357 TEST ("", "a", 2, 0, "", 1),
358 TEST ("", "x@4096", 4106, 0, "", 1),
359
360 TEST ("last", "test", 0, 4, "test", 0)
361};
362
363
365// used to exercise:
366// assign (size_type, value_type)
367static const StringTestCase
368size_val_test_cases [] = {
369
370#undef TEST
371#define TEST(str, size, val, res, bthrow) { \
372 __LINE__, -1, size, -1, -1, val, \
373 str, sizeof str - 1, \
374 0, 0, res, sizeof res - 1, bthrow \
375 }
376
377 // +----------------------------------------- controlled sequence
378 // | +------------------------ assign() count argument
379 // | | +-------------------- character to be assigned
380 // | | | +---------------- expected result sequence
381 // | | | | +-------- exception info
382 // | | | | | 0 - no exception
383 // | | | | | 1 - out_of_range
384 // | | | | | 2 - length_error
385 // | | | | | -1 - exc. safety
386 // | | | | |
387 // | | | | +--------+
388 // V V V V V
389 TEST ("ab", 1, 'c', "c", 0),
390
391 TEST ("", 0, ' ', "", 0),
392 TEST ("", 1, 'b', "b", 0),
393 TEST ("", 3, 'b', "bbb", 0),
394
395 TEST ("<U0>", 0, ' ', "", 0),
396 TEST ("", 2, '\0', "<U0>@2", 0),
397
398 TEST ("<U0>", 1, 'a', "a", 0),
399 TEST ("<U0>", 1, '\0', "<U0>", 0),
400 TEST ("<U0>", 2, '\0', "<U0>@2", 0),
401 TEST ("<U0>", 0, '\0', "", 0),
402
403 TEST ("cde", 3, 'a', "aaa", 0),
404 TEST ("ab", 2, '\0', "<U0>@2", 0),
405 TEST ("ab", 1, '\0', "<U0>", 0),
406
407 TEST ("a<U0>b<U0>@2c", 2, '\0', "<U0>@2", 0),
408 TEST ("a<U0>b<U0>@2c", 1, '\0', "<U0>", 0),
409 TEST ("<U0>ab<U0>@2c", 3, '\0', "<U0>@3", 0),
410 TEST ("a<U0>bc<U0>@2", 2, 'a', "aa", 0),
411
412 TEST ("", 4096, 'x', "x@4096", 0),
413 TEST ("x@4096", 0, 'x', "", 0),
414
415 TEST ("x@127", 128, 'x', "x@128", 0),
416 TEST ("x@200", 207, 'x', "x@207", 0),
417 TEST ("x@334", 128, 'x', "x@128", 0),
418 TEST ("", 540, 'x', "x@540", 0),
419 TEST ("xx", 873, 'x', "x@873", 0),
420 TEST ("x@873", 1412, 'x', "x@1412", 0),
421 TEST ("x@3695", 207, 'x', "x@207", 0),
422 TEST ("x@540", 3695, 'x', "x@3695", 0),
423
424 TEST ("", -1, 'x', "", 2),
425
426 TEST ("last", 4, 't', "tttt", 0)
427};
428
429
431// invokes specializations of the member function template
432// on the required iterator categories
433template <class String, class Iterator>
434struct AssignRange: RangeBase<String> {
435
436 typedef typename String::iterator StringIter;
437 typedef typename String::value_type StringChar;
438
440
441 virtual String&
443 const StringTestCaseData<StringChar>& tdata) const {
444
445 const StringTestCase &tcase = tdata.tcase_;
446
447 const String &cstr = str;
448
449 // when (0 == tcase.arg) exercise self-referential modification
450 // (i.e., replacing a range of elements with a subrange of its
451 // own elements)
452 const StringChar* const beg =
453 (tcase.arg ? tdata.arg_ : cstr.data ()) + tdata.off2_;
454
455 const StringChar* const end = beg + tdata.ext2_;
456
457 const Iterator first (beg, beg, end);
458 const Iterator last (end, beg, end);
459
460 return str.assign (first, last);
461 }
462};
463
464
466// invokes possible overloads of the member function template
467// on common RandomAccessIterator types
468template <class String, class Iterator>
469struct AssignRangeOverload: RangeBase<String>
470{
471 typedef typename String::iterator StringIter;
472 typedef typename String::value_type StringChar;
473
475
476 virtual String&
478 const StringTestCaseData<StringChar>& tdata) const {
479
480 const StringTestCase &tcase = tdata.tcase_;
481
482 bool reverse_iter = StringIds::ReverseIterator == tdata.func_.iter_id_
484
485 const std::size_t srclen_ = tcase.arg ? tdata.arglen_ : str.size ();
486
487 const std::size_t off =
488 reverse_iter ? srclen_ - tdata.off2_ - tdata.ext2_ : tdata.off2_;
489 const std::size_t ext = tdata.ext2_;
490
491 if (0 == tcase.arg) {
492 // exercise self-referential modification (i.e., replacing
493 // a range of elements with a subrange of its own elements)
494
495 const Iterator first (this->begin (str, (Iterator*)0) + off);
496 const Iterator last (first + ext);
497
498 return str.assign (first, last);
499 }
500
501 String str_arg (tdata.arg_, tdata.arglen_);
502
503 const Iterator first (this->begin (str_arg, (Iterator*)0) + off);
504 const Iterator last (first + ext);
505
506 return str.assign (first, last);
507 }
508};
509
510
512template <class charT, class Traits, class Allocator>
514 std::basic_string <charT, Traits, Allocator> > &rng,
515 const StringTestCaseData<charT> &tdata)
516{
517 typedef std::basic_string <charT, Traits, Allocator> String;
518 typedef typename String::iterator StringIter;
519 typedef typename UserTraits<charT>::MemFun TraitsFunc;
520
521 const StringFunc &func = tdata.func_;
522 const StringTestCase &tcase = tdata.tcase_;
523
524 // construct the string object to be modified
525 // and the (possibly unused) argument string
526 /* const */ String str (tdata.str_, tdata.strlen_);
527 const String arg (tdata.arg_, tdata.arglen_);
528
529 std::size_t size = tcase.size >= 0 ? tcase.size : str.max_size () + 1;
530 std::size_t size2 = tcase.size2 >= 0 ? tcase.size2 : str.max_size () + 1;
531
532 // save the state of the string object before the call
533 // to detect wxception safety violations (changes to
534 // the state of the object after an exception)
535 const StringState str_state (rw_get_string_state (str));
536
537 // first function argument
538 const charT* const arg_ptr = tcase.arg ? arg.c_str () : str.c_str ();
539 const String& arg_str = tcase.arg ? arg : str;
540
541 std::size_t total_length_calls = 0;
542 std::size_t n_length_calls = 0;
543 std::size_t* const rg_calls = rw_get_call_counters ((Traits*)0, (charT*)0);
544
545 if (rg_calls)
546 total_length_calls = rg_calls [TraitsFunc::length];
547
548 rwt_free_store* const pst = rwt_get_free_store (0);
549 SharedAlloc* const pal = SharedAlloc::instance ();
550
551 // iterate for`throw_after' starting at the next call to operator new,
552 // forcing each call to throw an exception, until the function finally
553 // succeeds (i.e, no exception is thrown)
554 std::size_t throw_count;
555 for (throw_count = 0; ; ++throw_count) {
556
557 // (name of) expected and caught exception
558 const char* expected = 0;
559 const char* caught = 0;
560
561#ifndef _RWSTD_NO_EXCEPTIONS
562
563 if (1 == tcase.bthrow && Assign (cstr_size_size) == func.which_)
564 expected = exceptions [1]; // out_of_range
565 else if (2 == tcase.bthrow)
566 expected = exceptions [2]; // length_error
567 else if (0 == tcase.bthrow) {
568 // by default excercise the exception safety of the function
569 // by iteratively inducing an exception at each call to operator
570 // new or Allocator::allocate() until the call succeeds
571 expected = exceptions [3]; // bad_alloc
572 *pst->throw_at_calls_ [0] = pst->new_calls_ [0] + throw_count + 1;
573 pal->throw_at_calls_ [pal->m_allocate] =
574 pal->throw_at_calls_ [pal->m_allocate] + throw_count + 1;
575 }
576 else {
577 // exceptions disabled for this test case
578 }
579
580#else // if defined (_RWSTD_NO_EXCEPTIONS)
581
582 if (tcase.bthrow)
583 return;
584
585#endif // _RWSTD_NO_EXCEPTIONS
586
587 // pointer to the returned reference
588 const String* ret_ptr = 0;
589
590 // start checking for memory leaks
591 rw_check_leaks (str.get_allocator ());
592
593 try {
594 switch (func.which_) {
595
596 case Assign (cptr):
597 ret_ptr = &str.assign (arg_ptr);
598 if (rg_calls)
599 n_length_calls = rg_calls [TraitsFunc::length];
600 break;
601
602 case Assign (cstr):
603 ret_ptr = &str.assign (arg_str);
604 break;
605
606 case Assign (cptr_size):
607 ret_ptr = &str.assign (arg_ptr, size);
608 break;
609
610 case Assign (cstr_size_size):
611 ret_ptr = &str.assign (arg_str, tcase.off2, size2);
612 break;
613
614 case Assign (size_val): {
615 const charT val = make_char (char (tcase.val), (charT*)0);
616 ret_ptr = &str.assign (size, val);
617 break;
618 }
619
620 case Assign (range):
621 ret_ptr = &rng (str, tdata);
622 break;
623
624 default:
625 RW_ASSERT (!"test logic error: unknown assign overload");
626 }
627
628 // verify that the reference returned from the function
629 // refers to the modified string object (i.e., *this
630 // within the function)
631 const std::ptrdiff_t ret_off = ret_ptr - &str;
632
633 // verify the returned value
634 rw_assert (0 == ret_off, 0, tcase.line,
635 "line %d. %{$FUNCALL} returned invalid reference, "
636 "offset is %td", __LINE__, ret_off);
637
638 // for convenience
639 static const int cwidth = sizeof (charT);
640
641 // verfiy that strings length are equal
642 rw_assert (tdata.reslen_ == str.size (), 0, tcase.line,
643 "line %d. %{$FUNCALL}: expected %{/*.*Gs} with length "
644 "%zu, got %{/*.*Gs} with length %zu", __LINE__,
645 cwidth, int (tdata.reslen_), tdata.res_, tdata.reslen_,
646 cwidth, int (str.size ()), str.c_str (), str.size ());
647
648 if (tdata.reslen_ == str.size ()) {
649 // if the result length matches the expected length
650 // (and only then), also verify that the modified
651 // string matches the expected result
652 const std::size_t match =
653 rw_match (tcase.res, str.c_str(), str.size ());
654
655 rw_assert (match == tdata.reslen_, 0, tcase.line,
656 "line %d. %{$FUNCALL}: expected %{/*.*Gs}, "
657 "got %{/*.*Gs}, difference at off %zu",
658 __LINE__, cwidth, int (tdata.reslen_), tdata.res_,
659 cwidth, int (str.size ()), str.c_str (), match);
660 }
661
662 // verify that Traits::length was used
663 if (Assign (cptr) == func.which_ && rg_calls) {
664 rw_assert (n_length_calls - total_length_calls > 0,
665 0, tcase.line, "line %d. %{$FUNCALL} doesn't "
666 "use traits::length()", __LINE__);
667 }
668 }
669
670#ifndef _RWSTD_NO_EXCEPTIONS
671
672 catch (const std::out_of_range &ex) {
673 caught = exceptions [1];
674 rw_assert (caught == expected, 0, tcase.line,
675 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
676 "unexpectedly%{;} caught std::%s(%#s)",
677 __LINE__, 0 != expected, expected, caught, ex.what ());
678 }
679 catch (const std::length_error &ex) {
680 caught = exceptions [2];
681 rw_assert (caught == expected, 0, tcase.line,
682 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
683 "unexpectedly%{;} caught std::%s(%#s)",
684 __LINE__, 0 != expected, expected, caught, ex.what ());
685 }
686 catch (const std::bad_alloc &ex) {
687 caught = exceptions [3];
688 rw_assert (0 == tcase.bthrow, 0, tcase.line,
689 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
690 "unexpectedly%{;} caught std::%s(%#s)",
691 __LINE__, 0 != expected, expected, caught, ex.what ());
692 }
693 catch (const std::exception &ex) {
694 caught = exceptions [4];
695 rw_assert (0, 0, tcase.line,
696 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
697 "unexpectedly%{;} caught std::%s(%#s)",
698 __LINE__, 0 != expected, expected, caught, ex.what ());
699 }
700 catch (...) {
701 caught = exceptions [0];
702 rw_assert (0, 0, tcase.line,
703 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
704 "unexpectedly%{;} caught %s",
705 __LINE__, 0 != expected, expected, caught);
706 }
707
708#endif // _RWSTD_NO_EXCEPTIONS
709
710 // FIXME: verify the number of blocks the function call
711 // is expected to allocate and detect any memory leaks
712 rw_check_leaks (str.get_allocator (), tcase.line,
713 std::size_t (-1), std::size_t (-1));
714
715 if (caught) {
716 // verify that an exception thrown during allocation
717 // didn't cause a change in the state of the object
719 __LINE__, tcase.line, caught);
720
721 if (0 == tcase.bthrow) {
722 // allow this call to operator new to succeed and try
723 // to make the next one to fail during the next call
724 // to the same function again
725 continue;
726 }
727 }
728 else if (0 < tcase.bthrow) {
729 rw_assert (caught == expected, 0, tcase.line,
730 "line %d. %{$FUNCALL} %{?}expected %s, caught %s"
731 "%{:}unexpectedly caught %s%{;}",
732 __LINE__, 0 != expected, expected, caught, caught);
733 }
734
735 break;
736 }
737
738 std::size_t expect_throws = 0;
739
740#ifndef _RWSTD_NO_STRING_REF_COUNT
741 if (Assign (cstr) != func.which_) {
742#endif
743
744#ifndef _RWSTD_NO_REPLACEABLE_NEW_DELETE
745
746 // verify that if exceptions are enabled and when capacity changes
747 // at least one exception is thrown
748 expect_throws = str_state.capacity_ < str.capacity ();
749
750#else // if defined (_RWSTD_NO_REPLACEABLE_NEW_DELETE)
751
752 expect_throws = (StringIds::UserAlloc == func.alloc_id_)
753 ? str_state.capacity_ < str.capacity (): 0;
754
755#endif // _RWSTD_NO_REPLACEABLE_NEW_DELETE
756
757#ifndef _RWSTD_NO_STRING_REF_COUNT
758 }
759#endif
760
761 // verify number of exceptions thrown
762 // for range version the allocation may take place several times
763 if (Assign (range) != func.which_)
764 rw_assert (expect_throws == throw_count, 0, tcase.line,
765 "line %d: %{$FUNCALL}: expected exactly 1 %s exception "
766 "while changing capacity from %zu to %zu, got %zu",
767 __LINE__, exceptions [3],
768 str_state.capacity_, str.capacity (), throw_count);
769 else
770 rw_assert (expect_throws <= throw_count, 0, tcase.line,
771 "line %d: %{$FUNCALL}: expected at least 1 %s exception "
772 "while changing capacity from %zu to %zu, got %zu",
773 __LINE__, exceptions [3],
774 str_state.capacity_, str.capacity (), throw_count);
775
776 // disable bad_alloc exceptions
777 *pst->throw_at_calls_ [0] = 0;
778 pal->throw_at_calls_ [pal->m_allocate] = 0;
779}
780
781
783template <class charT, class Traits, class Allocator>
785 const StringTestCaseData<charT> &tdata)
786{
787 typedef std::basic_string<charT, Traits, Allocator> String;
788
789 if (tdata.func_.which_ == Assign (range)) {
790
791 switch (tdata.func_.iter_id_) {
792
793 // exercise possible overloads of the member function template
794 // on common RandomAccessIterator types
795#undef TEST
796#define TEST(Iterator) do { \
797 typedef typename String::Iterator Iter; \
798 static const \
799 AssignRangeOverload<String, Iter> rng; \
800 test_assign ((charT*)0, (Traits*)0, (Allocator*)0, rng, tdata); \
801 } while (0)
802
803 case StringIds::Pointer: TEST (pointer); break;
804 case StringIds::ConstPointer: TEST (const_pointer); break;
805 case StringIds::Iterator: TEST (iterator); break;
806 case StringIds::ConstIterator: TEST (const_iterator); break;
807
808 case StringIds::ReverseIterator: TEST (reverse_iterator); break;
809 case StringIds::ConstReverseIterator: TEST (const_reverse_iterator);
810 break;
811
812 // exercise specializations of the member function template
813 // on the required iterator categories
814
815#undef TEST
816#define TEST(Iterator) do { \
817 typedef Iterator<charT> Iter; \
818 static const \
819 AssignRange<String, Iter> rng; \
820 test_assign ((charT*)0, (Traits*)0, (Allocator*)0, rng, tdata); \
821 } while (0)
822
823 case StringIds::Input: TEST (InputIter); break;
824 case StringIds::Forward: TEST (ConstFwdIter); break;
825 case StringIds::Bidir: TEST (ConstBidirIter); break;
827
828 default:
829 rw_error (0, 0, __LINE__, "bad iterator id");
830 }
831 }
832 else {
833 // exercise ordinary overloads of the member function
834 static const RangeBase<String> rng;
835 test_assign ((charT*)0, (Traits*)0, (Allocator*)0, rng, tdata);
836 }
837}
838
839
842
843int main (int argc, char** argv)
844{
845 static const StringTest
846 tests [] = {
847
848#undef TEST
849#define TEST(sig) { \
850 Assign (sig), sig ## _test_cases, \
851 sizeof sig ## _test_cases / sizeof *sig ## _test_cases \
852 }
853
854 TEST (cptr),
855 TEST (cstr),
856 TEST (cptr_size),
857 TEST (cstr_size_size),
858 TEST (size_val),
859 TEST (range)
860 };
861
862 const std::size_t test_count = sizeof tests / sizeof *tests;
863
864 const int status =
865 rw_run_string_test (argc, argv, __FILE__,
866 "lib.string.assign",
867 test_assign_func_array, tests, test_count);
868
869 return status;
870}
#define last
Definition 17.names.cpp:487
#define off
Definition 17.names.cpp:507
#define charT
Definition 17.names.cpp:456
#define val
Definition 17.names.cpp:570
#define Assign(sig)
#define TEST(str, arg, res, bthrow)
#define range_test_cases
void test_assign()
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)
String::value_type StringChar
virtual List & operator()(List &lst, const ContainerTestCaseData< ListVal > &tdata) const
String::iterator StringIter
String::value_type StringChar
virtual List & operator()(List &lst, const ContainerTestCaseData< ListVal > &tdata) const
String::iterator StringIter
static ContIter begin(List &cont, ContIter *)
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
_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