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