def _create_impl(self): if self.declaration.already_exposed: return "" bpl_enum = '%(bpl::enum_)s< %(name)s>("%(alias)s")' % { "bpl::enum_": algorithm.create_identifier(self, "::boost::python::enum_"), "name": algorithm.create_identifier(self, self.declaration.decl_string), "alias": self.alias, } values = [] # Add the values that should be exported for value_name in self.declaration.export_values: values.append(self._generate_value_code(value_name)) # Export the values if len(self.declaration.export_values) > 0: values.append(".export_values()") # Add the values that should not be exported for name in self.declaration.no_export_values: values.append(self._generate_value_code(name)) values.append(";") values = self.indent(os.linesep.join(values)) return bpl_enum + os.linesep + values
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 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.type.decl_string] ) , [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 ) ) if stmt: stmt = 'return ' + stmt + ';' self.__return_stmt = stmt return self.__return_stmt
def create( self, creator): """ Return string of type to use for held type. Ex: boost::shared_ptr<Class> """ smart_ptr = algorithm.create_identifier( creator, self.smart_ptr ) arg = algorithm.create_identifier( creator, creator.declaration.decl_string ) return templates.join( smart_ptr, [ arg ] )
def _create_impl(self): if self.declaration.already_exposed: return '' bpl_enum = '%(bpl::enum_)s< %(name)s>("%(alias)s")' \ % { 'bpl::enum_' : algorithm.create_identifier( self, '::boost::python::enum_' ) , 'name' : algorithm.create_identifier( self, self.declaration.decl_string ) , 'alias' : self.alias } values = [] # Add the values that should be exported for value_name in self.declaration.export_values: values.append( self._generate_value_code( value_name ) ) # Export the values if len(self.declaration.export_values)>0: values.append( '.export_values()' ) # Add the values that should not be exported for name in self.declaration.no_export_values: values.append( self._generate_value_code( name ) ) values.append( ';' ) values = self.indent( os.linesep.join( values ) ) return bpl_enum + os.linesep + values
def _generate_constructor(self): result = [] result.append( '(' ) result.append( ' "%s"' % self.alias ) if self.documentation: result.append( ', %s' % self.documentation ) used_init = None inits = filter( lambda x: isinstance( x, calldef.constructor_t ), self.creators ) if ( self.declaration.is_abstract \ or not declarations.has_any_non_copyconstructor(self.declaration) ) \ and not self.wrapper \ or ( declarations.has_destructor( self.declaration ) and not declarations.has_public_destructor( self.declaration ) ): #TODO: or self.declaration has public constructor and destructor result.append( ", " ) result.append( algorithm.create_identifier( self, '::boost::python::no_init' ) ) elif not declarations.has_trivial_constructor( self.declaration ): if inits: used_init = inits[0] result.append( ", " ) result.append( used_init.create_init_code() ) elif self.declaration.indexing_suite: pass #in this case all constructors are exposed by indexing suite else:#it is possible to class to have public accessed constructor #that could not be exported by boost.python library #for example constructor takes as argument pointer to function result.append( ", " ) result.append( algorithm.create_identifier( self, '::boost::python::no_init' ) ) else: pass result.append( ' )' ) return ( ''.join( result ), used_init )
def create_default(self): cntrl = self.controller.default_controller 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 tmpl_values['wrapped_inst_constness'] = '' if declarations.is_const( declarations.remove_reference(cntrl.inst_arg.type)): tmpl_values['wrapped_inst_constness'] = 'const' 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_tmp = '%(result_var_name)s = ' if declarations.is_reference(self.declaration.return_type): tmpl_tmp = tmpl_tmp + '&' tmpl_values['save_result'] = tmpl_tmp % dict( result_var_name=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 _create_impl(self): if self.declaration.already_exposed: return '' tmpl = algorithm.create_identifier( self, '::boost::python::scope' ) + '().attr("%s") = (int)%s;' full_name = pygccxml.declarations.full_name( self.declaration ) result = [] for name, value in self.declaration.values: result.append( tmpl % ( self.value_aliases.get( name, name ) , algorithm.create_identifier( self, full_name + '::' + name ) ) ) return os.linesep.join( result )
def create_fun_definition(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') tmpl_values = dict() tmpl_values['unique_function_name'] = self.wrapper_name() tmpl_values[ 'return_type'] = self.controller.wrapper_return_type.decl_string tmpl_values['arg_declarations'] = self.args_declaration() tmpl_values['declare_variables'] \ = os.linesep + os.linesep.join( map( lambda var: self.indent( var.declare_var_string() ) , cntrl.variables ) ) 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_tmp = '%(type)s %(name)s = ' if declarations.is_reference(self.declaration.return_type): tmpl_tmp = tmpl_tmp + '&' tmpl_values['save_result'] = tmpl_tmp \ % { 'type': cntrl.result_variable.type.decl_string , 'name' : cntrl.result_variable.name } tmpl_values['function_name'] = self.resolve_function_ref() tmpl_values['arg_expressions'] = self.PARAM_SEPARATOR.join( cntrl.arg_expressions) return_stmt_creator = calldef_utils.return_stmt_creator_t( self, self.controller, self.controller.result_variable, self.controller.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 = self.controller.template.substitute(tmpl_values) return remove_duplicate_linesep(f_def)
def create_default(self): cntrl = self.controller.default_controller 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 tmpl_values['wrapped_inst_constness'] = '' if declarations.is_const( declarations.remove_reference( cntrl.inst_arg.type ) ): tmpl_values['wrapped_inst_constness'] = 'const' 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_tmp = '%(result_var_name)s = ' if declarations.is_reference( self.declaration.return_type ): tmpl_tmp = tmpl_tmp + '&' tmpl_values['save_result'] = tmpl_tmp % dict( result_var_name=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 _create_impl(self): if self.declaration.already_exposed: return '' tmpl = algorithm.create_identifier( self, '::boost::python::scope') + '().attr("%s") = (int)%s;' full_name = pygccxml.declarations.full_name(self.declaration) result = [] for name, value in self.declaration.values: result.append( tmpl % (self.value_aliases.get(name, name), algorithm.create_identifier(self, full_name + '::' + name))) return os.linesep.join(result)
def _generate_bases(self, base_creators): bases = [] assert isinstance( self.declaration, declarations.class_t ) for base_desc in self.declaration.bases: assert isinstance( base_desc, declarations.hierarchy_info_t ) if base_desc.access != declarations.ACCESS_TYPES.PUBLIC: continue if base_creators.has_key( id(base_desc.related_class) ): bases.append( algorithm.create_identifier( self, base_desc.related_class.partial_decl_string ) ) elif base_desc.related_class.already_exposed: bases.append( base_desc.related_class.partial_decl_string ) if not bases: return None bases_identifier = algorithm.create_identifier( self, '::boost::python::bases' ) return declarations.templates.join( bases_identifier, bases )
def _create_impl( self ): make_constructor = algorithm.create_identifier( self, 'boost::python::make_constructor' ) code = 'def( "__init__, %s( &::%s ) )' % self.wrapper.wrapper_name() if not self.works_on_instance: code = self.parent.class_var_name + '.' + code + ';' return code
def _generate_class_definition(self, base_creators): class_identifier = algorithm.create_identifier( self, '::boost::python::class_') args = [] held_type = self._generated_held_type() if self.wrapper: if self.declaration.exposed_class_type == self.declaration.EXPOSED_CLASS_TYPE.WRAPPER: args.append(self.wrapper.full_name) else: if not self.target_configuration.boost_python_has_wrapper_held_type \ or self.declaration.require_self_reference: args.append(self.decl_identifier) if self.declaration.require_self_reference: if not held_type: args.append(self.wrapper.full_name) else: args.append(self.wrapper.full_name) else: args.append(self.decl_identifier) bases = self._generate_bases(base_creators) if bases: args.append(bases) if held_type: args.append(held_type) notcopyable = self._generate_noncopyable() if notcopyable: args.append(notcopyable) return declarations.templates.join(class_identifier, args)
def _generate_code_with_scope(self): result = [] scope_var_name = self.alias + '_scope' result.append('typedef ' + self._generate_class_definition() + ' ' + self.typedef_name + ';') result.append(self.typedef_name + ' ' + self.class_var_name) result[-1] = result[ -1] + ' = ' + self.typedef_name + '("%s");' % self.declaration.alias result.append( algorithm.create_identifier(self, '::boost::python::scope')) result[-1] = result[-1] + ' ' + scope_var_name result[-1] = result[-1] + '( %s );' % self.class_var_name for x in self.creators: if not x.works_on_instance: result.append(x.create()) else: result.append('%s.%s;' % (self.class_var_name, x.create())) code = os.linesep.join(result) result = ['{ //scope begin'] result.append(self.indent(code)) result.append('} //scope end') return os.linesep.join(result)
def _get_args(self, function_creator): if function_creator: rcg = algorithm.create_identifier(function_creator, self.result_converter_generator) return [rcg] else: return [self.result_converter_generator]
def _generate_value_code(self, value_name): # in C++ you can't write namespace::enum::value, you should write namespace::value full_name = self.declaration.parent.decl_string return '.value("%(alias)s", %(name)s)' % { "alias": self.value_aliases.get(value_name, value_name), "name": algorithm.create_identifier(self, full_name + "::" + value_name), }
def _create_impl( self ): answer = [ 'add_property' ] answer.append( '( ' ) answer.append('"%s"' % self.alias) answer.append( self.PARAM_SEPARATOR ) make_function = algorithm.create_identifier( self, '::boost::python::make_function' ) answer.append( '%(mk_func)s( (%(getter_type)s)(&%(wfname)s) )' % { 'mk_func' : make_function , 'getter_type' : self.wrapper.getter_type , 'wfname' : self.wrapper.getter_full_name } ) if self.wrapper.has_setter: answer.append( self.PARAM_SEPARATOR ) answer.append( '%(mk_func)s( (%(setter_type)s)(&%(wfname)s) )' % { 'mk_func' : make_function , 'setter_type' : self.wrapper.setter_type , 'wfname' : self.wrapper.setter_full_name } ) if self.documentation: answer.append( self.PARAM_SEPARATOR ) answer.append( self.documentation ) answer.append( ' ) ' ) code = ''.join( answer ) if len( code ) <= self.LINE_LENGTH: return code else: for i in range( len( answer ) ): if answer[i] == self.PARAM_SEPARATOR: answer[i] = os.linesep + self.indent( self.indent( self.indent( answer[i] ) ) ) return ''.join( answer )
def _create_impl(self, function_creator): name = algorithm.create_identifier( function_creator, '::pyplusplus::call_policies::return_range') args = [self.get_size_class, self.value_type.decl_string] if not self.value_policies.is_default(): args.append(self.value_policies.create_type()) return declarations.templates.join(name, args)
def _create_impl( self ): if self.declaration.already_exposed: return '' answer = [] if self.does_user_disable_methods(): answer.append( self.generate_algorithm_mask() ) answer.append( os.linesep ) if not self.works_on_instance: answer.append( '%s.def( ' % self.parent.class_var_name) else: answer.append( 'def( ' ) bpi = algorithm.create_identifier(self, "::boost::python::indexing" ) if self.declaration.indexing_suite.use_container_suite: answer.append( bpi + '::container_suite' ) else: answer.append( bpi + '::' + self.declaration.name.split( '<' )[0] + '_suite' ) answer.append( '< ' ) answer.append( self.decl_identifier ) if self.does_user_disable_methods(): answer.append( self.PARAM_SEPARATOR ) answer.append( self.__method_mask_var_name ) answer.append( ' >' ) if self.declaration.indexing_suite.call_policies \ and not self.declaration.indexing_suite.call_policies.is_default(): answer.append( '::with_policies(%s)' % self.declaration.indexing_suite.call_policies.create( self ) ) else: answer.append( '()' ) answer.append( ' )' ) if not self.works_on_instance: answer.append( ';' ) return ''.join( answer )
def _create_impl(self): if self.declaration.already_exposed: return "" answer = [] if self.does_user_disable_methods(): answer.append(self.generate_algorithm_mask()) answer.append(os.linesep) if not self.works_on_instance: answer.append("%s.def( " % self.parent.class_var_name) else: answer.append("def( ") bpi = algorithm.create_identifier(self, "::boost::python::indexing") if self.declaration.indexing_suite.use_container_suite: answer.append(bpi + "::container_suite") else: answer.append(bpi + "::" + self.declaration.name.split("<")[0] + "_suite") answer.append("< ") answer.append(self.decl_identifier) if self.does_user_disable_methods(): answer.append(self.PARAM_SEPARATOR) answer.append(self.__method_mask_var_name) answer.append(" >") if ( self.declaration.indexing_suite.call_policies and not self.declaration.indexing_suite.call_policies.is_default() ): answer.append("::with_policies(%s)" % self.declaration.indexing_suite.call_policies.create(self)) else: answer.append("()") answer.append(" )") if not self.works_on_instance: answer.append(";") return "".join(answer)
def _generate_noncopyable(self): noncopyable_vars = self.declaration.find_noncopyable_vars() copy_constr = self.declaration.find_copy_constructor() if self.declaration.noncopyable \ or copy_constr and copy_constr.is_artificial and noncopyable_vars: return algorithm.create_identifier( self, '::boost::noncopyable' )
def _create_impl(self): if self.declaration.already_exposed: return '' answer = [] if self.does_user_disable_methods(): answer.append(self.generate_algorithm_mask()) answer.append(os.linesep) if not self.works_on_instance: answer.append('%s.def( ' % self.parent.class_var_name) else: answer.append('def( ') bpi = algorithm.create_identifier(self, "::boost::python::indexing") if self.declaration.indexing_suite.use_container_suite: answer.append(bpi + '::container_suite') else: answer.append(bpi + '::' + self.declaration.name.split('<')[0] + '_suite') answer.append('< ') answer.append(self.decl_identifier) if self.does_user_disable_methods(): answer.append(self.PARAM_SEPARATOR) answer.append(self.__method_mask_var_name) answer.append(' >') if self.declaration.indexing_suite.call_policies \ and not self.declaration.indexing_suite.call_policies.is_default(): answer.append( '::with_policies(%s)' % self.declaration.indexing_suite.call_policies.create(self)) else: answer.append('()') answer.append(' )') if not self.works_on_instance: answer.append(';') return ''.join(answer)
def _create_body( self ): answer = [] answer.append( 'typedef %s;' % self.wrapper.wrapper_creator_type.create_typedef( 'array_wrapper_creator' ) ) answer.append( os.linesep * 2 ) doc = '' if self.declaration.type_qualifiers.has_static: answer.append( self.parent.class_var_name + '.add_static_property' ) else: if self.documentation: doc = self.documentation answer.append( self.parent.class_var_name + '.add_property' ) answer.append( '( ' ) answer.append('"%s"' % self.declaration.name ) answer.append( os.linesep + self.indent( self.PARAM_SEPARATOR ) ) temp = [ algorithm.create_identifier( self, "::boost::python::make_function" ) ] temp.append( '( ' ) temp.append( 'array_wrapper_creator(&%s)' % self.wrapper.wrapper_creator_full_name ) if not self.declaration.type_qualifiers.has_static: temp.append( os.linesep + self.indent( self.PARAM_SEPARATOR, 6 ) ) temp.append( call_policies.with_custodian_and_ward_postcall( 0, 1 ).create(self) ) temp.append( ' )' ) answer.append( ''.join( temp ) ) if doc: answer.append( os.linesep ) answer.append( self.PARAM_SEPARATOR ) answer.append( doc ) answer.append( ' );' ) return ''.join( answer )
def _generate_class_definition(self, base_creators): class_identifier = algorithm.create_identifier( self, '::boost::python::class_' ) args = [] held_type = self._generated_held_type() if self.wrapper: if self.declaration.exposed_class_type == self.declaration.EXPOSED_CLASS_TYPE.WRAPPER: args.append( self.wrapper.full_name ) else: if not self.target_configuration.boost_python_has_wrapper_held_type \ or self.declaration.require_self_reference: args.append( self.decl_identifier ) if self.declaration.require_self_reference: if not held_type: args.append( self.wrapper.full_name ) else: args.append( self.wrapper.full_name ) else: args.append( self.decl_identifier ) bases = self._generate_bases(base_creators) if bases: args.append( bases ) if held_type: args.append( held_type ) notcopyable = self._generate_noncopyable() if notcopyable: args.append( notcopyable ) return declarations.templates.join( class_identifier, args)
def _create_impl(self): if self.declaration.already_exposed: return '' return '%(register_exception_translator)s< %(cls)s >( &%(translator)s );' \ % { 'register_exception_translator' : algorithm.create_identifier( self, 'boost::python::register_exception_translator' ) , 'cls' : self.decl_identifier , 'translator' : self.translator.translator_name }
def _create_impl( self ): if self.declaration.already_exposed: return '' return '%(register_exception_translator)s< %(cls)s >( &%(translator)s );' \ % { 'register_exception_translator' : algorithm.create_identifier( self, 'boost::python::register_exception_translator' ) , 'cls' : self.decl_identifier , 'translator' : self.translator.translator_name }
def _create_impl(self): if self.declaration.already_exposed: return '' assert isinstance( self.declaration, pygccxml.declarations.variable_t ) result = [] result.append( algorithm.create_identifier( self, '::boost::python::scope' ) ) result.append( '().attr("%s")' % self.alias ) dtype = self.declaration.type if decl_wrappers.python_traits.is_immutable( dtype ) \ or pygccxml.declarations.is_const( dtype ) \ or pygccxml.declarations.smart_pointer_traits.is_smart_pointer( dtype ): result.append( ' = %s;' % self.decl_identifier ) else: obj_identifier = algorithm.create_identifier( self, '::boost::python::object' ) ref_identifier = algorithm.create_identifier( self, '::boost::ref' ) result.append( ' = %s( %s( %s ) );' % ( obj_identifier, ref_identifier, self.decl_identifier ) ) return ''.join( result )
def _create_impl(self, function_creator): args = self._get_args(function_creator) if not self._base.is_default(): args.append( self._base.create(function_creator, CREATION_POLICY.AS_TEMPLATE_ARGUMENT)) name = algorithm.create_identifier(function_creator, self._get_name(function_creator)) return declarations.templates.join(name, args)
def _get_args(self, function_creator): as_tuple_args = [ str( self.array_size ) ] as_tuple_args.append( memory_managers.create( self.memory_manager, function_creator ) ) if not self.make_objec_call_policies.is_default(): as_tuple_args.append( self.make_objec_call_policies.create_template_arg( function_creator ) ) as_tuple = '::pyplusplus::call_policies::arrays::as_tuple' if function_creator: as_tuple = algorithm.create_identifier( function_creator, as_tuple ) return [ declarations.templates.join( as_tuple, as_tuple_args ) ]
def create_fun_definition(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' ) tmpl_values = dict() tmpl_values['unique_function_name'] = self.wrapper_name() tmpl_values['return_type'] = self.controller.wrapper_return_type.decl_string tmpl_values['arg_declarations'] = self.args_declaration() tmpl_values['declare_variables'] \ = os.linesep + os.linesep.join( map( lambda var: self.indent( var.declare_var_string() ) , cntrl.variables ) ) 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_tmp = '%(type)s %(name)s = ' if declarations.is_reference( self.declaration.return_type ): tmpl_tmp = tmpl_tmp + '&' tmpl_values['save_result'] = tmpl_tmp \ % { 'type': cntrl.result_variable.type.decl_string , 'name' : cntrl.result_variable.name } tmpl_values['function_name'] = self.resolve_function_ref() tmpl_values['arg_expressions'] = self.PARAM_SEPARATOR.join( cntrl.arg_expressions ) return_stmt_creator = calldef_utils.return_stmt_creator_t( self , self.controller , self.controller.result_variable , self.controller.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 = self.controller.template.substitute(tmpl_values) return remove_duplicate_linesep( f_def )
def generate_algorithm_mask( self ): disable = [] for group in self.declaration.indexing_suite.disabled_methods_groups: group_id = algorithm.create_identifier(self, "::boost::python::indexing::%s_methods" % group ) disable.append( group_id ) for method in self.declaration.indexing_suite.disable_methods: method_id = algorithm.create_identifier(self, "::boost::python::indexing::method_" + method ) disable.append( method_id ) answer = [ 'unsigned long const %s = ' % self.__method_mask_var_name ] answer.append( algorithm.create_identifier(self, "::boost::python::indexing::all_methods" ) ) answer.append( ' & ~' ) if 1 == len ( disable ): answer.append( disable[0] ) else: answer.append( '( ' ) answer.append( ' | '.join( disable ) ) answer.append( ' ) ' ) answer.append( ';' ) return ''.join( answer )
def _generate_for_pointer(self): doc = '' #static property does not support documentation if self.declaration.type_qualifiers.has_static: add_property = 'add_static_property' else: if self.documentation: doc = self.documentation add_property = 'add_property' answer = [add_property] answer.append('( ') answer.append('"%s"' % self.alias) answer.append(self.PARAM_SEPARATOR) #according to David Abrahams: #http://mail.python.org/pipermail/c++-sig/2003-January/003276.html call_pol = call_policies.return_internal_reference().create(self) make_function = algorithm.create_identifier( self, '::boost::python::make_function') answer.append( '%(mk_func)s( (%(getter_type)s)(&%(wfname)s), %(call_pol)s )' % { 'mk_func': make_function, 'getter_type': self.wrapper.getter_type, 'wfname': self.wrapper.getter_full_name, 'call_pol': call_pol }) #don't generate setter method, right now I don't know how to do it. if self.wrapper.has_setter: answer.append(self.PARAM_SEPARATOR) call_pol = '' if not self.declaration.type_qualifiers.has_static: call_pol = ", " + call_policies.with_custodian_and_ward_postcall( 1, 2).create(self) answer.append( '%(mk_func)s( (%(setter_type)s)(&%(wfname)s)%(call_pol)s )' % { 'mk_func': make_function, 'setter_type': self.wrapper.setter_type, 'wfname': self.wrapper.setter_full_name, 'call_pol': call_pol }) if doc: answer.append(self.PARAM_SEPARATOR) answer.append(doc) answer.append(' ) ') code = ''.join(answer) if len(code) <= self.LINE_LENGTH: return code else: for i in range(len(answer)): if answer[i] == self.PARAM_SEPARATOR: answer[i] = os.linesep + self.indent( self.indent(self.indent(answer[i]))) return ''.join(answer)
def _create_impl( self ): if self.declaration.already_exposed: return '' answer = [] answer.append( algorithm.create_identifier( self, '::boost::python::scope' ) ) answer.append( '().attr("%s")' % self.alias ) answer.append( ' = ' ) answer.append( self.wrapper.wrapper_creator_full_name ) answer.append( '();' ) return ''.join( answer )
def _create_impl(self): if self.declaration.already_exposed: return '' assert isinstance( self.declaration, pygccxml.declarations.variable_t ) result = [] #TODO: porting to 64Bit is welcome result.append( algorithm.create_identifier( self, '::boost::python::scope' ) ) result.append( '().attr("%s")' % self.alias ) result.append( ' = size_t( boost::addressof( %s ) );' % self.decl_identifier ) return ''.join( result )
def _create_impl(self): answer = [] cls_type = algorithm.create_identifier( self, self.declaration.parent.decl_string ) substitutions = dict( type=self._get_exported_var_type().decl_string , class_type=cls_type , name=self.declaration.name ) answer.append( self.GET_TEMPLATE % substitutions ) if self.has_setter: answer.append( self.SET_TEMPLATE % substitutions ) return os.linesep.join( answer )
def _get_args(self, function_creator): as_tuple_args = [str(self.array_size)] as_tuple_args.append( memory_managers.create(self.memory_manager, function_creator)) if not self.make_objec_call_policies.is_default(): as_tuple_args.append( self.make_objec_call_policies.create_template_arg( function_creator)) as_tuple = '::pyplusplus::call_policies::arrays::as_tuple' if function_creator: as_tuple = algorithm.create_identifier(function_creator, as_tuple) return [declarations.templates.join(as_tuple, as_tuple_args)]
def _create_impl(self): if self.declaration.already_exposed: return '' if self.class_creator \ and self.class_creator.held_type \ and isinstance( self.class_creator.held_type, held_type_t ) \ and self.class_creator.held_type.smart_ptr == self.smart_ptr \ and self.target_configuration.boost_python_has_wrapper_held_type \ and not self.class_creator.declaration.require_self_reference: return '' #boost.python does it automaticly rptp = algorithm.create_identifier( self, '::boost::python::register_ptr_to_python' ) held_type = held_type_t(self.smart_ptr).create( self ) return templates.join( rptp, [ held_type ] ) + '();'
def _create_suite_declaration( self ): suite_identifier = algorithm.create_identifier( self, self.guess_suite_name() ) args = [ self.container.partial_decl_string ] try: no_proxy = str( self.configuration.no_proxy ).lower() except: no_proxy = 'false' if self.configuration.derived_policies: args.append( no_proxy ) args.append( self.configuration.derived_policies ) else: if 'true' == no_proxy: args.append( no_proxy) return declarations.templates.join( suite_identifier, args )
def generate_algorithm_mask(self): disable = [] for group in self.declaration.indexing_suite.disabled_methods_groups: group_id = algorithm.create_identifier( self, "::boost::python::indexing::%s_methods" % group) disable.append(group_id) for method in self.declaration.indexing_suite.disable_methods: method_id = algorithm.create_identifier( self, "::boost::python::indexing::method_" + method) disable.append(method_id) answer = ['unsigned long const %s = ' % self.__method_mask_var_name] answer.append( algorithm.create_identifier( self, "::boost::python::indexing::all_methods")) answer.append(' & ~') if 1 == len(disable): answer.append(disable[0]) else: answer.append('( ') answer.append(' | '.join(disable)) answer.append(' ) ') answer.append(';') return ''.join(answer)
def create_class_typedef_on_demand( self, f, prefix='' ): if None is f: return ( None, None ) if not isinstance( f.parent, declarations.class_t ): return ( None, None ) if not declarations.templates.is_instantiation( f.parent.decl_string ): return ( None, None ) cls_name = None cls_identifier = algorithm.create_identifier( self, f.parent.decl_string ) if prefix: cls_name = prefix + 'class_t' else: cls_name = 'exported_class_t' return ( 'typedef %s %s;' % ( cls_identifier, cls_name ), cls_name )
def _generate_using_functions(self): doc = '' add_property = '' make_getter = algorithm.create_identifier( self, '::boost::python::make_getter') make_setter = algorithm.create_identifier( self, '::boost::python::make_setter') if self.declaration.type_qualifiers.has_static: add_property = 'add_static_property' else: if self.documentation: doc = self.documentation add_property = 'add_property' add_property_args = ['"%s"' % self.alias] getter_code = declarations.call_invocation.join( make_getter, [ '&' + self.decl_identifier, self.declaration.getter_call_policies.create(self) ], os.linesep + self.indent(self.PARAM_SEPARATOR, 6)) add_property_args.append(getter_code) if not self.declaration.is_read_only: setter_code = '' setter_args = ['&' + self.decl_identifier] if self.declaration.setter_call_policies \ and not self.declaration.setter_call_policies.is_default(): setter_args.append( self.declaration.setter_call_policies.create(self)) setter_code = declarations.call_invocation.join( make_setter, setter_args, os.linesep + self.indent(self.PARAM_SEPARATOR, 6)) add_property_args.append(setter_code) if doc: add_property_args.append(doc) return declarations.call_invocation.join( add_property, add_property_args, os.linesep + self.indent(self.PARAM_SEPARATOR, 4))
def _generate_code_with_scope(self): result = [] scope_var_name = self.alias + '_scope' base_classes, base_creators = self._exported_base_classes() result.append('typedef ' + self._generate_class_definition(base_creators) + ' ' + self.typedef_name + ';') result.append(self.typedef_name + ' ' + self.class_var_name) result[-1] = result[-1] + ' = ' class_constructor, used_init = self._generate_constructor() result[-1] = result[-1] + self.typedef_name + class_constructor result[-1] = result[-1] + ';' result.append( algorithm.create_identifier(self, '::boost::python::scope')) result[-1] = result[-1] + ' ' + scope_var_name result[-1] = result[-1] + '( %s );' % self.class_var_name creators = self.creators if self.declaration.redefine_operators: creators = self.creators + self._get_base_operators( base_classes, base_creators) for x in creators: if x is used_init: continue if isinstance(x, (calldef.calldef_t, calldef.calldef_overloads_t)): x.works_on_instance = False code = x.create() if code: result.append(code) continue if not x.works_on_instance: code = x.create() if code: result.append(code) else: result.append('%s.%s;' % (self.class_var_name, x.create())) code = os.linesep.join(result) result = [ '{ //%s' % declarations.full_name(self.declaration, with_defaults=False) ] result.append(self.indent(code)) result.append('}') return os.linesep.join(result)
def create_class_typedef_on_demand(self, f, prefix=''): if None is f: return (None, None) if not isinstance(f.parent, declarations.class_t): return (None, None) if not declarations.templates.is_instantiation(f.parent.decl_string): return (None, None) cls_name = None cls_identifier = algorithm.create_identifier(self, f.parent.decl_string) if prefix: cls_name = prefix + 'class_t' else: cls_name = 'exported_class_t' return ('typedef %s %s;' % (cls_identifier, cls_name), cls_name)
def _generate_constructor(self): result = [] result.append('(') result.append(' "%s"' % self.alias) if self.documentation: result.append(', %s' % self.documentation) used_init = None inits = filter(lambda x: isinstance(x, calldef.constructor_t), self.creators) if ( self.declaration.is_abstract \ or not declarations.has_any_non_copyconstructor(self.declaration) ) \ and not self.wrapper \ or ( declarations.has_destructor( self.declaration ) and not declarations.has_public_destructor( self.declaration ) ): #TODO: or self.declaration has public constructor and destructor result.append(", ") result.append( algorithm.create_identifier(self, '::boost::python::no_init')) elif not declarations.has_trivial_constructor(self.declaration): if inits: used_init = inits[0] result.append(", ") result.append(used_init.create_init_code()) elif self.declaration.indexing_suite: pass #in this case all constructors are exposed by indexing suite else: #it is possible to class to have public accessed constructor #that could not be exported by boost.python library #for example constructor takes as argument pointer to function result.append(", ") result.append( algorithm.create_identifier(self, '::boost::python::no_init')) else: pass result.append(' )') return (''.join(result), used_init)
def _generate_using_functions( self ): doc = '' add_property = '' make_getter = algorithm.create_identifier( self, '::boost::python::make_getter') make_setter = algorithm.create_identifier( self, '::boost::python::make_setter') if self.declaration.type_qualifiers.has_static: add_property = 'add_static_property' else: if self.documentation: doc = self.documentation add_property = 'add_property' add_property_args = [ '"%s"' % self.alias ] getter_code = declarations.call_invocation.join( make_getter , [ '&' + self.decl_identifier , self.declaration.getter_call_policies.create( self ) ] , os.linesep + self.indent( self.PARAM_SEPARATOR, 6) ) add_property_args.append( getter_code ) if not self.declaration.is_read_only: setter_code = '' setter_args = [ '&' + self.decl_identifier ] if self.declaration.setter_call_policies \ and not self.declaration.setter_call_policies.is_default(): setter_args.append( self.declaration.setter_call_policies.create( self ) ) setter_code = declarations.call_invocation.join( make_setter , setter_args , os.linesep + self.indent( self.PARAM_SEPARATOR, 6) ) add_property_args.append( setter_code) if doc: add_property_args.append( doc ) return declarations.call_invocation.join( add_property , add_property_args , os.linesep + self.indent( self.PARAM_SEPARATOR, 4 ) )
def _generate_for_pointer( self ): doc = '' #static property does not support documentation if self.declaration.type_qualifiers.has_static: add_property = 'add_static_property' else: if self.documentation: doc = self.documentation add_property = 'add_property' answer = [ add_property ] answer.append( '( ' ) answer.append('"%s"' % self.alias) answer.append( self.PARAM_SEPARATOR ) #according to David Abrahams: #http://mail.python.org/pipermail/c++-sig/2003-January/003276.html call_pol = call_policies.return_internal_reference().create( self ) make_function = algorithm.create_identifier( self, '::boost::python::make_function' ) answer.append( '%(mk_func)s( (%(getter_type)s)(&%(wfname)s), %(call_pol)s )' % { 'mk_func' : make_function , 'getter_type' : self.wrapper.getter_type , 'wfname' : self.wrapper.getter_full_name , 'call_pol' : call_pol } ) #don't generate setter method, right now I don't know how to do it. if self.wrapper.has_setter: answer.append( self.PARAM_SEPARATOR ) call_pol = '' if not self.declaration.type_qualifiers.has_static: call_pol = ", " + call_policies.with_custodian_and_ward_postcall( 1, 2 ).create(self) answer.append( '%(mk_func)s( (%(setter_type)s)(&%(wfname)s)%(call_pol)s )' % { 'mk_func' : make_function , 'setter_type' : self.wrapper.setter_type , 'wfname' : self.wrapper.setter_full_name , 'call_pol' : call_pol } ) if doc: answer.append( self.PARAM_SEPARATOR ) answer.append( doc ) answer.append( ' ) ' ) code = ''.join( answer ) if len( code ) <= self.LINE_LENGTH: return code else: for i in range( len( answer ) ): if answer[i] == self.PARAM_SEPARATOR: answer[i] = os.linesep + self.indent( self.indent( self.indent( answer[i] ) ) ) return ''.join( answer )
def _generate_code_with_scope(self): result = [] scope_var_name = self.alias + '_scope' base_classes, base_creators = self._exported_base_classes() result.append( 'typedef ' + self._generate_class_definition(base_creators) + ' ' + self.typedef_name + ';') result.append( self.typedef_name + ' ' + self.class_var_name ) result[-1] = result[-1] + ' = ' class_constructor, used_init = self._generate_constructor() result[-1] = result[-1] + self.typedef_name + class_constructor result[-1] = result[-1] + ';' result.append( algorithm.create_identifier( self, '::boost::python::scope' ) ) result[-1] = result[-1] + ' ' + scope_var_name result[-1] = result[-1] + '( %s );' % self.class_var_name creators = self.creators if self.declaration.redefine_operators: creators = self.creators + self._get_base_operators(base_classes, base_creators) for x in creators: if x is used_init: continue if isinstance( x, ( calldef.calldef_t, calldef.calldef_overloads_t ) ): x.works_on_instance = False code = x.create() if code: result.append( code ) continue if not x.works_on_instance: code = x.create() if code: result.append( code ) else: result.append( '%s.%s;' % ( self.class_var_name, x.create() ) ) code = os.linesep.join( result ) result = [ '{ //%s' % declarations.full_name( self.declaration, with_defaults=False ) ] result.append( self.indent( code ) ) result.append( '}' ) return os.linesep.join( result )