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