[pygccxml-commit] SF.net SVN: pygccxml: [736] pyplusplus_dev/docs/bpl_lessons_learned
Brought to you by:
mbaas,
roman_yakovenko
From: <rom...@us...> - 2006-11-20 13:27:24
|
Revision: 736 http://svn.sourceforge.net/pygccxml/?rev=736&view=rev Author: roman_yakovenko Date: 2006-11-20 05:27:21 -0800 (Mon, 20 Nov 2006) Log Message: ----------- adding shared_ptr< const T> documentation Modified Paths: -------------- pyplusplus_dev/docs/bpl_lessons_learned/lessons_learned.rest pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/www_configuration.py Added Paths: ----------- pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/ pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/definition.rest pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/generate_code.py pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/sconstruct pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/sconstruct.rest pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/shared_ptr.rest pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/solution.cpp pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/solution.cpp.rest pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/test.py pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/test.py.rest pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/www_configuration.py Modified: pyplusplus_dev/docs/bpl_lessons_learned/lessons_learned.rest =================================================================== --- pyplusplus_dev/docs/bpl_lessons_learned/lessons_learned.rest 2006-11-20 08:46:26 UTC (rev 735) +++ pyplusplus_dev/docs/bpl_lessons_learned/lessons_learned.rest 2006-11-20 13:27:21 UTC (rev 736) @@ -14,13 +14,18 @@ On this page you will find my collection of the solutions to some of the problems. -`Custom smart pointer class`_ +`custom smart pointer class`_ .. include:: ./smart_ptrs/definition.rest -.. _`Custom smart pointer class` : ./smart_ptrs/smart_ptrs.html +.. _`custom smart pointer class` : ./smart_ptrs/smart_ptrs.html +`boost::shared_ptr< const T>`_ + .. include:: ./shared_ptr/definition.rest + +.. _`boost::shared_ptr< const T>` : ./shared_ptr/shared_ptr.html + .. _`Py++` : ./../pyplusplus.html .. _`pygccxml` : http://www.language-binding.net/pygccxml/pygccxml.html .. _`SourceForge`: http://sourceforge.net/index.php Added: pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/definition.rest =================================================================== --- pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/definition.rest (rev 0) +++ pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/definition.rest 2006-11-20 13:27:21 UTC (rev 736) @@ -0,0 +1,3 @@ +Boost.Python works pretty well with ``boost::shared_ptr< T >`` class, but +additional work should be done if you want to register a conversion to +``boost::shared_ptr< const T>`` class. Added: pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/generate_code.py =================================================================== --- pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/generate_code.py (rev 0) +++ pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/generate_code.py 2006-11-20 13:27:21 UTC (rev 736) @@ -0,0 +1,120 @@ +#The code contained in this file will show you how to instruct Py++ to generate +#code, that uses your smart pointer class. +# + +#Advise: +#Using your favorite editor create regular C++ header file and to it next code. +#You don't really need to generate it every time. +# +# template<class T> +# inline T * get_pointer(smart_ptr_t<T> const& p){ +# return p.get(); +# } +# +# template <class T> +# struct pointee< smart_ptr_t<T> >{ +# typedef T type; +# }; + + +HELD_TYPE_TMPL = \ +""" +namespace boost{ namespace python{ + +%(class_name)s* get_pointer( %(class_ptr_name)s const& p ){ + return p.get(); +} + +template <> +struct pointee< %(class_ptr_name)s >{ + typedef %(class_name)s type; +}; + +}}// namespace boost::python +""" + +REGISTER_PTR_TO_PYTHON_TMPL = \ +""" +boost::python::register_ptr_to_python< %(sp_inst_class_name)s >(); +""" + +IMPLICITLY_CONVERTIBLE_TMPL = \ +""" +boost::python::implicitly_convertible< %(derived)s, %(base)s >(); +""" + + +def get_pointee( sp_instantiation ): + #sp_instantiation - reference to smart_ptr_t<XXX> + #returns reference to XXX type/declaration + #I will find m_managed member variable and will find out its type + no_ptr = declarations.remove_pointer( sp_instantiation.variable ('m_managed').type ) + no_alias = declarations.remove_alias( no_ptr ) + return declarations.remove_declarated( no_alias ) + +def expose_single( sp_instantiation ): + #This function instructs Py++ how to expose pointee class functionality + #related to your smart pointer + #sp_instantiation - reference to smart_ptr_t<XXX> + + # You don't need to expose smart_ptr_t< X > class + sp_instantiation.exclude() + + pointee = get_pointee( sp_instantiation ) + + #Our example defines derived_ptr_t class: + #struct derived_ptr_t : public smart_ptr_t< derived_t > + #{...}; + #Next if checks that smart_ptr_t< XXX > class has a derived class + #and "exposes" it. + if sp_instantiation.derived: + assert 1 == len( sp_instantiation.derived ) + sp_derived = sp_instantiation.derived[0].related_class + #You don't want to expose it + sp_derived.exclude() + + #Adding your custom code to pointee class. + #You don't have to warry about order or place of generated code, + #Py++ does it right. + + #Telling Boost.Python how to work with your smart pointer + pointee.add_declaration_code( + HELD_TYPE_TMPL % { 'class_name': pointee.decl_string + , 'class_ptr_name': sp_derived.decl_string } ) + + #Telling Boost.Python about relationship between classes + pointee.add_registration_code( + IMPLICITLY_CONVERTIBLE_TMPL % { 'derived' : sp_derived.decl_string + , 'base' : sp_instantiation.decl_string } + , works_on_instance=False ) + + pointee.add_registration_code( + REGISTER_PTR_TO_PYTHON_TMPL % { 'sp_inst_class_name' : sp_derived.decl_string } + , works_on_instance=False ) + + #Setting class held type + pointee.held_type = 'smart_ptr_t< %s >' % pointee.wrapper_alias + + #Registering relationships between classes + pointee.add_registration_code( + IMPLICITLY_CONVERTIBLE_TMPL % { 'derived' : pointee.held_type + , 'base' : sp_instantiation.decl_string } + , works_on_instance=False ) + + pointee.add_registration_code( + REGISTER_PTR_TO_PYTHON_TMPL % { 'sp_inst_class_name' : sp_instantiation.decl_string } + , works_on_instance=False ) + + #Registering relationships between classes + base_classes = filter( lambda hierarchy_info: hierarchy_info.access_type == 'public', pointee.bases ) + for base in base_classes: + pointee.add_registration_code( + IMPLICITLY_CONVERTIBLE_TMPL % { 'derived' : sp_instantiation.decl_string + , 'base' : 'smart_ptr_t< %s >' % base.related_class.decl_string } + , works_on_instance=False) + +def expose(mb): + sp_instantiations = mb.classes( lambda decl: decl.name.startswith( 'smart_ptr_t' ) ) + map( lambda sp: expose_single( sp ), sp_instantiations ) + + Added: pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/sconstruct =================================================================== --- pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/sconstruct (rev 0) +++ pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/sconstruct 2006-11-20 13:27:21 UTC (rev 736) @@ -0,0 +1,10 @@ +#scons build script +SharedLibrary( target=r'custom_sptr' + , source=[ r'bindings.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' +) Added: pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/sconstruct.rest =================================================================== --- pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/sconstruct.rest (rev 0) +++ pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/sconstruct.rest 2006-11-20 13:27:21 UTC (rev 736) @@ -0,0 +1,3 @@ +.. code-block:: + :language: Python + :source-file: ./sconstruct Added: pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/shared_ptr.rest =================================================================== --- pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/shared_ptr.rest (rev 0) +++ pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/shared_ptr.rest 2006-11-20 13:27:21 UTC (rev 736) @@ -0,0 +1,89 @@ +=================================================== +How to register ``shared_ptr<const T>`` conversion? +=================================================== + +.. contents:: Table of contents + +------------ +Introduction +------------ + +.. include:: ./definition.rest + +-------- +Solution +-------- + +The solution is pretty simple: + + .. code-block:: C++ + + namespace boost{ namespace python{ + + template<class T> + inline T* get_pointer( boost::shared_ptr<const T> const& p ){ + return const_cast<T*>(p.get()); + } + + template<class T> + struct pointee< boost::shared_ptr<const T> >{ + 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 >(); + } + +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. + +* `sconstruct`_ file contains build instructions for scons build tool. + +* `test.py`_ file contains complete unit tests for the exposed classes + +All files contain comments, which describe what and why was done. + +.. _`solution.cpp` : ./solution.hpp.html +.. _`sconstruct` : ./sconstruct.html +.. _`test.py` : ./test.py.html + +-------- +Download +-------- + +https://sourceforge.net/project/showfiles.php?group_id=118209 + + +.. _`Py++` : ./../pyplusplus.html +.. _`pygccxml` : http://www.language-binding.net/pygccxml/pygccxml.html +.. _`SourceForge`: http://sourceforge.net/index.php + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: + Added: pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/solution.cpp =================================================================== --- pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/solution.cpp (rev 0) +++ pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/solution.cpp 2006-11-20 13:27:21 UTC (rev 736) @@ -0,0 +1,77 @@ +#include "boost/python.hpp" +#include "boost/shared_ptr.hpp" +#include <string> + +//Your code: + +struct info_t{ + //class info_t records in what function it was created information + info_t( const std::string& n ) + : text( n ) + {} + + std::string text; +}; + +typedef boost::shared_ptr< info_t > ptr_t; +typedef boost::shared_ptr< const info_t > const_ptr_t; + +ptr_t create_ptr(){ + return ptr_t( new fruit( "ptr" ) ); +} + +const_ptr_t create_const_ptr(){ + return const_ptr_t( new fruit( "const ptr" ) ); +} + +std::string read_ptr( ptr_t x ){ + if( !x ) + return ""; + return x->text; +} + +std::string read_const_ptr( const_ptr_t x ){ + if( !x ) + return ""; + return x->text; +} + + +namespace boost{ namespace python{ + + template<class T> + inline T* get_pointer( boost::shared_ptr<const T> const& p ){ + return const_cast<T*>(p.get()); + } + + template<class T> + struct pointee< boost::shared_ptr<const T> >{ + typedef T type; + }; + +} } //boost::python + +namespace bpl = boost::python; + +namespace utils{ + + template< class T > + register_shared_ptrs_to_python(){ + //small helper function, which will register shared_ptr conversions + 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( shared_ptr ){ + bpl::class_< fruit >( "fruit", bp::init< std::string >() ); + utils::register_shared_ptrs_to_python< fruit >(); + + bpl::def( "create_ptr", &create_ptr ); + bpl::def( "create_const_ptr", &create_const_ptr ); + bpl::def( "read_ptr", &read_ptr ); + bpl::def( "read_const_ptr", &read_const_ptr ); + +} Added: pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/solution.cpp.rest =================================================================== --- pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/solution.cpp.rest (rev 0) +++ pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/solution.cpp.rest 2006-11-20 13:27:21 UTC (rev 736) @@ -0,0 +1,3 @@ +.. code-block:: + :language: C++ + :source-file: ./solution.cpp Added: pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/test.py =================================================================== --- pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/test.py (rev 0) +++ pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/test.py 2006-11-20 13:27:21 UTC (rev 736) @@ -0,0 +1,29 @@ +import unittest +import shared_ptr + + +class tester_t( unittest.TestCase ): + def __init__( self, *args ): + unittest.TestCase.__init__( self, *args ) + + def test( self ): + ptr = shared_ptr.create_ptr() + self.failUnless( ptr.name == "ptr" ) + self.failUnless( shared_ptr.read_ptr( ptr ) == "ptr" ) + + const_ptr = shared_ptr.create_const_ptr() + self.failUnless( const_ptr.name == "const ptr" ) + self.failUnless( shared_ptr.read_const_ptr( const_ptr ) == "const ptr" ) + + self.failUnless( shared_ptr.read_const_ptr( ptr ) == "ptr" ) + +def create_suite(): + suite = unittest.TestSuite() + suite.addTest( unittest.makeSuite(tester_t)) + return suite + +def run_suite(): + unittest.TextTestRunner(verbosity=2).run( create_suite() ) + +if __name__ == "__main__": + run_suite() Added: pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/test.py.rest =================================================================== --- pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/test.py.rest (rev 0) +++ pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/test.py.rest 2006-11-20 13:27:21 UTC (rev 736) @@ -0,0 +1,3 @@ +.. code-block:: + :language: Python + :source-file: ./test.py Added: pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/www_configuration.py =================================================================== --- pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/www_configuration.py (rev 0) +++ pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/www_configuration.py 2006-11-20 13:27:21 UTC (rev 736) @@ -0,0 +1,3 @@ +name = 'shared_ptr< const T>' +files_to_skip = ['definition.rest'] +names = {} Modified: pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/www_configuration.py =================================================================== --- pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/www_configuration.py 2006-11-20 08:46:26 UTC (rev 735) +++ pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/www_configuration.py 2006-11-20 13:27:21 UTC (rev 736) @@ -1,3 +1,3 @@ -name = 'Custom smart pointer' +name = 'custom smart pointer' files_to_skip = ['definition.rest'] names = {} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |