Thread: [pygccxml-commit] SF.net SVN: pygccxml: [742] pyplusplus_dev_ft
Brought to you by:
mbaas,
roman_yakovenko
From: <rom...@us...> - 2006-11-21 13:00:32
|
Revision: 742 http://svn.sourceforge.net/pygccxml/?rev=742&view=rev Author: roman_yakovenko Date: 2006-11-21 05:00:32 -0800 (Tue, 21 Nov 2006) Log Message: ----------- Modified Paths: -------------- pyplusplus_dev_ft/pyplusplus/code_creators/__init__.py pyplusplus_dev_ft/pyplusplus/code_creators/algorithm.py pyplusplus_dev_ft/pyplusplus/code_creators/calldef.py pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py pyplusplus_dev_ft/pyplusplus/function_transformers/__init__.py pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py pyplusplus_dev_ft/pyplusplus/function_transformers/function_transformation.py pyplusplus_dev_ft/pyplusplus/function_transformers/templates.py pyplusplus_dev_ft/pyplusplus/function_transformers/transformer.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/__init__.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/code_creators/__init__.py 2006-11-21 09:10:20 UTC (rev 741) +++ pyplusplus_dev_ft/pyplusplus/code_creators/__init__.py 2006-11-21 13:00:32 UTC (rev 742) @@ -78,8 +78,8 @@ from calldef_transformed import mem_fun_transformed_t from calldef_transformed import mem_fun_transformed_wrapper_t -from calldef_transformed import mem_fun_v_transformed_t -from calldef_transformed import mem_fun_v_transformed_wrapper_t +#~ from calldef_transformed import mem_fun_v_transformed_t +#~ from calldef_transformed import mem_fun_v_transformed_wrapper_t from global_variable import global_variable_base_t from global_variable import global_variable_t Modified: pyplusplus_dev_ft/pyplusplus/code_creators/algorithm.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/code_creators/algorithm.py 2006-11-21 09:10:20 UTC (rev 741) +++ pyplusplus_dev_ft/pyplusplus/code_creators/algorithm.py 2006-11-21 13:00:32 UTC (rev 742) @@ -99,3 +99,6 @@ if recursive: search_area = make_flatten_generator( where ) return filter( lambda inst: isinstance( inst, what ), search_area ) + +def make_id_creator( code_creator ): + return lambda decl_string: create_identifier( code_creator, decl_string ) Modified: pyplusplus_dev_ft/pyplusplus/code_creators/calldef.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/code_creators/calldef.py 2006-11-21 09:10:20 UTC (rev 741) +++ pyplusplus_dev_ft/pyplusplus/code_creators/calldef.py 2006-11-21 13:00:32 UTC (rev 742) @@ -19,9 +19,6 @@ #protected member functions - call, override #private - override -def make_id_creator( code_creator ): - return lambda decl_string: algorithm.create_identifier( code_creator, decl_string ) - class calldef_t( registration_based.registration_based_t , declaration_based.declaration_based_t ): def __init__(self, function, wrapper=None ): @@ -51,7 +48,7 @@ return os.linesep + self.indent( self.PARAM_SEPARATOR ) def keywords_args(self): - arg_utils = calldef_utils.argument_utils_t( self.declaration, make_id_creator( self ) ) + arg_utils = calldef_utils.argument_utils_t( self.declaration, algorithm.make_id_creator( self ) ) return arg_utils.keywords_args() def create_def_code( self ): @@ -139,11 +136,11 @@ return algorithm.create_identifier( self, '::boost::python::override' ) def function_call_args( self ): - arg_utils = calldef_utils.argument_utils_t( self.declaration, make_id_creator( self ) ) + arg_utils = calldef_utils.argument_utils_t( self.declaration, algorithm.make_id_creator( self ) ) return arg_utils.call_args() def args_declaration( self ): - arg_utils = calldef_utils.argument_utils_t( self.declaration, make_id_creator( self ) ) + arg_utils = calldef_utils.argument_utils_t( self.declaration, algorithm.make_id_creator( self ) ) return arg_utils.args_declaration() def wrapped_class_identifier( self ): @@ -841,7 +838,7 @@ def _create_constructor_call( self ): answer = [ algorithm.create_identifier( self, self.parent.declaration.decl_string ) ] answer.append( '( ' ) - arg_utils = calldef_utils.argument_utils_t( self.declaration, make_id_creator( self ) ) + arg_utils = calldef_utils.argument_utils_t( self.declaration, algorithm.make_id_creator( self ) ) params = arg_utils.call_args() answer.append( params ) if params: Modified: pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py 2006-11-21 09:10:20 UTC (rev 741) +++ pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py 2006-11-21 13:00:32 UTC (rev 742) @@ -4,8 +4,9 @@ # http://www.boost.org/LICENSE_1_0.txt) import os -#import algorithm -#import code_creator +import algorithm +import code_creator +import calldef_utils import class_declaration from pygccxml import declarations from calldef import calldef_t, calldef_wrapper_t @@ -21,42 +22,34 @@ def __init__( self, function, wrapper=None ): calldef_t.__init__( self, function=function, wrapper=wrapper ) + @property + def ft( self ): #function transformation + return self.declaration.transformations[0] + def create_function_type_alias_code( self, exported_class_alias=None ): - if self.wrapper==None: - ftype = self.declaration.function_type() - else: - ftype = self.wrapper.function_type() - res = 'typedef %s;' % ftype.create_typedef( self.function_type_alias, exported_class_alias ) - return res + ftype = self.wrapper.function_type() + return 'typedef %s;' % ftype.create_typedef( self.function_type_alias, exported_class_alias ) def create_function_ref_code(self, use_function_alias=False): - if self.wrapper: - full_name = self.wrapper.full_name() - else: - full_name = declarations.full_name( self.declaration ) + full_name = self.wrapper.full_name() if use_function_alias: return '%s( &%s )' \ % ( self.function_type_alias, full_name ) elif self.declaration.create_with_signature: - if self.wrapper: - func_type = self.wrapper.function_type() - else: - func_type = self.declaration.function_type().decl_string - return '(%s)( &%s )' \ - % ( func_type, full_name ) + func_type = self.wrapper.function_type() + return '(%s)( &%s )' % ( func_type, full_name ) else: return '&%s' % full_name + def keywords_args(self): + arg_utils = calldef_utils.argument_utils_t( self.declaration + , algorithm.make_id_creator( self ) + , self.ft.controller.wrapper_args ) + return arg_utils.keywords_args() -class mem_fun_transformed_wrapper_t( calldef_wrapper_t ): - """Creates wrapper code for (public) non-virtual member functions. - The generated function is either used as a static member inside the - wrapper class (when self.parent is not None) or as a free function - (when self.parent is None). - """ - +class mem_fun_transformed_wrapper_t( calldef_wrapper_t ): def __init__( self, function ): """Constructor. @@ -64,422 +57,390 @@ @type function: calldef_t """ calldef_wrapper_t.__init__( self, function=function ) + + this_arg_type = declarations.declarated_t( self.declaration.parent ) + if self.declaration.has_const: + this_arg_type = declarations.const_t( this_arg_type ) + this_arg_type = declarations.reference_t( this_arg_type ) + + self.__this_arg = declarations.argument_t( + name=self.ft.controller.register_variable_name( 'self' ) + , type=this_arg_type ) + + @property + def ft( self ): #function transformation + return self.declaration.transformations[0] - # Create the substitution manager - sm = function_transformers.substitution_manager_t( function - , transformers=function.transformations[0].transformers) - sm.init_funcs() - self._subst_manager = sm - def function_type(self): - """Return the type of the wrapper function. - - @rtype: type_t - """ - template = '$RET_TYPE' - rettype = self._subst_manager.subst_wrapper(template) - rettype = declarations.dummy_type_t(rettype) - return declarations.free_function_type_t( - return_type=rettype - , arguments_types=map( lambda arg: arg.type, self.declaration.arguments ) ) + return_type=self.declaration.return_type + , arguments_types=[ declarations.dummy_type_t( self.parent.full_name ) ] + + map( lambda arg: arg.type, self.ft.controller.wrapper_args ) ) - def wrapper_name(self): - """Return the name of the wrapper function. - - This is just the local name without any scope information. - """ - # A list with the individual components of the name - components = ["_py"] - # Is the wrapper placed outside a wrapper class? - if not isinstance(self.parent, class_declaration.class_wrapper_t): - # Incorporate the original class name into the name - components.append(self.declaration.parent.name) - components.append(self.declaration.alias) - return "_".join(components) - def full_name(self): - """Return the full name of the wrapper function. + return self.parent.full_name + '::' + self.declaration.name - The returned name also includes the class name (if there is any). + def args_declaration( self ): + arg_utils = calldef_utils.argument_utils_t( + self.declaration + , algorithm.make_id_creator( self ) + , [ self.__this_arg ] + self.ft.controller.wrapper_args ) + return arg_utils.args_declaration() - @rtype: str - """ - if isinstance(self.parent, class_declaration.class_wrapper_t): - return self.parent.full_name + '::' + self.wrapper_name() - else: - return self.wrapper_name() - def create_declaration(self, name): - """Create the function header. - """ - template = 'static $RET_TYPE %(name)s( $ARG_LIST_DEF ) %(throw)s' + template = 'static %(return_type)s %(name)s( %(args)s )' - # Substitute the $-variables - template = self._subst_manager.subst_wrapper(template) - return template % { - 'name' : self.wrapper_name() - , 'throw' : self.throw_specifier_code() + 'return_type' : self.ft.controller.wrapper_return_type.decl_string + , 'name' : self.declaration.name + , 'args' : self.args_declaration() } def create_body(self): - body = os.linesep.join([ - '$DECLARATIONS' - , '$PRE_CALL' - , '$RESULT_VAR_ASSIGNMENT$CALL_FUNC_NAME($INPUT_PARAMS);' - , '$POST_CALL' - , '$RETURN_STMT' - ]) + cntrl = self.ft.controller + arg_utils = calldef_utils.argument_utils_t( + self.declaration + , algorithm.make_id_creator( self ) + , cntrl.wrapper_args ) - # Replace the $-variables - body = self._subst_manager.subst_wrapper(body) - - return body - - def create_function(self): - answer = [70*"/"] - answer.append("// Transformed wrapper function for:") - answer.append("// %s"%self.declaration) - answer.append(70*"/") + return cntrl.template.substitute( + declare_variables=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 ) + , save_return_value_stmt=cntrl.save_return_value_stmt + , function=self.__this_arg.name + '.' + self.declaration.name + , arg_expressions=self.PARAM_SEPARATOR.join( cntrl.arg_expressions ) + , return_stmt='' + ) + + def _create_impl(self): + answer = ['// Transformed wrapper function for "%s"' % self.declaration ] answer.append( self.create_declaration(self.declaration.alias) + '{') answer.append( self.indent( self.create_body() ) ) answer.append( '}' ) return os.linesep.join( answer ) - def _create_impl(self): +#~ ###################################################################### - answer = self.create_function() +#~ class mem_fun_v_transformed_t( calldef_t ): + #~ """Creates code for (public) virtual member functions. + #~ """ - # Replace the argument list of the declaration so that in the - # case that keywords are created, the correct arguments will be - # picked up (i.e. the modified argument list and not the original - # argument list) - self.declaration.arguments = self._subst_manager.wrapper_func.arg_list + #~ def __init__( self, function, wrapper=None ): + #~ calldef_t.__init__( self, function=function, wrapper=wrapper ) + #~ self.default_function_type_alias = 'default_' + self.function_type_alias - return answer + #~ def create_function_type_alias_code( self, exported_class_alias=None ): + #~ if self.wrapper==None: + #~ ftype = self.declaration.function_type() + #~ else: + #~ ftype = self.wrapper.function_type() -###################################################################### + #~ result = [] + #~ result.append( 'typedef %s;' % ftype.create_typedef( self.function_type_alias, exported_class_alias ) ) + #~ return ''.join( result ) -class mem_fun_v_transformed_t( calldef_t ): - """Creates code for (public) virtual member functions. - """ + #~ def create_doc(self): + #~ return None - def __init__( self, function, wrapper=None ): - calldef_t.__init__( self, function=function, wrapper=wrapper ) - self.default_function_type_alias = 'default_' + self.function_type_alias + #~ def create_function_ref_code(self, use_function_alias=False): + #~ if self.wrapper: + #~ full_name = self.wrapper.default_full_name() + #~ else: + #~ full_name = declarations.full_name( self.declaration ) - def create_function_type_alias_code( self, exported_class_alias=None ): - if self.wrapper==None: - ftype = self.declaration.function_type() - else: - ftype = self.wrapper.function_type() + #~ result = [] + #~ if use_function_alias: + #~ result.append( '%s(&%s)' + #~ % ( self.function_type_alias, full_name ) ) + #~ elif self.declaration.create_with_signature: + #~ if self.wrapper: + #~ func_type = self.wrapper.function_type() + #~ else: + #~ func_type = self.declaration.function_type().decl_string + #~ result.append( '(%s)(&%s)' + #~ % ( func_type, full_name ) ) + #~ else: + #~ result.append( '&%s' % full_name ) - result = [] - result.append( 'typedef %s;' % ftype.create_typedef( self.function_type_alias, exported_class_alias ) ) - return ''.join( result ) + #~ return ''.join( result ) - def create_doc(self): - return None - def create_function_ref_code(self, use_function_alias=False): - if self.wrapper: - full_name = self.wrapper.default_full_name() - else: - full_name = declarations.full_name( self.declaration ) +#~ class mem_fun_v_transformed_wrapper_t( calldef_wrapper_t ): + #~ """Creates wrapper code for (public) virtual member functions. - result = [] - if use_function_alias: - result.append( '%s(&%s)' - % ( self.function_type_alias, full_name ) ) - elif self.declaration.create_with_signature: - if self.wrapper: - func_type = self.wrapper.function_type() - else: - func_type = self.declaration.function_type().decl_string - result.append( '(%s)(&%s)' - % ( func_type, full_name ) ) - else: - result.append( '&%s' % full_name ) + #~ The generated code consists of two functions: the virtual function + #~ and the 'default' function. + #~ """ - return ''.join( result ) + #~ def __init__( self, function ): + #~ """Constructor. + #~ @param function: Function declaration + #~ @type function: calldef_t + #~ """ + #~ calldef_wrapper_t.__init__( self, function=function ) -class mem_fun_v_transformed_wrapper_t( calldef_wrapper_t ): - """Creates wrapper code for (public) virtual member functions. - - The generated code consists of two functions: the virtual function - and the 'default' function. - """ - - def __init__( self, function ): - """Constructor. - - @param function: Function declaration - @type function: calldef_t - """ - calldef_wrapper_t.__init__( self, function=function ) - - # Create the substitution manager - sm = function_transformers.substitution_manager_t(function - , transformers=function.transformations[0].transformers ) + #~ # Create the substitution manager + #~ sm = function_transformers.substitution_manager_t(function + #~ , transformers=function.transformations[0].transformers ) - sm.init_funcs() - self._subst_manager = sm + #~ sm.init_funcs() + #~ self._subst_manager = sm - # Stores the name of the variable that holds the override - self._override_var \ - = sm.virtual_func.declare_variable(function.alias + "_callable", 'boost::python::override') - # Stores the name of the 'gstate' variable - self._gstate_var \ - = sm.virtual_func.declare_variable("gstate", 'pyplusplus::threading ::gil_guard_t' ) + #~ # Stores the name of the variable that holds the override + #~ self._override_var \ + #~ = sm.virtual_func.declare_variable(function.alias + "_callable", 'boost::python::override') + #~ # Stores the name of the 'gstate' variable + #~ self._gstate_var \ + #~ = sm.virtual_func.declare_variable("gstate", 'pyplusplus::threading ::gil_guard_t' ) - def default_name(self): - """Return the name of the 'default' function. + #~ def default_name(self): + #~ """Return the name of the 'default' function. - @rtype: str - """ - return "default_" + self.declaration.alias + #~ @rtype: str + #~ """ + #~ return "default_" + self.declaration.alias - def default_full_name(self): - """Return the full name of the 'default' function. + #~ def default_full_name(self): + #~ """Return the full name of the 'default' function. - The returned name also includes the class name. + #~ The returned name also includes the class name. - @rtype: str - """ - return self.parent.full_name + '::default_' + self.declaration.alias + #~ @rtype: str + #~ """ + #~ return self.parent.full_name + '::default_' + self.declaration.alias - def virtual_name(self): - """Return the name of the 'virtual' function. + #~ def virtual_name(self): + #~ """Return the name of the 'virtual' function. - @rtype: str - """ - return self.declaration.name + #~ @rtype: str + #~ """ + #~ return self.declaration.name - def base_name(self): - """Return the name of the 'base' function. + #~ def base_name(self): + #~ """Return the name of the 'base' function. - @rtype: str - """ - return "base_" + self.declaration.name + #~ @rtype: str + #~ """ + #~ return "base_" + self.declaration.name - def function_type(self): - template = '$RET_TYPE' - rettype = self._subst_manager.subst_wrapper(template) - rettype = declarations.dummy_type_t(rettype) + #~ def function_type(self): + #~ template = '$RET_TYPE' + #~ rettype = self._subst_manager.subst_wrapper(template) + #~ rettype = declarations.dummy_type_t(rettype) - return declarations.free_function_type_t( - return_type=rettype - , arguments_types=map( lambda arg: arg.type, self.declaration.arguments ) ) + #~ return declarations.free_function_type_t( + #~ return_type=rettype + #~ , arguments_types=map( lambda arg: arg.type, self.declaration.arguments ) ) - 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 ) + #~ 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 create_declaration(self, name, virtual=True): - """Create the function header. + #~ def create_declaration(self, name, virtual=True): + #~ """Create the function header. - This method is used for the virtual function (and the base_ function), - but not for the default function. - """ - template = '%(virtual)s$RET_TYPE %(name)s( $ARG_LIST_DEF )%(constness)s %(throw)s' + #~ This method is used for the virtual function (and the base_ function), + #~ but not for the default function. + #~ """ + #~ template = '%(virtual)s$RET_TYPE %(name)s( $ARG_LIST_DEF )%(constness)s %(throw)s' - # Substitute the $-variables - template = self._subst_manager.subst_virtual(template) + #~ # Substitute the $-variables + #~ template = self._subst_manager.subst_virtual(template) - virtualspec = '' - if virtual: - virtualspec = 'virtual ' + #~ virtualspec = '' + #~ if virtual: + #~ virtualspec = 'virtual ' - constness = '' - if self.declaration.has_const: - constness = ' const ' + #~ constness = '' + #~ if self.declaration.has_const: + #~ constness = ' const ' - return template % { - 'virtual' : virtualspec - , 'name' : name - , 'constness' : constness - , 'throw' : self.throw_specifier_code() - } + #~ return template % { + #~ 'virtual' : virtualspec + #~ , 'name' : name + #~ , 'constness' : constness + #~ , 'throw' : self.throw_specifier_code() + #~ } - def create_base_body(self): - body = "%(return_)s%(wrapped_class)s::%(name)s( %(args)s );" + #~ def create_base_body(self): + #~ body = "%(return_)s%(wrapped_class)s::%(name)s( %(args)s );" - return_ = '' - if not declarations.is_void( self.declaration.return_type ): - return_ = 'return ' + #~ return_ = '' + #~ if not declarations.is_void( self.declaration.return_type ): + #~ return_ = 'return ' - return body % { - 'name' : self.declaration.name - , 'args' : self.function_call_args() - , 'return_' : return_ - , 'wrapped_class' : self.wrapped_class_identifier() - } + #~ return body % { + #~ 'name' : self.declaration.name + #~ , 'args' : self.function_call_args() + #~ , 'return_' : return_ + #~ , 'wrapped_class' : self.wrapped_class_identifier() + #~ } - def create_virtual_body(self): + #~ def create_virtual_body(self): - thread_safe = self.declaration.transformations[0].thread_safe + #~ thread_safe = self.declaration.transformations[0].thread_safe - if thread_safe: - body = """ -pyplusplus::threading::gil_guard_t %(gstate_var)s; + #~ if thread_safe: + #~ body = """ +#~ pyplusplus::threading::gil_guard_t %(gstate_var)s; -%(gstate_var)s.ensure(); -boost::python::override %(override_var)s = this->get_override( "%(alias)s" ); -%(gstate_var)s.release(); +#~ %(gstate_var)s.ensure(); +#~ boost::python::override %(override_var)s = this->get_override( "%(alias)s" ); +#~ %(gstate_var)s.release(); -if( %(override_var)s ) -{ - // The corresponding release() is done in the destructor of %(gstate_var)s - %(gstate_var)s.ensure(); +#~ if( %(override_var)s ) +#~ { + #~ // The corresponding release() is done in the destructor of %(gstate_var)s + #~ %(gstate_var)s.ensure(); - $DECLARATIONS + #~ $DECLARATIONS - try { - $PRE_CALL + #~ try { + #~ $PRE_CALL - ${RESULT_VAR_ASSIGNMENT}boost::python::call<$RESULT_TYPE>($INPUT_PARAMS); + #~ ${RESULT_VAR_ASSIGNMENT}boost::python::call<$RESULT_TYPE>($INPUT_PARAMS); - $POST_CALL + #~ $POST_CALL - $RETURN_STMT - } - catch(...) - { - if (PyErr_Occurred()) - { - PyErr_Print(); - } + #~ $RETURN_STMT + #~ } + #~ catch(...) + #~ { + #~ if (PyErr_Occurred()) + #~ { + #~ PyErr_Print(); + #~ } - $CLEANUP + #~ $CLEANUP - $EXCEPTION_HANDLER_EXIT - } -} -else -{ - %(inherited)s -} -""" + #~ $EXCEPTION_HANDLER_EXIT + #~ } +#~ } +#~ else +#~ { + #~ %(inherited)s +#~ } +#~ """ - if not thread_safe: - body = """ -boost::python::override %(override_var)s = this->get_override( "%(alias)s" ); + #~ if not thread_safe: + #~ body = """ +#~ boost::python::override %(override_var)s = this->get_override( "%(alias)s" ); -if( %(override_var)s ) -{ - $DECLARATIONS +#~ if( %(override_var)s ) +#~ { + #~ $DECLARATIONS - $PRE_CALL + #~ $PRE_CALL - ${RESULT_VAR_ASSIGNMENT}boost::python::call<$RESULT_TYPE>($INPUT_PARAMS); + #~ ${RESULT_VAR_ASSIGNMENT}boost::python::call<$RESULT_TYPE>($INPUT_PARAMS); - $POST_CALL + #~ $POST_CALL - $RETURN_STMT -} -else -{ - %(inherited)s -} -""" + #~ $RETURN_STMT +#~ } +#~ else +#~ { + #~ %(inherited)s +#~ } +#~ """ - vf = self._subst_manager.virtual_func - arg0 = "%s.ptr()"%self._override_var - if vf.INPUT_PARAMS=="": - vf.INPUT_PARAMS = arg0 - else: - vf.INPUT_PARAMS = arg0+", "+vf.INPUT_PARAMS + #~ vf = self._subst_manager.virtual_func + #~ arg0 = "%s.ptr()"%self._override_var + #~ if vf.INPUT_PARAMS=="": + #~ vf.INPUT_PARAMS = arg0 + #~ else: + #~ vf.INPUT_PARAMS = arg0+", "+vf.INPUT_PARAMS - # Replace the $-variables - body = self._subst_manager.subst_virtual(body) + #~ # Replace the $-variables + #~ body = self._subst_manager.subst_virtual(body) - return body % { - 'override_var' : self._override_var - , 'gstate_var' : self._gstate_var - , 'alias' : self.declaration.alias - , 'inherited' : self.create_base_body() - } + #~ return body % { + #~ 'override_var' : self._override_var + #~ , 'gstate_var' : self._gstate_var + #~ , 'alias' : self.declaration.alias + #~ , 'inherited' : self.create_base_body() + #~ } - def create_default_body(self): - cls_wrapper_type = self.parent.full_name - cls_wrapper = self._subst_manager.wrapper_func.declare_variable("cls_wrapper", cls_wrapper_type); - # The name of the 'self' variable (i.e. first argument) - selfname = self._subst_manager.wrapper_func.arg_list[0].name + #~ def create_default_body(self): + #~ cls_wrapper_type = self.parent.full_name + #~ cls_wrapper = self._subst_manager.wrapper_func.declare_variable("cls_wrapper", cls_wrapper_type); + #~ # The name of the 'self' variable (i.e. first argument) + #~ selfname = self._subst_manager.wrapper_func.arg_list[0].name - body = """$DECLARATIONS + #~ body = """$DECLARATIONS -$PRE_CALL +#~ $PRE_CALL -%(cls_wrapper_type)s* %(cls_wrapper)s = dynamic_cast<%(cls_wrapper_type)s*>(boost::addressof(%(self)s)); -if (%(cls_wrapper)s==0) -{ - // The following call is done on an instance created in C++, - // so it won't invoke Python code. - $RESULT_VAR_ASSIGNMENT$CALL_FUNC_NAME($INPUT_PARAMS); -} -else -{ - // The following call is done on an instance created in Python, - // i.e. a wrapper instance. This call might invoke Python code. - $RESULT_VAR_ASSIGNMENT%(cls_wrapper)s->%(base_name)s($INPUT_PARAMS); -} +#~ %(cls_wrapper_type)s* %(cls_wrapper)s = dynamic_cast<%(cls_wrapper_type)s*>(boost::addressof(%(self)s)); +#~ if (%(cls_wrapper)s==0) +#~ { + #~ // The following call is done on an instance created in C++, + #~ // so it won't invoke Python code. + #~ $RESULT_VAR_ASSIGNMENT$CALL_FUNC_NAME($INPUT_PARAMS); +#~ } +#~ else +#~ { + #~ // The following call is done on an instance created in Python, + #~ // i.e. a wrapper instance. This call might invoke Python code. + #~ $RESULT_VAR_ASSIGNMENT%(cls_wrapper)s->%(base_name)s($INPUT_PARAMS); +#~ } -$POST_CALL +#~ $POST_CALL -$RETURN_STMT -""" +#~ $RETURN_STMT +#~ """ - # Replace the $-variables - body = self._subst_manager.subst_wrapper(body) + #~ # Replace the $-variables + #~ body = self._subst_manager.subst_wrapper(body) - # Replace the remaining parameters - body = body%{"cls_wrapper_type" : cls_wrapper_type, - "cls_wrapper" : cls_wrapper, - "self" : selfname, - "base_name" : self.base_name() } - return body + #~ # Replace the remaining parameters + #~ body = body%{"cls_wrapper_type" : cls_wrapper_type, + #~ "cls_wrapper" : cls_wrapper, + #~ "self" : selfname, + #~ "base_name" : self.base_name() } + #~ return body - def create_function(self): - answer = [ self.create_declaration(self.declaration.name) + '{' ] - answer.append( self.indent( self.create_virtual_body() ) ) - answer.append( '}' ) - return os.linesep.join( answer ) + #~ def create_function(self): + #~ answer = [ self.create_declaration(self.declaration.name) + '{' ] + #~ answer.append( self.indent( self.create_virtual_body() ) ) + #~ answer.append( '}' ) + #~ return os.linesep.join( answer ) - def create_base_function( self ): - answer = [ self.create_declaration("base_"+self.declaration.name, False) + '{' ] - body = "%(return_)s%(wrapped_class)s::%(name)s( %(args)s );" - answer.append( self.indent( self.create_base_body() ) ) - answer.append( '}' ) - return os.linesep.join( answer ) + #~ def create_base_function( self ): + #~ answer = [ self.create_declaration("base_"+self.declaration.name, False) + '{' ] + #~ body = "%(return_)s%(wrapped_class)s::%(name)s( %(args)s );" + #~ answer.append( self.indent( self.create_base_body() ) ) + #~ answer.append( '}' ) + #~ return os.linesep.join( answer ) - def create_default_function( self ): + #~ def create_default_function( self ): - header = 'static $RET_TYPE %s( $ARG_LIST_DEF ) {'%self.default_name() - header = self._subst_manager.subst_wrapper(header) + #~ header = 'static $RET_TYPE %s( $ARG_LIST_DEF ) {'%self.default_name() + #~ header = self._subst_manager.subst_wrapper(header) - answer = [ header ] - answer.append( self.indent( self.create_default_body() ) ) - answer.append( '}' ) - return os.linesep.join( answer ) + #~ answer = [ header ] + #~ answer.append( self.indent( self.create_default_body() ) ) + #~ answer.append( '}' ) + #~ return os.linesep.join( answer ) - def _create_impl(self): + #~ def _create_impl(self): - answer = [ self.create_function() ] - answer.append( os.linesep ) - answer.append( self.create_base_function() ) - answer.append( os.linesep ) - answer.append( self.create_default_function() ) - answer = os.linesep.join( answer ) + #~ answer = [ self.create_function() ] + #~ answer.append( os.linesep ) + #~ answer.append( self.create_base_function() ) + #~ answer.append( os.linesep ) + #~ answer.append( self.create_default_function() ) + #~ answer = os.linesep.join( answer ) - # Replace the argument list of the declaration so that in the - # case that keywords are created, the correct arguments will be - # picked up (i.e. the modified argument list and not the original - # argument list) - self.declaration.arguments = self._subst_manager.wrapper_func.arg_list + #~ # Replace the argument list of the declaration so that in the + #~ # case that keywords are created, the correct arguments will be + #~ # picked up (i.e. the modified argument list and not the original + #~ # argument list) + #~ self.declaration.arguments = self._subst_manager.wrapper_func.arg_list - return answer - \ No newline at end of file + #~ return answer + Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/__init__.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/__init__.py 2006-11-21 09:10:20 UTC (rev 741) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/__init__.py 2006-11-21 13:00:32 UTC (rev 742) @@ -26,22 +26,22 @@ return transformers.output_t( function, *args, **keywd ) return creator -def input( *args, **keywd ): - def creator( function ): - return transformers.input_t( function, *args, **keywd ) - return creator +#def input( *args, **keywd ): + #def creator( function ): + #return transformers.input_t( function, *args, **keywd ) + #return creator -def inout( *args, **keywd ): - def creator( function ): - return transformers.inout_t( function, *args, **keywd ) - return creator +#def inout( *args, **keywd ): + #def creator( function ): + #return transformers.inout_t( function, *args, **keywd ) + #return creator -def input_array( *args, **keywd ): - def creator( function ): - return transformers.input_array_t( function, *args, **keywd ) - return creator +#def input_array( *args, **keywd ): + #def creator( function ): + #return transformers.input_array_t( function, *args, **keywd ) + #return creator -def output_array( *args, **keywd ): - def creator( function ): - return transformers.output_array_t( function, *args, **keywd ) - return creator +#def output_array( *args, **keywd ): + #def creator( function ): + #return transformers.output_array_t( function, *args, **keywd ) + #return creator \ No newline at end of file Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py 2006-11-21 09:10:20 UTC (rev 741) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py 2006-11-21 13:00:32 UTC (rev 742) @@ -32,7 +32,15 @@ self.__function = function self.__variables = {} #name : variable self.__names_in_use = set( map( lambda arg: arg.name, self.function.arguments ) ) + + @property + def function( self ): + return self.__function + @property + def variables( self ): + return self.__variables + def declare_variable( self, type, name, initialize_expr='' ): unique_name = self.__create_unique_var_name( name ) self.__variables[ unique_name ] = variable_t( type, unique_name, initialize_expr ) @@ -52,6 +60,7 @@ return unique_name class mem_fun_controller_t( controller_base_t ): + def __init__( self, function ): controller_base_t.__init__( self, function ) self.__wrapper_args = function.arguments[:] @@ -64,7 +73,12 @@ self.__arg_expressions = [ arg.name for arg in function.arguments ] self.__return_stmt = None + @property + def template( self ): + return templates.mem_fun.body + + @property def wrapper_args( self ): return self.__wrapper_args @@ -106,7 +120,7 @@ self.__pre_call.append( code ) @property - def pos_call( self ): + def post_call( self ): return self.__post_call def add_post_call_code( self, code ): Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/function_transformation.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/function_transformation.py 2006-11-21 09:10:20 UTC (rev 741) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/function_transformation.py 2006-11-21 13:00:32 UTC (rev 742) @@ -3,15 +3,16 @@ # accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) - """This module contains the class L{function_transformation_t}. """ +import controllers class function_transformation_t: def __init__(self, function, transformer_creator, **keywd): """Constructor. """ self.__function = function + self.__controller = controllers.mem_fun_controller_t( function ) self.__transformers = map( lambda tr_creator: tr_creator( function ), transformer_creator ) self.__thread_safe = keywd.get( 'thread_safe', False ) @@ -19,6 +20,10 @@ def transformers( self ): return self.__transformers + @property + def controller( self ): + return self.__controller + def required_headers( self ): headers = [] map( lambda transformer: headers.extend( transformer.required_headers() ) Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/templates.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/templates.py 2006-11-21 09:10:20 UTC (rev 741) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/templates.py 2006-11-21 13:00:32 UTC (rev 742) @@ -15,7 +15,7 @@ body = Template( os.linesep.join([ '$declare_variables' , '$pre_call' - , '$save_return_value_stmt$function_name($input_params);' + , '$save_return_value_stmt$function($arg_expressions);' , '$post_call' , '$return_stmt' ])) @@ -26,7 +26,7 @@ override_body = Template( os.linesep.join([ '$declare_variables' - , '$declare_override_function = this->get_override( "$function_alias" );' + , 'boost::python::override $override_function_var_name = this->get_override( "$function_alias" );' , 'if( $override_function_var_name ){' , ' $declare_override_variables' , ' $override_pre_call' Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/transformer.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/transformer.py 2006-11-21 09:10:20 UTC (rev 741) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/transformer.py 2006-11-21 13:00:32 UTC (rev 742) @@ -59,82 +59,5 @@ else: return self.get_argument( reference ).type - def init_funcs(self, sm): - """Wrapper initialization. - - This method is called before the actual wrapper source code is - generated. This is the place where you can modify the signature - of the C++ wrapper function or allocate local variables. - - @param sm: Substitution manager instance - @type sm: L{substitution_manager_t} - """ - pass - - def wrapper_pre_call(self, sm): - """Generate the C++ code that should be executed before the actual function call. - - The code from this method will be put into the wrapper function. - - @param sm: Substitution manager instance - @type sm: L{substitution_manager_t} - @return: C++ code or None - @rtype: str - """ - pass - - def wrapper_post_call(self, sm): - """Generate the C++ code that should be executed after the actual function call. - - The code from this method will be put into the wrapper function. - - @param sm: Substitution manager instance - @type sm: L{substitution_manager_t} - @return: C++ code or None - @rtype: str - """ - pass - - def wrapper_cleanup(self, sm): - """Generate code that should be executed in the case of an error. - - This method has to assume that the preCall code was executed but - the postCall code won't be executed because something went wrong. - - <not used yet> - - @param sm: Substitution manager instance - @type sm: L{substitution_manager_t} - @return: C++ code or None - @rtype: str - """ - pass - - def virtual_pre_call(self, sm): - """Generate the C++ code that should be executed before the actual function call. - - The code from this method will be put into the virtual function. - - @param sm: Substitution manager instance - @type sm: L{substitution_manager_t} - @return: C++ code or None - @rtype: str - """ - pass - - def virtual_post_call(self, sm): - """Generate the C++ code that should be executed after the actual function call. - - The code from this method will be put into the virtual function. - - @param sm: Substitution manager instance - @type sm: L{substitution_manager_t} - @return: C++ code or None - @rtype: str - """ - pass - - def virtual_cleanup(self, sm): - pass - - + def configure_mem_fun( self, controller ): + pass \ No newline at end of file Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py 2006-11-21 09:10:20 UTC (rev 741) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py 2006-11-21 13:00:32 UTC (rev 742) @@ -17,6 +17,7 @@ """ import os import transformer +import controllers from pygccxml import declarations from pyplusplus import code_repository @@ -58,8 +59,7 @@ """ self.arg = self.get_argument( arg_ref ) self.arg_index = self.function.arguments.index( self.arg ) - self.local_var = "<not initialized>" - + if not is_ref_or_ptr( self.arg.type ): raise ValueError( '%s\nin order to use "output" transformation, argument %s type must be a reference or a pointer (got %s).' ) \ % ( function, self.arg_ref.name, arg.type) @@ -67,286 +67,14 @@ def __str__(self): return "output(%d)"%(self.arg_index) - def init_funcs(self, sm): - # Remove the specified output argument from the wrapper function - sm.remove_arg(self.arg_index+1) + def configure_mem_fun( self, controller ): + assert isinstance( controller, controllers.mem_fun_controller_t ) + #removing arg from the function wrapper definition + controller.remove_wrapper_arg( self.arg.name ) + #declaring new variable, which will keep result + var_name = controller.declare_variable( remove_ref_or_ptr( self.arg.type ), self.arg.name ) + #adding just declared variable to the original function call expression + controller.modify_argument_expression( self.arg_index, var_name ) + #adding the variable to return variables list + controller.return_variable( var_name ) - # Declare a local variable that will receive the output value - self.local_var = sm.wrapper_func.declare_variable( self.arg.name, str( remove_ref_or_ptr( self.arg.type ) ) ) - # Append the output to the result tuple - sm.wrapper_func.result_exprs.append(self.local_var) - - # Replace the expression in the C++ function call - input_param = self.local_var - if declarations.is_pointer( self.arg.type ): - input_param = "&%s" % self.local_var - - sm.wrapper_func.input_params[self.arg_index] = input_param - - - def virtual_post_call(self, sm): - """Extract the C++ value after the call to the Python function.""" - res = [] - if declarations.is_pointer( self.arg.type ): - res.append( "*" ) - res.append( "%s = boost::python::extract<%s>(%s);" \ - % ( self.arg.name - , remove_ref_or_ptr( self.arg.type ) - , sm.py_result_expr(self.local_var) ) ) - return ''.join( res ) - -# input_t -class input_t(transformer.transformer_t): - """Handles a single input variable. - - The reference on the specified variable is removed. - - void setValue(int& v) -> setValue(v) - """ - - def __init__(self, function, arg_ref): - """Constructor. - - The specified argument must be a reference or a pointer. - - @param idx: Index of the argument that is an output value (the first arg has index 1). - @type idx: int - """ - transformer.transformer_t.__init__( self, function ) - self.arg = self.get_argument( arg_ref ) - self.arg_index = self.function.arguments.index( self.arg ) - - if not is_ref_or_ptr( self.arg.type ): - raise ValueError( '%s\nin order to use "input" transformation, argument %s type must be a reference or a pointer (got %s).' ) \ - % ( function, self.arg_ref.name, arg.type) - - def __str__(self): - return "input(%d)"%(self.idx) - - def init_funcs(self, sm): - # Remove the specified input argument from the wrapper function - sm.remove_arg(self.arg_index + 1) - - # Create an equivalent argument that is not a reference type - noref_arg = self.arg.clone( type=remove_ref_or_ptr( self.arg.type ) ) - # Insert the noref argument - sm.insert_arg(self.arg_index + 1, noref_arg, self.arg.name) - -# inout_t -class inout_t(transformer.transformer_t): - """Handles a single input/output variable. - - void foo(int& v) -> v = foo(v) - """ - - def __init__(self, function, arg_ref): - """Constructor. - - The specified argument must be a reference or a pointer. - - @param idx: Index of the argument that is an in/out value (the first arg has index 1). - @type idx: int - """ - transformer.transformer_t.__init__( self, function ) - self.arg = self.get_argument( arg_ref ) - self.arg_index = self.function.arguments.index( self.arg ) - self.local_var = "<not initialized>" - - if not is_ref_or_ptr( self.arg.type ): - raise ValueError( '%s\nin order to use "inout" transformation, argument %s type must be a reference or a pointer (got %s).' ) \ - % ( function, self.arg_ref.name, arg.type) - - def __str__(self): - return "inout(%d)"%(self.arg_index) - - def init_funcs(self, sm): - # Remove the specified input argument from the wrapper function - sm.remove_arg(self.arg_index + 1) - - # Create an equivalent argument that is not a reference type - noref_arg = self.arg.clone( type=remove_ref_or_ptr( self.arg.type ) ) - - # Insert the noref argument - sm.insert_arg(self.idx+1, noref_arg, arg.name) - - # Use the input arg to also store the output - self.local_var = noref_arg.name - # Append the output to the result tuple - sm.wrapper_func.result_exprs.append(self.local_var) - - # Replace the expression in the C++ function call - input_param = self.local_var - if declarations.is_pointer( self.arg.type ): - input_param = "&%s" % self.local_var - - sm.wrapper_func.input_params[self.arg_index] = input_param - - def virtual_post_call(self, sm): - """Extract the C++ value after the call to the Python function.""" - res = [] - if isinstance(arg.type, declarations.pointer_t): - res.append( "*" ) - res.append( "%s = boost::python::extract<%s>(%s);" - % ( self.arg.name - , remove_ref_or_ptr( self.arg.type ) - , sm.py_result_expr( self.local_var ) ) ) - return ''.join( res ) - -# input_array_t -class input_array_t(transformer.transformer_t): - """Handles an input array with fixed size. - - void setVec3(double* v) -> setVec3(object v) - # v must be a sequence of 3 floats - """ - - def __init__(self, function, arg_ref, array_size): - """Constructor. - - @param size: The fixed size of the input array - @type size: int - """ - transformer.transformer_t.__init__( self, function ) - - self.arg = self.get_argument( arg_ref ) - self.arg_index = self.function.arguments.index( self.arg ) - - if not is_ptr_or_array( self.arg.type ): - raise ValueError( '%s\nin order to use "input_array" transformation, argument %s type must be a array or a pointer (got %s).' ) \ - % ( function, self.arg_ref.name, arg.type) - - self.array_size = array_size - self.native_array = None - self.pylist = None - - def __str__(self): - return "input_array(%s,%d)"%( self.arg.name, self.array_size) - - def required_headers( self ): - """Returns list of header files that transformer generated code depends on.""" - return [ code_repository.convenience.file_name ] - - def init_funcs(self, sm): - # Remove the original argument... - sm.remove_arg(self.arg_index + 1) - - # Declare a variable that will hold the Python list - # (this will be the input of the Python call in the virtual function) - self.pylist = sm.virtual_func.declare_variable("py_" + self.arg.name, "boost::python::list") - - # Replace the removed argument with a Python object. - newarg = self.arg.clone( type=declarations.dummy_type_t("boost::python::object") ) - sm.insert_arg(self.arg_index+1, newarg, self.pylist) - - # Declare a variable that will hold the C array... - self.native_array = sm.wrapper_func.declare_variable( - "native_" + self.arg.name - , declarations.array_item_type( self.arg.type ) - , '[%d]' % self.array_size) - - # Replace the input parameter with the C array - sm.wrapper_func.input_params[self.arg_index] = self.native_array - - def wrapper_pre_call(self, sm): - """Wrapper function code. - """ - tmpl = [] - tmpl.append( '%(pypp_con)s::ensure_uniform_sequence< %(type)s >( %(pylist)s, %(array_size)d );' ) - tmpl.append( '%(pypp_con)s::copy_sequence( %(pylist)s, %(pypp_con)s::array_inserter( %(native_array)s, %(array_size)d ) );' ) - return os.linesep.join( tmpl ) % { - 'type' : declarations.array_item_type( self.arg.type ) - , 'pypp_con' : 'pyplusplus::convenience' - , 'pylist' : self.arg.name - , 'array_size' : self.array_size - , 'native_array' : self.native_array - } - - def virtual_pre_call(self, sm): - """Virtual function code.""" - tmpl = '%(pypp_con)s::copy_container( %(native_array)s, %(native_array)s + %(array_size)d, %(pypp_con)s::list_inserter( %(pylist)s ) );' - return tmpl % { - 'pypp_con' : 'pyplusplus::convenience' - , 'native_array' : self.arg.name - , 'array_size' : self.array_size - , 'pylist' : self.pylist - } - - -# output_array_t -class output_array_t(transformer.transformer_t): - """Handles an output array of a fixed size. - - void getVec3(double* v) -> v = getVec3() - # v will be a list with 3 floats - """ - - def __init__(self, function, arg_ref, size): - """Constructor. - - @param idx: Index of the argument that is an output array (the first arg has index 1). - @type idx: int - @param size: The fixed size of the output array - @type size: int - """ - transformer.transformer_t.__init__( self, function ) - self.arg = self.get_argument( arg_ref ) - self.arg_index = self.function.arguments.index( self.arg ) - - if not is_ptr_or_array( self.arg.type ): - raise ValueError( '%s\nin order to use "input_array" transformation, argument %s type must be a array or a pointer (got %s).' ) \ - % ( function, self.arg_ref.name, arg.type) - - self.array_size = size - self.native_array = None - self.pylist = None - - def __str__(self): - return "output_array(%s,%d)"%( self.arg.name, self.array_size) - - def required_headers( self ): - """Returns list of header files that transformer generated code depends on.""" - return [ code_repository.convenience.file_name ] - - def init_funcs(self, sm): - # Remove the original argument... - sm.remove_arg(self.arg_index + 1) - - # Declare a variable that will hold the C array... - self.native_array = sm.wrapper_func.declare_variable( - "native_" + self.arg.name - , declarations.array_item_type( self.arg.type ) - , '[%d]' % self.array_size) - - # Declare a Python list which will receive the output... - self.pylist = sm.wrapper_func.declare_variable( - 'py_' + self.arg.name - , "boost::python::list" ) - - # ...and add it to the result - sm.wrapper_func.result_exprs.append(self.pylist) - - sm.wrapper_func.input_params[ self.arg_index ] = self.native_array - - self.virtual_pylist = sm.virtual_func.declare_variable("py_"+self.arg.name, "boost::python::object") - - def wrapper_post_call(self, sm): - tmpl = '%(pypp_con)s::copy_container( %(native_array)s, %(native_array)s + %(array_size)d, %(pypp_con)s::list_inserter( %(pylist)s ) );' - return tmpl % { - 'pypp_con' : 'pyplusplus::convenience' - , 'native_array' : self.native_array - , 'array_size' : self.array_size - , 'pylist' : self.pylist - } - - def virtual_post_call(self, sm): - tmpl = [] - tmpl.append( '%(pypp_con)s::ensure_uniform_sequence< %(type)s >( %(pylist)s, %(array_size)d );' ) - tmpl.append( '%(pypp_con)s::copy_sequence( %(pylist)s, %(pypp_con)s::array_inserter( %(native_array)s, %(array_size)d ) );' ) - return os.linesep.join( tmpl ) % { - 'type' : declarations.array_item_type( self.arg.type ) - , 'pypp_con' : 'pyplusplus::convenience' - , 'pylist' : sm.py_result_expr(self.pylist) - , 'array_size' : self.array_size - , 'native_array' : self.arg.name - } - 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-21 09:10:20 UTC (rev 741) +++ pyplusplus_dev_ft/unittests/data/function_transformations_to_be_exported.hpp 2006-11-21 13:00:32 UTC (rev 742) @@ -17,7 +17,7 @@ // 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 ){ + void get_size( unsigned int& h, unsigned int& w ){ h = m_height; w = m_width; } Modified: pyplusplus_dev_ft/unittests/function_transformations_tester.py =================================================================== --- pyplusplus_dev_ft/unittests/function_transformations_tester.py 2006-11-21 09:10:20 UTC (rev 741) +++ pyplusplus_dev_ft/unittests/function_transformations_tester.py 2006-11-21 13:00:32 UTC (rev 742) @@ -19,24 +19,29 @@ , *args ) def customize( self, mb ): + mb.namespace( 'ft' ).exclude() image = mb.class_( "image_t" ) + image.include() + image.add_wrapper_code( '' ) + 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_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( "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() + #~ 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( "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() - 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[0]=="_").exclude() def run_tests(self, module): """Run the actual unit tests. @@ -49,101 +54,101 @@ # Check a method that returns two values by reference self.assertEqual(img.get_size(), (2,6)) - # Check a method that only returns one value by reference - self.a... [truncated message content] |
From: <rom...@us...> - 2006-11-21 20:48:01
|
Revision: 743 http://svn.sourceforge.net/pygccxml/?rev=743&view=rev Author: roman_yakovenko Date: 2006-11-21 12:47:59 -0800 (Tue, 21 Nov 2006) Log Message: ----------- the generated code could be compiled Modified Paths: -------------- pyplusplus_dev_ft/pyplusplus/code_creators/calldef.py pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py pyplusplus_dev_ft/pyplusplus/code_creators/calldef_utils.py pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py pyplusplus_dev_ft/pyplusplus/function_transformers/function_transformation.py pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py pyplusplus_dev_ft/pyplusplus/module_builder/builder.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-21 13:00:32 UTC (rev 742) +++ pyplusplus_dev_ft/pyplusplus/code_creators/calldef.py 2006-11-21 20:47:59 UTC (rev 743) @@ -93,8 +93,10 @@ result.append( self.create_function_ref_code( not self.works_on_instance ) ) if self.declaration.use_keywords: - result.append( self.param_sep() ) - result.append( self.keywords_args() ) + keywd_args = self.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(): Modified: pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py 2006-11-21 13:00:32 UTC (rev 742) +++ pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py 2006-11-21 20:47:59 UTC (rev 743) @@ -21,7 +21,8 @@ def __init__( self, function, wrapper=None ): calldef_t.__init__( self, function=function, wrapper=wrapper ) - + #map( lambda transformer: transformer.configure_mem_fun + @property def ft( self ): #function transformation return self.declaration.transformations[0] @@ -98,16 +99,18 @@ def create_body(self): cntrl = self.ft.controller - arg_utils = calldef_utils.argument_utils_t( - self.declaration - , algorithm.make_id_creator( self ) - , cntrl.wrapper_args ) - + save_return_value_stmt = '' + if not cntrl.save_return_value_stmt \ + and not declarations.is_void( self.declaration.return_type ): + save_return_value_stmt = '%(type)s %(name)s = ' \ + % { 'type': cntrl.result_variable.type.decl_string + , 'name' : cntrl.result_variable.name } + return cntrl.template.substitute( - declare_variables=map( lambda var: var.declare_var_string(), cntrl.variables ) + 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 ) - , save_return_value_stmt=cntrl.save_return_value_stmt + , save_return_value_stmt=save_return_value_stmt , function=self.__this_arg.name + '.' + self.declaration.name , arg_expressions=self.PARAM_SEPARATOR.join( cntrl.arg_expressions ) , return_stmt='' @@ -443,4 +446,4 @@ #~ self.declaration.arguments = self._subst_manager.wrapper_func.arg_list #~ return answer - + \ No newline at end of file Modified: pyplusplus_dev_ft/pyplusplus/code_creators/calldef_utils.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/code_creators/calldef_utils.py 2006-11-21 13:00:32 UTC (rev 742) +++ pyplusplus_dev_ft/pyplusplus/code_creators/calldef_utils.py 2006-11-21 20:47:59 UTC (rev 743) @@ -39,6 +39,8 @@ return False def keywords_args(self): + if not self.__args: + return '' boost_arg = self.__id_creator( '::boost::python::arg' ) boost_obj = self.__id_creator( '::boost::python::object' ) result = ['( '] Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py 2006-11-21 13:00:32 UTC (rev 742) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py 2006-11-21 20:47:59 UTC (rev 743) @@ -3,7 +3,7 @@ from pygccxml import declarations class variable_t( object ): - def __init__( self, name, type, initialize_expr='' ): + def __init__( self, type, name, initialize_expr='' ): self.__name = name self.__type = type self.__initialize_expr = initialize_expr @@ -30,7 +30,7 @@ def __init__( self, function ): object.__init__( self ) self.__function = function - self.__variables = {} #name : variable + self.__variables = [] #variables self.__names_in_use = set( map( lambda arg: arg.name, self.function.arguments ) ) @property @@ -43,7 +43,8 @@ def declare_variable( self, type, name, initialize_expr='' ): unique_name = self.__create_unique_var_name( name ) - self.__variables[ unique_name ] = variable_t( type, unique_name, initialize_expr ) + self.__variables.append( variable_t( type, unique_name, initialize_expr ) ) + return unique_name def register_variable_name( self, name ): return self.__create_unique_var_name( name ) @@ -53,19 +54,23 @@ unique_name = name while 1: if unique_name in self.__names_in_use: - unique_name = "%s_%d" % ( name, n ) + unique_name = "%s%d" % ( name, n ) n += 1 else: self.__names_in_use.add( unique_name ) return unique_name + def apply( self, transformations ): + raise NotImplementedError() + class mem_fun_controller_t( controller_base_t ): def __init__( self, function ): controller_base_t.__init__( self, function ) self.__wrapper_args = function.arguments[:] self.__wrapper_return_type = function.return_type - + self.__result_var = variable_t( self.function.return_type + , self.register_variable_name( 'result' ) ) self.__return_variables = [] self.__pre_call = [] self.__post_call = [] @@ -73,6 +78,12 @@ self.__arg_expressions = [ arg.name for arg in function.arguments ] self.__return_stmt = None + def apply( self, transformations ): + map( lambda t: t.configure_mem_fun( self ), transformations ) + + @property + def result_variable( self ): + return self.__result_var @property def template( self ): @@ -110,7 +121,7 @@ return self.__return_variables def return_variable( self, variable_name ): - self.__return_variables.append( name ) + self.__return_variables.append( variable_name ) @property def pre_call( self ): @@ -142,3 +153,4 @@ def set_return_stmt( self, stmt ): self.__return_stmt = stmt + Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/function_transformation.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/function_transformation.py 2006-11-21 13:00:32 UTC (rev 742) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/function_transformation.py 2006-11-21 20:47:59 UTC (rev 743) @@ -15,6 +15,7 @@ self.__controller = controllers.mem_fun_controller_t( function ) self.__transformers = map( lambda tr_creator: tr_creator( function ), transformer_creator ) self.__thread_safe = keywd.get( 'thread_safe', False ) + self.__controller.apply( self.__transformers ) @property def transformers( self ): Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py 2006-11-21 13:00:32 UTC (rev 742) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py 2006-11-21 20:47:59 UTC (rev 743) @@ -77,4 +77,3 @@ controller.modify_argument_expression( self.arg_index, var_name ) #adding the variable to return variables list controller.return_variable( var_name ) - Modified: pyplusplus_dev_ft/pyplusplus/module_builder/builder.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/module_builder/builder.py 2006-11-21 13:00:32 UTC (rev 742) +++ pyplusplus_dev_ft/pyplusplus/module_builder/builder.py 2006-11-21 20:47:59 UTC (rev 743) @@ -378,7 +378,8 @@ , header_dir=header_dir , header_file=header_file , recursive=recursive) - + var = variable + def variables( self, name=None, function=None, type=None, header_dir=None, header_file=None, recursive=None ): """Please see L{decl_wrappers.scopedef_t} class documentation""" return self.global_ns.variables( name=name @@ -387,7 +388,8 @@ , header_dir=header_dir , header_file=header_file , recursive=recursive) - + vars = variables + def calldef( self, name=None, function=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None ): """Please see L{decl_wrappers.scopedef_t} class documentation""" return self.global_ns.calldef( name=name @@ -441,6 +443,7 @@ , header_dir=header_dir , header_file=header_file , recursive=recursive ) + mem_fun = member_function def member_functions( self, name=None, function=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None ): """Please see L{decl_wrappers.scopedef_t} class documentation""" @@ -452,6 +455,8 @@ , header_file=header_file , recursive=recursive) + mem_funs = member_functions + def constructor( self, name=None, function=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None ): """Please see L{decl_wrappers.scopedef_t} class documentation""" return self.global_ns.constructor( name=name @@ -554,7 +559,8 @@ , header_dir=header_dir , header_file=header_file , recursive=recursive ) - + free_fun = free_function + def free_functions( self, name=None, function=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None ): """Please see L{decl_wrappers.namespace_t} class documentation""" return self.global_ns.free_functions( name=name @@ -564,7 +570,8 @@ , header_dir=header_dir , header_file=header_file , recursive=recursive) - + free_funs = free_functions + def free_operator( self, name=None, function=None, symbol=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None ): """Please see L{decl_wrappers.namespace_t} class documentation""" return self.global_ns.free_operator( name=name 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-21 13:00:32 UTC (rev 742) +++ pyplusplus_dev_ft/unittests/data/function_transformations_to_be_exported.hpp 2006-11-21 20:47:59 UTC (rev 743) @@ -6,98 +6,116 @@ #ifndef __function_transformations_to_be_exported_hpp__ #define __function_transformations_to_be_exported_hpp__ -namespace ft{ +namespace ft2{ + +struct calculator_t{ + + int assign_0_1_2( int& one, int& two ){ + one = 1; + two = 2; + return 0; + } + + void assign_1_2( int& one, int& two ){ + assign_0_1_2( one, two ); + } + +}; -struct image_t{ +} - image_t( unsigned int h, unsigned int w ) - : m_height( h ) - , m_width( w ) - {} +//~ namespace ft{ - // Made the method 'virtual' for now because func transformers - // are currently only taken into account on virtual functions. - void get_size( unsigned int& h, unsigned int& w ){ - h = m_height; - w = m_width; - } +//~ struct image_t{ - // Return only one value - virtual void get_one_value(unsigned int& h) { - h = m_height; - } + //~ image_t( unsigned int h, unsigned int w ) + //~ : m_height( h ) + //~ , m_width( w ) + //~ {} - // 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; - } + //~ // Made the method 'virtual' for now because func transformers + //~ // are currently only taken into account on virtual functions. + //~ void get_size( unsigned int& h, unsigned int& w ){ + //~ h = m_height; + //~ w = m_width; + //~ } - // A method with an input argument - virtual int input_arg(int& in){ - return in; - } + //~ // Return only one value + //~ virtual void get_one_value(unsigned int& h) { + //~ h = m_height; + //~ } - // A method taking an input array of fixed size - virtual int fixed_input_array(int v[3]) { - return v[0]+v[1]+v[2]; - } + //~ // 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 a output array of fixed size - virtual void fixed_output_array(int v[3]) { - v[0] = 1; - v[1] = 2; - v[2] = 3; - } + //~ // A method with an input argument + //~ virtual int input_arg(int& in){ + //~ return in; + //~ } - unsigned int m_width; - unsigned int m_height; + //~ // A method taking an input array of fixed size + //~ virtual int fixed_input_array(int v[3]) { + //~ return v[0]+v[1]+v[2]; + //~ } -}; + //~ // A method with a output array of fixed size + //~ virtual void fixed_output_array(int v[3]) { + //~ v[0] = 1; + //~ v[1] = 2; + //~ v[2] = 3; + //~ } -// 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; -} + //~ unsigned int m_width; + //~ unsigned int m_height; -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; -} +//~ // 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; +//~ } -// This is used for calling img.fixed_output_array() on an instance passed -// in by Python. -int image_fixed_output_array( image_t& img) { - int v[3]; - img.fixed_output_array(v); - return v[0]+v[1]+v[2]; -} +//~ 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; +//~ } -// A class without any virtual members -struct no_virtual_members_t -{ - bool member(int& v) { v=17; return true; } -}; +//~ // This is used for calling img.fixed_output_array() on an instance passed +//~ // in by Python. +//~ int image_fixed_output_array( image_t& img) { + //~ int v[3]; + //~ img.fixed_output_array(v); + //~ return v[0]+v[1]+v[2]; +//~ } -struct ft_private_destructor_t{ - static void get_value( int& x ){ x = 21; } -private: - ~ft_private_destructor_t(){} -}; +//~ ////////////////////////////////////////////////////////////////////// -} +//~ // 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(){} +//~ }; + +//~ } + #endif//__function_transformations_to_be_exported_hpp__ Modified: pyplusplus_dev_ft/unittests/function_transformations_tester.py =================================================================== --- pyplusplus_dev_ft/unittests/function_transformations_tester.py 2006-11-21 13:00:32 UTC (rev 742) +++ pyplusplus_dev_ft/unittests/function_transformations_tester.py 2006-11-21 20:47:59 UTC (rev 743) @@ -19,13 +19,17 @@ , *args ) def customize( self, mb ): - mb.namespace( 'ft' ).exclude() - image = mb.class_( "image_t" ) - image.include() - image.add_wrapper_code( '' ) - image.member_functions().exclude() - image.member_function( "get_size" ).include() - image.member_function( "get_size" ).add_transformation( ft.output(0), ft.output(1) ) + calc = mb.class_('calculator_t' ) + 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) ) + + #~ image = mb.class_( "image_t" ) + #~ image.include() + #~ image.add_wrapper_code( '' ) + #~ 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_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) ) @@ -49,10 +53,10 @@ ####### Do the tests directly on the wrapper C++ class ######## - 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) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-21 21:59:02
|
Revision: 745 http://svn.sourceforge.net/pygccxml/?rev=745&view=rev Author: roman_yakovenko Date: 2006-11-21 13:59:01 -0800 (Tue, 21 Nov 2006) Log Message: ----------- generated code now works as expected 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/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-21 20:48:45 UTC (rev 744) +++ pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py 2006-11-21 21:59:01 UTC (rev 745) @@ -99,22 +99,35 @@ def create_body(self): cntrl = self.ft.controller - save_return_value_stmt = '' - if not cntrl.save_return_value_stmt \ - and not declarations.is_void( self.declaration.return_type ): - save_return_value_stmt = '%(type)s %(name)s = ' \ - % { 'type': cntrl.result_variable.type.decl_string - , 'name' : cntrl.result_variable.name } + + 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 } + + 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 ) + elif not declarations.is_void( self.declaration.return_type ): + return_stmt = cntrl.result_variable.name + else: + pass + if return_stmt: + return_stmt = 'return ' + return_stmt + ';' - 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 ) - , save_return_value_stmt=save_return_value_stmt - , function=self.__this_arg.name + '.' + self.declaration.name - , arg_expressions=self.PARAM_SEPARATOR.join( cntrl.arg_expressions ) - , return_stmt='' - ) + 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 ) + , 'save_result' : result_var_assign + , 'function' : self.__this_arg.name + '.' + self.declaration.name + , 'arg_expressions' : self.PARAM_SEPARATOR.join( cntrl.arg_expressions ) + , 'return' : return_stmt + }) def _create_impl(self): answer = ['// Transformed wrapper function for "%s"' % self.declaration ] @@ -446,4 +459,4 @@ #~ self.declaration.arguments = self._subst_manager.wrapper_func.arg_list #~ return answer - \ No newline at end of file + Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py 2006-11-21 20:48:45 UTC (rev 744) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py 2006-11-21 21:59:01 UTC (rev 745) @@ -68,7 +68,6 @@ def __init__( self, function ): controller_base_t.__init__( self, function ) self.__wrapper_args = function.arguments[:] - self.__wrapper_return_type = function.return_type self.__result_var = variable_t( self.function.return_type , self.register_variable_name( 'result' ) ) self.__return_variables = [] @@ -76,7 +75,6 @@ self.__post_call = [] self.__save_return_value_stmt = None self.__arg_expressions = [ arg.name for arg in function.arguments ] - self.__return_stmt = None def apply( self, transformations ): map( lambda t: t.configure_mem_fun( self ), transformations ) @@ -107,14 +105,13 @@ def modify_argument_expression( self, index, expression ): self.arg_expressions[ index ] = expression - - def __get_wrapper_return_type( self ): - return self.__wrapper_return_type - def __set_wrapper_return_type( self, type_ ): - if isinstane( type, types.StringTypes ): - type_ = declarations.dummy_type_t( type_ ) - self.__wrapper_return_type = type_ - wrapper_return_type = property( __get_wrapper_return_type, __set_wrapper_return_type ) + + @property + def wrapper_return_type( self ): + if len( self.return_variables ): + return declarations.dummy_type_t( 'boost::python::tuple' ) + else: + return self.function.return_type @property def return_variables( self ): @@ -136,12 +133,6 @@ def add_post_call_code( self, code ): self.__post_call.append( code ) - - def __get_save_return_value_stmt( self ): - return self.__save_return_value_stmt - def __set_save_return_value_stmt( self, expr ): - self.__save_return_value_stmt = expr - save_return_value_stmt = property( __get_save_return_value_stmt, __set_save_return_value_stmt ) def set_input_param( self, index, var_name_or_expr ): self.__input_params[ index ] = var_name_or_expr Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/templates.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/templates.py 2006-11-21 20:48:45 UTC (rev 744) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/templates.py 2006-11-21 21:59:01 UTC (rev 745) @@ -15,9 +15,9 @@ body = Template( os.linesep.join([ '$declare_variables' , '$pre_call' - , '$save_return_value_stmt$function($arg_expressions);' + , '$save_result$function($arg_expressions);' , '$post_call' - , '$return_stmt' + , '$return' ])) class mem_fun_v: Modified: pyplusplus_dev_ft/unittests/function_transformations_tester.py =================================================================== --- pyplusplus_dev_ft/unittests/function_transformations_tester.py 2006-11-21 20:48:45 UTC (rev 744) +++ pyplusplus_dev_ft/unittests/function_transformations_tester.py 2006-11-21 21:59:01 UTC (rev 745) @@ -52,7 +52,9 @@ """ ####### Do the tests directly on the wrapper C++ class ######## - + calc = module.calculator_t() + self.failUnless( ( 0, 1, 2 ) == calc.assign_0_1_2() ) + self.failUnless( ( 1, 2 ) == calc.assign_1_2() ) #~ 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. |
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. |
From: <rom...@us...> - 2006-11-22 15:20:50
|
Revision: 748 http://svn.sourceforge.net/pygccxml/?rev=748&view=rev Author: roman_yakovenko Date: 2006-11-22 07:20:49 -0800 (Wed, 22 Nov 2006) Log Message: ----------- adding transformers and improving generated code Modified Paths: -------------- pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py pyplusplus_dev_ft/pyplusplus/function_transformers/__init__.py pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.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-22 09:26:21 UTC (rev 747) +++ pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py 2006-11-22 15:20:49 UTC (rev 748) @@ -3,6 +3,7 @@ # accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) +import re import os import algorithm import code_creator @@ -13,8 +14,10 @@ import pyplusplus.function_transformers as function_transformers from pyplusplus import code_repository -###################################################################### - +__REMOVE_DUPLICAET_LINESEP = re.compile( '(%s){2,}' % os.linesep ) +def remove_duplicate_linesep( code ): + return __REMOVE_DUPLICAET_LINESEP.sub( os.linesep, code ) + class mem_fun_transformed_t( calldef_t ): """Creates code for public non-virtual member functions. """ @@ -133,10 +136,13 @@ , 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 ) ) + + return_stmt = declarations.call_invocation.join( make_tuple, return_vars ) + if self.LINE_LENGTH < len( return_stmt ): + 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: @@ -157,7 +163,9 @@ def _create_impl(self): answer = ['// Transformed wrapper function for "%s"' % self.declaration ] answer.append( self.create_declaration(self.declaration.alias) + '{') - answer.append( self.indent( self.create_body() ) ) + body = self.create_body() + body = remove_duplicate_linesep( body ) + answer.append( self.indent( body ) ) answer.append( '}' ) return os.linesep.join( answer ) Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/__init__.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/__init__.py 2006-11-22 09:26:21 UTC (rev 747) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/__init__.py 2006-11-22 15:20:49 UTC (rev 748) @@ -26,15 +26,15 @@ return transformers.output_t( function, *args, **keywd ) return creator -#def input( *args, **keywd ): - #def creator( function ): - #return transformers.input_t( function, *args, **keywd ) - #return creator +def input( *args, **keywd ): + def creator( function ): + return transformers.input_t( function, *args, **keywd ) + return creator -#def inout( *args, **keywd ): - #def creator( function ): - #return transformers.inout_t( function, *args, **keywd ) - #return creator +def inout( *args, **keywd ): + def creator( function ): + return transformers.inout_t( function, *args, **keywd ) + return creator #def input_array( *args, **keywd ): #def creator( function ): @@ -44,4 +44,4 @@ #def output_array( *args, **keywd ): #def creator( function ): #return transformers.output_array_t( function, *args, **keywd ) - #return creator \ No newline at end of file + #return creator Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py 2006-11-22 09:26:21 UTC (rev 747) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py 2006-11-22 15:20:49 UTC (rev 748) @@ -67,9 +67,9 @@ def __init__( self, function ): controller_base_t.__init__( self, function ) - self.__wrapper_args = function.arguments[:] + self.__wrapper_args = [ arg.clone() for arg in function.arguments ] self.__result_var = variable_t( self.function.return_type - , self.register_variable_name( 'result' ) ) + , self.register_variable_name( 'result' ) ) self.__return_variables = [] self.__pre_call = [] self.__post_call = [] @@ -91,13 +91,17 @@ def wrapper_args( self ): return self.__wrapper_args + def find_wrapper_arg( self, name ): + for arg in self.wrapper_args: + if arg.name == name: + return arg + return None + def remove_wrapper_arg( self, name ): - for index, arg in enumerate( self.wrapper_args ): - if arg.name == name: - del self.wrapper_args[ index ] - return - else: + arg = self.find_wrapper_arg( name ) + if not arg: raise LookupError( "Unable to remove '%s' argument - not found!" % name ) + del self.wrapper_args[ self.wrapper_args.index(arg) ] @property def arg_expressions( self ): Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py 2006-11-22 09:26:21 UTC (rev 747) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py 2006-11-22 15:20:49 UTC (rev 748) @@ -77,3 +77,229 @@ controller.modify_argument_expression( self.arg_index, var_name ) #adding the variable to return variables list controller.return_variable( var_name ) + +# input_t +class input_t(transformer.transformer_t): + """Handles a single input variable. + + The reference on the specified variable is removed. + + void setValue(int& v) -> setValue(v) + """ + + def __init__(self, function, arg_ref): + """Constructor. + + The specified argument must be a reference or a pointer. + + @param idx: Index of the argument that is an output value (the first arg has index 1). + @type idx: int + """ + transformer.transformer_t.__init__( self, function ) + self.arg = self.get_argument( arg_ref ) + self.arg_index = self.function.arguments.index( self.arg ) + + if not is_ref_or_ptr( self.arg.type ): + raise ValueError( '%s\nin order to use "input" transformation, argument %s type must be a reference or a pointer (got %s).' ) \ + % ( function, self.arg_ref.name, arg.type) + + def __str__(self): + return "input(%d)"%(self.idx) + + def configure_mem_fun( self, controller ): + assert isinstance( controller, controllers.mem_fun_controller_t ) + w_arg = controller.find_wrapper_arg( self.arg.name ) + w_arg.type = remove_ref_or_ptr( self.arg.type ) + +# inout_t +class inout_t(transformer.transformer_t): + """Handles a single input/output variable. + + void foo(int& v) -> v = foo(v) + """ + + def __init__(self, function, arg_ref): + """Constructor. + + The specified argument must be a reference or a pointer. + + @param idx: Index of the argument that is an in/out value (the first arg has index 1). + @type idx: int + """ + transformer.transformer_t.__init__( self, function ) + self.arg = self.get_argument( arg_ref ) + self.arg_index = self.function.arguments.index( self.arg ) + + if not is_ref_or_ptr( self.arg.type ): + raise ValueError( '%s\nin order to use "inout" transformation, argument %s type must be a reference or a pointer (got %s).' ) \ + % ( function, self.arg_ref.name, arg.type) + + def __str__(self): + return "inout(%d)"%(self.arg_index) + + def init_funcs(self, sm): + assert isinstance( controller, controllers.mem_fun_controller_t ) + w_arg = controller.find_wrapper_arg( self.arg.name ) + w_arg.type = remove_ref_or_ptr( self.arg.type ) + #adding the variable to return variables list + controller.return_variable( w_arg ) + + +#~ # input_array_t +#~ class input_array_t(transformer.transformer_t): + #~ """Handles an input array with fixed size. + + #~ void setVec3(double* v) -> setVec3(object v) + #~ # v must be a sequence of 3 floats + #~ """ + + #~ def __init__(self, function, arg_ref, array_size): + #~ """Constructor. + + #~ @param size: The fixed size of the input array + #~ @type size: int + #~ """ + #~ transformer.transformer_t.__init__( self, function ) + + #~ self.arg = self.get_argument( arg_ref ) + #~ self.arg_index = self.function.arguments.index( self.arg ) + + #~ if not is_ptr_or_array( self.arg.type ): + #~ raise ValueError( '%s\nin order to use "input_array" transformation, argument %s type must be a array or a pointer (got %s).' ) \ + #~ % ( function, self.arg_ref.name, arg.type) + + #~ self.array_size = array_size + #~ self.native_array = None + #~ self.pylist = None + + #~ def __str__(self): + #~ return "input_array(%s,%d)"%( self.arg.name, self.array_size) + + #~ def required_headers( self ): + #~ """Returns list of header files that transformer generated code depends on.""" + #~ return [ code_repository.convenience.file_name ] + + #~ def init_funcs(self, sm): + #~ # Remove the original argument... + #~ sm.remove_arg(self.arg_index + 1) + + #~ # Declare a variable that will hold the Python list + #~ # (this will be the input of the Python call in the virtual function) + #~ self.pylist = sm.virtual_func.declare_variable("py_" + self.arg.name, "boost::python::list") + + #~ # Replace the removed argument with a Python object. + #~ newarg = self.arg.clone( type=declarations.dummy_type_t("boost::python::object") ) + #~ sm.insert_arg(self.arg_index+1, newarg, self.pylist) + + #~ # Declare a variable that will hold the C array... + #~ self.native_array = sm.wrapper_func.declare_variable( + #~ "native_" + self.arg.name + #~ , declarations.array_item_type( self.arg.type ) + #~ , '[%d]' % self.array_size) + + #~ # Replace the input parameter with the C array + #~ sm.wrapper_func.input_params[self.arg_index] = self.native_array + + #~ def wrapper_pre_call(self, sm): + #~ """Wrapper function code. + #~ """ + #~ tmpl = [] + #~ tmpl.append( '%(pypp_con)s::ensure_uniform_sequence< %(type)s >( %(pylist)s, %(array_size)d );' ) + #~ tmpl.append( '%(pypp_con)s::copy_sequence( %(pylist)s, %(pypp_con)s::array_inserter( %(native_array)s, %(array_size)d ) );' ) + #~ return os.linesep.join( tmpl ) % { + #~ 'type' : declarations.array_item_type( self.arg.type ) + #~ , 'pypp_con' : 'pyplusplus::convenience' + #~ , 'pylist' : self.arg.name + #~ , 'array_size' : self.array_size + #~ , 'native_array' : self.native_array + #~ } + + #~ def virtual_pre_call(self, sm): + #~ """Virtual function code.""" + #~ tmpl = '%(pypp_con)s::copy_container( %(native_array)s, %(native_array)s + %(array_size)d, %(pypp_con)s::list_inserter( %(pylist)s ) );' + #~ return tmpl % { + #~ 'pypp_con' : 'pyplusplus::convenience' + #~ , 'native_array' : self.arg.name + #~ , 'array_size' : self.array_size + #~ , 'pylist' : self.pylist + #~ } + + +#~ # output_array_t +#~ class output_array_t(transformer.transformer_t): + #~ """Handles an output array of a fixed size. + + #~ void getVec3(double* v) -> v = getVec3() + #~ # v will be a list with 3 floats + #~ """ + + #~ def __init__(self, function, arg_ref, size): + #~ """Constructor. + + #~ @param idx: Index of the argument that is an output array (the first arg has index 1). + #~ @type idx: int + #~ @param size: The fixed size of the output array + #~ @type size: int + #~ """ + #~ transformer.transformer_t.__init__( self, function ) + #~ self.arg = self.get_argument( arg_ref ) + #~ self.arg_index = self.function.arguments.index( self.arg ) + + #~ if not is_ptr_or_array( self.arg.type ): + #~ raise ValueError( '%s\nin order to use "input_array" transformation, argument %s type must be a array or a pointer (got %s).' ) \ + #~ % ( function, self.arg_ref.name, arg.type) + + #~ self.array_size = size + #~ self.native_array = None + #~ self.pylist = None + + #~ def __str__(self): + #~ return "output_array(%s,%d)"%( self.arg.name, self.array_size) + + #~ def required_headers( self ): + #~ """Returns list of header files that transformer generated code depends on.""" + #~ return [ code_repository.convenience.file_name ] + + #~ def init_funcs(self, sm): + #~ # Remove the original argument... + #~ sm.remove_arg(self.arg_index + 1) + + #~ # Declare a variable that will hold the C array... + #~ self.native_array = sm.wrapper_func.declare_variable( + #~ "native_" + self.arg.name + #~ , declarations.array_item_type( self.arg.type ) + #~ , '[%d]' % self.array_size) + + #~ # Declare a Python list which will receive the output... + #~ self.pylist = sm.wrapper_func.declare_variable( + #~ 'py_' + self.arg.name + #~ , "boost::python::list" ) + + #~ # ...and add it to the result + #~ sm.wrapper_func.result_exprs.append(self.pylist) + + #~ sm.wrapper_func.input_params[ self.arg_index ] = self.native_array + + #~ self.virtual_pylist = sm.virtual_func.declare_variable("py_"+self.arg.name, "boost::python::object") + + #~ def wrapper_post_call(self, sm): + #~ tmpl = '%(pypp_con)s::copy_container( %(native_array)s, %(native_array)s + %(array_size)d, %(pypp_con)s::list_inserter( %(pylist)s ) );' + #~ return tmpl % { + #~ 'pypp_con' : 'pyplusplus::convenience' + #~ , 'native_array' : self.native_array + #~ , 'array_size' : self.array_size + #~ , 'pylist' : self.pylist + #~ } + + #~ def virtual_post_call(self, sm): + #~ tmpl = [] + #~ tmpl.append( '%(pypp_con)s::ensure_uniform_sequence< %(type)s >( %(pylist)s, %(array_size)d );' ) + #~ tmpl.append( '%(pypp_con)s::copy_sequence( %(pylist)s, %(pypp_con)s::array_inserter( %(native_array)s, %(array_size)d ) );' ) + #~ return os.linesep.join( tmpl ) % { + #~ 'type' : declarations.array_item_type( self.arg.type ) + #~ , 'pypp_con' : 'pyplusplus::convenience' + #~ , 'pylist' : sm.py_result_expr(self.pylist) + #~ , 'array_size' : self.array_size + #~ , 'native_array' : self.arg.name + #~ } + 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:26:21 UTC (rev 747) +++ pyplusplus_dev_ft/unittests/data/function_transformations_to_be_exported.hpp 2006-11-22 15:20:49 UTC (rev 748) @@ -10,6 +10,7 @@ namespace ft2{ +//used to check output transformer struct calculator_t{ calculator_t(){ std::cout << std::endl << "=> calculator_t created"; @@ -35,6 +36,23 @@ } }; +//used to check input transformer +struct window_t{ + window_t() + : height( 0 ) + , width( 0 ) + {} + + void resize( int& h, int& w ){ + height = h; + width = w; + } + + int height; + int width; +}; + + } //~ namespace ft{ Modified: pyplusplus_dev_ft/unittests/function_transformations_tester.py =================================================================== --- pyplusplus_dev_ft/unittests/function_transformations_tester.py 2006-11-22 09:26:21 UTC (rev 747) +++ pyplusplus_dev_ft/unittests/function_transformations_tester.py 2006-11-22 15:20:49 UTC (rev 748) @@ -30,6 +30,11 @@ 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 ) + window = mb.class_( 'window_t' ) + window.add_wrapper_code( '' ) + window.mem_fun( 'resize' ).add_transformation( ft.input(0), ft.input(1) ) + + #~ image = mb.class_( "image_t" ) #~ image.include() #~ image.add_wrapper_code( '' ) @@ -67,6 +72,11 @@ #test make_object function self.failUnless( sys.getrefcount( calc ) == sys.getrefcount( calc2 ) ) + window = module.window_t() + window.height = 0 + window.width = 0 + window.resize( h=1, w=2 ) + self.failUnless( window.height==1 and window.width==2 ) #~ img = module.image_t( 2, 6) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-23 08:09:54
|
Revision: 749 http://svn.sourceforge.net/pygccxml/?rev=749&view=rev Author: roman_yakovenko Date: 2006-11-23 00:09:53 -0800 (Thu, 23 Nov 2006) Log Message: ----------- fixing few bugs + adding missing transformers Modified Paths: -------------- pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py pyplusplus_dev_ft/pyplusplus/code_repository/convenience.py pyplusplus_dev_ft/pyplusplus/function_transformers/__init__.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-22 15:20:49 UTC (rev 748) +++ pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py 2006-11-23 08:09:53 UTC (rev 749) @@ -14,6 +14,9 @@ import pyplusplus.function_transformers as function_transformers from pyplusplus import code_repository +#TODO: constructors also can have transformation defined. We should use make _init +# function for this purpose + __REMOVE_DUPLICAET_LINESEP = re.compile( '(%s){2,}' % os.linesep ) def remove_duplicate_linesep( code ): return __REMOVE_DUPLICAET_LINESEP.sub( os.linesep, code ) @@ -74,7 +77,7 @@ this_arg_type = declarations.reference_t( this_arg_type ) self.__this_arg = declarations.argument_t( - name=self.ft.controller.register_variable_name( 'self' ) + name=self.ft.controller.register_variable_name( 'inst' ) , type=this_arg_type ) @property @@ -83,8 +86,8 @@ def function_type(self): return declarations.free_function_type_t( - return_type=self.declaration.return_type - , arguments_types=[ declarations.dummy_type_t( self.parent.full_name ) ] + return_type=self.ft.controller.wrapper_return_type + , arguments_types=[ self.__this_arg.type ] + map( lambda arg: arg.type, self.ft.controller.wrapper_args ) ) def full_name(self): Modified: pyplusplus_dev_ft/pyplusplus/code_repository/convenience.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/code_repository/convenience.py 2006-11-22 15:20:49 UTC (rev 748) +++ pyplusplus_dev_ft/pyplusplus/code_repository/convenience.py 2006-11-23 08:09:53 UTC (rev 749) @@ -137,6 +137,7 @@ } /*pyplusplus*/ } /*convenience*/ +namespace pyplus_conv = pyplusplus::convenience; #endif//__convenience_pyplusplus_hpp__ Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/__init__.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/__init__.py 2006-11-22 15:20:49 UTC (rev 748) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/__init__.py 2006-11-23 08:09:53 UTC (rev 749) @@ -36,12 +36,12 @@ return transformers.inout_t( function, *args, **keywd ) return creator -#def input_array( *args, **keywd ): - #def creator( function ): - #return transformers.input_array_t( function, *args, **keywd ) - #return creator +def input_array( *args, **keywd ): + def creator( function ): + return transformers.input_array_t( function, *args, **keywd ) + return creator -#def output_array( *args, **keywd ): - #def creator( function ): - #return transformers.output_array_t( function, *args, **keywd ) - #return creator +def output_array( *args, **keywd ): + def creator( function ): + return transformers.output_array_t( function, *args, **keywd ) + return creator Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py 2006-11-22 15:20:49 UTC (rev 748) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py 2006-11-23 08:09:53 UTC (rev 749) @@ -16,6 +16,7 @@ - L{output_array_t} """ import os +import string import transformer import controllers from pygccxml import declarations @@ -137,169 +138,135 @@ def __str__(self): return "inout(%d)"%(self.arg_index) - def init_funcs(self, sm): + def configure_mem_fun(self, controller): assert isinstance( controller, controllers.mem_fun_controller_t ) w_arg = controller.find_wrapper_arg( self.arg.name ) w_arg.type = remove_ref_or_ptr( self.arg.type ) #adding the variable to return variables list - controller.return_variable( w_arg ) + controller.return_variable( w_arg.name ) -#~ # input_array_t -#~ class input_array_t(transformer.transformer_t): - #~ """Handles an input array with fixed size. +class input_array_t(transformer.transformer_t): + """Handles an input array with fixed size. - #~ void setVec3(double* v) -> setVec3(object v) - #~ # v must be a sequence of 3 floats - #~ """ + void setVec3(double* v) -> setVec3(object v) + # v must be a sequence of 3 floats + """ - #~ def __init__(self, function, arg_ref, array_size): - #~ """Constructor. + def __init__(self, function, arg_ref, size): + """Constructor. - #~ @param size: The fixed size of the input array - #~ @type size: int - #~ """ - #~ transformer.transformer_t.__init__( self, function ) + @param size: The fixed size of the input array + @type size: int + """ + transformer.transformer_t.__init__( self, function ) - #~ self.arg = self.get_argument( arg_ref ) - #~ self.arg_index = self.function.arguments.index( self.arg ) + self.arg = self.get_argument( arg_ref ) + self.arg_index = self.function.arguments.index( self.arg ) + + if not is_ptr_or_array( self.arg.type ): + raise ValueError( '%s\nin order to use "input_array" transformation, argument %s type must be a array or a pointer (got %s).' ) \ + % ( function, self.arg_ref.name, arg.type) - #~ if not is_ptr_or_array( self.arg.type ): - #~ raise ValueError( '%s\nin order to use "input_array" transformation, argument %s type must be a array or a pointer (got %s).' ) \ - #~ % ( function, self.arg_ref.name, arg.type) + self.array_size = size + self.array_item_type = declarations.array_item_type( self.arg.type ) - #~ self.array_size = array_size - #~ self.native_array = None - #~ self.pylist = None + def __str__(self): + return "input_array(%s,%d)"%( self.arg.name, self.array_size) - #~ def __str__(self): - #~ return "input_array(%s,%d)"%( self.arg.name, self.array_size) + def required_headers( self ): + """Returns list of header files that transformer generated code depends on.""" + return [ code_repository.convenience.file_name ] - #~ def required_headers( self ): - #~ """Returns list of header files that transformer generated code depends on.""" - #~ return [ code_repository.convenience.file_name ] + @property + def pre_call_tmpl( self ): + pre_call = [] + pre_call.append( 'pyplus_conv::ensure_uniform_sequence< $type >( $pylist, $array_size );' ) + pre_call.append( 'pyplus_conv::copy_sequence( $pylist, pyplus_conv::array_inserter( $native_array, $array_size ) );' ) + return string.Template( os.linesep.join( pre_call ) ) - #~ def init_funcs(self, sm): - #~ # Remove the original argument... - #~ sm.remove_arg(self.arg_index + 1) + def configure_mem_fun(self, controller): + assert isinstance( controller, controllers.mem_fun_controller_t ) + + w_arg = controller.find_wrapper_arg( self.arg.name ) + w_arg.type = declarations.dummy_type_t( "boost::python::object" ) - #~ # Declare a variable that will hold the Python list - #~ # (this will be the input of the Python call in the virtual function) - #~ self.pylist = sm.virtual_func.declare_variable("py_" + self.arg.name, "boost::python::list") + # Declare a variable that will hold the C array... + native_array = controller.declare_variable( self.array_item_type + , "native_" + self.arg.name + , '[%d]' % self.array_size ) + + seq2arr = self.pre_call_tmpl.substitute( type=self.array_item_type + , pylist=w_arg.name + , array_size=self.array_size + , native_array=native_array ) + + controller.add_pre_call_code( seq2arr ) + + controller.modify_argument_expression( self.arg_index, native_array ) - #~ # Replace the removed argument with a Python object. - #~ newarg = self.arg.clone( type=declarations.dummy_type_t("boost::python::object") ) - #~ sm.insert_arg(self.arg_index+1, newarg, self.pylist) - #~ # Declare a variable that will hold the C array... - #~ self.native_array = sm.wrapper_func.declare_variable( - #~ "native_" + self.arg.name - #~ , declarations.array_item_type( self.arg.type ) - #~ , '[%d]' % self.array_size) +# output_array_t +class output_array_t(transformer.transformer_t): + """Handles an output array of a fixed size. - #~ # Replace the input parameter with the C array - #~ sm.wrapper_func.input_params[self.arg_index] = self.native_array + void getVec3(double* v) -> v = getVec3() + # v will be a list with 3 floats + """ - #~ def wrapper_pre_call(self, sm): - #~ """Wrapper function code. - #~ """ - #~ tmpl = [] - #~ tmpl.append( '%(pypp_con)s::ensure_uniform_sequence< %(type)s >( %(pylist)s, %(array_size)d );' ) - #~ tmpl.append( '%(pypp_con)s::copy_sequence( %(pylist)s, %(pypp_con)s::array_inserter( %(native_array)s, %(array_size)d ) );' ) - #~ return os.linesep.join( tmpl ) % { - #~ 'type' : declarations.array_item_type( self.arg.type ) - #~ , 'pypp_con' : 'pyplusplus::convenience' - #~ , 'pylist' : self.arg.name - #~ , 'array_size' : self.array_size - #~ , 'native_array' : self.native_array - #~ } + def __init__(self, function, arg_ref, size): + """Constructor. - #~ def virtual_pre_call(self, sm): - #~ """Virtual function code.""" - #~ tmpl = '%(pypp_con)s::copy_container( %(native_array)s, %(native_array)s + %(array_size)d, %(pypp_con)s::list_inserter( %(pylist)s ) );' - #~ return tmpl % { - #~ 'pypp_con' : 'pyplusplus::convenience' - #~ , 'native_array' : self.arg.name - #~ , 'array_size' : self.array_size - #~ , 'pylist' : self.pylist - #~ } + @param idx: Index of the argument that is an output array (the first arg has index 1). + @type idx: int + @param size: The fixed size of the output array + @type size: int + """ + transformer.transformer_t.__init__( self, function ) + self.arg = self.get_argument( arg_ref ) + self.arg_index = self.function.arguments.index( self.arg ) + if not is_ptr_or_array( self.arg.type ): + raise ValueError( '%s\nin order to use "input_array" transformation, argument %s type must be a array or a pointer (got %s).' ) \ + % ( function, self.arg_ref.name, arg.type) -#~ # output_array_t -#~ class output_array_t(transformer.transformer_t): - #~ """Handles an output array of a fixed size. + self.array_size = size + self.array_item_type = declarations.array_item_type( self.arg.type ) - #~ void getVec3(double* v) -> v = getVec3() - #~ # v will be a list with 3 floats - #~ """ + def __str__(self): + return "output_array(%s,%d)"%( self.arg.name, self.array_size) - #~ def __init__(self, function, arg_ref, size): - #~ """Constructor. + def required_headers( self ): + """Returns list of header files that transformer generated code depends on.""" + return [ code_repository.convenience.file_name ] - #~ @param idx: Index of the argument that is an output array (the first arg has index 1). - #~ @type idx: int - #~ @param size: The fixed size of the output array - #~ @type size: int - #~ """ - #~ transformer.transformer_t.__init__( self, function ) - #~ self.arg = self.get_argument( arg_ref ) - #~ self.arg_index = self.function.arguments.index( self.arg ) + @property + def post_call_tmpl( self ): + return string.Template( 'pyplus_conv::copy_container( $native_array, $native_array + $array_size, pyplus_conv::list_inserter( $pylist ) );' ) - #~ if not is_ptr_or_array( self.arg.type ): - #~ raise ValueError( '%s\nin order to use "input_array" transformation, argument %s type must be a array or a pointer (got %s).' ) \ - #~ % ( function, self.arg_ref.name, arg.type) + def configure_mem_fun(self, controller): + assert isinstance( controller, controllers.mem_fun_controller_t ) + #removing arg from the function wrapper definition + controller.remove_wrapper_arg( self.arg.name ) - #~ self.array_size = size - #~ self.native_array = None - #~ self.pylist = None + # Declare a variable that will hold the C array... + native_array = controller.declare_variable( self.array_item_type + , "native_" + self.arg.name + , '[%d]' % self.array_size ) - #~ def __str__(self): - #~ return "output_array(%s,%d)"%( self.arg.name, self.array_size) + #adding just declared variable to the original function call expression + controller.modify_argument_expression( self.arg_index, native_array ) - #~ def required_headers( self ): - #~ """Returns list of header files that transformer generated code depends on.""" - #~ return [ code_repository.convenience.file_name ] - - #~ def init_funcs(self, sm): - #~ # Remove the original argument... - #~ sm.remove_arg(self.arg_index + 1) - - #~ # Declare a variable that will hold the C array... - #~ self.native_array = sm.wrapper_func.declare_variable( - #~ "native_" + self.arg.name - #~ , declarations.array_item_type( self.arg.type ) - #~ , '[%d]' % self.array_size) - - #~ # Declare a Python list which will receive the output... - #~ self.pylist = sm.wrapper_func.declare_variable( - #~ 'py_' + self.arg.name - #~ , "boost::python::list" ) + # Declare a Python list which will receive the output... + pylist = controller.declare_variable( declarations.dummy_type_t( "boost::python::list" ) + , 'py_' + self.arg.name ) + + arr2seq = self.post_call_tmpl.substitute( native_array=native_array + , array_size=self.array_size + , pylist=pylist ) - #~ # ...and add it to the result - #~ sm.wrapper_func.result_exprs.append(self.pylist) + controller.add_post_call_code( arr2seq ) - #~ sm.wrapper_func.input_params[ self.arg_index ] = self.native_array + #adding the variable to return variables list + controller.return_variable( pylist ) - #~ self.virtual_pylist = sm.virtual_func.declare_variable("py_"+self.arg.name, "boost::python::object") - - #~ def wrapper_post_call(self, sm): - #~ tmpl = '%(pypp_con)s::copy_container( %(native_array)s, %(native_array)s + %(array_size)d, %(pypp_con)s::list_inserter( %(pylist)s ) );' - #~ return tmpl % { - #~ 'pypp_con' : 'pyplusplus::convenience' - #~ , 'native_array' : self.native_array - #~ , 'array_size' : self.array_size - #~ , 'pylist' : self.pylist - #~ } - - #~ def virtual_post_call(self, sm): - #~ tmpl = [] - #~ tmpl.append( '%(pypp_con)s::ensure_uniform_sequence< %(type)s >( %(pylist)s, %(array_size)d );' ) - #~ tmpl.append( '%(pypp_con)s::copy_sequence( %(pylist)s, %(pypp_con)s::array_inserter( %(native_array)s, %(array_size)d ) );' ) - #~ return os.linesep.join( tmpl ) % { - #~ 'type' : declarations.array_item_type( self.arg.type ) - #~ , 'pypp_con' : 'pyplusplus::convenience' - #~ , 'pylist' : sm.py_result_expr(self.pylist) - #~ , 'array_size' : self.array_size - #~ , 'native_array' : self.arg.name - #~ } - 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 15:20:49 UTC (rev 748) +++ pyplusplus_dev_ft/unittests/data/function_transformations_to_be_exported.hpp 2006-11-23 08:09:53 UTC (rev 749) @@ -6,18 +6,14 @@ #ifndef __function_transformations_to_be_exported_hpp__ #define __function_transformations_to_be_exported_hpp__ -#include <iostream> - namespace ft2{ //used to check output transformer 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 ){ @@ -36,7 +32,7 @@ } }; -//used to check input transformer +//used to check input\inout transformers struct window_t{ window_t() : height( 0 ) @@ -48,11 +44,39 @@ width = w; } + int resize_in_out( int& h, int& w){ + height *= h; + h = height; + width *= w; + w = width; + return h*w; + } + int height; int width; }; - +struct point3d_t{ + point3d_t() + : x( 0 ), y(0), z(0) + {} + + int initialize( int v[3] ){ + x = v[0]; + y = v[1]; + z = v[2]; + return x*y*z; + } + + void position( int v[3] ){ + v[0] = x; + v[1] = y; + v[2] = z; + } + + int x, y, z; +}; + } //~ namespace ft{ Modified: pyplusplus_dev_ft/unittests/function_transformations_tester.py =================================================================== --- pyplusplus_dev_ft/unittests/function_transformations_tester.py 2006-11-22 15:20:49 UTC (rev 748) +++ pyplusplus_dev_ft/unittests/function_transformations_tester.py 2006-11-23 08:09:53 UTC (rev 749) @@ -21,6 +21,9 @@ , *args ) def customize( self, mb ): + + mb.global_ns.calldefs().create_with_signature = True + calc = mb.class_('calculator_t' ) calc.add_wrapper_code( '' ) assign_funs = calc.mem_funs( lambda decl: decl.name.startswith( 'assign' ) ) @@ -33,7 +36,12 @@ window = mb.class_( 'window_t' ) window.add_wrapper_code( '' ) window.mem_fun( 'resize' ).add_transformation( ft.input(0), ft.input(1) ) + window.mem_fun( 'resize_in_out' ).add_transformation( ft.inout(0), ft.inout(1) ) + point3d = mb.class_( 'point3d_t' ) + point3d.add_wrapper_code( '' ) + point3d.mem_fun( 'initialize' ).add_transformation( ft.input_array(0, size=3) ) + point3d.mem_fun( 'position' ).add_transformation( ft.output_array(0, size=3) ) #~ image = mb.class_( "image_t" ) #~ image.include() @@ -75,9 +83,16 @@ window = module.window_t() window.height = 0 window.width = 0 - window.resize( h=1, w=2 ) + window.resize( 1, 2 ) self.failUnless( window.height==1 and window.width==2 ) + square, h, w = window.resize_in_out( 3, 7 ) + self.failUnless( square == 1*3*2*7 and h==3 and w==2*7 ) + self.failUnless( window.height==3 and window.width==2*7 ) + point3d = module.point3d_t() + result = point3d.initialize( [ 1,2,3 ] ) + self.failUnless( result== 1*2*3 and point3d.x == 1 and point3d.y==2 and point3d.z==3 ) + self.failUnless( [1,2,3] == point3d.position()[0] ) #~ 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. |
From: <rom...@us...> - 2006-11-23 20:04:49
|
Revision: 750 http://svn.sourceforge.net/pygccxml/?rev=750&view=rev Author: roman_yakovenko Date: 2006-11-23 12:04:44 -0800 (Thu, 23 Nov 2006) Log Message: ----------- adding ability to create member function in the global namespace Modified Paths: -------------- pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py pyplusplus_dev_ft/pyplusplus/code_creators/declaration_based.py pyplusplus_dev_ft/pyplusplus/code_repository/call_policies.py pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py pyplusplus_dev_ft/pyplusplus/function_transformers/function_transformation.py 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-23 08:09:53 UTC (rev 749) +++ pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py 2006-11-23 20:04:44 UTC (rev 750) @@ -33,6 +33,9 @@ def ft( self ): #function transformation return self.declaration.transformations[0] + def _get_alias_impl( self ): + return self.wrapper.ft.alias + def create_function_type_alias_code( self, exported_class_alias=None ): ftype = self.wrapper.function_type() return 'typedef %s;' % ftype.create_typedef( self.function_type_alias, exported_class_alias ) @@ -79,7 +82,10 @@ self.__this_arg = declarations.argument_t( name=self.ft.controller.register_variable_name( 'inst' ) , type=this_arg_type ) - + + def __is_global( self ): + return not isinstance( self.parent, class_declaration.class_wrapper_t ) + @property def ft( self ): #function transformation return self.declaration.transformations[0] @@ -90,8 +96,21 @@ , arguments_types=[ self.__this_arg.type ] + map( lambda arg: arg.type, self.ft.controller.wrapper_args ) ) + def wrapper_name( self ): + if self.__is_global(): + return self.ft.unique_name + else: + if self.declaration.overloads: + #it is possible that other functions will have same signature + return self.ft.unique_name + else: + return self.declaration.name + def full_name(self): - return self.parent.full_name + '::' + self.declaration.name + if self.__is_global(): + return self.ft.unique_name + else: + return self.parent.full_name + '::' + self.wrapper_name() def args_declaration( self ): arg_utils = calldef_utils.argument_utils_t( @@ -105,7 +124,7 @@ return template % { 'return_type' : self.ft.controller.wrapper_return_type.decl_string - , 'name' : self.declaration.name + , 'name' : self.wrapper_name() , 'args' : self.args_declaration() } Modified: pyplusplus_dev_ft/pyplusplus/code_creators/declaration_based.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/code_creators/declaration_based.py 2006-11-23 08:09:53 UTC (rev 749) +++ pyplusplus_dev_ft/pyplusplus/code_creators/declaration_based.py 2006-11-23 20:04:44 UTC (rev 750) @@ -30,9 +30,13 @@ doc="""The declaration this code creator is based on. @type: L{decl_wrapper_t<decl_wrappers.decl_wrapper_t>} """) + + def _get_alias_impl( self ): + return self.declaration.alias def _get_alias(self): - return self.declaration.alias + return self._get_alias_impl() + def _set_alias(self, alias): self.declaration.alias = alias alias = property( _get_alias, _set_alias ) Modified: pyplusplus_dev_ft/pyplusplus/code_repository/call_policies.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/code_repository/call_policies.py 2006-11-23 08:09:53 UTC (rev 749) +++ pyplusplus_dev_ft/pyplusplus/code_repository/call_policies.py 2006-11-23 20:04:44 UTC (rev 750) @@ -73,7 +73,7 @@ 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; + typedef BOOST_DEDUCED_TYPENAME CallPolicies::result_converter:: template apply< T >::type result_converter_t; result_converter_t rc; return bpl::object( bpl::handle<>( rc( x ) ) ); } Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py 2006-11-23 08:09:53 UTC (rev 749) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py 2006-11-23 20:04:44 UTC (rev 750) @@ -73,7 +73,6 @@ self.__return_variables = [] self.__pre_call = [] self.__post_call = [] - self.__save_return_value_stmt = None self.__arg_expressions = [ arg.name for arg in function.arguments ] def apply( self, transformations ): Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/function_transformation.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/function_transformation.py 2006-11-23 08:09:53 UTC (rev 749) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/function_transformation.py 2006-11-23 20:04:44 UTC (rev 750) @@ -5,7 +5,7 @@ """This module contains the class L{function_transformation_t}. """ - +import md5 import controllers from pyplusplus import code_repository @@ -17,8 +17,27 @@ self.__transformers = map( lambda tr_creator: tr_creator( function ), transformer_creator ) self.__thread_safe = keywd.get( 'thread_safe', False ) self.__controller.apply( self.__transformers ) + self.__unique_name = None + self.__alias = keywd.get( 'alias', None ) @property + def unique_name( self ): + if None is self.__unique_name: + obj = md5.new() + obj.update( self.__function.mangled ) + self.__unique_name = self.__function.name + '_' + obj.hexdigest() + return self.__unique_name + + @property + def alias( self ): + if None is self.__alias: + if self.__function.overloads: + self.__alias = self.unique_name + else: + self.__alias = self.__function.alias + return self.__alias + + @property def transformers( self ): return self.__transformers Modified: pyplusplus_dev_ft/unittests/function_transformations_tester.py =================================================================== --- pyplusplus_dev_ft/unittests/function_transformations_tester.py 2006-11-23 08:09:53 UTC (rev 749) +++ pyplusplus_dev_ft/unittests/function_transformations_tester.py 2006-11-23 20:04:44 UTC (rev 750) @@ -25,7 +25,6 @@ mb.global_ns.calldefs().create_with_signature = True calc = mb.class_('calculator_t' ) - 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) ) @@ -34,7 +33,6 @@ clone_and_assign_5.call_policies = call_policies.return_value_policy( call_policies.manage_new_object ) window = mb.class_( 'window_t' ) - window.add_wrapper_code( '' ) window.mem_fun( 'resize' ).add_transformation( ft.input(0), ft.input(1) ) window.mem_fun( 'resize_in_out' ).add_transformation( ft.inout(0), ft.inout(1) ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-25 19:25:50
|
Revision: 752 http://svn.sourceforge.net/pygccxml/?rev=752&view=rev Author: roman_yakovenko Date: 2006-11-25 11:25:49 -0800 (Sat, 25 Nov 2006) Log Message: ----------- adding ft for free functions Modified Paths: -------------- pyplusplus_dev_ft/pyplusplus/code_creators/__init__.py pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py pyplusplus_dev_ft/pyplusplus/function_transformers/__init__.py pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py pyplusplus_dev_ft/pyplusplus/function_transformers/function_transformation.py pyplusplus_dev_ft/pyplusplus/function_transformers/templates.py pyplusplus_dev_ft/pyplusplus/function_transformers/transformer.py pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py pyplusplus_dev_ft/pyplusplus/module_creator/creator.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/__init__.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/code_creators/__init__.py 2006-11-23 20:26:16 UTC (rev 751) +++ pyplusplus_dev_ft/pyplusplus/code_creators/__init__.py 2006-11-25 19:25:49 UTC (rev 752) @@ -78,6 +78,9 @@ from calldef_transformed import mem_fun_transformed_t from calldef_transformed import mem_fun_transformed_wrapper_t +from calldef_transformed import free_fun_transformed_t +from calldef_transformed import free_fun_transformed_wrapper_t + #~ from calldef_transformed import mem_fun_v_transformed_t #~ from calldef_transformed import mem_fun_v_transformed_wrapper_t Modified: pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py 2006-11-23 20:26:16 UTC (rev 751) +++ pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py 2006-11-25 19:25:49 UTC (rev 752) @@ -21,14 +21,22 @@ def remove_duplicate_linesep( code ): return __REMOVE_DUPLICAET_LINESEP.sub( os.linesep, code ) -class mem_fun_transformed_t( calldef_t ): +class non_virtual_fun_transformed_t( calldef_t ): """Creates code for public non-virtual member functions. """ def __init__( self, function, wrapper=None ): calldef_t.__init__( self, function=function, wrapper=wrapper ) + if isinstance( self.declaration.parent, declarations.namespace_t ): + self.works_on_instance = False #map( lambda transformer: transformer.configure_mem_fun - + + def create_def_code( self ): + if isinstance( self.declaration.parent, declarations.namespace_t ): + return self.def_identifier() + else: + return super( non_virtual_fun_transformed_t, self ).create_def_code() + @property def ft( self ): #function transformation return self.declaration.transformations[0] @@ -65,7 +73,7 @@ return arg_utils.keywords_args() -class mem_fun_transformed_wrapper_t( calldef_wrapper_t ): +class non_virtual_fun_transformed_wrapper_t( calldef_wrapper_t ): def __init__( self, function ): """Constructor. @@ -74,27 +82,26 @@ """ calldef_wrapper_t.__init__( self, function=function ) - this_arg_type = declarations.declarated_t( self.declaration.parent ) - if self.declaration.has_const: - this_arg_type = declarations.const_t( this_arg_type ) - this_arg_type = declarations.reference_t( this_arg_type ) - - self.__this_arg = declarations.argument_t( - name=self.ft.controller.register_variable_name( 'inst' ) - , type=this_arg_type ) - def __is_global( self ): return not isinstance( self.parent, class_declaration.class_wrapper_t ) + def inst_arg( self ): + if isinstance( self.declaration.parent, declarations.class_t ): + return self.ft.controller.inst_arg + else: + return None + @property def ft( self ): #function transformation return self.declaration.transformations[0] def function_type(self): + args = map( lambda arg: arg.type, self.ft.controller.wrapper_args ) + if self.inst_arg(): + args.insert( 0, self.inst_arg().type ) return declarations.free_function_type_t( - return_type=self.ft.controller.wrapper_return_type - , arguments_types=[ self.__this_arg.type ] - + map( lambda arg: arg.type, self.ft.controller.wrapper_args ) ) + return_type=self.ft.controller.wrapper_return_type + , arguments_types=args ) def wrapper_name( self ): if self.__is_global(): @@ -113,10 +120,13 @@ return self.parent.full_name + '::' + self.wrapper_name() def args_declaration( self ): + args = self.ft.controller.wrapper_args[:] + if self.inst_arg(): + args.insert( 0, self.inst_arg() ) arg_utils = calldef_utils.argument_utils_t( self.declaration , algorithm.make_id_creator( self ) - , [ self.__this_arg ] + self.ft.controller.wrapper_args ) + , args ) return arg_utils.args_declaration() def create_declaration(self, name): @@ -171,13 +181,20 @@ pass if return_stmt: return_stmt = 'return ' + return_stmt + ';' + + f_invokation = None + if self.inst_arg(): + f_invokation = self.inst_arg().name + '.' + self.declaration.name + else: + f_invokation = declarations.full_name( self.declaration ) + 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' : post_call , 'save_result' : result_var_assign - , 'function' : self.__this_arg.name + '.' + self.declaration.name + , 'function' : f_invokation , 'arg_expressions' : self.PARAM_SEPARATOR.join( cntrl.arg_expressions ) , 'return' : return_stmt }) @@ -191,6 +208,11 @@ answer.append( '}' ) return os.linesep.join( answer ) +mem_fun_transformed_t = non_virtual_fun_transformed_t +mem_fun_transformed_wrapper_t = non_virtual_fun_transformed_wrapper_t +free_fun_transformed_t = non_virtual_fun_transformed_t +free_fun_transformed_wrapper_t = non_virtual_fun_transformed_wrapper_t + #~ ###################################################################### #~ class mem_fun_v_transformed_t( calldef_t ): Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/__init__.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/__init__.py 2006-11-23 20:26:16 UTC (rev 751) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/__init__.py 2006-11-25 19:25:49 UTC (rev 752) @@ -44,4 +44,4 @@ def output_array( *args, **keywd ): def creator( function ): return transformers.output_array_t( function, *args, **keywd ) - return creator + return creator \ No newline at end of file Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py 2006-11-23 20:26:16 UTC (rev 751) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py 2006-11-25 19:25:49 UTC (rev 752) @@ -63,8 +63,8 @@ def apply( self, transformations ): raise NotImplementedError() -class mem_fun_controller_t( controller_base_t ): - +class non_virtual_fun_controller_t( controller_base_t ): + #base class for free and member function controllers def __init__( self, function ): controller_base_t.__init__( self, function ) self.__wrapper_args = [ arg.clone() for arg in function.arguments ] @@ -75,9 +75,6 @@ self.__post_call = [] self.__arg_expressions = [ arg.name for arg in function.arguments ] - def apply( self, transformations ): - map( lambda t: t.configure_mem_fun( self ), transformations ) - @property def result_variable( self ): return self.__result_var @@ -147,4 +144,31 @@ def set_return_stmt( self, stmt ): self.__return_stmt = stmt +class mem_fun_controller_t( non_virtual_fun_controller_t ): + def __init__( self, function ): + non_virtual_fun_controller_t.__init__( self, function ) + + inst_arg_type = declarations.declarated_t( self.function.parent ) + if self.function.has_const: + inst_arg_type = declarations.const_t( inst_arg_type ) + inst_arg_type = declarations.reference_t( inst_arg_type ) + + self.__inst_arg = None + if not self.function.has_static: + self.__inst_arg = declarations.argument_t( name=self.register_variable_name( 'inst' ) + , type=inst_arg_type ) + def apply( self, transformations ): + map( lambda t: t.configure_mem_fun( self ), transformations ) + + @property + def inst_arg( self ): + return self.__inst_arg + +class free_fun_controller_t( non_virtual_fun_controller_t ): + def __init__( self, function ): + non_virtual_fun_controller_t.__init__( self, function ) + + def apply( self, transformations ): + map( lambda t: t.configure_free_fun( self ), transformations ) + Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/function_transformation.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/function_transformation.py 2006-11-23 20:26:16 UTC (rev 751) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/function_transformation.py 2006-11-25 19:25:49 UTC (rev 752) @@ -7,13 +7,18 @@ """ import md5 import controllers +from pygccxml import declarations from pyplusplus import code_repository class function_transformation_t: def __init__(self, function, transformer_creator, **keywd): """Constructor. """ self.__function = function - self.__controller = controllers.mem_fun_controller_t( function ) + self.__controller = None + if isinstance( function.parent, declarations.class_t ): + self.__controller = controllers.mem_fun_controller_t( function ) + else: + self.__controller = controllers.free_fun_controller_t( function ) self.__transformers = map( lambda tr_creator: tr_creator( function ), transformer_creator ) self.__thread_safe = keywd.get( 'thread_safe', False ) self.__controller.apply( self.__transformers ) Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/templates.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/templates.py 2006-11-23 20:26:16 UTC (rev 751) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/templates.py 2006-11-25 19:25:49 UTC (rev 752) @@ -11,6 +11,16 @@ # function_name - C++ function name # function_alias - function name that Python user will see +class free_fun: + body = Template( os.linesep.join([ + '$declare_variables' + , '$pre_call' + , '$save_result$function($arg_expressions);' + , '$post_call' + , '$return' + ])) + + class mem_fun: body = Template( os.linesep.join([ '$declare_variables' Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/transformer.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/transformer.py 2006-11-23 20:26:16 UTC (rev 751) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/transformer.py 2006-11-25 19:25:49 UTC (rev 752) @@ -60,4 +60,9 @@ return self.get_argument( reference ).type def configure_mem_fun( self, controller ): - pass \ No newline at end of file + pass + + def configure_free_fun( self, controller ): + pass + + \ No newline at end of file Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py 2006-11-23 20:26:16 UTC (rev 751) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py 2006-11-25 19:25:49 UTC (rev 752) @@ -68,8 +68,7 @@ def __str__(self): return "output(%d)"%(self.arg_index) - def configure_mem_fun( self, controller ): - assert isinstance( controller, controllers.mem_fun_controller_t ) + def __configure_non_virtual( self, controller ): #removing arg from the function wrapper definition controller.remove_wrapper_arg( self.arg.name ) #declaring new variable, which will keep result @@ -79,6 +78,12 @@ #adding the variable to return variables list controller.return_variable( var_name ) + def configure_mem_fun( self, controller ): + self.__configure_non_virtual( controller ) + + def configure_free_fun(self, controller ): + self.__configure_non_virtual( controller ) + # input_t class input_t(transformer.transformer_t): """Handles a single input variable. @@ -107,11 +112,16 @@ def __str__(self): return "input(%d)"%(self.idx) - def configure_mem_fun( self, controller ): - assert isinstance( controller, controllers.mem_fun_controller_t ) + def __configure_non_virtual( self, controller ): w_arg = controller.find_wrapper_arg( self.arg.name ) w_arg.type = remove_ref_or_ptr( self.arg.type ) + def configure_mem_fun( self, controller ): + self.__configure_non_virtual( controller ) + + def configure_free_fun(self, controller ): + self.__configure_non_virtual( controller ) + # inout_t class inout_t(transformer.transformer_t): """Handles a single input/output variable. @@ -138,14 +148,19 @@ def __str__(self): return "inout(%d)"%(self.arg_index) - def configure_mem_fun(self, controller): - assert isinstance( controller, controllers.mem_fun_controller_t ) + def __configure_non_virtual(self, controller): w_arg = controller.find_wrapper_arg( self.arg.name ) w_arg.type = remove_ref_or_ptr( self.arg.type ) #adding the variable to return variables list controller.return_variable( w_arg.name ) + def configure_mem_fun( self, controller ): + self.__configure_non_virtual( controller ) + + def configure_free_fun(self, controller ): + self.__configure_non_virtual( controller ) + class input_array_t(transformer.transformer_t): """Handles an input array with fixed size. @@ -185,9 +200,7 @@ pre_call.append( 'pyplus_conv::copy_sequence( $pylist, pyplus_conv::array_inserter( $native_array, $array_size ) );' ) return string.Template( os.linesep.join( pre_call ) ) - def configure_mem_fun(self, controller): - assert isinstance( controller, controllers.mem_fun_controller_t ) - + def __configure_non_virtual(self, controller): w_arg = controller.find_wrapper_arg( self.arg.name ) w_arg.type = declarations.dummy_type_t( "boost::python::object" ) @@ -205,6 +218,11 @@ controller.modify_argument_expression( self.arg_index, native_array ) + def configure_mem_fun( self, controller ): + self.__configure_non_virtual( controller ) + + def configure_free_fun(self, controller ): + self.__configure_non_virtual( controller ) # output_array_t class output_array_t(transformer.transformer_t): @@ -244,8 +262,7 @@ def post_call_tmpl( self ): return string.Template( 'pyplus_conv::copy_container( $native_array, $native_array + $array_size, pyplus_conv::list_inserter( $pylist ) );' ) - def configure_mem_fun(self, controller): - assert isinstance( controller, controllers.mem_fun_controller_t ) + def __configure_non_virtual(self, controller): #removing arg from the function wrapper definition controller.remove_wrapper_arg( self.arg.name ) @@ -269,4 +286,10 @@ #adding the variable to return variables list controller.return_variable( pylist ) + + def configure_mem_fun( self, controller ): + self.__configure_non_virtual( controller ) + + def configure_free_fun(self, controller ): + self.__configure_non_virtual( controller ) Modified: pyplusplus_dev_ft/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/module_creator/creator.py 2006-11-23 20:26:16 UTC (rev 751) +++ pyplusplus_dev_ft/pyplusplus/module_creator/creator.py 2006-11-25 19:25:49 UTC (rev 752) @@ -533,7 +533,14 @@ self.curr_decl.call_policies = self.__call_policies_resolver( self.curr_decl ) self.__on_demand_include_call_policies( self.curr_decl.call_policies ) - maker = code_creators.free_function_t( function=self.curr_decl ) + maker = None + if self.curr_decl.transformations: + wrapper = code_creators.free_fun_transformed_wrapper_t( self.curr_decl ) + self.__extmodule.adopt_declaration_creator( wrapper ) + maker = code_creators.free_fun_transformed_t( self.curr_decl, wrapper ) + maker.associated_decl_creators.append( wrapper ) + else: + maker = code_creators.free_function_t( function=self.curr_decl ) self.curr_code_creator.adopt_creator( maker ) self.__opaque_types_manager.register_opaque( maker, self.curr_decl ) 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-23 20:26:16 UTC (rev 751) +++ pyplusplus_dev_ft/unittests/data/function_transformations_to_be_exported.hpp 2006-11-25 19:25:49 UTC (rev 752) @@ -6,8 +6,15 @@ #ifndef __function_transformations_to_be_exported_hpp__ #define __function_transformations_to_be_exported_hpp__ +#include <cmath> +#include <string> + namespace ft2{ +void hello_world( std::string& hw ){ + hw = "hello world!"; +} + //used to check output transformer struct calculator_t{ calculator_t(){ @@ -57,6 +64,7 @@ }; struct point3d_t{ + point3d_t() : x( 0 ), y(0), z(0) {} @@ -74,6 +82,10 @@ v[2] = z; } + static void distance( const point3d_t& pt, double& dist ){ + dist = sqrt( pt.x*pt.x + pt.y*pt.y + pt.z*pt.z ); + } + int x, y, z; }; Modified: pyplusplus_dev_ft/unittests/function_transformations_tester.py =================================================================== --- pyplusplus_dev_ft/unittests/function_transformations_tester.py 2006-11-23 20:26:16 UTC (rev 751) +++ pyplusplus_dev_ft/unittests/function_transformations_tester.py 2006-11-25 19:25:49 UTC (rev 752) @@ -5,6 +5,7 @@ import os import sys +import math import unittest import fundamental_tester_base from pyplusplus import function_transformers as ft @@ -24,6 +25,9 @@ mb.global_ns.calldefs().create_with_signature = True + hello_world = mb.free_fun( 'hello_world' ) + hello_world.add_transformation( ft.output(0) ) + calc = mb.class_('calculator_t' ) assign_funs = calc.mem_funs( lambda decl: decl.name.startswith( 'assign' ) ) assign_funs.add_transformation( ft.output(0), ft.output(1) ) @@ -40,6 +44,7 @@ point3d.add_wrapper_code( '' ) point3d.mem_fun( 'initialize' ).add_transformation( ft.input_array(0, size=3) ) point3d.mem_fun( 'position' ).add_transformation( ft.output_array(0, size=3) ) + point3d.mem_fun( 'distance' ).add_transformation( ft.output(1) ) #~ image = mb.class_( "image_t" ) #~ image.include() @@ -91,6 +96,9 @@ result = point3d.initialize( [ 1,2,3 ] ) self.failUnless( result== 1*2*3 and point3d.x == 1 and point3d.y==2 and point3d.z==3 ) self.failUnless( [1,2,3] == point3d.position()[0] ) + self.failUnless( module.point3d_t.distance( point3d )[0] == math.sqrt( 1*1 + 2*2 + 3*3 ) ) + + self.failUnless( module.hello_world()[0] == "hello world!" ) #~ 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. |
From: <rom...@us...> - 2006-11-27 21:12:54
|
Revision: 759 http://svn.sourceforge.net/pygccxml/?rev=759&view=rev Author: roman_yakovenko Date: 2006-11-27 13:12:53 -0800 (Mon, 27 Nov 2006) Log Message: ----------- adding virtual mem fun controller Modified Paths: -------------- pyplusplus_dev_ft/pyplusplus/code_creators/__init__.py pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py pyplusplus_dev_ft/pyplusplus/code_creators/calldef_utils.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/function_transformations_tester.py Modified: pyplusplus_dev_ft/pyplusplus/code_creators/__init__.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/code_creators/__init__.py 2006-11-27 10:23:04 UTC (rev 758) +++ pyplusplus_dev_ft/pyplusplus/code_creators/__init__.py 2006-11-27 21:12:53 UTC (rev 759) @@ -80,10 +80,9 @@ from calldef_transformed import mem_fun_transformed_wrapper_t from calldef_transformed import free_fun_transformed_t from calldef_transformed import free_fun_transformed_wrapper_t +from calldef_transformed import mem_fun_v_transformed_t +from calldef_transformed import mem_fun_v_transformed_wrapper_t -#~ from calldef_transformed import mem_fun_v_transformed_t -#~ from calldef_transformed import mem_fun_v_transformed_wrapper_t - from global_variable import global_variable_base_t from global_variable import global_variable_t from global_variable import array_gv_t Modified: pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py 2006-11-27 10:23:04 UTC (rev 758) +++ pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py 2006-11-27 21:12:53 UTC (rev 759) @@ -21,7 +21,7 @@ def remove_duplicate_linesep( code ): return __REMOVE_DUPLICAET_LINESEP.sub( os.linesep, code ) -class non_virtual_fun_transformed_t( calldef_t ): +class sealed_fun_transformed_t( calldef_t ): def __init__( self, function, wrapper=None ): calldef_t.__init__( self, function=function, wrapper=wrapper ) @@ -53,12 +53,9 @@ return '&%s' % full_name def create_call_policies( self ): - if self.controller.wrapper_call_policies.is_default(): - return '' - else: - return super( non_virtual_fun_transformed_t, self ).create_call_policies() + return '' -class non_virtual_fun_transformed_wrapper_t( calldef_wrapper_t ): +class sealed_fun_transformed_wrapper_t( calldef_wrapper_t ): def __init__( self, function ): calldef_wrapper_t.__init__( self, function=function ) @@ -115,19 +112,19 @@ def _create_impl(self): answer = [ self.create_declaration(self.declaration.alias) + '{' ] - answer.append( '// Transformed wrapper function for "%s"' % self.declaration ) + answer.append( self.indent( '// Transformed wrapper function for "%s"' % self.declaration ) ) body = self.create_body() body = remove_duplicate_linesep( body ) answer.append( self.indent( body ) ) answer.append( '}' ) return os.linesep.join( answer ) -class free_fun_transformed_t( non_virtual_fun_transformed_t ): +class free_fun_transformed_t( sealed_fun_transformed_t ): """Creates code for public non-virtual member functions. """ def __init__( self, function, wrapper=None ): - non_virtual_fun_transformed_t.__init__( self, function=function, wrapper=wrapper ) + sealed_fun_transformed_t.__init__( self, function=function, wrapper=wrapper ) self.works_on_instance = False def create_def_code( self ): @@ -140,14 +137,14 @@ return arg_utils.keywords_args() -class free_fun_transformed_wrapper_t( non_virtual_fun_transformed_wrapper_t ): +class free_fun_transformed_wrapper_t( sealed_fun_transformed_wrapper_t ): def __init__( self, function ): """Constructor. @param function: Function declaration @type function: calldef_t """ - non_virtual_fun_transformed_wrapper_t .__init__( self, function=function ) + sealed_fun_transformed_wrapper_t .__init__( self, function=function ) def function_type(self): return declarations.free_function_type_t( @@ -180,11 +177,11 @@ return declarations.full_name( self.declaration ) -class mem_fun_transformed_t( non_virtual_fun_transformed_t ): +class mem_fun_transformed_t( sealed_fun_transformed_t ): """Creates code for public non-virtual member functions. """ def __init__( self, function, wrapper=None ): - non_virtual_fun_transformed_t.__init__( self, function=function, wrapper=wrapper ) + sealed_fun_transformed_t.__init__( self, function=function, wrapper=wrapper ) def create_keywords_args(self): args = self.controller.wrapper_args[:] @@ -196,14 +193,14 @@ , args ) return arg_utils.keywords_args() -class mem_fun_transformed_wrapper_t( non_virtual_fun_transformed_wrapper_t ): +class mem_fun_transformed_wrapper_t( sealed_fun_transformed_wrapper_t ): def __init__( self, function ): """Constructor. @param function: Function declaration @type function: calldef_t """ - non_virtual_fun_transformed_wrapper_t.__init__( self, function=function ) + sealed_fun_transformed_wrapper_t.__init__( self, function=function ) def __is_global( self ): return not isinstance( self.parent, class_declaration.class_wrapper_t ) @@ -247,3 +244,101 @@ return self.controller.inst_arg.name + '.' + self.declaration.name else: return declarations.full_name( self.declaration ) + +class mem_fun_v_transformed_t( calldef_t ): + def __init__( self, function, wrapper=None ): + calldef_t.__init__( self, function=function, wrapper=wrapper ) + + @property + def ft( self ): #function transformation + return self.declaration.transformations[0] + + @property + def controller( self ): + return self.ft.controller + + def _get_alias_impl( self ): + return self.wrapper.ft.alias + + def create_function_type_alias_code( self, exported_class_alias=None ): + ftype = self.wrapper.function_type() + return 'typedef %s;' % ftype.create_typedef( self.function_type_alias, exported_class_alias ) + + def create_function_ref_code(self, use_function_alias=False): + full_name = self.wrapper.full_name() + + if use_function_alias: + return '%s( &%s )' \ + % ( self.function_type_alias, full_name ) + elif self.declaration.create_with_signature: + func_type = self.wrapper.function_type() + return '(%s)( &%s )' % ( func_type, full_name ) + else: + return '&%s' % full_name + + def create_call_policies( self ): + return '' + +class mem_fun_v_transformed_wrapper_t( calldef_wrapper_t ): + def __init__( self, function ): + calldef_wrapper_t.__init__( self, function=function ) + + @property + def ft( self ): #function transformation + return self.declaration.transformations[0] + + @property + def controller( self ): + return self.ft.controller + + def create_declaration(self, name): + template = 'static %(return_type)s %(name)s( %(args)s )' + + return template % { + 'return_type' : self.controller.wrapper_return_type.decl_string + , 'name' : self.wrapper_name() + , 'args' : self.args_declaration() + } + + def resolve_function_ref( self ): + raise NotImplementedError() + + def create_body(self): + cntrl = self.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 } + + return_stmt_creator = calldef_utils.return_stmt_creator_t( self + , self.controller + , self.controller.result_variable + , self.controller.return_variables ) + + post_call = os.linesep.join( cntrl.post_call ) + if return_stmt_creator.pre_return_code: + post_call = os.linesep.join( [post_call, return_stmt_creator.pre_return_code] ) + + 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' : post_call + , 'save_result' : result_var_assign + , 'function' : self.resolve_function_ref() + , 'arg_expressions' : self.PARAM_SEPARATOR.join( cntrl.arg_expressions ) + , 'return' : return_stmt_creator.statement + }) + + def _create_impl(self): + answer = [ self.create_declaration(self.declaration.alias) + '{' ] + answer.append( self.indent( '// Transformed wrapper function for "%s"' % self.declaration ) ) + body = self.create_body() + body = remove_duplicate_linesep( body ) + answer.append( self.indent( body ) ) + answer.append( '}' ) + return os.linesep.join( answer ) Modified: pyplusplus_dev_ft/pyplusplus/code_creators/calldef_utils.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/code_creators/calldef_utils.py 2006-11-27 10:23:04 UTC (rev 758) +++ pyplusplus_dev_ft/pyplusplus/code_creators/calldef_utils.py 2006-11-27 21:12:53 UTC (rev 759) @@ -123,29 +123,31 @@ def statement( self ): if None is self.__return_stmt: stmt = '' + bpl_object = algorithm.create_identifier( self.__creator, 'boost::python::object' ) make_tuple = algorithm.create_identifier( self.__creator, 'boost::python::make_tuple' ) make_object = algorithm.create_identifier( self.__creator, 'pyplusplus::call_policies::make_object' ) - if self.__return_vars: - if not declarations.is_void( self.__function.return_type ): - if self.__function.call_policies.is_default(): - self.__return_vars.insert( 0, self.__result_var.name ) - else: - self.__return_vars.insert( 0 - , declarations.call_invocation.join( - declarations.templates.join( make_object, [self.__call_policy_alias] ) - , [self.__result_var.name] ) ) - + if not declarations.is_void( self.__function.return_type ): + if self.__function.call_policies.is_default(): + self.__return_vars.insert( 0, self.__result_var.name ) + else: + self.__return_vars.insert( 0 + , declarations.call_invocation.join( + declarations.templates.join( make_object, [self.__call_policy_alias] ) + , [self.__result_var.name] ) ) + + if 0 == len( self.__return_vars ): + pass + elif 1 == len( self.__return_vars ): + stmt = bpl_object + '( %s )' % self.__return_vars[ 0 ] + else: # 1 < stmt = declarations.call_invocation.join( make_tuple, self.__return_vars ) if self.__creator.LINE_LENGTH < len( stmt ): stmt = declarations.call_invocation.join( - make_tuple - , self.__return_vars - , os.linesep + self.__creator.indent( self.__creator.PARAM_SEPARATOR, 6 ) ) - elif not declarations.is_void( self.__function.return_type ): - stmt = self.__result_var.name - else: - pass + make_tuple + , self.__return_vars + , os.linesep + self.__creator.indent( self.__creator.PARAM_SEPARATOR, 6 ) ) + if stmt: stmt = 'return ' + stmt + ';' self.__return_stmt = stmt Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py 2006-11-27 10:23:04 UTC (rev 758) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py 2006-11-27 21:12:53 UTC (rev 759) @@ -25,18 +25,13 @@ , name=self.name , type=self.type , initialize_expr=self.initialize_expr ) - -class controller_base_t( object ): - def __init__( self, function ): + +class variables_manager_t( object ): + def __init__( self ): object.__init__( self ) - self.__function = function self.__variables = [] #variables - self.__names_in_use = set( map( lambda arg: arg.name, self.function.arguments ) ) + self.__names_in_use = set() - @property - def function( self ): - return self.__function - @property def variables( self ): return self.__variables @@ -46,7 +41,7 @@ self.__variables.append( variable_t( type, unique_name, initialize_expr ) ) return unique_name - def register_variable_name( self, name ): + def register_name( self, name ): return self.__create_unique_var_name( name ) def __create_unique_var_name( self, name ): @@ -60,13 +55,27 @@ self.__names_in_use.add( unique_name ) return unique_name +def create_variables_manager( function ): + vm = variables_manager_t() + map( lambda arg: vm.register_name( arg.name ) , function.arguments ) + return vm + +class controller_base_t( object ): + def __init__( self, function ): + self.__function = function + + @property + def function( self ): + return self.__function + def apply( self, transformations ): raise NotImplementedError() -class non_virtual_fun_controller_t( controller_base_t ): +class sealed_fun_controller_t( controller_base_t ): #base class for free and member function controllers def __init__( self, function ): controller_base_t.__init__( self, function ) + self.__vars_manager = create_variables_manager( function ) self.__wrapper_args = [ arg.clone() for arg in function.arguments ] self.__result_var = variable_t( self.function.return_type , self.register_variable_name( 'result' ) ) @@ -74,7 +83,17 @@ self.__pre_call = [] self.__post_call = [] self.__arg_expressions = [ arg.name for arg in function.arguments ] + + @property + def variables( self ): + return self.__vars_manager.variables + def declare_variable( self, type, name, initialize_expr='' ): + return self.__vars_manager.declare_variable( type, name, initialize_expr) + + def register_variable_name( self, name ): + return self.__vars_manager.register_name( name ) + @property def result_variable( self ): return self.__result_var @@ -103,26 +122,22 @@ def arg_expressions( self ): return self.__arg_expressions - def modify_argument_expression( self, index, expression ): + def modify_arg_expression( self, index, expression ): self.arg_expressions[ index ] = expression @property def wrapper_return_type( self ): - if len( self.return_variables ): + return_vars_count = len( self.return_variables ) + if not declarations.is_void( self.function.return_type ): + return_vars_count += 1 + if 0 == return_vars_count: + return self.function.return_type #return type is void + elif 1 == return_vars_count: + return declarations.dummy_type_t( 'boost::python::object' ) + else: return declarations.dummy_type_t( 'boost::python::tuple' ) - else: - return self.function.return_type - + @property - def wrapper_call_policies( self ): - #prevent recursive import - from pyplusplus import decl_wrappers - if 'boost::python::tuple' == self.wrapper_return_type.decl_string: - return decl_wrappers.default_call_policies() - else: - return self.function.call_policies - - @property def return_variables( self ): return self.__return_variables @@ -143,13 +158,9 @@ def add_post_call_code( self, code ): self.__post_call.append( code ) - def set_input_param( self, index, var_name_or_expr ): - self.__input_params[ index ] = var_name_or_expr - - -class mem_fun_controller_t( non_virtual_fun_controller_t ): +class mem_fun_controller_t( sealed_fun_controller_t ): def __init__( self, function ): - non_virtual_fun_controller_t.__init__( self, function ) + sealed_fun_controller_t.__init__( self, function ) inst_arg_type = declarations.declarated_t( self.function.parent ) if self.function.has_const: @@ -168,10 +179,67 @@ def inst_arg( self ): return self.__inst_arg -class free_fun_controller_t( non_virtual_fun_controller_t ): +class free_fun_controller_t( sealed_fun_controller_t ): def __init__( self, function ): - non_virtual_fun_controller_t.__init__( self, function ) + sealed_fun_controller_t.__init__( self, function ) def apply( self, transformations ): map( lambda t: t.configure_free_fun( self ), transformations ) + +class virtual_mem_fun_controller_t( controller_base_t ): + def __init__( self, function ): + controller_base_t.__init__( self, function ) + self.__py_vars_manager = create_variables_manager( function ) + self.__py_function_var \ + = self.__py_vars_manager.register_name( 'func_' + function.alias ) + self.__py_pre_call = [] + self.__py_post_call = [] + self.__py_result_var = variable_t( declarations.dummy_type_t( 'boost::python::object' ) + , self.register_py_variable_name( 'py_result' ) ) + + self.__py_arg_expressions = [ arg.name for arg in function.arguments ] + + @property + def py_variables( self ): + return self.__py_vars_manager.variables + + def declare_py_variable( self, type, name, initialize_expr='' ): + return self.__py_vars_manager.declare_variable( type, name, initialize_expr) + + def register_py_variable_name( self, name ): + return self.__py_vars_manager.register_name( name ) + + @property + def py_function_var( self ): + return self.__py_function_var + + @property + def py_pre_call( self ): + return self.__py_pre_call + + def add_py_pre_call_code( self, code ): + self.__py_pre_call.append( code ) + + @property + def py_post_call( self ): + return self.__py_post_call + + def add_py_post_call_code( self, code ): + self.__py_post_call.append( code ) + + @property + def py_result_variable( self ): + return self.__py_result_var + + @property + def py_arg_expressions( self ): + return filter( None, self.__py_arg_expressions ) + + def remove_py_arg( self, index ): + self.__py_arg_expressions[ index ] = None + + def modify_py_arg_expression( self, index, expression ): + self.arg_expressions[ index ] = expression + + Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/templates.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/templates.py 2006-11-27 10:23:04 UTC (rev 758) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/templates.py 2006-11-27 21:12:53 UTC (rev 759) @@ -30,7 +30,7 @@ , '$return' ])) -class mem_fun_v: +class virtual_mem_fun: override_body = Template( os.linesep.join([ 'if( boost::python::override $py_function_var = this->get_override( "$function_alias" ) ){' , ' $declare_py_variables' Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py 2006-11-27 10:23:04 UTC (rev 758) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py 2006-11-27 21:12:53 UTC (rev 759) @@ -74,7 +74,7 @@ #declaring new variable, which will keep result var_name = controller.declare_variable( remove_ref_or_ptr( self.arg.type ), self.arg.name ) #adding just declared variable to the original function call expression - controller.modify_argument_expression( self.arg_index, var_name ) + controller.modify_arg_expression( self.arg_index, var_name ) #adding the variable to return variables list controller.return_variable( var_name ) @@ -84,6 +84,12 @@ def configure_free_fun(self, controller ): self.__configure_non_virtual( controller ) + def configure_virtual_mem_fun( self, controller ): + assert isinstance( controller, controllers.virtual_mem_fun_controller_t ) + #removing arg from the function wrapper definition + controller.remove_py_arg( self.arg_index ) + + # input_t class input_t(transformer.transformer_t): """Handles a single input variable. @@ -216,7 +222,7 @@ controller.add_pre_call_code( seq2arr ) - controller.modify_argument_expression( self.arg_index, native_array ) + controller.modify_arg_expression( self.arg_index, native_array ) def configure_mem_fun( self, controller ): self.__configure_non_virtual( controller ) @@ -272,7 +278,7 @@ , '[%d]' % self.array_size ) #adding just declared variable to the original function call expression - controller.modify_argument_expression( self.arg_index, native_array ) + controller.modify_arg_expression( self.arg_index, native_array ) # Declare a Python list which will receive the output... pylist = controller.declare_variable( declarations.dummy_type_t( "boost::python::list" ) @@ -292,4 +298,3 @@ def configure_free_fun(self, controller ): self.__configure_non_virtual( controller ) - Modified: pyplusplus_dev_ft/unittests/function_transformations_tester.py =================================================================== --- pyplusplus_dev_ft/unittests/function_transformations_tester.py 2006-11-27 10:23:04 UTC (rev 758) +++ pyplusplus_dev_ft/unittests/function_transformations_tester.py 2006-11-27 21:12:53 UTC (rev 759) @@ -95,10 +95,10 @@ point3d = module.point3d_t() result = point3d.initialize( [ 1,2,3 ] ) self.failUnless( result== 1*2*3 and point3d.x == 1 and point3d.y==2 and point3d.z==3 ) - self.failUnless( [1,2,3] == point3d.position()[0] ) - self.failUnless( module.point3d_t.distance( point3d )[0] == math.sqrt( 1*1 + 2*2 + 3*3 ) ) + self.failUnless( [1,2,3] == point3d.position() ) + self.failUnless( module.point3d_t.distance( point3d ) == math.sqrt( 1*1 + 2*2 + 3*3 ) ) - self.failUnless( module.hello_world()[0] == "hello world!" ) + self.failUnless( module.hello_world() == "hello world!" ) #~ 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. |
From: <rom...@us...> - 2006-11-28 21:23:48
|
Revision: 762 http://svn.sourceforge.net/pygccxml/?rev=762&view=rev Author: roman_yakovenko Date: 2006-11-28 13:23:41 -0800 (Tue, 28 Nov 2006) Log Message: ----------- adding support for virtual function part of transformer Modified Paths: -------------- pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py pyplusplus_dev_ft/pyplusplus/code_creators/calldef_utils.py pyplusplus_dev_ft/pyplusplus/code_repository/convenience.py pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py pyplusplus_dev_ft/pyplusplus/function_transformers/function_transformation.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-28 14:01:48 UTC (rev 761) +++ pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py 2006-11-28 21:23:41 UTC (rev 762) @@ -3,7 +3,6 @@ # accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) -import re import os import algorithm import code_creator @@ -17,9 +16,10 @@ #TODO: constructors also can have transformation defined. We should use make _init # function for this purpose -__REMOVE_DUPLICAET_LINESEP = re.compile( '(%s){2,}' % os.linesep ) def remove_duplicate_linesep( code ): - return __REMOVE_DUPLICAET_LINESEP.sub( os.linesep, code ) + lines = code.split( os.linesep ) + lines = filter( lambda line: line.strip(), lines ) + return os.linesep.join( lines ) class sealed_fun_transformed_t( calldef_t ): def __init__( self, function, wrapper=None ): @@ -260,25 +260,44 @@ def _get_alias_impl( self ): return self.wrapper.ft.alias - def create_function_type_alias_code( self, exported_class_alias=None ): - ftype = self.wrapper.function_type() - return 'typedef %s;' % ftype.create_typedef( self.function_type_alias, exported_class_alias ) + def create_function_type_alias_code( self, exported_class_alias=None ): + result = [] + ftype = self.declaration.function_type() + result.append( 'typedef %s;' % ftype.create_typedef( self.function_type_alias, exported_class_alias ) ) + if self.wrapper: + result.append( os.linesep ) + ftype = self.wrapper.function_type() + result.append( 'typedef %s;' % ftype.create_typedef( self.default_function_type_alias ) ) + return ''.join( result ) + + def create_doc(self): + return None + def create_function_ref_code(self, use_function_alias=False): - full_name = self.wrapper.full_name() - + result = [] if use_function_alias: - return '%s( &%s )' \ - % ( self.function_type_alias, full_name ) + 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() ) ) elif self.declaration.create_with_signature: - func_type = self.wrapper.function_type() - return '(%s)( &%s )' % ( func_type, full_name ) + 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() ) ) else: - return '&%s' % full_name + 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 ) - def create_call_policies( self ): - return '' - class mem_fun_v_transformed_wrapper_t( calldef_wrapper_t ): def __init__( self, function ): calldef_wrapper_t.__init__( self, function=function ) @@ -291,54 +310,98 @@ def controller( self ): return self.ft.controller - def create_declaration(self, name): - template = 'static %(return_type)s %(name)s( %(args)s )' + def default_full_name(self): + return self.parent.full_name + '::default_' + self.declaration.alias + 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 create_declaration(self, name, has_virtual=True): + template = '%(virtual)s%(return_type)s %(name)s( %(args)s )%(constness)s %(throw)s' + + virtual = 'virtual ' + if not has_virtual: + virtual = '' + + constness = '' + if self.declaration.has_const: + constness = ' const ' + return template % { - 'return_type' : self.controller.wrapper_return_type.decl_string - , 'name' : self.wrapper_name() + 'virtual' : virtual + , 'return_type' : self.declaration.return_type.decl_string + , 'name' : name , 'args' : self.args_declaration() + , 'constness' : constness + , 'throw' : self.throw_specifier_code() } - def resolve_function_ref( self ): - raise NotImplementedError() + def wrapped_class_identifier( self ): + return algorithm.create_identifier( self, declarations.full_name( self.declaration.parent ) ) - def create_body(self): - cntrl = self.controller - - make_object = algorithm.create_identifier( self, 'pyplusplus::call_policies::make_object' ) - make_tuple = algorithm.create_identifier( self, 'boost::python::make_tuple' ) + def create_virtual_body(self): + cntrl = self.controller.override_controller - result_var_assign = '' + tmpl_values = dict() + tmpl_values['py_function_var'] = cntrl.py_function_var + tmpl_values['function_alias'] = self.declaration.alias + tmpl_values['declare_py_variables'] \ + = os.linesep.join( map( lambda var: var.declare_var_string(), cntrl.py_variables ) ) + tmpl_values['py_pre_call'] = os.linesep.join( cntrl.py_pre_call ) + tmpl_values['py_post_call'] = os.linesep.join( cntrl.py_post_call ) + tmpl_values['py_arg_expressions'] = '' + if cntrl.py_arg_expressions: + tmpl_values['py_arg_expressions'] \ + = ', ' + declarations.call_invocation.join( '', cntrl.py_arg_expressions ) + + tmpl_values['save_py_result'] = "bpl::object %s = " % cntrl.py_result_variable.name + tmpl_values['py_return'] = '' + tmpl_values['cpp_return'] = '' 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 } + tmpl_values['py_return'] \ + = 'return bpl::extract< %(type)s >( pyplus_conv::get_out_argument( %(py_result)s, 0 ) );' \ + % { 'type' : self.declaration.return_type.decl_string + , 'py_result' : cntrl.py_result_variable.name } + tmpl_values['cpp_return'] = 'return ' - return_stmt_creator = calldef_utils.return_stmt_creator_t( self - , self.controller - , self.controller.result_variable - , self.controller.return_variables ) + tmpl_values['wrapped_class'] = self.wrapped_class_identifier() + tmpl_values['function_name'] = self.declaration.name - post_call = os.linesep.join( cntrl.post_call ) - if return_stmt_creator.pre_return_code: - post_call = os.linesep.join( [post_call, return_stmt_creator.pre_return_code] ) - - 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' : post_call - , 'save_result' : result_var_assign - , 'function' : self.resolve_function_ref() - , 'arg_expressions' : self.PARAM_SEPARATOR.join( cntrl.arg_expressions ) - , 'return' : return_stmt_creator.statement - }) - - def _create_impl(self): - answer = [ self.create_declaration(self.declaration.alias) + '{' ] - answer.append( self.indent( '// Transformed wrapper function for "%s"' % self.declaration ) ) - body = self.create_body() + arg_utils = calldef_utils.argument_utils_t( self.declaration + , algorithm.make_id_creator( self ) + , self.declaration.arguments ) + tmpl_values['cpp_arg_expressions'] = arg_utils.call_args() + + return cntrl.template.substitute(tmpl_values) + + 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_function(self): + answer = [ self.create_declaration(self.declaration.name) + '{' ] + body = self.create_virtual_body() body = remove_duplicate_linesep( body ) answer.append( self.indent( body ) ) answer.append( '}' ) return os.linesep.join( answer ) + + def create_default_function( self ): + answer = [ self.create_declaration('default_' + self.declaration.alias, False) + '{' ] + answer.append( self.indent( self.create_default_body() ) ) + answer.append( '}' ) + return os.linesep.join( answer ) + + def _create_impl(self): + answer = [ self.create_function() ] + answer.append( os.linesep ) + answer.append( self.create_default_function() ) + return os.linesep.join( answer ) Modified: pyplusplus_dev_ft/pyplusplus/code_creators/calldef_utils.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/code_creators/calldef_utils.py 2006-11-28 14:01:48 UTC (rev 761) +++ pyplusplus_dev_ft/pyplusplus/code_creators/calldef_utils.py 2006-11-28 21:23:41 UTC (rev 762) @@ -90,7 +90,8 @@ def call_args( self ): params = [] for index, arg in enumerate( self.__args ): - params.append( decl_wrappers.python_traits.call_traits( arg.type ) % self.argument_name( index ) ) + params.append( decl_wrappers.python_traits.call_traits( arg.type ) + % self.argument_name( index ) ) return ', '.join( params ) class return_stmt_creator_t( object ): Modified: pyplusplus_dev_ft/pyplusplus/code_repository/convenience.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/code_repository/convenience.py 2006-11-28 14:01:48 UTC (rev 761) +++ pyplusplus_dev_ft/pyplusplus/code_repository/convenience.py 2006-11-28 21:23:41 UTC (rev 762) @@ -145,6 +145,16 @@ } } +inline boost::python::object +get_out_argument( boost::python::object result, index_type index ){ + if( PySequence_Check( result.ptr() ) ){ + return result[ index ]; + } + else{ + return result; + } +} + } /*pyplusplus*/ } /*convenience*/ namespace pyplus_conv = pyplusplus::convenience; Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py 2006-11-28 14:01:48 UTC (rev 761) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py 2006-11-28 21:23:41 UTC (rev 762) @@ -100,7 +100,7 @@ @property def template( self ): - return templates.mem_fun.body + return templates.sealed_fun.body @property def wrapper_args( self ): @@ -188,58 +188,73 @@ class virtual_mem_fun_controller_t( controller_base_t ): - def __init__( self, function ): - controller_base_t.__init__( self, function ) - self.__py_vars_manager = create_variables_manager( function ) - self.__py_function_var \ - = self.__py_vars_manager.register_name( 'func_' + function.alias ) - self.__py_pre_call = [] - self.__py_post_call = [] - self.__py_result_var = variable_t( declarations.dummy_type_t( 'boost::python::object' ) - , self.register_py_variable_name( 'py_result' ) ) + class override_fun_controller_t( controller_base_t ): + def __init__( self, function ): + controller_base_t.__init__( self, function ) + self.__py_vars_manager = create_variables_manager( function ) + self.__py_function_var \ + = self.__py_vars_manager.register_name( 'func_' + function.alias ) + self.__py_pre_call = [] + self.__py_post_call = [] + self.__py_result_var = variable_t( declarations.dummy_type_t( 'boost::python::object' ) + , self.register_py_variable_name( 'py_result' ) ) + + self.__py_arg_expressions = [ arg.name for arg in function.arguments ] - self.__py_arg_expressions = [ arg.name for arg in function.arguments ] - - @property - def py_variables( self ): - return self.__py_vars_manager.variables + @property + def template( self ): + return templates.virtual_mem_fun.override_body + + @property + def py_variables( self ): + return self.__py_vars_manager.variables + + def declare_py_variable( self, type, name, initialize_expr='' ): + return self.__py_vars_manager.declare_variable( type, name, initialize_expr) - def declare_py_variable( self, type, name, initialize_expr='' ): - return self.__py_vars_manager.declare_variable( type, name, initialize_expr) - - def register_py_variable_name( self, name ): - return self.__py_vars_manager.register_name( name ) + def register_py_variable_name( self, name ): + return self.__py_vars_manager.register_name( name ) + + @property + def py_function_var( self ): + return self.__py_function_var - @property - def py_function_var( self ): - return self.__py_function_var + @property + def py_pre_call( self ): + return self.__py_pre_call + + def add_py_pre_call_code( self, code ): + self.__py_pre_call.append( code ) + + @property + def py_post_call( self ): + return self.__py_post_call + + def add_py_post_call_code( self, code ): + self.__py_post_call.append( code ) - @property - def py_pre_call( self ): - return self.__py_pre_call + @property + def py_result_variable( self ): + return self.__py_result_var - def add_py_pre_call_code( self, code ): - self.__py_pre_call.append( code ) - - @property - def py_post_call( self ): - return self.__py_post_call + @property + def py_arg_expressions( self ): + return filter( None, self.__py_arg_expressions ) - def add_py_post_call_code( self, code ): - self.__py_post_call.append( code ) + def remove_py_arg( self, index ): + self.__py_arg_expressions[ index ] = None + + def modify_py_arg_expression( self, index, expression ): + self.arg_expressions[ index ] = expression - @property - def py_result_variable( self ): - return self.__py_result_var - @property - def py_arg_expressions( self ): - return filter( None, self.__py_arg_expressions ) + def __init__( self, function ): + controller_base_t.__init__( self, function ) + self.__override_cntrl = self.override_fun_controller_t( function ) - def remove_py_arg( self, index ): - self.__py_arg_expressions[ index ] = None - - def modify_py_arg_expression( self, index, expression ): - self.arg_expressions[ index ] = expression + def apply( self, transformations ): + map( lambda t: t.configure_virtual_mem_fun( self ), transformations ) - + @property + def override_controller( self ): + return self.__override_cntrl Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/function_transformation.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/function_transformation.py 2006-11-28 14:01:48 UTC (rev 761) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/function_transformation.py 2006-11-28 21:23:41 UTC (rev 762) @@ -16,7 +16,10 @@ self.__function = function self.__controller = None if isinstance( function.parent, declarations.class_t ): - self.__controller = controllers.mem_fun_controller_t( function ) + if declarations.VIRTUALITY_TYPES.NOT_VIRTUAL == function.virtuality: + self.__controller = controllers.mem_fun_controller_t( function ) + else: + self.__controller = controllers.virtual_mem_fun_controller_t( function ) else: self.__controller = controllers.free_fun_controller_t( function ) self.__transformers = map( lambda tr_creator: tr_creator( function ), transformer_creator ) Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/templates.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/templates.py 2006-11-28 14:01:48 UTC (rev 761) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/templates.py 2006-11-28 21:23:41 UTC (rev 762) @@ -11,17 +11,10 @@ # function_name - C++ function name # function_alias - function name that Python user will see -class free_fun: - body = Template( os.linesep.join([ - '$declare_variables' - , '$pre_call' - , '$save_result$function($arg_expressions);' - , '$post_call' - , '$return' - ])) +#TODO: pre_call, post_call terminology should be changed. Use prefix and suffix +#instead: http://boost.org/libs/smart_ptr/sp_techniques.html#wrapper - -class mem_fun: +class sealed_fun: body = Template( os.linesep.join([ '$declare_variables' , '$pre_call' @@ -32,15 +25,16 @@ class virtual_mem_fun: override_body = Template( os.linesep.join([ - 'if( boost::python::override $py_function_var = this->get_override( "$function_alias" ) ){' + 'namespace bpl = boost::python;' + , 'if( bpl::override $py_function_var = this->get_override( "$function_alias" ) ){' , ' $declare_py_variables' , ' $py_pre_call' - , ' ${save_py_result}boost::python::call<$py_return_type>( $py_function_var$py_arg_expressions );' + , ' ${save_py_result}bpl::call<bpl::object>( $py_function_var.ptr()$py_arg_expressions );' , ' $py_post_call' , ' $py_return' , '}' , 'else{' - , ' $cpp_return$wrapped_class::%function_name( $cpp_arg_expressions );' + , ' $cpp_return$wrapped_class::$function_name( $cpp_arg_expressions );' , '}' ])) @@ -50,7 +44,6 @@ , 'if( $wrapper_class $py_wrapper_var = dynamic_cast< $wrapper_class >( boost::addressof( $wrapped_inst ) ) ){' , ' // The following call is done on an instance created in Python i.e.' , ' // a wrapper instance. this call might invoke python code.' - , ' // a wrapper instance. this call might invoke python code.' , ' $py_save_result$wrapped_inst->$wrapped_class::$function_name($py_arg_expressions);' , '}' , 'else{' Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py 2006-11-28 14:01:48 UTC (rev 761) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py 2006-11-28 21:23:41 UTC (rev 762) @@ -72,8 +72,7 @@ """Returns list of header files that transformer generated code depends on.""" return [ code_repository.convenience.file_name ] - - def __configure_non_virtual( self, controller ): + def __configure_sealed( self, controller ): #removing arg from the function wrapper definition controller.remove_wrapper_arg( self.arg.name ) #declaring new variable, which will keep result @@ -84,21 +83,21 @@ controller.return_variable( var_name ) def configure_mem_fun( self, controller ): - self.__configure_non_virtual( controller ) + self.__configure_sealed( controller ) def configure_free_fun(self, controller ): - self.__configure_non_virtual( controller ) + self.__configure_sealed( controller ) def configure_virtual_mem_fun( self, controller ): assert isinstance( controller, controllers.virtual_mem_fun_controller_t ) - #removing arg from the function wrapper definition - controller.remove_py_arg( self.arg_index ) + override_cntrl = controller.override_controller + override_cntrl.remove_py_arg( self.arg_index ) 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 ) + , type=remove_ref_or_ptr( self.arg.type ).decl_string + , py_result=override_cntrl.py_result_variable.name ) + override_cntrl.add_py_post_call_code( store_py_result_in_arg ) # input_t @@ -129,15 +128,15 @@ def __str__(self): return "input(%d)"%(self.idx) - def __configure_non_virtual( self, controller ): + def __configure_sealed( self, controller ): w_arg = controller.find_wrapper_arg( self.arg.name ) w_arg.type = remove_ref_or_ptr( self.arg.type ) def configure_mem_fun( self, controller ): - self.__configure_non_virtual( controller ) + self.__configure_sealed( controller ) def configure_free_fun(self, controller ): - self.__configure_non_virtual( controller ) + self.__configure_sealed( controller ) def configure_virtual_mem_fun( self, controller ): pass #according to boost.python documentation, it will create a copy of @@ -170,17 +169,17 @@ def __str__(self): return "inout(%d)"%(self.arg_index) - def __configure_non_virtual(self, controller): + def __configure_sealed(self, controller): w_arg = controller.find_wrapper_arg( self.arg.name ) w_arg.type = remove_ref_or_ptr( self.arg.type ) #adding the variable to return variables list controller.return_variable( w_arg.name ) def configure_mem_fun( self, controller ): - self.__configure_non_virtual( controller ) + self.__configure_sealed( controller ) def configure_free_fun(self, controller ): - self.__configure_non_virtual( controller ) + self.__configure_sealed( controller ) def configure_virtual_mem_fun( self, controller ): assert isinstance( controller, controllers.virtual_mem_fun_controller_t ) @@ -230,7 +229,7 @@ pre_call.append( 'pyplus_conv::copy_sequence( $pylist, pyplus_conv::array_inserter( $native_array, $array_size ) );' ) return string.Template( os.linesep.join( pre_call ) ) - def __configure_non_virtual(self, controller): + def __configure_sealed(self, controller): w_arg = controller.find_wrapper_arg( self.arg.name ) w_arg.type = declarations.dummy_type_t( "boost::python::object" ) @@ -249,10 +248,10 @@ controller.modify_arg_expression( self.arg_index, native_array ) def configure_mem_fun( self, controller ): - self.__configure_non_virtual( controller ) + self.__configure_sealed( controller ) def configure_free_fun(self, controller ): - self.__configure_non_virtual( controller ) + self.__configure_sealed( controller ) # output_array_t class output_array_t(transformer.transformer_t): @@ -292,7 +291,7 @@ def post_call_tmpl( self ): return string.Template( 'pyplus_conv::copy_container( $native_array, $native_array + $array_size, pyplus_conv::list_inserter( $pylist ) );' ) - def __configure_non_virtual(self, controller): + def __configure_sealed(self, controller): #removing arg from the function wrapper definition controller.remove_wrapper_arg( self.arg.name ) @@ -318,7 +317,7 @@ controller.return_variable( pylist ) def configure_mem_fun( self, controller ): - self.__configure_non_virtual( controller ) + self.__configure_sealed( controller ) def configure_free_fun(self, controller ): - self.__configure_non_virtual( controller ) + self.__configure_sealed( controller ) 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-28 14:01:48 UTC (rev 761) +++ pyplusplus_dev_ft/unittests/data/function_transformations_to_be_exported.hpp 2006-11-28 21:23:41 UTC (rev 762) @@ -91,26 +91,26 @@ } -//~ namespace ft{ +namespace ft{ -//~ struct image_t{ +struct image_t{ - //~ image_t( unsigned int h, unsigned int w ) - //~ : m_height( h ) - //~ , m_width( w ) - //~ {} + image_t( unsigned int h, unsigned int w ) + : m_height( h ) + , m_width( w ) + {} - //~ // Made the method 'virtual' for now because func transformers - //~ // are currently only taken into account on virtual functions. - //~ void get_size( unsigned int& h, unsigned int& w ){ + // 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; //~ } - //~ // Return only one value - //~ virtual void get_one_value(unsigned int& h) { - //~ h = m_height; - //~ } + // 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 @@ -137,10 +137,10 @@ //~ v[2] = 3; //~ } - //~ unsigned int m_width; - //~ unsigned int m_height; + unsigned int m_width; + unsigned int m_height; -//~ }; +}; //~ // Provide an instance created in C++ (i.e. this is not a wrapper instance) //~ image_t cpp_instance(12,13); @@ -183,6 +183,6 @@ //~ ~ft_private_destructor_t(){} //~ }; -//~ } +} #endif//__function_transformations_to_be_exported_hpp__ Modified: pyplusplus_dev_ft/unittests/function_transformations_tester.py =================================================================== --- pyplusplus_dev_ft/unittests/function_transformations_tester.py 2006-11-28 14:01:48 UTC (rev 761) +++ pyplusplus_dev_ft/unittests/function_transformations_tester.py 2006-11-28 21:23:41 UTC (rev 762) @@ -46,13 +46,13 @@ point3d.mem_fun( 'position' ).add_transformation( ft.output_array(0, size=3) ) point3d.mem_fun( 'distance' ).add_transformation( ft.output(1) ) - #~ image = mb.class_( "image_t" ) - #~ image.include() - #~ image.add_wrapper_code( '' ) + 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_one_value" ).add_transformation( ft.output(0) ) + 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( "fixed_input_array" ).add_transformation( ft.input_array(0,3) ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
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. |
From: <rom...@us...> - 2006-11-29 20:12:39
|
Revision: 765 http://svn.sourceforge.net/pygccxml/?rev=765&view=rev Author: roman_yakovenko Date: 2006-11-29 12:10:52 -0800 (Wed, 29 Nov 2006) Log Message: ----------- adding treatment for array transformers for virtual mem fun Modified Paths: -------------- pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.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 15:05:10 UTC (rev 764) +++ pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py 2006-11-29 20:10:52 UTC (rev 765) @@ -384,9 +384,11 @@ tmpl_values['py_function_var'] = cntrl.py_function_var tmpl_values['function_alias'] = self.declaration.alias tmpl_values['declare_py_variables'] \ - = os.linesep.join( map( lambda var: var.declare_var_string(), cntrl.py_variables ) ) - tmpl_values['py_pre_call'] = os.linesep.join( cntrl.py_pre_call ) - tmpl_values['py_post_call'] = os.linesep.join( cntrl.py_post_call ) + = os.linesep + os.linesep.join( map( lambda var: self.indent( var.declare_var_string(), 2 ) + , cntrl.py_variables ) ) + + tmpl_values['py_pre_call'] = os.linesep + self.indent( os.linesep.join( cntrl.py_pre_call ), 2 ) + tmpl_values['py_post_call'] = os.linesep + self.indent( os.linesep.join( cntrl.py_post_call ), 2 ) tmpl_values['py_arg_expressions'] = '' if cntrl.py_arg_expressions: tmpl_values['py_arg_expressions'] \ Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py 2006-11-29 15:05:10 UTC (rev 764) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py 2006-11-29 20:10:52 UTC (rev 765) @@ -137,6 +137,9 @@ w_arg = controller.find_wrapper_arg( self.arg.name ) w_arg.type = remove_ref_or_ptr( self.arg.type ) + def __configure_v_mem_fun_default( self, controller ): + self.__configure_sealed( controller ) + def configure_mem_fun( self, controller ): self.__configure_sealed( controller ) @@ -144,7 +147,7 @@ self.__configure_sealed( controller ) def configure_virtual_mem_fun( self, controller ): - self.__configure_sealed( controller.default_controller ) + self.__configure_v_mem_fun_default( controller.default_controller ) # inout_t class inout_t(transformer.transformer_t): @@ -177,7 +180,10 @@ w_arg.type = remove_ref_or_ptr( self.arg.type ) #adding the variable to return variables list controller.return_variable( w_arg.name ) - + + def __configure_v_mem_fun_default( self, controller ): + self.__configure_sealed( controller ) + def __configure_v_mem_fun_override( self, controller ): tmpl = string.Template( '$name = boost::python::extract< $type >( pyplus_conv::get_out_argument( $py_result, "$name" ) );' ) @@ -194,8 +200,16 @@ def configure_virtual_mem_fun( self, controller ): self.__configure_v_mem_fun_override( controller.override_controller ) - self.__configure_sealed( controller.default_controller ) + self.__configure_v_mem_fun_default( controller.default_controller ) + +_seq2arr = string.Template( os.linesep.join([ + 'pyplus_conv::ensure_uniform_sequence< $type >( $pylist, $array_size );' + , 'pyplus_conv::copy_sequence( $pylist, pyplus_conv::array_inserter( $native_array, $array_size ) );'])) + +_arr2seq = string.Template( + 'pyplus_conv::copy_container( $native_array, $native_array + $array_size, pyplus_conv::list_inserter( $pylist ) );' ) + class input_array_t(transformer.transformer_t): """Handles an input array with fixed size. @@ -228,14 +242,8 @@ """Returns list of header files that transformer generated code depends on.""" return [ code_repository.convenience.file_name ] - @property - def pre_call_tmpl( self ): - pre_call = [] - pre_call.append( 'pyplus_conv::ensure_uniform_sequence< $type >( $pylist, $array_size );' ) - pre_call.append( 'pyplus_conv::copy_sequence( $pylist, pyplus_conv::array_inserter( $native_array, $array_size ) );' ) - return string.Template( os.linesep.join( pre_call ) ) - def __configure_sealed(self, controller): + global _seq2arr w_arg = controller.find_wrapper_arg( self.arg.name ) w_arg.type = declarations.dummy_type_t( "boost::python::object" ) @@ -243,22 +251,41 @@ native_array = controller.declare_variable( self.array_item_type , "native_" + self.arg.name , '[%d]' % self.array_size ) + + copy_pylist2arr = _seq2arr.substitute( type=self.array_item_type + , pylist=w_arg.name + , array_size=self.array_size + , native_array=native_array ) - seq2arr = self.pre_call_tmpl.substitute( type=self.array_item_type - , pylist=w_arg.name - , array_size=self.array_size - , native_array=native_array ) + controller.add_pre_call_code( copy_pylist2arr ) - controller.add_pre_call_code( seq2arr ) - controller.modify_arg_expression( self.arg_index, native_array ) + def __configure_v_mem_fun_default( self, controller ): + self.__configure_sealed( controller ) + + def __configure_v_mem_fun_override( self, controller ): + global _arr2seq + pylist = controller.declare_py_variable( declarations.dummy_type_t( 'boost::python::list' ) + , 'py_' + self.arg.name ) + + copy_arr2pylist = _arr2seq.substitute( native_array=self.arg.name + , array_size=self.array_size + , pylist=pylist ) + + controller.add_py_pre_call_code( copy_arr2pylist ) + def configure_mem_fun( self, controller ): self.__configure_sealed( controller ) def configure_free_fun(self, controller ): self.__configure_sealed( controller ) + def configure_virtual_mem_fun( self, controller ): + self.__configure_v_mem_fun_override( controller.override_controller ) + self.__configure_v_mem_fun_default( controller.default_controller ) + + # output_array_t class output_array_t(transformer.transformer_t): """Handles an output array of a fixed size. @@ -293,11 +320,8 @@ """Returns list of header files that transformer generated code depends on.""" return [ code_repository.convenience.file_name ] - @property - def post_call_tmpl( self ): - return string.Template( 'pyplus_conv::copy_container( $native_array, $native_array + $array_size, pyplus_conv::list_inserter( $pylist ) );' ) - def __configure_sealed(self, controller): + global _arr2seq #removing arg from the function wrapper definition controller.remove_wrapper_arg( self.arg.name ) @@ -313,17 +337,41 @@ pylist = controller.declare_variable( declarations.dummy_type_t( "boost::python::list" ) , 'py_' + self.arg.name ) - arr2seq = self.post_call_tmpl.substitute( native_array=native_array - , array_size=self.array_size - , pylist=pylist ) + copy_arr2pylist = _arr2seq.substitute( native_array=native_array + , array_size=self.array_size + , pylist=pylist ) - controller.add_post_call_code( arr2seq ) + controller.add_post_call_code( copy_arr2pylist ) #adding the variable to return variables list controller.return_variable( pylist ) - + + def __configure_v_mem_fun_default( self, controller ): + self.__configure_sealed( controller ) + + def __configure_v_mem_fun_override( self, controller ): + global _seq2arr + seq = controller.declare_py_variable( declarations.dummy_type_t( 'boost::python::object' ) + , 'py_' + self.arg.name ) + controller.remove_py_arg( self.arg_index ) + tmpl = string.Template( '$seq = pyplus_conv::get_out_argument( $py_result, "$name" );' ) + get_ref_to_seq = tmpl.substitute( seq=seq + , py_result=controller.py_result_variable.name + , name=self.arg.name ) + controller.add_py_post_call_code( get_ref_to_seq ) + + copy_pylist2arr = _seq2arr.substitute( type=self.array_item_type + , pylist=seq + , array_size=self.array_size + , native_array=self.arg.name ) + controller.add_py_post_call_code( copy_pylist2arr ) + def configure_mem_fun( self, controller ): self.__configure_sealed( controller ) def configure_free_fun(self, controller ): self.__configure_sealed( controller ) + + def configure_virtual_mem_fun( self, controller ): + self.__configure_v_mem_fun_override( controller.override_controller ) + self.__configure_v_mem_fun_default( controller.default_controller ) 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 15:05:10 UTC (rev 764) +++ pyplusplus_dev_ft/unittests/data/function_transformations_to_be_exported.hpp 2006-11-29 20:10:52 UTC (rev 765) @@ -125,17 +125,17 @@ return in; } - //~ // A method taking an input array of fixed size - //~ virtual int fixed_input_array(int v[3]) { - //~ return v[0]+v[1]+v[2]; - //~ } + // A method taking an input array of fixed size + virtual int fixed_input_array(int v[3]) { + return v[0]+v[1]+v[2]; + } - //~ // A method with a output array of fixed size - //~ virtual void fixed_output_array(int v[3]) { - //~ v[0] = 1; - //~ v[1] = 2; - //~ v[2] = 3; - //~ } + // A method with a output array of fixed size + virtual void fixed_output_array(int v[3]) { + v[0] = 1; + v[1] = 2; + v[2] = 3; + } unsigned int m_width; unsigned int m_height; @@ -161,13 +161,13 @@ return v; } -//~ // This is used for calling img.fixed_output_array() on an instance passed -//~ // in by Python. -//~ int image_fixed_output_array( image_t& img) { - //~ int v[3]; - //~ img.fixed_output_array(v); - //~ return v[0]+v[1]+v[2]; -//~ } +// This is used for calling img.fixed_output_array() on an instance passed +// in by Python. +int image_fixed_output_array( image_t& img) { + int v[3]; + img.fixed_output_array(v); + return v[0]+v[1]+v[2]; +} ////////////////////////////////////////////////////////////////////// Modified: pyplusplus_dev_ft/unittests/function_transformations_tester.py =================================================================== --- pyplusplus_dev_ft/unittests/function_transformations_tester.py 2006-11-29 15:05:10 UTC (rev 764) +++ pyplusplus_dev_ft/unittests/function_transformations_tester.py 2006-11-29 20:10:52 UTC (rev 765) @@ -8,6 +8,7 @@ import math import unittest import fundamental_tester_base +from named_tuple import named_tuple from pyplusplus import function_transformers as ft from pyplusplus.module_builder import call_policies @@ -52,8 +53,8 @@ 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( "fixed_input_array" ).add_transformation( ft.input_array(0,3) ) - #~ image.member_function( "fixed_output_array" ).add_transformation( ft.output_array(0,3) ) + 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() @@ -114,12 +115,12 @@ # 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) - #~ self.assertEqual(img.fixed_input_array((1,2,3)), 6) + # Check the fixed_input_array method + self.assertEqual(img.fixed_input_array([1,2,3]), 6) + self.assertEqual(img.fixed_input_array((1,2,3)), 6) - #~ # Check the fixed_output_array method - #~ self.assertEqual(img.fixed_output_array(), [1,2,3]) + # 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) @@ -134,16 +135,16 @@ def get_one_value(self): return self.m_height+1 - #~ def fixed_output_array(self): - #~ # Produce a correct return value - #~ if self.fixed_output_array_mode==0: - #~ return (2,5,7) - #~ # Produce the wrong type - #~ elif self.fixed_output_array_mode==1: - #~ return 5 - #~ # Produce a sequence with the wrong number of items - #~ elif self.fixed_output_array_mode==2: - #~ return (2,5) + def fixed_output_array(self): + # Produce a correct return value + if self.fixed_output_array_mode==0: + return named_tuple( v=(2,5,7) ) + # Produce the wrong type + elif self.fixed_output_array_mode==1: + return 5 + # Produce a sequence with the wrong number of items + elif self.fixed_output_array_mode==2: + return named_tuple( v=(2,5) ) pyimg1 = py_image1_t(3,7) @@ -156,12 +157,12 @@ # 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) - #~ pyimg1.fixed_output_array_mode = 1 - #~ self.assertRaises(TypeError, lambda : module.image_fixed_output_array(pyimg1)) - #~ pyimg1.fixed_output_array_mode = 2 - #~ self.assertRaises(ValueError, lambda : module.image_fixed_output_array(pyimg1)) + # Check if fixed_output_array() is correctly called from C++ + self.assertEqual(module.image_fixed_output_array(pyimg1), 14) + pyimg1.fixed_output_array_mode = 1 + self.assertRaises(TypeError, lambda : module.image_fixed_output_array(pyimg1)) + 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): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |