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) && !defined (_STLP_DONT_USE_PRIV_NAMESPACE)
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 # if defined (__BORLANDC__)
104 template <class _CondT
, class _Tp1
, class _Tp2
>
105 struct __selectT
{ typedef _Tp1 _Ret
; };
107 template <class _Tp1
, class _Tp2
>
108 struct __selectT
<__false_type
, _Tp1
, _Tp2
> { typedef _Tp2 _Ret
; };
111 # if !defined (__BORLANDC__) || (__BORLANDC__ >= 0x590)
112 template <bool _Cond
, class _Tp1
, class _Tp2
>
113 struct __select
{ typedef _Tp1 _Ret
; };
115 template <class _Tp1
, class _Tp2
>
116 struct __select
<false, _Tp1
, _Tp2
> { typedef _Tp2 _Ret
; };
118 template <bool _Cond
, class _Tp1
, class _Tp2
>
120 { typedef __selectT
<typename __bool2type
<_Cond
>::_Ret
, _Tp1
, _Tp2
>::_Ret _Ret
; };
125 # if defined (_STLP_MEMBER_TEMPLATE_CLASSES)
127 struct __select_aux
{
128 template <class _Tp1
, class _Tp2
>
135 struct __select_aux
<0> {
136 template <class _Tp1
, class _Tp2
>
142 template <int _Cond
, class _Tp1
, class _Tp2
>
144 typedef typename __select_aux
<_Cond
>::_STLP_TEMPLATE _In
<_Tp1
, _Tp2
>::_Ret _Ret
;
146 # else /* _STLP_MEMBER_TEMPLATE_CLASSES */
148 template <int _Cond
, class _Tp1
, class _Tp2
>
152 # endif /* _STLP_MEMBER_TEMPLATE_CLASSES */
154 #endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */
156 /* Rather than introducing a new macro for the following constrution we use
157 * an existing one (_STLP_DONT_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS) that
158 * is used for a similar feature.
160 #if !defined (_STLP_DONT_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS) && \
161 (!defined (__GNUC__) || (__GNUC__ > 2))
162 // Helper struct that will forbid volatile qualified types:
163 # if !defined (__BORLANDC__)
164 struct _NoVolatilePointerShim
{ _NoVolatilePointerShim(const void*); };
166 char _STLP_CALL
_IsCopyableFun(bool, _NoVolatilePointerShim
, _Tp
const*, _Tp
*); // no implementation is required
167 char* _STLP_CALL
_IsCopyableFun(bool, ...); // no implementation is required
169 template <class _Src
, class _Dst
>
171 static _Src
* __null_src();
172 static _Dst
* __null_dst();
173 enum { _Ret
= (sizeof(_IsCopyableFun(false, __null_src(), __null_src(), __null_dst())) == sizeof(char)) };
174 typedef typename __bool2type
<_Ret
>::_Ret _RetT
;
177 template <class _Tp1
, class _Tp2
> struct _AreSameTypes
;
178 template <class _Tp
> struct _IsUnQual
;
179 template <class _Src
, class _Dst
>
181 typedef typename _AreSameTypes
<_Src
, _Dst
>::_Ret _Tr1
;
182 typedef typename _IsUnQual
<_Dst
>::_Ret _Tr2
;
183 typedef typename _Land2
<_Tr1
, _Tr2
>::_Ret _RetT
;
184 enum { _Ret
= __type2bool
<_RetT
>::_Ret
};
188 template <class _Src
, class _Dst
>
191 typedef __false_type _RetT
;
196 * The following struct will tell you if 2 types are the same and if copying memory
197 * from the _Src type to the _Dst type is right considering qualifiers. If _Src and
198 * _Dst types are the same unqualified types _Ret will be false if:
199 * - any of the type has the volatile qualifier
200 * - _Dst is const qualified
202 template <class _Src
, class _Dst
>
203 struct _AreCopyable
{
204 enum { _Same
= _Copyable
<_Src
, _Dst
>::_Ret
};
205 typedef typename _Copyable
<_Src
, _Dst
>::_RetT _Ret
;
208 template <class _Tp1
, class _Tp2
>
209 struct _AreSameTypes
{
211 typedef __false_type _Ret
;
214 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
216 struct _AreSameTypes
<_Tp
, _Tp
> {
218 typedef __true_type _Ret
;
222 #if !defined (_STLP_DONT_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS)
223 template <class _Src
, class _Dst
>
224 struct _ConversionHelper
{
225 static char _Test(bool, _Dst
);
226 static char* _Test(bool, ...);
227 static _Src
_MakeSource();
230 template <class _Src
, class _Dst
>
231 struct _IsConvertible
{
232 typedef _ConversionHelper
<_Src
*, const volatile _Dst
*> _H
;
233 enum { value
= (sizeof(char) == sizeof(_H::_Test(false, _H::_MakeSource()))) };
234 typedef typename __bool2type
<value
>::_Ret _Ret
;
237 # if defined (__BORLANDC__)
238 # if (__BORLANDC__ < 0x590)
240 struct _UnConstPtr
{ typedef _Tp _Type
; };
243 struct _UnConstPtr
<_Tp
*> { typedef _Tp _Type
; };
246 struct _UnConstPtr
<const _Tp
*> { typedef _Tp _Type
; };
249 # if !defined (_STLP_QUALIFIED_SPECIALIZATION_BUG)
251 struct _IsConst
{ typedef __false_type _Ret
; };
254 struct _IsConst
{ typedef _AreSameTypes
<_Tp
, const _Tp
>::_Ret _Ret
; };
257 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) && !defined (_STLP_QUALIFIED_SPECIALIZATION_BUG)
259 struct _IsConst
<const _Tp
> { typedef __true_type _Ret
; };
262 # if (__BORLANDC__ < 0x590)
264 struct _IsConst
<_Tp
*> { typedef _AreSameTypes
<_Tp
*, const _Tp
*>::_Ret _Ret
; };
267 struct _IsVolatile
{ typedef _AreSameTypes
<_Tp
, volatile _Tp
>::_Ret _Ret
; };
271 typedef _IsConst
<_Tp
>::_Ret _Tr1
;
272 typedef _IsVolatile
<_Tp
>::_Ret _Tr2
;
273 typedef _Not
<_Tr1
>::_Ret _NotCon
;
274 typedef _Not
<_Tr2
>::_Ret _NotVol
;
275 typedef _Land2
<_NotCon
, _NotVol
>::_Ret _Ret
;
278 # if !defined (_STLP_QUALIFIED_SPECIALIZATION_BUG)
279 template <class _Tp
> struct _UnQual
{ typedef _Tp _Type
; };
280 template <class _Tp
> struct _UnQual
<const _Tp
> { typedef _Tp _Type
; };
281 template <class _Tp
> struct _UnQual
<volatile _Tp
> { typedef _Tp _Type
; };
282 template <class _Tp
> struct _UnQual
<const volatile _Tp
> { typedef _Tp _Type
; };
286 /* This struct is intended to say if a pointer can be convertible to an other
287 * taking into account cv qualifications. It shouldn't be instanciated with
288 * something else than pointer type as it uses pass by value parameter that
289 * results in compilation error when parameter type has a special memory
292 template <class _Src
, class _Dst
>
293 struct _IsCVConvertible
{
294 # if !defined (__BORLANDC__) || (__BORLANDC__ >= 0x590)
295 typedef _ConversionHelper
<_Src
, _Dst
> _H
;
296 enum { value
= (sizeof(char) == sizeof(_H::_Test(false, _H::_MakeSource()))) };
298 enum { _Is1
= __type2bool
<_IsConst
<_Src
>::_Ret
>::_Ret
};
299 enum { _Is2
= _IsConvertible
<_UnConstPtr
<_Src
>::_Type
, _UnConstPtr
<_Dst
>::_Type
>::value
};
300 enum { value
= _Is1
? 0 : _Is2
};
302 typedef typename __bool2type
<value
>::_Ret _Ret
;
306 template <class _Src
, class _Dst
>
307 struct _IsConvertible
{
309 typedef __false_type _Ret
;
312 template <class _Src
, class _Dst
>
313 struct _IsCVConvertible
{
315 typedef __false_type _Ret
;
321 #endif /* _STLP_TYPE_MANIPS_H */