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