[C++-sig] lvalue converter (and other) questions
Ralf W. Grosse-Kunstleve
rwgk at yahoo.com
Sat Aug 31 00:03:09 CEST 2002
I have questions (for David), but first the
Context:
I have made a new cvs module scitbx that contains an "array_family"
incl. Python bindings. At the C++ level there is the type
shared<ElementType>
which is just like std::vector, but reference counted or IOW with
shallow copy semantics. Then there is the type
versa<ElementType, AccessorType>
to cover multi-dimensional arrays (or arrays with any other method
for accessing the elements). versa inherits<> from shared<>.
At the C++ level I have two general accessor types (among others):
grid<N> // number of dimensions N known at compile-time
flex_grid<> // number of dimensions determined at run-time
To minimize the memory footprint for the Python bindings, only
one array type is visible in Python:
C++: versa<ElementType, flex_grid<> >
Python: flex.int, flex.double, etc.
shared<T> and versa<T, grid<N> > are automatically mapped (two-way) to
versa<ElementType, flex_grid<> >/flex.xxx: only the accessor is
changed, the actual data are not copied or modified. The shared<->flex
mappings are achieved with the code in this file:
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/cctbx/scitbx/include/scitbx/array_family/boost_python/shared_flex_conversions.h?rev=1.1&content-type=text/vnd.viewcvs-markup
First question:
Fragment from the file referenced above:
static void* convertible(PyObject* obj_ptr)
{
using namespace boost::python;
object obj(borrowed(obj_ptr));
extract<flex_type const&> flex_proxy(obj);
if (!flex_proxy.check()) return 0;
//...
}
Am I using extract<> in the intended way?
Is there a more direct way to just check the type? Something similar
to PyInt_Check(), e.g.
if (!boost::python::class_check<flex_type>(obj_ptr)) return 0;
Would using this make sense as an optimization: extract<> is only
called after this test?
Second question:
If I understand correctly, struct shared_from_flex in the reference
code implements an rvalue converter only. However, I am also interested
in a similar lvalue converter. Here is an example of what I am doing at
the moment (btw: the C++ language /really/ needs template typedefs):
static void
push_back(versa<ElementType, flex_grid<> >& a, ElementType const& x)
{
// first check that "a" is a 0-based, 1-dimensional, unpadded array
// and then convert "a" to a shared<ElementType>
base_array_type b = flex_as_base_array(a);
b.push_back(x);
// make a new (1-dimensional) accessor for "a".
a.resize(flex_grid<>(b.size()));
}
Could I do it like this if I had an lvalue converter?
static void
push_back(shared<ElementType>& a, ElementType const& x)
{
a.push_back(x);
}
This would require that the lvalue converter can do the a.resize()
after push_back() returns. Is this possible (and where can I find an
example for creating a lvalue converter)?
Another question, related to the previous one:
Since push_back() is .def'ed as a member function of a wrapped
versa<T,A> there is an additional concern: the first argument is a
shared<T>& instead of a versa<T,A>& . Will this work/is it safe?
Thanks,
Ralf
__________________________________________________
Do You Yahoo!?
Yahoo! Finance - Get real-time stock quotes
http://finance.yahoo.com
More information about the Cplusplus-sig
mailing list