DMD 1.019 and 2.003 releases

Robert Fraser fraserofthenight at gmail.com
Mon Jul 23 16:38:28 PDT 2007


Christian Kamm Wrote:

> The extended compile time reflection opens the door for all kinds of cool
> things! Here's an RTTI-Visitor, for instance. 
> 
> It uses compile-time foreach to build a sequence of if-statements that check
> the classinfo and call the matching method.
> 
> Regards,
> Christian
> // released into the public domain
> 
> import std.stdio;
> 
> class A
> {}
> 
> class B : A
> {}
> 
> class C : A
> {}
> 
> class Dispatcher
> {
>   void foo(A a)
> 	{
> 		writefln("A");
> 	}
> 	
> 	void foo(B b)
> 	{
> 		writefln("B");
> 	}	
> 	
> 	mixin Dispatch!("foo");
> }
> 
> class ExDispatcher : Dispatcher
> {
> 	alias Dispatcher.foo foo;
> 	
> 	override void foo(B b)
> 	{
> 		writefln("B override");
> 	}
> 	
> 	void foo(C c)
> 	{
> 		writefln("C");
> 	}
> 	
> 	mixin Dispatch!("foo");
> }
> 
> void main()
> {
> 	auto disp = new Dispatcher;	
> 	disp.dispatch(new A); // calls disp.foo(A)
> 	disp.dispatch(new B); // calls disp.foo(B)
> 	
> 	Dispatcher exdisp = new ExDispatcher;
> 	exdisp.dispatch(new A); // calls disp.foo(A)
> 	exdisp.dispatch(new B); // calls exdisp.foo(B)
> 	exdisp.dispatch(new C); // calls exdisp.foo(C)
> }
> 
> 
> class MethodNotFoundException : Exception
> {
> 	this(string msg) { super(msg); }
> }
> 
> template Dispatch(string fname)
> {
> 	mixin("alias typeof(" ~ fname ~ ") fsym;");
> 	static if(is(fsym arg_types == function) && is(fsym return_type == return))
> 	{
> 		return_type dispatch(Object o, arg_types[1..$] params)
> 		{
> 			alias typeof(__traits(getVirtualFunctions, typeof(this), fname)) funcs;
> 			foreach(i, func; funcs)
> 			{
> 				static if(is(func it_arg_types == function) && is(func it_return_type == return))
> 				{
> 					static assert(is(arg_types[1..$] == it_arg_types[1..$]) && is(return_type == it_return_type), 
> 						"Except for the first argument, the signature of all functions must be identical.");
> 					static assert(is(it_arg_types[0] == class), "First argument must be a class type.");
> 					
> 					if(it_arg_types[0].classinfo is o.classinfo)
> 						return __traits(getVirtualFunctions, this, fname)[i](cast(it_arg_types[0]) o, params);
> 				}
> 				else
> 					static assert(false, fname ~ " is not a function");
> 			}
> 			
> 			throw new MethodNotFoundException("No matching method '" ~ fname ~ "' found in " ~ this.classinfo.name ~ " for class " ~ o.classinfo.name);
> 		}
> 	}
> 	else
> 		static assert(false, fname ~ " is not a function");
> }
> 
> 

Awesome! My first thought was generating hash functions for arbitrary structures, which would make using classes in AAs much easier.

But there's still a niche for runtime reflection!




More information about the Digitalmars-d-announce mailing list