Loop through all modules and module members?
Philippe Sigaud
philippe.sigaud at gmail.com
Sat Jan 1 05:05:37 PST 2011
On Sat, Jan 1, 2011 at 11:14, bearophile <bearophileHUGS at lycos.com> wrote:
> %u:
>
>> I would like to perform compile-time reflection on a module (such as
>> enumerating all the classes inside the module) and/or on all modules in the
>> code -- are either of these possible? And if so, how?
>
> You may add your enhancement requests here, explaining why you need them:
> http://d.puremagic.com/issues/show_bug.cgi?id=4476
>
> At the moment the static reflection is not able to do everything. Listing all modules in the code looks like work for rmdm. Listing all classes in a module seems work for __traits/meta, plus a compile-time Filter.
Yes, it's doable :
template StaticFilter(alias Pred, T...)
{
static if (T.length == 0)
alias TypeTuple!() StaticFilter;
else static if (Pred!(T[0]))
alias TypeTuple!(T[0], StaticFilter!(Pred, T[1 .. $])) StaticFilter;
else
alias StaticFilter!(Pred, T[1 .. $]) StaticFilter;
}
template isClass(string name)
{
mixin("
static if (is(" ~ name ~ " == class))
enum bool isClass = true;
else
enum bool isClass = false;");
}
template extractClasses(string moduleName, members...)
{
alias StaticFilter!(isClass,members) extractClasses;
}
template classMembers(string moduleName)
{
mixin("alias extractClasses!(moduleName, __traits(allMembers, " ~
moduleName ~ ")) classMembers;");
}
if in module dir.mod1.d you have
class A {}
class B : A {}
struct S {}
class C {}
int foo() { return 0;}
then
classMembers!("dir.mod1") will become the tuple ("A", "B", "C") during
compilation.
It's buggy, though: the module needs to be in a directory. You cannot
do classMembers!("mod1"). Too bad.
Note that class templates are *not* classes. So most of std.* modules
will return an empty tuple, because they're full of templates.
Another detail I didn't have the time to correct: the names should be
tested fully qualified, to avoid any name clash with locally-defined
classes.
As for listing all modules imported by a module, I have something, but
it's not very elegant: it scans the text, looking for import
declarations. It works, but at runtime. I'm not sure it's doable at
compile-time right now: you need to have access to the module code, as
text. Do imports work in CT-evaluable functions?
Philippe
More information about the Digitalmars-d-learn
mailing list