[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