#ifndef classes_11_11_2006
#define classes_11_11_2006
#include "smart_ptr.h"
struct base_i{
public:
virtual ~base_i() {}
virtual int get_value() const = 0;
};
struct derived_t : base_i{
derived_t(){}
virtual int get_value() const{ return 0xD; }
};
// 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_pointers::smart_ptr_t< derived_t >{
derived_ptr_t()
: smart_pointers::smart_ptr_t< derived_t >()
{}
explicit derived_ptr_t(derived_t* rep)
: smart_pointers::smart_ptr_t<derived_t>(rep)
{}
derived_ptr_t(const derived_ptr_t& r)
: smart_pointers::smart_ptr_t<derived_t>(r) {}
derived_ptr_t( const smart_pointers::smart_ptr_t< base_i >& r)
: smart_pointers::smart_ptr_t<derived_t>()
{
m_managed = static_cast<derived_t*>(r.get());
m_use_count = r.use_count_ptr();
if (m_use_count)
{
++(*m_use_count);
}
}
derived_ptr_t& operator=(const smart_pointers::smart_ptr_t< base_i >& r)
{
if (m_managed == static_cast<derived_t*>(r.get()))
return *this;
release();
m_managed = static_cast<derived_t*>(r.get());
m_use_count = r.use_count_ptr();
if (m_use_count)
{
++(*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() );
}
smart_pointers::smart_ptr_t< base_i > create_base(){
return smart_pointers::smart_ptr_t< base_i >( new derived_t() );
}
// 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_pointers::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_pointers::smart_ptr_t<base>& x);
// smart_pointers::smart_ptr_t<derived> y;
// int z = f(y); // fails to compile
inline int
ref_get_value( smart_pointers::smart_ptr_t< base_i >& a ){
return a->get_value();
}
inline int
val_get_value( smart_pointers::smart_ptr_t< base_i > a ){
return a->get_value();
}
inline int
const_ref_get_value( const smart_pointers::smart_ptr_t< base_i >& a ){
return a->get_value();
}
struct numeric_t{
numeric_t()
: value(0)
{}
int value;
};
smart_pointers::smart_ptr_t< numeric_t > create_numeric( int value ){
smart_pointers::smart_ptr_t< numeric_t > num( new numeric_t() );
num->value = value;
return num;
}
int get_numeric_value( smart_pointers::smart_ptr_t< numeric_t > n ){
if( n.get() ){
return n->value;
}
else{
return 0;
}
}
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_pointers::smart_ptr_t< buffer_t > get_data(){ return data; }
smart_pointers::smart_ptr_t< buffer_t > data;
};
}
#endif//classes_11_11_2006