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.
|