]> git.buserror.net Git - polintos/scott/priv.git/blob - include/c++/stl/stl/type_manips.h
Add STLport 5.1.4
[polintos/scott/priv.git] / include / c++ / stl / stl / type_manips.h
1 /*
2  *
3  * Copyright (c) 2003
4  * François Dumont
5  *
6  * This material is provided "as is", with absolutely no warranty expressed
7  * or implied. Any use is at your own risk.
8  *
9  * Permission to use or copy this software for any purpose is hereby granted
10  * without fee, provided the above notices are retained on all copies.
11  * Permission to modify the code and to distribute modified code is granted,
12  * provided the above notices are retained, and a notice that the code was
13  * modified is included with the above copyright notice.
14  *
15  */
16
17
18 #ifndef _STLP_TYPE_MANIPS_H
19 #define _STLP_TYPE_MANIPS_H
20
21 _STLP_BEGIN_NAMESPACE
22
23 struct __true_type {};
24 struct __false_type {};
25
26 #if defined (_STLP_USE_NAMESPACES)
27 _STLP_MOVE_TO_PRIV_NAMESPACE
28 using _STLP_STD::__true_type;
29 using _STLP_STD::__false_type;
30 _STLP_MOVE_TO_STD_NAMESPACE
31 #endif
32
33 //bool to type
34 template <int _Is>
35 struct __bool2type
36 { typedef __true_type _Ret; };
37
38 _STLP_TEMPLATE_NULL
39 struct __bool2type<1> { typedef __true_type _Ret; };
40
41 _STLP_TEMPLATE_NULL
42 struct __bool2type<0> { typedef __false_type _Ret; };
43
44 //type to bool
45 template <class __bool_type>
46 struct __type2bool { enum {_Ret = 1}; };
47
48 _STLP_TEMPLATE_NULL
49 struct __type2bool<__true_type> { enum {_Ret = 1}; };
50
51 _STLP_TEMPLATE_NULL
52 struct __type2bool<__false_type> { enum {_Ret = 0}; };
53
54 //Negation
55 template <class _BoolType>
56 struct _Not { typedef __false_type _Ret; };
57
58 _STLP_TEMPLATE_NULL
59 struct _Not<__false_type> { typedef __true_type _Ret; };
60
61 // logical and of 2 predicated
62 template <class _P1, class _P2>
63 struct _Land2 { typedef __false_type _Ret; };
64
65 _STLP_TEMPLATE_NULL
66 struct _Land2<__true_type, __true_type> { typedef __true_type _Ret; };
67
68 // logical and of 3 predicated
69 template <class _P1, class _P2, class _P3>
70 struct _Land3 { typedef __false_type _Ret; };
71
72 _STLP_TEMPLATE_NULL
73 struct _Land3<__true_type, __true_type, __true_type> { typedef __true_type _Ret; };
74
75 //logical or of 2 predicated
76 template <class _P1, class _P2>
77 struct _Lor2 { typedef __true_type _Ret; };
78
79 _STLP_TEMPLATE_NULL
80 struct _Lor2<__false_type, __false_type> { typedef __false_type _Ret; };
81
82 // logical or of 3 predicated
83 template <class _P1, class _P2, class _P3>
84 struct _Lor3 { typedef __true_type _Ret; };
85
86 _STLP_TEMPLATE_NULL
87 struct _Lor3<__false_type, __false_type, __false_type> { typedef __false_type _Ret; };
88
89 ////////////////////////////////////////////////////////////////////////////////
90 // class template __select
91 // Selects one of two types based upon a boolean constant
92 // Invocation: __select<_Cond, T, U>::Result
93 // where:
94 // flag is a compile-time boolean constant
95 // T and U are types
96 // Result evaluates to T if flag is true, and to U otherwise.
97 ////////////////////////////////////////////////////////////////////////////////
98 // BEWARE: If the compiler do not support partial template specialization or nested template
99 //classes the default behavior of the __select is to consider the condition as false and so return
100 //the second template type!!
101
102 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
103 template <bool _Cond, class _Tp1, class _Tp2>
104 struct __select { typedef _Tp1 _Ret; };
105
106 template <class _Tp1, class _Tp2>
107 struct __select<false, _Tp1, _Tp2> { typedef _Tp2 _Ret; };
108
109 #  if defined (__BORLANDC__)
110 template <class _CondT, class _Tp1, class _Tp2>
111 struct __selectT { typedef _Tp1 _Ret; };
112
113 template <class _Tp1, class _Tp2>
114 struct __selectT<__false_type, _Tp1, _Tp2> { typedef _Tp2 _Ret; };
115 #  endif
116
117 #else /* _STLP_CLASS_PARTIAL_SPECIALIZATION */
118
119 #  if defined (_STLP_MEMBER_TEMPLATE_CLASSES)
120 template <int _Cond>
121 struct __select_aux {
122   template <class _Tp1, class _Tp2>
123   struct _In {
124     typedef _Tp1 _Ret;
125   };
126 };
127
128 _STLP_TEMPLATE_NULL
129 struct __select_aux<0> {
130   template <class _Tp1, class _Tp2>
131   struct _In {
132     typedef _Tp2 _Ret;
133   };
134 };
135
136 template <int _Cond, class _Tp1, class _Tp2>
137 struct __select {
138   typedef typename __select_aux<_Cond>::_STLP_TEMPLATE _In<_Tp1, _Tp2>::_Ret _Ret;
139 };
140 #  else /* _STLP_MEMBER_TEMPLATE_CLASSES */
141 //default behavior
142 template <int _Cond, class _Tp1, class _Tp2>
143 struct __select {
144   typedef _Tp2 _Ret;
145 };
146 #  endif /* _STLP_MEMBER_TEMPLATE_CLASSES */
147
148 #endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */
149
150 #if defined (_STLP_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS)
151 // Boris : simulation technique is used here according to Adobe Open Source License Version 1.0.
152 // Copyright 2000 Adobe Systems Incorporated and others. All rights reserved.
153 // Authors: Mat Marcus and Jesse Jones
154 // The original version of this source code may be found at
155 // http://opensource.adobe.com.
156
157 // These are the discriminating functions
158 template <class _Tp>
159 char _STLP_CALL _IsSameFun(bool, _Tp const volatile*, _Tp const volatile*); // no implementation is required
160 char* _STLP_CALL _IsSameFun(bool, ...);       // no implementation is required
161
162 template <class _Tp1, class _Tp2>
163 struct _IsSame {
164   static _Tp1* __null_rep1();
165   static _Tp2* __null_rep2();
166   enum { _Ret = (sizeof(_IsSameFun(false,__null_rep1(), __null_rep2())) == sizeof(char)) };
167   typedef typename __bool2type<_Ret>::_Ret _RetT;
168 };
169
170 #else
171
172 template <class _Tp1, class _Tp2>
173 struct _IsSameAux {
174   typedef __false_type _RetT;
175   enum { _Ret = 0 };
176 };
177
178 template <class _Tp>
179 struct _UnConstType { typedef _Tp _Type; };
180
181 template <class _Tp>
182 struct _UnVolatileType { typedef _Tp _Type; };
183
184 template <class _Tp>
185 struct _UnCVType {
186   typedef typename _UnVolatileType<_Tp>::_Type _UnVType;
187   typedef typename _UnConstType<_UnVType>::_Type _Type;
188 };
189
190 #  if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
191 template <class _Tp>
192 struct _IsSameAux<_Tp, _Tp> {
193   typedef __true_type _RetT;
194   enum { _Ret = 1 };
195 };
196
197 #    if !defined (_STLP_QUALIFIED_SPECIALIZATION_BUG)
198 template <class _Tp>
199 struct _UnConstType<const _Tp> { typedef _Tp _Type; };
200
201 template <class _Tp>
202 struct _UnVolatileType<volatile _Tp> { typedef _Tp _Type; };
203 #    endif
204
205 #    if defined(__BORLANDC__)
206 template<class _Tp>
207 struct _UnConstPtr { typedef _Tp _Type; };
208
209 template<class _Tp>
210 struct _UnConstPtr<_Tp*> { typedef _Tp _Type; };
211
212 template<class _Tp>
213 struct _UnConstPtr<const _Tp*> { typedef _Tp _Type; };
214 #    endif
215 #  endif
216
217 template <class _Tp1, class _Tp2>
218 struct _IsSame {
219   typedef typename _UnCVType<_Tp1>::_Type _Type1;
220   typedef typename _UnCVType<_Tp2>::_Type _Type2;
221
222   typedef _IsSameAux<_Type1, _Type2> _Aux;
223   enum { _Ret = _Aux::_Ret };
224   typedef typename _Aux::_RetT _RetT;
225 };
226 #endif
227
228 /*
229  * The following struct will tell you if 2 types are the same, the limitations are:
230  *  - it compares the types without the const or volatile qualifiers, int and const int
231  *    will be considered as same for instance.
232  *  - the previous remarks do not apply to pointer types, int* and int const* won't be
233  *    considered as comparable. (int * and int *const are).
234  */
235 template <class _Tp1, class _Tp2>
236 struct _AreSameUnCVTypes {
237   enum { _Same = _IsSame<_Tp1, _Tp2>::_Ret };
238   typedef typename _IsSame<_Tp1, _Tp2>::_RetT _Ret;
239 };
240
241 /* Rather than introducing a new macro for the following constrution we use
242  * an existing one (_STLP_DONT_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS) that
243  * is used for a similar feature.
244  */
245 #if !defined (_STLP_DONT_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS)
246 template <class _Src, class _Dst>
247 struct _ConversionHelper {
248   static char _Test(bool, _Dst);
249   static char* _Test(bool, ...);
250   static _Src _MakeSource();
251 };
252
253 template <class _Src, class _Dst>
254 struct _IsConvertible {
255   typedef _ConversionHelper<_Src*, const volatile _Dst*> _H;
256   enum { value = (sizeof(char) == sizeof(_H::_Test(false, _H::_MakeSource()))) };
257   typedef typename __bool2type<value>::_Ret _Ret;
258 };
259
260 /* This struct is intended to say if a pointer can be convertible to an other
261  * taking into account cv qualifications. It shouldn't be instanciated with
262  * something else than pointer type as it uses pass by value parameter that
263  * results in compilation error when parameter type has a special memory
264  * alignment
265  */
266 template <class _Src, class _Dst>
267 struct _IsCVConvertible {
268 #if !defined (__BORLANDC__)
269   typedef _ConversionHelper<_Src, _Dst> _H;
270   enum { value = (sizeof(char) == sizeof(_H::_Test(false, _H::_MakeSource()))) };
271 #else
272   enum { _Is1 = __type2bool<_IsConst<_Src>::_Ret>::_Ret };
273   enum { _Is2 = _IsConvertible<_UnConstPtr<_Src>::_Type, _UnConstPtr<_Dst>::_Type>::value };
274   enum { value = _Is1 ? 0 : _Is2 };
275 #endif
276   typedef typename __bool2type<value>::_Ret _Ret;
277 };
278
279 #else
280 template <class _Src, class _Dst>
281 struct _IsConvertible {
282   enum {value = 0};
283   typedef __false_type _Ret;
284 };
285 #endif
286
287 template <class _Tp>
288 struct _IsConst { typedef __false_type _Ret; };
289
290 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) && !defined (_STLP_QUALIFIED_SPECIALIZATION_BUG)
291 template <class _Tp>
292 struct _IsConst <const _Tp> { typedef __true_type _Ret; };
293 #endif
294
295 #  if defined(__BORLANDC__)
296 template<class _Tp>
297 struct _IsConst <const _Tp*> { typedef __true_type _Ret; };
298
299 template<class _Tp>
300 struct _IsConst <const volatile _Tp*> { typedef __true_type _Ret; };
301 #  endif
302
303 _STLP_END_NAMESPACE
304
305 #endif /* _STLP_TYPE_MANIPS_H */