// (C) Copyright 2006 Douglas Gregor
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Authors: Douglas Gregor
#ifndef BOOST_MPI_PYTHON_SKELETON_AND_CONTENT_HPP
#define BOOST_MPI_PYTHON_SKELETON_AND_CONTENT_HPP
/** @file skeleton_and_content.hpp
*
* This file reflects the skeleton/content facilities into Python.
*/
#include
#include
#include
#define BOOST_MPI_PYTHON_FORWARD_ONLY
#include
#include
namespace boost { namespace mpi { namespace python {
/**
* INTERNAL ONLY
*
* This @c content class is a wrapper around the C++ "content"
* retrieved from get_content. This wrapper is only needed to store a
* copy of the Python object on which get_content() was called.
*/
class content : public boost::mpi::content
{
typedef boost::mpi::content inherited;
public:
content(const inherited& base, boost::python::object object)
: inherited(base), object(object) { }
inherited& base() { return *this; }
const inherited& base() const { return *this; }
boost::python::object object;
};
/**
* INTERNAL ONLY
*
* A class specific to the Python bindings that mimics the behavior of
* the skeleton_proxy template. In the case of Python skeletons, we
* only need to know the object (and its type) to transmit the
* skeleton. This is the only user-visible skeleton proxy type,
* although instantiations of its derived classes (@c
* skeleton_proxy) will be returned from the Python skeleton()
* function.
*/
class skeleton_proxy_base
{
public:
skeleton_proxy_base(const boost::python::object& object) : object(object) { }
boost::python::object object;
};
/**
* INTERNAL ONLY
*
* The templated @c skeleton_proxy class represents a skeleton proxy
* in Python. The only data is stored in the @c skeleton_proxy_base
* class (which is the type actually exposed as @c skeleton_proxy in
* Python). However, the type of @c skeleton_proxy is important for
* (de-)serialization of @c skeleton_proxy's for transmission.
*/
template
class skeleton_proxy : public skeleton_proxy_base
{
public:
skeleton_proxy(const boost::python::object& object)
: skeleton_proxy_base(object) { }
};
namespace detail {
using boost::python::object;
using boost::python::extract;
extern BOOST_MPI_DECL boost::python::object skeleton_proxy_base_type;
template
struct skeleton_saver
{
void
operator()(packed_oarchive& ar, const object& obj, const unsigned int)
{
packed_skeleton_oarchive pso(ar);
pso << extract(obj.attr("object"))();
}
};
template
struct skeleton_loader
{
void
operator()(packed_iarchive& ar, object& obj, const unsigned int)
{
packed_skeleton_iarchive psi(ar);
extract&> proxy(obj);
if (!proxy.check())
obj = object(skeleton_proxy(object(T())));
psi >> extract(obj.attr("object"))();
}
};
/**
* The @c skeleton_content_handler structure contains all of the
* information required to extract a skeleton and content from a
* Python object with a certain C++ type.
*/
struct skeleton_content_handler {
function1