/home/ntakagi/work/STLport-5.1.5/stlport/stl/type_manips.h

Go to the documentation of this file.
00001 /*
00002  *
00003  * Copyright (c) 2003
00004  * François Dumont
00005  *
00006  * This material is provided "as is", with absolutely no warranty expressed
00007  * or implied. Any use is at your own risk.
00008  *
00009  * Permission to use or copy this software for any purpose is hereby granted
00010  * without fee, provided the above notices are retained on all copies.
00011  * Permission to modify the code and to distribute modified code is granted,
00012  * provided the above notices are retained, and a notice that the code was
00013  * modified is included with the above copyright notice.
00014  *
00015  */
00016 
00017 
00018 #ifndef _STLP_TYPE_MANIPS_H
00019 #define _STLP_TYPE_MANIPS_H
00020 
00021 _STLP_BEGIN_NAMESPACE
00022 
00023 struct __true_type {};
00024 struct __false_type {};
00025 
00026 #if defined (_STLP_USE_NAMESPACES)
00027 _STLP_MOVE_TO_PRIV_NAMESPACE
00028 using _STLP_STD::__true_type;
00029 using _STLP_STD::__false_type;
00030 _STLP_MOVE_TO_STD_NAMESPACE
00031 #endif
00032 
00033 //bool to type
00034 template <int _Is>
00035 struct __bool2type
00036 { typedef __true_type _Ret; };
00037 
00038 _STLP_TEMPLATE_NULL
00039 struct __bool2type<1> { typedef __true_type _Ret; };
00040 
00041 _STLP_TEMPLATE_NULL
00042 struct __bool2type<0> { typedef __false_type _Ret; };
00043 
00044 //type to bool
00045 template <class __bool_type>
00046 struct __type2bool { enum {_Ret = 1}; };
00047 
00048 _STLP_TEMPLATE_NULL
00049 struct __type2bool<__true_type> { enum {_Ret = 1}; };
00050 
00051 _STLP_TEMPLATE_NULL
00052 struct __type2bool<__false_type> { enum {_Ret = 0}; };
00053 
00054 //Negation
00055 template <class _BoolType>
00056 struct _Not { typedef __false_type _Ret; };
00057 
00058 _STLP_TEMPLATE_NULL
00059 struct _Not<__false_type> { typedef __true_type _Ret; };
00060 
00061 // logical and of 2 predicated
00062 template <class _P1, class _P2>
00063 struct _Land2 { typedef __false_type _Ret; };
00064 
00065 _STLP_TEMPLATE_NULL
00066 struct _Land2<__true_type, __true_type> { typedef __true_type _Ret; };
00067 
00068 // logical and of 3 predicated
00069 template <class _P1, class _P2, class _P3>
00070 struct _Land3 { typedef __false_type _Ret; };
00071 
00072 _STLP_TEMPLATE_NULL
00073 struct _Land3<__true_type, __true_type, __true_type> { typedef __true_type _Ret; };
00074 
00075 //logical or of 2 predicated
00076 template <class _P1, class _P2>
00077 struct _Lor2 { typedef __true_type _Ret; };
00078 
00079 _STLP_TEMPLATE_NULL
00080 struct _Lor2<__false_type, __false_type> { typedef __false_type _Ret; };
00081 
00082 // logical or of 3 predicated
00083 template <class _P1, class _P2, class _P3>
00084 struct _Lor3 { typedef __true_type _Ret; };
00085 
00086 _STLP_TEMPLATE_NULL
00087 struct _Lor3<__false_type, __false_type, __false_type> { typedef __false_type _Ret; };
00088 
00090 // class template __select
00091 // Selects one of two types based upon a boolean constant
00092 // Invocation: __select<_Cond, T, U>::Result
00093 // where:
00094 // flag is a compile-time boolean constant
00095 // T and U are types
00096 // Result evaluates to T if flag is true, and to U otherwise.
00098 // BEWARE: If the compiler do not support partial template specialization or nested template
00099 //classes the default behavior of the __select is to consider the condition as false and so return
00100 //the second template type!!
00101 
00102 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
00103 template <bool _Cond, class _Tp1, class _Tp2>
00104 struct __select { typedef _Tp1 _Ret; };
00105 
00106 template <class _Tp1, class _Tp2>
00107 struct __select<false, _Tp1, _Tp2> { typedef _Tp2 _Ret; };
00108 
00109 #  if defined (__BORLANDC__)
00110 template <class _CondT, class _Tp1, class _Tp2>
00111 struct __selectT { typedef _Tp1 _Ret; };
00112 
00113 template <class _Tp1, class _Tp2>
00114 struct __selectT<__false_type, _Tp1, _Tp2> { typedef _Tp2 _Ret; };
00115 #  endif
00116 
00117 #else /* _STLP_CLASS_PARTIAL_SPECIALIZATION */
00118 
00119 #  if defined (_STLP_MEMBER_TEMPLATE_CLASSES)
00120 template <int _Cond>
00121 struct __select_aux {
00122   template <class _Tp1, class _Tp2>
00123   struct _In {
00124     typedef _Tp1 _Ret;
00125   };
00126 };
00127 
00128 _STLP_TEMPLATE_NULL
00129 struct __select_aux<0> {
00130   template <class _Tp1, class _Tp2>
00131   struct _In {
00132     typedef _Tp2 _Ret;
00133   };
00134 };
00135 
00136 template <int _Cond, class _Tp1, class _Tp2>
00137 struct __select {
00138   typedef typename __select_aux<_Cond>::_STLP_TEMPLATE _In<_Tp1, _Tp2>::_Ret _Ret;
00139 };
00140 #  else /* _STLP_MEMBER_TEMPLATE_CLASSES */
00141 //default behavior
00142 template <int _Cond, class _Tp1, class _Tp2>
00143 struct __select {
00144   typedef _Tp2 _Ret;
00145 };
00146 #  endif /* _STLP_MEMBER_TEMPLATE_CLASSES */
00147 
00148 #endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */
00149 
00150 #if defined (_STLP_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS)
00151 // Boris : simulation technique is used here according to Adobe Open Source License Version 1.0.
00152 // Copyright 2000 Adobe Systems Incorporated and others. All rights reserved.
00153 // Authors: Mat Marcus and Jesse Jones
00154 // The original version of this source code may be found at
00155 // http://opensource.adobe.com.
00156 
00157 // These are the discriminating functions
00158 template <class _Tp>
00159 char _STLP_CALL _IsSameFun(bool, _Tp const volatile*, _Tp const volatile*); // no implementation is required
00160 char* _STLP_CALL _IsSameFun(bool, ...);       // no implementation is required
00161 
00162 template <class _Tp1, class _Tp2>
00163 struct _IsSame {
00164   static _Tp1* __null_rep1();
00165   static _Tp2* __null_rep2();
00166   enum { _Ret = (sizeof(_IsSameFun(false,__null_rep1(), __null_rep2())) == sizeof(char)) };
00167   typedef typename __bool2type<_Ret>::_Ret _RetT;
00168 };
00169 
00170 #else
00171 
00172 template <class _Tp1, class _Tp2>
00173 struct _IsSameAux {
00174   typedef __false_type _RetT;
00175   enum { _Ret = 0 };
00176 };
00177 
00178 template <class _Tp>
00179 struct _UnConstType { typedef _Tp _Type; };
00180 
00181 template <class _Tp>
00182 struct _UnVolatileType { typedef _Tp _Type; };
00183 
00184 template <class _Tp>
00185 struct _UnCVType {
00186   typedef typename _UnVolatileType<_Tp>::_Type _UnVType;
00187   typedef typename _UnConstType<_UnVType>::_Type _Type;
00188 };
00189 
00190 #  if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
00191 template <class _Tp>
00192 struct _IsSameAux<_Tp, _Tp> {
00193   typedef __true_type _RetT;
00194   enum { _Ret = 1 };
00195 };
00196 
00197 #    if !defined (_STLP_QUALIFIED_SPECIALIZATION_BUG)
00198 template <class _Tp>
00199 struct _UnConstType<const _Tp> { typedef _Tp _Type; };
00200 
00201 template <class _Tp>
00202 struct _UnVolatileType<volatile _Tp> { typedef _Tp _Type; };
00203 #    endif
00204 
00205 #    if defined(__BORLANDC__)
00206 template<class _Tp>
00207 struct _UnConstPtr { typedef _Tp _Type; };
00208 
00209 template<class _Tp>
00210 struct _UnConstPtr<_Tp*> { typedef _Tp _Type; };
00211 
00212 template<class _Tp>
00213 struct _UnConstPtr<const _Tp*> { typedef _Tp _Type; };
00214 #    endif
00215 #  endif
00216 
00217 template <class _Tp1, class _Tp2>
00218 struct _IsSame {
00219   typedef typename _UnCVType<_Tp1>::_Type _Type1;
00220   typedef typename _UnCVType<_Tp2>::_Type _Type2;
00221 
00222   typedef _IsSameAux<_Type1, _Type2> _Aux;
00223   enum { _Ret = _Aux::_Ret };
00224   typedef typename _Aux::_RetT _RetT;
00225 };
00226 #endif
00227 
00228 /*
00229  * The following struct will tell you if 2 types are the same, the limitations are:
00230  *  - it compares the types without the const or volatile qualifiers, int and const int
00231  *    will be considered as same for instance.
00232  *  - the previous remarks do not apply to pointer types, int* and int const* won't be
00233  *    considered as comparable. (int * and int *const are).
00234  */
00235 template <class _Tp1, class _Tp2>
00236 struct _AreSameUnCVTypes {
00237   enum { _Same = _IsSame<_Tp1, _Tp2>::_Ret };
00238   typedef typename _IsSame<_Tp1, _Tp2>::_RetT _Ret;
00239 };
00240 
00241 /* Rather than introducing a new macro for the following constrution we use
00242  * an existing one (_STLP_DONT_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS) that
00243  * is used for a similar feature.
00244  */
00245 #if !defined (_STLP_DONT_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS)
00246 template <class _Src, class _Dst>
00247 struct _ConversionHelper {
00248   static char _Test(bool, _Dst);
00249   static char* _Test(bool, ...);
00250   static _Src _MakeSource();
00251 };
00252 
00253 template <class _Src, class _Dst>
00254 struct _IsConvertible {
00255   typedef _ConversionHelper<_Src*, const volatile _Dst*> _H;
00256   enum { value = (sizeof(char) == sizeof(_H::_Test(false, _H::_MakeSource()))) };
00257   typedef typename __bool2type<value>::_Ret _Ret;
00258 };
00259 
00260 /* This struct is intended to say if a pointer can be convertible to an other
00261  * taking into account cv qualifications. It shouldn't be instanciated with
00262  * something else than pointer type as it uses pass by value parameter that
00263  * results in compilation error when parameter type has a special memory
00264  * alignment
00265  */
00266 template <class _Src, class _Dst>
00267 struct _IsCVConvertible {
00268 #if !defined (__BORLANDC__)
00269   typedef _ConversionHelper<_Src, _Dst> _H;
00270   enum { value = (sizeof(char) == sizeof(_H::_Test(false, _H::_MakeSource()))) };
00271 #else
00272   enum { _Is1 = __type2bool<_IsConst<_Src>::_Ret>::_Ret };
00273   enum { _Is2 = _IsConvertible<_UnConstPtr<_Src>::_Type, _UnConstPtr<_Dst>::_Type>::value };
00274   enum { value = _Is1 ? 0 : _Is2 };
00275 #endif
00276   typedef typename __bool2type<value>::_Ret _Ret;
00277 };
00278 
00279 #else
00280 template <class _Src, class _Dst>
00281 struct _IsConvertible {
00282   enum {value = 0};
00283   typedef __false_type _Ret;
00284 };
00285 #endif
00286 
00287 template <class _Tp>
00288 struct _IsConst { typedef __false_type _Ret; };
00289 
00290 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) && !defined (_STLP_QUALIFIED_SPECIALIZATION_BUG)
00291 template <class _Tp>
00292 struct _IsConst <const _Tp> { typedef __true_type _Ret; };
00293 #endif
00294 
00295 #  if defined(__BORLANDC__)
00296 template<class _Tp>
00297 struct _IsConst <const _Tp*> { typedef __true_type _Ret; };
00298 
00299 template<class _Tp>
00300 struct _IsConst <const volatile _Tp*> { typedef __true_type _Ret; };
00301 #  endif
00302 
00303 _STLP_END_NAMESPACE
00304 
00305 #endif /* _STLP_TYPE_MANIPS_H */



Generated on Mon Mar 10 15:32:46 2008 by  doxygen 1.5.1