Re: Re: [C++-sig] [Implementation] Calling wrapped functions, converters, policies
Daniel Wallin <[email protected]>
| Newsgroups | gmane.comp.lib.boost.langbinding |
|---|---|
| Message-ID | <[email protected]> |
At 18:39 2003-09-17, David Abrahams wrote: >I think we need to stop using the term "policy" without qualification. >It gets too confusing. Every time I do it, I mean CallPolicy (as in >Boost.Python). I think when you do it you mean ConversionPolicy. In >fact, why don't we say "[argument|result] [to|from]_xxx converter >generator" for what I called ConversionPolicy? Agreed. We still need to settle what a CallPolicy and converter generator actually is though. :) >Daniel Wallin <[email protected]> writes: > > > At 14:09 2003-09-17, David Abrahams wrote: > >>Daniel Wallin <[email protected]> writes: > >> > >> >> > struct ContextConcept > >> >> > { > >> >> > ... > >> >> > something postcall(something_else); > >> >> > }; > >> >> > > >> >> > struct ConverterConcept > >> >> > { > >> >> > ... > >> >> > T convert(PolicyConcept::context_type& context); > >> >> > }; > >> >> > >> >>This is passing the per-call state into the convert function? The > >> >>problem I have with this is that the dynamically-registered converter > >> >>implementation doesn't have access to the policy's static type, nor > >> >>presumably to its nested context_type. > >> > > >> > Yes it does; the dynamically-registered converters are implemented as > >> > a default policy > >> > >>You're not making sense here. The dynamic from-XXX converter > >>implementation does not model the CallPolicy concept, nor, I think, > >>the ConversionPolicy concept. > > > > The functions that does the actual conversion isn't, but the code that > > looks them up and calls them is a model of ConversionPolicy. > >Of course. But it's the function which does the actual conversion >which needs access to the state (or not, depending on the >dynamically-selected converter). > > >>It basically comes down to one or two function pointers with a fixed > >>static type for any given C++ target type. These function pointers > >>get plugged into the static converter at runtime. > > > > Yeah, but they are called from a converter type. Like Boost.Pythons > > rvalue_from_python, pointer_cref_from_python etc.. > >Sure, but what can that thing do with state, except in the case where >there is no dynamic converter lookup at all? Not much. > >Maybe that's the way you see it? The default from_xxx converter >generator builds a static converter which uses dynamic lookup and uses >a default kind of state (say, a postcall chain) which is known to all >the dynamically-registered converters, and the others use a kind of >state which is determined at compile time by the static type of the >converter (say, nested in the converter). I think this is exactly what I mean. > >> > which selects the appropriate converter type. There > >> > is no reason the system cannot be aware of the state type: > >> > > >> > struct default_state > >> > { > >> > postcall_chain* chain; > >> > }; > >> > > >> > template<class T> > >> > struct rvalue_converter > >> > { > >> > T& convert(default_state& state, ...) > >> > }; > >> > >>If it's always a postcall chain, what's the point of nesting its type > >>in the CallPolicy? > > > > My point was that it isn't always the postcall chain, it is in the case of > > the default policy though. It isn't a postcall chain in the case of the > > PyUnicode you mentioned earlier. > >Actually it could be handled that way... but I suppose that would be >wasteful. Right. >As a matter of fact I think many static from_xxx converter types will >want to wrap the default converter with additional behavior, so their >state will need to include the postcall chain anyway. Yeah, I don't know how that would work. :| > > Anyway, we don't need to nest it. It could just be a copy of the policy > > object. > > > > What I'm driving at is that we don't need to make the whole postcall chain > > thing into a special case, it can just as well be handled by the policy > system > >"Policy system" is getting to be way too-fuzzy a term for me. >But, yeah, I'm all for not having it be a special case. > > >> > Note that this is quite possible even if the policy object is copied and > >> > used as state: > >> > > >> > struct default_policy > >> > { > >> > postcall_chain* chain; > >> > void postcall(...) { for (postcall_chain* c = chain; c != 0; c = c > >> > ->next) (*c)(..); > >> > }; > >> > > >> > >>Ya lost me here. > > > > Ok, I'll try to describe my vision of this. > > > > We have two concepts, CallPolicy and ConverterPolicy. We hold these > policies > > for each wrapped function object, in some type of list. > > > It is possible to ask for the ConverterPolicy that can generate a > > converter for a type in the signature at index N. > > > > ConverterPolicy is also a model of CallPolicy > >Noooooo! At least, not the way I understand it. > >CallPolicy is the Boost.Python concept that includes pre- and >post-processing of the native interpreter argument tuple. Ok, your view of CallPolicies is the same as mine. It's just that I think of the converter generators as a model of CallPolicy as well. I wanted the converter generators to have precall/postcall functions as well, since that would enable the "dynamic postcall action chain" thing in default_generator. In that case the default generator would generate an appropriate converter and pass it's state to the convert() functions, which can add postcall actions to the chain. When we call postcall() on the generator, it could call it's chain.. I guess default generator could model both a generator and CallPolicy instead though. BTW, in luabind the converter object also has precall/postcall actions. This can be very useful. For example, they are used in out_value_policy, which can handle T* and T& which are meant to be out values. void f(int& x); is treated like int f_wrap(int x) { f(x); return x; } Here the postcall function in the converter is used to convert the result back to lua. > > with the additional nested template type 'apply' which generates a > > converter type. > >In that case, what's the concept you have been calling "CallPolicy?" Same as you, something that has precall/postcall. > > with the signature void f(T0, T1) and Policies we would wind up with > > something like: > > > > Make copy of policy objects > > > > Call precall on each of the copied policy objects. > > > > Fetch converter policy type for index 0. > > Create converter for index 0. > >What's the point of copying the policies in this scheme? Why not just >store the state in the converter itself? Because the converter is a unique object for each argument in the signature. This state needs to be shared by several converters. > > Fetch converter policy type for index 1. > > Create converter for index 1. > > > > call ConverterN.match(...), if it fails overload > > resolution fails. > > > > f(Converter0.convert(CopiedPolicyObject0), > > Converter1.convert(CopiedPolicyObject1)); > > > > Call postcall on each of the copied policy objects. > > > > ----- And sample C++ code.. > > > > // the copied policy object, same policy for T0 and T1 > > // so it's just one policy > > default_policy policy0; > >Just one?! Wow, I'm really confused about that. What if they each >need their own state? I differentiate between "converter state" and "call (policy) state". The converters already have their own state. I think of this state as the glue between converters that are generated by the same generator type. > > policy0.precall(...); > ^^^ >What gets passed here? I really don't know. I guess something that can describe the argument tuple in python and the stack in lua. > > // create converters > > typename default_policy::apply<T0>::type c0; > > typename default_policy::apply<T1>::type c1; > > > > int match_value = 0; > > > > match_value += c0.match(...); > > match_value += c1.match(...); > > > > // do some magic with the match value to choose "best" overload > > > > f(c0.convert(policy0, ...), c1.convert(policy0, ...)); > > > > policy0.postcall(...); > > > > I'm having a really hard time getting my message across here. :/ > >I think we're having a problem with terminology. Yeah, that and my ability to express myself. ;) --- Daniel Wallin ------------------------------------------------------- This sf.net email is sponsored by:ThinkGeek Welcome to geek heaven. http://thinkgeek.com/sf