| /* |
| * |
| * Copyright (c) 2003 |
| * François Dumont |
| * |
| * This material is provided "as is", with absolutely no warranty expressed |
| * or implied. Any use is at your own risk. |
| * |
| * Permission to use or copy this software for any purpose is hereby granted |
| * without fee, provided the above notices are retained on all copies. |
| * Permission to modify the code and to distribute modified code is granted, |
| * provided the above notices are retained, and a notice that the code was |
| * modified is included with the above copyright notice. |
| * |
| */ |
| |
| |
| #ifndef _STLP_TYPE_MANIPS_H |
| #define _STLP_TYPE_MANIPS_H |
| |
| _STLP_BEGIN_NAMESPACE |
| |
| struct __true_type {}; |
| struct __false_type {}; |
| |
| #if defined (_STLP_USE_NAMESPACES) |
| _STLP_MOVE_TO_PRIV_NAMESPACE |
| using _STLP_STD::__true_type; |
| using _STLP_STD::__false_type; |
| _STLP_MOVE_TO_STD_NAMESPACE |
| #endif |
| |
| //bool to type |
| template <int _Is> |
| struct __bool2type |
| { typedef __true_type _Ret; }; |
| |
| _STLP_TEMPLATE_NULL |
| struct __bool2type<1> { typedef __true_type _Ret; }; |
| |
| _STLP_TEMPLATE_NULL |
| struct __bool2type<0> { typedef __false_type _Ret; }; |
| |
| //type to bool |
| template <class __bool_type> |
| struct __type2bool { enum {_Ret = 1}; }; |
| |
| _STLP_TEMPLATE_NULL |
| struct __type2bool<__true_type> { enum {_Ret = 1}; }; |
| |
| _STLP_TEMPLATE_NULL |
| struct __type2bool<__false_type> { enum {_Ret = 0}; }; |
| |
| //Negation |
| template <class _BoolType> |
| struct _Not { typedef __false_type _Ret; }; |
| |
| _STLP_TEMPLATE_NULL |
| struct _Not<__false_type> { typedef __true_type _Ret; }; |
| |
| // logical and of 2 predicated |
| template <class _P1, class _P2> |
| struct _Land2 { typedef __false_type _Ret; }; |
| |
| _STLP_TEMPLATE_NULL |
| struct _Land2<__true_type, __true_type> { typedef __true_type _Ret; }; |
| |
| // logical and of 3 predicated |
| template <class _P1, class _P2, class _P3> |
| struct _Land3 { typedef __false_type _Ret; }; |
| |
| _STLP_TEMPLATE_NULL |
| struct _Land3<__true_type, __true_type, __true_type> { typedef __true_type _Ret; }; |
| |
| //logical or of 2 predicated |
| template <class _P1, class _P2> |
| struct _Lor2 { typedef __true_type _Ret; }; |
| |
| _STLP_TEMPLATE_NULL |
| struct _Lor2<__false_type, __false_type> { typedef __false_type _Ret; }; |
| |
| // logical or of 3 predicated |
| template <class _P1, class _P2, class _P3> |
| struct _Lor3 { typedef __true_type _Ret; }; |
| |
| _STLP_TEMPLATE_NULL |
| struct _Lor3<__false_type, __false_type, __false_type> { typedef __false_type _Ret; }; |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // class template __select |
| // Selects one of two types based upon a boolean constant |
| // Invocation: __select<_Cond, T, U>::Result |
| // where: |
| // flag is a compile-time boolean constant |
| // T and U are types |
| // Result evaluates to T if flag is true, and to U otherwise. |
| //////////////////////////////////////////////////////////////////////////////// |
| // BEWARE: If the compiler do not support partial template specialization or nested template |
| //classes the default behavior of the __select is to consider the condition as false and so return |
| //the second template type!! |
| |
| #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) |
| template <bool _Cond, class _Tp1, class _Tp2> |
| struct __select { typedef _Tp1 _Ret; }; |
| |
| template <class _Tp1, class _Tp2> |
| struct __select<false, _Tp1, _Tp2> { typedef _Tp2 _Ret; }; |
| |
| # if defined (__BORLANDC__) |
| template <class _CondT, class _Tp1, class _Tp2> |
| struct __selectT { typedef _Tp1 _Ret; }; |
| |
| template <class _Tp1, class _Tp2> |
| struct __selectT<__false_type, _Tp1, _Tp2> { typedef _Tp2 _Ret; }; |
| # endif |
| |
| #else /* _STLP_CLASS_PARTIAL_SPECIALIZATION */ |
| |
| # if defined (_STLP_MEMBER_TEMPLATE_CLASSES) |
| template <int _Cond> |
| struct __select_aux { |
| template <class _Tp1, class _Tp2> |
| struct _In { |
| typedef _Tp1 _Ret; |
| }; |
| }; |
| |
| _STLP_TEMPLATE_NULL |
| struct __select_aux<0> { |
| template <class _Tp1, class _Tp2> |
| struct _In { |
| typedef _Tp2 _Ret; |
| }; |
| }; |
| |
| template <int _Cond, class _Tp1, class _Tp2> |
| struct __select { |
| typedef typename __select_aux<_Cond>::_STLP_TEMPLATE _In<_Tp1, _Tp2>::_Ret _Ret; |
| }; |
| # else /* _STLP_MEMBER_TEMPLATE_CLASSES */ |
| //default behavior |
| template <int _Cond, class _Tp1, class _Tp2> |
| struct __select { |
| typedef _Tp2 _Ret; |
| }; |
| # endif /* _STLP_MEMBER_TEMPLATE_CLASSES */ |
| |
| #endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */ |
| |
| #if defined (_STLP_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS) |
| // Boris : simulation technique is used here according to Adobe Open Source License Version 1.0. |
| // Copyright 2000 Adobe Systems Incorporated and others. All rights reserved. |
| // Authors: Mat Marcus and Jesse Jones |
| // The original version of this source code may be found at |
| // http://opensource.adobe.com. |
| |
| // These are the discriminating functions |
| template <class _Tp> |
| char _STLP_CALL _IsSameFun(bool, _Tp const volatile*, _Tp const volatile*); // no implementation is required |
| char* _STLP_CALL _IsSameFun(bool, ...); // no implementation is required |
| |
| template <class _Tp1, class _Tp2> |
| struct _IsSame { |
| static _Tp1* __null_rep1(); |
| static _Tp2* __null_rep2(); |
| enum { _Ret = (sizeof(_IsSameFun(false,__null_rep1(), __null_rep2())) == sizeof(char)) }; |
| typedef typename __bool2type<_Ret>::_Ret _RetT; |
| }; |
| |
| #else |
| |
| template <class _Tp1, class _Tp2> |
| struct _IsSameAux { |
| typedef __false_type _RetT; |
| enum { _Ret = 0 }; |
| }; |
| |
| template <class _Tp> |
| struct _UnConstType { typedef _Tp _Type; }; |
| |
| template <class _Tp> |
| struct _UnVolatileType { typedef _Tp _Type; }; |
| |
| template <class _Tp> |
| struct _UnCVType { |
| typedef typename _UnVolatileType<_Tp>::_Type _UnVType; |
| typedef typename _UnConstType<_UnVType>::_Type _Type; |
| }; |
| |
| # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) |
| template <class _Tp> |
| struct _IsSameAux<_Tp, _Tp> { |
| typedef __true_type _RetT; |
| enum { _Ret = 1 }; |
| }; |
| |
| # if !defined (_STLP_QUALIFIED_SPECIALIZATION_BUG) |
| template <class _Tp> |
| struct _UnConstType<const _Tp> { typedef _Tp _Type; }; |
| |
| template <class _Tp> |
| struct _UnVolatileType<volatile _Tp> { typedef _Tp _Type; }; |
| # endif |
| |
| # if defined(__BORLANDC__) |
| template<class _Tp> |
| struct _UnConstPtr { typedef _Tp _Type; }; |
| |
| template<class _Tp> |
| struct _UnConstPtr<_Tp*> { typedef _Tp _Type; }; |
| |
| template<class _Tp> |
| struct _UnConstPtr<const _Tp*> { typedef _Tp _Type; }; |
| # endif |
| # endif |
| |
| template <class _Tp1, class _Tp2> |
| struct _IsSame { |
| typedef typename _UnCVType<_Tp1>::_Type _Type1; |
| typedef typename _UnCVType<_Tp2>::_Type _Type2; |
| |
| typedef _IsSameAux<_Type1, _Type2> _Aux; |
| enum { _Ret = _Aux::_Ret }; |
| typedef typename _Aux::_RetT _RetT; |
| }; |
| #endif |
| |
| /* |
| * The following struct will tell you if 2 types are the same, the limitations are: |
| * - it compares the types without the const or volatile qualifiers, int and const int |
| * will be considered as same for instance. |
| * - the previous remarks do not apply to pointer types, int* and int const* won't be |
| * considered as comparable. (int * and int *const are). |
| */ |
| template <class _Tp1, class _Tp2> |
| struct _AreSameUnCVTypes { |
| enum { _Same = _IsSame<_Tp1, _Tp2>::_Ret }; |
| typedef typename _IsSame<_Tp1, _Tp2>::_RetT _Ret; |
| }; |
| |
| /* Rather than introducing a new macro for the following constrution we use |
| * an existing one (_STLP_DONT_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS) that |
| * is used for a similar feature. |
| */ |
| #if !defined (_STLP_DONT_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS) |
| template <class _Src, class _Dst> |
| struct _ConversionHelper { |
| static char _Test(bool, _Dst); |
| static char* _Test(bool, ...); |
| static _Src _MakeSource(); |
| }; |
| |
| template <class _Src, class _Dst> |
| struct _IsConvertible { |
| typedef _ConversionHelper<_Src*, const volatile _Dst*> _H; |
| enum { value = (sizeof(char) == sizeof(_H::_Test(false, _H::_MakeSource()))) }; |
| typedef typename __bool2type<value>::_Ret _Ret; |
| }; |
| |
| /* This struct is intended to say if a pointer can be convertible to an other |
| * taking into account cv qualifications. It shouldn't be instanciated with |
| * something else than pointer type as it uses pass by value parameter that |
| * results in compilation error when parameter type has a special memory |
| * alignment |
| */ |
| template <class _Src, class _Dst> |
| struct _IsCVConvertible { |
| #if !defined (__BORLANDC__) |
| typedef _ConversionHelper<_Src, _Dst> _H; |
| enum { value = (sizeof(char) == sizeof(_H::_Test(false, _H::_MakeSource()))) }; |
| #else |
| enum { _Is1 = __type2bool<_IsConst<_Src>::_Ret>::_Ret }; |
| enum { _Is2 = _IsConvertible<_UnConstPtr<_Src>::_Type, _UnConstPtr<_Dst>::_Type>::value }; |
| enum { value = _Is1 ? 0 : _Is2 }; |
| #endif |
| typedef typename __bool2type<value>::_Ret _Ret; |
| }; |
| |
| #else |
| template <class _Src, class _Dst> |
| struct _IsConvertible { |
| enum {value = 0}; |
| typedef __false_type _Ret; |
| }; |
| #endif |
| |
| template <class _Tp> |
| struct _IsConst { typedef __false_type _Ret; }; |
| |
| #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) && !defined (_STLP_QUALIFIED_SPECIALIZATION_BUG) |
| template <class _Tp> |
| struct _IsConst <const _Tp> { typedef __true_type _Ret; }; |
| #endif |
| |
| # if defined(__BORLANDC__) |
| template<class _Tp> |
| struct _IsConst <const _Tp*> { typedef __true_type _Ret; }; |
| |
| template<class _Tp> |
| struct _IsConst <const volatile _Tp*> { typedef __true_type _Ret; }; |
| # endif |
| |
| _STLP_END_NAMESPACE |
| |
| #endif /* _STLP_TYPE_MANIPS_H */ |