3
* Copyright (c) 1996,1997
4
* Silicon Graphics Computer Systems, Inc.
7
* Moscow Center for SPARC Technology
12
* This material is provided "as is", with absolutely no warranty expressed
13
* or implied. Any use is at your own risk.
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.
23
#ifndef _STLP_TYPE_TRAITS_H
24
#define _STLP_TYPE_TRAITS_H
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.
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
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
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);
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());
59
# include <stl/_cwchar.h>
64
struct __true_type {};
65
struct __false_type {};
68
template <int _Is> struct __bool2type {
69
typedef __false_type _Ret;
73
struct __bool2type<1> { typedef __true_type _Ret; };
76
struct __bool2type<0> { typedef __false_type _Ret; };
78
// logical end of 3 predicated
79
template <class _P1, class _P2, class _P3>
81
typedef __false_type _Ret;
85
struct _Land3<__true_type, __true_type, __true_type> {
86
typedef __true_type _Ret;
90
// Forward declarations.
91
template <class _Tp> struct __type_traits;
92
template <int _IsPOD> struct __type_traits_aux {
93
typedef __false_type has_trivial_default_constructor;
94
typedef __false_type has_trivial_copy_constructor;
95
typedef __false_type has_trivial_assignment_operator;
96
typedef __false_type has_trivial_destructor;
97
typedef __false_type is_POD_type;
101
struct __type_traits_aux<0> {
102
typedef __false_type has_trivial_default_constructor;
103
typedef __false_type has_trivial_copy_constructor;
104
typedef __false_type has_trivial_assignment_operator;
105
typedef __false_type has_trivial_destructor;
106
typedef __false_type is_POD_type;
110
struct __type_traits_aux<1> {
111
typedef __true_type has_trivial_default_constructor;
112
typedef __true_type has_trivial_copy_constructor;
113
typedef __true_type has_trivial_assignment_operator;
114
typedef __true_type has_trivial_destructor;
115
typedef __true_type is_POD_type;
118
# ifdef _STLP_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS
120
// Boris : simulation technique is used here according to Adobe Open Source License Version 1.0.
121
// Copyright 2000 Adobe Systems Incorporated and others. All rights reserved.
122
// Authors: Mat Marcus and Jesse Jones
123
// The original version of this source code may be found at
124
// http://opensource.adobe.com.
126
struct _PointerShim {
127
// Since the compiler only allows at most one non-trivial
128
// implicit conversion we can make use of a shim class to
129
// be sure that IsPtr below doesn't accept classes with
130
// implicit pointer conversion operators
131
_PointerShim(const volatile void*); // no implementation
134
// These are the discriminating functions
136
char _STLP_CALL _IsP(bool, _PointerShim); // no implementation is required
137
char* _STLP_CALL _IsP(bool, ...); // no implementation is required
140
char _STLP_CALL _IsSameFun(bool, _Tp*, _Tp*); // no implementation is required
141
char* _STLP_CALL _IsSameFun(bool, ...); // no implementation is required
143
template <class _Tp1, class _Tp2>
146
static _Tp1* __null_rep1();
147
static _Tp2* __null_rep2();
148
enum { _Ret = (sizeof(_IsSameFun(false,__null_rep1(),__null_rep2())) == sizeof(char)) };
154
// This template meta function takes a type T
155
// and returns true exactly when T is a pointer.
156
// One can imagine meta-functions discriminating on
158
static _Tp& __null_rep();
159
enum { _Ret = (sizeof(_IsP(false,__null_rep())) == sizeof(char)) };
165
enum { _Is = _IsPtr<_Tp>::_Ret } ;
166
typedef __bool2type< _Is > _BT;
167
typedef typename _BT::_Ret _Type;
168
static _Type _Ret() { return _Type(); }
171
template <class _Tp1, class _Tp2>
172
struct _BothPtrType {
173
typedef __bool2type< _IsPtr<_Tp1>::_Ret> _B1;
174
typedef __bool2type< _IsPtr<_Tp2>::_Ret> _B2;
175
typedef typename _B1::_Ret _Type1;
176
typedef typename _B2::_Ret _Type2;
177
typedef typename _Land3<_Type1, _Type2, __true_type>::_Ret _Type;
178
static _Type _Ret() { return _Type(); }
181
// we make general case dependant on the fact the type is actually a pointer.
184
struct __type_traits : __type_traits_aux<_IsPtr<_Tp>::_Ret> {};
189
struct __type_traits {
190
typedef __true_type this_dummy_member_must_be_first;
191
/* Do not remove this member. It informs a compiler which
192
automatically specializes __type_traits that this
193
__type_traits template is special. It just makes sure that
194
things work if an implementation is using a template
195
called __type_traits for something unrelated. */
197
/* The following restrictions should be observed for the sake of
198
compilers which automatically produce type specific specializations
200
- You may reorder the members below if you wish
201
- You may remove any of the members below if you wish
202
- You must not rename members without making the corresponding
203
name change in the compiler
204
- Members you add will be treated like regular members unless
205
you add the appropriate support in the compiler. */
206
typedef __false_type has_trivial_default_constructor;
207
typedef __false_type has_trivial_copy_constructor;
208
typedef __false_type has_trivial_assignment_operator;
209
typedef __false_type has_trivial_destructor;
210
typedef __false_type is_POD_type;
214
template <class _Tp> struct _IsPtr { enum { _Ret = 0 }; };
215
template <class _Tp> struct _IsPtrType {
216
static __false_type _Ret() { return __false_type();}
218
template <class _Tp1, class _Tp2> struct _BothPtrType {
219
static __false_type _Ret() { return __false_type();}
222
template <class _Tp1, class _Tp2>
223
struct _IsSame { enum { _Ret = 0 }; };
225
// template <class _Tp1, class _Tp2>
226
// struct _IsSameType { static __false_type _Ret() { return __false_type(); } };
228
# ifdef _STLP_CLASS_PARTIAL_SPECIALIZATION
229
template <class _Tp> struct _IsPtr<_Tp*> { enum { _Ret = 1 }; };
230
template <class _Tp> struct _IsPtrType<_Tp*> {
231
static __true_type _Ret() { return __true_type();}
233
template <class _Tp1, class _Tp2> struct _BothPtrType<_Tp1*, _Tp2*> {
234
static __true_type _Ret() { return __true_type();}
237
struct _IsSame<_Tp, _Tp> { enum { _Ret = 1 }; };
240
# endif /* _STLP_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS */
242
// Provide some specializations. This is harmless for compilers that
243
// have built-in __types_traits support, and essential for compilers
245
#ifndef _STLP_NO_BOOL
246
_STLP_TEMPLATE_NULL struct __type_traits<bool> : __type_traits_aux<1> {};
247
#endif /* _STLP_NO_BOOL */
248
_STLP_TEMPLATE_NULL struct __type_traits<char> : __type_traits_aux<1> {};
249
#ifndef _STLP_NO_SIGNED_BUILTINS
250
_STLP_TEMPLATE_NULL struct __type_traits<signed char> : __type_traits_aux<1> {};
252
_STLP_TEMPLATE_NULL struct __type_traits<unsigned char> : __type_traits_aux<1> {};
253
#if defined ( _STLP_HAS_WCHAR_T ) && ! defined (_STLP_WCHAR_T_IS_USHORT)
254
_STLP_TEMPLATE_NULL struct __type_traits<wchar_t> : __type_traits_aux<1> {};
255
#endif /* _STLP_HAS_WCHAR_T */
257
_STLP_TEMPLATE_NULL struct __type_traits<short> : __type_traits_aux<1> {};
258
_STLP_TEMPLATE_NULL struct __type_traits<unsigned short> : __type_traits_aux<1> {};
259
_STLP_TEMPLATE_NULL struct __type_traits<int> : __type_traits_aux<1> {};
260
_STLP_TEMPLATE_NULL struct __type_traits<unsigned int> : __type_traits_aux<1> {};
261
_STLP_TEMPLATE_NULL struct __type_traits<long> : __type_traits_aux<1> {};
262
_STLP_TEMPLATE_NULL struct __type_traits<unsigned long> : __type_traits_aux<1> {};
264
#ifdef _STLP_LONG_LONG
265
_STLP_TEMPLATE_NULL struct __type_traits<_STLP_LONG_LONG> : __type_traits_aux<1> {};
266
_STLP_TEMPLATE_NULL struct __type_traits<unsigned _STLP_LONG_LONG> : __type_traits_aux<1> {};
267
#endif /* _STLP_LONG_LONG */
269
_STLP_TEMPLATE_NULL struct __type_traits<float> : __type_traits_aux<1> {};
270
_STLP_TEMPLATE_NULL struct __type_traits<double> : __type_traits_aux<1> {};
272
# if !defined ( _STLP_NO_LONG_DOUBLE )
273
_STLP_TEMPLATE_NULL struct __type_traits<long double> : __type_traits_aux<1> {};
276
#ifdef _STLP_CLASS_PARTIAL_SPECIALIZATION
277
template <class _Tp> struct __type_traits<_Tp*> : __type_traits_aux<1> {};
280
// The following could be written in terms of numeric_limits.
281
// We're doing it separately to reduce the number of dependencies.
283
template <class _Tp> struct _Is_integer {
284
typedef __false_type _Integral;
287
#ifndef _STLP_NO_BOOL
289
_STLP_TEMPLATE_NULL struct _Is_integer<bool> {
290
typedef __true_type _Integral;
293
#endif /* _STLP_NO_BOOL */
295
_STLP_TEMPLATE_NULL struct _Is_integer<char> {
296
typedef __true_type _Integral;
299
#ifndef _STLP_NO_SIGNED_BUILTINS
301
_STLP_TEMPLATE_NULL struct _Is_integer<signed char> {
302
typedef __true_type _Integral;
306
_STLP_TEMPLATE_NULL struct _Is_integer<unsigned char> {
307
typedef __true_type _Integral;
310
#if defined ( _STLP_HAS_WCHAR_T ) && ! defined (_STLP_WCHAR_T_IS_USHORT)
312
_STLP_TEMPLATE_NULL struct _Is_integer<wchar_t> {
313
typedef __true_type _Integral;
316
#endif /* _STLP_HAS_WCHAR_T */
318
_STLP_TEMPLATE_NULL struct _Is_integer<short> {
319
typedef __true_type _Integral;
322
_STLP_TEMPLATE_NULL struct _Is_integer<unsigned short> {
323
typedef __true_type _Integral;
326
_STLP_TEMPLATE_NULL struct _Is_integer<int> {
327
typedef __true_type _Integral;
330
_STLP_TEMPLATE_NULL struct _Is_integer<unsigned int> {
331
typedef __true_type _Integral;
334
_STLP_TEMPLATE_NULL struct _Is_integer<long> {
335
typedef __true_type _Integral;
338
_STLP_TEMPLATE_NULL struct _Is_integer<unsigned long> {
339
typedef __true_type _Integral;
342
#ifdef _STLP_LONG_LONG
344
_STLP_TEMPLATE_NULL struct _Is_integer<_STLP_LONG_LONG> {
345
typedef __true_type _Integral;
348
_STLP_TEMPLATE_NULL struct _Is_integer<unsigned _STLP_LONG_LONG> {
349
typedef __true_type _Integral;
352
#endif /* _STLP_LONG_LONG */
354
template <class _Tp1, class _Tp2>
356
enum { _Same = _IsSame<_Tp1,_Tp2>::_Ret } ;
357
typedef typename __type_traits<_Tp1>::has_trivial_assignment_operator _Tr1;
358
typedef typename __type_traits<_Tp2>::has_trivial_assignment_operator _Tr2;
359
typedef typename __bool2type< _Same >::_Ret _Tr3;
360
typedef typename _Land3<_Tr1, _Tr2, _Tr3>::_Ret _Type;
361
static _Type _Ret() { return _Type(); }
364
template <class _Tp1, class _Tp2>
365
inline _OKToMemCpy<_Tp1, _Tp2> _IsOKToMemCpy(_Tp1*, _Tp2*) {
366
return _OKToMemCpy<_Tp1, _Tp2>();
371
typedef typename __type_traits<_Tp>::is_POD_type _Type;
372
static _Type _Ret() { return _Type(); }
376
inline _IsPOD<_Tp> _Is_POD (_Tp*) { return _IsPOD<_Tp>(); }
378
# ifdef _STLP_CLASS_PARTIAL_SPECIALIZATION
379
# if defined (__BORLANDC__) || defined (__SUNPRO_CC) || ( defined (__MWERKS__) && (__MWERKS__ <= 0x2303)) || ( defined (__sgi) && defined (_COMPILER_VERSION)) || defined (__DMC__)
380
# define _IS_POD_ITER(_It, _Tp) __type_traits< typename iterator_traits< _Tp >::value_type >::is_POD_type()
382
# define _IS_POD_ITER(_It, _Tp) typename __type_traits< typename iterator_traits< _Tp >::value_type >::is_POD_type()
385
# define _IS_POD_ITER(_It, _Tp) _Is_POD( _STLP_VALUE_TYPE( _It, _Tp ) )._Ret()
388
# ifdef _STLP_DEFAULT_CONSTRUCTOR_BUG
389
// Those adaptors are here to fix common compiler bug regarding builtins:
390
// expressions like int k = int() should initialize k to 0
392
inline _Tp __default_constructed_aux(_Tp*, const __false_type&) {
396
inline _Tp __default_constructed_aux(_Tp*, const __true_type&) {
401
inline _Tp __default_constructed(_Tp* __p) {
402
typedef typename _Is_integer<_Tp>::_Integral _Is_Integral;
403
return __default_constructed_aux(__p, _Is_Integral());
406
# define _STLP_DEFAULT_CONSTRUCTED(_TTp) __default_constructed((_TTp*)0)
408
# define _STLP_DEFAULT_CONSTRUCTED(_TTp) _TTp()
413
#endif /* __TYPE_TRAITS_H */