Fixing cyclic import static construction problems
Rainer Schuetze
r.sagitario at gmx.de
Fri Nov 30 00:13:09 PST 2012
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.
More information about the Digitalmars-d
mailing list