mvctor_declaration_test.cpp revision e46c9386c4f79aa40185f79a19fc5b2a7ef528b3
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)
28using namespace std;
29#  if defined (STLPORT)
30using 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
43static bool type_to_bool(__true_type)
44{ return true; }
45static bool type_to_bool(__false_type)
46{ return false; }
47
48template <class _Tp>
49static bool is_movable(const _Tp&) {
50  typedef typename __move_traits<_Tp>::implemented _MovableTp;
51  return type_to_bool(_MovableTp());
52}
53
54template <class _Tp>
55static 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
61struct 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__)
69bool specially_allocated_struct::operator < (const specially_allocated_struct&) const
70{ return false; }
71#endif
72
73struct struct_with_specialized_less {};
74
75#  if defined (_STLP_USE_NAMESPACES)
76namespace 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
97    allocator() _STLP_NOTHROW {}
98#  if defined (_STLP_MEMBER_TEMPLATES)
99    template <class _Tp1> allocator(const allocator<_Tp1>&) _STLP_NOTHROW {}
100#  endif
101    allocator(const allocator&) _STLP_NOTHROW {}
102    ~allocator() _STLP_NOTHROW {}
103    pointer address(reference __x) const { return &__x; }
104    const_pointer address(const_reference __x) const { return &__x; }
105    pointer allocate(size_type, const void* = 0) { return 0; }
106    void deallocate(pointer, size_type) {}
107    size_type max_size() const _STLP_NOTHROW  { return 0; }
108    void construct(pointer, const_reference) {}
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
165void 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
286void 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
347void 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