Re: [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:

> David Abrahams wrote:
>> Daniel Wallin <[email protected]> writes:
>> 
>>>Because the different CallPolicies in the composite_call_policies type
>>> have no knowledge of each other. 
>> What I don't like here is the need for a "special overload".  It
>> feels
>> like a very nonuniform special-case.  And it proliferates: you'll need
>> to do something similar for arity (querying the size of the argument
>> package), won't you?
>
> Yes. It could be written:
>
>     template<class Base, int M, int M>
>     PyObject* get(
>         const composite_package<offset_arg<N>, Base>& args
>       , mpl::int_<N>)
>     {
>         return get(args.base(), mpl::int_<N + M>());
>     }
>
> Althought that's probably more characters to type. ;)

Yes, and it feels wrong to have to know about composite_package at the
level of implementing get for offset_arg.  But worse, what *is*
offset_arg in this case, anyway?  It can't be an argument package,
because it doesn't stand on its own - you can't use it without a
native argument package.  It could be an "argument repackager".

>>>Meaning we would need to make the
>>>nested argument_package a metafunction:
>>>
>>>   struct my_policy
>>>   {
>>>       template<class Base>
>>>       struct argument_package
>>>       {
>>>           typedef offset_arg<1, Base> type;
>>>       };
>>>   };
>> That might be better.
>
> I disagree. Earlier I agreed with you that it was better to consider
> CallPolicies as one concept and doing the actual composing (?) at
> another level. To me, having a metafunction implies that there are
> actually other CallPolicies as well. Which seems to contradict our
> there-is-only-one design somewhat.

OK, I understand, though I think I disagree.  It only implies that
CallPolicies don't have a fixed notion of what kind of argument
package they're going to get.  That's a separate issue.

Let me try to further understand what's going on here.  When we
compose CallPolicies, do we want to transform the argument package
sequentially as it passes through all the sub-policies?  If not, I
presume this wouldn't be an issue.  What are the use cases which lead
us here?  The only one I can think of at the moment is the one which
repackages arguments to drop the self argument when building injected
constructors.  *That* sort of thing can be handled by wrapping a new
CallPolicies template around the composite, and having each element of
the composite do only its *own* transform on the incoming (native)
argument package.  In fact that seems much more appropriate to me in
many ways.  After all:

    policyA(_1) + policyB(_2) + policyC(_3)

does little to suggest anything other than parallel operation.  If we
were going to drop the first argument, I'd represent it using an
expression like:

    make_constructor_policy( policyA(_1) + policyB(_2) + policyC(_3) )

As a result, the CallPolicy generated by make_constructor_policy would
be something like:

    constructor_policy< composite_policy_generated_by_addition >

Am I making sense to you?

Then I'm also asking myself whether these policies need to explicitly
declare their argument package transformations, or whether we can get
away with a chain of calls:

    p3.repackage(p2.repackage(p1.repackage(native)))

I think this might be hard to achieve without auto/typeof/decltype.

> With the interface I proposed there is no such implication. You only
> need the special overload if you are using
> composite_call_policies. In another implementation that uses
> explicit inheritance (like BPL), you won't need the overloads.

I don't have any reason to want to keep that interface, though I
guess I don't want to rule out the implementation yet.

>>>I think it's nicer to create a composite hierarchy:
>>>
>>>   composite_argument_package<
>>>       offset_arg<1>
>>>     , composite_argument_package<
>>>           offset_arg<9>
>>>         , composite_argument_package_native<
>>>               PyObject*
>>>           >
>>>       >
>>>   >
>>>
>>>   template<class Pkg, class Base>
>>>   struct composite_argument_package : Base
>>>   {
>>>       // some forwarding constructors goes here
>> Nasty.  Forwarding is hard to do well.
>
> Not in this case. Every argument_package must be constructible from the
> native argument package, so there is no forwarding problems here. Not
> that I can see anyway.

Now I'm really confused.  What you're saying seems to imply that
there's no need to chain transformations of the argument package type.


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



-------------------------------------------------------
This SF. Net email is sponsored by: GoToMyPC
GoToMyPC is the fast, easy and secure way to access your computer from
any Web browser or wireless device. Click here to Try it Free!
https://www.gotomypc.com/tr/OSDN/AW/Q4_2003/t/g22lp?Target=mm/g22lp.tmpl
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.