#include <boost/python.hpp>
using namespace boost::python;
using namespace boost;

struct B {};
typedef shared_ptr<B> BPtr;

struct A
{
   A(BPtr b) : mB(b) {}
   BPtr mB;
};
typedef shared_ptr<A> APtr;


struct Creator
{
   virtual ~Creator() {}
   virtual APtr create(BPtr b) = 0;
};


struct Factory
{
   void reg(Creator* c) { mC = c; }
   APtr create(BPtr b) { return mC->create(b); }

private:
   Creator* mC;
};

struct CreatorWrap : public Creator
{
   CreatorWrap(PyObject* self) : mSelf(self) {}
   APtr create(BPtr b) { call_method<APtr>(mSelf, "create", b); }
   PyObject* mSelf;
};

BOOST_PYTHON_MODULE(simple)
{
   class_<B, BPtr>("B");

   class_<A, APtr>("A", init<BPtr>());

   class_<Creator, CreatorWrap, noncopyable>("Creator", no_init)
      .def("create", &CreatorWrap::create)
   ;

   class_<Factory>("Factory")
      .def("reg", &Factory::reg, with_custodian_and_ward<1,2>())
      .def("create", &Factory::create)
   ;
}