[C++-sig] lvalue converter (and other) questions
Ralf W. Grosse-Kunstleve
rwgk at yahoo.com
Sat Aug 31 06:47:20 CEST 2002
> > Can I have a class_<shared<E> > at the same time?
>
> Sure (why not?), but I'm not sure any longer that it will help you.
>
> > How could bpl.so decide what
> > pops up the the Python layer?
>
> I don't understand the question.
Say I have a function
shared<double> return_shared();
In Python:
a = return_shared()
type(a) # what will I get here?
As said, I want to see flex.double, not shared.double.
> Ralf, this is clearly a non-trivial problem, and I clearly don't yet
> understand it at a deep level.
Here is an idea for an implementation that would work for me.
It is a generalized version of the rvalue converter:
template <typename WrappedType>
struct lvalue_conversion_policy
{
BOOST_STATIC_CONSTANT(bool, enable_lvalue_conversion = false);
// This is meant to be called after the function that uses the
// lvalue returned, but before we get back to the Python interpreter.
static void post_call(
PyObject* obj_ptr,
converter::rvalue_from_python_stage1_data* data)
{
// do nothing by default; should optimize away
}
};
// Now the full specialization for a particular type.
// Since we have to do without partial specialization I could
// use inheritance to make this easy to use with multiple types.
template <>
struct lvalue_conversion_policy<shared<double> >
{
// Tell the registry that this should participate in lvalue conversions.
BOOST_STATIC_CONSTANT(bool, enable_lvalue_conversion = true);
typedef shared<double> shared_type;
typedef versa<double, flex_grid<> > flex_type;
static void post_call(
PyObject* obj_ptr,
converter::rvalue_from_python_stage1_data* data)
{
object obj(borrowed(obj_ptr));
flex_type& a = extract<flex_type&>(obj)();
assert(a.accessor().nd() == 1);
assert(a.accessor().is_0_based());
assert(!a.accessor().is_padded());
shared_type& b = *(reinterpret_cast<shared_type*>(data->convertible));
a.resize(flex_grid<>(b.size());
}
};
template <typename SharedType>
struct shared_from_flex
{
typedef typename SharedType::value_type element_type;
typedef versa<element_type, flex_grid<> > flex_type;
shared_from_flex()
{
converter::registry::push_back(
&convertible,
&construct,
type_id<SharedType>());
}
static void* convertible(PyObject* obj_ptr)
{
using namespace boost::python;
object obj(borrowed(obj_ptr));
extract<flex_type&> flex_proxy(obj);
if (!flex_proxy.check()) return 0;
flex_type& a = flex_proxy();
if (a.accessor().nd() != 1) return 0;
if (!a.accessor().is_0_based()) return 0;
if (a.accessor().is_padded()) return 0;
return obj_ptr;
}
static void construct(
PyObject* obj_ptr,
converter::rvalue_from_python_stage1_data* data)
{
using namespace boost::python;
object obj(borrowed(obj_ptr));
flex_type& a = extract<flex_type&>(obj)();
assert(a.accessor().nd() == 1);
assert(a.accessor().is_0_based());
assert(!a.accessor().is_padded());
void* storage = (
(converter::rvalue_from_python_storage<SharedType>*)
data)->storage.bytes;
new (storage) SharedType(a);
data->convertible = storage;
}
};
Is there hope that this or something similar could be done?
Thanks,
Ralf
__________________________________________________
Do You Yahoo!?
Yahoo! Finance - Get real-time stock quotes
http://finance.yahoo.com
More information about the Cplusplus-sig
mailing list