Re: [C++-sig] [Implementation] Calling wrapped functions, converters, policies

David Abrahams <[email protected]>
Newsgroups gmane.comp.lib.boost.langbinding
Message-ID <[email protected]>
Daniel Wallin <[email protected]> writes:

>> >>Still another
>> >>possibility is to require a class type with member get/arity for
>> >>argument_package.
>> >>
>> >>Thoughts?
>> >
>> > Yeah, it looks good. I guess we would need to complicate things a
>> bit though,
>> > since we don't have inheritance from our base policy:
>>
>>One might ask "why not?"  After all, your slick interface doesn't
>>preclude inheritance as an implementation detail.
>
> It wouldn't be an implementation detail if it affects the policy
> concept though, would it? Or did you mean something else?

I don't know, maybe I misinterpreted you.  I don't see why/how it
would affect the CallPolicy concept.  Right now in Boost.Python
there's nothing in the concept which says "you must use
inheritance".  It's just that since it's a multidimensional thing
(result converter, argument package, precall, postcall) it's very
convenient to use inheritance for composition and overriding a single
dimension.

>> >    struct CallPolicy
>> >    {
>> >       template<class Base>
>> >       struct argument_package
>> >       {
>> >         typedef /* .. */ type; // perhaps this doesn't need to be a
>> >         metafunction..
>> >       };
>> >    };
>> >
>> >    typedef typename LanguageDescriptor::argument_package arg_pk0;
>> >    typedef typename call_policy0::template
>> >    argument_package<arg_pk0>::type arg_pkg1;
>> >    typedef typename call_policy1::template
>> >    argument_package<arg_pk1>::type arg_pkg2;

You're still using your per-argument CallPolicy concept.  I thought
we agreed that CallPolicies was a single wad that gets passed into
the invoke function.  Maybe the problem is that I never got you to
agree to that.

Using the decomposition of functionality I outlined a few posts back,
there's no need for multiple per-argument policy types at the point of
function invocation.  The world is already complicated enough right
there; we should be dealing with a few larger-scale types at that
point in the code.  You can build the big CallPolicies wad any way
you like (including by composing argument policies) but I don't want
to force that particular structure on wrapped function invocation.
It may not always be the best choice.

>>Just require ArgumentPackage types to have templated constructors and
>>you can avoid all this multi-step hoo-ha.  You can pass a
>>LanguageDescriptor::argument_package straight through to the innermost
>>member or base class.
>
> Right. You are just referring to the construction of the object? We'd
> still need the "multi-step hoo-ha" to compose the actual type.

Yes, done elsewhere please!

>> >    arg_pk2 argument_package(arg_pk1(args_));
>> >
>> >    f( c0.convert( argument_package.get(mpl::int_<1>()) ));
>> >
>> > Also keeping the get() function in the argument_package type seems
>> > simpler to me.
>>
>>It has two negative implications:
>>
>>    1. I can't just pass around PyObject* in the usual case, which is
>>       likely to be more efficient.  Few compilers still pass classes
>>       in registers.
>
> Right.
>
>>    2. The syntax for invoking get becomes ugly:
>>
>>          args.template get<3>()
>>
>>       I don't care so much for myself, but writers of custom policies
>>       will have to touch that syntax too.
>
> Ok.

Those may not be too serious, but they are worth considering.

>> > We would probably need to wrap your PyObject* args in a class type
>> > anyway, so that we can have a single access point to
>> > args/self/result.
>>
>>Huh?  Single access point?
>
> Yeah, I meant that I would like all language dependent arguments
> passed to the invoke functions wrapped in the same object.

Sure.

> I believe in python you get more than one PyObject* to your callback, perhaps
> the self argument or something like that? 

You get a tuple of positional arguments and an optional dictionary of
keywords, which is usually NULL.  Even if keywords is not null, by the
time you get to function invocation it has usually been pre-processed
into a new, comprehensive positional argument tuple by function::call
(see function.cpp).  There's one case I haven't dealt with, though:
I'd want an argument policy to say "accept any number of additional
keywords and pass them to this argument in a dictionary", so depending
on how things are structured I may need to process two PyObject*s.  I
hope to avoid it, though.

> I can imagine a lot of languages do something like this. In lua your
> PyObject* is represented by a (lua_State*, int) pair.

OK.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com



-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.