On Sunday, 2 June 2013 at 13:28:28 UTC, Rainer Schuetze wrote:
and TypeInfo.rtInfo() would then return a pointer to RTInfoData instead of void*. This doesn't make it modifiable from outside object.di, but I have no idea how that could be possible to begin with (without recompiling the runtime library).

I think I have something figured out:

use side:

// i'll use this as a UDA
struct InfoStruct {
        string info;
}

// and this as the template extension
struct MoreRtInfo {
        string amazing;
}

@CustomInfo!(InfoStruct("info struct data")) // UDA style, goes into an array
class RTTest {
       // template style, goes in a special member
        static template userRtInfo(This) {
                static __gshared i = MoreRtInfo("amazingness");
                enum userRtInfo = &i;
        }
}


Retrieve:

        auto info = typeid(RTTest).rtInfo();
        if(info is null)
                throw new Exception("wtf");

auto urtInfo = info.userRtInfo; // this is from the template..
        if(urtInfo is null)
                write("urtInfo == null\n");
        else {
// it comes out as a void*, so we have to cast it back.
                auto urt = cast(immutable(MoreRtInfo)*) urtInfo;
                write("cool ",urt.amazing,"\n");
        }

        // and this is fetching the CustomInfo UDA
        auto cd = info.getCustomInfo!InfoStruct;
if(cd is null) // it returns a InfoStruct*, like AA's in operator
                write("InfoStruct is null\n");
        else
                write(cd.info, "\n");







And the implementation side in object.d:



        struct MoreTypeInfo {
                // other stuff druntime is free to declare
                hash_t hash;
                string stringOf;

                 // holder for the template thing
                immutable(void)* userRtInfo;

                 // holder for the UDA thing
                immutable(CustomTypeInfoExtension)[] customInfo;

                 // helper for the UDA get
                immutable(T)* getCustomInfo(T)() immutable {
                        auto hash = typeid(T); // typehash!T;
                        foreach(ci; customInfo) {
                                if(ci.typeOfData == hash)
return cast(immutable(T)*) ci.data();
                        }
                        return null;
                }
        }


       // instantiates the T.userRtInfo, if possible
        template urtInfo(T) {
static if (__traits(compiles, { auto a = cast(immutable(void)*) T.userRtInfo!T; })) enum urtInfo = cast(immutable(void)*) T.userRtInfo!T;
                else
                        enum urtInfo = null;
        }


        template RTInfo(T) {
                __gshared static immutable minfo = MoreTypeInfo(
                      // stuff druntime is free to add
                      typehash!T, T.stringof,

                       // the user defined template
                        urtInfo!T,

                       // getting the UDA stuff
                        getCustomInfoInternal!T);
                enum RTInfo = &minfo;
        }

// finally, helpers in getting the UDAs, I posted this before too

        struct CustomTypeInfoExtension {
                TypeInfo typeOfData;
// ctfe complained when I tried to just do &static_data // so instead this little function helper does it for us
                void* function() data;
        }

immutable(CustomTypeInfoExtension)[] getCustomInfoInternal(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;
        }

       // this is the user uses: @CustomInfo!(something)
        template CustomInfo(alias T) {
                __gshared static data = T;
                void* getRaw() { return cast(void*) &data; }
enum CustomInfo = CustomTypeInfoExtension( typeid(typeof(data))/*typehash!(typeof(data))*/, &getRaw);
        }



Unfortunately the compiler sometimes doesn't force the generation of RTInfo, but sets the m_rtInfo to 0 or 1 depending on whether the Type contains pointers or not. I always wanted to figure out why that happens...

weird

Reply via email to