1 //Has to be first for StackAllocator swap overload to be taken
2 //into account (at least using GCC 4.0.1)
3 #include "stack_allocator.h"
4
5 #include <algorithm>
6 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
7 # include <slist>
8 # if !defined (_STLP_USE_NO_IOSTREAMS)
9 # include <sstream>
10 # endif
11 # include <iterator>
12 # include <functional>
13 #endif
14
15 #include "cppunit/cppunit_proxy.h"
16
17 #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
18 using namespace std;
19 #endif
20
21 #if !defined (STLPORT) && defined(__GNUC__)
22 using namespace __gnu_cxx;
23 #endif
24
25 //
26 // TestCase class
27 //
28 class SlistTest : public CPPUNIT_NS::TestCase
29 {
30 CPPUNIT_TEST_SUITE(SlistTest);
31 #if !defined (STLPORT) || defined (_STLP_NO_EXTENSIONS) || defined (_STLP_USE_NO_IOSTREAMS)
32 CPPUNIT_IGNORE;
33 #endif
34 CPPUNIT_TEST(slist1);
35 #if defined (STLPORT) && defined (_STLP_USE_NO_IOSTREAMS)
36 CPPUNIT_STOP_IGNORE;
37 #endif
38 CPPUNIT_TEST(erase);
39 CPPUNIT_TEST(insert);
40 CPPUNIT_TEST(splice);
41 CPPUNIT_TEST(allocator_with_state);
42 CPPUNIT_TEST_SUITE_END();
43
44 protected:
45 void slist1();
46 void erase();
47 void insert();
48 void splice();
49 void allocator_with_state();
50 };
51
52 CPPUNIT_TEST_SUITE_REGISTRATION(SlistTest);
53
54 //
55 // tests implementation
56 //
slist1()57 void SlistTest::slist1()
58 {
59 #if defined (STLPORT) && !defined (_STLP_USE_NO_IOSTREAMS) && !defined (_STLP_NO_EXTENSIONS)
60 /*
61 original: xlxtss
62 reversed: sstxlx
63 removed: sstl
64 uniqued: stl
65 sorted: lst
66 */
67
68 char array [] = { 'x', 'l', 'x', 't', 's', 's' };
69 ostringstream os;
70 ostream_iterator<char> o(os,"");
71 slist<char> str(array+0, array + 6);
72 slist<char>::iterator i;
73 //Check const_iterator construction from iterator
74 slist<char>::const_iterator ci(i);
75 slist<char>::const_iterator ci2(ci);
76 // cout << "reversed: ";
77 str.reverse();
78 for(i = str.begin(); i != str.end(); i++)
79 os << *i;
80 stringbuf* buff=os.rdbuf();
81 string result=buff->str();
82 CPPUNIT_ASSERT(!strcmp(result.c_str(),"sstxlx"));
83
84 //cout << "removed: ";
85 str.remove('x');
86 ostringstream os2;
87 for(i = str.begin(); i != str.end(); i++)
88 os2 << *i;
89 buff=os2.rdbuf();
90 result=buff->str();
91 CPPUNIT_ASSERT(!strcmp(result.c_str(),"sstl"));
92
93
94 //cout << "uniqued: ";
95 str.unique();
96 ostringstream os3;
97 for(i = str.begin(); i != str.end(); i++)
98 os3 << *i;
99 buff=os3.rdbuf();
100 result=buff->str();
101 CPPUNIT_ASSERT(!strcmp(result.c_str(),"stl"));
102
103 //cout << "sorted: ";
104 str.sort();
105 ostringstream os4;
106 for(i = str.begin(); i != str.end(); i++)
107 os4 << *i;
108 buff = os4.rdbuf();
109 result = buff->str();
110 CPPUNIT_ASSERT(!strcmp(result.c_str(),"lst"));
111
112 //A small compilation time check to be activated from time to time:
113 # if 0
114 {
115 slist<char>::iterator sl_char_ite;
116 slist<int>::iterator sl_int_ite;
117 CPPUNIT_ASSERT( sl_char_ite != sl_int_ite );
118 }
119 # endif
120 #endif
121 }
122
erase()123 void SlistTest::erase()
124 {
125 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
126 int array[] = { 0, 1, 2, 3, 4 };
127 slist<int> sl(array, array + 5);
128 slist<int>::iterator slit;
129
130 slit = sl.erase(sl.begin());
131 CPPUNIT_ASSERT( *slit == 1);
132
133 ++slit++; ++slit;
134 slit = sl.erase(sl.begin(), slit);
135 CPPUNIT_ASSERT( *slit == 3 );
136
137 sl.assign(array, array + 5);
138
139 slit = sl.erase_after(sl.begin());
140 CPPUNIT_ASSERT( *slit == 2 );
141
142 slit = sl.begin(); ++slit; ++slit;
143 slit = sl.erase_after(sl.begin(), slit);
144 CPPUNIT_ASSERT( *slit == 3 );
145
146 sl.erase_after(sl.before_begin());
147 CPPUNIT_ASSERT( sl.front() == 3 );
148 #endif
149 }
150
insert()151 void SlistTest::insert()
152 {
153 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
154 int array[] = { 0, 1, 2, 3, 4 };
155
156 //insert
157 {
158 slist<int> sl;
159
160 sl.insert(sl.begin(), 5);
161 CPPUNIT_ASSERT( sl.front() == 5 );
162 CPPUNIT_ASSERT( sl.size() == 1 );
163
164 //debug mode check:
165 //sl.insert(sl.before_begin(), array, array + 5);
166
167 sl.insert(sl.begin(), array, array + 5);
168 CPPUNIT_ASSERT( sl.size() == 6 );
169 int i;
170 slist<int>::iterator slit(sl.begin());
171 for (i = 0; slit != sl.end(); ++slit, ++i) {
172 CPPUNIT_ASSERT( *slit == i );
173 }
174 }
175
176 //insert_after
177 {
178 slist<int> sl;
179
180 //debug check:
181 //sl.insert_after(sl.begin(), 5);
182
183 sl.insert_after(sl.before_begin(), 5);
184 CPPUNIT_ASSERT( sl.front() == 5 );
185 CPPUNIT_ASSERT( sl.size() == 1 );
186
187 sl.insert_after(sl.before_begin(), array, array + 5);
188 CPPUNIT_ASSERT( sl.size() == 6 );
189 int i;
190 slist<int>::iterator slit(sl.begin());
191 for (i = 0; slit != sl.end(); ++slit, ++i) {
192 CPPUNIT_ASSERT( *slit == i );
193 }
194 }
195 #endif
196 }
197
splice()198 void SlistTest::splice()
199 {
200 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
201 int array[] = { 0, 1, 2, 3, 4 };
202
203 //splice
204 {
205 slist<int> sl1(array, array + 5);
206 slist<int> sl2(array, array + 5);
207 slist<int>::iterator slit;
208
209 //a no op:
210 sl1.splice(sl1.begin(), sl1, sl1.begin());
211 CPPUNIT_ASSERT( sl1 == sl2 );
212
213 slit = sl1.begin(); ++slit;
214 //a no op:
215 sl1.splice(slit, sl1, sl1.begin());
216 CPPUNIT_ASSERT( sl1 == sl2 );
217
218 sl1.splice(sl1.end(), sl1, sl1.begin());
219 slit = sl1.begin();
220 CPPUNIT_ASSERT( *(slit++) == 1 );
221 CPPUNIT_ASSERT( *(slit++) == 2 );
222 CPPUNIT_ASSERT( *(slit++) == 3 );
223 CPPUNIT_ASSERT( *(slit++) == 4 );
224 CPPUNIT_ASSERT( *slit == 0 );
225 sl1.splice(sl1.begin(), sl1, slit);
226 CPPUNIT_ASSERT( sl1 == sl2 );
227
228 sl1.splice(sl1.begin(), sl2);
229 size_t i;
230 for (i = 0, slit = sl1.begin(); slit != sl1.end(); ++slit, ++i) {
231 if (i == 5) i = 0;
232 CPPUNIT_ASSERT( *slit == array[i] );
233 }
234
235 slit = sl1.begin();
236 advance(slit, 5);
237 CPPUNIT_ASSERT( *slit == 0 );
238 sl2.splice(sl2.begin(), sl1, sl1.begin(), slit);
239 CPPUNIT_ASSERT( sl1 == sl2 );
240
241 slit = sl1.begin(); ++slit;
242 sl1.splice(sl1.begin(), sl1, slit, sl1.end());
243 slit = sl1.begin();
244 CPPUNIT_ASSERT( *(slit++) == 1 );
245 CPPUNIT_ASSERT( *(slit++) == 2 );
246 CPPUNIT_ASSERT( *(slit++) == 3 );
247 CPPUNIT_ASSERT( *(slit++) == 4 );
248 CPPUNIT_ASSERT( *slit == 0 );
249
250 // a no op
251 sl2.splice(sl2.end(), sl2, sl2.begin(), sl2.end());
252 for (i = 0, slit = sl2.begin(); slit != sl2.end(); ++slit, ++i) {
253 CPPUNIT_ASSERT( i < 5 );
254 CPPUNIT_ASSERT( *slit == array[i] );
255 }
256
257 slit = sl2.begin();
258 advance(slit, 3);
259 sl2.splice(sl2.end(), sl2, sl2.begin(), slit);
260 slit = sl2.begin();
261 CPPUNIT_ASSERT( *(slit++) == 3 );
262 CPPUNIT_ASSERT( *(slit++) == 4 );
263 CPPUNIT_ASSERT( *(slit++) == 0 );
264 CPPUNIT_ASSERT( *(slit++) == 1 );
265 CPPUNIT_ASSERT( *slit == 2 );
266 }
267
268 //splice_after
269 {
270 slist<int> sl1(array, array + 5);
271 slist<int> sl2(array, array + 5);
272 slist<int>::iterator slit;
273
274 //a no op:
275 sl1.splice_after(sl1.begin(), sl1, sl1.begin());
276 CPPUNIT_ASSERT( sl1 == sl2 );
277
278 sl1.splice_after(sl1.before_begin(), sl1, sl1.begin());
279 slit = sl1.begin();
280 CPPUNIT_ASSERT( *(slit++) == 1 );
281 CPPUNIT_ASSERT( *(slit++) == 0 );
282 CPPUNIT_ASSERT( *(slit++) == 2 );
283 CPPUNIT_ASSERT( *(slit++) == 3 );
284 CPPUNIT_ASSERT( *slit == 4 );
285 sl1.splice_after(sl1.before_begin(), sl1, sl1.begin());
286 CPPUNIT_ASSERT( sl1 == sl2 );
287
288 sl1.splice_after(sl1.before_begin(), sl2);
289 size_t i;
290 for (i = 0, slit = sl1.begin(); slit != sl1.end(); ++slit, ++i) {
291 if (i == 5) i = 0;
292 CPPUNIT_ASSERT( *slit == array[i] );
293 }
294
295 slit = sl1.begin();
296 advance(slit, 4);
297 CPPUNIT_ASSERT( *slit == 4 );
298 sl2.splice_after(sl2.before_begin(), sl1, sl1.before_begin(), slit);
299 CPPUNIT_ASSERT( sl1 == sl2 );
300
301 sl1.splice_after(sl1.before_begin(), sl1, sl1.begin(), sl1.previous(sl1.end()));
302 slit = sl1.begin();
303 CPPUNIT_ASSERT( *(slit++) == 1 );
304 CPPUNIT_ASSERT( *(slit++) == 2 );
305 CPPUNIT_ASSERT( *(slit++) == 3 );
306 CPPUNIT_ASSERT( *(slit++) == 4 );
307 CPPUNIT_ASSERT( *slit == 0 );
308
309 // a no op
310 sl2.splice_after(sl2.before_begin(), sl2, sl2.before_begin(), sl2.previous(sl2.end()));
311 for (i = 0, slit = sl2.begin(); slit != sl2.end(); ++slit, ++i) {
312 CPPUNIT_ASSERT( i < 5 );
313 CPPUNIT_ASSERT( *slit == array[i] );
314 }
315
316 slit = sl2.begin();
317 advance(slit, 2);
318 sl2.splice_after(sl2.previous(sl2.end()), sl2, sl2.before_begin(), slit);
319 slit = sl2.begin();
320 CPPUNIT_ASSERT( *(slit++) == 3 );
321 CPPUNIT_ASSERT( *(slit++) == 4 );
322 CPPUNIT_ASSERT( *(slit++) == 0 );
323 CPPUNIT_ASSERT( *(slit++) == 1 );
324 CPPUNIT_ASSERT( *slit == 2 );
325 }
326 #endif
327 }
328
329
allocator_with_state()330 void SlistTest::allocator_with_state()
331 {
332 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
333 char buf1[1024];
334 StackAllocator<int> stack1(buf1, buf1 + sizeof(buf1));
335
336 char buf2[1024];
337 StackAllocator<int> stack2(buf2, buf2 + sizeof(buf2));
338
339 typedef slist<int, StackAllocator<int> > SlistInt;
340 {
341 SlistInt slint1(10, 0, stack1);
342 SlistInt slint1Cpy(slint1);
343
344 SlistInt slint2(10, 1, stack2);
345 SlistInt slint2Cpy(slint2);
346
347 slint1.swap(slint2);
348
349 CPPUNIT_ASSERT( slint1.get_allocator().swaped() );
350 CPPUNIT_ASSERT( slint2.get_allocator().swaped() );
351
352 CPPUNIT_ASSERT( slint1 == slint2Cpy );
353 CPPUNIT_ASSERT( slint2 == slint1Cpy );
354 CPPUNIT_ASSERT( slint1.get_allocator() == stack2 );
355 CPPUNIT_ASSERT( slint2.get_allocator() == stack1 );
356 }
357 CPPUNIT_CHECK( stack1.ok() );
358 CPPUNIT_CHECK( stack2.ok() );
359 stack1.reset(); stack2.reset();
360
361 {
362 SlistInt slint1(stack1);
363 SlistInt slint1Cpy(slint1);
364
365 SlistInt slint2(10, 1, stack2);
366 SlistInt slint2Cpy(slint2);
367
368 slint1.swap(slint2);
369
370 CPPUNIT_ASSERT( slint1.get_allocator().swaped() );
371 CPPUNIT_ASSERT( slint2.get_allocator().swaped() );
372
373 CPPUNIT_ASSERT( slint1 == slint2Cpy );
374 CPPUNIT_ASSERT( slint2 == slint1Cpy );
375 CPPUNIT_ASSERT( slint1.get_allocator() == stack2 );
376 CPPUNIT_ASSERT( slint2.get_allocator() == stack1 );
377 }
378 CPPUNIT_CHECK( stack1.ok() );
379 CPPUNIT_CHECK( stack2.ok() );
380 stack1.reset(); stack2.reset();
381
382 {
383 SlistInt slint1(10, 0, stack1);
384 SlistInt slint1Cpy(slint1);
385
386 SlistInt slint2(stack2);
387 SlistInt slint2Cpy(slint2);
388
389 slint1.swap(slint2);
390
391 CPPUNIT_ASSERT( slint1.get_allocator().swaped() );
392 CPPUNIT_ASSERT( slint2.get_allocator().swaped() );
393
394 CPPUNIT_ASSERT( slint1 == slint2Cpy );
395 CPPUNIT_ASSERT( slint2 == slint1Cpy );
396 CPPUNIT_ASSERT( slint1.get_allocator() == stack2 );
397 CPPUNIT_ASSERT( slint2.get_allocator() == stack1 );
398 }
399 CPPUNIT_CHECK( stack1.ok() );
400 CPPUNIT_CHECK( stack2.ok() );
401 stack1.reset(); stack2.reset();
402
403 //splice(iterator, slist)
404 {
405 SlistInt slint1(10, 0, stack1);
406 SlistInt slint2(10, 1, stack2);
407
408 slint1.splice(slint1.begin(), slint2);
409 CPPUNIT_ASSERT( slint1.size() == 20 );
410 CPPUNIT_ASSERT( slint2.empty() );
411 }
412 CPPUNIT_CHECK( stack1.ok() );
413 CPPUNIT_CHECK( stack2.ok() );
414 stack1.reset(); stack2.reset();
415
416 //splice(iterator, slist, iterator)
417 {
418 SlistInt slint1(10, 0, stack1);
419 SlistInt slint2(10, 1, stack2);
420
421 slint1.splice(slint1.begin(), slint2, slint2.begin());
422 CPPUNIT_ASSERT( slint1.size() == 11 );
423 CPPUNIT_ASSERT( slint2.size() == 9 );
424 }
425 CPPUNIT_CHECK( stack1.ok() );
426 CPPUNIT_CHECK( stack2.ok() );
427 stack1.reset(); stack2.reset();
428
429 //splice(iterator, slist, iterator, iterator)
430 {
431 SlistInt slint1(10, 0, stack1);
432 SlistInt slint2(10, 1, stack2);
433
434 SlistInt::iterator lit(slint2.begin());
435 advance(lit, 5);
436 slint1.splice(slint1.begin(), slint2, slint2.begin(), lit);
437 CPPUNIT_ASSERT( slint1.size() == 15 );
438 CPPUNIT_ASSERT( slint2.size() == 5 );
439 }
440 CPPUNIT_CHECK( stack1.ok() );
441 CPPUNIT_CHECK( stack2.ok() );
442 stack1.reset(); stack2.reset();
443
444 //splice_after(iterator, slist)
445 {
446 SlistInt slint1(10, 0, stack1);
447 SlistInt slint2(10, 1, stack2);
448
449 slint1.splice_after(slint1.before_begin(), slint2);
450 CPPUNIT_ASSERT( slint1.size() == 20 );
451 CPPUNIT_ASSERT( slint2.empty() );
452 }
453 CPPUNIT_CHECK( stack1.ok() );
454 CPPUNIT_CHECK( stack2.ok() );
455 stack1.reset(); stack2.reset();
456
457 //splice_after(iterator, slist, iterator)
458 {
459 SlistInt slint1(10, 0, stack1);
460 SlistInt slint2(10, 1, stack2);
461
462 slint1.splice_after(slint1.before_begin(), slint2, slint2.before_begin());
463 CPPUNIT_ASSERT( slint1.size() == 11 );
464 CPPUNIT_ASSERT( slint2.size() == 9 );
465 }
466 CPPUNIT_CHECK( stack1.ok() );
467 CPPUNIT_CHECK( stack2.ok() );
468 stack1.reset(); stack2.reset();
469
470 //splice_after(iterator, slist, iterator, iterator)
471 {
472 SlistInt slint1(10, 0, stack1);
473 SlistInt slint2(10, 1, stack2);
474
475 SlistInt::iterator lit(slint2.begin());
476 advance(lit, 4);
477 slint1.splice_after(slint1.before_begin(), slint2, slint2.before_begin(), lit);
478 CPPUNIT_ASSERT( slint1.size() == 15 );
479 CPPUNIT_ASSERT( slint2.size() == 5 );
480 }
481 CPPUNIT_CHECK( stack1.ok() );
482 CPPUNIT_CHECK( stack2.ok() );
483 stack1.reset(); stack2.reset();
484
485 //merge(slist)
486 {
487 SlistInt slint1(10, 0, stack1);
488 SlistInt slint2(10, 1, stack2);
489
490 SlistInt slintref(stack2);
491 slintref.insert_after(slintref.before_begin(), 10, 1);
492 slintref.insert_after(slintref.before_begin(), 10, 0);
493
494 slint1.merge(slint2);
495 CPPUNIT_ASSERT( slint1.size() == 20 );
496 CPPUNIT_ASSERT( slint1 == slintref );
497 CPPUNIT_ASSERT( slint2.empty() );
498 }
499 CPPUNIT_CHECK( stack1.ok() );
500 CPPUNIT_CHECK( stack2.ok() );
501
502 //merge(slist, predicate)
503 # if (!defined (STLPORT) || !defined (_STLP_NO_MEMBER_TEMPLATES)) && \
504 (!defined (_MSC_VER) || (_MSC_VER >= 1300))
505 {
506 SlistInt slint1(10, 0, stack1);
507 SlistInt slint2(10, 1, stack2);
508
509 SlistInt slintref(stack2);
510 slintref.insert_after(slintref.before_begin(), 10, 0);
511 slintref.insert_after(slintref.before_begin(), 10, 1);
512
513 slint1.merge(slint2, greater<int>());
514 CPPUNIT_ASSERT( slint1.size() == 20 );
515 CPPUNIT_ASSERT( slint1 == slintref );
516 CPPUNIT_ASSERT( slint2.empty() );
517 }
518 CPPUNIT_CHECK( stack1.ok() );
519 CPPUNIT_CHECK( stack2.ok() );
520
521 //sort
522 {
523 //This is rather a compile time test.
524 //We check that sort implementation is correct when list is instanciated
525 //with an allocator that do not have a default constructor.
526 SlistInt slint1(stack1);
527 slint1.push_front(1);
528 slint1.insert_after(slint1.before_begin(), 10, 0);
529 greater<int> gt;
530 slint1.sort(gt);
531 CPPUNIT_ASSERT( slint1.front() == 1 );
532 slint1.sort();
533 SlistInt::iterator slit(slint1.begin());
534 advance(slit, 10);
535 CPPUNIT_ASSERT( *slit == 1 );
536 }
537 # endif
538 #endif
539 }
540
541 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) && \
542 (!defined (_STLP_USE_PTR_SPECIALIZATIONS) || defined (_STLP_CLASS_PARTIAL_SPECIALIZATION))
543 # if !defined (__DMC__)
544 /* Simple compilation test: Check that nested types like iterator
545 * can be access even if type used to instanciate container is not
546 * yet completely defined.
547 */
548 class IncompleteClass
549 {
550 slist<IncompleteClass> instances;
551 typedef slist<IncompleteClass>::iterator it;
552 };
553 # endif
554 #endif
555