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

David Abrahams dave at boost-consulting.com
Sat Aug 31 02:45:25 CEST 2002


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


> --- David Abrahams <dave at boost-consulting.com> wrote:
> > > the moment (btw: the C++ language /really/ needs template typedefs):
> >
> > (btw: it's pretty hard to see why from your example)
>
> Isn't
>
> flex<ElementType>
>
> a lot nicer than repeating
>
> versa<ElementType, flex_grid<> >
>
> all the time? With:
>
> template <typename ElementType>
> typedef versa<ElementType, flex_grid<> > flex;

Sure. For now you can do it with:

    typename flex<ElementType>::type

FWIW.

> > If shared<E> is already exposed via class_<>, it's already done.
> > In which case, consider:
>
> Note what this struct in the referenced code is doing:
>
>   template <typename ElementType>
>   struct shared_to_flex
>   {
>     static PyObject* convert(shared_plain<ElementType> const& a)
>     {
>       using namespace boost::python;
>       versa<ElementType, flex_grid<> > result(a, flex_grid<>(a.size()));
>       return incref(object(result).ptr());
>     }
>   };
>
> It constructs a flex<E> from a shared<E> and then uses object() to wrap
it up
> for Python.

Ah. I thought you said that versa<> was derived from shared<>, but it
appears now to just be a handle (as shared<> is the body in the handle/body
idiom).

This seems to be very similar to what happens with all of the object
manager types in Boost.Python: e.g., object, list, tuple, dict...

Each of these, though not contained in the corresponding Python object, can
bind to a non-const reference argument since it is merely a wrapper around
some other value. I'm not sure what it would take to generalize this
mechanism to handle cases like yours.

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

> I want the flex<E>. flex<E> has a large number of
> associated member/regular functions that I do not wish to bind another
time for
> shared<E>. Look at this file to see the damage:
>
>
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/cctbx/scitbx/include/scitbx/
array_family/boost_python/flex_wrapper.h?rev=1.5&content-type=text/vnd.view
cvs-markup
>
> Note that the entire file is one large template (well, one small and one
> large). In addition there is the pickle suite (file names flex_pickle_*.h
in
> the same directory). Currently I use this to define eight Python types
(bool,
> std::size_t, int, long, float, double, std::complex<double>,
std::string).
> Sizes of the resulting flex.so/.pyd modules:
>
> vc70, 800k
> tru64 cxx, -O2, 12M unstripped, 11M stripped
> linux gcc 3.0.4, -g, 80M unstripped, 6M stripped

Surely these are not the numbers with full optimization and inlining?!?

> And that is just the beginning. I still have a bunch of custom types to
wrap.
> While vc70 is very tame, I will have to buy an extra harddisk for my
Linux
> compilations if I duplicate everything for shared<E> and flex<E>. In
addition,
> at the Python level there is no point at all in having the two types. One
is
> better.

Ralf, this is clearly a non-trivial problem, and I clearly don't yet
understand it at a deep level. The best I can do is to point you at
boost/python/converter/obj_mgr_arg_from_python.hpp and
boost/python/converter/object_manager_traits.hpp. A generalized mechanism
to deal with handle/body designs is a worthy goal.

-Dave

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






More information about the Cplusplus-sig mailing list