]> git.buserror.net Git - polintos/scott/priv.git/blob - include/c++/stl/stl/type_traits.h
Add STLport 5.1.4
[polintos/scott/priv.git] / include / c++ / stl / stl / type_traits.h
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 /*
27 This header file provides a framework for allowing compile time dispatch
28 based on type attributes. This is useful when writing template code.
29 For example, when making a copy of an array of an unknown type, it helps
30 to know if the type has a trivial copy constructor or not, to help decide
31 if a memcpy can be used.
32
33 The class template __type_traits provides a series of typedefs each of
34 which is either __true_type or __false_type. The argument to
35 __type_traits can be any type. The typedefs within this template will
36 attain 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
44 EXAMPLE:
45
46 //Copy an array of elements which have non-trivial copy constructors
47 template <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.
49 template <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
52 template <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
79 template <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
129 template <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.
144 template <class _Tp> struct __type_traits;
145 template <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
154 struct __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
163 struct __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
171 template <class _Tp>
172 struct _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
185 struct _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
196 char _STLP_CALL _IsP(bool, _PointerShim);  // no implementation is required
197 char* _STLP_CALL _IsP(bool, ...);          // no implementation is required
198
199 template <class _Tp>
200 struct _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.
214 template <class _Tp>
215 struct __type_traits : __type_traits_aux<typename _IsPtr<_Tp>::_Ret> {};
216
217 #  else /* _STLP_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS */
218
219 template <class _Tp>  struct _IsPtr {
220   typedef __false_type _Ret;
221 };
222
223 template <class _Tp>
224 struct __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)
258 template <class _Tp> struct _IsPtr<_Tp*>
259 { typedef __true_type _Ret; };
260 template <class _Tp> struct _IsRef<_Tp&>
261 { typedef __true_type _Ret; };
262
263 template <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)
315 template <class _ArePtrs, class _Src, class _Dst>
316 struct _IsCVConvertibleIf
317 { typedef typename _IsCVConvertible<_Src, _Dst>::_Ret _Ret; };
318
319 template <class _Src, class _Dst>
320 struct _IsCVConvertibleIf<__false_type, _Src, _Dst>
321 { typedef __false_type _Ret; };
322 #else
323 #  if defined (_STLP_MEMBER_TEMPLATE_CLASSES)
324 template <class _ArePtrs>
325 struct _IsCVConvertibleIfAux {
326   template <class _Src, class _Dst>
327   struct _In
328   { typedef typename _IsCVConvertible<_Src, _Dst>::_Ret _Ret; };
329 };
330
331 _STLP_TEMPLATE_NULL
332 struct _IsCVConvertibleIfAux<__false_type> {
333   template <class _Src, class _Dst>
334   struct _In
335   { typedef __false_type _Ret; };
336 };
337
338 template <class _ArePtrs, class _Src, class _Dst>
339 struct _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  */
346 template <class _ArePtrs, class _Src, class _Dst>
347 struct _IsCVConvertibleIf
348 { typedef __false_type _Ret; };
349 #  endif
350 #endif
351
352 template <class _Src, class _Dst>
353 struct _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   typedef typename _IsIntegral<_Src>::_Ret _Int1;
363   typedef typename _IsIntegral<_Dst>::_Ret _Int2;
364   typedef typename _Land2<_Int1, _Int2>::_Ret _BothInts;
365
366   typedef typename _IsRational<_Src>::_Ret _Rat1;
367   typedef typename _IsRational<_Dst>::_Ret _Rat2;
368   typedef typename _Land2<_Rat1, _Rat2>::_Ret _BothRats;
369
370   typedef typename _Lor2<_BothInts, _BothRats>::_Ret _BothNatives;
371   typedef typename _Land2<_BothNatives, _SameSize>::_Ret _Trivial2;
372
373   typedef typename _Lor2<_Trivial1, _Trivial2>::_Ret _Ret;
374 };
375
376 template <class _Src, class _Dst>
377 struct _TrivialCopy {
378   typedef typename _TrivialNativeTypeCopy<_Src, _Dst>::_Ret _NativeRet;
379
380 #if !defined (__BORLANDC__) || (__BORLANDC__ != 0x560)
381   typedef typename __type_traits<_Src>::has_trivial_assignment_operator _Tr1;
382 #else
383   typedef typename _UnConstPtr<_Src*>::_Type _Tp3;
384   typedef typename __type_traits<_Tp3>::has_trivial_assignment_operator _Tr1;
385 #endif
386   typedef typename _AreSameUnCVTypes<_Src, _Dst>::_Ret _Tr2;
387   typedef typename _Land2<_Tr1, _Tr2>::_Ret _UserRet;
388
389   typedef typename _Lor2<_NativeRet, _UserRet>::_Ret _Ret;
390   static _Ret _Answer() { return _Ret(); }
391 };
392
393 template <class _Src, class _Dst>
394 struct _TrivialUCopy {
395   typedef typename _TrivialNativeTypeCopy<_Src, _Dst>::_Ret _NativeRet;
396
397 #if !defined (__BORLANDC__) || (__BORLANDC__ != 0x560)
398   typedef typename __type_traits<_Src>::has_trivial_copy_constructor _Tr1;
399 #else
400   typedef typename _UnConstPtr<_Src*>::_Type _Tp3;
401   typedef typename __type_traits<_Tp3>::has_trivial_copy_constructor _Tr1;
402 #endif
403   typedef typename _AreSameUnCVTypes<_Src, _Dst>::_Ret _Tr2;
404   typedef typename _Land2<_Tr1, _Tr2>::_Ret _UserRet;
405
406   typedef typename _Lor2<_NativeRet, _UserRet>::_Ret _Ret;
407   static _Ret _Answer() { return _Ret(); }
408 };
409
410 template <class _Tp>
411 struct _DefaultZeroValue {
412   typedef typename _IsIntegral<_Tp>::_Ret _Tr1;
413   typedef typename _IsRational<_Tp>::_Ret _Tr2;
414   typedef typename _IsPtr<_Tp>::_Ret _Tr3;
415   typedef typename _Lor3<_Tr1, _Tr2, _Tr3>::_Ret _Ret;
416 };
417
418 template <class _Tp>
419 struct _TrivialInit {
420 #if !defined (__BORLANDC__) || (__BORLANDC__ != 0x560)
421   typedef typename __type_traits<_Tp>::has_trivial_default_constructor _Tr1;
422 #else
423   typedef typename _UnConstPtr<_Tp*>::_Type _Tp1;
424   typedef typename __type_traits<_Tp1>::has_trivial_copy_constructor _Tr1;
425 #endif
426   typedef typename _DefaultZeroValue<_Tp>::_Ret _Tr2;
427   typedef typename _Not<_Tr2>::_Ret _Tr3;
428   typedef typename _Land2<_Tr1, _Tr3>::_Ret _Ret;
429   static _Ret _Answer() { return _Ret(); }
430 };
431
432 #endif /* !_STLP_USE_BOOST_SUPPORT */
433
434 template <class _Tp>
435 struct _IsPtrType {
436   typedef typename _IsPtr<_Tp>::_Ret _Type;
437   static _Type _Ret() { return _Type(); }
438 };
439
440 template <class _Tp>
441 struct _IsRefType {
442   typedef typename _IsRef<_Tp>::_Ret _Type;
443   static _Type _Ret() { return _Type();}
444 };
445
446 template <class _Tp>
447 struct __call_traits {
448 #if defined (_STLP_USE_BOOST_SUPPORT) && !defined (_STLP_NO_EXTENSIONS)
449   typedef typename __select< ::boost::is_reference<_Tp>::value,
450                              _Tp, typename ::boost::add_reference< typename ::boost::add_const<_Tp>::type >::type>::_Ret param_type;
451 #else
452   typedef const _Tp& param_type;
453 #endif /* _STLP_USE_BOOST_SUPPORT */
454 };
455
456 #if !defined (_STLP_USE_BOOST_SUPPORT) && !defined (_STLP_NO_EXTENSIONS) && defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
457 template <class _Tp>
458 struct __call_traits<_Tp&>
459 { typedef _Tp& param_type; };
460 #endif
461
462 template <class _Tp1, class _Tp2>
463 struct _BothPtrType {
464   typedef typename _IsPtr<_Tp1>::_Ret _IsPtr1;
465   typedef typename _IsPtr<_Tp2>::_Ret _IsPtr2;
466
467   typedef typename _Land2<_IsPtr1, _IsPtr2>::_Ret _Ret;
468   static _Ret _Answer() { return _Ret(); }
469 };
470
471 template <class _Tp1, class _Tp2, class _IsRef1, class _IsRef2>
472 struct _OKToSwap {
473   typedef typename _AreSameUnCVTypes<_Tp1, _Tp2>::_Ret _Same;
474   typedef typename _Land3<_Same, _IsRef1, _IsRef2>::_Ret _Type;
475   static _Type _Answer() { return _Type(); }
476 };
477
478 template <class _Tp1, class _Tp2, class _IsRef1, class _IsRef2>
479 inline _OKToSwap<_Tp1, _Tp2, _IsRef1, _IsRef2>
480 _IsOKToSwap(_Tp1*, _Tp2*, const _IsRef1&, const _IsRef2&)
481 { return _OKToSwap<_Tp1, _Tp2, _IsRef1, _IsRef2>(); }
482
483 template <class _Src, class _Dst>
484 inline _TrivialCopy<_Src, _Dst> _UseTrivialCopy(_Src*, _Dst*)
485 { return _TrivialCopy<_Src, _Dst>(); }
486
487 template <class _Src, class _Dst>
488 inline _TrivialUCopy<_Src, _Dst> _UseTrivialUCopy(_Src*, _Dst*)
489 { return _TrivialUCopy<_Src, _Dst>(); }
490
491 template <class _Tp>
492 inline _TrivialInit<_Tp> _UseTrivialInit(_Tp*)
493 { return _TrivialInit<_Tp>(); }
494
495 template <class _Tp>
496 struct _IsPOD {
497   typedef typename __type_traits<_Tp>::is_POD_type _Type;
498   static _Type _Answer() { return _Type(); }
499 };
500
501 template <class _Tp>
502 inline _IsPOD<_Tp> _Is_POD(_Tp*)
503 { return _IsPOD<_Tp>(); }
504
505 template <class _Tp>
506 struct _DefaultZeroValueQuestion {
507   typedef typename _DefaultZeroValue<_Tp>::_Ret _Ret;
508   static _Ret _Answer() { return _Ret(); }
509 };
510
511 template <class _Tp>
512 inline _DefaultZeroValueQuestion<_Tp> _HasDefaultZeroValue(_Tp*)
513 { return _DefaultZeroValueQuestion<_Tp>(); }
514
515 /*
516  * Base class used:
517  * - to simulate partial template specialization
518  * - to simulate partial function ordering
519  * - to recognize STLport class from user specialized one
520  */
521 template <class _Tp>
522 struct __stlport_class
523 { typedef _Tp _Type; };
524
525 template <class _Tp>
526 struct _IsSTLportClass {
527   typedef typename _IsConvertible<_Tp, __stlport_class<_Tp> >::_Ret _Ret;
528 #if defined (__BORLANDC__)
529   enum { _Is = _IsConvertible<_Tp, __stlport_class<_Tp> >::value };
530 #endif
531 };
532
533 #if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER)
534 template <class _Tp>
535 struct _SwapImplemented {
536   typedef typename _IsSTLportClass<_Tp>::_Ret _Ret;
537 #  if defined (__BORLANDC__)
538   enum { _Is = _IsSTLportClass<_Tp>::_Is };
539 #  endif
540 };
541 #endif
542
543 template <class _Tp>
544 class _TpWithState : private _Tp {
545   _TpWithState();
546   int _state;
547 };
548
549 /* This is an internal helper struct used to guess if we are working
550  * on a stateless class. It can only be instanciated with a class type. */
551 template <class _Tp>
552 struct _IsStateless {
553   enum { _Is = sizeof(_TpWithState<_Tp>) == sizeof(int) };
554   typedef typename __bool2type<_Is>::_Ret _Ret;
555 };
556
557 _STLP_END_NAMESPACE
558
559 #ifdef _STLP_CLASS_PARTIAL_SPECIALIZATION
560 #  if defined (__BORLANDC__) || \
561       defined (__SUNPRO_CC) ||  \
562      (defined (__MWERKS__) && (__MWERKS__ <= 0x2303)) || \
563      (defined (__sgi) && defined (_COMPILER_VERSION)) || \
564       defined (__DMC__)
565 #    define _STLP_IS_POD_ITER(_It, _Tp) __type_traits< typename iterator_traits< _Tp >::value_type >::is_POD_type()
566 #  else
567 #    define _STLP_IS_POD_ITER(_It, _Tp) typename __type_traits< typename iterator_traits< _Tp >::value_type >::is_POD_type()
568 #  endif
569 #else
570 #  define _STLP_IS_POD_ITER(_It, _Tp) _Is_POD( _STLP_VALUE_TYPE( _It, _Tp ) )._Answer()
571 #endif
572
573 #endif /* _STLP_TYPE_TRAITS_H */
574
575 // Local Variables:
576 // mode:C++
577 // End: