6 * This material is provided "as is", with absolutely no warranty expressed
7 * or implied. Any use is at your own risk.
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.
18 #ifndef _STLP_TYPE_MANIPS_H
19 #define _STLP_TYPE_MANIPS_H
23 struct __true_type {};
24 struct __false_type {};
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
36 { typedef __true_type _Ret; };
39 struct __bool2type<1> { typedef __true_type _Ret; };
42 struct __bool2type<0> { typedef __false_type _Ret; };
45 template <class __bool_type>
46 struct __type2bool { enum {_Ret = 1}; };
49 struct __type2bool<__true_type> { enum {_Ret = 1}; };
52 struct __type2bool<__false_type> { enum {_Ret = 0}; };
55 template <class _BoolType>
56 struct _Not { typedef __false_type _Ret; };
59 struct _Not<__false_type> { typedef __true_type _Ret; };
61 // logical and of 2 predicated
62 template <class _P1, class _P2>
63 struct _Land2 { typedef __false_type _Ret; };
66 struct _Land2<__true_type, __true_type> { typedef __true_type _Ret; };
68 // logical and of 3 predicated
69 template <class _P1, class _P2, class _P3>
70 struct _Land3 { typedef __false_type _Ret; };
73 struct _Land3<__true_type, __true_type, __true_type> { typedef __true_type _Ret; };
75 //logical or of 2 predicated
76 template <class _P1, class _P2>
77 struct _Lor2 { typedef __true_type _Ret; };
80 struct _Lor2<__false_type, __false_type> { typedef __false_type _Ret; };
82 // logical or of 3 predicated
83 template <class _P1, class _P2, class _P3>
84 struct _Lor3 { typedef __true_type _Ret; };
87 struct _Lor3<__false_type, __false_type, __false_type> { typedef __false_type _Ret; };
89 ////////////////////////////////////////////////////////////////////////////////
90 // class template __select
91 // Selects one of two types based upon a boolean constant
92 // Invocation: __select<_Cond, T, U>::Result
94 // flag is a compile-time boolean constant
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!!
102 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
103 template <bool _Cond, class _Tp1, class _Tp2>
104 struct __select { typedef _Tp1 _Ret; };
106 template <class _Tp1, class _Tp2>
107 struct __select<false, _Tp1, _Tp2> { typedef _Tp2 _Ret; };
109 # if defined (__BORLANDC__)
110 template <class _CondT, class _Tp1, class _Tp2>
111 struct __selectT { typedef _Tp1 _Ret; };
113 template <class _Tp1, class _Tp2>
114 struct __selectT<__false_type, _Tp1, _Tp2> { typedef _Tp2 _Ret; };
117 #else /* _STLP_CLASS_PARTIAL_SPECIALIZATION */
119 # if defined (_STLP_MEMBER_TEMPLATE_CLASSES)
121 struct __select_aux {
122 template <class _Tp1, class _Tp2>
129 struct __select_aux<0> {
130 template <class _Tp1, class _Tp2>
136 template <int _Cond, class _Tp1, class _Tp2>
138 typedef typename __select_aux<_Cond>::_STLP_TEMPLATE _In<_Tp1, _Tp2>::_Ret _Ret;
140 # else /* _STLP_MEMBER_TEMPLATE_CLASSES */
142 template <int _Cond, class _Tp1, class _Tp2>
146 # endif /* _STLP_MEMBER_TEMPLATE_CLASSES */
148 #endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */
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.
157 // These are the discriminating functions
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
162 template <class _Tp1, class _Tp2>
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;
172 template <class _Tp1, class _Tp2>
174 typedef __false_type _RetT;
179 struct _UnConstType { typedef _Tp _Type; };
182 struct _UnVolatileType { typedef _Tp _Type; };
186 typedef typename _UnVolatileType<_Tp>::_Type _UnVType;
187 typedef typename _UnConstType<_UnVType>::_Type _Type;
190 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
192 struct _IsSameAux<_Tp, _Tp> {
193 typedef __true_type _RetT;
197 # if !defined (_STLP_QUALIFIED_SPECIALIZATION_BUG)
199 struct _UnConstType<const _Tp> { typedef _Tp _Type; };
202 struct _UnVolatileType<volatile _Tp> { typedef _Tp _Type; };
205 # if defined(__BORLANDC__)
207 struct _UnConstPtr { typedef _Tp _Type; };
210 struct _UnConstPtr<_Tp*> { typedef _Tp _Type; };
213 struct _UnConstPtr<const _Tp*> { typedef _Tp _Type; };
217 template <class _Tp1, class _Tp2>
219 typedef typename _UnCVType<_Tp1>::_Type _Type1;
220 typedef typename _UnCVType<_Tp2>::_Type _Type2;
222 typedef _IsSameAux<_Type1, _Type2> _Aux;
223 enum { _Ret = _Aux::_Ret };
224 typedef typename _Aux::_RetT _RetT;
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).
235 template <class _Tp1, class _Tp2>
236 struct _AreSameUnCVTypes {
237 enum { _Same = _IsSame<_Tp1, _Tp2>::_Ret };
238 typedef typename _IsSame<_Tp1, _Tp2>::_RetT _Ret;
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.
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();
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;
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
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()))) };
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 };
276 typedef typename __bool2type<value>::_Ret _Ret;
280 template <class _Src, class _Dst>
281 struct _IsConvertible {
283 typedef __false_type _Ret;
288 struct _IsConst { typedef __false_type _Ret; };
290 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) && !defined (_STLP_QUALIFIED_SPECIALIZATION_BUG)
292 struct _IsConst <const _Tp> { typedef __true_type _Ret; };
295 # if defined(__BORLANDC__)
297 struct _IsConst <const _Tp*> { typedef __true_type _Ret; };
300 struct _IsConst <const volatile _Tp*> { typedef __true_type _Ret; };
305 #endif /* _STLP_TYPE_MANIPS_H */