Runtime reflection idea
Adam D. Ruppe
destructionator at gmail.com
Sat Jun 1 13:12:45 PDT 2013
I got a better thing implemented, what do you think of this?
// usage
@CustomInfo!("hey") // can be anything in there, but don't repeat
a type
@CustomInfo!(1)
class Test {}
auto info = typeid(Test).rtInfo();
immutable(string)* str = rtInfo.getCustomData!string;
writeln(str is null ? "not there" : *str); // prints "hey"
immutable(int)* i = rtInfo.getCustomData!int;
writeln(i is null ? "not there" : *i); // prints 1.
// implementation
struct MoreTypeInfo {
// the first two fields just show druntime can
still do its thing
hash_t hash;
string stringOf;
// and here's the extensible part
immutable(CustomTypeInfoExtension)[] customInfo;
immutable(T)* getCustomData(T)() immutable {
auto hash = typeid(T); // typehash!T;
foreach(ci; customInfo) {
if(ci.typeOfData == hash)
return cast(immutable(T)*) ci.data();
}
return null;
}
}
struct CustomTypeInfoExtension {
TypeInfo typeOfData;
void* function() data;
}
immutable(CustomTypeInfoExtension)[] getCustomInfo(T)() {
if(__ctfe) {
//bool[hash_t] seen;
immutable(CustomTypeInfoExtension)[] ext;
foreach(attr; __traits(getAttributes, T))
static if(is(typeof(attr) == CustomTypeInfoExtension)) {
//auto hash = attr.typeOfData.rtInfo.hash;
//if(hash in seen)
//assert(0, "repeated data");
//seen[hash] = true;
ext ~= cast(immutable) attr;
}
return ext;
} else return null;
}
template CustomInfo(alias T) {
__gshared static data = T;
void* getRaw() { return cast(void*) &data; }
enum CustomInfo = CustomTypeInfoExtension(
typeid(typeof(data)), &getRaw);
}
template RTInfo(T) {
__gshared static immutable minfo = MoreTypeInfo(typehash!T,
T.stringof, getCustomInfo!T);
enum RTInfo = &minfo;
}
More information about the Digitalmars-d
mailing list