@@ -312,21 +312,54 @@ def class_declaration( self, type ):
312312 raise TypeError ( 'Type "%s" is not instantiation of std::%s' % ( type .decl_string , self .name () ) )
313313 return cls
314314
315+ def is_sequence ( self , type ):
316+ #raise exception if type is not container
317+ unused = self .class_declaration ( type )
318+ return self .key_type_index is None
319+
320+ def is_mapping ( self , type ):
321+ return not self .is_sequence ( type )
322+
323+ def __find_xxx_type ( self , type , xxx_index , xxx_typedef , cache_property_name ):
324+ cls = self .class_declaration ( type )
325+ result = getattr ( cls .cache , cache_property_name )
326+ if not result :
327+ if isinstance ( cls , class_declaration .class_t ):
328+ xxx_type = cls .typedef ( xxx_typedef , recursive = False ).type
329+ result = type_traits .remove_declarated ( xxx_type )
330+ else :
331+ xxx_type_str = templates .args ( cls .name )[xxx_index ]
332+ result = type_traits .impl_details .find_value_type ( cls .top_parent , xxx_type_str )
333+ if None is result :
334+ raise RuntimeError ( "Unable to find out %s '%s' key\\ value type."
335+ % ( self .name (), cls .decl_string ) )
336+ setattr ( cls .cache , cache_property_name , result )
337+ return result
338+
315339 def element_type ( self , type ):
316340 """returns reference to the class value\\ mapped type declaration"""
317- cls = self .class_declaration ( type )
318- if isinstance ( cls , class_declaration .class_t ):
319- value_type = cls .typedef ( self .element_type_typedef , recursive = False ).type
320- return type_traits .remove_declarated ( value_type )
321- else :
322- value_type_str = templates .args ( cls .name )[self .element_type_index ]
323- ref = type_traits .impl_details .find_value_type ( cls .top_parent , value_type_str )
324- if None is ref :
325- raise RuntimeError ( "Unable to find out %s '%s' value type."
326- % ( self .name (), cls .decl_string ) )
327- return ref
341+ return self .__find_xxx_type ( type
342+ , self .element_type_index
343+ , self .element_type_typedef
344+ , 'container_element_type' )
345+
346+ def key_type ( self , type ):
347+ """returns reference to the class key type declaration"""
348+ if not self .is_mapping ( type ):
349+ raise TypeError ( 'Type "%s" is not "mapping" container' % str ( type ) )
350+ return self .__find_xxx_type ( type
351+ , self .key_type_index
352+ , self .key_type_typedef
353+ , 'container_key_type' )
328354
329355 def remove_defaults ( self , type_or_string ):
356+ """remove template defaults from a template class instantiation
357+
358+ For example:
359+ std::vector< int, std::allocator< int > >
360+ will become
361+ std::vector< int >
362+ """
330363 name = type_or_string
331364 if not isinstance ( type_or_string , types .StringTypes ):
332365 name = self .class_declaration ( type_or_string ).name
@@ -338,29 +371,86 @@ def remove_defaults( self, type_or_string ):
338371 else :
339372 return no_defaults
340373
341- list_traits = container_traits_impl_t ( 'list' , 0 , 'value_type' , defaults_eraser .erase_allocator )
342-
343- deque_traits = container_traits_impl_t ( 'deque' , 0 , 'value_type' , defaults_eraser .erase_allocator )
344-
345- queue_traits = container_traits_impl_t ( 'queue' , 0 , 'value_type' , defaults_eraser .erase_container )
346-
347- priority_queue_traits = container_traits_impl_t ( 'priority_queue' , 0 , 'value_type' , defaults_eraser .erase_container_compare )
348-
349- vector_traits = container_traits_impl_t ( 'vector' , 0 , 'value_type' , defaults_eraser .erase_allocator )
350-
351- stack_traits = container_traits_impl_t ( 'stack' , 0 , 'value_type' , defaults_eraser .erase_container )
352-
353- map_traits = container_traits_impl_t ( 'map' , 1 , 'mapped_type' , defaults_eraser .erase_map_compare_allocator )
354- multimap_traits = container_traits_impl_t ( 'multimap' , 1 , 'mapped_type' , defaults_eraser .erase_map_compare_allocator )
355-
356- hash_map_traits = container_traits_impl_t ( 'hash_map' , 1 , 'mapped_type' , defaults_eraser .erase_hashmap_compare_allocator )
357- hash_multimap_traits = container_traits_impl_t ( 'hash_multimap' , 1 , 'mapped_type' , defaults_eraser .erase_hashmap_compare_allocator )
358-
359- set_traits = container_traits_impl_t ( 'set' , 0 , 'value_type' , defaults_eraser .erase_compare_allocator )
360- multiset_traits = container_traits_impl_t ( 'multiset' , 0 , 'value_type' , defaults_eraser .erase_compare_allocator )
361-
362- hash_set_traits = container_traits_impl_t ( 'hash_set' , 0 , 'value_type' , defaults_eraser .erase_hash_allocator )
363- hash_multiset_traits = container_traits_impl_t ( 'hash_multiset' , 0 , 'value_type' , defaults_eraser .erase_hash_allocator )
374+ create_traits = container_traits_impl_t
375+ list_traits = create_traits ( 'list'
376+ , 0
377+ , 'value_type'
378+ , defaults_eraser .erase_allocator )
379+
380+ deque_traits = create_traits ( 'deque'
381+ , 0
382+ , 'value_type'
383+ , defaults_eraser .erase_allocator )
384+
385+ queue_traits = create_traits ( 'queue'
386+ , 0
387+ , 'value_type'
388+ , defaults_eraser .erase_container )
389+
390+ priority_queue_traits = create_traits ( 'priority_queue'
391+ , 0
392+ , 'value_type'
393+ , defaults_eraser .erase_container_compare )
394+
395+ vector_traits = create_traits ( 'vector'
396+ , 0
397+ , 'value_type'
398+ , defaults_eraser .erase_allocator )
399+
400+ stack_traits = create_traits ( 'stack'
401+ , 0
402+ , 'value_type'
403+ , defaults_eraser .erase_container )
404+
405+ map_traits = create_traits ( 'map'
406+ , 1
407+ , 'mapped_type'
408+ , defaults_eraser .erase_map_compare_allocator
409+ , key_type_index = 0
410+ , key_type_typedef = 'key_type' )
411+
412+ multimap_traits = create_traits ( 'multimap'
413+ , 1
414+ , 'mapped_type'
415+ , defaults_eraser .erase_map_compare_allocator
416+ , key_type_index = 0
417+ , key_type_typedef = 'key_type' )
418+
419+
420+ hash_map_traits = create_traits ( 'hash_map'
421+ , 1
422+ , 'mapped_type'
423+ , defaults_eraser .erase_hashmap_compare_allocator
424+ , key_type_index = 0
425+ , key_type_typedef = 'key_type' )
426+
427+
428+ hash_multimap_traits = create_traits ( 'hash_multimap'
429+ , 1
430+ , 'mapped_type'
431+ , defaults_eraser .erase_hashmap_compare_allocator
432+ , key_type_index = 0
433+ , key_type_typedef = 'key_type' )
434+
435+ set_traits = create_traits ( 'set'
436+ , 0
437+ , 'value_type'
438+ , defaults_eraser .erase_compare_allocator )
439+
440+ multiset_traits = create_traits ( 'multiset'
441+ , 0
442+ , 'value_type'
443+ , defaults_eraser .erase_compare_allocator )
444+
445+ hash_set_traits = create_traits ( 'hash_set'
446+ , 0
447+ , 'value_type'
448+ , defaults_eraser .erase_hash_allocator )
449+
450+ hash_multiset_traits = create_traits ( 'hash_multiset'
451+ , 0
452+ , 'value_type'
453+ , defaults_eraser .erase_hash_allocator )
364454
365455container_traits = (
366456 list_traits
0 commit comments