[pygccxml-commit] SF.net SVN: pygccxml: [764] pyplusplus_dev_ft
Brought to you by:
mbaas,
roman_yakovenko
From: <rom...@us...> - 2006-11-29 15:05:14
|
Revision: 764 http://svn.sourceforge.net/pygccxml/?rev=764&view=rev Author: roman_yakovenko Date: 2006-11-29 07:05:10 -0800 (Wed, 29 Nov 2006) Log Message: ----------- adding support for almost all transformers for virtual member functions Modified Paths: -------------- pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py pyplusplus_dev_ft/pyplusplus/function_transformers/templates.py pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py pyplusplus_dev_ft/unittests/data/function_transformations_to_be_exported.hpp pyplusplus_dev_ft/unittests/function_transformations_tester.py Modified: pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py 2006-11-29 12:24:50 UTC (rev 763) +++ pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py 2006-11-29 15:05:10 UTC (rev 764) @@ -267,32 +267,22 @@ result.append( 'typedef %s;' % ftype.create_typedef( self.default_function_type_alias ) ) return ''.join( result ) - def create_doc(self): - return None + def create_keywords_args(self): + cntrl = self.controller.default_controller + arg_utils = calldef_utils.argument_utils_t( self.declaration + , algorithm.make_id_creator( self ) + , [cntrl.inst_arg] + cntrl.wrapper_args ) + return arg_utils.keywords_args() def create_function_ref_code(self, use_function_alias=False): - result = [] + full_name = self.wrapper.default_full_name() if use_function_alias: - result.append( '%s(&%s)' - % ( self.function_type_alias, declarations.full_name( self.declaration ) ) ) - if self.wrapper: - result.append( self.param_sep() ) - result.append( '%s(&%s)' - % ( self.default_function_type_alias, self.wrapper.default_full_name() ) ) + return '%s( &%s )' % ( self.function_type_alias, full_name ) elif self.declaration.create_with_signature: - result.append( '(%s)(&%s)' - % ( self.declaration.function_type().decl_string - , declarations.full_name( self.declaration ) ) ) - if self.wrapper: - result.append( self.param_sep() ) - result.append( '(%s)(&%s)' - % ( self.wrapper.function_type().decl_string, self.wrapper.default_full_name() ) ) + func_type = self.wrapper.default_function_type() + return '(%s)( &%s )' % ( func_type, full_name ) else: - result.append( '&%s'% declarations.full_name( self.declaration ) ) - if self.wrapper: - result.append( self.param_sep() ) - result.append( '&%s' % self.wrapper.default_full_name() ) - return ''.join( result ) + return '&%s' % full_name class mem_fun_v_transformed_wrapper_t( calldef_wrapper_t ): def __init__( self, function ): @@ -306,34 +296,77 @@ def controller( self ): return self.ft.controller + def default_name(self): + if self.declaration.overloads: + #it is possible that other functions will have same signature + return 'default_' + self.ft.unique_name + else: + return 'default_' + self.declaration.alias + def default_full_name(self): - return self.parent.full_name + '::default_' + self.declaration.alias + return self.parent.full_name + '::' + self.default_name() def args_override_declaration( self ): return self.args_declaration() - def function_type(self): - return declarations.member_function_type_t( - return_type=self.declaration.return_type - , class_inst=declarations.dummy_type_t( self.parent.full_name ) - , arguments_types=map( lambda arg: arg.type, self.declaration.arguments ) - , has_const=self.declaration.has_const ) + def args_default_declaration( self ): + cntrl = self.controller.default_controller + arg_utils = calldef_utils.argument_utils_t( self.declaration + , algorithm.make_id_creator( self ) + , [cntrl.inst_arg] + cntrl.wrapper_args ) + return arg_utils.args_declaration() - def create_default_declaration(self): - template = '%(return_type)s %(name)s( %(args)s )%(constness)s %(throw)s' + def default_function_type(self): + cntrl = self.controller.default_controller + args = [cntrl.inst_arg.type] + map( lambda arg: arg.type, cntrl.wrapper_args ) + return declarations.free_function_type_t( return_type=cntrl.wrapper_return_type + , arguments_types=args ) - constness = '' - if self.declaration.has_const: - constness = ' const ' + def create_default(self): + cntrl = self.controller.default_controller - return template % { - 'return_type' : self.declaration.return_type.decl_string - , 'name' : 'default_' + self.declaration.alias - , 'args' : self.args_override_declaration() - , 'constness' : constness - , 'throw' : self.throw_specifier_code() - } + make_object = algorithm.create_identifier( self, 'pyplusplus::call_policies::make_object' ) + make_tuple = algorithm.create_identifier( self, 'boost::python::make_tuple' ) + + tmpl_values = dict() + tmpl_values['unique_function_name'] = self.default_name() + tmpl_values['return_type'] = cntrl.wrapper_return_type.decl_string + tmpl_values['arg_declarations'] = self.args_default_declaration() + tmpl_values['wrapper_class'] = self.parent.wrapper_alias + tmpl_values['wrapped_class'] = declarations.full_name( self.declaration.parent ) + tmpl_values['wrapped_inst'] = cntrl.inst_arg.name + + decl_vars = cntrl.variables[:] + if not declarations.is_void( self.declaration.return_type ): + decl_vars.append( cntrl.result_variable ) + tmpl_values['declare_variables'] \ + = os.linesep + os.linesep.join( map( lambda var: self.indent( var.declare_var_string() ) + , decl_vars ) ) + + tmpl_values['pre_call'] = os.linesep + self.indent( os.linesep.join( cntrl.pre_call ) ) + + tmpl_values['save_result'] = '' + if not declarations.is_void( self.declaration.return_type ): + tmpl_values['save_result'] = '%s = ' % cntrl.result_variable.name + + tmpl_values['function_name'] = self.declaration.name + tmpl_values['arg_expressions'] = self.PARAM_SEPARATOR.join( cntrl.arg_expressions ) + return_stmt_creator = calldef_utils.return_stmt_creator_t( self + , cntrl + , cntrl.result_variable + , cntrl.return_variables ) + + tmpl_values['post_call'] = os.linesep + self.indent( os.linesep.join( cntrl.post_call ) ) + if return_stmt_creator.pre_return_code: + tmpl_values['post_call'] \ + = os.linesep.join([ tmpl_values['post_call'] + , self.indent( return_stmt_creator.pre_return_code )]) + tmpl_values['return'] = os.linesep + self.indent( return_stmt_creator.statement ) + + f_def = cntrl.template.substitute(tmpl_values) + return remove_duplicate_linesep( f_def ) + def wrapped_class_identifier( self ): return algorithm.create_identifier( self, declarations.full_name( self.declaration.parent ) ) @@ -379,22 +412,5 @@ f_def_code = cntrl.template.substitute(tmpl_values) return remove_duplicate_linesep( f_def_code ) - def create_default_body(self): - function_call = declarations.call_invocation.join( self.declaration.name - , [ self.function_call_args() ] ) - body = self.wrapped_class_identifier() + '::' + function_call + ';' - if not declarations.is_void( self.declaration.return_type ): - body = 'return ' + body - return body - - def create_default_function( self ): - answer = [ self.create_default_declaration() + '{' ] - answer.append( self.indent( self.create_default_body() ) ) - answer.append( '}' ) - return os.linesep.join( answer ) - def _create_impl(self): - answer = [ self.create_override() ] - answer.append( os.linesep ) - answer.append( self.create_default_function() ) - return os.linesep.join( answer ) + return os.linesep.join([ self.create_override(), '', self.create_default() ]) Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py 2006-11-29 12:24:50 UTC (rev 763) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py 2006-11-29 15:05:10 UTC (rev 764) @@ -203,7 +203,7 @@ @property def template( self ): - return templates.virtual_mem_fun.override_body + return templates.virtual_mem_fun.override @property def py_variables( self ): @@ -262,7 +262,11 @@ @property def inst_arg( self ): return self.__inst_arg - + + @property + def template( self ): + return templates.virtual_mem_fun.default + def __init__( self, function ): controller_base_t.__init__( self, function ) self.__override_cntrl = self.override_fun_controller_t( function ) Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/templates.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/templates.py 2006-11-29 12:24:50 UTC (rev 763) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/templates.py 2006-11-29 15:05:10 UTC (rev 764) @@ -23,7 +23,7 @@ ])) class virtual_mem_fun: - override_body = Template( os.linesep.join([ + override = Template( os.linesep.join([ 'virtual $return_type $function_name( $arg_declarations )$constness $throw{' , ' namespace bpl = boost::python;' , ' if( bpl::override $py_function_var = this->get_override( "$function_alias" ) ){' @@ -39,12 +39,12 @@ , '}' ])) - default_body = Template( os.linesep.join([ - 'static $return_type $unique_function_name( $arg_declarations ){' + default = Template( os.linesep.join([ + 'static $return_type $unique_function_name( $arg_declarations ){' , ' $declare_variables' , ' $pre_call' - , ' if( $wrapper_class $py_wrapper_var = dynamic_cast< $wrapper_class >( boost::addressof( $wrapped_inst ) ) ){' - , ' $save_result$wrapped_inst->$wrapped_class::$function_name($arg_expressions);' + , ' if( dynamic_cast< $wrapper_class* >( boost::addressof( $wrapped_inst ) ) ){' + , ' $save_result$wrapped_inst.$wrapped_class::$function_name($arg_expressions);' , ' }' , ' else{' , ' $save_result$wrapped_inst.$function_name($arg_expressions);' Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py 2006-11-29 12:24:50 UTC (rev 763) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py 2006-11-29 15:05:10 UTC (rev 764) @@ -100,7 +100,6 @@ def configure_free_fun(self, controller ): self.__configure_sealed( controller ) - def configure_virtual_mem_fun( self, controller ): self.__configure_v_mem_fun_default( controller.default_controller ) self.__configure_v_mem_fun_override( controller.override_controller ) @@ -145,9 +144,7 @@ self.__configure_sealed( controller ) def configure_virtual_mem_fun( self, controller ): - pass #according to boost.python documentation, it will create a copy of - #the object by itself - + self.__configure_sealed( controller.default_controller ) # inout_t class inout_t(transformer.transformer_t): @@ -181,6 +178,14 @@ #adding the variable to return variables list controller.return_variable( w_arg.name ) + def __configure_v_mem_fun_override( self, controller ): + tmpl = string.Template( + '$name = boost::python::extract< $type >( pyplus_conv::get_out_argument( $py_result, "$name" ) );' ) + store_py_result_in_arg = tmpl.substitute( name=self.arg.name + , type=self.arg.type.decl_string + , py_result=controller.py_result_variable.name ) + controller.add_py_post_call_code( store_py_result_in_arg ) + def configure_mem_fun( self, controller ): self.__configure_sealed( controller ) @@ -188,13 +193,8 @@ self.__configure_sealed( controller ) def configure_virtual_mem_fun( self, controller ): - assert isinstance( controller, controllers.virtual_mem_fun_controller_t ) - tmpl = string.Template( - '$name = boost::python::extract< $type >( pyplus_conv::get_out_argument( $py_result, "$name" ) );' ) - store_py_result_in_arg = tmpl.substitute( name=self.arg.name - , type=self.arg.type.decl_string - , py_result=controller.py_result_variable.name ) - controller.add_py_post_call_code( store_py_result_in_arg ) + self.__configure_v_mem_fun_override( controller.override_controller ) + self.__configure_sealed( controller.default_controller ) class input_array_t(transformer.transformer_t): """Handles an input array with fixed size. Modified: pyplusplus_dev_ft/unittests/data/function_transformations_to_be_exported.hpp =================================================================== --- pyplusplus_dev_ft/unittests/data/function_transformations_to_be_exported.hpp 2006-11-29 12:24:50 UTC (rev 763) +++ pyplusplus_dev_ft/unittests/data/function_transformations_to_be_exported.hpp 2006-11-29 15:05:10 UTC (rev 764) @@ -102,28 +102,28 @@ // Made the method 'virtual' for now because func transformers // are currently only taken into account on virtual functions. - //~ virtual void get_size( unsigned int& h, unsigned int& w ){ - //~ h = m_height; - //~ w = m_width; - //~ } + virtual void get_size( unsigned int& h, unsigned int& w ){ + h = m_height; + w = m_width; + } // Return only one value virtual void get_one_value(unsigned int& h) { h = m_height; } - //~ // Like get_size() but with a return type and an additional argument - //~ // that has to be kept in the signature - //~ virtual int get_size2( unsigned int& h, unsigned int& w, int noref=0 ){ - //~ h = m_height; - //~ w = m_width; - //~ return noref; - //~ } + // Like get_size() but with a return type and an additional argument + // that has to be kept in the signature + virtual int get_size2( unsigned int& h, unsigned int& w, int noref=0 ){ + h = m_height; + w = m_width; + return noref; + } - //~ // A method with an input argument - //~ virtual int input_arg(int& in){ - //~ return in; - //~ } + // A method with an input argument + virtual int input_arg(int& in){ + return in; + } //~ // A method taking an input array of fixed size //~ virtual int fixed_input_array(int v[3]) { @@ -142,24 +142,24 @@ }; -//~ // Provide an instance created in C++ (i.e. this is not a wrapper instance) -//~ image_t cpp_instance(12,13); -//~ image_t& get_cpp_instance() { - //~ return cpp_instance; -//~ } +// Provide an instance created in C++ (i.e. this is not a wrapper instance) +image_t cpp_instance(12,13); +image_t& get_cpp_instance() { + return cpp_instance; +} -//~ inline void -//~ get_image_size( image_t& img, unsigned int& h, unsigned int& w ){ - //~ img.get_size( h, w ); -//~ } +inline void +get_image_size( image_t& img, unsigned int& h, unsigned int& w ){ + img.get_size( h, w ); +} -//~ // This is used for calling img.get_one_value() on an instance passed -//~ // in by Python. -//~ unsigned int get_image_one_value( image_t& img ) { - //~ unsigned int v; - //~ img.get_one_value(v); - //~ return v; -//~ } +// This is used for calling img.get_one_value() on an instance passed +// in by Python. +unsigned int get_image_one_value( image_t& img ) { + unsigned int v; + img.get_one_value(v); + return v; +} //~ // This is used for calling img.fixed_output_array() on an instance passed //~ // in by Python. @@ -169,19 +169,19 @@ //~ return v[0]+v[1]+v[2]; //~ } -//~ ////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// -//~ // A class without any virtual members -//~ struct no_virtual_members_t -//~ { - //~ bool member(int& v) { v=17; return true; } -//~ }; +// A class without any virtual members +struct no_virtual_members_t +{ + bool member(int& v) { v=17; return true; } +}; -//~ struct ft_private_destructor_t{ - //~ static void get_value( int& x ){ x = 21; } -//~ private: - //~ ~ft_private_destructor_t(){} -//~ }; +struct ft_private_destructor_t{ + static void get_value( int& x ){ x = 21; } +private: + ~ft_private_destructor_t(){} +}; } Modified: pyplusplus_dev_ft/unittests/function_transformations_tester.py =================================================================== --- pyplusplus_dev_ft/unittests/function_transformations_tester.py 2006-11-29 12:24:50 UTC (rev 763) +++ pyplusplus_dev_ft/unittests/function_transformations_tester.py 2006-11-29 15:05:10 UTC (rev 764) @@ -47,27 +47,24 @@ point3d.mem_fun( 'distance' ).add_transformation( ft.output(1) ) image = mb.class_( "image_t" ) - image.include() - - #~ image.member_functions().exclude() - #~ image.member_function( "get_size" ).include() - #~ image.member_function( "get_size" ).add_transformation( ft.output(0), ft.output(1) ) + image.member_function( "get_size" ) + image.member_function( "get_size" ).add_transformation( ft.output(0), ft.output(1) ) image.member_function( "get_one_value" ).add_transformation( ft.output(0) ) - #~ image.member_function( "get_size2" ).add_transformation( ft.output(0), ft.output(1) ) - #~ image.member_function( "input_arg" ).add_transformation( ft.input(0) ) + image.member_function( "get_size2" ).add_transformation( ft.output(0), ft.output(1) ) + image.member_function( "input_arg" ).add_transformation( ft.input(0) ) #~ image.member_function( "fixed_input_array" ).add_transformation( ft.input_array(0,3) ) #~ image.member_function( "fixed_output_array" ).add_transformation( ft.output_array(0,3) ) - #~ mb.free_function("get_cpp_instance").call_policies \ - #~ = call_policies.return_value_policy(call_policies.reference_existing_object) - #~ mb.variable( "cpp_instance" ).exclude() + mb.free_function("get_cpp_instance").call_policies \ + = call_policies.return_value_policy(call_policies.reference_existing_object) + mb.variable( "cpp_instance" ).exclude() - #~ cls = mb.class_("no_virtual_members_t") - #~ cls.member_function("member").add_transformation( ft.output(0) ) + cls = mb.class_("no_virtual_members_t") + cls.member_function("member").add_transformation( ft.output(0) ) - #~ cls = mb.class_("ft_private_destructor_t") - #~ cls.member_function("get_value").add_transformation( ft.output(0) ) + cls = mb.class_("ft_private_destructor_t") + cls.member_function("get_value").add_transformation( ft.output(0) ) - #~ mb.decls(lambda decl: decl.name[0]=="_").exclude() + mb.decls(lambda decl: decl.name.startswith("_")).exclude() def run_tests(self, module): """Run the actual unit tests. @@ -99,23 +96,23 @@ self.failUnless( module.point3d_t.distance( point3d ) == math.sqrt( 1*1 + 2*2 + 3*3 ) ) self.failUnless( module.hello_world() == "hello world!" ) - #~ img = module.image_t( 2, 6) + img = module.image_t( 2, 6) # Check a method that returns two values by reference - #~ self.assertEqual(img.get_size(), (2,6)) + self.assertEqual(img.get_size(), (2,6)) - #~ # Check a method that only returns one value by reference - #~ self.assertEqual(img.get_one_value(), 2) + # Check a method that only returns one value by reference + self.assertEqual(img.get_one_value(), 2) - #~ # Check if the C++ class can also be passed back to C++ - #~ self.assertEqual(module.get_image_one_value(img), 2) + # Check if the C++ class can also be passed back to C++ + self.assertEqual(module.get_image_one_value(img), 2) - #~ # Check get_size2() - #~ self.assertEqual(img.get_size2(), (0,2,6)) - #~ self.assertEqual(img.get_size2(1), (1,2,6)) + # Check get_size2() + self.assertEqual(img.get_size2(), (0,2,6)) + self.assertEqual(img.get_size2(1), (1,2,6)) - #~ # Check the input_arg method - #~ self.assertEqual(img.input_arg(5), 5) + # Check the input_arg method + self.assertEqual(img.input_arg(5), 5) #~ # Check the fixed_input_array method #~ self.assertEqual(img.fixed_input_array([1,2,3]), 6) @@ -124,18 +121,18 @@ #~ # Check the fixed_output_array method #~ self.assertEqual(img.fixed_output_array(), [1,2,3]) - #~ self.assertEqual(module.ft_private_destructor_t.get_value(), 21) + self.assertEqual(module.ft_private_destructor_t.get_value(), 21) - #~ ####### Do the tests on a class derived in Python ######## + ####### Do the tests on a class derived in Python ######## - #~ class py_image1_t(module.image_t): - #~ def __init__(self, h, w): - #~ module.image_t.__init__(self, h, w) - #~ self.fixed_output_array_mode = 0 + class py_image1_t(module.image_t): + def __init__(self, h, w): + module.image_t.__init__(self, h, w) + self.fixed_output_array_mode = 0 - #~ # Override a virtual method - #~ def get_one_value(self): - #~ return self.m_height+1 + # Override a virtual method + def get_one_value(self): + return self.m_height+1 #~ def fixed_output_array(self): #~ # Produce a correct return value @@ -148,16 +145,16 @@ #~ elif self.fixed_output_array_mode==2: #~ return (2,5) - #~ pyimg1 = py_image1_t(3,7) + pyimg1 = py_image1_t(3,7) - #~ # Check a method that returns two values by reference - #~ self.assertEqual(pyimg1.get_size(), (3,7)) + # Check a method that returns two values by reference + self.assertEqual(pyimg1.get_size(), (3,7)) - #~ # Check a method that only returns one value by reference - #~ self.assertEqual(pyimg1.get_one_value(), 4) + # Check a method that only returns one value by reference + self.assertEqual(pyimg1.get_one_value(), 4) - #~ # Check if the Python class can also be passed back to C++ - #~ self.assertEqual(module.get_image_one_value(pyimg1), 4) + # Check if the Python class can also be passed back to C++ + self.assertEqual(module.get_image_one_value(pyimg1), 4) #~ # Check if fixed_output_array() is correctly called from C++ #~ self.assertEqual(module.image_fixed_output_array(pyimg1), 14) @@ -166,39 +163,39 @@ #~ pyimg1.fixed_output_array_mode = 2 #~ self.assertRaises(ValueError, lambda : module.image_fixed_output_array(pyimg1)) - #~ class py_image2_t(module.image_t): - #~ def __init__(self, h, w): - #~ module.image_t.__init__(self, h, w) + class py_image2_t(module.image_t): + def __init__(self, h, w): + module.image_t.__init__(self, h, w) - #~ # Override a virtual method and invoke the inherited method - #~ def get_one_value(self): - #~ return module.image_t.get_one_value(self)+2 + # Override a virtual method and invoke the inherited method + def get_one_value(self): + return module.image_t.get_one_value(self)+2 - #~ pyimg2 = py_image2_t(4,8) + pyimg2 = py_image2_t(4,8) - #~ # Check the derived get_one_value() method - #~ self.assertEqual(pyimg2.get_one_value(), 6) + # Check the derived get_one_value() method + self.assertEqual(pyimg2.get_one_value(), 6) - #~ # Check if the Python class can also be passed back to C++ - #~ self.assertEqual(module.get_image_one_value(pyimg2), 6) + # Check if the Python class can also be passed back to C++ + self.assertEqual(module.get_image_one_value(pyimg2), 6) - #~ ####### Do the tests on a class instantiated in C++ ######## + ####### Do the tests on a class instantiated in C++ ######## - #~ cppimg = module.get_cpp_instance() + cppimg = module.get_cpp_instance() - #~ # Check a method that returns two values by reference - #~ self.assertEqual(cppimg.get_size(), (12,13)) + # Check a method that returns two values by reference + self.assertEqual(cppimg.get_size(), (12,13)) - #~ # Check a method that only returns one value by reference - #~ self.assertEqual(cppimg.get_one_value(), 12) + # Check a method that only returns one value by reference + self.assertEqual(cppimg.get_one_value(), 12) - #~ # Check if the C++ class can also be passed back to C++ - #~ self.assertEqual(module.get_image_one_value(cppimg), 12) + # Check if the C++ class can also be passed back to C++ + self.assertEqual(module.get_image_one_value(cppimg), 12) - #~ ######### Test no_virtual_members_t ######## + ######### Test no_virtual_members_t ######## - #~ cls = module.no_virtual_members_t() - #~ self.assertEqual(cls.member(), (True, 17)) + cls = module.no_virtual_members_t() + self.assertEqual(cls.member(), (True, 17)) def create_suite(): suite = unittest.TestSuite() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |