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 {
NotTrivialCopyStructNotTrivialCopyStruct31 NotTrivialCopyStruct() : member(0) {}
NotTrivialCopyStructNotTrivialCopyStruct32 NotTrivialCopyStruct(NotTrivialCopyStruct const&) : member(1) {}
33
34 int member;
35 };
36
37 struct TrivialCopyStruct {
TrivialCopyStructTrivialCopyStruct38 TrivialCopyStruct() : member(0) {}
TrivialCopyStructTrivialCopyStruct39 TrivialCopyStruct(TrivialCopyStruct const&) : member(1) {}
40
41 int member;
42 };
43
44 struct TrivialInitStruct {
TrivialInitStructTrivialInitStruct45 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 //
copy_test()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