Re: Re: Conversion policies
Daniel Wallin <[email protected]>
| Newsgroups | gmane.comp.lib.boost.langbinding |
|---|---|
| Message-ID | <[email protected]> |
At 03:04 2003-08-27, David Abrahams wrote: >Daniel Wallin <[email protected]> writes: > > > At 21:31 2003-08-26, David Abrahams wrote: > >>Daniel Wallin <[email protected]> writes: > >> > >> >>I confess, though, that I am really confused about where this is > >> >>coming from, since I was sure you had agreed that "100% compile-time > >> >>converters" are not worth their costs. > >> > > >> > Yeah you're right, I did agree to that. I'm just trying to clear > >> > things up. ;) It is still unclear to me how runtime and compile time > >> > converters will interact though > >> > >>Didn't we just say there weren't going to be any "compile-time > >>converters?" Or did you mean something else? > > > > I don't know, we certainly already have a system which allows for > > both type of converters. > >Well, let me back up. I was talking about XXX -> C++ converters. In >ther other direction, provided XXX is truly dynamically typed, >compile-time converter selection makes sense. Hm Ok, I was talking about both directions I guess. > > IIRC, during earlier conversations we did agree that runtime converters > > was better, but that it should also be possible to override the runtime > > system with compile time selections. > >Do you mean on a "per-wrapped function argument" basis? I'm OK with >that, though I don't love it because it will tend to mask viable >converter "overloads" unless we use the runtime system as a fallback. > >If you mean on an extension-wide basis, I think I'm against it, since >I see no advantages. Right, I'm talking about "per-wrapped function argument". Also in some cases masking is just what you want, for instance if you are wrapping a function that takes a void*, or a A* but wants this to map to a null terminated list of A's. > > I don't know if this is still a viable approach, but I'm just trying > > to keep the discussion open. > >We have too many options at this point; shouldn't we be looking for >opportunities to close some of them down? I guess, at least if they're not viable. > >> > like in the case of our "adopt" policy.. In luabind it's a > >> > converter, in langbinding perhaps it will be a policy with a > >> > post-call action which removes ownership instead. I don't know.. > >> > >>Err... > >> > >>I don't see how "it's a converter" vs. "it's a policy" is anything > >>more than a name game. Ultimately it needs to do the same thing. > > > > We are yet to define "policy" and "converter" in langbinding, but in > luabind > > they are different things. Policies can generate converters, but they don't > > perform any actual conversion. They do however have static pre/post-call > > functions. > >Likewise in Boost.Python. However, so far call policies in >Boost.Python only generate return value converters. > >Incidentally, I don't know if "policy" is actually an appropriate >term here. No? Don't they match the common definition of policies? > >>As for whether ownership is removed post- call, it may be important to > >>choose pre-call removal in case an exception is thrown from the call > >>and the callee has already claimed ownership. > > > > Ok, is this less dangerous than assuming the callee never got to claiming > > ownership? > >No; I just think it may be important to allow the user to decide which >one to use. See >with_custodian_and_ward/with_custodian_and_ward_postcall Agreed. I generally tend to not think about exception safety as much as I should. ;) > >> >>It's called "extract" in Boost.Python and > >> >> > >> >> 1. Yes, it's a type with an implicit conversion operator > >> >> > >> >> 2. Extraction of a reference to a temporary should fail at runtime > >> > > >> > Ok. Out of curiosity, why should it fail at runtime? > >> > >>Because we can't make it fail at compile time? It's clearly an error! > > > > Yeah, I misread the second point. What confused me was that in > > Boost.Python this would work fine, no? If I'm not mistaken no > > converter returns an actual temporary, but rather const& to in-place > > constructed objects.. > >True, but I'm not sure whether extract<T> stores its converter >internally... [looking at code] > >As a matter of fact, it was a conscious decision to make > > extract<T const&> > >require an *lvalue* conversion. This is one of the ways in which >conversion rules are slightly nonuniform. In fact I think the same >goes for const& returns from Python with call<T const&>(...) or >call_method<T const&>(...), in contrast to from-python conversions >for arguments. Ok. > >> > I should have named "chain" "composite" instead; it tries all it's > >> > converters and returns a best match, just like the runtime system > >> > does. > >> > >>Most confusing. > > > > What is confusing here? Consider for just a moment that we had > > compile time converters AND runtime converters, it would be > > really good to be able to use both together. > >I don't even know what you mean by "compile time converters" yet. Ok, if you look further down I've posted the current converter concept. The runtime converter system and a "compile time converter" is just an implementation of this concept. > > Consider a compile time converter which handles conversions to const > > char* from some type X. We also have a standard converter registered > > that handles this conversion, so when we use our compile time > > converter policy we want to try using the standard converter as > > well. > >Why? I'd understand if the standard conversion handled Y->char*, but >X->char* is uninteresting; it's already handled by this >"compile-time" thingy. Yeah sorry, that's what I meant. The standard converter handles Y->char*. > > Here some sample code for a simple composite converter that > > uses a converter generated both from my_policy and from the > > default policy: > > > > Just assume param_type is just a parameter in the interpreter > > environment; PyObject* or whatever. > > > > template<class T> > > struct my_composite_converter > > { > > typedef typename my_policy::template apply<T>::type c0_t; > > typedef typename default_policy::template apply<T>::type c1_t; > > > > std::size_t choice; > > c0_t c0; > > c0_t c1; > > > > int match(const param_type& param) > > { > > int r0 = c0.match(param); > > int r1 = c1.match(param); > > > > choice = r0 > r1 ? 0 : 1; > > return r0 > r1 ? r0 : r1; > > } > > > > T convert(const param_type& param) > > { > > switch (choice) > > { > > case 0: return c0.convert(param); > > case 1: return c1.convert(param); > > } > > } > > }; > >IIUC, this is for per-function-argument conversion customization. Why >don't we use the same converter interface in all cases, and just have >the policy build a converter chain which starts with the custom >converter and uses the "default" converter chain as its tail? I think this is at least close to what I'm saying. What I mean is that the policy system can generate the above function for various number of combined policies, and the default converter. I'm not sure what you mean by "converter interface" here. This is the current converter concept: template<class T> struct converter { int match(param_type); T convert(param_type); }; Or do you mean the policies should build an actual lvalue/rvalue chain? --- Daniel Wallin ------------------------------------------------------- This sf.net email is sponsored by:ThinkGeek Welcome to geek heaven. http://thinkgeek.com/sf