[pygccxml-commit] SF.net SVN: pygccxml:[1392] pyplusplus_dev
Brought to you by:
mbaas,
roman_yakovenko
From: <rom...@us...> - 2008-08-13 19:45:24
|
Revision: 1392 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1392&view=rev Author: roman_yakovenko Date: 2008-08-13 19:45:24 +0000 (Wed, 13 Aug 2008) Log Message: ----------- adding make_constructor functionality Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/__init__.py pyplusplus_dev/pyplusplus/code_creators/calldef.py pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py pyplusplus_dev/pyplusplus/module_creator/creator.py pyplusplus_dev/unittests/test_all.py Added Paths: ----------- pyplusplus_dev/unittests/cp_return_addressof_tester.py pyplusplus_dev/unittests/data/cp_return_addressof_to_be_exported.hpp pyplusplus_dev/unittests/data/make_constructor_to_be_exported.hpp pyplusplus_dev/unittests/make_constructor_tester.py Property Changed: ---------------- pyplusplus_dev/unittests/data/ Modified: pyplusplus_dev/pyplusplus/code_creators/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/__init__.py 2008-08-12 04:30:53 UTC (rev 1391) +++ pyplusplus_dev/pyplusplus/code_creators/__init__.py 2008-08-13 19:45:24 UTC (rev 1392) @@ -44,6 +44,7 @@ from calldef import free_function_t from calldef import mem_fun_t +from calldef import make_constructor_t from calldef import mem_fun_pv_t from calldef import mem_fun_pv_wrapper_t Modified: pyplusplus_dev/pyplusplus/code_creators/calldef.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/calldef.py 2008-08-12 04:30:53 UTC (rev 1391) +++ pyplusplus_dev/pyplusplus/code_creators/calldef.py 2008-08-13 19:45:24 UTC (rev 1392) @@ -51,10 +51,12 @@ 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(): + def create_call_policies( self, default_generates_code_too=False ): + if False == default_generates_code_too \ + and self.declaration.call_policies.is_default(): return '' - return self.declaration.call_policies.create( self ) + else: + return self.declaration.call_policies.create( self ) def create_def_code( self ): if not self.works_on_instance: @@ -221,6 +223,81 @@ else: return '&%s' % fname +class make_constructor_t( calldef_t ): + def __init__( self, function ): + calldef_t.__init__( self, function=function ) + + def make_cnstr_identifier( self ): + return algorithm.create_identifier( self, '::boost::python::make_constructor' ) + + def create_function_type_alias_code( self, exported_class_alias=None ): + ftype = self.declaration.function_type() + return 'typedef %s;' % ftype.create_typedef( self.function_type_alias, exported_class_alias, with_defaults=False ) + + def create_function_ref_code(self, use_function_alias=False): + fname = declarations.full_name( self.declaration, with_defaults=False ) + if use_function_alias: + return '%s( &%s )' % ( self.function_type_alias, fname ) + elif self.declaration.create_with_signature: + return '(%s)( &%s )' % ( self.declaration.function_type().partial_decl_string, fname ) + else: + return '&%s' % fname + + def _create_impl( self ): + if self.declaration.already_exposed: + return '' + + result = [] + + if not self.works_on_instance: + result.append( self.create_function_type_alias_code() ) + result.append( os.linesep * 2 ) + + result.append( self.create_def_code() + '( ' ) + result.append( os.linesep + self.indent( '"__init__"' ) ) + + result.append( self.param_sep() ) + result.append( self.make_cnstr_identifier() + '( ') + result.append( self.create_function_ref_code( not self.works_on_instance ) ) + + keywd_args = None + if self.declaration.use_keywords: + keywd_args = self.create_keywords_args() + + if self.declaration.call_policies: + default_generates_code_too = bool( keywd_args ) + c_p_code = self.create_call_policies( default_generates_code_too ) + if c_p_code: + result.append( self.indent( self.param_sep(), 3 ) ) + result.append( c_p_code ) + + if keywd_args: + result.append( self.indent( self.param_sep(), 3 ) ) + result.append( keywd_args ) + + result.append( ' )' ) #make_constructor + + doc = self.create_doc() + if doc: + result.append( self.param_sep() ) + result.append( doc ) + + result.append( ' )' ) + if not self.works_on_instance: + result.append( ';' ) + + if not self.works_on_instance: + #indenting and adding scope + code = ''.join( result ) + result = [ '{ //%s' % declarations.full_name( self.declaration, with_defaults=False ) ] + result.append( os.linesep * 2 ) + result.append( self.indent( code ) ) + result.append( os.linesep * 2 ) + result.append( '}' ) + + return ''.join( result ) + + class mem_fun_pv_t( calldef_t ): def __init__( self, function, wrapper ): calldef_t.__init__( self, function=function, wrapper=wrapper ) Modified: pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2008-08-12 04:30:53 UTC (rev 1391) +++ pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2008-08-13 19:45:24 UTC (rev 1392) @@ -192,6 +192,23 @@ self._exposed_class_type = self.EXPOSED_CLASS_TYPE.DECLARED self._expose_this = None self._expose_sizeof = None + self._fake_constructors = [] + + @property + def fake_constructors(self): + """list of fake constructors""" + return self._fake_constructors + + def add_fake_constructors( self, f ): + """f - reference to a calldef_t object or list of them + + boost::python::make_constructor allows to register a C++ function, as a + class constructor. + """ + if isinstance( f, declarations.calldef_t ): + self._fake_constructors.add( f ) + else: + self._fake_constructors.extend( f ) def _get_redefine_operators( self ): return self._redefine_operators Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2008-08-12 04:30:53 UTC (rev 1391) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2008-08-13 19:45:24 UTC (rev 1392) @@ -78,8 +78,9 @@ self.__types_db = types_db if not self.__types_db: self.__types_db = types_database.types_database_t() - - self.__extmodule = code_creators.module_t( declarations.get_global_namespace(decls) ) + + global_ns = declarations.get_global_namespace(decls) + self.__extmodule = code_creators.module_t( global_ns ) if boost_python_ns_name: bp_ns_alias = code_creators.namespace_alias_t( alias=boost_python_ns_name , full_namespace_name='::boost::python' ) @@ -100,8 +101,10 @@ self.__array_1_registered = set() #(type.decl_string,size) self.__free_operators = [] self.__exposed_free_fun_overloads = set() + self.__fake_constructors = set() + for cls in global_ns.classes(recursive=True, allow_empty=True): + self.__fake_constructors.update( cls.fake_constructors ) - def __print_readme( self, decl ): readme = decl.readme() if not readme: @@ -347,9 +350,13 @@ return self.__extmodule def visit_member_function( self ): - fwrapper = None self.__types_db.update( self.curr_decl ) self.__dependencies_manager.add_exported( self.curr_decl ) + + if self.curr_decl in self.__fake_constructors: + return + + fwrapper = None if None is self.curr_decl.call_policies: self.curr_decl.call_policies = self.__call_policies_resolver( self.curr_decl ) @@ -453,6 +460,12 @@ def visit_free_function( self ): if self.curr_decl in self.__exposed_free_fun_overloads: return + + if self.curr_decl in self.__fake_constructors: + self.__types_db.update( self.curr_decl ) + self.__dependencies_manager.add_exported( self.curr_decl ) + return + elif self.curr_decl.use_overload_macro: parent_decl = self.curr_decl.parent names = set( map( lambda decl: decl.name @@ -595,6 +608,9 @@ if cls_decl.expose_sizeof: cls_cc.adopt_creator( code_creators.expose_sizeof_t( cls_decl ) ) + for fc in cls_decl.fake_constructors: + cls_cc.adopt_creator( code_creators.make_constructor_t( fc ) ) + for decl in exportable_members: if decl in exposed: continue Added: pyplusplus_dev/unittests/cp_return_addressof_tester.py =================================================================== --- pyplusplus_dev/unittests/cp_return_addressof_tester.py (rev 0) +++ pyplusplus_dev/unittests/cp_return_addressof_tester.py 2008-08-13 19:45:24 UTC (rev 1392) @@ -0,0 +1,42 @@ +# Copyright 2004 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. (See +# accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import os +import sys +import ctypes +import unittest +import fundamental_tester_base +from pyplusplus.module_builder import call_policies + +class tester_t(fundamental_tester_base.fundamental_tester_base_t): + EXTENSION_NAME = 'cp_return_addressof' + + def __init__( self, *args ): + fundamental_tester_base.fundamental_tester_base_t.__init__( + self + , tester_t.EXTENSION_NAME + , *args ) + + def customize(self, mb ): + mb.classes().always_expose_using_scope = True + mb.calldef( 'get_buffer' ).call_policies \ + = call_policies.return_value_policy( call_policies.return_addressof ) + + def run_tests(self, module): + image = module.image_t() + buffer_type = ctypes.c_int * 5 + buffer = buffer_type.from_address( image.get_buffer() ) + self.failUnless( [0,1,2,3,4] == list( buffer ) ) + +def create_suite(): + suite = unittest.TestSuite() + suite.addTest( unittest.makeSuite(tester_t)) + return suite + +def run_suite(): + unittest.TextTestRunner(verbosity=2).run( create_suite() ) + +if __name__ == "__main__": + run_suite() Property changes on: pyplusplus_dev/unittests/data ___________________________________________________________________ Modified: svn:ignore - *.obj call_policies_to_be_exported.os global_variables_to_be_exported.os member_functions_to_be_exported.os + *.obj call_policies_to_be_exported.os global_variables_to_be_exported.os member_functions_to_be_exported.os cache duplicate_aliases_to_be_exported.os factory_to_be_exported.os member_variables_to_be_exported.os non_overridable_to_be_exported.os particleuniverse.xml smart_pointers_to_be_exported.os split_module_bug_to_be_exported.os statics_to_be_exported.os throw_to_be_exported.os vector3_to_be_exported.os vector_with_shared_data_to_be_exported.os Added: pyplusplus_dev/unittests/data/cp_return_addressof_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/cp_return_addressof_to_be_exported.hpp (rev 0) +++ pyplusplus_dev/unittests/data/cp_return_addressof_to_be_exported.hpp 2008-08-13 19:45:24 UTC (rev 1392) @@ -0,0 +1,28 @@ +// Copyright 2004 Roman Yakovenko. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef __cp_return_addressof_to_be_exported_hpp__ +#define __cp_return_addressof_to_be_exported_hpp__ + +#include <string> + +struct image_t{ + image_t() + : buffer( new int[5] ) + { + for( int i = 0; i < 5; ++i ){ + buffer[i] = i; + } + } + + ~image_t(){ delete[] buffer; } + + int* get_buffer() const { return buffer; } + +private: + int* buffer; +}; + +#endif//__cp_return_addressof_to_be_exported_hpp__ Added: pyplusplus_dev/unittests/data/make_constructor_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/make_constructor_to_be_exported.hpp (rev 0) +++ pyplusplus_dev/unittests/data/make_constructor_to_be_exported.hpp 2008-08-13 19:45:24 UTC (rev 1392) @@ -0,0 +1,40 @@ +// Copyright 2004 Roman Yakovenko. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef __make_constructor_to_be_exported_hpp__ +#define __make_constructor_to_be_exported_hpp__ + +#include <memory> + +namespace mc{ + +struct numbers_t{ + numbers_t() + : x( 0 ) + , y( 0 ) + {} + ~numbers_t(){} + + static std::auto_ptr<numbers_t> create( int i, int j, int k, int m ){ + std::auto_ptr<numbers_t> n( new numbers_t() ); + n->x = i + j; + n->y = k + m; + return n; + } + + int x; + int y; +}; + +inline std::auto_ptr<numbers_t> create( int i, int j){ + std::auto_ptr<numbers_t> n( new numbers_t() ); + n->x = i; + n->y = j; + return n; +} + +} + +#endif//__make_constructor_to_be_exported_hpp__ Added: pyplusplus_dev/unittests/make_constructor_tester.py =================================================================== --- pyplusplus_dev/unittests/make_constructor_tester.py (rev 0) +++ pyplusplus_dev/unittests/make_constructor_tester.py 2008-08-13 19:45:24 UTC (rev 1392) @@ -0,0 +1,41 @@ +# Copyright 2004 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. (See +# accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import os +import sys +import unittest +import fundamental_tester_base + +class tester_t(fundamental_tester_base.fundamental_tester_base_t): + EXTENSION_NAME = 'make_constructor' + + def __init__( self, *args ): + fundamental_tester_base.fundamental_tester_base_t.__init__( + self + , tester_t.EXTENSION_NAME + , *args ) + + def customize(self, mb ): + mc = mb.namespace( 'mc' ) + numbers = mc.class_( 'numbers_t' ) + numbers.add_fake_constructors( mc.calldefs( 'create' ) ) + + + def run_tests(self, module): + n = module.numbers_t( 1,2,3,4) + self.failUnless( n.x == 1+2 and n.y == 3+4) + n = module.numbers_t( 10, 18) + self.failUnless( n.x == 10 and n.y == 18) + +def create_suite(): + suite = unittest.TestSuite() + suite.addTest( unittest.makeSuite(tester_t)) + return suite + +def run_suite(): + unittest.TextTestRunner(verbosity=2).run( create_suite() ) + +if __name__ == "__main__": + run_suite() Modified: pyplusplus_dev/unittests/test_all.py =================================================================== --- pyplusplus_dev/unittests/test_all.py 2008-08-12 04:30:53 UTC (rev 1391) +++ pyplusplus_dev/unittests/test_all.py 2008-08-13 19:45:24 UTC (rev 1392) @@ -107,6 +107,7 @@ import embeded_tester import unions_tester import cp_return_addressof_tester +import make_constructor_tester #import ogre_generate_tester testers = [ @@ -202,6 +203,7 @@ , embeded_tester , unions_tester , cp_return_addressof_tester + , make_constructor_tester # , ogre_generate_tester too much time ] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |