Thread overview
Base type of a typedef
Dec 21, 2007
bearophile
Dec 22, 2007
Daniel Keep
Dec 22, 2007
bearophile
December 21, 2007
A template function of mine (a replacement for writeln) uses is() and some static if to change its behavour according to the type of the input. But it doesn't work when the input type comes from a typedef, like T and T2 here:

void main() {
    typedef int T;
    T i = 10;
    writefln( is(T == int) ); // Prints: 0  (false)
    writefln("is T typedef: ", is(T == typedef));
    typedef T T2;
    writefln("is T2 typedef: ", is(T2 == typedef));
    struct S { string a; }
    typedef S S2;
    writefln("is S2 typedef: ", is(S2 == typedef));
}


is(T2 == typedef) allows me to know if S2 comes from a typedef, but how can I find (at compile time) the base type of T, T2, S2? So far I have tried silly solutions like:

template TypedefBase(T) {
    static if( is(T == typedef) ) {
        static if(T.mangleof == (void).mangleof)         alias void TypedefBase;
        else static if(T.mangleof == (bool).mangleof)    alias bool TypedefBase;
        else static if(T.mangleof == (byte).mangleof)    alias byte TypedefBase;
        ...
        else
            static assert(0, "TypedefBase: basic type not recognized.");
    } else
        alias T TypedefBase;
}

It works with T and T2, but I think it can't work with S2, I need a more general solution to find the basic type of something type-defined.

In the newsgroup I have found things like:
static assert (is (typeof(typeid(i).base) == int));
But I presume they are proposed ideas, because a typeid object lacks the "base" attribute (DMD 1.X) :-)

Bye and thank you,
bearophile
December 22, 2007
Copy + pasted random code segment from one of my projects:

static if( is( T_Type T_BaseType == typedef ) )
{
    toStream(stream, cast(T_BaseType)value);
}


Hope that helps.

	-- Daniel
December 22, 2007
Thank you very much Daniel Keep, this is the code I use now:

/*************************************
Template, gives the base type of type type-defined one or more times.

Example:
----------------------
typedef int T;
typedef T T2;
BaseTypedef!(T2) ==> int
----------------------
*/
template BaseTypedef(T) {
    static if( is( T BaseType == typedef ) )
        alias BaseTypedef!(BaseType) BaseTypedef;
    else
        alias T BaseTypedef;
}

unittest { // Tests of BaseTypedef!()
    assert( is(BaseTypedef!(int) == int) );

    typedef int T1;
    assert( is(BaseTypedef!(T1) == int) );

    typedef T1 T2;
    assert( is(BaseTypedef!(T2) == int) );

    typedef T2 T3;
    assert( is(BaseTypedef!(T3) == int) );

    struct S { string a; }
    assert( is(BaseTypedef!(S) == S) );

    typedef S S2;
    assert( is(BaseTypedef!(S2) == S) );
} // End tests of BaseTypedef!()


And it solves my problem nicely! :o)

Bye,
bearophile