• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <list>
6 #include <algorithm>
7 #include <functional>
8 
9 #include "cppunit/cppunit_proxy.h"
10 
11 #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
12 using namespace std;
13 #endif
14 
15 //
16 // TestCase class
17 //
18 class ListTest : public CPPUNIT_NS::TestCase
19 {
20   CPPUNIT_TEST_SUITE(ListTest);
21   CPPUNIT_TEST(list1);
22   CPPUNIT_TEST(list2);
23   CPPUNIT_TEST(list3);
24   CPPUNIT_TEST(list4);
25   CPPUNIT_TEST(erase);
26   CPPUNIT_TEST(resize);
27   CPPUNIT_TEST(push_back);
28   CPPUNIT_TEST(push_front);
29   CPPUNIT_TEST(allocator_with_state);
30   CPPUNIT_TEST(swap);
31   CPPUNIT_TEST(adl);
32   //CPPUNIT_TEST(const_list);
33   CPPUNIT_TEST_SUITE_END();
34 
35 protected:
36   void list1();
37   void list2();
38   void list3();
39   void list4();
40   void erase();
41   void resize();
42   void push_back();
43   void push_front();
44   void allocator_with_state();
45   void swap();
46   void adl();
47   //void const_list();
48 };
49 
50 CPPUNIT_TEST_SUITE_REGISTRATION(ListTest);
51 
52 //
53 // tests implementation
54 //
list1()55 void ListTest::list1()
56 {
57   int array1 [] = { 9, 16, 36 };
58   int array2 [] = { 1, 4 };
59 
60   list<int> l1(array1, array1 + 3);
61   list<int> l2(array2, array2 + 2);
62   list<int>::iterator i1 = l1.begin();
63   list<int>::iterator i2 = l2.begin();
64   list<int>::const_iterator ci(i1);
65   list<int>::const_iterator ci1(ci);
66   l1.splice(i1, l2);
67   i1 = l1.begin();
68   CPPUNIT_ASSERT( *i1++ == 1 );
69   CPPUNIT_ASSERT( *i1++ == 4 );
70   CPPUNIT_ASSERT( *i1++ == 9 );
71   CPPUNIT_ASSERT( *i1++ == 16 );
72   CPPUNIT_ASSERT( *i1++ == 36 );
73 
74 #if defined (STLPORT) && \
75    (!defined (_STLP_DEBUG) || (_STLP_DEBUG_LEVEL != _STLP_STANDARD_DBG_LEVEL))
76   CPPUNIT_ASSERT( i2 == l1.begin() );
77 #endif
78 
79   //Default construct check (_STLP_DEF_CONST_PLCT_NEW_BUG)
80   list<int> l(2);
81   i1 = l.begin();
82   CPPUNIT_ASSERT( *(i1++) == 0 );
83   CPPUNIT_ASSERT( *i1 == 0 );
84 #if 0
85   //A small compilation time check to be activated from time to time,
86   //compilation should fail.
87   {
88     list<char>::iterator l_char_ite;
89     list<int>::iterator l_int_ite;
90     CPPUNIT_ASSERT( l_char_ite != l_int_ite );
91   }
92 #endif
93 }
94 
list2()95 void ListTest::list2()
96 {
97   int array1 [] = { 1, 16 };
98   int array2 [] = { 4, 9 };
99 
100   list<int> l1(array1, array1 + 2);
101   list<int> l2(array2, array2 + 2);
102   list<int>::iterator i = l1.begin();
103   i++;
104   l1.splice(i, l2, l2.begin(), l2.end());
105   i = l1.begin();
106   CPPUNIT_ASSERT(*i++==1);
107   CPPUNIT_ASSERT(*i++==4);
108   CPPUNIT_ASSERT(*i++==9);
109   CPPUNIT_ASSERT(*i++==16);
110 }
111 
list3()112 void ListTest::list3()
113 {
114   char array [] = { 'x', 'l', 'x', 't', 's', 's' };
115 
116   list<char> str(array, array + 6);
117   list<char>::iterator i;
118 
119   str.reverse();
120   i = str.begin();
121   CPPUNIT_ASSERT(*i++=='s');
122   CPPUNIT_ASSERT(*i++=='s');
123   CPPUNIT_ASSERT(*i++=='t');
124   CPPUNIT_ASSERT(*i++=='x');
125   CPPUNIT_ASSERT(*i++=='l');
126   CPPUNIT_ASSERT(*i++=='x');
127 
128   str.remove('x');
129   i = str.begin();
130   CPPUNIT_ASSERT(*i++=='s');
131   CPPUNIT_ASSERT(*i++=='s');
132   CPPUNIT_ASSERT(*i++=='t');
133   CPPUNIT_ASSERT(*i++=='l');
134 
135   str.unique();
136   i = str.begin();
137   CPPUNIT_ASSERT(*i++=='s');
138   CPPUNIT_ASSERT(*i++=='t');
139   CPPUNIT_ASSERT(*i++=='l');
140 
141   str.sort();
142   i = str.begin();
143   CPPUNIT_ASSERT(*i++=='l');
144   CPPUNIT_ASSERT(*i++=='s');
145   CPPUNIT_ASSERT(*i++=='t');
146 }
147 
list4()148 void ListTest::list4()
149 {
150   int array1 [] = { 1, 3, 6, 7 };
151   int array2 [] = { 2, 4 };
152 
153   list<int> l1(array1, array1 + 4);
154   list<int> l2(array2, array2 + 2);
155   l1.merge(l2);
156   list<int>::iterator i = l1.begin();
157   CPPUNIT_ASSERT(*i++==1);
158   CPPUNIT_ASSERT(*i++==2);
159   CPPUNIT_ASSERT(*i++==3);
160   CPPUNIT_ASSERT(*i++==4);
161   CPPUNIT_ASSERT(*i++==6);
162   CPPUNIT_ASSERT(*i++==7);
163 
164   //We use distance to avoid a simple call to an internal counter
165   CPPUNIT_ASSERT(distance(l1.begin(), l1.end()) == 6);
166   CPPUNIT_ASSERT(distance(l2.begin(), l2.end()) == 0);
167 
168   l1.swap(l2);
169 
170   CPPUNIT_ASSERT(distance(l1.begin(), l1.end()) == 0);
171   CPPUNIT_ASSERT(distance(l2.begin(), l2.end()) == 6);
172 }
173 
erase()174 void ListTest::erase()
175 {
176   list<int> l;
177   l.push_back( 1 );
178   l.erase(l.begin());
179   CPPUNIT_ASSERT( l.empty() );
180 
181   int array[] = { 0, 1, 2, 3 };
182   l.assign(array, array + 4);
183   list<int>::iterator lit;
184   lit = l.erase(l.begin());
185   CPPUNIT_ASSERT( *lit == 1 );
186 
187   lit = l.erase(l.begin(), --l.end());
188   CPPUNIT_ASSERT( *lit == 3 );
189 
190   l.clear();
191   CPPUNIT_ASSERT( l.empty() );
192 }
193 
194 
resize()195 void ListTest::resize()
196 {
197   {
198     list<int> l;
199     l.resize(5, 1);
200 
201     size_t i;
202     list<int>::iterator lit(l.begin());
203     for (i = 0; i < 5; ++i) {
204       CPPUNIT_ASSERT( lit != l.end() );
205       CPPUNIT_ASSERT( *(lit++) == 1 );
206     }
207     CPPUNIT_ASSERT( lit == l.end() );
208 
209     l.resize(3);
210     lit = l.begin();
211     for (i = 0; i < 3; ++i) {
212       CPPUNIT_ASSERT( lit != l.end() );
213       CPPUNIT_ASSERT( *(lit++) == 1 );
214     }
215     CPPUNIT_ASSERT( lit == l.end() );
216   }
217 
218   {
219     list<int> l;
220     l.resize(5);
221 
222     size_t i;
223     list<int>::iterator lit(l.begin());
224     for (i = 0; i < 5; ++i) {
225       CPPUNIT_ASSERT( lit != l.end() );
226       CPPUNIT_ASSERT( *(lit++) == 0 );
227     }
228     CPPUNIT_ASSERT( lit == l.end() );
229   }
230 }
231 
push_back()232 void ListTest::push_back()
233 {
234   list<int> l;
235   l.push_back( 1 );
236   l.push_back( 2 );
237   l.push_back( 3 );
238 
239   list<int>::reverse_iterator r = l.rbegin();
240 
241   CPPUNIT_ASSERT( *r == 3 );
242   l.push_back( 4 );
243   /*
244    * Following lines are commented, because ones show standard contradiction
245    * (24.4.1 and 23.2.2.3); but present behaviour is valid, 24.4.1, paragraphs 1 and 2,
246    * 24.4.1.3.3 and 23.1 paragraph 9 (Table 66). The 24.4.1 is more common rule,
247    * so it has preference under 23.2.2.3, by my opinion.
248    *
249    *      - ptr
250    */
251   // CPPUNIT_ASSERT( *r == 3 );
252   // ++r;
253   // CPPUNIT_ASSERT( *r == 2 );
254 }
255 
push_front()256 void ListTest::push_front()
257 {
258   list<int> l;
259   l.push_back( 1 );
260   l.push_back( 2 );
261   l.push_back( 3 );
262 
263   list<int>::iterator i = l.begin();
264 
265   CPPUNIT_ASSERT( *i == 1 );
266   l.push_front( 0 );
267   CPPUNIT_ASSERT( *i == 1 );
268   ++i;
269   CPPUNIT_ASSERT( *i == 2 );
270 }
271 
allocator_with_state()272 void ListTest::allocator_with_state()
273 {
274   char buf1[1024];
275   StackAllocator<int> stack1(buf1, buf1 + sizeof(buf1));
276 
277   char buf2[1024];
278   StackAllocator<int> stack2(buf2, buf2 + sizeof(buf2));
279 
280   typedef list<int, StackAllocator<int> > ListInt;
281   {
282     //Swap with both list non empty
283     ListInt lint1(10, 0, stack1);
284     ListInt lint1Cpy(lint1);
285 
286     ListInt lint2(10, 1, stack2);
287     ListInt lint2Cpy(lint2);
288 
289     lint1.swap(lint2);
290 
291     CPPUNIT_ASSERT( lint1.get_allocator().swaped() );
292     CPPUNIT_ASSERT( lint2.get_allocator().swaped() );
293 
294     CPPUNIT_ASSERT( lint1 == lint2Cpy );
295     CPPUNIT_ASSERT( lint2 == lint1Cpy );
296     CPPUNIT_ASSERT( lint1.get_allocator() == stack2 );
297     CPPUNIT_ASSERT( lint2.get_allocator() == stack1 );
298   }
299   CPPUNIT_CHECK( stack1.ok() );
300   CPPUNIT_CHECK( stack2.ok() );
301   stack1.reset(); stack2.reset();
302 
303   {
304     //Swap with empty calle list
305     ListInt lint1(10, 0, stack1);
306     ListInt lint1Cpy(lint1);
307 
308     ListInt lint2(stack2);
309     ListInt lint2Cpy(lint2);
310 
311     lint1.swap(lint2);
312 
313     CPPUNIT_ASSERT( lint1.get_allocator().swaped() );
314     CPPUNIT_ASSERT( lint2.get_allocator().swaped() );
315 
316     CPPUNIT_ASSERT( lint1 == lint2Cpy );
317     CPPUNIT_ASSERT( lint2 == lint1Cpy );
318     CPPUNIT_ASSERT( lint1.get_allocator() == stack2 );
319     CPPUNIT_ASSERT( lint2.get_allocator() == stack1 );
320   }
321   CPPUNIT_CHECK( stack1.ok() );
322   CPPUNIT_CHECK( stack2.ok() );
323   stack1.reset(); stack2.reset();
324 
325   {
326     //Swap with empty caller list
327     ListInt lint1(stack1);
328     ListInt lint1Cpy(lint1);
329 
330     ListInt lint2(10, 0, stack2);
331     ListInt lint2Cpy(lint2);
332 
333     lint1.swap(lint2);
334 
335     CPPUNIT_ASSERT( lint1.get_allocator().swaped() );
336     CPPUNIT_ASSERT( lint2.get_allocator().swaped() );
337 
338     CPPUNIT_ASSERT( lint1 == lint2Cpy );
339     CPPUNIT_ASSERT( lint2 == lint1Cpy );
340     CPPUNIT_ASSERT( lint1.get_allocator() == stack2 );
341     CPPUNIT_ASSERT( lint2.get_allocator() == stack1 );
342   }
343   CPPUNIT_CHECK( stack1.ok() );
344   CPPUNIT_CHECK( stack2.ok() );
345   stack1.reset(); stack2.reset();
346 
347   {
348     ListInt lint1(10, 0, stack1);
349     ListInt lint2(10, 1, stack2);
350 
351     lint1.splice(lint1.begin(), lint2);
352     CPPUNIT_ASSERT( lint1.size() == 20 );
353     CPPUNIT_ASSERT( lint2.empty() );
354   }
355   CPPUNIT_CHECK( stack1.ok() );
356   CPPUNIT_CHECK( stack2.ok() );
357   stack1.reset(); stack2.reset();
358 
359   {
360     ListInt lint1(10, 0, stack1);
361     ListInt lint2(10, 1, stack2);
362 
363     lint1.splice(lint1.begin(), lint2, lint2.begin());
364     CPPUNIT_ASSERT( lint1.size() == 11 );
365     CPPUNIT_ASSERT( lint2.size() == 9 );
366   }
367   CPPUNIT_CHECK( stack1.ok() );
368   CPPUNIT_CHECK( stack2.ok() );
369   stack1.reset(); stack2.reset();
370 
371   {
372     ListInt lint1(10, 0, stack1);
373     ListInt lint2(10, 1, stack2);
374 
375     ListInt::iterator lit(lint2.begin());
376     advance(lit, 5);
377     lint1.splice(lint1.begin(), lint2, lint2.begin(), lit);
378     CPPUNIT_ASSERT( lint1.size() == 15 );
379     CPPUNIT_ASSERT( lint2.size() == 5 );
380   }
381   CPPUNIT_CHECK( stack1.ok() );
382   CPPUNIT_CHECK( stack2.ok() );
383   stack1.reset(); stack2.reset();
384 
385   {
386     ListInt lint1(10, 0, stack1);
387     ListInt lint2(10, 1, stack2);
388 
389     ListInt lintref(stack2);
390     lintref.insert(lintref.begin(), 10, 1);
391     lintref.insert(lintref.begin(), 10, 0);
392 
393     lint1.merge(lint2);
394     CPPUNIT_ASSERT( lint1.size() == 20 );
395     CPPUNIT_ASSERT( lint1 == lintref );
396     CPPUNIT_ASSERT( lint2.empty() );
397   }
398   CPPUNIT_CHECK( stack1.ok() );
399   CPPUNIT_CHECK( stack2.ok() );
400 
401 #if defined (STLPORT) && !defined (_STLP_NO_MEMBER_TEMPLATES) && \
402     (!defined (_MSC_VER) || (_MSC_VER >= 1300))
403   {
404     //This is a compile time test.
405     //We check that sort implementation is correct when list is instanciated
406     //with an allocator that do not have a default constructor.
407     ListInt lint1(10, 0, stack1);
408     lint1.sort();
409     lint1.sort(greater<int>());
410   }
411 #endif
412 }
413 
414 /*
415 void ListTest::const_list()
416 {
417   list<const int> cint_list;
418   cint_list.push_back(1);
419   cint_list.push_front(2);
420 }
421 */
swap()422 void ListTest::swap()
423 {
424   list<int> lst1;
425   list<int> lst2;
426 
427   lst1.push_back(1);
428   lst2.push_back(2);
429 
430   lst1.swap( lst2 );
431 
432   CPPUNIT_CHECK( lst1.front() == 2 );
433   CPPUNIT_CHECK( lst2.front() == 1 );
434   CPPUNIT_CHECK( lst1.size() == 1 );
435   CPPUNIT_CHECK( lst2.size() == 1 );
436 
437   lst1.pop_front();
438   lst2.pop_front();
439 
440   CPPUNIT_CHECK( lst1.empty() );
441   CPPUNIT_CHECK( lst2.empty() );
442 }
443 
444 namespace foo {
445   class bar {};
446 
447   template <class _It>
448   size_t distance(_It, _It);
449 }
450 
adl()451 void ListTest::adl()
452 {
453   list<foo::bar> lbar;
454   CPPUNIT_ASSERT( lbar.size() == 0);
455 }
456 
457 #if !defined (STLPORT) || \
458     !defined (_STLP_USE_PTR_SPECIALIZATIONS) || defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
459 /* Simple compilation test: Check that nested types like iterator
460  * can be access even if type used to instanciate container is not
461  * yet completely defined.
462  */
463 class IncompleteClass
464 {
465   list<IncompleteClass> instances;
466   typedef list<IncompleteClass>::iterator it;
467 };
468 #endif
469