On 11/29/2012 5:51 PM, Max Samukha wrote:
On Thursday, 29 November 2012 at 15:18:11 UTC, Paulo Pinto wrote:

Maybe you care to provide an example?


The general problem is constructing global data structures based on data
introspected at compile-time.

My specific problem is extending scarce runtime type information
provided by the language with something usable for runtime reflection.
With lots of detail omitted:

module reflect;

Meta[string] metas;
mixin template Reflect(alias object) {
     static this()
     {
         auto m = meta!(object);
         metas[m.fullName] ~= m;
     }
}


module a;
import reflect;

struct S
{
}
mixin Reflect!S;

The meta-object for S is automatically made available at runtime through
the global metas array. Note that we do not want to force the user to
register the meta-object manually because then it would not be a "better
architecture".

The important (Andrei somehow thinks it is not) requirement is there
must not be circular dependency issues for the users of the "reflect"
module.


How about running your own set of "constructors" searching the module info array, searching for specific classes in the module that are added by a mixin:

----------------------------------
module register;

RegisterBase[string] registry;

void doRegister(string name, RegisterBase r) { registry[name] = r; }

class RegisterBase
{
        abstract void _register();
}

template Register(string name)
{
        enum string Register = "
        class Register : RegisterBase
        {
                override void _register() { doRegister(\"" ~ name ~ "\", this); 
}
        }
        ";
}

void registerAll()
{
        foreach(m; ModuleInfo)
        {
                TypeInfo_Class[] clss = m.localClasses();
                foreach(c; clss)
                {
                        if(c.base is RegisterBase.classinfo)
                        {
                                if(auto reg = cast(RegisterBase) c.create())
                                {
                                        reg._register();
                                }
                        }
                }
        }
}


-----------------------
module a;
import register;

mixin(Register!"a");

-----------------------
module main;
import std.stdio;
import register;

void main()
{
        registerAll();
        foreach(a, o; registry)
                writeln(a, " ", o);
}

This might also work for the benchmark module.

Reply via email to