1 #include <memory>
2 #include <vector>
3 #include <list>
4 
5 #include "cppunit/cppunit_proxy.h"
6 
7 #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
8 using namespace std;
9 #endif
10 
11 //
12 // TestCase class
13 //
14 class UninitializedTest : public CPPUNIT_NS::TestCase
15 {
16   CPPUNIT_TEST_SUITE(UninitializedTest);
17   CPPUNIT_TEST(copy_test);
18   //CPPUNIT_TEST(fill_test);
19   //CPPUNIT_TEST(fill_n_test);
20   CPPUNIT_TEST_SUITE_END();
21 
22 protected:
23   void copy_test();
24   void fill_test();
25   void fill_n_test();
26 };
27 
28 CPPUNIT_TEST_SUITE_REGISTRATION(UninitializedTest);
29 
30 struct NotTrivialCopyStruct {
31   NotTrivialCopyStruct() : member(0) {}
32   NotTrivialCopyStruct(NotTrivialCopyStruct const&) : member(1) {}
33 
34   int member;
35 };
36 
37 struct TrivialCopyStruct {
38   TrivialCopyStruct() : member(0) {}
39   TrivialCopyStruct(TrivialCopyStruct const&) : member(1) {}
40 
41   int member;
42 };
43 
44 struct TrivialInitStruct {
45   TrivialInitStruct()
46   { ++nbConstructorCalls; }
47 
48   static size_t nbConstructorCalls;
49 };
50 
51 size_t TrivialInitStruct::nbConstructorCalls = 0;
52 
53 #if defined (STLPORT)
54 #  if defined (_STLP_USE_NAMESPACES)
55 namespace std {
56 #  endif
57   _STLP_TEMPLATE_NULL
58   struct __type_traits<TrivialCopyStruct> {
59      typedef __false_type has_trivial_default_constructor;
60      //This is a wrong declaration just to check that internaly a simple memcpy is called:
61      typedef __true_type has_trivial_copy_constructor;
62      typedef __true_type has_trivial_assignment_operator;
63      typedef __true_type has_trivial_destructor;
64      typedef __false_type is_POD_type;
65   };
66 
67   _STLP_TEMPLATE_NULL
68   struct __type_traits<TrivialInitStruct> {
69      //This is a wrong declaration just to check that internaly no initialization is done:
70      typedef __true_type has_trivial_default_constructor;
71      typedef __true_type has_trivial_copy_constructor;
72      typedef __true_type has_trivial_assignment_operator;
73      typedef __true_type has_trivial_destructor;
74      typedef __false_type is_POD_type;
75   };
76 #  if defined (_STLP_USE_NAMESPACES)
77 }
78 #  endif
79 #endif
80 
81 struct base {};
82 struct derived : public base {};
83 
84 //
85 // tests implementation
86 //
87 void UninitializedTest::copy_test()
88 {
89   {
90     //Random iterators
91     {
92       vector<NotTrivialCopyStruct> src(10);
93       vector<NotTrivialCopyStruct> dst(10);
94       uninitialized_copy(src.begin(), src.end(), dst.begin());
95       vector<NotTrivialCopyStruct>::const_iterator it(dst.begin()), end(dst.end());
96       for (; it != end; ++it) {
97         CPPUNIT_ASSERT( (*it).member == 1 );
98       }
99     }
100     {
101       /** Note: we use static arrays here so the iterators are always
102       pointers, even in debug mode. */
103       size_t const count = 10;
104       TrivialCopyStruct src[count];
105       TrivialCopyStruct dst[count];
106 
107       TrivialCopyStruct* it = src + 0;
108       TrivialCopyStruct* end = src + count;
109       for (; it != end; ++it) {
110         (*it).member = 0;
111       }
112 
113       uninitialized_copy(src+0, src+count, dst+0);
114       for (it = dst+0, end = dst+count; it != end; ++it) {
115 #if defined (STLPORT)
116         /* If the member is 1, it means that library has not found any
117         optimization oportunity and called the regular copy-ctor instead. */
118         CPPUNIT_ASSERT( (*it).member == 0 );
119 #else
120         CPPUNIT_ASSERT( (*it).member == 1 );
121 #endif
122       }
123     }
124   }
125 
126   {
127     //Bidirectional iterator
128     {
129       vector<NotTrivialCopyStruct> src(10);
130       list<NotTrivialCopyStruct> dst(10);
131 
132       list<NotTrivialCopyStruct>::iterator it(dst.begin()), end(dst.end());
133       for (; it != end; ++it) {
134         (*it).member = -1;
135       }
136 
137       uninitialized_copy(src.begin(), src.end(), dst.begin());
138 
139       for (it = dst.begin(); it != end; ++it) {
140         CPPUNIT_ASSERT( (*it).member == 1 );
141       }
142     }
143 
144     {
145       list<NotTrivialCopyStruct> src(10);
146       vector<NotTrivialCopyStruct> dst(10);
147 
148       vector<NotTrivialCopyStruct>::iterator it(dst.begin()), end(dst.end());
149       for (; it != end; ++it) {
150         (*it).member = -1;
151       }
152 
153       uninitialized_copy(src.begin(), src.end(), dst.begin());
154 
155       for (it = dst.begin(); it != end; ++it) {
156         CPPUNIT_ASSERT( (*it).member == 1 );
157       }
158     }
159   }
160 
161   {
162     //Using containers of native types:
163 #if !defined (STLPORT) || !defined (_STLP_NO_MEMBER_TEMPLATES)
164     {
165       vector<int> src;
166       int i;
167       for (i = -5; i < 6; ++i) {
168         src.push_back(i);
169       }
170 
171       //Building a vector result in a uninitialized_copy call internally
172       vector<unsigned int> dst(src.begin(), src.end());
173       vector<unsigned int>::const_iterator it(dst.begin());
174       for (i = -5; i < 6; ++i, ++it) {
175         CPPUNIT_ASSERT( *it == (unsigned int)i );
176       }
177     }
178 
179     {
180       vector<char> src;
181       char i;
182       for (i = -5; i < 6; ++i) {
183         src.push_back(i);
184       }
185 
186       //Building a vector result in a uninitialized_copy call internally
187       vector<unsigned int> dst(src.begin(), src.end());
188       vector<unsigned int>::const_iterator it(dst.begin());
189       for (i = -5; i < 6; ++i, ++it) {
190         CPPUNIT_ASSERT( *it == (unsigned int)i );
191       }
192     }
193 
194     {
195       vector<int> src;
196       int i;
197       for (i = -5; i < 6; ++i) {
198         src.push_back(i);
199       }
200 
201       //Building a vector result in a uninitialized_copy call internally
202       vector<float> dst(src.begin(), src.end());
203       vector<float>::const_iterator it(dst.begin());
204       for (i = -5; i < 6; ++i, ++it) {
205         CPPUNIT_ASSERT( *it == (float)i );
206       }
207     }
208 
209     {
210       vector<vector<float>*> src(10);
211       vector<vector<float>*> dst(src.begin(), src.end());
212     }
213 
214     {
215       derived d;
216       //base *pb = &d;
217       derived *pd = &d;
218       //base **ppb = &pd;
219       vector<derived*> src(10, pd);
220       vector<base*> dst(src.begin(), src.end());
221       vector<base*>::iterator it(dst.begin()), end(dst.end());
222       for (; it != end; ++it) {
223         CPPUNIT_ASSERT( (*it) == pd );
224       }
225     }
226 #endif
227   }
228 
229   {
230     //Vector initialization:
231     vector<TrivialInitStruct> vect(10);
232     //Just 1 constructor call for the default value:
233     CPPUNIT_ASSERT( TrivialInitStruct::nbConstructorCalls == 1  );
234   }
235 }
236 
237 /*
238 void UninitializedTest::fill_test()
239 {
240 }
241 
242 void UninitializedTest::fill_n_test()
243 {
244 }
245 */
246