DMD 0.173 release
Chris Nicholson-Sauls
ibisbasenji at gmail.com
Thu Nov 2 20:20:42 PST 2006
Jarrett Billingsley wrote:
> "Jarrett Billingsley" <kb3ctd2 at yahoo.com> wrote in message
> news:eidi8o$11o4$2 at digitaldaemon.com...
>
>>Un. Be. Liev. A. Ble.
>>
>>Not only are variadic templates _amazing_ things, they're also _exactly_
>>what I'll need to do the MiniD binding library (and Kirk is understandably
>>happy as well!).
>
>
> Waaahaha! This is so cool. A variadic "call" function for MiniD which used
> to look like:
>
> public void easyCall(MDClosure func, uint numReturns, ...)
> {
> uint funcReg = push(func);
>
> for(int i = 0; i < _arguments.length; i++)
> {
> TypeInfo ti = _arguments[i];
>
> if(ti == typeid(bool))
> push(cast(bool)va_arg!(bool)(_argptr));
> else if(ti == typeid(byte)) push(cast(int)va_arg!(byte)(_argptr));
> else if(ti == typeid(ubyte))
> push(cast(int)va_arg!(ubyte)(_argptr));
> else if(ti == typeid(short))
> push(cast(int)va_arg!(ushort)(_argptr));
> else if(ti == typeid(ushort))
> push(cast(int)va_arg!(ushort)(_argptr));
> else if(ti == typeid(int)) push(cast(int)va_arg!(int)(_argptr));
> else if(ti == typeid(uint)) push(cast(int)va_arg!(uint)(_argptr));
> else if(ti == typeid(long)) push(cast(int)va_arg!(long)(_argptr));
> else if(ti == typeid(ulong))
> push(cast(int)va_arg!(ulong)(_argptr));
> else if(ti == typeid(float))
> push(cast(float)va_arg!(float)(_argptr));
> else if(ti == typeid(double))
> push(cast(float)va_arg!(double)(_argptr));
> else if(ti == typeid(real))
> push(cast(float)va_arg!(real)(_argptr));
> else if(ti == typeid(char[])) push(new
> MDString(va_arg!(char[])(_argptr)));
> else if(ti == typeid(wchar[])) push(new
> MDString(va_arg!(wchar[])(_argptr)));
> else if(ti == typeid(dchar[])) push(new
> MDString(va_arg!(dchar[])(_argptr)));
> else if(ti == typeid(MDObject))
> push(cast(MDObject)va_arg!(MDObject)(_argptr));
> else if(ti == typeid(MDUserdata))
> push(cast(MDUserdata)va_arg!(MDUserdata)(_argptr));
> else if(ti == typeid(MDClosure))
> push(cast(MDClosure)va_arg!(MDClosure)(_argptr));
> else if(ti == typeid(MDTable))
> push(cast(MDTable)va_arg!(MDTable)(_argptr));
> else if(ti == typeid(MDArray))
> push(cast(MDArray)va_arg!(MDArray)(_argptr));
> else throw new MDRuntimeException(this, "MDState.easyCall(): invalid
> parameter ", i);
> }
>
> call(funcReg, _arguments.length, numReturns);
> }
>
> Has now become:
>
> public void easyCall(T...)(MDClosure func, uint numReturns, T params)
> {
> uint funcReg = push(func);
>
> foreach(param; params)
> push(param);
>
> call(funcReg, params.length, numReturns);
> }
>
> Not only is it magnitudes easier to read, it's also far more efficient.
>
> Amazing, amazing, amazing. Thank you so much, again and again.
>
>
That has to be about as significant an example as one could ask for. Also, the new code
makes it much more future-compatable, as it can be made ready for new datatypes without
ever editing easyCall itself! (So long as push() supports the type, you're good to go.)
-- Chris Nicholson-Sauls
More information about the Digitalmars-d-announce
mailing list