pygccxml-commit Mailing List for C++ Python language bindings (Page 40)
Brought to you by:
mbaas,
roman_yakovenko
You can subscribe to this list here.
2006 |
Jan
|
Feb
|
Mar
(190) |
Apr
(166) |
May
(170) |
Jun
(75) |
Jul
(105) |
Aug
(131) |
Sep
(99) |
Oct
(84) |
Nov
(67) |
Dec
(54) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2007 |
Jan
(66) |
Feb
(49) |
Mar
(25) |
Apr
(62) |
May
(21) |
Jun
(34) |
Jul
(9) |
Aug
(21) |
Sep
(5) |
Oct
|
Nov
(63) |
Dec
(34) |
2008 |
Jan
(10) |
Feb
(42) |
Mar
(26) |
Apr
(25) |
May
(6) |
Jun
(40) |
Jul
(18) |
Aug
(29) |
Sep
(6) |
Oct
(32) |
Nov
(14) |
Dec
(56) |
2009 |
Jan
(127) |
Feb
(52) |
Mar
(2) |
Apr
(10) |
May
(29) |
Jun
(3) |
Jul
|
Aug
(16) |
Sep
(4) |
Oct
(11) |
Nov
(8) |
Dec
(14) |
2010 |
Jan
(31) |
Feb
(1) |
Mar
(7) |
Apr
(9) |
May
(1) |
Jun
|
Jul
(2) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2011 |
Jan
|
Feb
(8) |
Mar
(4) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2014 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <rom...@us...> - 2007-01-28 19:20:20
|
Revision: 883 http://svn.sourceforge.net/pygccxml/?rev=883&view=rev Author: roman_yakovenko Date: 2007-01-28 11:20:20 -0800 (Sun, 28 Jan 2007) Log Message: ----------- allow construction of c-tuple from any sequence Added Paths: ----------- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/automatic_conversion.zip Added: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/automatic_conversion.zip =================================================================== (Binary files differ) Property changes on: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/automatic_conversion.zip ___________________________________________________________________ Name: svn:mime-type + application/octet-stream This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-01-28 19:11:58
|
Revision: 882 http://svn.sourceforge.net/pygccxml/?rev=882&view=rev Author: roman_yakovenko Date: 2007-01-28 11:11:58 -0800 (Sun, 28 Jan 2007) Log Message: ----------- allow construction of c-tuple from any sequence Modified Paths: -------------- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/custom_rvalue.cpp pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/test.py pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuples.hpp Modified: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/custom_rvalue.cpp =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/custom_rvalue.cpp 2007-01-28 13:14:56 UTC (rev 881) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/custom_rvalue.cpp 2007-01-28 19:11:58 UTC (rev 882) @@ -61,7 +61,7 @@ typedef boost::tuples::tuple< float, float, float> colour_tuple_type; - typedef bpl::from_py_tuple< colour_tuple_type > converter_type; + typedef bpl::from_py_sequence< colour_tuple_type > converter_type; static void* convertible(PyObject* obj){ return converter_type::convertible( obj ); @@ -74,7 +74,7 @@ void* memory_chunk = the_storage->storage.bytes; float red(0.0), green(0.0), blue(0.0); - boost::tuples::tie(red, green, blue) = converter_type::construct_c_tuple( obj ); + boost::tuples::tie(red, green, blue) = converter_type::to_c_tuple( obj ); colour_t* colour = new (memory_chunk) colour_t(red, green, blue); data->convertible = memory_chunk; Modified: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/test.py =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/test.py 2007-01-28 13:14:56 UTC (rev 881) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/test.py 2007-01-28 19:11:58 UTC (rev 882) @@ -13,12 +13,16 @@ self.failUnlessRaises( TypeError, tuples.triplet_ret_ptr_110 ) self.failUnless( tuples.test_triplet_val_000( (0,0,0) ) ) self.failUnless( tuples.test_triplet_cref_010( (0,1,0) ) ) + self.failUnless( tuples.test_triplet_val_000( [0,0,0] ) ) + self.failUnless( tuples.test_triplet_cref_010( [0,1,0] ) ) self.failUnlessRaises( TypeError, tuples.test_triplet_ref_110, (1,1,0) ) self.failUnlessRaises( TypeError, tuples.test_triplet_ptr_101, (1,0,1) ) def test_from_sequence( self ): self.failUnless( custom_rvalue.test_val_010( (0,1,0) ) ) self.failUnless( custom_rvalue.test_cref_000( (0,0,0) ) ) + self.failUnless( custom_rvalue.test_val_010( [0,1,0] ) ) + self.failUnless( custom_rvalue.test_cref_000( [0,0,0] ) ) self.failUnlessRaises( Exception, custom_rvalue.test_ref_111, (1,1,1) ) self.failUnlessRaises( Exception, custom_rvalue.test_ptr_101, (1,0,1) ) self.failUnlessRaises( Exception, custom_rvalue.test_cptr_110, (1,1,0) ) Modified: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuples.hpp =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuples.hpp 2007-01-28 13:14:56 UTC (rev 881) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuples.hpp 2007-01-28 19:11:58 UTC (rev 882) @@ -139,7 +139,7 @@ template< class TTuple> -struct from_py_tuple{ +struct from_py_sequence{ typedef TTuple tuple_type; @@ -148,16 +148,16 @@ static void* convertible(PyObject* py_obj){ - if( !PyTuple_Check( py_obj ) ){ + if( !PySequence_Check( py_obj ) ){ return 0; } - python::tuple py_tuple( handle<>( borrowed( py_obj ) ) ); - if( tuples::length< TTuple >::value != len( py_tuple ) ){ + python::object py_sequence( handle<>( borrowed( py_obj ) ) ); + if( tuples::length< TTuple >::value != len( py_sequence ) ){ return 0; } - if( convertible_impl( py_tuple, mpl::int_< 0 >(), length_type() ) ){ + if( convertible_impl( py_sequence, mpl::int_< 0 >(), length_type() ) ){ return py_obj; } else{ @@ -173,17 +173,17 @@ TTuple* c_tuple = new (memory_chunk) TTuple(); data->convertible = memory_chunk; - python::tuple py_tuple( handle<>( borrowed( py_obj ) ) ); - construct_impl( py_tuple, *c_tuple, mpl::int_< 0 >(), length_type() ); + python::object py_sequence( handle<>( borrowed( py_obj ) ) ); + construct_impl( py_sequence, *c_tuple, mpl::int_< 0 >(), length_type() ); } - static TTuple construct_c_tuple( PyObject* py_obj ){ + static TTuple to_c_tuple( PyObject* py_obj ){ if( !convertible( py_obj ) ){ throw std::runtime_error( "Unable to construct boost::tuples::tuple from Python object!" ); } TTuple c_tuple; - python::tuple py_tuple( handle<>( borrowed( py_obj ) ) ); - construct_impl( py_tuple, c_tuple, mpl::int_< 0 >(), length_type() ); + python::object py_sequence( handle<>( borrowed( py_obj ) ) ); + construct_impl( py_sequence, c_tuple, mpl::int_< 0 >(), length_type() ); return c_tuple; } @@ -191,41 +191,41 @@ template< int index, int length > static bool - convertible_impl( const python::tuple& py_tuple, mpl::int_< index >, mpl::int_< length > ){ + convertible_impl( const python::object& py_sequence, mpl::int_< index >, mpl::int_< length > ){ typedef typename tuples::element< index, TTuple>::type element_type; - object element = py_tuple[index]; + object element = py_sequence[index]; extract<element_type> type_checker( element ); if( !type_checker.check() ){ return false; } else{ - return convertible_impl( py_tuple, details::increment_index<index>(), length_type() ); + return convertible_impl( py_sequence, details::increment_index<index>(), length_type() ); } } template< int length > static bool - convertible_impl( const python::tuple& py_tuple, mpl::int_< length >, mpl::int_< length > ){ + convertible_impl( const python::object& py_sequence, mpl::int_< length >, mpl::int_< length > ){ return true; } template< int index, int length > static void - construct_impl( const python::tuple& py_tuple, TTuple& c_tuple, mpl::int_< index >, mpl::int_< length > ){ + construct_impl( const python::object& py_sequence, TTuple& c_tuple, mpl::int_< index >, mpl::int_< length > ){ typedef typename tuples::element< index, TTuple>::type element_type; - object element = py_tuple[index]; + object element = py_sequence[index]; c_tuple.template get< index >() = extract<element_type>( element ); - construct_impl( py_tuple, c_tuple, details::increment_index<index>(), length_type() ); + construct_impl( py_sequence, c_tuple, details::increment_index<index>(), length_type() ); } template< int length > static void - construct_impl( const python::tuple& py_tuple, TTuple& c_tuple, mpl::int_< length >, mpl::int_< length > ) + construct_impl( const python::object& py_sequence, TTuple& c_tuple, mpl::int_< length >, mpl::int_< length > ) {} }; @@ -235,8 +235,8 @@ to_python_converter< TTuple, to_py_tuple<TTuple> >(); - converter::registry::push_back( &from_py_tuple<TTuple>::convertible - , &from_py_tuple<TTuple>::construct + converter::registry::push_back( &from_py_sequence<TTuple>::convertible + , &from_py_sequence<TTuple>::construct , type_id<TTuple>() ); }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-01-28 13:14:56
|
Revision: 881 http://svn.sourceforge.net/pygccxml/?rev=881&view=rev Author: roman_yakovenko Date: 2007-01-28 05:14:56 -0800 (Sun, 28 Jan 2007) Log Message: ----------- adding initial support for multi-module development Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/calldef.py pyplusplus_dev/pyplusplus/code_creators/class_declaration.py pyplusplus_dev/pyplusplus/code_creators/enum.py pyplusplus_dev/pyplusplus/code_creators/exception_translator.py pyplusplus_dev/pyplusplus/code_creators/global_variable.py pyplusplus_dev/pyplusplus/code_creators/indexing_suites.py pyplusplus_dev/pyplusplus/code_creators/smart_pointers.py pyplusplus_dev/pyplusplus/code_creators/unnamed_enum.py pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py pyplusplus_dev/pyplusplus/decl_wrappers/scopedef_wrapper.py pyplusplus_dev/pyplusplus/file_writers/multiple_files.py pyplusplus_dev/pyplusplus/module_creator/creator.py Modified: pyplusplus_dev/pyplusplus/code_creators/calldef.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/calldef.py 2007-01-22 17:36:24 UTC (rev 880) +++ pyplusplus_dev/pyplusplus/code_creators/calldef.py 2007-01-28 13:14:56 UTC (rev 881) @@ -80,6 +80,9 @@ raise NotImplementedError() def _create_impl( self ): + if self.declaration.already_exposed: + return '' + result = [] if not self.works_on_instance: @@ -1144,6 +1147,9 @@ calldef_overloads_class_t.__init__( self, mem_funs ) def _create_impl(self): + if self.max_function.already_exposed: + return '' + min_, max_ = self.min_max_num_of_args() return "BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( %(overloads_cls)s, %(fun)s, %(min)d, %(max)d )" \ % { 'overloads_cls' : self.name @@ -1159,6 +1165,9 @@ calldef_overloads_class_t.__init__( self, free_funs ) def _create_impl(self): + if self.max_function.already_exposed: + return '' + min_, max_ = self.min_max_num_of_args() return "BOOST_PYTHON_FUNCTION_OVERLOADS( %(overloads_cls)s, %(fun)s, %(min)d, %(max)d )" \ % { 'overloads_cls' : self.name Modified: pyplusplus_dev/pyplusplus/code_creators/class_declaration.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/class_declaration.py 2007-01-22 17:36:24 UTC (rev 880) +++ pyplusplus_dev/pyplusplus/code_creators/class_declaration.py 2007-01-28 13:14:56 UTC (rev 881) @@ -75,6 +75,8 @@ return os.linesep.join( result ) def _create_impl(self): + if self.declaration.already_exposed: + return '' if self.is_exposed_using_scope(): return self._generate_code_with_scope() else: @@ -306,6 +308,8 @@ return bool( filter( lambda cc: not cc.works_on_instance, self.creators ) ) def _create_impl(self): + if self.declaration.already_exposed: + return '' if self.is_exposed_using_scope(): return self._generate_code_with_scope() else: @@ -374,6 +378,8 @@ return ', '.join( [self.exposed_identifier, self.boost_wrapper_identifier] ) def _create_impl(self): + if self.declaration.already_exposed: + return '' answer = ['struct %s : %s {' % ( self.wrapper_alias, self._create_bases() )] answer.append( '' ) answer.append( self.create_internal_code( self.creators ) ) Modified: pyplusplus_dev/pyplusplus/code_creators/enum.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/enum.py 2007-01-22 17:36:24 UTC (rev 880) +++ pyplusplus_dev/pyplusplus/code_creators/enum.py 2007-01-28 13:14:56 UTC (rev 881) @@ -38,6 +38,9 @@ , 'name' : algorithm.create_identifier( self, full_name + '::' + value_name ) } 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 ) Modified: pyplusplus_dev/pyplusplus/code_creators/exception_translator.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/exception_translator.py 2007-01-22 17:36:24 UTC (rev 880) +++ pyplusplus_dev/pyplusplus/code_creators/exception_translator.py 2007-01-28 13:14:56 UTC (rev 881) @@ -22,6 +22,8 @@ return 'translate_%(alias)s' % { 'alias' : self.declaration.alias } def _create_impl(self): + if self.declaration.already_exposed: + return '' return os.linesep.join([ "void translate_%(alias)s( const %(cls_name)s& %(arg_name)s ){" \ , self.indent( self.declaration.exception_translation_code ) @@ -40,9 +42,12 @@ self.translator = exception_translator 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 } - \ No newline at end of file + Modified: pyplusplus_dev/pyplusplus/code_creators/global_variable.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/global_variable.py 2007-01-22 17:36:24 UTC (rev 880) +++ pyplusplus_dev/pyplusplus/code_creators/global_variable.py 2007-01-28 13:14:56 UTC (rev 881) @@ -41,6 +41,9 @@ global_variable_base_t.__init__( self, variable=variable ) 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' ) ) @@ -59,6 +62,9 @@ global_variable_base_t.__init__( self, variable=variable, wrapper=wrapper ) 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 ) @@ -122,6 +128,9 @@ return ''.join( temp ) def _create_impl( self ): + if self.declaration.already_exposed: + return '' + answer = [self._create_namespaces_name()] answer.append( self.wrapper_type.decl_string ) answer.append( ''.join([ self.wrapper_creator_name, '(){']) ) Modified: pyplusplus_dev/pyplusplus/code_creators/indexing_suites.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/indexing_suites.py 2007-01-22 17:36:24 UTC (rev 880) +++ pyplusplus_dev/pyplusplus/code_creators/indexing_suites.py 2007-01-28 13:14:56 UTC (rev 881) @@ -46,7 +46,7 @@ args.append( no_proxy) return declarations.templates.join( suite_identifier, args ) - def _create_impl(self): + def _create_impl(self): return "def( %s() )" % self._create_suite_declaration() @@ -83,6 +83,9 @@ 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() ) @@ -161,6 +164,8 @@ pass # for inner class this code will generate error :-(((( def _create_impl( self ): + if self.declaration.already_exposed: + return '' return self.generate_value_traits() Modified: pyplusplus_dev/pyplusplus/code_creators/smart_pointers.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/smart_pointers.py 2007-01-22 17:36:24 UTC (rev 880) +++ pyplusplus_dev/pyplusplus/code_creators/smart_pointers.py 2007-01-28 13:14:56 UTC (rev 881) @@ -61,6 +61,8 @@ class_creator = property( _get_class_creator, _set_class_creator ) 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 ) \ @@ -109,4 +111,4 @@ to_arg = self._instantiate_smart_ptr( self.target ) return templates.join(implicitly_convertible, [ from_arg, to_arg ] ) + '();' - \ No newline at end of file + Modified: pyplusplus_dev/pyplusplus/code_creators/unnamed_enum.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/unnamed_enum.py 2007-01-22 17:36:24 UTC (rev 880) +++ pyplusplus_dev/pyplusplus/code_creators/unnamed_enum.py 2007-01-28 13:14:56 UTC (rev 881) @@ -23,6 +23,9 @@ value_aliases = property( _get_value_aliases, _set_value_aliases ) 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 = [] @@ -30,4 +33,4 @@ result.append( tmpl % ( self.value_aliases.get( name, name ) , algorithm.create_identifier( self, full_name + '::' + name ) ) ) return os.linesep.join( result ) - \ No newline at end of file + Modified: pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2007-01-22 17:36:24 UTC (rev 880) +++ pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2007-01-28 13:14:56 UTC (rev 881) @@ -127,6 +127,20 @@ +"Thus it will be able to generate code, that uses " \ +" BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID macro in a right places." ) + def _get_already_exposed_impl( self ): + if not self.indexing_suite: + return self._already_exposed + try: + et = self.indexing_suite.element_type + et = declarations.remove_const( et ) + et = declarations.remove_pointer( et ) + et = declarations.remove_declarated( et ) + if isinstance(et, declarations.declaration_t): + return et._already_exposed + return False + except: + return False + #this will only be exported if indexing suite is not None and only when needed class class_declaration_t( class_common_details_t , decl_wrapper.decl_wrapper_t Modified: pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py 2007-01-22 17:36:24 UTC (rev 880) +++ pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py 2007-01-28 13:14:56 UTC (rev 881) @@ -26,6 +26,7 @@ object.__init__(self) self._alias = None self._ignore = False + self._already_exposed = False self._exportable = None self._exportable_reason = None self._documentation = None @@ -100,14 +101,24 @@ ignore = property( _get_ignore, _set_ignore ,doc="If you set ignore to True then this declaration will not be exported." ) + def _get_already_exposed_impl( self ): + return self._already_exposed + + def _get_already_exposed( self ): + return self._get_already_exposed_impl() + def _set_already_exposed( self, value ): + self._already_exposed = value + already_exposed = property( _get_already_exposed, _set_already_exposed ) + def exclude( self ): """Exclude "self" and child declarations from being exposed.""" self.ignore = True - def include( self ): + def include( self, already_exposed=False ): """Include "self" and child declarations to be exposed.""" self.ignore = False - + self.already_exposed = already_exposed + def why_not_exportable( self ): """returns strings that explains why this declaration could not be exported or None otherwise""" if None is self._exportable_reason: Modified: pyplusplus_dev/pyplusplus/decl_wrappers/scopedef_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/scopedef_wrapper.py 2007-01-22 17:36:24 UTC (rev 880) +++ pyplusplus_dev/pyplusplus/decl_wrappers/scopedef_wrapper.py 2007-01-28 13:14:56 UTC (rev 881) @@ -22,7 +22,8 @@ self.ignore = True map( lambda decl: decl.exclude(), self.declarations ) - def include( self ): + def include( self, already_exposed=False ): """Include "self" and child declarations to be exposed.""" self.ignore = False - map( lambda decl: decl.include(), self.declarations ) + self.already_exposed = already_exposed + map( lambda decl: decl.include(already_exposed), self.declarations ) Modified: pyplusplus_dev/pyplusplus/file_writers/multiple_files.py =================================================================== --- pyplusplus_dev/pyplusplus/file_writers/multiple_files.py 2007-01-22 17:36:24 UTC (rev 880) +++ pyplusplus_dev/pyplusplus/file_writers/multiple_files.py 2007-01-28 13:14:56 UTC (rev 881) @@ -251,6 +251,8 @@ @type class_creator: class_t """ try: + if class_creator.declaration.already_exposed: + return self.split_class_impl( class_creator ) except IOError, error: msg = [ 'Failed to write code for class "%s" into file.;' % class_creator.declaration.name ] @@ -267,6 +269,9 @@ Write the value_traits class to header file, that will be included from files, that uses indexing suite 2 """ + if value_traits.declaration.already_exposed: + return + header_name = self.create_value_traits_header_name( value_traits.declaration ) file_path = os.path.join( self.directory_path, header_name ) self.write_file( file_path Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2007-01-22 17:36:24 UTC (rev 880) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2007-01-28 13:14:56 UTC (rev 881) @@ -137,7 +137,10 @@ for decl in decls: if decl.ignore: continue - + + if decl.already_exposed: + continue + #Right now this functionality introduce a bug: declarations that should #not be exported for some reason are not marked as such. I will need to #find out. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <al...@us...> - 2007-01-22 17:36:24
|
Revision: 880 http://svn.sourceforge.net/pygccxml/?rev=880&view=rev Author: allenb Date: 2007-01-22 09:36:24 -0800 (Mon, 22 Jan 2007) Log Message: ----------- Disable broken optimization. Modified Paths: -------------- pyplusplus_dev/contrib/goodies/goodie_perf_overrides.py Modified: pyplusplus_dev/contrib/goodies/goodie_perf_overrides.py =================================================================== --- pyplusplus_dev/contrib/goodies/goodie_perf_overrides.py 2007-01-22 16:55:20 UTC (rev 879) +++ pyplusplus_dev/contrib/goodies/goodie_perf_overrides.py 2007-01-22 17:36:24 UTC (rev 880) @@ -219,6 +219,6 @@ self._module_builder_t__registrations_code_head = [] self._module_builder_t__registrations_code_tail = [] -pyplusplus.module_builder.module_builder_t.__init__ = mb_override__init__ -print " overriding module_builder.__init__ with cache." +#pyplusplus.module_builder.module_builder_t.__init__ = mb_override__init__ +#print " overriding module_builder.__init__ with cache." This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-01-22 17:09:59
|
Revision: 879 http://svn.sourceforge.net/pygccxml/?rev=879&view=rev Author: roman_yakovenko Date: 2007-01-22 08:55:20 -0800 (Mon, 22 Jan 2007) Log Message: ----------- updating docs Modified Paths: -------------- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/automatic_conversion.rest pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/definition.rest pyplusplus_dev/docs/troubleshooting_guide/smart_ptrs/smart_ptrs.rest Modified: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/automatic_conversion.rest =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/automatic_conversion.rest 2007-01-22 08:46:18 UTC (rev 878) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/automatic_conversion.rest 2007-01-22 16:55:20 UTC (rev 879) @@ -10,40 +10,54 @@ .. include:: ./definition.rest ---------------- -Example content ---------------- +------- +Content +------- +This example actually consist from 2 small, well documented examples. +The first one shows how to handle conversion between tuples: `boost::tuples::tuple`_ +and Python tuple. +.. _`boost::tuples::tuple` : http://boost.org/libs/tuple/doc/tuple_users_guide.html + +The second one shows how to add an automatic conversion from Python tuple to +some registered class. The class registration allows you to use its functionality +and enjoy from automatic conversion. + Files ----- -* `solution.cpp`_ file contains definition of a class and few functions, which - have ``shared_ptr< T >`` and ``shared_ptr< const T>`` as return type or as an - argument. The file also contains source code that exposes the defined - functionality to Python. +* `tuples.hpp`_ file contains Boost.Tuple to\\from Python tuple conversion + implementation + +* `tuples_tester.cpp`_ file contains few functions, which test the tuples + conversion functionality +* `custom_rvalue.cpp`_ file contains example of registration custom r-value + converter + * `sconstruct`_ file contains build instructions for scons build tool. -* `test.py`_ file contains complete unit tests for the exposed classes +* `test.py`_ file contains complete unit tests for both example -* `pointer_holder.hpp.patch`_ file contains patch for the library - All files contain comments, which describe what and why was done. -.. _`solution.cpp` : ./solution.cpp.html +.. _`tuples.hpp` : ./tuples.hpp.html +.. _`tuples_tester.cpp` : ./tuples_tester.cpp.html +.. _`custom_rvalue.cpp` : ./custom_rvalue.cpp.html .. _`sconstruct` : ./sconstruct.html .. _`test.py` : ./test.py.html -.. _`pointer_holder.hpp.patch` : ./pointer_holder.hpp.patch.html -------- Download -------- -https://sourceforge.net/project/showfiles.php?group_id=118209 +`automatic_conversion.zip`_ +.. _`automatic_conversion.zip` : ./automatic_conversion.zip + .. _`Py++` : ./../pyplusplus.html .. _`pygccxml` : http://www.language-binding.net/pygccxml/pygccxml.html .. _`SourceForge`: http://sourceforge.net/index.php Modified: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/definition.rest =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/definition.rest 2007-01-22 08:46:18 UTC (rev 878) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/definition.rest 2007-01-22 16:55:20 UTC (rev 879) @@ -1,3 +1,3 @@ -Boost.Python allows to define automatic conversion from\\to Python classes. +Boost.Python allows to define automatic conversion from\\to C++\\Python types. While this is very, very useful functionality, the documentation for it does not -exist. This example will shed some light on "rvalue"\\"lvalue" converters. \ No newline at end of file +exist. This example will shed some light on "r-value"\\"l-value" converters. Modified: pyplusplus_dev/docs/troubleshooting_guide/smart_ptrs/smart_ptrs.rest =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/smart_ptrs/smart_ptrs.rest 2007-01-22 08:46:18 UTC (rev 878) +++ pyplusplus_dev/docs/troubleshooting_guide/smart_ptrs/smart_ptrs.rest 2007-01-22 16:55:20 UTC (rev 879) @@ -36,9 +36,11 @@ Download -------- -https://sourceforge.net/project/showfiles.php?group_id=118209 +`smart_ptrs.zip`_ +.. _`smart_ptrs.zip` : ./smart_ptrs.zip + .. _`Py++` : ./../pyplusplus.html .. _`pygccxml` : http://www.language-binding.net/pygccxml/pygccxml.html .. _`SourceForge`: http://sourceforge.net/index.php This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-01-22 08:46:20
|
Revision: 878 http://svn.sourceforge.net/pygccxml/?rev=878&view=rev Author: roman_yakovenko Date: 2007-01-22 00:46:18 -0800 (Mon, 22 Jan 2007) Log Message: ----------- adding license Modified Paths: -------------- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuples.hpp Modified: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuples.hpp =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuples.hpp 2007-01-21 20:18:01 UTC (rev 877) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuples.hpp 2007-01-22 08:46:18 UTC (rev 878) @@ -1,3 +1,8 @@ +// Copyright 2004-2007 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 TUPLES_HPP_16_JAN_2007 #define TUPLES_HPP_16_JAN_2007 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-01-21 20:18:04
|
Revision: 877 http://svn.sourceforge.net/pygccxml/?rev=877&view=rev Author: roman_yakovenko Date: 2007-01-21 12:18:01 -0800 (Sun, 21 Jan 2007) Log Message: ----------- Removed Paths: ------------- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/auto_conversion.cpp.rest Deleted: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/auto_conversion.cpp.rest =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/auto_conversion.cpp.rest 2007-01-21 20:15:23 UTC (rev 876) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/auto_conversion.cpp.rest 2007-01-21 20:18:01 UTC (rev 877) @@ -1,3 +0,0 @@ -.. code-block:: - :language: C++ - :source-file: ./auto_conversion.cpp This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-01-21 20:15:24
|
Revision: 876 http://svn.sourceforge.net/pygccxml/?rev=876&view=rev Author: roman_yakovenko Date: 2007-01-21 12:15:23 -0800 (Sun, 21 Jan 2007) Log Message: ----------- r-value converters first draft Modified Paths: -------------- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/automatic_conversion.rest pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/definition.rest pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/sconstruct pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/test.py pyplusplus_dev/docs/troubleshooting_guide/shared_ptr/shared_ptr.rest Added Paths: ----------- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/custom_rvalue.cpp pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/custom_rvalue.cpp.rest pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuples.hpp pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuples.hpp.rest pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuples_tester.cpp pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuples_tester.cpp.rest pyplusplus_dev/docs/troubleshooting_guide/shared_ptr/shared_ptr.zip pyplusplus_dev/docs/troubleshooting_guide/smart_ptrs/smart_ptrs.zip Removed Paths: ------------- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/auto_conversion.cpp pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/from_conversion.cpp pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/from_conversion.cpp.rest pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuple_conversion.hpp pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuple_conversion.hpp.rest Deleted: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/auto_conversion.cpp =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/auto_conversion.cpp 2007-01-21 07:17:10 UTC (rev 875) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/auto_conversion.cpp 2007-01-21 20:15:23 UTC (rev 876) @@ -1,71 +0,0 @@ -#include "boost/python.hpp" -#include "tuple_conversion.hpp" -#include "boost/tuple/tuple_comparison.hpp" - -//This example is very similar to one found in Boost.Python FAQs: -//How can I automatically convert my custom string type to and from a Python string? -//http://www.boost.org/libs/python/doc/v2/faq.html#custom_string -//I will introduce another example with detailed explanation. - -//Simple class, which describes a record in 3D. I don't want to export the class. -//Instead of this I want Python user pass tuple as argument to all functions -//that expects record_t class instance and Boost.Python will automaticly handle -//the conversion. Same conversion should be applied on functions, which returns -//record_t class instance - -typedef boost::tuple< int, int, int > record_t; - -record_t record_ret_val_000() { - return record_t(0,0,0); -} - -record_t record_ret_val_101() { - return record_t(1,0,1); -} - -record_t& record_ret_ref_010(){ - static record_t pt( 0,1,0 ); - return pt; -} - -record_t* record_ret_ptr_110(){ - static record_t pt( 1,1,0 ); - return &pt; -} - -bool test_record_val_000( record_t pt ){ - return pt == record_t( 0,0,0 ); -} - -bool test_record_cref_010( const record_t& pt ){ - return pt == record_t( 0,1,0 ); -} - -bool test_record_ref_110( record_t& pt ){ - return pt == record_t( 1,1,0 ); -} - -bool test_record_ptr_101( record_t* pt ){ - return pt && *pt == record_t( 1,0,1 ); -} - - -namespace bpl = boost::python; - -BOOST_PYTHON_MODULE( auto_conversion ){ - bpl::register_tuple< record_t >(); - - bpl::def("record_ret_val_000", &::record_ret_val_000); - bpl::def("record_ret_val_101", &::record_ret_val_101); - bpl::def("record_ret_ref_010" - , &::record_ret_ref_010 - , bpl::return_value_policy<bpl:: copy_non_const_reference>() ); - bpl::def( "record_ret_ptr_110" - , &::record_ret_ptr_110 - , bpl::return_value_policy<bpl::return_by_value>() ); - bpl::def("test_record_val_000", &::test_record_val_000); - bpl::def("test_record_cref_010", &::test_record_cref_010); - bpl::def("test_record_ref_110", &::test_record_ref_110); - bpl::def("test_record_ptr_101", &::test_record_ptr_101); -} - Modified: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/automatic_conversion.rest =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/automatic_conversion.rest 2007-01-21 07:17:10 UTC (rev 875) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/automatic_conversion.rest 2007-01-21 20:15:23 UTC (rev 876) @@ -10,63 +10,18 @@ .. include:: ./definition.rest ---------- -Solutions ---------- +--------------- +Example content +--------------- -There are two possible solutions to the problem. The first one is to fix -Boost.Python library: `pointer_holder.hpp.patch`_ . The patch was contributed -to the library ( 8-December-2006 ) and some day it will be commited to the CVS. -It is also possible to solve the problem, without changing Boost.Python library: - .. code-block:: C++ - - namespace boost{ - - template<class T> - inline T* get_pointer( boost::shared_ptr<const T> const& p ){ - return const_cast< T* >( p.get() ); - } - - } - - namespace boost{ namespace python{ - - template<class T> - struct pointee< boost::shared_ptr<T const> >{ - typedef T type; - }; - - } } //boost::python - - namespace utils{ - - template< class T > - register_shared_ptrs_to_python(){ - namespace bpl = boost::python; - bpl::register_ptr_to_python< boost::shared_ptr< T > >(); - bpl::register_ptr_to_python< boost::shared_ptr< const T > >(); - bpl::implicitly_convertible< boost::shared_ptr< T >, boost::shared_ptr< const T > >(); - } - - } - - BOOST_PYTHON_MODULE(...){ - class_< YourClass >( "YourClass" ) - ...; - utils::register_shared_ptrs_to_python< YourClass >(); - } - -The second approach is a little bit "evil" because it redefines ``get_pointer`` -function for all shared pointer class instantiations. So you should be careful. - Files ----- -* `solution.cpp`_ file contains definition of a class and few functions, which - have ``shared_ptr< T >`` and ``shared_ptr< const T>`` as return type or as an - argument. The file also contains source code that exposes the defined +* `solution.cpp`_ file contains definition of a class and few functions, which + have ``shared_ptr< T >`` and ``shared_ptr< const T>`` as return type or as an + argument. The file also contains source code that exposes the defined functionality to Python. * `sconstruct`_ file contains build instructions for scons build tool. @@ -75,7 +30,7 @@ * `pointer_holder.hpp.patch`_ file contains patch for the library -All files contain comments, which describe what and why was done. +All files contain comments, which describe what and why was done. .. _`solution.cpp` : ./solution.cpp.html .. _`sconstruct` : ./sconstruct.html Added: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/custom_rvalue.cpp =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/custom_rvalue.cpp (rev 0) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/custom_rvalue.cpp 2007-01-21 20:15:23 UTC (rev 876) @@ -0,0 +1,135 @@ +#include "boost/python.hpp" +#include "boost/python/object.hpp" //len function +#include "boost/python/ssize_t.hpp" //ssize_t type definition +#include "boost/python/detail/none.hpp" +#include "tuples.hpp" + +/** + * Custom r-value converter example. + * + * Use-case description. I and few other developers work on Python bindings for + * Ogre (http://ogre3d.org). The engine defines ColourValue class. This class + * describes colour using 4 components: red, green, blue and transparency. The + * class is used through the whole engine. One of the first features users ask + * is to add an ability to pass a tuple, instead of the "ColourValue" instance. + * This feature would allow them to write less code: + * + * x.do_smth( (1,2,3,4) ) + * + * instead of + * + * x.do_smth( ogre.ColourValue( 1,2,3,4 ) ) + * + * That's not all. They also wanted to be able to use ColourValue functionality. + * + * Solution. + * + * Fortunately, Boost.Python library provides enough functionality to implement + * users requirements - r-value converters. + * + * R-Value converters allows to register custom conversion from Python type to + * C++ type. The conversion will be handled by Boost.Python library automaticly + * "on-the-fly". + * + * The example introduces "colour_t" class and few testers. + * + **/ + + +struct colour_t{ + explicit colour_t( float red_=0.0, float green_=0.0, float blue_=0.0 ) + : red( red_ ), green( green_ ), blue( blue_ ) + {} + + bool operator==( const colour_t& other ) const{ + return red == other.red && green == other.green && blue == other.blue; + } + + float red, green, blue; +}; + +struct desktop_t{ + bool is_same_colour( const colour_t& colour ) const{ + return colour == background; + } + colour_t background; +}; + +namespace bpl = boost::python; + +struct pytuple2colour{ + + typedef boost::tuples::tuple< float, float, float> colour_tuple_type; + + typedef bpl::from_py_tuple< colour_tuple_type > converter_type; + + static void* convertible(PyObject* obj){ + return converter_type::convertible( obj ); + } + + static void + construct( PyObject* obj, bpl::converter::rvalue_from_python_stage1_data* data){ + typedef bpl::converter::rvalue_from_python_storage<colour_t> colour_storage_t; + colour_storage_t* the_storage = reinterpret_cast<colour_storage_t*>( data ); + void* memory_chunk = the_storage->storage.bytes; + + float red(0.0), green(0.0), blue(0.0); + boost::tuples::tie(red, green, blue) = converter_type::construct_c_tuple( obj ); + + colour_t* colour = new (memory_chunk) colour_t(red, green, blue); + data->convertible = memory_chunk; + } +}; + +void register_pytuple2colour(){ + bpl::converter::registry::push_back( &pytuple2colour::convertible + , &pytuple2colour::construct + , bpl::type_id<colour_t>() ); +} + + + +bool test_val_010( colour_t colour ){ + return colour == colour_t( 0, 1, 0); +} + +bool test_cref_000( const colour_t& colour ){ + return colour == colour_t( 0, 0, 0); +} + +bool test_ref_111( colour_t& colour ){ + return colour == colour_t( 1, 1, 1); +} + +bool test_ptr_101( colour_t* colour ){ + return colour && *colour == colour_t( 1, 0, 1); +} + +bool test_cptr_110( const colour_t* colour ){ + return colour && *colour == colour_t( 1, 1, 0); +} + +BOOST_PYTHON_MODULE( custom_rvalue ){ + bpl::class_< colour_t >( "colour_t" ) + .def( bpl::init< bpl::optional< float, float, float > >( + ( bpl::arg("red_")=0.0, bpl::arg("green_")=0.0, bpl::arg("blue_")=0.0 ) ) ) + .def_readwrite( "red", &colour_t::red ) + .def_readwrite( "green", &colour_t::green ) + .def_readwrite( "blue", &colour_t::blue ); + register_pytuple2colour(); + + bpl::class_< desktop_t >( "desktop_t" ) + //naive aproach that will not work - plain Python assignment + //.def_readwrite( "background", &desktop_t::background ) + //You should use properties to force the conversion + .add_property( "background" + , bpl::make_getter( &desktop_t::background ) + , bpl::make_setter( &desktop_t::background ) ) + .def( "is_same_colour", &desktop_t::is_same_colour ); + + bpl::def("test_val_010", &::test_val_010); + bpl::def("test_cref_000", &::test_cref_000); + bpl::def("test_ref_111", &::test_ref_111); + bpl::def("test_ptr_101", &::test_ptr_101); + bpl::def("test_cptr_110", &::test_cptr_110); +} Added: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/custom_rvalue.cpp.rest =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/custom_rvalue.cpp.rest (rev 0) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/custom_rvalue.cpp.rest 2007-01-21 20:15:23 UTC (rev 876) @@ -0,0 +1,3 @@ +.. code-block:: + :language: C++ + :source-file: ./custom_rvalue.cpp Modified: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/definition.rest =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/definition.rest 2007-01-21 07:17:10 UTC (rev 875) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/definition.rest 2007-01-21 20:15:23 UTC (rev 876) @@ -1,3 +1,3 @@ Boost.Python allows to define automatic conversion from\\to Python classes. While this is very, very useful functionality, the documentation for it does not -exist. The example will shed some light on "rvalue"\\"lvalue" converters. \ No newline at end of file +exist. This example will shed some light on "rvalue"\\"lvalue" converters. \ No newline at end of file Deleted: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/from_conversion.cpp =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/from_conversion.cpp 2007-01-21 07:17:10 UTC (rev 875) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/from_conversion.cpp 2007-01-21 20:15:23 UTC (rev 876) @@ -1,131 +0,0 @@ -#include "boost/python.hpp" -#include "boost/python/object.hpp" //len function -#include "boost/python/ssize_t.hpp" //ssize_t type definition -#include "boost/python/detail/none.hpp" - - -struct colour_t{ - explicit colour_t( float red_=0.0, float green_=0.0, float blue_=0.0 ) - : red( red_ ), green( green_ ), blue( blue_ ) - {} - - bool operator==( const colour_t& other ) const{ - return red == other.red && green == other.green && blue == other.blue; - } - - float red, green, blue; -}; - -struct image_t{ - colour_t background; - bool test_background( const colour_t& color )const{ - return color == background; - } -}; - -bool test_val_010( colour_t colour ){ - return colour == colour_t( 0, 1, 0); -} - -bool test_cref_000( const colour_t& colour ){ - return colour == colour_t( 0, 0, 0); -} - -bool test_ref_111( const colour_t& colour ){ - return colour == colour_t( 1, 1, 1); -} - -bool test_ptr_101( colour_t* colour ){ - return colour && *colour == colour_t( 1, 0, 1); -} - -bool test_cptr_110( const colour_t* colour ){ - return colour && *colour == colour_t( 1, 1, 0); -} - - -namespace bpl = boost::python; - -namespace colour_conversion{ - -struct from_tuple{ - - static void* convertible(PyObject* py_seq){ - if( !PySequence_Check( py_seq ) ){ - return 0; - } - - bpl::object seq = bpl::object( bpl::handle<>( bpl::borrowed( py_seq ) ) ); - bpl::ssize_t size = bpl::len( seq ); - if( 3 != size ){ - return 0; - } - for( bpl::ssize_t i = 0; i < 3; ++i ){ - //test that every item in sequence has int type - bpl::object item = seq[i]; - bpl::extract<float> type_checker( item ); - if( !type_checker.check() ){ - return 0; - } - } - return py_seq; - } - - static void - construct( PyObject* py_seq, bpl::converter::rvalue_from_python_stage1_data* data){ - if( !convertible( py_seq ) ){ - bpl::throw_error_already_set(); - } - - typedef bpl::converter::rvalue_from_python_storage<colour_t> colour_storage_t; - colour_storage_t* the_storage = reinterpret_cast<colour_storage_t*>( data ); - void* memory_chunk = the_storage->storage.bytes; - colour_t* colour = new (memory_chunk) colour_t(); - data->convertible = memory_chunk; - - bpl::object seq = bpl::object( bpl::handle<>( bpl::borrowed( py_seq ) ) ); - //Now I actually creates the object from the Python tuple - bpl::object tmp = seq[0]; - colour->red = bpl::extract< float >( tmp ); - tmp = seq[1]; - colour->green = bpl::extract< float >( tmp ); - tmp = seq[2]; - colour->blue = bpl::extract< float >( tmp ); - - } - -}; - -void register_conversion(){ - - bpl::converter::registry::push_back( &from_tuple::convertible - , &from_tuple::construct - , bpl::type_id<colour_t>() ); -} - -}//namespace colour_conversion - -BOOST_PYTHON_MODULE( from_conversion ){ - bpl::class_< colour_t >( "colour_t" ) - .def( bpl::init< bpl::optional< float, float, float > >( - ( bpl::arg("red_")=0.0, bpl::arg("green_")=0.0, bpl::arg("blue_")=0.0 ) ) ) - .def_readwrite( "red", &colour_t::red ) - .def_readwrite( "green", &colour_t::green ) - .def_readwrite( "blue", &colour_t::blue ); - colour_conversion::register_conversion(); - - bpl::class_< image_t >( "image_t" ) - //naive aproach that will not work - plain Python assignment - //.def_readwrite( "background", &image_t::background ) - //You should use properties to force the conversion - .add_property( "background" - , bpl::make_getter( &image_t::background ) - , bpl::make_setter( &image_t::background ) ) - .def( "test_background", &image_t::test_background ); - - bpl::def("test_val_010", &::test_val_010); - bpl::def("test_cref_000", &::test_cref_000); - bpl::def("test_ref_111", &::test_ref_111); - bpl::def("test_ptr_101", &::test_ptr_101); - bpl::def("test_cptr_110", &::test_cptr_110); -} Deleted: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/from_conversion.cpp.rest =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/from_conversion.cpp.rest 2007-01-21 07:17:10 UTC (rev 875) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/from_conversion.cpp.rest 2007-01-21 20:15:23 UTC (rev 876) @@ -1,3 +0,0 @@ -.. code-block:: - :language: C++ - :source-file: ./from_conversion.cpp Modified: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/sconstruct =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/sconstruct 2007-01-21 07:17:10 UTC (rev 875) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/sconstruct 2007-01-21 20:15:23 UTC (rev 876) @@ -1,6 +1,6 @@ #scons build script -SharedLibrary( target=r'auto_conversion' - , source=[ r'auto_conversion.cpp' ] +SharedLibrary( target=r'tuples' + , source=[ r'tuples_tester.cpp' ] , LIBS=[ r"boost_python" ] , LIBPATH=[ r"/home/roman/boost_cvs/bin",r"" ] , CPPPATH=[ r"/home/roman/boost_cvs" @@ -9,8 +9,8 @@ , SHLIBSUFFIX='.so' ) -SharedLibrary( target=r'from_conversion' - , source=[ r'from_conversion.cpp' ] +SharedLibrary( target=r'custom_rvalue' + , source=[ r'custom_rvalue.cpp' ] , LIBS=[ r"boost_python" ] , LIBPATH=[ r"/home/roman/boost_cvs/bin",r"" ] , CPPPATH=[ r"/home/roman/boost_cvs" Modified: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/test.py =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/test.py 2007-01-21 07:17:10 UTC (rev 875) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/test.py 2007-01-21 20:15:23 UTC (rev 876) @@ -1,51 +1,51 @@ import unittest -import auto_conversion as auto_conv -import from_conversion as from_conv +import tuples +import custom_rvalue -class auto_conversion_tester_t( unittest.TestCase ): +class tuplesersion_tester_t( unittest.TestCase ): def __init__( self, *args ): unittest.TestCase.__init__( self, *args ) - def test_auto( self ): - self.failUnless( (0,0,0) == auto_conv.record_ret_val_000() ) - self.failUnless( (1,0,1) == auto_conv.record_ret_val_101() ) - self.failUnless( (0,1,0) == auto_conv.record_ret_ref_010() ) - self.failUnlessRaises( TypeError, auto_conv.record_ret_ptr_110 ) - self.failUnless( auto_conv.test_record_val_000( (0,0,0) ) ) - self.failUnless( auto_conv.test_record_cref_010( (0,1,0) ) ) - self.failUnlessRaises( TypeError, auto_conv.test_record_ref_110, (1,1,0) ) - self.failUnlessRaises( TypeError, auto_conv.test_record_ptr_101, (1,0,1) ) - + def test_tuples( self ): + self.failUnless( (0,0,0) == tuples.triplet_ret_val_000() ) + self.failUnless( (1,0,1) == tuples.triplet_ret_val_101() ) + self.failUnless( (0,1,0) == tuples.triplet_ret_ref_010() ) + self.failUnlessRaises( TypeError, tuples.triplet_ret_ptr_110 ) + self.failUnless( tuples.test_triplet_val_000( (0,0,0) ) ) + self.failUnless( tuples.test_triplet_cref_010( (0,1,0) ) ) + self.failUnlessRaises( TypeError, tuples.test_triplet_ref_110, (1,1,0) ) + self.failUnlessRaises( TypeError, tuples.test_triplet_ptr_101, (1,0,1) ) + def test_from_sequence( self ): - self.failUnless( from_conv.test_val_010( (0,1,0) ) ) - self.failUnless( from_conv.test_cref_000( [0,0,0] ) ) - self.failUnless( from_conv.test_ref_111( [1,1,1] ) ) - self.failUnlessRaises( Exception, from_conv.test_ptr_101, (1,0,1) ) - self.failUnlessRaises( Exception, from_conv.test_cptr_110, (1,1,0) ) + self.failUnless( custom_rvalue.test_val_010( (0,1,0) ) ) + self.failUnless( custom_rvalue.test_cref_000( (0,0,0) ) ) + self.failUnlessRaises( Exception, custom_rvalue.test_ref_111, (1,1,1) ) + self.failUnlessRaises( Exception, custom_rvalue.test_ptr_101, (1,0,1) ) + self.failUnlessRaises( Exception, custom_rvalue.test_cptr_110, (1,1,0) ) def test_from_class( self ): - color = from_conv.colour_t - self.failUnless( from_conv.test_val_010( color(0,1,0) ) ) - self.failUnless( from_conv.test_cref_000( color(0,0,0) ) ) - self.failUnless( from_conv.test_ref_111( color(1,1,1) ) ) - self.failUnless( from_conv.test_ptr_101( color(1,0,1) ) ) - self.failUnless( from_conv.test_cptr_110( color(1,1,0) ) ) - + color = custom_rvalue.colour_t + self.failUnless( custom_rvalue.test_val_010( color(0,1,0) ) ) + self.failUnless( custom_rvalue.test_cref_000( color(0,0,0) ) ) + self.failUnless( custom_rvalue.test_ref_111( color(1,1,1) ) ) + self.failUnless( custom_rvalue.test_ptr_101( color(1,0,1) ) ) + self.failUnless( custom_rvalue.test_cptr_110( color(1,1,0) ) ) + def cmp_colours( self, c1, c2 ): return c1.red == c2.red and c1.green == c2.green and c1.blue == c2.blue - + def test_from_class_property( self ): - colour = from_conv.colour_t - image = from_conv.image_t() - self.failUnless( self.cmp_colours( image.background, colour() ) ) - image.background = (1,0,1) - self.failUnless( self.cmp_colours( image.background, colour(1,0,1) ) ) - self.failUnless( image.test_background( [1,0,1] ) ) - self.failUnless( image.test_background( colour(1,0,1 ) ) ) + colour = custom_rvalue.colour_t + desktop = custom_rvalue.desktop_t() + self.failUnless( self.cmp_colours( desktop.background, colour() ) ) + desktop.background = (1,0,1) + self.failUnless( self.cmp_colours( desktop.background, colour(1,0,1) ) ) + self.failUnless( desktop.is_same_colour( (1,0,1) ) ) + self.failUnless( desktop.is_same_colour( colour(1,0,1 ) ) ) def create_suite(): suite = unittest.TestSuite() - suite.addTest( unittest.makeSuite(auto_conversion_tester_t)) + suite.addTest( unittest.makeSuite(tuplesersion_tester_t)) return suite def run_suite(): Deleted: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuple_conversion.hpp =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuple_conversion.hpp 2007-01-21 07:17:10 UTC (rev 875) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuple_conversion.hpp 2007-01-21 20:15:23 UTC (rev 876) @@ -1,227 +0,0 @@ -#ifndef tuple_conversion_hpp -#define tuple_conversion_hpp - -#include "boost/python.hpp" -#include "boost/tuple/tuple.hpp" -#include "boost/python/object.hpp" //len function -#include <boost/mpl/int.hpp> -#include <boost/mpl/next.hpp> - -/** - * Converts boost::tuples::tuple<...> to\from Python tuple - * - * The conversion is done "on-the-fly", you should only register the conversion - * with your tuple classes. - * For example: - * - * typedef boost::tuples::tuple< int, double, std::string > triplet; - * boost::python::register_tuple< triplet >(); - * - * That's all. After this point conversion to\from next types will be handled - * by Boost.Python library: - * - * triplet - * const triplet - * const triplet& - * - * Implementation description. - * The conversion uses Boost.Python custom r-value converters. r-value converters - * is very powerful and undocumented feature of the library. The only documentation - * we have is http://boost.org/libs/python/doc/v2/faq.html#custom_string . - * - * The conversion consists from two parts: "to" and "from". - * - * "To" conversion - * The "to" part is pretty easy and well documented ( http://docs.python.org/api/api.html ). - * You should use Python C API to create an instance of a class and than you - * initialize the relevant members of the instance. - * - * "From" conversion - * Lets start from analyzing one of the use case Boost.Python library have to - * deal with: - * - * void do_smth( const triplet& arg ){...} - * - * In order to allow calling this function from Python, the library should keep - * parameter "arg" alive until the function returns. In other words, the library - * should provide instances life-time management. The provided interface is not - * ideal and could be improved. You have to implement two functions: - * - * void* convertible( PyObject* obj ) - * Checks whether the "obj" could be converted to an instance of the desired - * class. If true, the function should return "obj", otherwise NULL - * - * void construct( PyObject* obj, converter::rvalue_from_python_stage1_data* data) - * Constructs the instance of the desired class. This function will be called - * if and only if "convertible" function returned true. The first argument - * is Python object, which was passed as parameter to "convertible" function. - * The second object is some kind of memory allocator for one object. Basically - * it keeps a memory chunk. You will use the memory for object allocation. - * - * For some unclear for me reason, the library implements "C style Inheritance" - * ( http://www.embedded.com/97/fe29712.htm ). So, in order to create new - * object in the storage you have to cast to the "right" class: - * - * typedef converter::rvalue_from_python_storage<your_type_t> storage_t; - * storage_t* the_storage = reinterpret_cast<storage_t*>( data ); - * void* memory_chunk = the_storage->storage.bytes; - * - * "memory_chunk" points to the memory, where the instance will be allocated. - * - * In order to create object at specific location, you should use placement new - * operator: - * - * your_type_t* instance = new (memory_chunk) your_type_t(); - * - * Now, you can continue to initialize the instance. - * - * instance->set_xyz = read xyz from obj - * - * If "your_type_t" constructor requires some arguments, "read" the Python - * object before you call the constructor: - * - * xyz_type xyz = read xyz from obj - * your_type_t* instance = new (memory_chunk) your_type_t(xyz); - * - * Hint: - * In most case you don't really need\have to work with C Python API. Let - * Boost.Python library to do some work for you! - * - **/ - -namespace boost{ namespace python{ - -namespace details{ - -//Small helper function, introduced to allow short syntax for index incrementing -template< int index> -typename mpl::next< mpl::int_< index > >::type increment_index(){ - typedef typename mpl::next< mpl::int_< index > >::type next_index_type; - return next_index_type(); -} - -} - -template< class TTuple > -struct to_py_tuple{ - - typedef mpl::int_< tuples::length< TTuple >::value > length_type; - - static PyObject* convert(const TTuple& c_tuple){ - list values; - //add all c_tuple items to "values" list - convert_impl( c_tuple, values, mpl::int_< 0 >(), length_type() ); - //create Python tuple from the list - return incref( python::tuple( values ).ptr() ); - } - -private: - - template< int index, int length > - static void - convert_impl( const TTuple &c_tuple, list& values, mpl::int_< index >, mpl::int_< length > ) { - values.append( c_tuple.template get< index >() ); - convert_impl( c_tuple, values, details::increment_index<index>(), length_type() ); - } - - template< int length > - static void - convert_impl( const TTuple&, list& values, mpl::int_< length >, mpl::int_< length >) - {} - -}; - - -template< class TTuple> -struct from_py_tuple{ - - typedef mpl::int_< tuples::length< TTuple >::value > length_type; - - static void* - convertible(PyObject* py_obj){ - - if( !PyTuple_Check( py_obj ) ){ - return 0; - } - - python::tuple py_tuple( handle<>( borrowed( py_obj ) ) ); - if( tuples::length< TTuple >::value != len( py_tuple ) ){ - return 0; - } - - if( convertible_impl( py_tuple, mpl::int_< 0 >(), length_type() ) ){ - return py_obj; - } - else{ - return 0; - } - } - - static void - construct( PyObject* py_obj, converter::rvalue_from_python_stage1_data* data){ - typedef converter::rvalue_from_python_storage<TTuple> storage_t; - storage_t* the_storage = reinterpret_cast<storage_t*>( data ); - void* memory_chunk = the_storage->storage.bytes; - TTuple* c_tuple = new (memory_chunk) TTuple(); - data->convertible = memory_chunk; - - python::tuple py_tuple( handle<>( borrowed( py_obj ) ) ); - construct_impl( py_tuple, *c_tuple, mpl::int_< 0 >(), length_type() ); - } - -private: - - template< int index, int length > - static bool - convertible_impl( const python::tuple& py_tuple, mpl::int_< index >, mpl::int_< length > ){ - - typedef typename tuples::element< index, TTuple>::type element_type; - - object element = py_tuple[index]; - extract<element_type> type_checker( element ); - if( !type_checker.check() ){ - return false; - } - else{ - return convertible_impl( py_tuple, details::increment_index<index>(), length_type() ); - } - } - - template< int length > - static bool - convertible_impl( const python::tuple& py_tuple, mpl::int_< length >, mpl::int_< length > ){ - return true; - } - - template< int index, int length > - static void - construct_impl( const python::tuple& py_tuple, TTuple& c_tuple, mpl::int_< index >, mpl::int_< length > ){ - - typedef typename tuples::element< index, TTuple>::type element_type; - - object element = py_tuple[index]; - c_tuple.template get< index >() = extract<element_type>( element ); - - construct_impl( py_tuple, c_tuple, details::increment_index<index>(), length_type() ); - } - - template< int length > - static void - construct_impl( const python::tuple& py_tuple, TTuple& c_tuple, mpl::int_< length >, mpl::int_< length > ) - {} - -}; - -template< class TTuple> -void register_tuple(){ - - to_python_converter< TTuple, to_py_tuple<TTuple> >(); - - converter::registry::push_back( &from_py_tuple<TTuple>::convertible - , &from_py_tuple<TTuple>::construct - , type_id<TTuple>() ); -}; - -} } //boost::python - -#endif//tuple_conversion_hpp Deleted: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuple_conversion.hpp.rest =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuple_conversion.hpp.rest 2007-01-21 07:17:10 UTC (rev 875) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuple_conversion.hpp.rest 2007-01-21 20:15:23 UTC (rev 876) @@ -1,3 +0,0 @@ -.. code-block:: - :language: C++ - :source-file: ./tuple_conversion.hpp Added: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuples.hpp =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuples.hpp (rev 0) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuples.hpp 2007-01-21 20:15:23 UTC (rev 876) @@ -0,0 +1,241 @@ +#ifndef TUPLES_HPP_16_JAN_2007 +#define TUPLES_HPP_16_JAN_2007 + +#include "boost/python.hpp" +#include "boost/tuple/tuple.hpp" +#include "boost/python/object.hpp" //len function +#include <boost/mpl/int.hpp> +#include <boost/mpl/next.hpp> + +/** + * Converts boost::tuples::tuple<...> to\from Python tuple + * + * The conversion is done "on-the-fly", you should only register the conversion + * with your tuple classes. + * For example: + * + * typedef boost::tuples::tuple< int, double, std::string > triplet; + * boost::python::register_tuple< triplet >(); + * + * That's all. After this point conversion to\from next types will be handled + * by Boost.Python library: + * + * triplet + * triplet& ( return type only ) + * const triplet + * const triplet& + * + * Implementation description. + * The conversion uses Boost.Python custom r-value converters. r-value converters + * is very powerful and undocumented feature of the library. The only documentation + * we have is http://boost.org/libs/python/doc/v2/faq.html#custom_string . + * + * The conversion consists from two parts: "to" and "from". + * + * "To" conversion + * The "to" part is pretty easy and well documented ( http://docs.python.org/api/api.html ). + * You should use Python C API to create an instance of a class and than you + * initialize the relevant members of the instance. + * + * "From" conversion + * Lets start from analyzing one of the use case Boost.Python library have to + * deal with: + * + * void do_smth( const triplet& arg ){...} + * + * In order to allow calling this function from Python, the library should keep + * parameter "arg" alive until the function returns. In other words, the library + * should provide instances life-time management. The provided interface is not + * ideal and could be improved. You have to implement two functions: + * + * void* convertible( PyObject* obj ) + * Checks whether the "obj" could be converted to an instance of the desired + * class. If true, the function should return "obj", otherwise NULL + * + * void construct( PyObject* obj, converter::rvalue_from_python_stage1_data* data) + * Constructs the instance of the desired class. This function will be called + * if and only if "convertible" function returned true. The first argument + * is Python object, which was passed as parameter to "convertible" function. + * The second object is some kind of memory allocator for one object. Basically + * it keeps a memory chunk. You will use the memory for object allocation. + * + * For some unclear for me reason, the library implements "C style Inheritance" + * ( http://www.embedded.com/97/fe29712.htm ). So, in order to create new + * object in the storage you have to cast to the "right" class: + * + * typedef converter::rvalue_from_python_storage<your_type_t> storage_t; + * storage_t* the_storage = reinterpret_cast<storage_t*>( data ); + * void* memory_chunk = the_storage->storage.bytes; + * + * "memory_chunk" points to the memory, where the instance will be allocated. + * + * In order to create object at specific location, you should use placement new + * operator: + * + * your_type_t* instance = new (memory_chunk) your_type_t(); + * + * Now, you can continue to initialize the instance. + * + * instance->set_xyz = read xyz from obj + * + * If "your_type_t" constructor requires some arguments, "read" the Python + * object before you call the constructor: + * + * xyz_type xyz = read xyz from obj + * your_type_t* instance = new (memory_chunk) your_type_t(xyz); + * + * Hint: + * In most case you don't really need\have to work with C Python API. Let + * Boost.Python library to do some work for you! + * + **/ + +namespace boost{ namespace python{ + +namespace details{ + +//Small helper function, introduced to allow short syntax for index incrementing +template< int index> +typename mpl::next< mpl::int_< index > >::type increment_index(){ + typedef typename mpl::next< mpl::int_< index > >::type next_index_type; + return next_index_type(); +} + +} + +template< class TTuple > +struct to_py_tuple{ + + typedef mpl::int_< tuples::length< TTuple >::value > length_type; + + static PyObject* convert(const TTuple& c_tuple){ + list values; + //add all c_tuple items to "values" list + convert_impl( c_tuple, values, mpl::int_< 0 >(), length_type() ); + //create Python tuple from the list + return incref( python::tuple( values ).ptr() ); + } + +private: + + template< int index, int length > + static void + convert_impl( const TTuple &c_tuple, list& values, mpl::int_< index >, mpl::int_< length > ) { + values.append( c_tuple.template get< index >() ); + convert_impl( c_tuple, values, details::increment_index<index>(), length_type() ); + } + + template< int length > + static void + convert_impl( const TTuple&, list& values, mpl::int_< length >, mpl::int_< length >) + {} + +}; + + +template< class TTuple> +struct from_py_tuple{ + + typedef TTuple tuple_type; + + typedef mpl::int_< tuples::length< TTuple >::value > length_type; + + static void* + convertible(PyObject* py_obj){ + + if( !PyTuple_Check( py_obj ) ){ + return 0; + } + + python::tuple py_tuple( handle<>( borrowed( py_obj ) ) ); + if( tuples::length< TTuple >::value != len( py_tuple ) ){ + return 0; + } + + if( convertible_impl( py_tuple, mpl::int_< 0 >(), length_type() ) ){ + return py_obj; + } + else{ + return 0; + } + } + + static void + construct( PyObject* py_obj, converter::rvalue_from_python_stage1_data* data){ + typedef converter::rvalue_from_python_storage<TTuple> storage_t; + storage_t* the_storage = reinterpret_cast<storage_t*>( data ); + void* memory_chunk = the_storage->storage.bytes; + TTuple* c_tuple = new (memory_chunk) TTuple(); + data->convertible = memory_chunk; + + python::tuple py_tuple( handle<>( borrowed( py_obj ) ) ); + construct_impl( py_tuple, *c_tuple, mpl::int_< 0 >(), length_type() ); + } + + static TTuple construct_c_tuple( PyObject* py_obj ){ + if( !convertible( py_obj ) ){ + throw std::runtime_error( "Unable to construct boost::tuples::tuple from Python object!" ); + } + TTuple c_tuple; + python::tuple py_tuple( handle<>( borrowed( py_obj ) ) ); + construct_impl( py_tuple, c_tuple, mpl::int_< 0 >(), length_type() ); + return c_tuple; + } + +private: + + template< int index, int length > + static bool + convertible_impl( const python::tuple& py_tuple, mpl::int_< index >, mpl::int_< length > ){ + + typedef typename tuples::element< index, TTuple>::type element_type; + + object element = py_tuple[index]; + extract<element_type> type_checker( element ); + if( !type_checker.check() ){ + return false; + } + else{ + return convertible_impl( py_tuple, details::increment_index<index>(), length_type() ); + } + } + + template< int length > + static bool + convertible_impl( const python::tuple& py_tuple, mpl::int_< length >, mpl::int_< length > ){ + return true; + } + + template< int index, int length > + static void + construct_impl( const python::tuple& py_tuple, TTuple& c_tuple, mpl::int_< index >, mpl::int_< length > ){ + + typedef typename tuples::element< index, TTuple>::type element_type; + + object element = py_tuple[index]; + c_tuple.template get< index >() = extract<element_type>( element ); + + construct_impl( py_tuple, c_tuple, details::increment_index<index>(), length_type() ); + } + + template< int length > + static void + construct_impl( const python::tuple& py_tuple, TTuple& c_tuple, mpl::int_< length >, mpl::int_< length > ) + {} + +}; + +template< class TTuple> +void register_tuple(){ + + to_python_converter< TTuple, to_py_tuple<TTuple> >(); + + converter::registry::push_back( &from_py_tuple<TTuple>::convertible + , &from_py_tuple<TTuple>::construct + , type_id<TTuple>() ); +}; + +} } //boost::python + +#endif//TUPLES_HPP_16_JAN_2007 + Added: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuples.hpp.rest =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuples.hpp.rest (rev 0) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuples.hpp.rest 2007-01-21 20:15:23 UTC (rev 876) @@ -0,0 +1,3 @@ +.. code-block:: + :language: C++ + :source-file: ./tuples.hpp Added: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuples_tester.cpp =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuples_tester.cpp (rev 0) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuples_tester.cpp 2007-01-21 20:15:23 UTC (rev 876) @@ -0,0 +1,72 @@ +#include "boost/python.hpp" +#include "boost/tuple/tuple_comparison.hpp" +#include "tuples.hpp" + +/** + * Content: + * * few testers for boost::tuples::tuple<...> to\from Python tuple conversion + * functionality + * + * * example of custom r-value converter for a registered class + * + * + **/ + +typedef boost::tuple< int, int, int > triplet_type; + +triplet_type triplet_ret_val_000() { + return triplet_type(0,0,0); +} + +triplet_type triplet_ret_val_101() { + return triplet_type(1,0,1); +} + +triplet_type& triplet_ret_ref_010(){ + static triplet_type pt( 0,1,0 ); + return pt; +} + +triplet_type* triplet_ret_ptr_110(){ + static triplet_type pt( 1,1,0 ); + return &pt; +} + +bool test_triplet_val_000( triplet_type pt ){ + return pt == triplet_type( 0,0,0 ); +} + +bool test_triplet_cref_010( const triplet_type& pt ){ + return pt == triplet_type( 0,1,0 ); +} + +bool test_triplet_ref_110( triplet_type& pt ){ + return pt == triplet_type( 1,1,0 ); +} + +bool test_triplet_ptr_101( triplet_type* pt ){ + return pt && *pt == triplet_type( 1,0,1 ); +} + + +namespace bpl = boost::python; + +BOOST_PYTHON_MODULE( tuples ){ + + bpl::register_tuple< triplet_type >(); + + bpl::def("triplet_ret_val_000", &::triplet_ret_val_000); + bpl::def("triplet_ret_val_101", &::triplet_ret_val_101); + bpl::def("triplet_ret_ref_010" + , &::triplet_ret_ref_010 + , bpl::return_value_policy<bpl:: copy_non_const_reference>() ); + bpl::def( "triplet_ret_ptr_110" + , &::triplet_ret_ptr_110 + , bpl::return_value_policy<bpl::return_by_value>() ); + bpl::def("test_triplet_val_000", &::test_triplet_val_000); + bpl::def("test_triplet_cref_010", &::test_triplet_cref_010); + bpl::def("test_triplet_ref_110", &::test_triplet_ref_110); + bpl::def("test_triplet_ptr_101", &::test_triplet_ptr_101); + +} + Added: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuples_tester.cpp.rest =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuples_tester.cpp.rest (rev 0) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuples_tester.cpp.rest 2007-01-21 20:15:23 UTC (rev 876) @@ -0,0 +1,3 @@ +.. code-block:: + :language: C++ + :source-file: ./tuples_tester.cpp Modified: pyplusplus_dev/docs/troubleshooting_guide/shared_ptr/shared_ptr.rest =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/shared_ptr/shared_ptr.rest 2007-01-21 07:17:10 UTC (rev 875) +++ pyplusplus_dev/docs/troubleshooting_guide/shared_ptr/shared_ptr.rest 2007-01-21 20:15:23 UTC (rev 876) @@ -86,9 +86,11 @@ Download -------- -https://sourceforge.net/project/showfiles.php?group_id=118209 +`shared_ptr.zip`_ +.. _`shared_ptr.zip` : ./shared_ptr.zip + .. _`Py++` : ./../pyplusplus.html .. _`pygccxml` : http://www.language-binding.net/pygccxml/pygccxml.html .. _`SourceForge`: http://sourceforge.net/index.php Added: pyplusplus_dev/docs/troubleshooting_guide/shared_ptr/shared_ptr.zip =================================================================== (Binary files differ) Property changes on: pyplusplus_dev/docs/troubleshooting_guide/shared_ptr/shared_ptr.zip ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: pyplusplus_dev/docs/troubleshooting_guide/smart_ptrs/smart_ptrs.zip =================================================================== (Binary files differ) Property changes on: pyplusplus_dev/docs/troubleshooting_guide/smart_ptrs/smart_ptrs.zip ___________________________________________________________________ Name: svn:mime-type + application/octet-stream This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-01-21 07:17:10
|
Revision: 875 http://svn.sourceforge.net/pygccxml/?rev=875&view=rev Author: roman_yakovenko Date: 2007-01-20 23:17:10 -0800 (Sat, 20 Jan 2007) Log Message: ----------- change deallocate to deallocate_array Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_repository/call_policies.py Modified: pyplusplus_dev/pyplusplus/code_repository/call_policies.py =================================================================== --- pyplusplus_dev/pyplusplus/code_repository/call_policies.py 2007-01-20 20:30:38 UTC (rev 874) +++ pyplusplus_dev/pyplusplus/code_repository/call_policies.py 2007-01-21 07:17:10 UTC (rev 875) @@ -31,12 +31,12 @@ struct none{ template< typename T> - static void deallocate(T*){} + static void deallocate_array(T*){} }; struct delete_{ template< typename T> - static void deallocate(T* arr){ + static void deallocate_array(T* arr){ delete[] arr; } }; @@ -111,7 +111,7 @@ for( unsigned int i = 0; i < size; ++i ){ list_.append( make_object< CallPolicies>( arr[i] ) ); } - MemoryManager::deallocate( arr ); + MemoryManager::deallocate_array( arr ); return bpl::incref( bpl::tuple( list_ ).ptr() ); } }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-01-20 20:30:38
|
Revision: 874 http://svn.sourceforge.net/pygccxml/?rev=874&view=rev Author: roman_yakovenko Date: 2007-01-20 12:30:38 -0800 (Sat, 20 Jan 2007) Log Message: ----------- adding new call policy for arrays Modified Paths: -------------- pyplusplus_dev/unittests/call_policies_tester.py pyplusplus_dev/unittests/data/call_policies_to_be_exported.hpp Modified: pyplusplus_dev/unittests/call_policies_tester.py =================================================================== --- pyplusplus_dev/unittests/call_policies_tester.py 2007-01-20 20:30:16 UTC (rev 873) +++ pyplusplus_dev/unittests/call_policies_tester.py 2007-01-20 20:30:38 UTC (rev 874) @@ -33,6 +33,9 @@ mb.calldef( 'get_fundamental_ptr_value_null' ).call_policies \ = call_policies.return_value_policy( call_policies.return_pointee_value ) + mb.calldef( 'create_arr_3' ).call_policies \ + = call_policies.convert_array_to_tuple( 3, call_policies.memory_managers.delete_ ) + def run_tests(self, module): self.failUnless( module.compare( module.my_address() ) ) @@ -56,6 +59,11 @@ module.get_impl_details() module.get_opaque() + + x = module.arrays() + for i in range( 4 ): + arr3 = x.create_arr_3() + self.failUnless( arr3 == (0,1,2) ) def create_suite(): suite = unittest.TestSuite() Modified: pyplusplus_dev/unittests/data/call_policies_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/call_policies_to_be_exported.hpp 2007-01-20 20:30:16 UTC (rev 873) +++ pyplusplus_dev/unittests/data/call_policies_to_be_exported.hpp 2007-01-20 20:30:38 UTC (rev 874) @@ -72,9 +72,18 @@ return (float*)(0); } - } +struct arrays{ + int* create_arr_3(){ + int* arr3 = new int[3]; + for( int i = 0 ; i < 3; ++i ){ + arr3[i] = i; + } + return arr3; + } +}; + } #endif//__call_policies_to_be_exported_hpp__ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-01-20 20:30:16
|
Revision: 873 http://svn.sourceforge.net/pygccxml/?rev=873&view=rev Author: roman_yakovenko Date: 2007-01-20 12:30:16 -0800 (Sat, 20 Jan 2007) Log Message: ----------- adding new call policy for arrays Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_repository/call_policies.py pyplusplus_dev/pyplusplus/decl_wrappers/__init__.py pyplusplus_dev/pyplusplus/decl_wrappers/call_policies.py pyplusplus_dev/pyplusplus/module_builder/call_policies.py Modified: pyplusplus_dev/pyplusplus/code_repository/call_policies.py =================================================================== --- pyplusplus_dev/pyplusplus/code_repository/call_policies.py 2007-01-19 19:52:24 UTC (rev 872) +++ pyplusplus_dev/pyplusplus/code_repository/call_policies.py 2007-01-20 20:30:16 UTC (rev 873) @@ -27,6 +27,23 @@ namespace bpl = boost::python; +namespace memory_managers{ + + struct none{ + template< typename T> + static void deallocate(T*){} + }; + + struct delete_{ + template< typename T> + static void deallocate(T* arr){ + delete[] arr; + } + }; + +}/*memory_managers*/ + + namespace detail{ struct make_value_holder{ @@ -78,6 +95,44 @@ return bpl::object( bpl::handle<>( rc( x ) ) ); } +namespace arrays{ + +namespace details{ + +template< unsigned int size, typename MemoryManager, typename CallPolicies> +struct as_tuple_impl{ + + template <class U> + inline PyObject* operator()(U const* arr) const{ + if( !arr ){ + return bpl::incref( bpl::tuple().ptr() ); + } + bpl::list list_; + for( unsigned int i = 0; i < size; ++i ){ + list_.append( make_object< CallPolicies>( arr[i] ) ); + } + MemoryManager::deallocate( arr ); + return bpl::incref( bpl::tuple( list_ ).ptr() ); + } +}; + +} + +template< unsigned int size, typename MemoryManager, typename MakeObjectCallPolicies=bpl::default_call_policies> +struct as_tuple{ +public: + + template <class T> + struct apply{ + BOOST_STATIC_CONSTANT( bool, ok = boost::is_pointer<T>::value ); + typedef details::as_tuple_impl<size, MemoryManager, MakeObjectCallPolicies> type; + }; + +}; + +} /*arrays*/ + + } /*pyplusplus*/ } /*call_policies*/ Modified: pyplusplus_dev/pyplusplus/decl_wrappers/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/__init__.py 2007-01-19 19:52:24 UTC (rev 872) +++ pyplusplus_dev/pyplusplus/decl_wrappers/__init__.py 2007-01-20 20:30:16 UTC (rev 873) @@ -85,6 +85,11 @@ from call_policies import return_pointee_value from call_policies import is_return_opaque_pointer_policy from call_policies import is_return_pointee_value_policy +from call_policies import custom_call_policies_t +from call_policies import custom_call_policies +from call_policies import convert_array_to_tuple_t +from call_policies import convert_array_to_tuple +from call_policies import memory_managers from decl_wrapper_printer import decl_wrapper_printer_t from decl_wrapper_printer import print_declarations Modified: pyplusplus_dev/pyplusplus/decl_wrappers/call_policies.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/call_policies.py 2007-01-19 19:52:24 UTC (rev 872) +++ pyplusplus_dev/pyplusplus/decl_wrappers/call_policies.py 2007-01-20 20:30:16 UTC (rev 873) @@ -231,3 +231,75 @@ return isinstance( policy, return_value_policy_t ) \ and policy.result_converter_generator == return_pointee_value + +class custom_call_policies_t(call_policy_t): + """implementation for user defined call policies""" + def __init__( self, call_policies ): + call_policy_t.__init__( self ) + self.__call_policies = call_policies + + def _create_impl(self, function_creator ): + return str( self.__call_policies ) + + def __str__(self): + return 'custom call policies' + +def custom_call_policies(call_policies): + """create custom\\user defined call policies""" + return custom_call_policies_t(call_policies) + +class memory_managers: + none = 'none' + delete_ = 'delete_' + all = [ none, delete_ ] + + @staticmethod + def create( manager, function_creator=None): + mem_manager = 'pyplusplus::call_policies::memory_managers::' + manager + if function_creator: + mem_manager = algorithm.create_identifier( function_creator, mem_manager ) + return mem_manager + +class convert_array_to_tuple_t( compound_policy_t ): + def __init__( self, array_size, memory_manager, make_object_call_policies=None, base=None): + compound_policy_t.__init__( self, base ) + self._array_size = array_size + self._memory_manager = memory_manager + self._make_objec_call_policies = make_object_call_policies + + def _get_array_size( self ): + return self._array_size + def _set_array_size( self, new_array_size): + self._array_size = new_array_size + array_size = property( _get_array_size, _set_array_size ) + + def _get_memory_manager( self ): + return self._memory_manager + def _set_memory_manager( self, new_memory_manager): + self._memory_manager = new_memory_manager + memory_manager = property( _get_memory_manager, _set_memory_manager ) + + def _get_make_objec_call_policies( self ): + if None is self._make_objec_call_policies: + self._make_objec_call_policies = default_call_policies() + return self._make_objec_call_policies + def _set_make_objec_call_policies( self, new_make_objec_call_policies): + self._make_objec_call_policies = new_make_objec_call_policies + make_objec_call_policies = property( _get_make_objec_call_policies, _set_make_objec_call_policies ) + + + def _get_name(self, function_creator): + return '::boost::python::return_value_policy' + + 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 convert_array_to_tuple( array_size, memory_manager, make_object_call_policies=None, base=None ): + return convert_array_to_tuple_t( array_size, memory_manager, make_object_call_policies, base ) \ No newline at end of file Modified: pyplusplus_dev/pyplusplus/module_builder/call_policies.py =================================================================== --- pyplusplus_dev/pyplusplus/module_builder/call_policies.py 2007-01-19 19:52:24 UTC (rev 872) +++ pyplusplus_dev/pyplusplus/module_builder/call_policies.py 2007-01-20 20:30:16 UTC (rev 873) @@ -17,4 +17,7 @@ from pyplusplus.decl_wrappers import return_by_value from pyplusplus.decl_wrappers import return_opaque_pointer from pyplusplus.decl_wrappers import return_value_policy -from pyplusplus.decl_wrappers import return_pointee_value \ No newline at end of file +from pyplusplus.decl_wrappers import return_pointee_value +from pyplusplus.decl_wrappers import custom_call_policies +from pyplusplus.decl_wrappers import convert_array_to_tuple +from pyplusplus.decl_wrappers import memory_managers This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-01-19 19:53:10
|
Revision: 872 http://svn.sourceforge.net/pygccxml/?rev=872&view=rev Author: roman_yakovenko Date: 2007-01-19 11:52:24 -0800 (Fri, 19 Jan 2007) Log Message: ----------- adding new warnings for X** types in functions Modified Paths: -------------- pyplusplus_dev/unittests/data/free_function_ignore_bug_to_be_exported.hpp pyplusplus_dev/unittests/free_function_ignore_bug_tester.py Modified: pyplusplus_dev/unittests/data/free_function_ignore_bug_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/free_function_ignore_bug_to_be_exported.hpp 2007-01-19 19:51:51 UTC (rev 871) +++ pyplusplus_dev/unittests/data/free_function_ignore_bug_to_be_exported.hpp 2007-01-19 19:52:24 UTC (rev 872) @@ -14,6 +14,14 @@ inline void do_nothing(int, int){} +struct some_dummy_struct_t{}; + +some_dummy_struct_t** return_some_dummy_struct_ptr_ptr(){ + return 0; } +void fill_some_dummy_struct_ptr_ptr(some_dummy_struct_t**){} + +} + #endif//__user_text_to_be_exported_hpp__ Modified: pyplusplus_dev/unittests/free_function_ignore_bug_tester.py =================================================================== --- pyplusplus_dev/unittests/free_function_ignore_bug_tester.py 2007-01-19 19:51:51 UTC (rev 871) +++ pyplusplus_dev/unittests/free_function_ignore_bug_tester.py 2007-01-19 19:52:24 UTC (rev 872) @@ -20,10 +20,19 @@ def customize(self, mb ): do_nothing = mb.free_functions( 'do_nothing' ) do_nothing.exclude() + + x = mb.free_fun( 'fill_some_dummy_struct_ptr_ptr' ) + self.failUnless( '1051' in ''.join( x.readme() ) ) + x.exclude() + x = mb.free_fun( 'return_some_dummy_struct_ptr_ptr' ) + self.failUnless( '1050' in ''.join( x.readme() ) ) + x.exclude() + + mb.build_code_creator(self.EXTENSION_NAME) code = mb.code_creator.create() self.failUnless( 'do_nothing' not in code ) - + def run_tests(self, module): pass This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-01-19 19:51:51
|
Revision: 871 http://svn.sourceforge.net/pygccxml/?rev=871&view=rev Author: roman_yakovenko Date: 2007-01-19 11:51:51 -0800 (Fri, 19 Jan 2007) Log Message: ----------- adding new warnings for X** types in functions Modified Paths: -------------- pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py pyplusplus_dev/pyplusplus/messages/warnings_.py Modified: pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2007-01-18 06:24:12 UTC (rev 870) +++ pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2007-01-19 19:51:51 UTC (rev 871) @@ -157,6 +157,13 @@ return self._exportable_impl_derived() def _readme_impl( self ): + def is_double_ptr( type_ ): + #check for X** + if not declarations.is_pointer( type_ ): + return False + base = declarations.remove_pointer( type_ ) + return declarations.is_pointer( base ) + def suspicious_type( type_ ): if not declarations.is_reference( type_ ): return False @@ -180,10 +187,15 @@ if suspicious_type( self.return_type ) and None is self.call_policies: msgs.append( messages.W1008 ) + + if is_double_ptr( self.return_type ) and None is self.call_policies: + msgs.append( messages.W1050 % str(self.return_type) ) for index, arg in enumerate( self.arguments ): if suspicious_type( arg.type ): msgs.append( messages.W1009 % ( arg.name, index ) ) + if is_double_ptr( arg.type ): + msgs.append( messages.W1051 % ( arg.name, index, str(arg.type) ) ) if False == self.overridable: msgs.append( self._non_overridable_reason) Modified: pyplusplus_dev/pyplusplus/messages/warnings_.py =================================================================== --- pyplusplus_dev/pyplusplus/messages/warnings_.py 2007-01-18 06:24:12 UTC (rev 870) +++ pyplusplus_dev/pyplusplus/messages/warnings_.py 2007-01-19 19:51:51 UTC (rev 871) @@ -148,6 +148,14 @@ W1049 = 'This method could not be overriden in Python - method returns reference ' \ 'to local variable!' +W1050 = 'The function returns "%s" type. You have to specify a call policies.' + + +W1051 = 'The function takes as argument (name=%s, pos=%d) "%s" type. ' \ + 'You have to specify a call policies or to use "Function Transformation" ' \ + 'functionality.' + + warnings = globals() for identifier, explanation in warnings.items(): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-01-18 06:24:13
|
Revision: 870 http://svn.sourceforge.net/pygccxml/?rev=870&view=rev Author: roman_yakovenko Date: 2007-01-17 22:24:12 -0800 (Wed, 17 Jan 2007) Log Message: ----------- fixing spell errors Modified Paths: -------------- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuple_conversion.hpp Modified: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuple_conversion.hpp =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuple_conversion.hpp 2007-01-17 20:00:35 UTC (rev 869) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuple_conversion.hpp 2007-01-18 06:24:12 UTC (rev 870) @@ -37,14 +37,14 @@ * initialize the relevant members of the instance. * * "From" conversion - * Lets start from analizing one of the use case Boost.Python library have to + * Lets start from analyzing one of the use case Boost.Python library have to * deal with: * * void do_smth( const triplet& arg ){...} * - * In order to allow to call this function from Python, the library should keep - * parameter "arg" alive untill the function returns. In other words, the library - * should provide instances life-time managment. The provided interface is not + * In order to allow calling this function from Python, the library should keep + * parameter "arg" alive until the function returns. In other words, the library + * should provide instances life-time management. The provided interface is not * ideal and could be improved. You have to implement two functions: * * void* convertible( PyObject* obj ) @@ -58,7 +58,7 @@ * The second object is some kind of memory allocator for one object. Basically * it keeps a memory chunk. You will use the memory for object allocation. * - * For some unclear for me reason, the library implements "C style Inheritance" + * For some unclear for me reason, the library implements "C style Inheritance" * ( http://www.embedded.com/97/fe29712.htm ). So, in order to create new * object in the storage you have to cast to the "right" class: * @@ -73,10 +73,20 @@ * * your_type_t* instance = new (memory_chunk) your_type_t(); * - * Now, you can continue to initialize the instance. If "your_type_t" constructor - * requires some arguments, well just "parse" the Python object before you call - * the constructor. + * Now, you can continue to initialize the instance. * + * instance->set_xyz = read xyz from obj + * + * If "your_type_t" constructor requires some arguments, "read" the Python + * object before you call the constructor: + * + * xyz_type xyz = read xyz from obj + * your_type_t* instance = new (memory_chunk) your_type_t(xyz); + * + * Hint: + * In most case you don't really need\have to work with C Python API. Let + * Boost.Python library to do some work for you! + * **/ namespace boost{ namespace python{ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-01-17 20:01:27
|
Revision: 869 http://svn.sourceforge.net/pygccxml/?rev=869&view=rev Author: roman_yakovenko Date: 2007-01-17 12:00:35 -0800 (Wed, 17 Jan 2007) Log Message: ----------- improving documentation Modified Paths: -------------- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuple_conversion.hpp Modified: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuple_conversion.hpp =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuple_conversion.hpp 2007-01-16 10:08:28 UTC (rev 868) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuple_conversion.hpp 2007-01-17 20:00:35 UTC (rev 869) @@ -7,23 +7,78 @@ #include <boost/mpl/int.hpp> #include <boost/mpl/next.hpp> -/******************************************************************************* - -This file contains conversion from boost::tuples::tuple class instantiation to -Python tuple and vice versa. The conversion uses Boost.Python custom r-value -converters. Custom r-value converters allows Boost.Python library to handle -[from|to] [C++|Python] variables conversion "on-the-fly". For example: +/** + * Converts boost::tuples::tuple<...> to\from Python tuple + * + * The conversion is done "on-the-fly", you should only register the conversion + * with your tuple classes. + * For example: + * + * typedef boost::tuples::tuple< int, double, std::string > triplet; + * boost::python::register_tuple< triplet >(); + * + * That's all. After this point conversion to\from next types will be handled + * by Boost.Python library: + * + * triplet + * const triplet + * const triplet& + * + * Implementation description. + * The conversion uses Boost.Python custom r-value converters. r-value converters + * is very powerful and undocumented feature of the library. The only documentation + * we have is http://boost.org/libs/python/doc/v2/faq.html#custom_string . + * + * The conversion consists from two parts: "to" and "from". + * + * "To" conversion + * The "to" part is pretty easy and well documented ( http://docs.python.org/api/api.html ). + * You should use Python C API to create an instance of a class and than you + * initialize the relevant members of the instance. + * + * "From" conversion + * Lets start from analizing one of the use case Boost.Python library have to + * deal with: + * + * void do_smth( const triplet& arg ){...} + * + * In order to allow to call this function from Python, the library should keep + * parameter "arg" alive untill the function returns. In other words, the library + * should provide instances life-time managment. The provided interface is not + * ideal and could be improved. You have to implement two functions: + * + * void* convertible( PyObject* obj ) + * Checks whether the "obj" could be converted to an instance of the desired + * class. If true, the function should return "obj", otherwise NULL + * + * void construct( PyObject* obj, converter::rvalue_from_python_stage1_data* data) + * Constructs the instance of the desired class. This function will be called + * if and only if "convertible" function returned true. The first argument + * is Python object, which was passed as parameter to "convertible" function. + * The second object is some kind of memory allocator for one object. Basically + * it keeps a memory chunk. You will use the memory for object allocation. + * + * For some unclear for me reason, the library implements "C style Inheritance" + * ( http://www.embedded.com/97/fe29712.htm ). So, in order to create new + * object in the storage you have to cast to the "right" class: + * + * typedef converter::rvalue_from_python_storage<your_type_t> storage_t; + * storage_t* the_storage = reinterpret_cast<storage_t*>( data ); + * void* memory_chunk = the_storage->storage.bytes; + * + * "memory_chunk" points to the memory, where the instance will be allocated. + * + * In order to create object at specific location, you should use placement new + * operator: + * + * your_type_t* instance = new (memory_chunk) your_type_t(); + * + * Now, you can continue to initialize the instance. If "your_type_t" constructor + * requires some arguments, well just "parse" the Python object before you call + * the constructor. + * + **/ -typedef boost::tupls::tuple< int, std::string > record_t; - -record_t read_record(); -bool validate_record(record_t const & r); - -If you don't use custom r-value converters than you need to create small wrappers -around the function or expose record_t class. - -**/ - namespace boost{ namespace python{ namespace details{ @@ -37,12 +92,6 @@ } -/******************************************************************************* - -Conversion from C++ type to Python type is pretty simple. Basically, using -Python C API you create an object and than initialize it. - -**/ template< class TTuple > struct to_py_tuple{ @@ -73,17 +122,6 @@ }; -/******************************************************************************* - -Conversion from Python type to C++ type is a little bit complex. Boost.Python -library implements solution, which manages the memory of the allocated object. -This was done in order to allow -In order to implement "from Python" conversion you should supply 2 functions. -The first one checks whether the conversion is possible. The second function -should construct an instance of the desired class. - -**/ - template< class TTuple> struct from_py_tuple{ @@ -111,18 +149,10 @@ static void construct( PyObject* py_obj, converter::rvalue_from_python_stage1_data* data){ - //At this point you are exposed to low level implementation details - //of Boost.Python library. You use the reinterpret_cast, in order to get - //access to the number of bytes, needed to store C++ object typedef converter::rvalue_from_python_storage<TTuple> storage_t; storage_t* the_storage = reinterpret_cast<storage_t*>( data ); - //Now we need to get access to the memory, which will held the object. void* memory_chunk = the_storage->storage.bytes; - //You should use placement new in order to create object in specific - //location TTuple* c_tuple = new (memory_chunk) TTuple(); - //We allocated the memory, now we should tell Boost.Python to manage( free ) - //it later data->convertible = memory_chunk; python::tuple py_tuple( handle<>( borrowed( py_obj ) ) ); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-01-16 10:08:29
|
Revision: 868 http://svn.sourceforge.net/pygccxml/?rev=868&view=rev Author: roman_yakovenko Date: 2007-01-16 02:08:28 -0800 (Tue, 16 Jan 2007) Log Message: ----------- adding rest files Modified Paths: -------------- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuple_conversion.hpp Added Paths: ----------- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/auto_conversion.cpp.rest pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/from_conversion.cpp.rest pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuple_conversion.hpp.rest Added: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/auto_conversion.cpp.rest =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/auto_conversion.cpp.rest (rev 0) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/auto_conversion.cpp.rest 2007-01-16 10:08:28 UTC (rev 868) @@ -0,0 +1,3 @@ +.. code-block:: + :language: C++ + :source-file: ./auto_conversion.cpp Added: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/from_conversion.cpp.rest =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/from_conversion.cpp.rest (rev 0) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/from_conversion.cpp.rest 2007-01-16 10:08:28 UTC (rev 868) @@ -0,0 +1,3 @@ +.. code-block:: + :language: C++ + :source-file: ./from_conversion.cpp Modified: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuple_conversion.hpp =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuple_conversion.hpp 2007-01-15 22:11:57 UTC (rev 867) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuple_conversion.hpp 2007-01-16 10:08:28 UTC (rev 868) @@ -7,10 +7,28 @@ #include <boost/mpl/int.hpp> #include <boost/mpl/next.hpp> +/******************************************************************************* + +This file contains conversion from boost::tuples::tuple class instantiation to +Python tuple and vice versa. The conversion uses Boost.Python custom r-value +converters. Custom r-value converters allows Boost.Python library to handle +[from|to] [C++|Python] variables conversion "on-the-fly". For example: + +typedef boost::tupls::tuple< int, std::string > record_t; + +record_t read_record(); +bool validate_record(record_t const & r); + +If you don't use custom r-value converters than you need to create small wrappers +around the function or expose record_t class. + +**/ + namespace boost{ namespace python{ namespace details{ -//Small helper for incrementing index + +//Small helper function, introduced to allow short syntax for index incrementing template< int index> typename mpl::next< mpl::int_< index > >::type increment_index(){ typedef typename mpl::next< mpl::int_< index > >::type next_index_type; @@ -19,8 +37,12 @@ } -//Conversion from C++ type to Python type is pretty simple. Basically, using -//Python C API create an object and than initialize it. +/******************************************************************************* + +Conversion from C++ type to Python type is pretty simple. Basically, using +Python C API you create an object and than initialize it. + +**/ template< class TTuple > struct to_py_tuple{ @@ -43,20 +65,25 @@ convert_impl( c_tuple, values, details::increment_index<index>(), length_type() ); } - template< int index > + template< int length > static void - convert_impl( const TTuple&, list& values, mpl::int_< index >, mpl::int_< index >) + convert_impl( const TTuple&, list& values, mpl::int_< length >, mpl::int_< length >) {} }; -//Conversion from Python type to C++ type is a little bit complex. Boost.Python -//library implements solution, which manages the memory of the allocated object. -//In order to implement "from Python" conversion you should supply 2 functions. -//The first one checks whether the conversion is possible. The second function -//should construct an instance of the desired class. +/******************************************************************************* +Conversion from Python type to C++ type is a little bit complex. Boost.Python +library implements solution, which manages the memory of the allocated object. +This was done in order to allow +In order to implement "from Python" conversion you should supply 2 functions. +The first one checks whether the conversion is possible. The second function +should construct an instance of the desired class. + +**/ + template< class TTuple> struct from_py_tuple{ @@ -120,9 +147,9 @@ } } - template< int index > + template< int length > static bool - convertible_impl( const python::tuple& py_tuple, mpl::int_< index >, mpl::int_< index > ){ + convertible_impl( const python::tuple& py_tuple, mpl::int_< length >, mpl::int_< length > ){ return true; } @@ -138,9 +165,9 @@ construct_impl( py_tuple, c_tuple, details::increment_index<index>(), length_type() ); } - template< int index > + template< int length > static void - construct_impl( const python::tuple& py_tuple, TTuple& c_tuple, mpl::int_< index >, mpl::int_< index > ) + construct_impl( const python::tuple& py_tuple, TTuple& c_tuple, mpl::int_< length >, mpl::int_< length > ) {} }; Added: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuple_conversion.hpp.rest =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuple_conversion.hpp.rest (rev 0) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuple_conversion.hpp.rest 2007-01-16 10:08:28 UTC (rev 868) @@ -0,0 +1,3 @@ +.. code-block:: + :language: C++ + :source-file: ./tuple_conversion.hpp This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-01-15 22:11:59
|
Revision: 867 http://svn.sourceforge.net/pygccxml/?rev=867&view=rev Author: roman_yakovenko Date: 2007-01-15 14:11:57 -0800 (Mon, 15 Jan 2007) Log Message: ----------- replacing auto_conversion example with more interesting one Modified Paths: -------------- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/auto_conversion.cpp pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/test.py Added Paths: ----------- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuple_conversion.hpp Modified: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/auto_conversion.cpp =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/auto_conversion.cpp 2007-01-11 20:36:31 UTC (rev 866) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/auto_conversion.cpp 2007-01-15 22:11:57 UTC (rev 867) @@ -1,174 +1,71 @@ #include "boost/python.hpp" -#include "boost/python/object.hpp" //len function -#include "boost/python/ssize_t.hpp" //ssize_t type definition -#include "boost/python/detail/none.hpp" +#include "tuple_conversion.hpp" +#include "boost/tuple/tuple_comparison.hpp" //This example is very similar to one found in Boost.Python FAQs: //How can I automatically convert my custom string type to and from a Python string? //http://www.boost.org/libs/python/doc/v2/faq.html#custom_string //I will introduce another example with detailed explanation. -//Simple class, which describes a point in 3D. I don't want to export the class. +//Simple class, which describes a record in 3D. I don't want to export the class. //Instead of this I want Python user pass tuple as argument to all functions -//that expects point3d_t class instance and Boost.Python will automaticly handle +//that expects record_t class instance and Boost.Python will automaticly handle //the conversion. Same conversion should be applied on functions, which returns -//point3d_t class instance +//record_t class instance -struct point3d_t{ - explicit point3d_t(int x_=0, int y_=0, int z_=0) - : x(x_), y(y_), z(z_) - {} - - bool operator==( const point3d_t& other ) const{ - return x == other.x && y == other.y && z == other.z; - } - - int x, y, z; -}; +typedef boost::tuple< int, int, int > record_t; - -point3d_t point_ret_val_000() { - return point3d_t(); +record_t record_ret_val_000() { + return record_t(0,0,0); } -point3d_t point_ret_val_101() { - return point3d_t(1,0,1); +record_t record_ret_val_101() { + return record_t(1,0,1); } -point3d_t& point_ret_ref_010(){ - static point3d_t pt( 0,1,0 ); +record_t& record_ret_ref_010(){ + static record_t pt( 0,1,0 ); return pt; } -point3d_t* point_ret_ptr_110(){ - static point3d_t pt( 1,1,0 ); +record_t* record_ret_ptr_110(){ + static record_t pt( 1,1,0 ); return &pt; } -bool test_point_val_000( point3d_t pt ){ - return pt == point3d_t( 0,0,0 ); +bool test_record_val_000( record_t pt ){ + return pt == record_t( 0,0,0 ); } -bool test_point_cref_010( const point3d_t& pt ){ - return pt == point3d_t( 0,1,0 ); +bool test_record_cref_010( const record_t& pt ){ + return pt == record_t( 0,1,0 ); } -bool test_point_ref_110( point3d_t& pt ){ - return pt == point3d_t( 1,1,0 ); +bool test_record_ref_110( record_t& pt ){ + return pt == record_t( 1,1,0 ); } -bool test_point_ptr_101( point3d_t* pt ){ - return pt && *pt == point3d_t( 1,0,1 ); +bool test_record_ptr_101( record_t* pt ){ + return pt && *pt == record_t( 1,0,1 ); } namespace bpl = boost::python; -namespace point3d_conversion{ - -struct to_tuple{ - //"To Python" conversion is pretty simple: - //Using Python C API create an object and than manually fill it with data. - //In this case Boost.Python provides a convenience API for tuple construction. - //I don't see any reason not to use it. - static PyObject* convert(point3d_t const& pt){ - return bpl::incref( bpl::make_tuple( pt.x, pt.y, pt.z ).ptr() ); - } -}; - -struct from_tuple{ - //"From Python" conversion is more complex. Memory managment is the main - //reason for this. - - //The first step in conversion from the Python object is to check whether - //the object is the right one. - static void* convertible(PyObject* py_seq){ - if( !PySequence_Check( py_seq ) ){ - //check that the argument is a sequence - return 0; - } - bpl::object seq = bpl::object( bpl::handle<>( bpl::borrowed( py_seq ) ) ); - bpl::ssize_t size = bpl::len( seq ); - if( 3 != size ){ - return 0; - } - for( bpl::ssize_t i = 0; i < 3; ++i ){ - //test that every item in sequence has int type - bpl::object item = seq[i]; - bpl::extract<int> type_checker( item ); - if( !type_checker.check() ){ - return 0; - } - } - return py_seq; - } - - //rvalue_from_python_stage1_data is a class defined in - //boost/python/converter/rvalue_from_python_data.hpp file. The file contains - //nice and not "very" technical explanation about data management for rvalue - //conversions from Python to C++ types. - - //In my words, the rvalue_from_python_stage1_data class contains memory - //needed for construction of appropriate C++ object. The class also manages - //the life time of the constructed C++ object. - - static void - construct( PyObject* py_seq, bpl::converter::rvalue_from_python_stage1_data* data){ - if( !convertible( py_seq ) ){ - bpl::throw_error_already_set(); - } - - //At this point you are exposed to low level implementation details - //of Boost.Python library. You use the reinterpret_cast, in order to get - //access to the number of bytes, needed to store C++ object - typedef bpl::converter::rvalue_from_python_storage<point3d_t> point3d_storage_t; - point3d_storage_t* the_storage = reinterpret_cast<point3d_storage_t*>( data ); - //Now we need to get access to the memory, which will held the object. - void* memory_chunk = the_storage->storage.bytes; - //You should use placement new in order to create object in specific - //location - point3d_t* point = new (memory_chunk) point3d_t(); - //We allocated the memory, now we should tell Boost.Python to manage( free ) - //it later - data->convertible = memory_chunk; - - bpl::object seq = bpl::object( bpl::handle<>( bpl::borrowed( py_seq ) ) ); - //Now I actually creates the object from the Python tuple - bpl::object tmp = seq[0]; - point->x = bpl::extract< int >( tmp ); - tmp = seq[1]; - point->y = bpl::extract< int >( tmp ); - tmp = seq[2]; - point->z = bpl::extract< int >( tmp ); - - } - -}; - -void register_conversion(){ - - bpl::to_python_converter< point3d_t, to_tuple>(); - - bpl::converter::registry::push_back( &from_tuple::convertible - , &from_tuple::construct - , bpl::type_id<point3d_t>() ); -} - -}//namespace point3d_conversion - BOOST_PYTHON_MODULE( auto_conversion ){ - point3d_conversion::register_conversion(); - bpl::def("point_ret_val_000", &::point_ret_val_000); - bpl::def("point_ret_val_101", &::point_ret_val_101); - bpl::def("point_ret_ref_010" - , &::point_ret_ref_010 + bpl::register_tuple< record_t >(); + + bpl::def("record_ret_val_000", &::record_ret_val_000); + bpl::def("record_ret_val_101", &::record_ret_val_101); + bpl::def("record_ret_ref_010" + , &::record_ret_ref_010 , bpl::return_value_policy<bpl:: copy_non_const_reference>() ); - bpl::def( "point_ret_ptr_110" - , &::point_ret_ptr_110 + bpl::def( "record_ret_ptr_110" + , &::record_ret_ptr_110 , bpl::return_value_policy<bpl::return_by_value>() ); - bpl::def("test_point_val_000", &::test_point_val_000); - bpl::def("test_point_cref_010", &::test_point_cref_010); - bpl::def("test_point_ref_110", &::test_point_ref_110); - bpl::def("test_point_ptr_101", &::test_point_ptr_101); + bpl::def("test_record_val_000", &::test_record_val_000); + bpl::def("test_record_cref_010", &::test_record_cref_010); + bpl::def("test_record_ref_110", &::test_record_ref_110); + bpl::def("test_record_ptr_101", &::test_record_ptr_101); } Modified: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/test.py =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/test.py 2007-01-11 20:36:31 UTC (rev 866) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/test.py 2007-01-15 22:11:57 UTC (rev 867) @@ -7,14 +7,14 @@ unittest.TestCase.__init__( self, *args ) def test_auto( self ): - self.failUnless( (0,0,0) == auto_conv.point_ret_val_000() ) - self.failUnless( (1,0,1) == auto_conv.point_ret_val_101() ) - self.failUnless( (0,1,0) == auto_conv.point_ret_ref_010() ) - self.failUnlessRaises( TypeError, auto_conv.point_ret_ptr_110 ) - self.failUnless( auto_conv.test_point_val_000( (0,0,0) ) ) - self.failUnless( auto_conv.test_point_cref_010( (0,1,0) ) ) - self.failUnlessRaises( TypeError, auto_conv.test_point_ref_110, (1,1,0) ) - self.failUnlessRaises( TypeError, auto_conv.test_point_ptr_101, (1,0,1) ) + self.failUnless( (0,0,0) == auto_conv.record_ret_val_000() ) + self.failUnless( (1,0,1) == auto_conv.record_ret_val_101() ) + self.failUnless( (0,1,0) == auto_conv.record_ret_ref_010() ) + self.failUnlessRaises( TypeError, auto_conv.record_ret_ptr_110 ) + self.failUnless( auto_conv.test_record_val_000( (0,0,0) ) ) + self.failUnless( auto_conv.test_record_cref_010( (0,1,0) ) ) + self.failUnlessRaises( TypeError, auto_conv.test_record_ref_110, (1,1,0) ) + self.failUnlessRaises( TypeError, auto_conv.test_record_ptr_101, (1,0,1) ) def test_from_sequence( self ): self.failUnless( from_conv.test_val_010( (0,1,0) ) ) Added: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuple_conversion.hpp =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuple_conversion.hpp (rev 0) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/tuple_conversion.hpp 2007-01-15 22:11:57 UTC (rev 867) @@ -0,0 +1,160 @@ +#ifndef tuple_conversion_hpp +#define tuple_conversion_hpp + +#include "boost/python.hpp" +#include "boost/tuple/tuple.hpp" +#include "boost/python/object.hpp" //len function +#include <boost/mpl/int.hpp> +#include <boost/mpl/next.hpp> + +namespace boost{ namespace python{ + +namespace details{ +//Small helper for incrementing index +template< int index> +typename mpl::next< mpl::int_< index > >::type increment_index(){ + typedef typename mpl::next< mpl::int_< index > >::type next_index_type; + return next_index_type(); +} + +} + +//Conversion from C++ type to Python type is pretty simple. Basically, using +//Python C API create an object and than initialize it. +template< class TTuple > +struct to_py_tuple{ + + typedef mpl::int_< tuples::length< TTuple >::value > length_type; + + static PyObject* convert(const TTuple& c_tuple){ + list values; + //add all c_tuple items to "values" list + convert_impl( c_tuple, values, mpl::int_< 0 >(), length_type() ); + //create Python tuple from the list + return incref( python::tuple( values ).ptr() ); + } + +private: + + template< int index, int length > + static void + convert_impl( const TTuple &c_tuple, list& values, mpl::int_< index >, mpl::int_< length > ) { + values.append( c_tuple.template get< index >() ); + convert_impl( c_tuple, values, details::increment_index<index>(), length_type() ); + } + + template< int index > + static void + convert_impl( const TTuple&, list& values, mpl::int_< index >, mpl::int_< index >) + {} + +}; + + +//Conversion from Python type to C++ type is a little bit complex. Boost.Python +//library implements solution, which manages the memory of the allocated object. +//In order to implement "from Python" conversion you should supply 2 functions. +//The first one checks whether the conversion is possible. The second function +//should construct an instance of the desired class. + +template< class TTuple> +struct from_py_tuple{ + + typedef mpl::int_< tuples::length< TTuple >::value > length_type; + + static void* + convertible(PyObject* py_obj){ + + if( !PyTuple_Check( py_obj ) ){ + return 0; + } + + python::tuple py_tuple( handle<>( borrowed( py_obj ) ) ); + if( tuples::length< TTuple >::value != len( py_tuple ) ){ + return 0; + } + + if( convertible_impl( py_tuple, mpl::int_< 0 >(), length_type() ) ){ + return py_obj; + } + else{ + return 0; + } + } + + static void + construct( PyObject* py_obj, converter::rvalue_from_python_stage1_data* data){ + //At this point you are exposed to low level implementation details + //of Boost.Python library. You use the reinterpret_cast, in order to get + //access to the number of bytes, needed to store C++ object + typedef converter::rvalue_from_python_storage<TTuple> storage_t; + storage_t* the_storage = reinterpret_cast<storage_t*>( data ); + //Now we need to get access to the memory, which will held the object. + void* memory_chunk = the_storage->storage.bytes; + //You should use placement new in order to create object in specific + //location + TTuple* c_tuple = new (memory_chunk) TTuple(); + //We allocated the memory, now we should tell Boost.Python to manage( free ) + //it later + data->convertible = memory_chunk; + + python::tuple py_tuple( handle<>( borrowed( py_obj ) ) ); + construct_impl( py_tuple, *c_tuple, mpl::int_< 0 >(), length_type() ); + } + +private: + + template< int index, int length > + static bool + convertible_impl( const python::tuple& py_tuple, mpl::int_< index >, mpl::int_< length > ){ + + typedef typename tuples::element< index, TTuple>::type element_type; + + object element = py_tuple[index]; + extract<element_type> type_checker( element ); + if( !type_checker.check() ){ + return false; + } + else{ + return convertible_impl( py_tuple, details::increment_index<index>(), length_type() ); + } + } + + template< int index > + static bool + convertible_impl( const python::tuple& py_tuple, mpl::int_< index >, mpl::int_< index > ){ + return true; + } + + template< int index, int length > + static void + construct_impl( const python::tuple& py_tuple, TTuple& c_tuple, mpl::int_< index >, mpl::int_< length > ){ + + typedef typename tuples::element< index, TTuple>::type element_type; + + object element = py_tuple[index]; + c_tuple.template get< index >() = extract<element_type>( element ); + + construct_impl( py_tuple, c_tuple, details::increment_index<index>(), length_type() ); + } + + template< int index > + static void + construct_impl( const python::tuple& py_tuple, TTuple& c_tuple, mpl::int_< index >, mpl::int_< index > ) + {} + +}; + +template< class TTuple> +void register_tuple(){ + + to_python_converter< TTuple, to_py_tuple<TTuple> >(); + + converter::registry::push_back( &from_py_tuple<TTuple>::convertible + , &from_py_tuple<TTuple>::construct + , type_id<TTuple>() ); +}; + +} } //boost::python + +#endif//tuple_conversion_hpp This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-01-11 20:52:16
|
Revision: 866 http://svn.sourceforge.net/pygccxml/?rev=866&view=rev Author: roman_yakovenko Date: 2007-01-11 12:36:31 -0800 (Thu, 11 Jan 2007) Log Message: ----------- adding new conversion Modified Paths: -------------- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/sconstruct pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/test.py Added Paths: ----------- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/from_conversion.cpp Added: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/from_conversion.cpp =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/from_conversion.cpp (rev 0) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/from_conversion.cpp 2007-01-11 20:36:31 UTC (rev 866) @@ -0,0 +1,131 @@ +#include "boost/python.hpp" +#include "boost/python/object.hpp" //len function +#include "boost/python/ssize_t.hpp" //ssize_t type definition +#include "boost/python/detail/none.hpp" + + +struct colour_t{ + explicit colour_t( float red_=0.0, float green_=0.0, float blue_=0.0 ) + : red( red_ ), green( green_ ), blue( blue_ ) + {} + + bool operator==( const colour_t& other ) const{ + return red == other.red && green == other.green && blue == other.blue; + } + + float red, green, blue; +}; + +struct image_t{ + colour_t background; + bool test_background( const colour_t& color )const{ + return color == background; + } +}; + +bool test_val_010( colour_t colour ){ + return colour == colour_t( 0, 1, 0); +} + +bool test_cref_000( const colour_t& colour ){ + return colour == colour_t( 0, 0, 0); +} + +bool test_ref_111( const colour_t& colour ){ + return colour == colour_t( 1, 1, 1); +} + +bool test_ptr_101( colour_t* colour ){ + return colour && *colour == colour_t( 1, 0, 1); +} + +bool test_cptr_110( const colour_t* colour ){ + return colour && *colour == colour_t( 1, 1, 0); +} + + +namespace bpl = boost::python; + +namespace colour_conversion{ + +struct from_tuple{ + + static void* convertible(PyObject* py_seq){ + if( !PySequence_Check( py_seq ) ){ + return 0; + } + + bpl::object seq = bpl::object( bpl::handle<>( bpl::borrowed( py_seq ) ) ); + bpl::ssize_t size = bpl::len( seq ); + if( 3 != size ){ + return 0; + } + for( bpl::ssize_t i = 0; i < 3; ++i ){ + //test that every item in sequence has int type + bpl::object item = seq[i]; + bpl::extract<float> type_checker( item ); + if( !type_checker.check() ){ + return 0; + } + } + return py_seq; + } + + static void + construct( PyObject* py_seq, bpl::converter::rvalue_from_python_stage1_data* data){ + if( !convertible( py_seq ) ){ + bpl::throw_error_already_set(); + } + + typedef bpl::converter::rvalue_from_python_storage<colour_t> colour_storage_t; + colour_storage_t* the_storage = reinterpret_cast<colour_storage_t*>( data ); + void* memory_chunk = the_storage->storage.bytes; + colour_t* colour = new (memory_chunk) colour_t(); + data->convertible = memory_chunk; + + bpl::object seq = bpl::object( bpl::handle<>( bpl::borrowed( py_seq ) ) ); + //Now I actually creates the object from the Python tuple + bpl::object tmp = seq[0]; + colour->red = bpl::extract< float >( tmp ); + tmp = seq[1]; + colour->green = bpl::extract< float >( tmp ); + tmp = seq[2]; + colour->blue = bpl::extract< float >( tmp ); + + } + +}; + +void register_conversion(){ + + bpl::converter::registry::push_back( &from_tuple::convertible + , &from_tuple::construct + , bpl::type_id<colour_t>() ); +} + +}//namespace colour_conversion + +BOOST_PYTHON_MODULE( from_conversion ){ + bpl::class_< colour_t >( "colour_t" ) + .def( bpl::init< bpl::optional< float, float, float > >( + ( bpl::arg("red_")=0.0, bpl::arg("green_")=0.0, bpl::arg("blue_")=0.0 ) ) ) + .def_readwrite( "red", &colour_t::red ) + .def_readwrite( "green", &colour_t::green ) + .def_readwrite( "blue", &colour_t::blue ); + colour_conversion::register_conversion(); + + bpl::class_< image_t >( "image_t" ) + //naive aproach that will not work - plain Python assignment + //.def_readwrite( "background", &image_t::background ) + //You should use properties to force the conversion + .add_property( "background" + , bpl::make_getter( &image_t::background ) + , bpl::make_setter( &image_t::background ) ) + .def( "test_background", &image_t::test_background ); + + bpl::def("test_val_010", &::test_val_010); + bpl::def("test_cref_000", &::test_cref_000); + bpl::def("test_ref_111", &::test_ref_111); + bpl::def("test_ptr_101", &::test_ptr_101); + bpl::def("test_cptr_110", &::test_cptr_110); +} Modified: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/sconstruct =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/sconstruct 2007-01-10 18:31:02 UTC (rev 865) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/sconstruct 2007-01-11 20:36:31 UTC (rev 866) @@ -8,3 +8,13 @@ , SHLIBPREFIX='' , SHLIBSUFFIX='.so' ) + +SharedLibrary( target=r'from_conversion' + , source=[ r'from_conversion.cpp' ] + , LIBS=[ r"boost_python" ] + , LIBPATH=[ r"/home/roman/boost_cvs/bin",r"" ] + , CPPPATH=[ r"/home/roman/boost_cvs" + , r"/usr/include/python2.4" ] + , SHLIBPREFIX='' + , SHLIBSUFFIX='.so' +) Modified: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/test.py =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/test.py 2007-01-10 18:31:02 UTC (rev 865) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/test.py 2007-01-11 20:36:31 UTC (rev 866) @@ -1,20 +1,48 @@ import unittest -from auto_conversion import * +import auto_conversion as auto_conv +import from_conversion as from_conv class auto_conversion_tester_t( unittest.TestCase ): def __init__( self, *args ): unittest.TestCase.__init__( self, *args ) - def test( self ): - self.failUnless( (0,0,0) == point_ret_val_000() ) - self.failUnless( (1,0,1) == point_ret_val_101() ) - self.failUnless( (0,1,0) == point_ret_ref_010() ) - self.failUnlessRaises( TypeError, point_ret_ptr_110 ) - self.failUnless( test_point_val_000( (0,0,0) ) ) - self.failUnless( test_point_cref_010( (0,1,0) ) ) - self.failUnlessRaises( TypeError, test_point_ref_110, (1,1,0) ) - self.failUnlessRaises( TypeError, test_point_ptr_101, (1,0,1) ) + def test_auto( self ): + self.failUnless( (0,0,0) == auto_conv.point_ret_val_000() ) + self.failUnless( (1,0,1) == auto_conv.point_ret_val_101() ) + self.failUnless( (0,1,0) == auto_conv.point_ret_ref_010() ) + self.failUnlessRaises( TypeError, auto_conv.point_ret_ptr_110 ) + self.failUnless( auto_conv.test_point_val_000( (0,0,0) ) ) + self.failUnless( auto_conv.test_point_cref_010( (0,1,0) ) ) + self.failUnlessRaises( TypeError, auto_conv.test_point_ref_110, (1,1,0) ) + self.failUnlessRaises( TypeError, auto_conv.test_point_ptr_101, (1,0,1) ) + + def test_from_sequence( self ): + self.failUnless( from_conv.test_val_010( (0,1,0) ) ) + self.failUnless( from_conv.test_cref_000( [0,0,0] ) ) + self.failUnless( from_conv.test_ref_111( [1,1,1] ) ) + self.failUnlessRaises( Exception, from_conv.test_ptr_101, (1,0,1) ) + self.failUnlessRaises( Exception, from_conv.test_cptr_110, (1,1,0) ) + + def test_from_class( self ): + color = from_conv.colour_t + self.failUnless( from_conv.test_val_010( color(0,1,0) ) ) + self.failUnless( from_conv.test_cref_000( color(0,0,0) ) ) + self.failUnless( from_conv.test_ref_111( color(1,1,1) ) ) + self.failUnless( from_conv.test_ptr_101( color(1,0,1) ) ) + self.failUnless( from_conv.test_cptr_110( color(1,1,0) ) ) + + def cmp_colours( self, c1, c2 ): + return c1.red == c2.red and c1.green == c2.green and c1.blue == c2.blue + def test_from_class_property( self ): + colour = from_conv.colour_t + image = from_conv.image_t() + self.failUnless( self.cmp_colours( image.background, colour() ) ) + image.background = (1,0,1) + self.failUnless( self.cmp_colours( image.background, colour(1,0,1) ) ) + self.failUnless( image.test_background( [1,0,1] ) ) + self.failUnless( image.test_background( colour(1,0,1 ) ) ) + def create_suite(): suite = unittest.TestSuite() suite.addTest( unittest.makeSuite(auto_conversion_tester_t)) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-01-10 18:31:05
|
Revision: 865 http://svn.sourceforge.net/pygccxml/?rev=865&view=rev Author: roman_yakovenko Date: 2007-01-10 10:31:02 -0800 (Wed, 10 Jan 2007) Log Message: ----------- adding pyplusplus::aliases hint Modified Paths: -------------- pyplusplus_dev/docs/documentation/hints.rest Modified: pyplusplus_dev/docs/documentation/hints.rest =================================================================== --- pyplusplus_dev/docs/documentation/hints.rest 2007-01-10 06:38:42 UTC (rev 864) +++ pyplusplus_dev/docs/documentation/hints.rest 2007-01-10 18:31:02 UTC (rev 865) @@ -29,10 +29,34 @@ class_< std::vector< int > >( "numbers" ) ... ; + +`Py++`_ will pick up the alias, only in case the class has single "typedef". + +``pyplusplus::aliases`` namespace +--------------------------------- + +The previous approach is "implicit" - `Py++`_ does something behind the scene. +Recently (version 0.8.6 ), another approach was introduced: + +.. code-block:: C++ + + #include <vector> -This feature will work only in case there is only one such ``typedef``. Using class -property ``aliases`` you can get access to all ``typedef``'s of the class. + namespace pyplusplus{ namespace aliases{ + //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + typedef std::vector< int > numbers; + + } } //pyplusplus::aliases +The idea is that you create namespace with a special name - ``pyplusplus::aliases`` +and `Py++`_ automatically picks the class aliases from it. In case you accidentally +introduced two or more different aliases to the same class, it will pick the +longest one and print a warning. Other advantages of the approach: + +* you are not forced to learn new API + +* you continue to use your favorite editor and familiar language + .. _`Py++` : ./../pyplusplus.html .. _`Boost.Python`: http://www.boost.org/libs/python/doc/index.html .. _`Python`: http://www.python.org This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-01-10 06:38:44
|
Revision: 864 http://svn.sourceforge.net/pygccxml/?rev=864&view=rev Author: roman_yakovenko Date: 2007-01-09 22:38:42 -0800 (Tue, 09 Jan 2007) Log Message: ----------- add new test case Modified Paths: -------------- pygccxml_dev/unittests/data/patcher.hpp pygccxml_dev/unittests/patcher_tester.py Modified: pygccxml_dev/unittests/data/patcher.hpp =================================================================== --- pygccxml_dev/unittests/data/patcher.hpp 2007-01-09 21:24:49 UTC (rev 863) +++ pygccxml_dev/unittests/data/patcher.hpp 2007-01-10 06:38:42 UTC (rev 864) @@ -6,6 +6,8 @@ #ifndef __patcher_hpp__ #define __patcher_hpp__ +#include <vector> + namespace ns1{ namespace ns2{ enum fruit{ apple, orange }; @@ -45,6 +47,11 @@ void typedef__func( const typedef_::alias& position = typedef_::alias() ); +namespace osg{ + struct node{}; + node* clone_tree( const std::vector<std::string> &types=std::vector<std::string>() ); + +} /*struct default_arg_t{};*/ /*default_arg_t create_default_argument();*/ Modified: pygccxml_dev/unittests/patcher_tester.py =================================================================== --- pygccxml_dev/unittests/patcher_tester.py 2007-01-09 21:24:49 UTC (rev 863) +++ pygccxml_dev/unittests/patcher_tester.py 2007-01-10 06:38:42 UTC (rev 864) @@ -13,60 +13,56 @@ from pygccxml import declarations class tester_impl_t( parser_test_case.parser_test_case_t ): - - decls = None - + def __init__(self, architecture, *args): parser_test_case.parser_test_case_t.__init__(self, *args) self.architecture = architecture - self.__decls = None + self.global_ns = None def setUp( self ): reader = parser.source_reader_t( self.config ) if 32 == self.architecture: - self.__decls = reader.read_file( 'patcher.hpp' ) + self.global_ns = reader.read_file( 'patcher.hpp' )[0].top_parent else: original_get_architecture = utils.get_architecture utils.get_architecture = lambda: 64 - self.__decls = reader.read_xml_file( - os.path.join( autoconfig.data_directory, 'patcher_tester_64bit.xml' ) ) + self.global_ns = reader.read_xml_file( + os.path.join( autoconfig.data_directory, 'patcher_tester_64bit.xml' ) )[0].top_parent utils.get_architecture = original_get_architecture def test_enum_patcher(self): - fix_enum = declarations.find_declaration( self.__decls, type=declarations.free_function_t, name='fix_enum' ) - self.failUnless( fix_enum, "Free function fix_enum has not been found." ) + fix_enum = self.global_ns.free_fun( 'fix_enum' ) self.failUnless( fix_enum.arguments[0].default_value == '::ns1::ns2::apple' ) #double_call = declarations.find_declaration( decls, type=declarations.free_function_t, name='double_call' ) def test_numeric_patcher(self): - fix_numeric = declarations.find_declaration( self.__decls, type=declarations.free_function_t, name='fix_numeric' ) - self.failUnless( fix_numeric, "Free function fix_numeric has not been found." ) + fix_numeric = self.global_ns.free_fun( 'fix_numeric' ) if 32 == self.architecture: self.failUnless( fix_numeric.arguments[0].default_value == u"0xffffffffffffffff" ) else: self.failUnless( fix_numeric.arguments[0].default_value == u"0ffffffff" ) def test_unnamed_enum_patcher(self): - fix_unnamed = declarations.find_declaration( self.__decls, type=declarations.free_function_t, name='fix_unnamed' ) - self.failUnless( fix_unnamed, "Free function fix_unnamed has not been found." ) + fix_unnamed = self.global_ns.free_fun( 'fix_unnamed' ) self.failUnless( fix_unnamed.arguments[0].default_value == u"int(::fx::unnamed)" ) def test_function_call_patcher(self): - fix_function_call = declarations.find_declaration( self.__decls, type=declarations.free_function_t, name='fix_function_call' ) - self.failUnless( fix_function_call, "Free function fix_function_call has not been found." ) + fix_function_call = self.global_ns.free_fun( 'fix_function_call' ) self.failUnless( fix_function_call.arguments[0].default_value == u"function_call::calc( 1, 2, 3 )" ) def test_fundamental_patcher(self): - fcall = declarations.find_declaration( self.__decls, type=declarations.free_function_t, name='fix_fundamental' ) - self.failUnless( fcall, "Free function fix_function_call has not been found." ) + fcall = self.global_ns.free_fun( 'fix_fundamental' ) self.failUnless( fcall.arguments[0].default_value == u"(unsigned int)(::fundamental::eggs)" ) def test_constructor_patcher(self): - typedef__func = declarations.find_declaration( self.__decls, type=declarations.free_function_t, name='typedef__func' ) - self.failUnless( typedef__func, "Free function typedef__func has not been found." ) + typedef__func = self.global_ns.free_fun( 'typedef__func' ) self.failUnless( typedef__func.arguments[0].default_value == u"::typedef_::alias( )" ) - + if 32 == self.architecture: + clone_tree = self.global_ns.free_fun( 'clone_tree' ) + default_value = 'vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >,std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >()' + self.failUnless( default_value == clone_tree.arguments[0].default_value ) + class tester_32_t( tester_impl_t ): def __init__(self, *args): tester_impl_t.__init__(self, 32, *args) @@ -85,4 +81,4 @@ unittest.TextTestRunner(verbosity=2).run( create_suite() ) if __name__ == "__main__": - run_suite() \ No newline at end of file + run_suite() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-01-09 21:24:51
|
Revision: 863 http://svn.sourceforge.net/pygccxml/?rev=863&view=rev Author: roman_yakovenko Date: 2007-01-09 13:24:49 -0800 (Tue, 09 Jan 2007) Log Message: ----------- adding example of auto conversion Modified Paths: -------------- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/auto_conversion.cpp pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/test.py Modified: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/auto_conversion.cpp =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/auto_conversion.cpp 2007-01-09 09:29:03 UTC (rev 862) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/auto_conversion.cpp 2007-01-09 21:24:49 UTC (rev 863) @@ -1,40 +1,93 @@ #include "boost/python.hpp" #include "boost/python/object.hpp" //len function #include "boost/python/ssize_t.hpp" //ssize_t type definition -#include <string> +#include "boost/python/detail/none.hpp" +//This example is very similar to one found in Boost.Python FAQs: +//How can I automatically convert my custom string type to and from a Python string? +//http://www.boost.org/libs/python/doc/v2/faq.html#custom_string +//I will introduce another example with detailed explanation. + +//Simple class, which describes a point in 3D. I don't want to export the class. +//Instead of this I want Python user pass tuple as argument to all functions +//that expects point3d_t class instance and Boost.Python will automaticly handle +//the conversion. Same conversion should be applied on functions, which returns +//point3d_t class instance + struct point3d_t{ - point3d_t() - : x(0), y(0), z(0) + explicit point3d_t(int x_=0, int y_=0, int z_=0) + : x(x_), y(y_), z(z_) {} - + + bool operator==( const point3d_t& other ) const{ + return x == other.x && y == other.y && z == other.z; + } + int x, y, z; }; + +point3d_t point_ret_val_000() { + return point3d_t(); +} + +point3d_t point_ret_val_101() { + return point3d_t(1,0,1); +} + +point3d_t& point_ret_ref_010(){ + static point3d_t pt( 0,1,0 ); + return pt; +} + +point3d_t* point_ret_ptr_110(){ + static point3d_t pt( 1,1,0 ); + return &pt; +} + +bool test_point_val_000( point3d_t pt ){ + return pt == point3d_t( 0,0,0 ); +} + +bool test_point_cref_010( const point3d_t& pt ){ + return pt == point3d_t( 0,1,0 ); +} + +bool test_point_ref_110( point3d_t& pt ){ + return pt == point3d_t( 1,1,0 ); +} + +bool test_point_ptr_101( point3d_t* pt ){ + return pt && *pt == point3d_t( 1,0,1 ); +} + + namespace bpl = boost::python; namespace point3d_conversion{ struct to_tuple{ - - to_tuple(){ - bpl::to_python_converter< point3d_t, to_tuple>(); - } - + //"To Python" conversion is pretty simple: + //Using Python C API create an object and than manually fill it with data. + //In this case Boost.Python provides a convenience API for tuple construction. + //I don't see any reason not to use it. static PyObject* convert(point3d_t const& pt){ return bpl::incref( bpl::make_tuple( pt.x, pt.y, pt.z ).ptr() ); } - }; struct from_tuple{ - + //"From Python" conversion is more complex. Memory managment is the main + //reason for this. + + //The first step in conversion from the Python object is to check whether + //the object is the right one. static void* convertible(PyObject* py_seq){ if( !PySequence_Check( py_seq ) ){ //check that the argument is a sequence return 0; } - bpl::object seq = bpl::object( bpl::handle<>( py_seq ) ); + bpl::object seq = bpl::object( bpl::handle<>( bpl::borrowed( py_seq ) ) ); bpl::ssize_t size = bpl::len( seq ); if( 3 != size ){ return 0; @@ -79,7 +132,7 @@ //it later data->convertible = memory_chunk; - bpl::object seq = bpl::object( bpl::handle<>( py_seq ) ); + bpl::object seq = bpl::object( bpl::handle<>( bpl::borrowed( py_seq ) ) ); //Now I actually creates the object from the Python tuple bpl::object tmp = seq[0]; point->x = bpl::extract< int >( tmp ); @@ -87,6 +140,7 @@ point->y = bpl::extract< int >( tmp ); tmp = seq[2]; point->z = bpl::extract< int >( tmp ); + } }; @@ -94,7 +148,7 @@ void register_conversion(){ bpl::to_python_converter< point3d_t, to_tuple>(); - + bpl::converter::registry::push_back( &from_tuple::convertible , &from_tuple::construct , bpl::type_id<point3d_t>() ); @@ -102,13 +156,19 @@ }//namespace point3d_conversion -point3d_t zero_point() { - return point3d_t(); -} - - BOOST_PYTHON_MODULE( auto_conversion ){ point3d_conversion::register_conversion(); - bpl::def("zero_point", &::zero_point); + bpl::def("point_ret_val_000", &::point_ret_val_000); + bpl::def("point_ret_val_101", &::point_ret_val_101); + bpl::def("point_ret_ref_010" + , &::point_ret_ref_010 + , bpl::return_value_policy<bpl:: copy_non_const_reference>() ); + bpl::def( "point_ret_ptr_110" + , &::point_ret_ptr_110 + , bpl::return_value_policy<bpl::return_by_value>() ); + bpl::def("test_point_val_000", &::test_point_val_000); + bpl::def("test_point_cref_010", &::test_point_cref_010); + bpl::def("test_point_ref_110", &::test_point_ref_110); + bpl::def("test_point_ptr_101", &::test_point_ptr_101); } Modified: pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/test.py =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/test.py 2007-01-09 09:29:03 UTC (rev 862) +++ pyplusplus_dev/docs/troubleshooting_guide/automatic_conversion/test.py 2007-01-09 21:24:49 UTC (rev 863) @@ -1,26 +1,23 @@ import unittest -import shared_ptr +from auto_conversion import * - -class tester_t( unittest.TestCase ): +class auto_conversion_tester_t( unittest.TestCase ): def __init__( self, *args ): unittest.TestCase.__init__( self, *args ) def test( self ): - ptr = shared_ptr.create_ptr() - self.failUnless( ptr.text == "ptr" ) - self.failUnless( shared_ptr.read_ptr( ptr ) == "ptr" ) + self.failUnless( (0,0,0) == point_ret_val_000() ) + self.failUnless( (1,0,1) == point_ret_val_101() ) + self.failUnless( (0,1,0) == point_ret_ref_010() ) + self.failUnlessRaises( TypeError, point_ret_ptr_110 ) + self.failUnless( test_point_val_000( (0,0,0) ) ) + self.failUnless( test_point_cref_010( (0,1,0) ) ) + self.failUnlessRaises( TypeError, test_point_ref_110, (1,1,0) ) + self.failUnlessRaises( TypeError, test_point_ptr_101, (1,0,1) ) - const_ptr = shared_ptr.create_const_ptr() - self.failUnless( const_ptr.text == "const ptr" ) - self.failUnless( shared_ptr.read_const_ptr( const_ptr ) == "const ptr" ) - - #testing conversion functionality - self.failUnless( shared_ptr.read_const_ptr( ptr ) == "ptr" ) - def create_suite(): suite = unittest.TestSuite() - suite.addTest( unittest.makeSuite(tester_t)) + suite.addTest( unittest.makeSuite(auto_conversion_tester_t)) return suite def run_suite(): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-01-09 09:29:07
|
Revision: 862 http://svn.sourceforge.net/pygccxml/?rev=862&view=rev Author: roman_yakovenko Date: 2007-01-09 01:29:03 -0800 (Tue, 09 Jan 2007) Log Message: ----------- fixing indexing suite and adding aliases to class declarations Modified Paths: -------------- pygccxml_dev/pygccxml/declarations/__init__.py pygccxml_dev/pygccxml/declarations/class_declaration.py pygccxml_dev/pygccxml/parser/source_reader.py pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py pyplusplus_dev/pyplusplus/decl_wrappers/indexing_suite2.py pyplusplus_dev/pyplusplus/messages/warnings_.py pyplusplus_dev/pyplusplus/module_creator/creator.py pyplusplus_dev/unittests/classes_tester.py Modified: pygccxml_dev/pygccxml/declarations/__init__.py =================================================================== --- pygccxml_dev/pygccxml/declarations/__init__.py 2007-01-09 07:11:09 UTC (rev 861) +++ pygccxml_dev/pygccxml/declarations/__init__.py 2007-01-09 09:29:03 UTC (rev 862) @@ -199,6 +199,22 @@ ] """list, that contains all STD container traits classes""" +sequential_container_traits = \ +[ + list_traits + , deque_traits + , queue_traits + , priority_queue + , vector_traits + , stack_traits + , set_traits + , hash_set_traits + , multiset_traits + , hash_multiset_traits +] +"""list, that contains all STD container traits classes""" + + import templates import call_invocation Modified: pygccxml_dev/pygccxml/declarations/class_declaration.py =================================================================== --- pygccxml_dev/pygccxml/declarations/class_declaration.py 2007-01-09 07:11:09 UTC (rev 861) +++ pygccxml_dev/pygccxml/declarations/class_declaration.py 2007-01-09 09:29:03 UTC (rev 862) @@ -80,14 +80,22 @@ def __init__( self, name='' ): """creates class that describes C++ class declaration( and not definition )""" declaration.declaration_t.__init__( self, name ) - + self._aliases = [] + def _get__cmp__items(self): """implementation details""" return [] def i_depend_on_them( self, recursive=True ): return [] - + + def _get_aliases(self): + return self._aliases + def _set_aliases( self, new_aliases ): + self._aliases = new_aliases + aliases = property( _get_aliases, _set_aliases + , doc="List of L{aliases<typedef_t>} to this instance") + class class_t( scopedef.scopedef_t ): """describes class definition""" Modified: pygccxml_dev/pygccxml/parser/source_reader.py =================================================================== --- pygccxml_dev/pygccxml/parser/source_reader.py 2007-01-09 07:11:09 UTC (rev 861) +++ pygccxml_dev/pygccxml/parser/source_reader.py 2007-01-09 09:29:03 UTC (rev 862) @@ -35,7 +35,7 @@ if not isinstance( type_, declarated_t ): continue cls_inst = type_.declaration - if not isinstance( cls_inst, class_t ): + if not isinstance( cls_inst, class_types ): continue if id( cls_inst ) not in visited: visited.add( id( cls_inst ) ) Modified: pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py 2007-01-09 07:11:09 UTC (rev 861) +++ pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py 2007-01-09 09:29:03 UTC (rev 862) @@ -12,6 +12,7 @@ from pyplusplus import messages class decl_wrapper_t(object): + SPECIAL_TYPEDEF_PICK_ANY = True """Declaration interface. This class represents the interface to the declaration tree. Its @@ -47,14 +48,28 @@ name = self.name return algorithm.create_valid_name( name ) - def __select_alias_directives( self ): - if not isinstance( self, declarations.class_t ): + def __select_alias_directives( self, be_smart ): + if not isinstance( self, declarations.class_types ): return [] - return list( set( filter( lambda typedef: typedef.is_directive, self.aliases ) ) ) + typedefs = list( set( filter( lambda typedef: typedef.is_directive, self.aliases ) ) ) + if decl_wrapper_t.SPECIAL_TYPEDEF_PICK_ANY: + if typedefs and be_smart: + longest_name_len = 0 + longest_typedef = None + for typedef in typedefs: + typedef_name_len = len( typedef.name ) + if longest_name_len < typedef_name_len: + longest_name_len = typedef_name_len + longest_typedef = typedef + return [longest_typedef] + else: + return typedefs + else: + return typedefs def _get_alias(self): if not self._alias: - directives = self.__select_alias_directives() + directives = self.__select_alias_directives(be_smart=True) if 1 == len( directives ): self._alias = directives[0].name else: @@ -142,10 +157,10 @@ and self.alias == self._generate_valid_name(): msgs.append( messages.W1043 % self.alias ) - directives = self.__select_alias_directives() + directives = self.__select_alias_directives(be_smart=False) if 1 < len( directives ): msgs.append( messages.W1048 - % ', '.join( map( lambda typedef: typedef.name, directives ) ) ) + % ( self.alias, ', '.join( map( lambda typedef: typedef.name, directives ) ) ) ) msgs.extend( self._readme_impl() ) Modified: pyplusplus_dev/pyplusplus/decl_wrappers/indexing_suite2.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/indexing_suite2.py 2007-01-09 07:11:09 UTC (rev 861) +++ pyplusplus_dev/pyplusplus/decl_wrappers/indexing_suite2.py 2007-01-09 09:29:03 UTC (rev 862) @@ -76,7 +76,7 @@ , doc="Reference to STD container class" ) def _get_container_traits( self ): - return self._get_container_traits() + return self.__container_traits container_traits = property( _get_container_traits , doc="Reference to container traits. See " "pygccxml documentation for STD container traits.") @@ -89,7 +89,9 @@ def _get_call_policies( self ): if self.__call_policies: return self.__call_policies - + if self.container_traits not in declarations.sequential_container_traits: + #TODO: find out why map's don't like the policy + return self.__call_policies element_type = None try: element_type = self.element_type Modified: pyplusplus_dev/pyplusplus/messages/warnings_.py =================================================================== --- pyplusplus_dev/pyplusplus/messages/warnings_.py 2007-01-09 07:11:09 UTC (rev 861) +++ pyplusplus_dev/pyplusplus/messages/warnings_.py 2007-01-09 09:29:03 UTC (rev 862) @@ -143,8 +143,7 @@ 'Other classes : %s' W1048 = 'There are two or more aliases within "pyplusplus::aliases" namespace for ' \ - 'the class. In order to enjoy from automatic aliasing, the class alias ' \ - 'should be unique. Other aliases: %s' + 'the class. Py++ selected "%s" as class alias. Other aliases: %s' W1049 = 'This method could not be overriden in Python - method returns reference ' \ 'to local variable!' Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2007-01-09 07:11:09 UTC (rev 861) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2007-01-09 09:29:03 UTC (rev 862) @@ -300,6 +300,9 @@ if not isuite.has_key( container_name ): continue #not supported + for msg in cls.readme(): + self.decl_logger.warn( "%s;%s" % ( cls, msg ) ) + if isuite is INDEXING_SUITE_2_CONTAINERS: used_headers.add( INDEXING_SUITE_2_MAIN_HEADER ) Modified: pyplusplus_dev/unittests/classes_tester.py =================================================================== --- pyplusplus_dev/unittests/classes_tester.py 2007-01-09 07:11:09 UTC (rev 861) +++ pyplusplus_dev/unittests/classes_tester.py 2007-01-09 09:29:03 UTC (rev 862) @@ -23,6 +23,10 @@ self.failUnless( apple.alias == 'the_tastest_fruit' ) apple.alias = 'apple' + protected_static_t = mb.class_( 'protected_static_t' ) + self.failUnless( 'PROTECTED_STATIC' in protected_static_t.alias) + protected_static_t.alias = 'protected_static_t' + def run_tests(self, module): self.failIfRaisesAny( module.fundamental1 ) self.failIfRaisesAny( module.FUNDAMENTAL2 ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-01-09 07:11:11
|
Revision: 861 http://svn.sourceforge.net/pygccxml/?rev=861&view=rev Author: roman_yakovenko Date: 2007-01-08 23:11:09 -0800 (Mon, 08 Jan 2007) Log Message: ----------- adding ability to guess call policies for indexing suite v2 Modified Paths: -------------- pyplusplus_dev/pyplusplus/decl_wrappers/indexing_suite2.py pyplusplus_dev/unittests/indexing_suites2_tester.py Modified: pyplusplus_dev/pyplusplus/decl_wrappers/indexing_suite2.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/indexing_suite2.py 2007-01-09 06:20:10 UTC (rev 860) +++ pyplusplus_dev/pyplusplus/decl_wrappers/indexing_suite2.py 2007-01-09 07:11:09 UTC (rev 861) @@ -6,7 +6,7 @@ """defines interface for exposing STD containers, using next version of indexing suite""" from pygccxml import declarations - +import call_policies """ method_len method_iter @@ -86,9 +86,21 @@ element_type = property( _get_element_type , doc="Reference to container value_type( mapped_type ) type" ) - def _get_call_policies( self ): - #TODO find out call policies + def _get_call_policies( self ): + if self.__call_policies: + return self.__call_policies + + element_type = None + try: + element_type = self.element_type + except: + return + if declarations.is_const( element_type ): + element_type = declarations.remove_const( element_type ) + if declarations.is_pointer( element_type ): + self.__call_policies = call_policies.return_internal_reference() return self.__call_policies + def _set_call_policies( self, call_policies ): self.__call_policies = call_policies call_policies = property( _get_call_policies, _set_call_policies Modified: pyplusplus_dev/unittests/indexing_suites2_tester.py =================================================================== --- pyplusplus_dev/unittests/indexing_suites2_tester.py 2007-01-09 06:20:10 UTC (rev 860) +++ pyplusplus_dev/unittests/indexing_suites2_tester.py 2007-01-09 07:11:09 UTC (rev 861) @@ -32,8 +32,8 @@ #fvector.indexing_suite.call_policies = module_builder.call_policies.default_call_policies() items_ptr = generator.global_ns.typedef( 'items_ptr_t' ) items_ptr = declarations.remove_declarated( items_ptr.type ) - items_ptr.indexing_suite.call_policies = module_builder.call_policies.return_internal_reference() - + self.failUnless( items_ptr.indexing_suite.call_policies.__class__ + is module_builder.call_policies.return_internal_reference().__class__ ) def run_tests( self, module): fv = module.fvector() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-01-09 06:20:09
|
Revision: 860 http://svn.sourceforge.net/pygccxml/?rev=860&view=rev Author: roman_yakovenko Date: 2007-01-08 22:20:10 -0800 (Mon, 08 Jan 2007) Log Message: ----------- improving error message Modified Paths: -------------- pygccxml_dev/pygccxml/declarations/mdecl_wrapper.py pyplusplus_dev/unittests/mdecl_wrapper_tester.py Modified: pygccxml_dev/pygccxml/declarations/mdecl_wrapper.py =================================================================== --- pygccxml_dev/pygccxml/declarations/mdecl_wrapper.py 2007-01-08 17:28:00 UTC (rev 859) +++ pygccxml_dev/pygccxml/declarations/mdecl_wrapper.py 2007-01-09 06:20:10 UTC (rev 860) @@ -10,6 +10,8 @@ The L{class<mdecl_wrapper_t>} allows user to not write "for" loops within the code. """ +import os + class call_redirector_t( object ): """Internal class used to call some function of objects""" def __init__( self, name, decls ): @@ -65,8 +67,10 @@ def __ensure_attribute( self, name ): invalid_decls = filter( lambda d: not hasattr( d, name ), self.declarations ) + sep = os.linesep + ' ' if invalid_decls: - raise RuntimeError( "Not all declarations have '%s' attribute." % name ) + raise RuntimeError( "Next declarations don't have '%s' attribute: %s" + % ( name, sep.join( map( str, invalid_decls ) ) ) ) def __setattr__( self, name, value ): """Updates the value of attribute on all declarations. Modified: pyplusplus_dev/unittests/mdecl_wrapper_tester.py =================================================================== --- pyplusplus_dev/unittests/mdecl_wrapper_tester.py 2007-01-08 17:28:00 UTC (rev 859) +++ pyplusplus_dev/unittests/mdecl_wrapper_tester.py 2007-01-09 06:20:10 UTC (rev 860) @@ -60,7 +60,7 @@ try: mdw.call_policies = None self.fail( "Runtime error has not been raised." ) - except RuntimeError: + except RuntimeError, err: pass def test__getitem__( self ): @@ -108,4 +108,4 @@ unittest.TextTestRunner(verbosity=2).run( create_suite() ) if __name__ == "__main__": - run_suite() \ No newline at end of file + run_suite() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-01-08 17:28:03
|
Revision: 859 http://svn.sourceforge.net/pygccxml/?rev=859&view=rev Author: roman_yakovenko Date: 2007-01-08 09:28:00 -0800 (Mon, 08 Jan 2007) Log Message: ----------- adding test for vector of pointers Modified Paths: -------------- pyplusplus_dev/unittests/data/indexing_suites2_to_be_exported.hpp pyplusplus_dev/unittests/indexing_suites2_tester.py Modified: pyplusplus_dev/unittests/data/indexing_suites2_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/indexing_suites2_to_be_exported.hpp 2007-01-08 07:23:19 UTC (rev 858) +++ pyplusplus_dev/unittests/data/indexing_suites2_to_be_exported.hpp 2007-01-08 17:28:00 UTC (rev 859) @@ -19,7 +19,8 @@ struct item_t{ item_t() : value( -1 ){} - + explicit item_t( int v) : value( v ){} + bool operator==(item_t const& item) const { return value == item.value; } @@ -36,7 +37,13 @@ typedef std::vector<item_t*> items_ptr_t; inline items_ptr_t create_items_ptr(){ - return items_ptr_t(); + items_ptr_t items; + items.push_back( new item_t(0) ); + items.push_back( new item_t(1) ); + items.push_back( new item_t(2) ); + items.push_back( new item_t(3) ); + items.push_back( new item_t(4) ); + return items; } inline item_t get_value( const std::vector<item_t>& vec, unsigned int index ){ Modified: pyplusplus_dev/unittests/indexing_suites2_tester.py =================================================================== --- pyplusplus_dev/unittests/indexing_suites2_tester.py 2007-01-08 07:23:19 UTC (rev 858) +++ pyplusplus_dev/unittests/indexing_suites2_tester.py 2007-01-08 17:28:00 UTC (rev 859) @@ -53,7 +53,15 @@ items_ptr = module.items_ptr_t() items_ptr.append( item ) self.failUnless( items_ptr[0].value == 1977 ) - + for i in items_ptr: + self.failUnless( i.value == 1977 ) + + items_ptr2 = module.create_items_ptr() + prev_value = -1 + for i in items_ptr2: + self.failUnless( prev_value + 1 == i.value ) + prev_value = i.value + set_of_strings = module.create_set_strings() set_of_strings.add("s") set_of_strings.add("s1") This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |