[C++-sig] lvalue converter (and other) questions

David Abrahams dave at boost-consulting.com
Sat Aug 31 01:14:03 CEST 2002


From: "Ralf W. Grosse-Kunstleve" <rwgk at yahoo.com>

> 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?

Yes.

> 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;

We could write one. However, this check would fail for some C++ wrapped
class derived from flex_type, whereas the one above would not.

> Would using this make sense as an optimization: extract<> is only
> called after this test?

No, extract<> will still do the check when you ask it to convert the source
object, so your class_check would be wasted effort.

> Second question:
>
> If I understand correctly, struct shared_from_flex in the reference
> code implements an rvalue converter only.

Yup.

> 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):

(btw: it's pretty hard to see why from your example)

>     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)?

If shared<E> is already exposed via class_<>, it's already done.
In which case, consider:

    static void
    push_back(back_reference<shared<ElementType>&> b, ElementType const& x)
    {
        b.get().push_back(x);
        extract<versa<ElementType, flex_grid<> >&> x(b.source());
        ... // use x to get at the outer versa object.
    }

> 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?

It's safe. It'll work if shared<T> is declared in a bases<...> clause for
class_<versa<T>, ...>

-----------------------------------------------------------
           David Abrahams * Boost Consulting
dave at boost-consulting.com * http://www.boost-consulting.com






More information about the Cplusplus-sig mailing list