| Home | Trees | Indices | Help |
|
|---|
|
|
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
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
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
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
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
81 """implementation details"""
82 types = decompose_type( type )
83 return [ tp.__class__ for tp in types ]
84
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
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
112 """returns True, if type represents C{bool}, False otherwise"""
113 return remove_alias( type_ ) in create_cv_types( cpptypes.bool_t() )
114
116 """returns True, if type represents C{void}, False otherwise"""
117 return remove_alias( type ) in create_cv_types( cpptypes.void_t() )
118
120 """returns True, if type represents C{void*}, False otherwise"""
121 return is_same( type, cpptypes.pointer_t( cpptypes.void_t() ) )
122
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
262 """returns True, if type represents C++ volatile type, False otherwise"""
263 nake_type = remove_alias( type