Revision: 786
http://svn.sourceforge.net/pygccxml/?rev=786&view=rev
Author: roman_yakovenko
Date: 2006-12-08 11:46:21 -0800 (Fri, 08 Dec 2006)
Log Message:
-----------
adding work around for smart pointers as member variables
Modified Paths:
--------------
pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/bindings.cpp
pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/classes.hpp
pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/test.py
Modified: pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/bindings.cpp
===================================================================
--- pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/bindings.cpp 2006-12-07 10:39:03 UTC (rev 785)
+++ pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/bindings.cpp 2006-12-08 19:46:21 UTC (rev 786)
@@ -3,30 +3,30 @@
namespace bp = boost::python;
-namespace boost{ namespace python{
+// "get_pointer" function returns pointer to the object managed by smart pointer
+// class instance
- //We need to tell Boost.Python how to work with your smart pointer.
- //Short explanation:
- // "get_pointer" extracts the pointer to the object it manages.
- // "pointee" extracts the type of the object, smart pointer manages.
+template<class T>
+inline T * get_pointer(smart_ptr_t<T> const& p){
+ return p.get();
+}
+
+inline derived_t * get_pointer(derived_ptr_t const& p){
+ return p.get();
+}
- //You can read more about this functionality in the reference manual:
- //http://boost.org/libs/python/doc/v2/pointee.html .
+namespace boost{ namespace python{
- template<class T>
- inline T * get_pointer(smart_ptr_t<T> const& p){
- return p.get();
- }
+ // "pointee" class tells Boost.Python the type of the object managed by smart
+ // pointer class.
+ // You can read more about "pointee" class here:
+ // http://boost.org/libs/python/doc/v2/pointee.html
template <class T>
struct pointee< smart_ptr_t<T> >{
typedef T type;
};
- inline derived_t * get_pointer(derived_ptr_t const& p){
- return p.get();
- }
-
template<>
struct pointee< derived_ptr_t >{
typedef derived_t type;
@@ -34,6 +34,9 @@
} }
+// "get_pointer" and "pointee" are needed, in order to allow Boost.Python to
+// work with user defined smart pointer
+
struct base_wrapper_t : base_i, bp::wrapper< base_i > {
base_wrapper_t()
@@ -76,33 +79,33 @@
BOOST_PYTHON_MODULE( custom_sptr ){
bp::class_< base_wrapper_t, boost::noncopyable, smart_ptr_t< base_wrapper_t > >( "base_i" )
- //----------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- //HeldType of the abstract class, which is managed by custom smart pointer
- //should be smart_ptr_t< base_wrapper_t >.
+ // ---------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ // HeldType of the abstract class, which is managed by custom smart pointer
+ // should be smart_ptr_t< base_wrapper_t >.
.def( "get_value", bp::pure_virtual( &base_i::get_value ) );
- //Register implicit conversion between smart pointers. Boost.Python library
- //can not discover relationship between classes. You have to tell about the
- //relationship to it. This will allow Boost.Python to treat right, the
- //functions, which expect to get as argument smart_ptr_t< base_i > class
- //instance, when smart_ptr_t< derived from base_i > class instance is passed.
+ // Register implicit conversion between smart pointers. Boost.Python library
+ // can not discover relationship between classes. You have to tell about the
+ // relationship to it. This will allow Boost.Python to treat right, the
+ // functions, which expect to get as argument smart_ptr_t< base_i > class
+ // instance, when smart_ptr_t< derived from base_i > class instance is passed.
//
- //For more information about implicitly_convertible see the documentation:
- //http://boost.org/libs/python/doc/v2/implicit.html .
+ // For more information about implicitly_convertible see the documentation:
+ // http://boost.org/libs/python/doc/v2/implicit.html .
bp::implicitly_convertible< smart_ptr_t< base_wrapper_t >, smart_ptr_t< base_i > >();
- //The register_ptr_to_python functionality is explaned very well in the
- //documentation:
- //http://boost.org/libs/python/doc/v2/register_ptr_to_python.html .
+ // The register_ptr_to_python functionality is explaned very well in the
+ // documentation:
+ // http://boost.org/libs/python/doc/v2/register_ptr_to_python.html .
bp::register_ptr_to_python< smart_ptr_t< base_i > >();
bp::class_< derived_wrapper_t, bp::bases< base_i >, smart_ptr_t<derived_wrapper_t> >( "derived_t" )
- //--------------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- //Pay attention on the class HeldType. It will allow us to create new classes
- //in Python, which derive from the derived_t class.
+ // -------------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ // Pay attention on the class HeldType. It will allow us to create new classes
+ // in Python, which derive from the derived_t class.
.def( "get_value", &derived_t::get_value, &derived_wrapper_t::default_get_value );
- //Now register all existing conversion:
+ // Now register all existing conversion:
bp::implicitly_convertible< smart_ptr_t< derived_wrapper_t >, smart_ptr_t< derived_t > >();
bp::implicitly_convertible< smart_ptr_t< derived_t >, smart_ptr_t< base_i > >();
bp::implicitly_convertible< derived_ptr_t, smart_ptr_t< derived_t > >();
@@ -113,4 +116,23 @@
bp::def( "val_get_value", &::val_get_value );
bp::def( "create_derived", &::create_derived );
bp::def( "create_base", &::create_base );
+
+ // Work around for the public member variable, where type of the variable
+ // is smart pointer problem
+ bp::class_< shared_data::buffer_t >( "buffer_t" )
+ .def_readwrite( "size", &shared_data::buffer_t::size );
+
+ bp::register_ptr_to_python< smart_ptr_t< shared_data::buffer_t > >();
+
+ bp::class_< shared_data::buffer_holder_t >( "buffer_holder_t" )
+ .def( "get_data", &shared_data::buffer_holder_t::get_data )
+ .def_readwrite( "data_naive", &shared_data::buffer_holder_t::data )
+ // If you will try to access "data_naive" you will get
+ // TypeError: No Python class registered for C++ class smart_ptr_t<shared_data::buffer_t>
+ // Next lines of code contain work around
+ .add_property( "data"
+ , bp::make_getter( &shared_data::buffer_holder_t::data
+ , bp::return_value_policy<bp::copy_non_const_reference>() )
+ , bp::make_setter( &shared_data::buffer_holder_t::data ) );
+
}
Modified: pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/classes.hpp
===================================================================
--- pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/classes.hpp 2006-12-07 10:39:03 UTC (rev 785)
+++ pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/classes.hpp 2006-12-08 19:46:21 UTC (rev 786)
@@ -13,9 +13,10 @@
derived_t(){}
virtual int get_value() const{ return 0xD; }
};
-
-//Small convenience class. Actually it is defined here, because this is a pattern
-//Ogre project uses.
+
+// Some smart pointer classes does not have reach interface as boost ones.
+// In order to provide same level of convenience, users are forced to create
+// classes, which derive from smart pointer class.
struct derived_ptr_t : public smart_ptr_t< derived_t >{
derived_ptr_t()
@@ -56,8 +57,8 @@
}
};
-//Few functions that will be used to test custom smart pointer functionality
-//from Python.
+// Few functions that will be used to test custom smart pointer functionality
+// from Python.
derived_ptr_t create_derived(){
return derived_ptr_t( new derived_t() );
}
@@ -67,16 +68,16 @@
}
-//Next function could be exposed, but it could not be called from Python, when
-//the argument is the instance of a derived class.
+// Next function could be exposed, but it could not be called from Python, when
+// the argument is the instance of a derived class.
//
-//This is the explanation David Abrahams gave:
-// Naturally; there is no instance of smart_ptr_t<base_i> anywhere in the
-// Python object for the reference to bind to. The rules are the same as in C++:
+// This is the explanation David Abrahams gave:
+// Naturally; there is no instance of smart_ptr_t<base_i> anywhere in the
+// Python object for the reference to bind to. The rules are the same as in C++:
//
-// int f(smart_ptr_t<base>& x);
-// smart_ptr_t<derived> y;
-// int z = f(y); // fails to compile
+// int f(smart_ptr_t<base>& x);
+// smart_ptr_t<derived> y;
+// int z = f(y); // fails to compile
inline int
ref_get_value( smart_ptr_t< base_i >& a ){
@@ -93,5 +94,30 @@
return a->get_value();
}
+namespace shared_data{
+
+// Boost.Python has small problem with user defined smart pointers and public
+// member variables, exposed using def_readonly, def_readwrite functionality
+// Read carefully "make_getter" documentation.
+// http://boost.org/libs/python/doc/v2/data_members.html#make_getter-spec
+// bindings.cpp contains solution to the problem.
+
+struct buffer_t{
+ buffer_t() : size(0) {}
+ int size;
+};
+
+struct buffer_holder_t{
+ buffer_holder_t()
+ : data( new buffer_t() )
+ {}
+
+ smart_ptr_t< buffer_t > get_data(){ return data; }
+
+ smart_ptr_t< buffer_t > data;
+};
+
+}
+
#endif//classes_11_11_2006
Modified: pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/test.py
===================================================================
--- pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/test.py 2006-12-07 10:39:03 UTC (rev 785)
+++ pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/test.py 2006-12-08 19:46:21 UTC (rev 786)
@@ -59,6 +59,16 @@
self.__test_val( inst, val )
self.__test_const_ref( inst, val )
+ def test_mem_var_access( self ):
+ holder = custom_sptr.buffer_holder_t()
+ self.failUnless( holder.get_data().size == 0 )
+ self.failUnless( holder.data.size == 0 )
+ try:
+ self.failUnless( holder.data_naive.size == 0 )
+ self.fail("TypeError exception was not raised.")
+ except TypeError:
+ pass
+
def create_suite():
suite = unittest.TestSuite()
suite.addTest( unittest.makeSuite(tester_t))
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|