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