Re: Re: [Implementation] Calling wrapped functions, converters, policies

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

> [Aleksey, please see below w.r.t. lambda exprs]
> 
> Daniel Wallin <[email protected]> writes:
> 
> 
>>David Abrahams wrote:
>>
>>>Daniel Wallin <[email protected]> writes:
>>>
>>>What does the first element of the vector mean?  Oh, looking back at
>>>your previous message that's a *very* strange ordering!  Why would you
>>>put the return type *second*?!
>>
>>The ordering was arbitrary. Well, sort of at least. The reason was to
>>keep the indexing consistent. A member function signature is the same as
>>a function signature, except it has the self-type at index 0. So the
>>index to some type in the signature is just offset one step. I don't
>>know if it matters though. :)
> 
> 
> Errf.  I think of these two as equivalent:
> 
>        A f(B*, C, D, E)
>        A B::f(C, D, E)
> 
> And they *are* equivalent as far as Boost.Python is concerned, except
> at the last second when the C++ function is invoked and we have to do
> some syntactic adjustment to account for the difference between
> member and non-member functions.  I don't see any reason to drag the
> B* to the beginning of the signature.

Good point.

>>>I'm not sure whether what you're suggesting above actually does the
>>>right thing.  In fact, I'm almost certain it doesn't.  You need the
>>>most_derived hook used in signature.hpp.  The idea is, "downcast if
>>>you can, otherwise leave it alone".
>>
>>I had a look in signature.hpp. I'm not sure I understand this though;
>>Target is not more derived than T => Target == T, no? Or is Target
>>something else than the current WrappedClass type?
> 
> 
> Well, this should probably be done for non-member functions as well,
> but...
> 
> suppose someone does this:
> 
> [snip code]
> 
> That should show why the most_derived thing is there.

OK, I had no idea you could do that. I can see why you would need
most_derived there. I'm not sure I can see why anyone would do something
like that though, but I haven't given it much thought. :)

>>>I have no problem in principle (I think) with bidirectional
>>>converter *generators*, but bidirectional converters won't work.  They
>>>need completely different data members, and from-XXX converters need
>>>to be 2-phase for overloading, while to-XXX converters are one
>>>phase.  In other words, I have no problem with:
>>>[snip]
>>
>>OK agreed. So, should the nested member be a metafunction class?
>>
>>   some_generator
>>   {
>>       typedef /* to converter */ to;
>>       typedef /* from converter */ from;
>>   };
> 
> 
> Well, it can be more efficient than using any generalized lambda expr,
> but it's also more work for the user.  AFAIK MPL is going to change so
> that apply<...> uses lambda<...> internally, but I guess there would
> always be a lower-level apply_metafunction_class<...> for efficiency.
> Even though we've written about that in our book, it's not implemented
> yet.  Aleksey, care to comment?

OK. How would you apply<> to a nested metafunction? By turning them into
lambda-types? Or is it safe (portable) to do

   typedef typename generator::template to<T, Index>::type cv_t;

I know I've had a lot of problems with that syntax on VC before.

>>How could the converter_tuple_generator know which types should be
>>"to" and which should be "from"? 
> 
> 
> If you use a consistent signature ordering as I'm suggesting, it's
> easy.  To for the first and from for the rest.

Yeah, that would work fine. But I'm not sure I like it. How does it
apply to explicit conversions? (object_cast<> / extract<>). I had
thought that we'd handle these cases by just supplying a vector1<T>
signature sequence.. But we could tell the policy to generate the
converter explicitly instead of using generate_converter_tuple<>.. I'm
not sure what I think about this.

>>No I think the children are CallPolicies as well - they should have
>>precall/postcall actions.
>>
>>I'm not sure what you mean by index-agnostic.
> 
> 
> I think I'm just forgetting stuff you already convinced me of, but
> what I meant was that the others are only really concerned with
> converting a single argument and so don't need an index, while the
> CallPolicies are concerned with the whole argument tuple.  But I
> think we agreed they all need the index.

Yeah I think we did. I guess most of "the others" will likely just
ignore the index though, provided that the index is passed to the
converter later.

    struct my_cv;
    my_cv cv;
    cv.from(..., mpl::int<2>());

vs

    template<int N>
    struct my_cv;
    my_cv<2> cv;
    cv.from(...);

>>Except I'm not using partial specialization..
> 
> 
> Cute, and reasonably efficient.  Only the generated type is too
> complicated in the case where the same state type is re-used.  Should
> be:
> 
> [snip code]

Yeah, that's better.

>>BTW, if you implement the composite CallPolicies like you have in BPL
>>there is no reason why offset_arg couldn't store it's Base. That's of
>>course a perfectly fine model of CallPolicies as well.
>>composite_call_policies is just an example of how it can be done without
>>explicit inheritance from your "Base policy".
> 
> 
> I think you can also get there by having the names that the user
> handles
> 
>     some_policyA(_1)
>     ^^^^^^^^^^^^
> 
> refer to instances of some concept other than CallPolicies which can
> generate CallPolicies.  Not sure what's best yet.

I think it's best to allow both approaches.

-- 
Daniel Wallin



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