1/*
2 *
3 * Copyright (c) 1996,1997
4 * Silicon Graphics Computer Systems, Inc.
5 *
6 * Copyright (c) 1997
7 * Moscow Center for SPARC Technology
8 *
9 * Copyright (c) 1999
10 * Boris Fomitchev
11 *
12 * This material is provided "as is", with absolutely no warranty expressed
13 * or implied. Any use is at your own risk.
14 *
15 * Permission to use or copy this software for any purpose is hereby granted
16 * without fee, provided the above notices are retained on all copies.
17 * Permission to modify the code and to distribute modified code is granted,
18 * provided the above notices are retained, and a notice that the code was
19 * modified is included with the above copyright notice.
20 *
21 */
22
23#ifndef _STLP_TYPE_TRAITS_H
24#define _STLP_TYPE_TRAITS_H
25
26/*
27This header file provides a framework for allowing compile time dispatch
28based on type attributes. This is useful when writing template code.
29For example, when making a copy of an array of an unknown type, it helps
30to know if the type has a trivial copy constructor or not, to help decide
31if a memcpy can be used.
32
33The class template __type_traits provides a series of typedefs each of
34which is either __true_type or __false_type. The argument to
35__type_traits can be any type. The typedefs within this template will
36attain their correct values by one of these means:
37    1. The general instantiation contain conservative values which work
38       for all types.
39    2. Specializations may be declared to make distinctions between types.
40    3. Some compilers (such as the Silicon Graphics N32 and N64 compilers)
41       will automatically provide the appropriate specializations for all
42       types.
43
44EXAMPLE:
45
46//Copy an array of elements which have non-trivial copy constructors
47template <class T> void copy(T* source, T* destination, int n, __false_type);
48//Copy an array of elements which have trivial copy constructors. Use memcpy.
49template <class T> void copy(T* source, T* destination, int n, __true_type);
50
51//Copy an array of any type by using the most efficient copy mechanism
52template <class T> inline void copy(T* source,T* destination,int n) {
53   copy(source, destination, n,
54        typename __type_traits<T>::has_trivial_copy_constructor());
55}
56*/
57
58#ifdef __WATCOMC__
59#  include <stl/_cwchar.h>
60#endif
61
62#ifndef _STLP_TYPE_MANIPS_H
63#  include <stl/type_manips.h>
64#endif
65
66#ifdef _STLP_USE_BOOST_SUPPORT
67#  include <stl/boost_type_traits.h>
68#  include <boost/type_traits/add_reference.hpp>
69#  include <boost/type_traits/add_const.hpp>
70#endif /* _STLP_USE_BOOST_SUPPORT */
71
72_STLP_BEGIN_NAMESPACE
73
74#if !defined (_STLP_USE_BOOST_SUPPORT)
75
76// The following could be written in terms of numeric_limits.
77// We're doing it separately to reduce the number of dependencies.
78
79template <class _Tp> struct _IsIntegral
80{ typedef __false_type _Ret; };
81
82#  ifndef _STLP_NO_BOOL
83_STLP_TEMPLATE_NULL struct _IsIntegral<bool>
84{ typedef __true_type _Ret; };
85#  endif /* _STLP_NO_BOOL */
86
87_STLP_TEMPLATE_NULL struct _IsIntegral<char>
88{ typedef __true_type _Ret; };
89
90#  ifndef _STLP_NO_SIGNED_BUILTINS
91_STLP_TEMPLATE_NULL struct _IsIntegral<signed char>
92{ typedef __true_type _Ret; };
93#  endif
94
95_STLP_TEMPLATE_NULL struct _IsIntegral<unsigned char>
96{ typedef __true_type _Ret; };
97
98#  if defined ( _STLP_HAS_WCHAR_T ) && ! defined (_STLP_WCHAR_T_IS_USHORT)
99_STLP_TEMPLATE_NULL struct _IsIntegral<wchar_t>
100{ typedef __true_type _Ret; };
101#  endif /* _STLP_HAS_WCHAR_T */
102
103_STLP_TEMPLATE_NULL struct _IsIntegral<short>
104{ typedef __true_type _Ret; };
105
106_STLP_TEMPLATE_NULL struct _IsIntegral<unsigned short>
107{ typedef __true_type _Ret; };
108
109_STLP_TEMPLATE_NULL struct _IsIntegral<int>
110{ typedef __true_type _Ret; };
111
112_STLP_TEMPLATE_NULL struct _IsIntegral<unsigned int>
113{ typedef __true_type _Ret; };
114
115_STLP_TEMPLATE_NULL struct _IsIntegral<long>
116{ typedef __true_type _Ret; };
117
118_STLP_TEMPLATE_NULL struct _IsIntegral<unsigned long>
119{ typedef __true_type _Ret; };
120
121#  ifdef _STLP_LONG_LONG
122_STLP_TEMPLATE_NULL struct _IsIntegral<_STLP_LONG_LONG>
123{ typedef __true_type _Ret; };
124
125_STLP_TEMPLATE_NULL struct _IsIntegral<unsigned _STLP_LONG_LONG>
126{ typedef __true_type _Ret; };
127#  endif /* _STLP_LONG_LONG */
128
129template <class _Tp> struct _IsRational
130{ typedef __false_type _Ret; };
131
132_STLP_TEMPLATE_NULL struct _IsRational<float>
133{ typedef __true_type _Ret; };
134
135_STLP_TEMPLATE_NULL struct _IsRational<double>
136{ typedef __true_type _Ret; };
137
138#  if !defined ( _STLP_NO_LONG_DOUBLE )
139_STLP_TEMPLATE_NULL struct _IsRational<long double>
140{ typedef __true_type _Ret; };
141#  endif
142
143// Forward declarations.
144template <class _Tp> struct __type_traits;
145template <class _IsPOD> struct __type_traits_aux {
146   typedef __false_type    has_trivial_default_constructor;
147   typedef __false_type    has_trivial_copy_constructor;
148   typedef __false_type    has_trivial_assignment_operator;
149   typedef __false_type    has_trivial_destructor;
150   typedef __false_type    is_POD_type;
151};
152
153_STLP_TEMPLATE_NULL
154struct __type_traits_aux<__false_type> {
155   typedef __false_type    has_trivial_default_constructor;
156   typedef __false_type    has_trivial_copy_constructor;
157   typedef __false_type    has_trivial_assignment_operator;
158   typedef __false_type    has_trivial_destructor;
159   typedef __false_type    is_POD_type;
160};
161
162_STLP_TEMPLATE_NULL
163struct __type_traits_aux<__true_type> {
164  typedef __true_type    has_trivial_default_constructor;
165  typedef __true_type    has_trivial_copy_constructor;
166  typedef __true_type    has_trivial_assignment_operator;
167  typedef __true_type    has_trivial_destructor;
168  typedef __true_type    is_POD_type;
169};
170
171template <class _Tp>
172struct _IsRef {
173  typedef __false_type _Ret;
174};
175
176#  if defined (_STLP_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS)
177/*
178 * Boris : simulation technique is used here according to Adobe Open Source License Version 1.0.
179 * Copyright 2000 Adobe Systems Incorporated and others. All rights reserved.
180 * Authors: Mat Marcus and Jesse Jones
181 * The original version of this source code may be found at
182 * http://opensource.adobe.com.
183 */
184
185struct _PointerShim {
186  /*
187   * Since the compiler only allows at most one non-trivial
188   * implicit conversion we can make use of a shim class to
189   * be sure that IsPtr below doesn't accept classes with
190   * implicit pointer conversion operators
191   */
192  _PointerShim(const volatile void*); // no implementation
193};
194
195// These are the discriminating functions
196char _STLP_CALL _IsP(bool, _PointerShim);  // no implementation is required
197char* _STLP_CALL _IsP(bool, ...);          // no implementation is required
198
199template <class _Tp>
200struct _IsPtr {
201  /*
202   * This template meta function takes a type T
203   * and returns true exactly when T is a pointer.
204   * One can imagine meta-functions discriminating on
205   * other criteria.
206   */
207  static _Tp& __null_rep();
208  enum { _Ptr = (sizeof(_IsP(false,__null_rep())) == sizeof(char)) };
209  typedef typename __bool2type<_Ptr>::_Ret _Ret;
210
211};
212
213// we make general case dependant on the fact the type is actually a pointer.
214template <class _Tp>
215struct __type_traits : __type_traits_aux<typename _IsPtr<_Tp>::_Ret> {};
216
217#  else /* _STLP_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS */
218
219template <class _Tp>  struct _IsPtr {
220  typedef __false_type _Ret;
221};
222
223template <class _Tp>
224struct __type_traits {
225   typedef __true_type     this_dummy_member_must_be_first;
226                   /* Do not remove this member. It informs a compiler which
227                      automatically specializes __type_traits that this
228                      __type_traits template is special. It just makes sure that
229                      things work if an implementation is using a template
230                      called __type_traits for something unrelated. */
231
232   /* The following restrictions should be observed for the sake of
233      compilers which automatically produce type specific specializations
234      of this class:
235          - You may reorder the members below if you wish
236          - You may remove any of the members below if you wish
237          - You must not rename members without making the corresponding
238            name change in the compiler
239          - Members you add will be treated like regular members unless
240
241            you add the appropriate support in the compiler. */
242#    if !defined (_STLP_HAS_TYPE_TRAITS_INTRINSICS)
243   typedef __false_type    has_trivial_default_constructor;
244   typedef __false_type    has_trivial_copy_constructor;
245   typedef __false_type    has_trivial_assignment_operator;
246   typedef __false_type    has_trivial_destructor;
247   typedef __false_type    is_POD_type;
248#    else
249   typedef typename __bool2type<_STLP_HAS_TRIVIAL_CONSTRUCTOR(_Tp)>::_Ret has_trivial_default_constructor;
250   typedef typename __bool2type<_STLP_HAS_TRIVIAL_COPY(_Tp)>::_Ret has_trivial_copy_constructor;
251   typedef typename __bool2type<_STLP_HAS_TRIVIAL_ASSIGN(_Tp)>::_Ret has_trivial_assignment_operator;
252   typedef typename __bool2type<_STLP_HAS_TRIVIAL_DESTRUCTOR(_Tp)>::_Ret has_trivial_destructor;
253   typedef typename __bool2type<_STLP_IS_POD(_Tp)>::_Ret is_POD_type;
254#    endif
255};
256
257#    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
258template <class _Tp> struct _IsPtr<_Tp*>
259{ typedef __true_type _Ret; };
260template <class _Tp> struct _IsRef<_Tp&>
261{ typedef __true_type _Ret; };
262
263template <class _Tp> struct __type_traits<_Tp*> : __type_traits_aux<__true_type>
264{};
265#    endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */
266
267#  endif /* _STLP_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS */
268
269// Provide some specializations.  This is harmless for compilers that
270//  have built-in __types_traits support, and essential for compilers
271//  that don't.
272#  if !defined (_STLP_QUALIFIED_SPECIALIZATION_BUG)
273#    define _STLP_DEFINE_TYPE_TRAITS_FOR(Type) \
274_STLP_TEMPLATE_NULL struct __type_traits< Type > : __type_traits_aux<__true_type> {}; \
275_STLP_TEMPLATE_NULL struct __type_traits< const Type > : __type_traits_aux<__true_type> {}; \
276_STLP_TEMPLATE_NULL struct __type_traits< volatile Type > : __type_traits_aux<__true_type> {}; \
277_STLP_TEMPLATE_NULL struct __type_traits< const volatile Type > : __type_traits_aux<__true_type> {}
278#  else
279#    define _STLP_DEFINE_TYPE_TRAITS_FOR(Type) \
280_STLP_TEMPLATE_NULL struct __type_traits< Type > : __type_traits_aux<__true_type> {};
281#  endif
282
283#  ifndef _STLP_NO_BOOL
284_STLP_DEFINE_TYPE_TRAITS_FOR(bool);
285#  endif /* _STLP_NO_BOOL */
286_STLP_DEFINE_TYPE_TRAITS_FOR(char);
287#  ifndef _STLP_NO_SIGNED_BUILTINS
288_STLP_DEFINE_TYPE_TRAITS_FOR(signed char);
289#  endif
290_STLP_DEFINE_TYPE_TRAITS_FOR(unsigned char);
291#  if defined ( _STLP_HAS_WCHAR_T ) && ! defined (_STLP_WCHAR_T_IS_USHORT)
292_STLP_DEFINE_TYPE_TRAITS_FOR(wchar_t);
293#  endif /* _STLP_HAS_WCHAR_T */
294
295_STLP_DEFINE_TYPE_TRAITS_FOR(short);
296_STLP_DEFINE_TYPE_TRAITS_FOR(unsigned short);
297_STLP_DEFINE_TYPE_TRAITS_FOR(int);
298_STLP_DEFINE_TYPE_TRAITS_FOR(unsigned int);
299_STLP_DEFINE_TYPE_TRAITS_FOR(long);
300_STLP_DEFINE_TYPE_TRAITS_FOR(unsigned long);
301
302#  ifdef _STLP_LONG_LONG
303_STLP_DEFINE_TYPE_TRAITS_FOR(_STLP_LONG_LONG);
304_STLP_DEFINE_TYPE_TRAITS_FOR(unsigned _STLP_LONG_LONG);
305#  endif /* _STLP_LONG_LONG */
306
307_STLP_DEFINE_TYPE_TRAITS_FOR(float);
308_STLP_DEFINE_TYPE_TRAITS_FOR(double);
309
310#  if !defined ( _STLP_NO_LONG_DOUBLE )
311_STLP_DEFINE_TYPE_TRAITS_FOR(long double);
312#  endif
313
314#  if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
315template <class _ArePtrs, class _Src, class _Dst>
316struct _IsCVConvertibleIf
317{ typedef typename _IsCVConvertible<_Src, _Dst>::_Ret _Ret; };
318
319template <class _Src, class _Dst>
320struct _IsCVConvertibleIf<__false_type, _Src, _Dst>
321{ typedef __false_type _Ret; };
322#  else
323#    if defined (_STLP_MEMBER_TEMPLATE_CLASSES)
324template <class _ArePtrs>
325struct _IsCVConvertibleIfAux {
326  template <class _Src, class _Dst>
327  struct _In
328  { typedef typename _IsCVConvertible<_Src, _Dst>::_Ret _Ret; };
329};
330
331_STLP_TEMPLATE_NULL
332struct _IsCVConvertibleIfAux<__false_type> {
333  template <class _Src, class _Dst>
334  struct _In
335  { typedef __false_type _Ret; };
336};
337
338template <class _ArePtrs, class _Src, class _Dst>
339struct _IsCVConvertibleIf {
340  typedef typename _IsCVConvertibleIfAux<_ArePtrs>::_STLP_TEMPLATE _In<_Src, _Dst>::_Ret _Ret;
341};
342#    else
343/* default behavior: we prefer to miss an optimization rather than taking the risk of
344 * a compilation error if playing with types with exotic memory alignment.
345 */
346template <class _ArePtrs, class _Src, class _Dst>
347struct _IsCVConvertibleIf
348{ typedef __false_type _Ret; };
349#    endif
350#  endif
351
352template <class _Src, class _Dst>
353struct _TrivialNativeTypeCopy {
354  typedef typename _IsPtr<_Src>::_Ret _Ptr1;
355  typedef typename _IsPtr<_Dst>::_Ret _Ptr2;
356  typedef typename _Land2<_Ptr1, _Ptr2>::_Ret _BothPtrs;
357  typedef typename _IsCVConvertibleIf<_BothPtrs, _Src, _Dst>::_Ret _Convertible;
358  typedef typename _Land2<_BothPtrs, _Convertible>::_Ret _Trivial1;
359
360  typedef typename __bool2type<(sizeof(_Src) == sizeof(_Dst))>::_Ret _SameSize;
361
362#if !defined (__BORLANDC__) || (__BORLANDC__ < 0x564)
363  typedef typename _IsIntegral<_Src>::_Ret _Int1;
364#else
365  typedef typename _UnQual<_Src>::_Type _UnQuSrc;
366  typedef typename _IsIntegral<_UnQuSrc>::_Ret _Int1;
367#endif
368  typedef typename _IsIntegral<_Dst>::_Ret _Int2;
369  typedef typename _Land2<_Int1, _Int2>::_Ret _BothInts;
370
371  typedef typename _IsRational<_Src>::_Ret _Rat1;
372  typedef typename _IsRational<_Dst>::_Ret _Rat2;
373  typedef typename _Land2<_Rat1, _Rat2>::_Ret _BothRats;
374
375  typedef typename _Lor2<_BothInts, _BothRats>::_Ret _BothNatives;
376#if !defined (__BORLANDC__) || (__BORLANDC__ >= 0x564)
377  typedef typename _Land2<_BothNatives, _SameSize>::_Ret _Trivial2;
378#else
379  typedef typename _IsUnQual<_Dst>::_Ret _UnQualDst;
380  typedef typename _Land3<_BothNatives, _SameSize, _UnQualDst>::_Ret _Trivial2;
381#endif
382  typedef typename _Lor2<_Trivial1, _Trivial2>::_Ret _Ret;
383};
384
385template <class _Src, class _Dst>
386struct _TrivialCopy {
387  typedef typename _TrivialNativeTypeCopy<_Src, _Dst>::_Ret _NativeRet;
388#  if !defined (__BORLANDC__) || (__BORLANDC__ != 0x560)
389  typedef typename __type_traits<_Src>::has_trivial_assignment_operator _Tr1;
390#  else
391  typedef typename _UnConstPtr<_Src*>::_Type _UnConstSrc;
392  typedef typename __type_traits<_UnConstSrc>::has_trivial_assignment_operator _Tr1;
393#  endif
394  typedef typename _AreCopyable<_Src, _Dst>::_Ret _Tr2;
395  typedef typename _Land2<_Tr1, _Tr2>::_Ret _UserRet;
396  typedef typename _Lor2<_NativeRet, _UserRet>::_Ret _Ret;
397  static _Ret _Answer() { return _Ret(); }
398};
399
400template <class _Src, class _Dst>
401struct _TrivialUCopy {
402  typedef typename _TrivialNativeTypeCopy<_Src, _Dst>::_Ret _NativeRet;
403#  if !defined (__BORLANDC__) || (__BORLANDC__ != 0x560)
404  typedef typename __type_traits<_Src>::has_trivial_copy_constructor _Tr1;
405#  else
406  typedef typename _UnConstPtr<_Src*>::_Type _UnConstSrc;
407  typedef typename __type_traits<_UnConstSrc>::has_trivial_copy_constructor _Tr1;
408#  endif
409  typedef typename _AreCopyable<_Src, _Dst>::_Ret _Tr2;
410  typedef typename _Land2<_Tr1, _Tr2>::_Ret _UserRet;
411  typedef typename _Lor2<_NativeRet, _UserRet>::_Ret _Ret;
412  static _Ret _Answer() { return _Ret(); }
413};
414
415template <class _Tp>
416struct _DefaultZeroValue {
417  typedef typename _IsIntegral<_Tp>::_Ret _Tr1;
418  typedef typename _IsRational<_Tp>::_Ret _Tr2;
419  typedef typename _IsPtr<_Tp>::_Ret _Tr3;
420  typedef typename _Lor3<_Tr1, _Tr2, _Tr3>::_Ret _Ret;
421};
422
423template <class _Tp>
424struct _TrivialInit {
425#  if !defined (__BORLANDC__) || (__BORLANDC__ != 0x560)
426  typedef typename __type_traits<_Tp>::has_trivial_default_constructor _Tr1;
427#  else
428  typedef typename _UnConstPtr<_Tp*>::_Type _Tp1;
429  typedef typename __type_traits<_Tp1>::has_trivial_copy_constructor _Tr1;
430#  endif
431  typedef typename _DefaultZeroValue<_Tp>::_Ret _Tr2;
432  typedef typename _Not<_Tr2>::_Ret _Tr3;
433  typedef typename _Land2<_Tr1, _Tr3>::_Ret _Ret;
434  static _Ret _Answer() { return _Ret(); }
435};
436
437#endif /* !_STLP_USE_BOOST_SUPPORT */
438
439template <class _Tp>
440struct _IsPtrType {
441  typedef typename _IsPtr<_Tp>::_Ret _Type;
442  static _Type _Ret() { return _Type(); }
443};
444
445template <class _Tp>
446struct _IsRefType {
447  typedef typename _IsRef<_Tp>::_Ret _Type;
448  static _Type _Ret() { return _Type();}
449};
450
451template <class _Tp>
452struct __call_traits {
453#if defined (_STLP_USE_BOOST_SUPPORT) && !defined (_STLP_NO_EXTENSIONS)
454  typedef typename __select< ::boost::is_reference<_Tp>::value,
455                             typename ::boost::add_const<_Tp>::type,
456                             typename ::boost::add_reference< typename ::boost::add_const<_Tp>::type >::type>::_Ret const_param_type;
457  typedef typename __select< ::boost::is_reference<_Tp>::value,
458                             typename ::boost::remove_const<_Tp>::type,
459                             typename ::boost::add_reference<_Tp>::type>::_Ret param_type;
460#else
461  typedef const _Tp& const_param_type;
462  typedef _Tp& param_type;
463#endif
464};
465
466#if !defined (_STLP_USE_BOOST_SUPPORT) && !defined (_STLP_NO_EXTENSIONS) && defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
467template <class _Tp>
468struct __call_traits<_Tp&> {
469  typedef _Tp& param_type;
470  typedef const _Tp& const_param_type;
471};
472template <class _Tp>
473struct __call_traits<const _Tp&> {
474  typedef _Tp& param_type;
475  typedef const _Tp& const_param_type;
476};
477#endif
478
479template <class _Tp1, class _Tp2>
480struct _BothPtrType {
481  typedef typename _IsPtr<_Tp1>::_Ret _IsPtr1;
482  typedef typename _IsPtr<_Tp2>::_Ret _IsPtr2;
483
484  typedef typename _Land2<_IsPtr1, _IsPtr2>::_Ret _Ret;
485  static _Ret _Answer() { return _Ret(); }
486};
487
488template <class _Tp1, class _Tp2, class _IsRef1, class _IsRef2>
489struct _OKToSwap {
490  typedef typename _AreSameTypes<_Tp1, _Tp2>::_Ret _Same;
491  typedef typename _Land3<_Same, _IsRef1, _IsRef2>::_Ret _Type;
492  static _Type _Answer() { return _Type(); }
493};
494
495template <class _Tp1, class _Tp2, class _IsRef1, class _IsRef2>
496inline _OKToSwap<_Tp1, _Tp2, _IsRef1, _IsRef2>
497_IsOKToSwap(_Tp1*, _Tp2*, const _IsRef1&, const _IsRef2&)
498{ return _OKToSwap<_Tp1, _Tp2, _IsRef1, _IsRef2>(); }
499
500template <class _Src, class _Dst>
501inline _TrivialCopy<_Src, _Dst> _UseTrivialCopy(_Src*, _Dst*)
502{ return _TrivialCopy<_Src, _Dst>(); }
503
504template <class _Src, class _Dst>
505inline _TrivialUCopy<_Src, _Dst> _UseTrivialUCopy(_Src*, _Dst*)
506{ return _TrivialUCopy<_Src, _Dst>(); }
507
508#if defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER) || defined (__BORLANDC__) || \
509    defined (__DMC__)
510struct _NegativeAnswer {
511  typedef __false_type _Ret;
512  static _Ret _Answer() { return _Ret(); }
513};
514
515template <class _Src, class _Dst>
516inline _NegativeAnswer _UseTrivialCopy(_Src*, const _Dst*)
517{ return _NegativeAnswer(); }
518
519template <class _Src, class _Dst>
520inline _NegativeAnswer _UseTrivialCopy(_Src*, volatile _Dst*)
521{ return _NegativeAnswer(); }
522
523template <class _Src, class _Dst>
524inline _NegativeAnswer _UseTrivialCopy(_Src*, const volatile _Dst*)
525{ return _NegativeAnswer(); }
526
527template <class _Src, class _Dst>
528inline _NegativeAnswer _UseTrivialUCopy(_Src*, const _Dst*)
529{ return _NegativeAnswer(); }
530
531template <class _Src, class _Dst>
532inline _NegativeAnswer _UseTrivialUCopy(_Src*, volatile _Dst*)
533{ return _NegativeAnswer(); }
534
535template <class _Src, class _Dst>
536inline _NegativeAnswer _UseTrivialUCopy(_Src*, const volatile _Dst*)
537{ return _NegativeAnswer(); }
538#endif
539
540template <class _Tp>
541inline _TrivialInit<_Tp> _UseTrivialInit(_Tp*)
542{ return _TrivialInit<_Tp>(); }
543
544template <class _Tp>
545struct _IsPOD {
546  typedef typename __type_traits<_Tp>::is_POD_type _Type;
547  static _Type _Answer() { return _Type(); }
548};
549
550template <class _Tp>
551inline _IsPOD<_Tp> _Is_POD(_Tp*)
552{ return _IsPOD<_Tp>(); }
553
554template <class _Tp>
555struct _DefaultZeroValueQuestion {
556  typedef typename _DefaultZeroValue<_Tp>::_Ret _Ret;
557  static _Ret _Answer() { return _Ret(); }
558};
559
560template <class _Tp>
561inline _DefaultZeroValueQuestion<_Tp> _HasDefaultZeroValue(_Tp*)
562{ return _DefaultZeroValueQuestion<_Tp>(); }
563
564/*
565 * Base class used:
566 * - to simulate partial template specialization
567 * - to simulate partial function ordering
568 * - to recognize STLport class from user specialized one
569 */
570template <class _Tp>
571struct __stlport_class
572{ typedef _Tp _Type; };
573
574template <class _Tp>
575struct _IsSTLportClass {
576  typedef typename _IsConvertible<_Tp, __stlport_class<_Tp> >::_Ret _Ret;
577#if defined (__BORLANDC__)
578  enum { _Is = _IsConvertible<_Tp, __stlport_class<_Tp> >::value };
579#endif
580};
581
582#if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER)
583template <class _Tp>
584struct _SwapImplemented {
585  typedef typename _IsSTLportClass<_Tp>::_Ret _Ret;
586#  if defined (__BORLANDC__)
587  enum { _Is = _IsSTLportClass<_Tp>::_Is };
588#  endif
589};
590#endif
591
592template <class _Tp>
593class _TpWithState : private _Tp {
594  _TpWithState();
595  int _state;
596};
597
598/* This is an internal helper struct used to guess if we are working
599 * on a stateless class. It can only be instanciated with a class type. */
600template <class _Tp>
601struct _IsStateless {
602  enum { _Is = sizeof(_TpWithState<_Tp>) == sizeof(int) };
603  typedef typename __bool2type<_Is>::_Ret _Ret;
604};
605
606_STLP_END_NAMESPACE
607
608#ifdef _STLP_CLASS_PARTIAL_SPECIALIZATION
609#  if defined (__BORLANDC__) || \
610      defined (__SUNPRO_CC) ||  \
611     (defined (__MWERKS__) && (__MWERKS__ <= 0x2303)) || \
612     (defined (__sgi) && defined (_COMPILER_VERSION)) || \
613      defined (__DMC__)
614#    define _STLP_IS_POD_ITER(_It, _Tp) __type_traits< typename iterator_traits< _Tp >::value_type >::is_POD_type()
615#  else
616#    define _STLP_IS_POD_ITER(_It, _Tp) typename __type_traits< typename iterator_traits< _Tp >::value_type >::is_POD_type()
617#  endif
618#else
619#  define _STLP_IS_POD_ITER(_It, _Tp) _Is_POD( _STLP_VALUE_TYPE( _It, _Tp ) )._Answer()
620#endif
621
622#endif /* _STLP_TYPE_TRAITS_H */
623
624// Local Variables:
625// mode:C++
626// End:
627