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:
> Daniel Wallin <[email protected]> writes:
> 
> 
>>Daniel Wallin wrote:
>>
>>>At 22:34 2003-10-05, David Abrahams wrote:
>>>
>>>
>>>>Daniel Wallin <[email protected]> writes:
>>>>
>>>>
>>>>>What's next? Should we start implementing this? Or did we
>>>>>leave anything unresolved?
>>>>
>>>>I don't think so.  I'd love to get started on it.  I am rather short
>>>>of time at the moment, but would be happy to act as "implementation
>>>>guide/shepherd" or something ;-)
>>>
>>>:) Ok great, I'll start working on it as soon as possible.
>>
>>I finally got started on the invoke/CallPolicies stuff. Right now I
>>have:
>>
>>
>>IIRC this is close to what you have in boost python today.
> 
> 
> Yep, close.  It's missing the "hidden this downcasting" feature,
> which we'll need.

Right,

   template<class R, class T, ..., class WrappedClass>
   signature<
       mpl::vector3<WrappedClass&, R, ...>
       ...
   >
   signature_of(R(T::*)(...), type<WrappedClass>)

?

>>   - A CallPolicies concept which is a binary metafunction class that can
>>     generate a converter for a type T and argument index N.
> 
> 
> That sounds like a from-XXX converter generator, but not the full
> concept that is CallPolicies in my mind, which includes converting
> results to-XXX.

Right.. I don't remember exactly what we decided on this, if we ever did
decide anything. When I wrote this I was thinking that
CallPolicies::apply generates a converter that can convert the type in
both directions, and the direction is decided later by calling the right
member function:

    cv.to(...); // converts to XXX
    cv.from(...); // converts from XXX

Then we'd actually only have the ConverterGenerator concept, which
CallPolicies models.

Did I miss anything, do we need to separate it into two concepts?

>>   - generate_converter_tuple<Signature, CallPolicies>
>>     Combines a given signature<> with a CallPolicies type and produces a
>>     tuple type with converters that can perform the given conversion.
>>
>>and..
>>
>>   - A sample composite_call_policies<Seq> type that creates the
>>     equivalent of map<Index, CallPolicy>. 
> 
> Do you really need random access over non-contiguous indices?  That's
> what map<Index, ...> implies to me.

To clarify, this models what we have in luabind.

   policy1(_2) + policy2(_1)

Would create something like:

   composite_call_policies<
       mpl::vector<
           node<mpl::int_<2>, policy1_type>
         , node<mpl::int_<1>, policy1_type>
       >
    >

And it's nested apply<> would do something like:

   apply(Type, Index)
      if we have a child, C,  that matches node<Index, _>
          C::apply(Type, Index)
       else
          default_call_policies::apply(Type, Index)


The indices here are generally non-contiguous, since the user rarely
would specify an explicit policy for each argument index.

>>     It also combines it's childrens argument_package types and
>>     state types by inheritance.
> 
> 
> Not sure what you mean by "by inheritance".

It means it's nested state_type inherits from all it's "childrens"
state_types.

Again,

   composite_call_policies<
       mpl::vector<
           node<mpl::int_<2>, policy1_type>
         , node<mpl::int_<1>, policy1_type>
       >
    >

Would make something like:

    template<class Base, class CallPolicies>
    struct inherit_state : Base, CallPolicies
    {
        template<class U>
        inherit_state(const U& init)
            : Base(init), CallPolicies(init)
        {}
    };

    typedef typename inherit_linearly<
        PoliciesSequence
      , empty
      , inherit_state<_1, _2>
    >::type

Except that it's a bit more complicated; every state type is only
inherited once.

The same goes for argument_package. Here we also have get() functions:

    template<class Base, int N>
    PyObject* get(PyObject* args, mpl::int_<N>)
    { return PySomethingSomething(.., N); }

    template<int N>
    struct offset_arg // IIRC you have something like this in BPL
    {
        offset_arg(PyObject*) {}
    };

With a special overload that handles the composite case where every
argument_package has a base type which must be queried:

    template<class Base, int M, int N>
    PyObject* get(offset_arg<M>, const Base& base, mpl::int_<N>)
    { return get(base, mpl::int_<N + M>()); }

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