Dear Boost::python experts,

I am trying to use a custom shared pointer type instead of
boost::shared_pointer, in my case Teuchos::RCP from the Trilinos
project. The details of Teuchos::RCP should not matter much here. In
any case there is a Doxygen documentation on the Trilinos webpage.

For completeness I attached a simple example code, but let me explain
here the problem. I have two simple classes A and B, where B is
derived from A.

The C++-functions:

void computeOnA(Teuchos::RCP<A> a)
{
    a->a *= 2;
}
and

void computeOnAs(boost::shared_ptr<A> a)
{
    a->a *= 2;
}
both work nicely from python.

The function

void computeOnTupleOfAs(const tuple& as)
{
  for(int i = 0; i < len(as); ++i) {
    boost::shared_ptr<A> a = extract<boost::shared_ptr<A> >(as[i]);
    computeOnAs(a);
  }
}
also works nicely, given both tuples containing instances of A or the
derived class B as expected.

However the function:
void computeOnTupleOfA(const tuple& as)
{
  for(int i = 0; i < len(as); ++i) {
    Teuchos::RCP<A> a = extract<Teuchos::RCP<A> >(as[i]);
    computeOnA(a);
  }
}
only works given tuples of A and not the derived class B, the
following error is shown:

TypeError: No registered converter was able to produce a C++ rvalue of
type Teuchos::RCP<A> from this Python object of type B.

So my question is, which magic do I need to do (I am willing to use
certain internals of boost::python) so that B elements can be
extracted from tuples of Bs.

I currently only provide the functions:
  T* get_pointer(Teuchos::RCP<T> const& p)
  T* get_pointer(Teuchos::RCP<T>& p)

Thanks for any help,
Holger
#include <boost/python.hpp>
#include "iostream"
#include "string"

#include "util/verboseObject.h"

#include <Teuchos_RCP.hpp>
#include <Teuchos_RCPBoostSharedPtrConversions.hpp>
#include "python/teuchosRCPPy.h"

using namespace boost::python;
using namespace std;
using namespace parfem;
using Teuchos::RCP;

// the details about "VerboseObject" are not important here
// VerboseObject is exported to python and provides a __str__ method.
class A : public virtual VerboseObject {
public:
  

  /**
   * \defgroup implement methods of VerboseObject 
   */
  /**@{*/
  virtual std::ostream& describe(std::ostream& o, VerbLevel verb) const 
  {
    o << "I am class A with a=" << a;
    return o;
  }
  /**@}*/
public:
    int a;
};

class B : public A 
{
public:

  /**
   * \defgroup implement methods of VerboseObject 
   */
  /**@{*/
  virtual std::ostream& describe(std::ostream& o, VerbLevel verb) const 
  {
    o << "I am class B with a=" << a << " and b=" << b;
    return o;
  }
  /**@}*/

public:
    int b;
};

void computeOnA(Teuchos::RCP<A> a) 
{
    a->a *= 2;
}

void computeOnTupleOfA(const tuple& as) 
{
  for(int i = 0; i < len(as); ++i) {
    Teuchos::RCP<A> a = extract<Teuchos::RCP<A> >(as[i]);
    computeOnA(a);
  }
}

void computeOnAs(boost::shared_ptr<A> a) 
{
    a->a *= 2;
}

void computeOnTupleOfAs(const tuple& as) 
{
  for(int i = 0; i < len(as); ++i) {
    boost::shared_ptr<A> a = extract<boost::shared_ptr<A> >(as[i]);
    computeOnAs(a);
  }
}

BOOST_PYTHON_MODULE(rcpPy) 
{
  class_<A, Teuchos::RCP<A>, bases<VerboseObject> >("A", init<>())
      .def_readwrite("a", &A::a)
    ;

  class_<B, Teuchos::RCP<B>, bases<A> >("B", init<>())
      .def_readwrite("b", &B::b)
    ;

  def("computeOnA", &computeOnA);
  def("computeOnTupleOfA", &computeOnTupleOfA);


  class_<A, boost::shared_ptr<A>, bases<VerboseObject> >("As", init<>())
      .def_readwrite("a", &A::a)
    ;

  class_<B, boost::shared_ptr<B>, bases<A> >("Bs", init<>())
      .def_readwrite("b", &B::b)
    ;

  def("computeOnAs", &computeOnAs);
  def("computeOnTupleOfAs", &computeOnTupleOfAs);

} // boost module

#pragma once
#include <Teuchos_RCP.hpp>

template<class T> 
T* get_pointer(Teuchos::RCP<T> const& p)
{
    return p.get();
}

template<class T> 
T* get_pointer(Teuchos::RCP<T>& p)
{
    return p.get();
}


Attachment: test_rcp.py.out
Description: Binary data

from parfem import *

print "######## test with boost::shared_ptr:\n\n"
a = As();
b = Bs();

a.a = 1;
b.a = 2;
b.b = 3;

print 'a:', a
computeOnAs(a)
print 'after computeOnA(a):', a
computeOnTupleOfAs( (a, ) )
print 'after computeOnTupleOfAs( (a, ) ):', a

print 'b:', b
computeOnAs(a)
print 'after computeOnA(b):', b
computeOnTupleOfAs( (b, ) )
print 'after computeOnTupleOfAs( (b, ) ):', b



print "######## test with Teuchos::RCP:\n\n"
a = A();
b = B();

a.a = 1;
b.a = 2;
b.b = 3;

print 'a:', a
computeOnA(a)
print 'after computeOnA(a):', a
computeOnTupleOfA( (a, ) )
print 'after computeOnTupleOfA( (a, ) ):', a

print 'b:', b
computeOnA(a)
print 'after computeOnA(b):', b
computeOnTupleOfA( (b, ) )
print 'after computeOnTupleOfA( (b, ) ):', b



_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to