def _get_no_init(self): if None is self._no_init and False == bool(self.indexing_suite): #select all public constructors and exclude copy constructor cs = self.constructors( lambda c: not declarations.is_copy_constructor( c) and c.access_type == 'public', recursive=False, allow_empty=True) has_suitable_constructor = bool(cs) if cs and len(cs) == 1 and declarations.is_trivial_constructor( cs[0]) and declarations.find_noncopyable_vars(self): has_suitable_constructor = False has_nonpublic_destructor = declarations.has_destructor( self ) \ and not declarations.has_public_destructor( self ) trivial_constructor = declarations.find_trivial_constructor(self) if has_nonpublic_destructor \ or ( self.is_abstract and not self.is_wrapper_needed() ) \ or not has_suitable_constructor: self._no_init = True elif not trivial_constructor or trivial_constructor.access_type != 'public': exportable_cs = [ c for c in cs if c.exportable and c.ignore == False ] if not exportable_cs: self._no_init = True else: pass if None is self._no_init: self._no_init = False return self._no_init
def _generate_noncopyable(self): noncopyable_vars = declarations.find_noncopyable_vars(self.declaration) copy_constr = declarations.find_copy_constructor(self.declaration) if self.declaration.noncopyable \ or copy_constr and copy_constr.is_artificial and noncopyable_vars: return algorithm.create_identifier( self, '::boost::noncopyable' )
def _generate_noncopyable(self): noncopyable_vars = declarations.find_noncopyable_vars(self.declaration) copy_constr = declarations.find_copy_constructor(self.declaration) if self.declaration.noncopyable \ or copy_constr and copy_constr.is_artificial and noncopyable_vars: return algorithm.create_identifier(self, '::boost::noncopyable')
def test(self): """ Test the find_noncopyable_vars function """ # The ptr1 variable in the holder struct can be copied, # but not the ptr2 variable holder = self.global_ns.class_("holder") nc_vars = declarations.find_noncopyable_vars(holder) self.assertEqual(len(nc_vars), 1) self.assertEqual(nc_vars[0].name, "ptr2") self.assertTrue(declarations.is_pointer(nc_vars[0].decl_type)) self.assertTrue(declarations.is_const(nc_vars[0].decl_type))
def visit_class(self): if self.curr_decl.indexing_suite: self.__types_db.update_containers(self.curr_decl) return #it will be exposed later, using other code creators self.__dependencies_manager.add_exported(self.curr_decl) cls_decl = self.curr_decl cls_parent_cc = self.curr_code_creator exportable_members = self.curr_decl.get_exportable_members( sort_algorithms.sort) wrapper = None cls_cc = None if cls_decl.introduces_new_scope: cls_cc = code_creators.class_t(class_inst=self.curr_decl) else: cls_cc = self.curr_code_creator if self.curr_decl.is_wrapper_needed(): wrapper = code_creators.class_wrapper_t(declaration=self.curr_decl, class_creator=cls_cc) cls_cc.wrapper = wrapper cls_cc.associated_decl_creators.append(wrapper) #insert wrapper before module body if isinstance(self.curr_decl.parent, declarations.class_t): #we deal with internal class self.curr_code_creator.wrapper.adopt_creator(wrapper) else: self.__extmodule.adopt_declaration_creator(wrapper) #next constructors are not present in code, but compiler generated #Boost.Python requiers them to be declared in the wrapper class noncopyable_vars = declarations.find_noncopyable_vars( self.curr_decl) copy_constr = declarations.find_copy_constructor(self.curr_decl) if not self.curr_decl.noncopyable and copy_constr and copy_constr.is_artificial: cccc = code_creators.copy_constructor_wrapper_t( constructor=copy_constr) wrapper.adopt_creator(cccc) trivial_constr = declarations.find_trivial_constructor( self.curr_decl) if trivial_constr and trivial_constr.is_artificial and not noncopyable_vars: tcons = code_creators.null_constructor_wrapper_t( constructor=trivial_constr) wrapper.adopt_creator(tcons) exposed = self.expose_overloaded_mem_fun_using_macro(cls_decl, cls_cc) if cls_decl.introduces_new_scope: cls_parent_cc.adopt_creator(cls_cc) self.curr_code_creator = cls_cc if cls_decl.expose_this: cls_cc.adopt_creator(code_creators.expose_this_t(cls_decl)) if cls_decl.expose_sizeof: cls_cc.adopt_creator(code_creators.expose_sizeof_t(cls_decl)) for declaration in exportable_members: if declaration in exposed: continue self.curr_decl = declaration declarations.apply_visitor(self, declaration) for redefined_func in cls_decl.redefined_funcs(): if isinstance(redefined_func, declarations.operator_t): continue self.curr_decl = redefined_func declarations.apply_visitor(self, redefined_func) #all static_methods_t should be moved to the end #better approach is to move them after last def of relevant function static_methods = [ creator for creator in cls_cc.creators if isinstance(creator, code_creators.static_method_t) ] for static_method in static_methods: cls_cc.remove_creator(static_method) cls_cc.adopt_creator(static_method) if cls_decl.exception_translation_code: translator = code_creators.exception_translator_t(cls_decl) self.__extmodule.adopt_declaration_creator(translator) cls_cc.associated_decl_creators.append(translator) translator_register \ = code_creators.exception_translator_register_t( cls_decl, translator ) cls_cc.adopt_creator(translator_register) for property_def in cls_decl.properties: cls_cc.adopt_creator(code_creators.property_t(property_def)) if wrapper and cls_decl.destructor_code: destructor = code_creators.destructor_wrapper_t(class_=cls_decl) wrapper.adopt_creator(destructor) for fc in cls_decl.fake_constructors: if self.__fc_manager.should_generate_code(fc): self.__dependencies_manager.add_exported(fc) cls_cc.adopt_creator(code_creators.make_constructor_t(fc)) self.curr_decl = cls_decl self.curr_code_creator = cls_parent_cc
def _get_no_init( self ): if None is self._no_init and False == bool( self.indexing_suite ): #select all public constructors and exclude copy constructor cs = self.constructors( lambda c: not declarations.is_copy_constructor(c) and c.access_type == 'public' , recursive=False, allow_empty=True ) has_suitable_constructor = bool( cs ) if cs and len(cs) == 1 and declarations.is_trivial_constructor(cs[0]) and declarations.find_noncopyable_vars(self): has_suitable_constructor = False has_nonpublic_destructor = declarations.has_destructor( self ) \ and not declarations.has_public_destructor( self ) trivial_constructor = declarations.find_trivial_constructor(self) if has_nonpublic_destructor \ or ( self.is_abstract and not self.is_wrapper_needed() ) \ or not has_suitable_constructor: self._no_init = True elif not trivial_constructor or trivial_constructor.access_type != 'public': exportable_cs = [c for c in cs if c.exportable and c.ignore == False] if not exportable_cs: self._no_init = True else: pass if None is self._no_init: self._no_init = False return self._no_init
def visit_class(self ): if self.curr_decl.indexing_suite: self.__types_db.update_containers( self.curr_decl ) return #it will be exposed later, using other code creators self.__dependencies_manager.add_exported( self.curr_decl ) cls_decl = self.curr_decl cls_parent_cc = self.curr_code_creator exportable_members = self.curr_decl.get_exportable_members(sort_algorithms.sort) wrapper = None cls_cc = None if cls_decl.introduces_new_scope: cls_cc = code_creators.class_t( class_inst=self.curr_decl ) else: cls_cc = self.curr_code_creator if self.curr_decl.is_wrapper_needed(): wrapper = code_creators.class_wrapper_t( declaration=self.curr_decl , class_creator=cls_cc ) cls_cc.wrapper = wrapper cls_cc.associated_decl_creators.append( wrapper ) #insert wrapper before module body if isinstance( self.curr_decl.parent, declarations.class_t ): #we deal with internal class self.curr_code_creator.wrapper.adopt_creator( wrapper ) else: self.__extmodule.adopt_declaration_creator( wrapper ) #next constructors are not present in code, but compiler generated #Boost.Python requiers them to be declared in the wrapper class noncopyable_vars = declarations.find_noncopyable_vars(self.curr_decl) copy_constr = declarations.find_copy_constructor(self.curr_decl) if not self.curr_decl.noncopyable and copy_constr and copy_constr.is_artificial: cccc = code_creators.copy_constructor_wrapper_t( constructor=copy_constr) wrapper.adopt_creator( cccc ) trivial_constr = declarations.find_trivial_constructor(self.curr_decl) if trivial_constr and trivial_constr.is_artificial and not noncopyable_vars: tcons = code_creators.null_constructor_wrapper_t( constructor=trivial_constr ) wrapper.adopt_creator( tcons ) exposed = self.expose_overloaded_mem_fun_using_macro( cls_decl, cls_cc ) if cls_decl.introduces_new_scope: cls_parent_cc.adopt_creator( cls_cc ) self.curr_code_creator = cls_cc if cls_decl.expose_this: cls_cc.adopt_creator( code_creators.expose_this_t( cls_decl ) ) if cls_decl.expose_sizeof: cls_cc.adopt_creator( code_creators.expose_sizeof_t( cls_decl ) ) for declaration in exportable_members: if declaration in exposed: continue self.curr_decl = declaration declarations.apply_visitor( self, declaration ) for redefined_func in cls_decl.redefined_funcs(): if isinstance( redefined_func, declarations.operator_t ): continue self.curr_decl = redefined_func declarations.apply_visitor( self, redefined_func ) #all static_methods_t should be moved to the end #better approach is to move them after last def of relevant function static_methods = [creator for creator in cls_cc.creators if isinstance( creator, code_creators.static_method_t )] for static_method in static_methods: cls_cc.remove_creator( static_method ) cls_cc.adopt_creator( static_method ) if cls_decl.exception_translation_code: translator = code_creators.exception_translator_t( cls_decl ) self.__extmodule.adopt_declaration_creator( translator ) cls_cc.associated_decl_creators.append( translator ) translator_register \ = code_creators.exception_translator_register_t( cls_decl, translator ) cls_cc.adopt_creator( translator_register ) for property_def in cls_decl.properties: cls_cc.adopt_creator( code_creators.property_t(property_def) ) if wrapper and cls_decl.destructor_code: destructor = code_creators.destructor_wrapper_t( class_=cls_decl ) wrapper.adopt_creator( destructor ) for fc in cls_decl.fake_constructors: if self.__fc_manager.should_generate_code( fc ): self.__dependencies_manager.add_exported( fc ) cls_cc.adopt_creator( code_creators.make_constructor_t( fc ) ) self.curr_decl = cls_decl self.curr_code_creator = cls_parent_cc