1
2
3
4
5
6 """
7 defines few algorithms, that deals with different properties of std containers
8 """
9
10 import types
11 import string
12 import calldef
13 import cpptypes
14 import namespace
15 import templates
16 import type_traits
17 import class_declaration
18
19 std_namespaces = ( 'std', 'stdext', '__gnu_cxx' )
22 @staticmethod
24 return type_str.replace( ' ', '' )
25
26 @staticmethod
28 strings = {
29 'std::string' : ( 'std::basic_string<char,std::char_traits<char>,std::allocator<char> >'
30 , 'std::basic_string<char, std::char_traits<char>, std::allocator<char> >' )
31 , 'std::wstring' : ( 'std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >'
32 , 'std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >' ) }
33
34 new_name = cls_name
35 for short_name, long_names in strings.iteritems():
36 for lname in long_names:
37 new_name = new_name.replace( lname, short_name )
38 return new_name
39
41 @staticmethod
43 has_text = cls_name.startswith( text )
44 if has_text:
45 cls_name = cls_name[ len( text ): ]
46 answer = doit( cls_name )
47 if has_text:
48 answer = text + answer
49 return answer
50
51 @staticmethod
53 has_text = cls_name.endswith( text )
54 if has_text:
55 cls_name = cls_name[: len( text )]
56 answer = doit( cls_name )
57 if has_text:
58 answer = answer + text
59 return answer
60
61 @staticmethod
68
69 @staticmethod
71 ri = defaults_eraser.recursive_impl
72 no_std = lambda cls_name: ri.decorated_call_prefix( cls_name, 'std::', ri.erase_call )
73 no_stdext = lambda cls_name: ri.decorated_call_prefix( cls_name, 'stdext::', no_std )
74 no_gnustd = lambda cls_name: ri.decorated_call_prefix( cls_name, '__gnu_cxx::', no_stdext )
75 no_const = lambda cls_name: ri.decorated_call_prefix( cls_name, 'const ', no_gnustd )
76 no_end_const = lambda cls_name: ri.decorated_call_suffix( cls_name, ' const', no_const )
77 return no_end_const( cls_name )
78
79 @staticmethod
82
83 @staticmethod
94
95 @staticmethod
107
108 @staticmethod
124
125 @staticmethod
139
140 @staticmethod
142 cls_name = defaults_eraser.replace_basic_string( cls_name )
143 c_name, c_args = templates.split( cls_name )
144 if 4 != len( c_args ):
145 return
146 key_type = c_args[0]
147 mapped_type = c_args[1]
148 tmpls = [
149 string.Template( "$container< $key_type, $mapped_type, $compare<$key_type>, $allocator< std::pair< const $key_type, $mapped_type> > >" )
150 , string.Template( "$container< $key_type, $mapped_type, $compare<$key_type>, $allocator< std::pair< $key_type const, $mapped_type> > >" )
151 , string.Template( "$container< $key_type, $mapped_type, $compare<$key_type>, $allocator< std::pair< $key_type, $mapped_type> > >" )]
152 for tmpl in tmpls:
153 tmpl = tmpl.substitute( container=c_name
154 , key_type=key_type
155 , mapped_type=mapped_type
156 , compare=default_compare
157 , allocator=default_allocator )
158 if defaults_eraser.normalize( cls_name ) == defaults_eraser.normalize( tmpl ):
159 return templates.join( c_name
160 , [ defaults_eraser.erase_recursive( key_type )
161 , defaults_eraser.erase_recursive( mapped_type )] )
162
163
164 @staticmethod
166 cls_name = defaults_eraser.replace_basic_string( cls_name )
167 c_name, c_args = templates.split( cls_name )
168 if len( c_args ) < 3:
169 return
170
171 default_hash=None
172 default_less='std::less'
173 default_equal_to='std::equal_to'
174 default_allocator='std::allocator'
175
176 tmpl = None
177 if 3 == len( c_args ):
178 default_hash='hash_compare'
179 tmpl = "$container< $value_type, $hash<$value_type, $less<$value_type> >, $allocator<$value_type> >"
180 elif 4 == len( c_args ):
181 default_hash='hash'
182 tmpl = "$container< $value_type, $hash<$value_type >, $equal_to<$value_type >, $allocator<$value_type> >"
183 else:
184 return
185
186 value_type = c_args[0]
187 tmpl = string.Template( tmpl )
188 for ns in std_namespaces:
189 inst = tmpl.substitute( container=c_name
190 , value_type=value_type
191 , hash= ns + '::' + default_hash
192 , less=default_less
193 , equal_to=default_equal_to
194 , allocator=default_allocator )
195 if defaults_eraser.normalize( cls_name ) == defaults_eraser.normalize( inst ):
196 return templates.join( c_name, [defaults_eraser.erase_recursive( value_type )] )
197
198
199 @staticmethod
201 cls_name = defaults_eraser.replace_basic_string( cls_name )
202 c_name, c_args = templates.split( cls_name )
203
204 default_hash=None
205 default_less='std::less'
206 default_allocator='std::allocator'
207 default_equal_to = 'std::equal_to'
208
209 tmpl = None
210 key_type = None
211 mapped_type = None
212 if 2 < len( c_args ):
213 key_type = c_args[0]
214 mapped_type = c_args[1]
215 else:
216 return
217
218 if 4 == len( c_args ):
219 default_hash = 'hash_compare'
220 tmpl = string.Template( "$container< $key_type, $mapped_type, $hash<$key_type, $less<$key_type> >, $allocator< std::pair< const $key_type, $mapped_type> > >" )
221 if key_type.startswith( 'const ' ) or key_type.endswith( ' const' ):
222 tmpl = string.Template( "$container< $key_type, $mapped_type, $hash<$key_type, $less<$key_type> >, $allocator< std::pair< $key_type, $mapped_type> > >" )
223 elif 5 == len( c_args ):
224 default_hash = 'hash'
225 tmpl = string.Template( "$container< $key_type, $mapped_type, $hash<$key_type >, $equal_to<$key_type>, $allocator< $mapped_type> >" )
226 if key_type.startswith( 'const ' ) or key_type.endswith( ' const' ):
227 tmpl = string.Template( "$container< $key_type, $mapped_type, $hash<$key_type >, $equal_to<$key_type>, $allocator< $mapped_type > >" )
228 else:
229 return
230
231 for ns in std_namespaces:
232 inst = tmpl.substitute( container=c_name
233 , key_type=key_type
234 , mapped_type=mapped_type
235 , hash=ns + '::' + default_hash
236 , less=default_less
237 , equal_to = default_equal_to
238 , allocator=default_allocator )
239 if defaults_eraser.normalize( cls_name ) == defaults_eraser.normalize( inst ):
240 return templates.join( c_name
241 , [ defaults_eraser.erase_recursive( key_type )
242 , defaults_eraser.erase_recursive( mapped_type )] )
243
246 """this class implements the functionality needed for convinient work with
247 STD container classes.
248
249 Implemented functionality:
250 - find out whether a declaration is STD container or not
251 - find out container value( mapped ) type
252
253 This class tries to be useful as much, as possible. For example, for class
254 declaration( and not definition ) it parsers the class name in order to
255 extract all the information.
256 """
257 - def __init__( self
258 , container_name
259 , element_type_index
260 , element_type_typedef
261 , defaults_remover
262 , key_type_index=None
263 , key_type_typedef=None ):
264 """
265 container_name - std container name
266 element_type_index - position of value\\mapped type within template
267 arguments list
268 element_type_typedef - class typedef to the value\\mapped type
269 key_type_index - position of key type within template arguments list
270 key_type_typedef - class typedef to the key type
271 """
272 self._name = container_name
273 self.remove_defaults_impl = defaults_remover
274 self.element_type_index = element_type_index
275 self.element_type_typedef = element_type_typedef
276 self.key_type_index = key_type_index
277 self.key_type_typedef = key_type_typedef
278
281