1 #include <vector>
2 #include <algorithm>
3 #include <string>
4 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
5 # include <rope>
6 #endif
7 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
8 # include <slist>
9 #endif
10 #include <list>
11 #include <deque>
12 #include <set>
13 #include <map>
14 #if defined (STLPORT)
15 # include <unordered_set>
16 # include <unordered_map>
17 #endif
18 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
19 # include <hash_set>
20 # include <hash_map>
21 #endif
22 #include <queue>
23 #include <stack>
24
25 #include "mvctor_test.h"
26
27 #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
28 using namespace std;
29 # if defined (STLPORT)
30 using namespace std::tr1;
31 # endif
32 #endif
33
34 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
35
36 # if defined (__GNUC__) && defined (_STLP_USE_NAMESPACES)
37 // libstdc++ sometimes exposed its own __true_type in
38 // global namespace resulting in an ambiguity.
39 # define __true_type std::__true_type
40 # define __false_type std::__false_type
41 # endif
42
type_to_bool(__true_type)43 static bool type_to_bool(__true_type)
44 { return true; }
type_to_bool(__false_type)45 static bool type_to_bool(__false_type)
46 { return false; }
47
48 template <class _Tp>
is_movable(const _Tp &)49 static bool is_movable(const _Tp&) {
50 typedef typename __move_traits<_Tp>::implemented _MovableTp;
51 return type_to_bool(_MovableTp());
52 }
53
54 template <class _Tp>
is_move_complete(const _Tp &)55 static bool is_move_complete(const _Tp&) {
56 typedef __move_traits<_Tp> _TpMoveTraits;
57 typedef typename _TpMoveTraits::complete _TpMoveComplete;
58 return type_to_bool(_TpMoveComplete());
59 }
60
61 struct specially_allocated_struct {
62 bool operator < (const specially_allocated_struct&) const;
63 # if defined (__DMC__) // slist<_Tp,_Alloc>::remove error
64 bool operator==(const specially_allocated_struct&) const;
65 # endif
66 };
67
68 #if defined (__DMC__)
operator <(const specially_allocated_struct &) const69 bool specially_allocated_struct::operator < (const specially_allocated_struct&) const
70 { return false; }
71 #endif
72
73 struct struct_with_specialized_less {};
74
75 # if defined (_STLP_USE_NAMESPACES)
76 namespace std {
77 # endif
78 _STLP_TEMPLATE_NULL
79 class allocator<specially_allocated_struct> {
80 //This allocator just represent what a STLport could do and in this
81 //case the STL containers implemented with it should still be movable
82 //but not completely as we cannot do any hypothesis on what is in this
83 //allocator.
84 public:
85 typedef specially_allocated_struct value_type;
86 typedef value_type * pointer;
87 typedef const value_type* const_pointer;
88 typedef value_type& reference;
89 typedef const value_type& const_reference;
90 typedef size_t size_type;
91 typedef ptrdiff_t difference_type;
92 # if defined (_STLP_MEMBER_TEMPLATE_CLASSES)
93 template <class _Tp1> struct rebind {
94 typedef allocator<_Tp1> other;
95 };
96 # endif
allocator()97 allocator() _STLP_NOTHROW {}
98 # if defined (_STLP_MEMBER_TEMPLATES)
allocator(const allocator<_Tp1> &)99 template <class _Tp1> allocator(const allocator<_Tp1>&) _STLP_NOTHROW {}
100 # endif
allocator(const allocator &)101 allocator(const allocator&) _STLP_NOTHROW {}
~allocator()102 ~allocator() _STLP_NOTHROW {}
address(reference __x) const103 pointer address(reference __x) const { return &__x; }
address(const_reference __x) const104 const_pointer address(const_reference __x) const { return &__x; }
allocate(size_type,const void * =0)105 pointer allocate(size_type, const void* = 0) { return 0; }
deallocate(pointer,size_type)106 void deallocate(pointer, size_type) {}
max_size() const107 size_type max_size() const _STLP_NOTHROW { return 0; }
construct(pointer,const_reference)108 void construct(pointer, const_reference) {}
destroy(pointer)109 void destroy(pointer) {}
110 };
111
112 _STLP_TEMPLATE_NULL
113 struct less<struct_with_specialized_less> {
114 bool operator() (struct_with_specialized_less const&,
115 struct_with_specialized_less const&) const;
116 };
117
118 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
119 # if !defined (_STLP_NO_MOVE_SEMANTIC)
120 # if defined (__BORLANDC__) && (__BORLANDC__ >= 0x564)
121 _STLP_TEMPLATE_NULL
122 struct __move_traits<vector<specially_allocated_struct> > {
123 typedef __true_type implemented;
124 typedef __false_type complete;
125 };
126 _STLP_TEMPLATE_NULL
127 struct __move_traits<deque<specially_allocated_struct> > {
128 typedef __true_type implemented;
129 typedef __false_type complete;
130 };
131 _STLP_TEMPLATE_NULL
132 struct __move_traits<list<specially_allocated_struct> > {
133 typedef __true_type implemented;
134 typedef __false_type complete;
135 };
136 _STLP_TEMPLATE_NULL
137 struct __move_traits<slist<specially_allocated_struct> > {
138 typedef __true_type implemented;
139 typedef __false_type complete;
140 };
141 _STLP_TEMPLATE_NULL
142 struct __move_traits<less<struct_with_specialized_less> > {
143 typedef __true_type implemented;
144 typedef __false_type complete;
145 };
146 _STLP_TEMPLATE_NULL
147 struct __move_traits<set<specially_allocated_struct> > {
148 typedef __true_type implemented;
149 typedef __false_type complete;
150 };
151 _STLP_TEMPLATE_NULL
152 struct __move_traits<multiset<specially_allocated_struct> > {
153 typedef __true_type implemented;
154 typedef __false_type complete;
155 };
156 # endif
157 # endif
158 # endif
159
160 # if defined (_STLP_USE_NAMESPACES)
161 }
162 # endif
163 #endif
164
movable_declaration()165 void MoveConstructorTest::movable_declaration()
166 {
167 #if defined (STLPORT) && !defined (_STLP_DONT_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS) && \
168 !defined (_STLP_NO_MOVE_SEMANTIC)
169 //This test purpose is to check correct detection of the STL movable
170 //traits declaration
171 {
172 //string, wstring:
173 CPPUNIT_ASSERT( is_movable(string()) );
174 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
175 CPPUNIT_ASSERT( is_move_complete(string()) );
176 # else
177 CPPUNIT_ASSERT( !is_move_complete(string()) );
178 # endif
179 # if defined (_STLP_HAS_WCHAR_T)
180 CPPUNIT_ASSERT( is_movable(wstring()) );
181 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
182 CPPUNIT_ASSERT( is_move_complete(wstring()) );
183 # else
184 CPPUNIT_ASSERT( !is_move_complete(wstring()) );
185 # endif
186 # endif
187 }
188
189 # if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
190 {
191 //crope, wrope:
192 CPPUNIT_ASSERT( is_movable(crope()) );
193 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
194 CPPUNIT_ASSERT( is_move_complete(crope()) );
195 # else
196 CPPUNIT_ASSERT( !is_move_complete(crope()) );
197 # endif
198 # if defined (_STLP_HAS_WCHAR_T)
199 CPPUNIT_ASSERT( is_movable(wrope()) );
200 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
201 CPPUNIT_ASSERT( is_move_complete(wrope()) );
202 # else
203 CPPUNIT_ASSERT( !is_move_complete(wrope()) );
204 # endif
205 # endif
206 }
207 # endif
208
209 {
210 //vector:
211 CPPUNIT_ASSERT( is_movable(vector<char>()) );
212 CPPUNIT_ASSERT( is_movable(vector<specially_allocated_struct>()) );
213 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
214 CPPUNIT_ASSERT( is_move_complete(vector<char>()) );
215 CPPUNIT_ASSERT( !is_move_complete(vector<specially_allocated_struct>()) );
216 # else
217 CPPUNIT_ASSERT( !is_move_complete(vector<char>()) );
218 # endif
219 }
220
221 {
222 //deque:
223 CPPUNIT_ASSERT( is_movable(deque<char>()) );
224 CPPUNIT_ASSERT( is_movable(deque<specially_allocated_struct>()) );
225 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
226 CPPUNIT_ASSERT( is_move_complete(deque<char>()) );
227 CPPUNIT_ASSERT( !is_move_complete(deque<specially_allocated_struct>()) );
228 # else
229 CPPUNIT_ASSERT( !is_move_complete(deque<char>()) );
230 # endif
231 }
232
233 {
234 //list:
235 CPPUNIT_ASSERT( is_movable(list<char>()) );
236 CPPUNIT_ASSERT( is_movable(list<specially_allocated_struct>()) );
237 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
238 CPPUNIT_ASSERT( is_move_complete(list<char>()) );
239 CPPUNIT_ASSERT( !is_move_complete(list<specially_allocated_struct>()) );
240 # else
241 CPPUNIT_ASSERT( !is_move_complete(list<char>()) );
242 # endif
243 }
244
245 # if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
246 {
247 //slist:
248 CPPUNIT_ASSERT( is_movable(slist<char>()) );
249 CPPUNIT_ASSERT( is_movable(slist<specially_allocated_struct>()) );
250 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
251 CPPUNIT_ASSERT( is_move_complete(slist<char>()) );
252 CPPUNIT_ASSERT( !is_move_complete(slist<specially_allocated_struct>()) );
253 # else
254 CPPUNIT_ASSERT( !is_move_complete(slist<char>()) );
255 # endif
256 }
257 # endif
258
259 {
260 //queue:
261 CPPUNIT_ASSERT( is_movable(queue<char>()) );
262 CPPUNIT_ASSERT( is_movable(queue<specially_allocated_struct>()) );
263 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
264 CPPUNIT_ASSERT( is_move_complete(queue<char>()) );
265 CPPUNIT_ASSERT( !is_move_complete(queue<specially_allocated_struct>()) );
266 # else
267 CPPUNIT_ASSERT( !is_move_complete(queue<char>()) );
268 # endif
269 }
270
271 {
272 //stack:
273 CPPUNIT_ASSERT( is_movable(stack<char>()) );
274 CPPUNIT_ASSERT( is_movable(stack<specially_allocated_struct>()) );
275 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
276 CPPUNIT_ASSERT( is_move_complete(stack<char>()) );
277 CPPUNIT_ASSERT( !is_move_complete(stack<specially_allocated_struct>()) );
278 # else
279 CPPUNIT_ASSERT( !is_move_complete(stack<char>()) );
280 # endif
281 }
282
283 #endif
284 }
285
movable_declaration_assoc()286 void MoveConstructorTest::movable_declaration_assoc()
287 {
288 #if defined (STLPORT) && !defined (_STLP_DONT_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS) && \
289 !defined (_STLP_NO_MOVE_SEMANTIC)
290 {
291 //associative containers, set multiset, map, multimap:
292
293 //For associative containers it is important that less is correctly recognize as
294 //the STLport less or a user specialized less:
295 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
296 CPPUNIT_ASSERT( is_move_complete(less<char>()) );
297 # endif
298 CPPUNIT_ASSERT( !is_move_complete(less<struct_with_specialized_less>()) );
299
300 //set
301 CPPUNIT_ASSERT( is_movable(set<char>()) );
302 CPPUNIT_ASSERT( is_movable(set<specially_allocated_struct>()) );
303 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
304 CPPUNIT_ASSERT( is_move_complete(set<char>()) );
305 CPPUNIT_ASSERT( !is_move_complete(set<specially_allocated_struct>()) );
306 # else
307 CPPUNIT_ASSERT( !is_move_complete(set<char>()) );
308 # endif
309
310 //multiset
311 CPPUNIT_ASSERT( is_movable(multiset<char>()) );
312 CPPUNIT_ASSERT( is_movable(multiset<specially_allocated_struct>()) );
313 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
314 CPPUNIT_ASSERT( is_move_complete(multiset<char>()) );
315 CPPUNIT_ASSERT( !is_move_complete(multiset<specially_allocated_struct>()) );
316 # else
317 CPPUNIT_ASSERT( !is_move_complete(multiset<char>()) );
318 # endif
319
320 //map
321 CPPUNIT_ASSERT( is_movable(map<char, char>()) );
322 CPPUNIT_ASSERT( is_movable(map<specially_allocated_struct, char>()) );
323 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
324 CPPUNIT_ASSERT( is_move_complete(map<char, char>()) );
325 //Here even if allocator has been specialized for specially_allocated_struct
326 //this pecialization won't be used in default map instanciation as the default
327 //allocator is allocator<pair<specially_allocated_struct, char> >
328 CPPUNIT_ASSERT( is_move_complete(map<specially_allocated_struct, char>()) );
329 # else
330 CPPUNIT_ASSERT( !is_move_complete(map<char, char>()) );
331 # endif
332
333 //multimap
334 CPPUNIT_ASSERT( is_movable(multimap<char, char>()) );
335 CPPUNIT_ASSERT( is_movable(multimap<specially_allocated_struct, char>()) );
336 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
337 CPPUNIT_ASSERT( is_move_complete(multimap<char, char>()) );
338 //Idem map remark
339 CPPUNIT_ASSERT( is_move_complete(multimap<specially_allocated_struct, char>()) );
340 # else
341 CPPUNIT_ASSERT( !is_move_complete(multimap<char, char>()) );
342 # endif
343 }
344 #endif
345 }
346
movable_declaration_hash()347 void MoveConstructorTest::movable_declaration_hash()
348 {
349 #if defined (STLPORT) && !defined (_STLP_DONT_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS) && \
350 !defined (_STLP_NO_MOVE_SEMANTIC)
351 {
352 //hashed containers, unordered_set unordered_multiset, unordered_map, unordered_multimap,
353 // hash_set, hash_multiset, hash_map, hash_multimap:
354
355 //We only check that they are movable, completness is not yet supported
356 CPPUNIT_ASSERT( is_movable(unordered_set<char>()) );
357 CPPUNIT_ASSERT( is_movable(unordered_multiset<char>()) );
358 CPPUNIT_ASSERT( is_movable(unordered_map<char, char>()) );
359 CPPUNIT_ASSERT( is_movable(unordered_multimap<char, char>()) );
360 # if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
361 CPPUNIT_ASSERT( is_movable(hash_set<char>()) );
362 CPPUNIT_ASSERT( is_movable(hash_multiset<char>()) );
363 CPPUNIT_ASSERT( is_movable(hash_map<char, char>()) );
364 CPPUNIT_ASSERT( is_movable(hash_multimap<char, char>()) );
365 # endif
366 }
367 #endif
368 }
369
370