[pygccxml-commit] SF.net SVN: pygccxml: [747] pyplusplus_dev_ft
Brought to you by:
mbaas,
roman_yakovenko
From: <rom...@us...> - 2006-11-22 09:26:21
|
Revision: 747 http://svn.sourceforge.net/pygccxml/?rev=747&view=rev Author: roman_yakovenko Date: 2006-11-22 01:26:21 -0800 (Wed, 22 Nov 2006) Log Message: ----------- adding ability to create wrapper function for function with non default call policies Modified Paths: -------------- pyplusplus_dev_ft/pyplusplus/code_creators/calldef.py pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py pyplusplus_dev_ft/pyplusplus/code_repository/call_policies.py pyplusplus_dev_ft/pyplusplus/decl_wrappers/call_policies.py pyplusplus_dev_ft/pyplusplus/decl_wrappers/calldef_wrapper.py pyplusplus_dev_ft/pyplusplus/function_transformers/function_transformation.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.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/code_creators/calldef.py 2006-11-22 09:14:13 UTC (rev 746) +++ pyplusplus_dev_ft/pyplusplus/code_creators/calldef.py 2006-11-22 09:26:21 UTC (rev 747) @@ -47,10 +47,15 @@ def param_sep(self): return os.linesep + self.indent( self.PARAM_SEPARATOR ) - def keywords_args(self): + def create_keywords_args(self): arg_utils = calldef_utils.argument_utils_t( self.declaration, algorithm.make_id_creator( self ) ) return arg_utils.keywords_args() + def create_call_policies( self ): + if self.declaration.call_policies.is_default(): + return '' + return self.declaration.call_policies.create( self ) + def create_def_code( self ): if not self.works_on_instance: return '%s.def' % self.parent.class_var_name @@ -93,17 +98,16 @@ result.append( self.create_function_ref_code( not self.works_on_instance ) ) if self.declaration.use_keywords: - keywd_args = self.keywords_args() + keywd_args = self.create_keywords_args() if keywd_args: result.append( self.param_sep() ) result.append( keywd_args ) if self.declaration.call_policies: - if not self.declaration.call_policies.is_default(): + c_p_code = self.create_call_policies() + if c_p_code: result.append( self.param_sep() ) - result.append( self.declaration.call_policies.create( self ) ) - else: - pass#don't generate default_call_policies + result.append( c_p_code ) else: result.append( os.linesep + self.indent( '/* undefined call policies */', 2 ) ) @@ -778,7 +782,7 @@ answer.append( '(' ) keywords_args = None if self.declaration.use_keywords: - keywords_args = self.keywords_args() + keywords_args = self.create_keywords_args() answer.append( '%s' % keywords_args ) if self.documentation: if keywords_args: @@ -1176,7 +1180,7 @@ def create_end_def_code( self ): raise NotImplementedError() - def keywords_args(self): + def create_keywords_args(self): result = [ algorithm.create_identifier( self, '::boost::python::args' ) ] result.append( '( ' ) args = [] @@ -1198,7 +1202,7 @@ def create_overloads_cls( self ): result = [ self.overloads_class.name ] result.append( '( ' ) - result.append( os.linesep + self.indent( self.keywords_args(), 3 ) ) + result.append( os.linesep + self.indent( self.create_keywords_args(), 3 ) ) if self.overloads_class.max_function.documentation: result.append( os.linesep + self.indent( self.PARAM_SEPARATOR, 3 ) ) result.append( self.overloads_class.max_function.documentation ) Modified: pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py 2006-11-22 09:14:13 UTC (rev 746) +++ pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py 2006-11-22 09:26:21 UTC (rev 747) @@ -43,7 +43,13 @@ else: return '&%s' % full_name - def keywords_args(self): + def create_call_policies( self ): + if self.ft.controller.return_variables: + return '' + else: + return super( mem_fun_transformed_t, self ).create_call_policies() + + def create_keywords_args(self): arg_utils = calldef_utils.argument_utils_t( self.declaration , algorithm.make_id_creator( self ) , self.ft.controller.wrapper_args ) @@ -100,18 +106,37 @@ def create_body(self): cntrl = self.ft.controller + make_object = algorithm.create_identifier( self, 'pyplusplus::call_policies::make_object' ) + make_tuple = algorithm.create_identifier( self, 'boost::python::make_tuple' ) + result_var_assign = '' if not declarations.is_void( self.declaration.return_type ): result_var_assign = '%(type)s %(name)s = ' \ % { 'type': cntrl.result_variable.type.decl_string , 'name' : cntrl.result_variable.name } + post_call = os.linesep.join( cntrl.post_call ) + return_stmt = '' if cntrl.return_variables: return_vars = cntrl.return_variables[:] if not declarations.is_void( self.declaration.return_type ): - return_vars.insert( 0, cntrl.result_variable.name ) - return_stmt = declarations.call_invocation.join( 'boost::python::make_tuple', return_vars ) + if self.declaration.call_policies.is_default(): + return_vars.insert( 0, cntrl.result_variable.name ) + else: + c_p_alias = cntrl.register_variable_name( 'call_policies_t' ) + c_p_typedef = 'typedef %s %s;' \ + % ( self.declaration.call_policies.create_template_arg( self ) + , c_p_alias ) + post_call = os.linesep.join( [post_call, c_p_typedef] ) + return_vars.insert( 0 + , declarations.call_invocation.join( + declarations.templates.join( make_object, [c_p_alias] ) + , [cntrl.result_variable.name] ) ) + return_stmt = declarations.call_invocation.join( + make_tuple + , return_vars + , os.linesep + self.indent( self.PARAM_SEPARATOR, 6 ) ) elif not declarations.is_void( self.declaration.return_type ): return_stmt = cntrl.result_variable.name else: @@ -122,7 +147,7 @@ return cntrl.template.substitute({ 'declare_variables' : os.linesep.join( map( lambda var: var.declare_var_string(), cntrl.variables ) ) , 'pre_call' : os.linesep.join( cntrl.pre_call ) - , 'post_call' : os.linesep.join( cntrl.post_call ) + , 'post_call' : post_call , 'save_result' : result_var_assign , 'function' : self.__this_arg.name + '.' + self.declaration.name , 'arg_expressions' : self.PARAM_SEPARATOR.join( cntrl.arg_expressions ) Modified: pyplusplus_dev_ft/pyplusplus/code_repository/call_policies.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/code_repository/call_policies.py 2006-11-22 09:14:13 UTC (rev 746) +++ pyplusplus_dev_ft/pyplusplus/code_repository/call_policies.py 2006-11-22 09:26:21 UTC (rev 747) @@ -70,6 +70,14 @@ }; +template< typename CallPolicies, class T > +bpl::object make_object( T const & x ){ + //constructs object using CallPolicies result_converter + typedef typename CallPolicies::result_converter::apply< T >::type result_converter_t; + result_converter_t rc; + return bpl::object( bpl::handle<>( rc( x ) ) ); +} + } /*pyplusplus*/ } /*call_policies*/ Modified: pyplusplus_dev_ft/pyplusplus/decl_wrappers/call_policies.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/decl_wrappers/call_policies.py 2006-11-22 09:14:13 UTC (rev 746) +++ pyplusplus_dev_ft/pyplusplus/decl_wrappers/call_policies.py 2006-11-22 09:26:21 UTC (rev 747) @@ -38,6 +38,9 @@ code = code + '()' return code + def create_template_arg( self, function_creator ): + return self.create( function_creator, CREATION_POLICY.AS_TEMPLATE_ARGUMENT ) + def is_default( self ): """Returns True is self is instance of L{default_call_policies_t} class""" #Small hack that allows to write nicer code @@ -227,4 +230,4 @@ """returns True is policy represents return_value_policy<return_pointee_value>, False otherwise""" return isinstance( policy, return_value_policy_t ) \ and policy.result_converter_generator == return_pointee_value - \ No newline at end of file + Modified: pyplusplus_dev_ft/pyplusplus/decl_wrappers/calldef_wrapper.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-11-22 09:14:13 UTC (rev 746) +++ pyplusplus_dev_ft/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-11-22 09:26:21 UTC (rev 747) @@ -171,7 +171,11 @@ tmp.append( "For more information see: http://mail.python.org/pipermail/c++-sig/2002-June/001554.html" ) tmp = ' '.join( tmp ) msgs.append( tmp % ( calldef_t.BOOST_PYTHON_MAX_ARITY, len( self.arguments ) ) ) - + + if self.transformations: + #if user defined transformation, than I think it took care of the problems + return msgs + if suspicious_type( self.return_type ) and None is self.call_policies: msgs.append( 'The function "%s" returns non-const reference to C++ fundamental type - value can not be modified from Python.' % str( self ) ) Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/function_transformation.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/function_transformation.py 2006-11-22 09:14:13 UTC (rev 746) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/function_transformation.py 2006-11-22 09:26:21 UTC (rev 747) @@ -7,6 +7,7 @@ """ import controllers +from pyplusplus import code_repository class function_transformation_t: def __init__(self, function, transformer_creator, **keywd): @@ -29,6 +30,8 @@ headers = [] map( lambda transformer: headers.extend( transformer.required_headers() ) , self.transformers ) + if self.__function.call_policies: + headers.append( code_repository.call_policies.file_name ) return headers @property 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-22 09:14:13 UTC (rev 746) +++ pyplusplus_dev_ft/unittests/data/function_transformations_to_be_exported.hpp 2006-11-22 09:26:21 UTC (rev 747) @@ -6,9 +6,18 @@ #ifndef __function_transformations_to_be_exported_hpp__ #define __function_transformations_to_be_exported_hpp__ +#include <iostream> + namespace ft2{ struct calculator_t{ + calculator_t(){ + std::cout << std::endl << "=> calculator_t created"; + } + + virtual ~calculator_t(){ + std::cout << std::endl << "=> calculator_t destroyed" << std::endl; + } int assign_0_1_2( int& one, int& two ){ one = 1; @@ -20,6 +29,10 @@ assign_0_1_2( one, two ); } + calculator_t* clone_and_assign_5( int& five ){ + five = 5; + return new calculator_t(); + } }; } Modified: pyplusplus_dev_ft/unittests/function_transformations_tester.py =================================================================== --- pyplusplus_dev_ft/unittests/function_transformations_tester.py 2006-11-22 09:14:13 UTC (rev 746) +++ pyplusplus_dev_ft/unittests/function_transformations_tester.py 2006-11-22 09:26:21 UTC (rev 747) @@ -9,6 +9,8 @@ import fundamental_tester_base from pyplusplus import function_transformers as ft from pyplusplus.module_builder import call_policies + + class tester_t(fundamental_tester_base.fundamental_tester_base_t): EXTENSION_NAME = 'function_transformations' @@ -23,6 +25,10 @@ calc.add_wrapper_code( '' ) assign_funs = calc.mem_funs( lambda decl: decl.name.startswith( 'assign' ) ) assign_funs.add_transformation( ft.output(0), ft.output(1) ) + + clone_and_assign_5 = calc.mem_fun( 'clone_and_assign_5' ) + clone_and_assign_5.add_transformation( ft.output(0) ) + clone_and_assign_5.call_policies = call_policies.return_value_policy( call_policies.manage_new_object ) #~ image = mb.class_( "image_t" ) #~ image.include() @@ -55,6 +61,13 @@ calc = module.calculator_t() self.failUnless( ( 0, 1, 2 ) == calc.assign_0_1_2() ) self.failUnless( ( 1, 2 ) == calc.assign_1_2() ) + calc2, five = calc.clone_and_assign_5() + self.failUnless( five == 5 ) + self.failUnless( calc2 ) + #test make_object function + self.failUnless( sys.getrefcount( calc ) == sys.getrefcount( calc2 ) ) + + #~ img = module.image_t( 2, 6) # Check a method that returns two values by reference This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |