1#include <algorithm>
2#include <vector>
3#include <string>
4
5#include "cppunit/cppunit_proxy.h"
6
7#if defined (_STLP_USE_NAMESPACES)
8using namespace std;
9#endif
10
11//
12// TestCase class
13//
14class TypeTraitsTest : public CPPUNIT_NS::TestCase
15{
16  CPPUNIT_TEST_SUITE(TypeTraitsTest);
17#if !defined (STLPORT)
18  CPPUNIT_IGNORE;
19#endif
20  CPPUNIT_TEST(manips);
21  CPPUNIT_TEST(integer);
22  CPPUNIT_TEST(rational);
23  CPPUNIT_TEST(pointer_type);
24#if defined (STLPORT) && !defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
25  CPPUNIT_IGNORE;
26#endif
27  CPPUNIT_TEST(reference_type);
28#if defined (STLPORT)
29  CPPUNIT_STOP_IGNORE;
30#endif
31  CPPUNIT_TEST(both_pointer_type);
32  CPPUNIT_TEST(ok_to_use_memcpy);
33  CPPUNIT_TEST(ok_to_use_memmove);
34  CPPUNIT_TEST(trivial_destructor);
35  CPPUNIT_TEST(is_POD);
36  CPPUNIT_TEST(stlport_class);
37  CPPUNIT_TEST_SUITE_END();
38
39protected:
40  void manips();
41  void integer();
42  void rational();
43  void pointer_type();
44  void reference_type();
45  void both_pointer_type();
46  void ok_to_use_memcpy();
47  void ok_to_use_memmove();
48  void trivial_destructor();
49  void is_POD();
50  void stlport_class();
51};
52
53CPPUNIT_TEST_SUITE_REGISTRATION(TypeTraitsTest);
54
55#if defined (STLPORT)
56
57#  if defined (__GNUC__) && defined (_STLP_USE_NAMESPACES)
58// libstdc++ sometimes exposed its own __true_type type in global
59// namespace resulting in an ambiguity.
60#    define __true_type std::__true_type
61#    define __false_type std::__false_type
62#  endif
63
64int type_to_value(__true_type)
65{ return 1; }
66int type_to_value(__false_type)
67{ return 0; }
68
69int* int_pointer;
70int const* int_const_pointer;
71int volatile* int_volatile_pointer;
72int const volatile* int_const_volatile_pointer;
73int int_val = 0;
74int const int_const_val = 0;
75int volatile int_volatile_val = 0;
76int & int_ref = int_val;
77int const& int_const_ref = int_val;
78int const volatile& int_const_volatile_ref = int_val;
79
80//A type that represent any type:
81struct any_type
82{
83  //Dummy operations to forbid to compilers with intrinsic
84  //type traits support to consider this type as a POD.
85  any_type() : m_data(1) {}
86  any_type(const any_type&) : m_data(2) {}
87  any_type& operator = (const any_type&)
88  { m_data = 3; return *this; }
89  ~any_type() { m_data = 0; }
90
91  size_t m_data;
92};
93
94any_type any;
95any_type* any_pointer;
96any_type const* any_const_pointer;
97any_type volatile* any_volatile_pointer;
98any_type const volatile* any_const_volatile_pointer;
99
100//A type that represent any pod type
101struct any_pod_type
102{};
103
104#  if defined (_STLP_USE_BOOST_SUPPORT)
105//Mandatory for compilers without without partial template specialization.
106BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(any_pod_type)
107#  endif
108
109any_pod_type any_pod;
110any_pod_type* any_pod_pointer;
111any_pod_type const* any_pod_const_pointer;
112any_pod_type volatile* any_pod_volatile_pointer;
113any_pod_type const volatile* any_pod_const_volatile_pointer;
114
115#  if defined (_STLP_USE_NAMESPACES)
116namespace std {
117#  endif
118  _STLP_TEMPLATE_NULL
119  struct __type_traits<any_pod_type> {
120    typedef __true_type has_trivial_default_constructor;
121    typedef __true_type has_trivial_copy_constructor;
122    typedef __true_type has_trivial_assignment_operator;
123    typedef __true_type has_trivial_destructor;
124    typedef __true_type is_POD_type;
125  };
126#  if defined (_STLP_USE_NAMESPACES)
127}
128#  endif
129
130struct base
131{};
132struct derived : public base
133{};
134
135//
136// tests implementation
137//
138template <typename _Src, typename _Dst>
139int is_convertible(_Src, _Dst) {
140#  if !defined(__BORLANDC__)
141  typedef typename _IsConvertible<_Src, _Dst>::_Ret _Ret;
142#  else
143  enum { _Is = _IsConvertible<_Src, _Dst>::value };
144  typedef typename __bool2type<_Is>::_Ret _Ret;
145#  endif
146  return type_to_value(_Ret());
147}
148
149template <typename _Src, typename _Dst>
150int is_cv_convertible(_Src, _Dst) {
151#  if !defined(__BORLANDC__)
152  typedef typename _IsCVConvertible<_Src, _Dst>::_Ret _Ret;
153#  else
154  enum { _Is = _IsCVConvertible<_Src, _Dst>::value };
155  typedef typename __bool2type<_Is>::_Ret _Ret;
156#  endif
157  return type_to_value(_Ret());
158}
159#endif
160
161void TypeTraitsTest::manips()
162{
163#if defined (STLPORT)
164  {
165    typedef __bool2type<0>::_Ret _ZeroRet;
166    CPPUNIT_ASSERT( type_to_value(_ZeroRet()) == 0 );
167    typedef __bool2type<1>::_Ret _OneRet;
168    CPPUNIT_ASSERT( type_to_value(_OneRet()) == 1 );
169    typedef __bool2type<65456873>::_Ret _AnyRet;
170    CPPUNIT_ASSERT( type_to_value(_AnyRet()) == 1 );
171  }
172
173  {
174    CPPUNIT_ASSERT( __type2bool<__true_type>::_Ret == 1 );
175    CPPUNIT_ASSERT( __type2bool<__false_type>::_Ret == 0 );
176    CPPUNIT_ASSERT( __type2bool<any_type>::_Ret == 1 );
177  }
178
179  {
180    typedef _Not<__true_type>::_Ret _NotTrueRet;
181    CPPUNIT_ASSERT( type_to_value(_NotTrueRet()) == 0 );
182    typedef _Not<__false_type>::_Ret _NotFalseRet;
183    CPPUNIT_ASSERT( type_to_value(_NotFalseRet()) == 1 );
184  }
185
186  {
187    typedef _Land2<__true_type, __true_type>::_Ret _TrueTrueRet;
188    CPPUNIT_ASSERT( type_to_value(_TrueTrueRet()) == 1 );
189    typedef _Land2<__true_type, __false_type>::_Ret _TrueFalseRet;
190    CPPUNIT_ASSERT( type_to_value(_TrueFalseRet()) == 0 );
191    typedef _Land2<__false_type, __true_type>::_Ret _FalseTrueRet;
192    CPPUNIT_ASSERT( type_to_value(_FalseTrueRet()) == 0 );
193    typedef _Land2<__false_type, __false_type>::_Ret _FalseFalseRet;
194    CPPUNIT_ASSERT( type_to_value(_FalseFalseRet()) == 0 );
195  }
196
197  {
198    typedef _Land3<__true_type, __true_type, __true_type>::_Ret _TrueTrueTrueRet;
199    CPPUNIT_ASSERT( type_to_value(_TrueTrueTrueRet()) == 1 );
200    typedef _Land3<__true_type, __true_type, __false_type>::_Ret _TrueTrueFalseRet;
201    CPPUNIT_ASSERT( type_to_value(_TrueTrueFalseRet()) == 0 );
202    typedef _Land3<__true_type, __false_type, __true_type>::_Ret _TrueFalseTrueRet;
203    CPPUNIT_ASSERT( type_to_value(_TrueFalseTrueRet()) == 0 );
204    typedef _Land3<__true_type, __false_type, __false_type>::_Ret _TrueFalseFalseRet;
205    CPPUNIT_ASSERT( type_to_value(_TrueFalseFalseRet()) == 0 );
206    typedef _Land3<__false_type, __true_type, __true_type>::_Ret _FalseTrueTrueRet;
207    CPPUNIT_ASSERT( type_to_value(_FalseTrueTrueRet()) == 0 );
208    typedef _Land3<__false_type, __true_type, __false_type>::_Ret _FalseTrueFalseRet;
209    CPPUNIT_ASSERT( type_to_value(_FalseTrueFalseRet()) == 0 );
210    typedef _Land3<__false_type, __false_type, __true_type>::_Ret _FalseFalseTrueRet;
211    CPPUNIT_ASSERT( type_to_value(_FalseFalseTrueRet()) == 0 );
212    typedef _Land3<__false_type, __false_type, __false_type>::_Ret _FalseFalseFalseRet;
213    CPPUNIT_ASSERT( type_to_value(_FalseFalseFalseRet()) == 0 );
214  }
215
216  {
217    typedef _Lor2<__true_type, __true_type>::_Ret _TrueTrueRet;
218    CPPUNIT_ASSERT( type_to_value(_TrueTrueRet()) == 1 );
219    typedef _Lor2<__true_type, __false_type>::_Ret _TrueFalseRet;
220    CPPUNIT_ASSERT( type_to_value(_TrueFalseRet()) == 1 );
221    typedef _Lor2<__false_type, __true_type>::_Ret _FalseTrueRet;
222    CPPUNIT_ASSERT( type_to_value(_FalseTrueRet()) == 1 );
223    typedef _Lor2<__false_type, __false_type>::_Ret _FalseFalseRet;
224    CPPUNIT_ASSERT( type_to_value(_FalseFalseRet()) == 0 );
225  }
226
227  {
228    typedef _Lor3<__true_type, __true_type, __true_type>::_Ret _TrueTrueTrueRet;
229    CPPUNIT_ASSERT( type_to_value(_TrueTrueTrueRet()) == 1 );
230    typedef _Lor3<__true_type, __true_type, __false_type>::_Ret _TrueTrueFalseRet;
231    CPPUNIT_ASSERT( type_to_value(_TrueTrueFalseRet()) == 1 );
232    typedef _Lor3<__true_type, __false_type, __true_type>::_Ret _TrueFalseTrueRet;
233    CPPUNIT_ASSERT( type_to_value(_TrueFalseTrueRet()) == 1 );
234    typedef _Lor3<__true_type, __false_type, __false_type>::_Ret _TrueFalseFalseRet;
235    CPPUNIT_ASSERT( type_to_value(_TrueFalseFalseRet()) == 1 );
236    typedef _Lor3<__false_type, __true_type, __true_type>::_Ret _FalseTrueTrueRet;
237    CPPUNIT_ASSERT( type_to_value(_FalseTrueTrueRet()) == 1 );
238    typedef _Lor3<__false_type, __true_type, __false_type>::_Ret _FalseTrueFalseRet;
239    CPPUNIT_ASSERT( type_to_value(_FalseTrueFalseRet()) == 1 );
240    typedef _Lor3<__false_type, __false_type, __true_type>::_Ret _FalseFalseTrueRet;
241    CPPUNIT_ASSERT( type_to_value(_FalseFalseTrueRet()) == 1 );
242    typedef _Lor3<__false_type, __false_type, __false_type>::_Ret _FalseFalseFalseRet;
243    CPPUNIT_ASSERT( type_to_value(_FalseFalseFalseRet()) == 0 );
244  }
245
246  {
247    typedef __select<1, __true_type, __false_type>::_Ret _SelectFirstRet;
248    CPPUNIT_ASSERT( type_to_value(_SelectFirstRet()) == 1 );
249    typedef __select<0, __true_type, __false_type>::_Ret _SelectSecondRet;
250    CPPUNIT_ASSERT( type_to_value(_SelectSecondRet()) == 0 );
251#  if defined (__BORLANDC__)
252    typedef __selectT<__true_type, __true_type, __false_type>::_Ret _SelectFirstRet;
253    CPPUNIT_ASSERT( type_to_value(_SelectFirstRet()) == 1 );
254    typedef __selectT<__false_type, __true_type, __false_type>::_Ret _SelectSecondRet;
255    CPPUNIT_ASSERT( type_to_value(_SelectSecondRet()) == 0 );
256#  endif
257  }
258
259  {
260    base b;
261    derived d;
262    const derived cd = d;
263    base *pb = &b;
264    derived *pd = &d;
265    derived const *pcd = pd;
266    CPPUNIT_CHECK( is_convertible(any, b) == 0 );
267    CPPUNIT_CHECK( is_convertible(d, b) == 1 );
268    CPPUNIT_CHECK( is_convertible(cd, b) == 1 );
269    // _IsCVConvertible only needs to work for pointer type:
270    //CPPUNIT_CHECK( is_cv_convertible(d, b) == 1 );
271    //CPPUNIT_CHECK( is_cv_convertible(cd, b) == 0 );
272
273    //_IsConvertible do not need to work for pointers:
274    //CPPUNIT_CHECK( is_convertible(pd, pb) == 1 );
275    //CPPUNIT_CHECK( is_convertible(pcd, pb) == 1 );
276
277    CPPUNIT_CHECK( is_cv_convertible(pd, pb) == 1 );
278    CPPUNIT_CHECK( is_cv_convertible(pcd, pb) == 0 );
279  }
280#endif
281}
282
283#if defined (STLPORT)
284template <typename _Type>
285int is_integer(_Type) {
286  typedef typename _IsIntegral<_Type>::_Ret _Ret;
287  return type_to_value(_Ret());
288}
289#endif
290
291void TypeTraitsTest::integer()
292{
293#if defined (STLPORT)
294  CPPUNIT_ASSERT( is_integer(bool()) == 1 );
295  CPPUNIT_ASSERT( is_integer(char()) == 1 );
296  typedef signed char signed_char;
297  CPPUNIT_ASSERT( is_integer(signed_char()) == 1 );
298  typedef unsigned char unsigned_char;
299  CPPUNIT_ASSERT( is_integer(unsigned_char()) == 1 );
300#  if defined (_STLP_HAS_WCHAR_T)
301  CPPUNIT_ASSERT( is_integer(wchar_t()) == 1 );
302#  endif
303  CPPUNIT_ASSERT( is_integer(short()) == 1 );
304  typedef unsigned short unsigned_short;
305  CPPUNIT_ASSERT( is_integer(unsigned_short()) == 1 );
306  CPPUNIT_ASSERT( is_integer(int()) == 1 );
307  typedef unsigned int unsigned_int;
308  CPPUNIT_ASSERT( is_integer(unsigned_int()) == 1 );
309  CPPUNIT_ASSERT( is_integer(long()) == 1 );
310  typedef unsigned long unsigned_long;
311  CPPUNIT_ASSERT( is_integer(unsigned_long()) == 1 );
312#  if defined (_STLP_LONG_LONG)
313  typedef _STLP_LONG_LONG long_long;
314  CPPUNIT_ASSERT( is_integer(long_long()) == 1 );
315  typedef unsigned _STLP_LONG_LONG unsigned_long_long;
316  CPPUNIT_ASSERT( is_integer(unsigned_long_long()) == 1 );
317#  endif
318  CPPUNIT_ASSERT( is_integer(float()) == 0 );
319  CPPUNIT_ASSERT( is_integer(double()) == 0 );
320#  if !defined ( _STLP_NO_LONG_DOUBLE )
321  typedef long double long_double;
322  CPPUNIT_ASSERT( is_integer(long_double()) == 0 );
323#  endif
324  CPPUNIT_ASSERT( is_integer(any) == 0 );
325  CPPUNIT_ASSERT( is_integer(any_pointer) == 0 );
326#endif
327}
328
329#if defined (STLPORT)
330template <typename _Type>
331int is_rational(_Type) {
332  typedef typename _IsRational<_Type>::_Ret _Ret;
333  return type_to_value(_Ret());
334}
335#endif
336
337void TypeTraitsTest::rational()
338{
339#if defined (STLPORT)
340  CPPUNIT_ASSERT( is_rational(bool()) == 0 );
341  CPPUNIT_ASSERT( is_rational(char()) == 0 );
342  typedef signed char signed_char;
343  CPPUNIT_ASSERT( is_rational(signed_char()) == 0 );
344  typedef unsigned char unsigned_char;
345  CPPUNIT_ASSERT( is_rational(unsigned_char()) == 0 );
346#  if defined (_STLP_HAS_WCHAR_T)
347  CPPUNIT_ASSERT( is_rational(wchar_t()) == 0 );
348#  endif
349  CPPUNIT_ASSERT( is_rational(short()) == 0 );
350  typedef unsigned short unsigned_short;
351  CPPUNIT_ASSERT( is_rational(unsigned_short()) == 0 );
352  CPPUNIT_ASSERT( is_rational(int()) == 0 );
353  typedef unsigned int unsigned_int;
354  CPPUNIT_ASSERT( is_rational(unsigned_int()) == 0 );
355  CPPUNIT_ASSERT( is_rational(long()) == 0 );
356  typedef unsigned long unsigned_long;
357  CPPUNIT_ASSERT( is_rational(unsigned_long()) == 0 );
358#  if defined (_STLP_LONG_LONG)
359  typedef _STLP_LONG_LONG long_long;
360  CPPUNIT_ASSERT( is_rational(long_long()) == 0 );
361  typedef unsigned _STLP_LONG_LONG unsigned_long_long;
362  CPPUNIT_ASSERT( is_rational(unsigned_long_long()) == 0 );
363#  endif
364  CPPUNIT_ASSERT( is_rational(float()) == 1 );
365  CPPUNIT_ASSERT( is_rational(double()) == 1 );
366#  if !defined ( _STLP_NO_LONG_DOUBLE )
367  typedef long double long_double;
368  CPPUNIT_ASSERT( is_rational(long_double()) == 1 );
369#  endif
370  CPPUNIT_ASSERT( is_rational(any) == 0 );
371  CPPUNIT_ASSERT( is_rational(any_pointer) == 0 );
372#endif
373}
374
375#if defined (STLPORT)
376template <typename _Type>
377int is_pointer_type(_Type) {
378  return type_to_value(_IsPtrType<_Type>::_Ret());
379}
380#endif
381
382void TypeTraitsTest::pointer_type()
383{
384#if defined (STLPORT)
385  CPPUNIT_ASSERT( is_pointer_type(int_val) == 0 );
386  CPPUNIT_ASSERT( is_pointer_type(int_pointer) == 1 );
387  CPPUNIT_ASSERT( is_pointer_type(int_const_pointer) == 1 );
388  CPPUNIT_ASSERT( is_pointer_type(int_volatile_pointer) == 1 );
389  CPPUNIT_ASSERT( is_pointer_type(int_const_volatile_pointer) == 1 );
390  CPPUNIT_ASSERT( is_pointer_type(int_ref) == 0 );
391  CPPUNIT_ASSERT( is_pointer_type(int_const_ref) == 0 );
392  CPPUNIT_ASSERT( is_pointer_type(any) == 0 );
393  CPPUNIT_ASSERT( is_pointer_type(any_pointer) == 1 );
394#endif
395}
396
397void TypeTraitsTest::reference_type()
398{
399#if defined (STLPORT) && defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
400  CPPUNIT_ASSERT( type_to_value(_IsRefType<int>::_Ret()) == 0 );
401  CPPUNIT_ASSERT( type_to_value(_IsRefType<int*>::_Ret()) == 0 );
402  CPPUNIT_ASSERT( type_to_value(_IsRefType<int&>::_Ret()) == 1 );
403  CPPUNIT_ASSERT( type_to_value(_IsRefType<int const&>::_Ret()) == 1 );
404  CPPUNIT_ASSERT( type_to_value(_IsRefType<int const volatile&>::_Ret()) == 1 );
405
406  CPPUNIT_ASSERT( type_to_value(_IsOKToSwap(int_pointer, int_pointer, __true_type(), __true_type())._Answer()) == 1 );
407  CPPUNIT_ASSERT( type_to_value(_IsOKToSwap(int_pointer, int_pointer, __false_type(), __false_type())._Answer()) == 0 );
408#endif
409}
410
411#if defined (STLPORT)
412template <typename _Tp1, typename _Tp2>
413int are_both_pointer_type (_Tp1, _Tp2) {
414  return type_to_value(_BothPtrType<_Tp1, _Tp2>::_Answer());
415}
416#endif
417
418void TypeTraitsTest::both_pointer_type()
419{
420#if defined (STLPORT)
421  CPPUNIT_CHECK( are_both_pointer_type(int_val, int_val) == 0 );
422  CPPUNIT_CHECK( are_both_pointer_type(int_pointer, int_pointer) == 1 );
423  CPPUNIT_CHECK( are_both_pointer_type(int_const_pointer, int_const_pointer) == 1 );
424  CPPUNIT_CHECK( are_both_pointer_type(int_volatile_pointer, int_volatile_pointer) == 1 );
425  CPPUNIT_CHECK( are_both_pointer_type(int_const_volatile_pointer, int_const_volatile_pointer) == 1 );
426  CPPUNIT_CHECK( are_both_pointer_type(int_ref, int_ref) == 0 );
427  CPPUNIT_CHECK( are_both_pointer_type(int_const_ref, int_const_ref) == 0 );
428  CPPUNIT_CHECK( are_both_pointer_type(any, any) == 0 );
429  CPPUNIT_CHECK( are_both_pointer_type(any_pointer, any_pointer) == 1 );
430#endif
431}
432
433#if defined (STLPORT)
434template <typename _Tp1, typename _Tp2>
435int is_ok_to_use_memcpy(_Tp1 val1, _Tp2 val2) {
436  return type_to_value(_UseTrivialCopy(val1, val2)._Answer());
437}
438#endif
439
440void TypeTraitsTest::ok_to_use_memcpy()
441{
442#if defined (STLPORT) && !defined (_STLP_DONT_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS)
443  CPPUNIT_CHECK( is_ok_to_use_memcpy(int_pointer, int_pointer) == 1 );
444  CPPUNIT_CHECK( is_ok_to_use_memcpy(int_const_pointer, int_pointer) == 1 );
445  CPPUNIT_CHECK( is_ok_to_use_memcpy(int_pointer, int_volatile_pointer) == 0 );
446  CPPUNIT_CHECK( is_ok_to_use_memcpy(int_pointer, int_const_volatile_pointer) == 0 );
447  CPPUNIT_CHECK( is_ok_to_use_memcpy(int_const_pointer, int_const_pointer) == 0 );
448  CPPUNIT_CHECK( is_ok_to_use_memcpy(int_const_pointer, int_volatile_pointer) == 0 );
449  CPPUNIT_CHECK( is_ok_to_use_memcpy(int_const_pointer, int_const_volatile_pointer) == 0 );
450  CPPUNIT_CHECK( is_ok_to_use_memcpy(int_const_volatile_pointer, int_const_volatile_pointer) == 0 );
451  CPPUNIT_CHECK( is_ok_to_use_memcpy(int_pointer, any_pointer) == 0 );
452  CPPUNIT_CHECK( is_ok_to_use_memcpy(any_pointer, int_pointer) == 0 );
453  CPPUNIT_CHECK( is_ok_to_use_memcpy(any_pointer, any_pointer) == 0 );
454  CPPUNIT_CHECK( is_ok_to_use_memcpy(any_pointer, any_const_pointer) == 0 );
455  CPPUNIT_CHECK( is_ok_to_use_memcpy(any_pod_pointer, int_pointer) == 0 );
456  CPPUNIT_CHECK( is_ok_to_use_memcpy(any_pod_pointer, any_pod_pointer) == 1 );
457  CPPUNIT_CHECK( is_ok_to_use_memcpy(any_pod_pointer, any_pod_const_pointer) == 0 );
458  vector<float> **pvf = 0;
459  vector<int> **pvi = 0;
460  CPPUNIT_CHECK( is_ok_to_use_memcpy(pvf, pvi) == 0 );
461  CPPUNIT_CHECK( is_ok_to_use_memcpy(pvi, pvf) == 0 );
462#endif
463}
464
465#if defined (STLPORT)
466template <typename _Tp1, typename _Tp2>
467int is_ok_to_use_memmove(_Tp1 val1, _Tp2 val2) {
468  return type_to_value(_UseTrivialUCopy(val1, val2)._Answer());
469}
470#endif
471
472void TypeTraitsTest::ok_to_use_memmove()
473{
474#if defined (STLPORT) && !defined (_STLP_DONT_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS)
475  CPPUNIT_CHECK( is_ok_to_use_memmove(int_pointer, int_pointer) == 1 );
476  CPPUNIT_CHECK( is_ok_to_use_memmove(int_const_pointer, int_pointer) == 1 );
477  CPPUNIT_CHECK( is_ok_to_use_memmove(int_pointer, int_volatile_pointer) == 0 );
478  CPPUNIT_CHECK( is_ok_to_use_memmove(int_pointer, int_const_volatile_pointer) == 0 );
479  CPPUNIT_CHECK( is_ok_to_use_memmove(int_const_pointer, int_const_pointer) == 0 );
480  CPPUNIT_CHECK( is_ok_to_use_memmove(int_const_pointer, int_volatile_pointer) == 0 );
481  CPPUNIT_CHECK( is_ok_to_use_memmove(int_const_pointer, int_const_volatile_pointer) == 0 );
482  CPPUNIT_CHECK( is_ok_to_use_memmove(int_const_volatile_pointer, int_const_volatile_pointer) == 0 );
483  CPPUNIT_CHECK( is_ok_to_use_memmove(int_pointer, any_pointer) == 0 );
484  CPPUNIT_CHECK( is_ok_to_use_memmove(any_pointer, int_pointer) == 0 );
485  CPPUNIT_CHECK( is_ok_to_use_memmove(any_pointer, any_pointer) == 0 );
486  CPPUNIT_CHECK( is_ok_to_use_memmove(any_pointer, any_const_pointer) == 0 );
487  CPPUNIT_CHECK( is_ok_to_use_memmove(any_pod_pointer, int_pointer) == 0 );
488  CPPUNIT_CHECK( is_ok_to_use_memmove(any_pod_pointer, any_pod_pointer) == 1 );
489  CPPUNIT_CHECK( is_ok_to_use_memmove(any_pod_pointer, any_pod_const_pointer) == 0 );
490#endif
491}
492
493#if defined (STLPORT)
494template <typename _Tp>
495int has_trivial_destructor(_Tp) {
496  typedef typename __type_traits<_Tp>::has_trivial_destructor _TrivialDestructor;
497  return type_to_value(_TrivialDestructor());
498}
499
500struct DestructorMonitor
501{
502  ~DestructorMonitor()
503  { ++nb_destructor_call; }
504
505  static size_t nb_destructor_call;
506};
507
508size_t DestructorMonitor::nb_destructor_call = 0;
509
510#  if defined (_STLP_USE_NAMESPACES)
511namespace std {
512#  endif
513  _STLP_TEMPLATE_NULL
514  struct __type_traits<DestructorMonitor> {
515    typedef __true_type has_trivial_default_constructor;
516    typedef __true_type has_trivial_copy_constructor;
517    typedef __true_type has_trivial_assignment_operator;
518    typedef __true_type has_trivial_destructor;
519    typedef __true_type is_POD_type;
520  };
521#  if defined (_STLP_USE_NAMESPACES)
522}
523#  endif
524#endif
525
526void TypeTraitsTest::trivial_destructor()
527{
528#if defined (STLPORT)
529  CPPUNIT_CHECK( has_trivial_destructor(int_pointer) == 1 );
530  CPPUNIT_CHECK( has_trivial_destructor(int_const_pointer) == 1 );
531  CPPUNIT_CHECK( has_trivial_destructor(int_volatile_pointer) == 1 );
532  CPPUNIT_CHECK( has_trivial_destructor(int_const_volatile_pointer) == 1 );
533  CPPUNIT_CHECK( has_trivial_destructor(any_pointer) == 1 );
534  CPPUNIT_CHECK( has_trivial_destructor(any) == 0 );
535  CPPUNIT_CHECK( has_trivial_destructor(any_pointer) == 1 );
536  CPPUNIT_CHECK( has_trivial_destructor(any_pod) == 1 );
537  CPPUNIT_CHECK( has_trivial_destructor(string()) == 0 );
538
539  //Check of the meta information impact in a container implementation
540  {
541    vector<DestructorMonitor> v(10);
542    DestructorMonitor::nb_destructor_call = 0;
543  }
544  CPPUNIT_CHECK( DestructorMonitor::nb_destructor_call == 0 );
545#endif
546}
547
548#if defined (STLPORT)
549template <typename _Tp>
550int is_POD_type(_Tp) {
551  typedef typename __type_traits<_Tp>::is_POD_type _IsPODType;
552  return type_to_value(_IsPODType());
553}
554#endif
555
556void TypeTraitsTest::is_POD()
557{
558#if defined (STLPORT)
559  CPPUNIT_CHECK( is_POD_type(int_pointer) == 1 );
560  CPPUNIT_CHECK( is_POD_type(int_const_pointer) == 1 );
561  CPPUNIT_CHECK( is_POD_type(int_volatile_pointer) == 1 );
562  CPPUNIT_CHECK( is_POD_type(int_const_volatile_pointer) == 1 );
563  CPPUNIT_CHECK( is_POD_type(any_pointer) == 1 );
564  CPPUNIT_CHECK( is_POD_type(any) == 0 );
565  CPPUNIT_CHECK( is_POD_type(any_pointer) == 1 );
566  CPPUNIT_CHECK( is_POD_type(any_pod) == 1 );
567  CPPUNIT_CHECK( is_POD_type(string()) == 0 );
568#endif
569}
570
571#if defined (STLPORT)
572template <typename _Tp>
573int is_stlport_class(_Tp) {
574  typedef _IsSTLportClass<_Tp> _STLportClass;
575#    if !defined (__BORLANDC__)
576  typedef typename _STLportClass::_Ret _Is;
577#    else
578  typedef typename __bool2type<_STLportClass::_Is>::_Ret _Is;
579#    endif
580  return type_to_value(_Is());
581}
582#endif
583
584void TypeTraitsTest::stlport_class()
585{
586#if defined (STLPORT)
587  CPPUNIT_CHECK( is_stlport_class(allocator<char>()) == 1 );
588#  if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND)
589  CPPUNIT_CHECK( is_stlport_class(string()) == 1 );
590#  endif
591  CPPUNIT_CHECK( is_stlport_class(any) == 0 );
592#endif
593}
594