Package pygccxml :: Package declarations :: Module type_traits

Source Code for Module pygccxml.declarations.type_traits

   1  # Copyright 2004 Roman Yakovenko. 
   2  # Distributed under the Boost Software License, Version 1.0. (See 
   3  # accompanying file LICENSE_1_0.txt or copy at 
   4  # http://www.boost.org/LICENSE_1_0.txt) 
   5   
   6  """ 
   7  defines few algorithms, that deals with different properties of C++ types 
   8   
   9  Do you aware of boost::type_traits library? pygccxml has functionality similar to 
  10  it. Using functions defined in this module you can 
  11      - find out some properties of the type 
  12      - modify type 
  13   
  14  Those functions are very valuable for code generation. Almost all functions 
  15  within this module works on L{type_t} class hierarchy and\\or L{class_t}. 
  16  """ 
  17   
  18  import os 
  19  import types 
  20  import matchers 
  21  import typedef 
  22  import calldef 
  23  import cpptypes 
  24  import variable 
  25  import algorithm 
  26  import namespace 
  27  import templates 
  28  import enumeration 
  29  import class_declaration 
  30  from pygccxml import utils 
  31  import types as build_in_types 
32 33 -def __remove_alias(type_):
34 """implementation details""" 35 if isinstance( type_, typedef.typedef_t ): 36 return __remove_alias( type_.type ) 37 if isinstance( type_, cpptypes.declarated_t ) and isinstance( type_.declaration, typedef.typedef_t ): 38 return __remove_alias( type_.declaration.type ) 39 if isinstance( type_, cpptypes.compound_t ): 40 type_.base = __remove_alias( type_.base ) 41 return type_ 42 return type_
43
44 -def remove_alias(type_):
45 """returns type without typedefs""" 46 type_ref = None 47 if isinstance( type_, cpptypes.type_t ): 48 type_ref = type_ 49 elif isinstance( type_, typedef.typedef_t ): 50 type_ref = type_.type 51 else: 52 pass #not a valid input, just return it 53 if not type_ref: 54 return type_ 55 if type_ref.cache.remove_alias: 56 return type_ref.cache.remove_alias 57 no_alias = __remove_alias( type_ref.clone() ) 58 type_ref.cache.remove_alias = no_alias 59 return no_alias
60
61 -def create_cv_types( base ):
62 """implementation details""" 63 return [ base 64 , cpptypes.const_t( base ) 65 , cpptypes.volatile_t( base ) 66 , cpptypes.volatile_t( cpptypes.const_t( base ) ) ]
67
68 -def decompose_type(tp):
69 """implementation details""" 70 #implementation of this function is important 71 if isinstance( tp, cpptypes.compound_t ): 72 return [tp] + decompose_type( tp.base ) 73 elif isinstance( tp, typedef.typedef_t ): 74 return decompose_type( tp.type ) 75 elif isinstance( tp, cpptypes.declarated_t ) and isinstance( tp.declaration, typedef.typedef_t ): 76 return decompose_type( tp.declaration.type ) 77 else: 78 return [tp]
79
80 -def decompose_class(type):
81 """implementation details""" 82 types = decompose_type( type ) 83 return [ tp.__class__ for tp in types ]
84
85 -def base_type(type):
86 """returns base type. 87 88 For C{const int} will return C{int} 89 """ 90 types = decompose_type( type ) 91 return types[-1]
92
93 -def does_match_definition(given, main, secondary ):
94 """implementation details""" 95 assert isinstance( secondary, build_in_types.TupleType ) 96 assert 2 == len( secondary ) #general solution could be provided 97 types = decompose_type( given ) 98 if isinstance( types[0], main ): 99 return True 100 elif 2 <= len( types ) and \ 101 ( ( isinstance( types[0], main ) and isinstance( types[1], secondary ) ) \ 102 or ( isinstance( types[1], main ) and isinstance( types[0], secondary ) ) ): 103 return True 104 elif 3 <= len( types ): 105 classes = set( [tp.__class__ for tp in types[:3]] ) 106 desired = set( [main] + list( secondary ) ) 107 return classes == desired 108 else: 109 return False
110
111 -def is_bool( type_ ):
112 """returns True, if type represents C{bool}, False otherwise""" 113 return remove_alias( type_ ) in create_cv_types( cpptypes.bool_t() )
114
115 -def is_void( type ):
116 """returns True, if type represents C{void}, False otherwise""" 117 return remove_alias( type ) in create_cv_types( cpptypes.void_t() )
118
119 -def is_void_pointer( type ):
120 """returns True, if type represents C{void*}, False otherwise""" 121 return is_same( type, cpptypes.pointer_t( cpptypes.void_t() ) )
122
123 -def is_integral( type ):
124 """returns True, if type represents C++ integral type, False otherwise""" 125 integral_def = create_cv_types( cpptypes.char_t() ) \ 126 + create_cv_types( cpptypes.unsigned_char_t() ) \ 127 + create_cv_types( cpptypes.signed_char_t() ) \ 128 + create_cv_types( cpptypes.wchar_t() ) \ 129 + create_cv_types( cpptypes.short_int_t() ) \ 130 + create_cv_types( cpptypes.short_unsigned_int_t() ) \ 131 + create_cv_types( cpptypes.bool_t() ) \ 132 + create_cv_types( cpptypes.int_t() ) \ 133 + create_cv_types( cpptypes.unsigned_int_t() ) \ 134 + create_cv_types( cpptypes.long_int_t() ) \ 135 + create_cv_types( cpptypes.long_unsigned_int_t() ) \ 136 + create_cv_types( cpptypes.long_long_int_t() ) \ 137 + create_cv_types( cpptypes.long_long_unsigned_int_t() ) 138 139 return remove_alias( type ) in integral_def
140
141 -def is_floating_point( type ):
142 """returns True, if type represents C++ floating point type, False otherwise""" 143 float_def = create_cv_types( cpptypes.float_t() ) \ 144 + create_cv_types( cpptypes.double_t() ) \ 145 + create_cv_types( cpptypes.long_double_t() ) 146 147 return remove_alias( type ) in float_def
148
149 -def is_arithmetic( type ):
150 """returns True, if type represents C++ integral or floating point type, False otherwise""" 151 return is_integral( type ) or is_floating_point( type )
152
153 -def is_pointer(type):
154 """returns True, if type represents C++ pointer type, False otherwise""" 155 return does_match_definition( type 156 , cpptypes.pointer_t 157 , (cpptypes.const_t, cpptypes.volatile_t) )
158
159 -def is_calldef_pointer(type):
160 """returns True, if type represents pointer to free/member function, False otherwise""" 161 if not is_pointer(type): 162 return False 163 nake_type = remove_alias( type ) 164 nake_type = remove_const( nake_type ) 165 nake_type = remove_volatile( nake_type ) 166 return isinstance( nake_type, cpptypes.compound_t ) \ 167 and isinstance( nake_type.base, cpptypes.calldef_type_t )
168
169 -def remove_pointer(type):
170 """removes pointer from the type definition 171 172 If type is not pointer type, it will be returned as is. 173 """ 174 nake_type = remove_alias( type ) 175 if not is_pointer( nake_type ): 176 return type 177 elif isinstance( nake_type, cpptypes.volatile_t ) and isinstance( nake_type.base, cpptypes.pointer_t ): 178 return cpptypes.volatile_t( nake_type.base.base ) 179 elif isinstance( nake_type, cpptypes.const_t ) and isinstance( nake_type.base, cpptypes.pointer_t ): 180 return cpptypes.const_t( nake_type.base.base ) 181 elif isinstance( nake_type.base, cpptypes.calldef_type_t ): 182 return type 183 else: 184 return nake_type.base
185
186 -def is_reference(type):
187 """returns True, if type represents C++ reference type, False otherwise""" 188 nake_type = remove_alias( type ) 189 return isinstance( nake_type, cpptypes.reference_t )
190
191 -def is_array(type):
192 """returns True, if type represents C++ array type, False otherwise""" 193 nake_type = remove_alias( type ) 194 nake_type = remove_reference( nake_type ) 195 nake_type = remove_cv( nake_type ) 196 return isinstance( nake_type, cpptypes.array_t )
197
198 -def array_size(type):
199 """returns array size""" 200 nake_type = remove_alias( type ) 201 nake_type = remove_reference( nake_type ) 202 nake_type = remove_cv( nake_type ) 203 assert isinstance( nake_type, cpptypes.array_t ) 204 return nake_type.size
205
206 -def array_item_type(type_):
207 """returns array item type""" 208 if is_array(type_): 209 type_ = remove_alias( type_ ) 210 type_ = remove_cv( type_ ) 211 return type_.base 212 elif is_pointer( type_ ): 213 return remove_pointer( type_ ) 214 else: 215 assert 0
216
217 -def remove_reference(type):
218 """removes reference from the type definition 219 220 If type is not reference type, it will be returned as is. 221 """ 222 nake_type = remove_alias( type ) 223 if not is_reference( nake_type ): 224 return type 225 else: 226 return nake_type.base
227
228 -def is_const(type):
229 """returns True, if type represents C++ const type, False otherwise""" 230 nake_type = remove_alias( type ) 231 return isinstance( nake_type, cpptypes.const_t )
232
233 -def remove_const(type):
234 """removes const from the type definition 235 236 If type is not const type, it will be returned as is 237 """ 238 239 nake_type = remove_alias( type ) 240 if not is_const( nake_type ): 241 return type 242 else: 243 return nake_type.base
244
245 -def remove_declarated( type ):
246 """removes type-declaration class-binder L{declarated_t} from the type 247 248 If type is not L{declarated_t}, it will be returned as is 249 """ 250 type = remove_alias( type ) 251 if isinstance( type, cpptypes.declarated_t ): 252 type = type.declaration 253 return type
254
255 -def is_same(type1, type2):
256 """returns True, if type1 and type2 are same types""" 257 nake_type1 = remove_declarated( type1 ) 258 nake_type2 = remove_declarated( type2 ) 259 return nake_type1 == nake_type2
260
261 -def is_volatile(type):
262 """returns True, if type represents C++ volatile type, False otherwise""" 263 nake_type = remove_alias( type