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)
8using namespace std;
9#endif
10
11//
12// TestCase class
13//
14class 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
22protected:
23  void copy_test();
24  void fill_test();
25  void fill_n_test();
26};
27
28CPPUNIT_TEST_SUITE_REGISTRATION(UninitializedTest);
29
30struct NotTrivialCopyStruct {
31  NotTrivialCopyStruct() : member(0) {}
32  NotTrivialCopyStruct(NotTrivialCopyStruct const&) : member(1) {}
33
34  int member;
35};
36
37struct TrivialCopyStruct {
38  TrivialCopyStruct() : member(0) {}
39  TrivialCopyStruct(TrivialCopyStruct const&) : member(1) {}
40
41  int member;
42};
43
44struct TrivialInitStruct {
45  TrivialInitStruct()
46  { ++nbConstructorCalls; }
47
48  static size_t nbConstructorCalls;
49};
50
51size_t TrivialInitStruct::nbConstructorCalls = 0;
52
53#if defined (STLPORT)
54#  if defined (_STLP_USE_NAMESPACES)
55namespace 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
81struct base {};
82struct derived : public base {};
83
84//
85// tests implementation
86//
87void 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/*
238void UninitializedTest::fill_test()
239{
240}
241
242void UninitializedTest::fill_n_test()
243{
244}
245*/
246