Revision: 643
http://svn.sourceforge.net/pygccxml/?rev=643&view=rev
Author: roman_yakovenko
Date: 2006-10-10 15:06:12 -0700 (Tue, 10 Oct 2006)
Log Message:
-----------
adding comments to the smart pointer example
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/smart_ptr.h
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-10-10 20:53:26 UTC (rev 642)
+++ pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/bindings.cpp 2006-10-10 22:06:12 UTC (rev 643)
@@ -10,6 +10,12 @@
namespace boost{ namespace python{
+ //We need to tell Boost.Python how to work with your smart pointer.
+ //You can read more about this functionality in the reference manual:
+ //http://boost.org/libs/python/doc/v2/pointee.html .
+ //In general
+ // 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();
@@ -20,7 +26,6 @@
typedef T type;
};
-
inline derived_t * get_pointer(derived_ptr_t const& p){
return p.get();
}
@@ -32,7 +37,6 @@
} }
-
struct base_wrapper_t : base_i, bp::wrapper< base_i > {
base_wrapper_t()
@@ -75,14 +79,31 @@
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 >.
.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.This will allow Boost.Python
+ //to treat right functions, which expect to get as argument smart_ptr_t< base_i >
+ //class instance.
+ //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 .
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.
.def( "get_value", &derived_t::get_value, &derived_wrapper_t::default_get_value );
+ //Nothing special, just registering 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 > >();
Modified: pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/classes.hpp
===================================================================
--- pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/classes.hpp 2006-10-10 20:53:26 UTC (rev 642)
+++ pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/classes.hpp 2006-10-10 22:06:12 UTC (rev 643)
@@ -1,3 +1,7 @@
+#ifndef classes_11_11_2006
+#define classes_11_11_2006
+
+
#include "smart_ptr.h"
struct base_i{
@@ -2,16 +6,13 @@
public:
- virtual ~base_i() { }
+ virtual ~base_i() {}
virtual int get_value() const = 0;
};
-
struct derived_t : base_i{
- derived_t()
- {}
-
- virtual int get_value() const{
- return 11;
- }
+ 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.
struct derived_ptr_t : public smart_ptr_t< derived_t >{
@@ -32,31 +33,32 @@
derived_ptr_t( const smart_ptr_t< base_i >& r)
: smart_ptr_t<derived_t>()
{
- pRep = static_cast<derived_t*>(r.getPointer());
- pUseCount = r.useCountPointer();
- if (pUseCount)
+ m_managed = static_cast<derived_t*>(r.get());
+ m_use_count = r.use_count_ptr();
+ if (m_use_count)
{
- ++(*pUseCount);
+ ++(*m_use_count);
}
}
derived_ptr_t& operator=(const smart_ptr_t< base_i >& r)
{
- if (pRep == static_cast<derived_t*>(r.getPointer()))
+ if (m_managed == static_cast<derived_t*>(r.get()))
return *this;
release();
- pRep = static_cast<derived_t*>(r.getPointer());
- pUseCount = r.useCountPointer();
- if (pUseCount)
+ m_managed = static_cast<derived_t*>(r.get());
+ m_use_count = r.use_count_ptr();
+ if (m_use_count)
{
- ++(*pUseCount);
+ ++(*m_use_count);
}
-
+
return *this;
}
};
-
+//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() );
}
@@ -71,8 +73,8 @@
//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_i>& x) { return 0; }
-// smart_ptr_t<base_wrapper_t> y;
+// int f(smart_ptr_t<base>& x) { return 0; }
+// smart_ptr_t<derived> y;
// int z = f(y); // fails to compile
inline int
@@ -89,3 +91,6 @@
const_ref_get_value( const smart_ptr_t< base_i >& a ){
return a->get_value();
}
+
+#endif//classes_11_11_2006
+
Modified: pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/smart_ptr.h
===================================================================
--- pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/smart_ptr.h 2006-10-10 20:53:26 UTC (rev 642)
+++ pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/smart_ptr.h 2006-10-10 22:06:12 UTC (rev 643)
@@ -3,70 +3,84 @@
#include <assert.h>
-template<class T> class smart_ptr_t {
+//The smart_ptr_t class has been created based on Ogre::SharedPtr class
+//http://www.ogre3d.org/docs/api/html/OgreSharedPtr_8h-source.html
+
+template<class T>
+class smart_ptr_t {
protected:
- T* pRep;
- unsigned int* pUseCount;
+ T* m_managed;
+ unsigned int* m_use_count;
public:
smart_ptr_t()
- : pRep(0), pUseCount(0)
+ : m_managed(0), m_use_count(0)
{}
- //What will happen if rep is NULL? -> bug
+ //rep should not be NULL
explicit smart_ptr_t(T* rep)
- : pRep(rep), pUseCount( new unsigned int(1) )
+ : m_managed(rep), m_use_count( new unsigned int(1) )
{}
+ //Every custom smart pointer class should have copy constructor and
+ //assignment operator. Probably you smart pointer class already has this
+ //functionality.
smart_ptr_t(const smart_ptr_t& r)
- : pRep(0), pUseCount(0)
+ : m_managed(0), m_use_count(0)
{
- pRep = r.get();
- pUseCount = r.useCountPointer();
- if(pUseCount){
- ++(*pUseCount);
+ m_managed = r.get();
+ m_use_count = r.use_count_ptr();
+ if(m_use_count){
+ ++(*m_use_count);
}
}
smart_ptr_t& operator=(const smart_ptr_t& r){
- if( pRep == r.pRep ){
+ if( m_managed == r.m_managed ){
return *this;
}
-
release();
-
- pRep = r.get();
- pUseCount = r.useCountPointer();
- if(pUseCount){
- ++(*pUseCount);
+
+ m_managed = r.get();
+ m_use_count = r.use_count_ptr();
+ if(m_use_count){
+ ++(*m_use_count);
}
return *this;
}
-
+ //Next two functions allows to construct smart pointer from an existing one,
+ //which manages object with a different type.
+ //For example:
+ // struct base{...};
+ // struct derived : base { ... };
+ // smart_ptr_t< base > b( smart_ptr_t<derived>() );
+ //
+ //This functionality is very important for C++ Python bindings. It will allow
+ //us to register smart pointer conversion:
+ // boost::python::implicitly_convertible< smart_ptr_t< derived >, smart_ptr_t< base > >();
template<class Y>
smart_ptr_t(const smart_ptr_t<Y>& r)
- : pRep(0), pUseCount(0)
+ : m_managed(0), m_use_count(0)
{
- pRep = r.get();
- pUseCount = r.useCountPointer();
- if(pUseCount){
- ++(*pUseCount);
+ m_managed = r.get();
+ m_use_count = r.use_count_ptr();
+ if(m_use_count){
+ ++(*m_use_count);
}
}
template< class Y>
smart_ptr_t& operator=(const smart_ptr_t<Y>& r){
- if( pRep == r.pRep ){
+ if( m_managed == r.m_managed ){
return *this;
}
-
release();
-
- pRep = r.get();
- pUseCount = r.useCountPointer();
- if(pUseCount){
- ++(*pUseCount);
+
+ m_managed = r.get();
+ m_use_count = r.use_count_ptr();
+ if(m_use_count){
+ ++(*m_use_count);
}
return *this;
}
@@ -76,43 +90,39 @@
}
inline T& operator*() const {
- assert(pRep); return *pRep;
+ assert(m_managed); return *m_managed;
}
inline T* operator->() const {
- assert(pRep); return pRep;
+ assert(m_managed); return m_managed;
}
inline T* get() const {
- return pRep;
+ return m_managed;
}
- inline unsigned int* useCountPointer() const {
- return pUseCount;
+ inline unsigned int* use_count_ptr() const {
+ return m_use_count;
}
- inline T* getPointer() const {
- return pRep;
- }
-
protected:
inline void release(void){
- bool destroyThis = false;
+ bool destroy_this = false;
- if( pUseCount ){
- if( --(*pUseCount) == 0){
- destroyThis = true;
+ if( m_use_count ){
+ if( --(*m_use_count) == 0){
+ destroy_this = true;
}
}
- if (destroyThis){
+ if (destroy_this){
destroy();
}
}
virtual void destroy(void){
- delete pRep;
- delete pUseCount;
+ delete m_managed;
+ delete m_use_count;
}
};
Modified: pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/test.py
===================================================================
--- pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/test.py 2006-10-10 20:53:26 UTC (rev 642)
+++ pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/test.py 2006-10-10 22:06:12 UTC (rev 643)
@@ -13,7 +13,7 @@
custom_sptr.derived_t.__init__( self )
def get_value( self ):
- return 31
+ return 0xDD
class tester_t( unittest.TestCase ):
def __init__( self, *args ):
@@ -41,20 +41,20 @@
self.__test_const_ref( inst, val )
def test_derived( self ):
- self.__test_impl( custom_sptr.derived_t(), 11 )
+ self.__test_impl( custom_sptr.derived_t(), 0xD )
def test_py_derived( self ):
self.__test_impl( py_derived_t(), 28 )
def test_py_double_derived( self ):
- self.__test_impl( py_double_derived_t(), 31 )
+ self.__test_impl( py_double_derived_t(), 0xDD )
def test_created_derived( self ):
- self.__test_impl( custom_sptr.create_derived(), 11 )
+ self.__test_impl( custom_sptr.create_derived(), 0xD )
def test_created_base( self ):
inst = custom_sptr.create_base()
- val = 11
+ val = 0xD
self.__test_ref_fine( inst, val )
self.__test_val( inst, val )
self.__test_const_ref( inst, val )
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|