[C++-sig] wrapper & HeldType

Roman Yakovenko roman.yakovenko at gmail.com
Wed Oct 19 07:38:12 CEST 2005


On 10/17/05, David Abrahams <dave at boost-consulting.com> wrote:
> I'm sorry, that looks neither minimal nor complete.

> I'm _sure_ you can illustrate your point with just a few functions and
> one (or at most two) classes. No?

Yes I am. I am sorry for being unclear. Before proceeding, I would
like to clear something. What I am trying to show are problems with
boost.python interface to user and not functionality. All code that I
show works okay. I will try to explain my self here and I attached
files you've asked.

I am talking about next use case: I have class with virtual function.
In order to override
it's virtual function I use boost::python::wrapper. Also I'd like to
have std::auto_ptr
( or shared_ptr ) as it's held type.

Now code.

My class:

struct data{
    virtual int id() const{
        return int(this);
    }
}

namespace bp = boost::python;

struct data_wrapper : data, bp::wrapper< data > {
    //If you remove PyObject* code will stop to compile

    data_wrapper(PyObject*, data const & arg )
    //-------------^^^^^^^^^^^
    //1. bp::wrapper< data > will hold PyObject* self by it self
    //2. I need it here because otherwise
   //    bp::register_ptr_to_python< std::auto_ptr< data > >()   will
not compile.
    : data( arg )
      , bp::wrapper< data >()
    {}

    data_wrapper(PyObject*)
    //same point here
    : data()
      , bp::wrapper< data >()
    {}

...

}

  bp::class_< data, data_wrapper, std::auto_ptr< data > >( "data" )
    //------------^^^^
    //I see no reasons to give class data as argument to class_
    //I do it only for HeldType functionality. Better interface could
be without requiring
    //class data as argument

The point is that you introduced new cool class wrapper, but not all
code has been
adopted to work with it. Also within documentation for example

here
http://boost.org/libs/python/doc/v2/register_ptr_to_python.html
and here
http://boost.org/libs/python/doc/v2/call_method.html
you are using old method of "overriding" virtual function in Python. If you try
to re-write those examples using boost::python::wrapper class you will see
my point.

Hope this time I was clear.

> --
> Dave Abrahams
> Boost Consulting
> www.boost-consulting.com


Thanks

Roman Yakovenko
-------------- next part --------------
#include "boost/python.hpp"

#include <memory>

struct data{

    virtual int id() const{
        return int(this);
    }
    
};
    
std::auto_ptr<data> create_data() { 
    return std::auto_ptr<data>( new data ); 
}

void do_nothing( std::auto_ptr<data>& ){}

    
namespace bp = boost::python;

struct data_wrapper : data, bp::wrapper< data > {
    //If you remove PyObject* code will stop to compile
    
    data_wrapper(PyObject*, data const & arg )
    //-------------^^^^^^^^^^^ 
    //1. bp::wrapper< data > will hold PyObject* self by it self
    //2. I need it here because otherwise bp::register_ptr_to_python< std::auto_ptr< data > >()
    //   will not compile. 
    : data( arg )
      , bp::wrapper< data >()
    {}

    data_wrapper(PyObject*)
    //same point here
    : data()
      , bp::wrapper< data >()
    {}

    virtual int id(  ) const {
        if( bp::override id = this->get_override( "id" ) )
            return id(  );
        else
            return data::id(  );
    }
    
    virtual int default_id(  ) const {
        return this->data::id( );
    }

};

BOOST_PYTHON_MODULE(xyz){
    bp::class_< data, data_wrapper, std::auto_ptr< data > >( "data" )    
    //------------^^^^ 
    //I see no reasons to give class data as argument to class_
    //I do it only for HeldType functionality. Better interface could be without requiring    
    //class data as argument
        .def( "id", &data::id, &::data_wrapper::default_id, bp::default_call_policies() );

    bp::register_ptr_to_python< std::auto_ptr< data > >();

    bp::def( "do_nothing"
            , &do_nothing
            , ( bp::arg("arg0") )
            , bp::default_call_policies() );

    bp::def( "create_data", &create_data, bp::default_call_policies() );
}    
-------------- next part --------------
import xyz

d = xyz.create_data()
print d.id()
xyz.do_nothing( d )
print d.id()


More information about the Cplusplus-sig mailing list