www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Base type of a typedef

reply bearophile <bearophileHUGS lycos.com> writes:
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
Dec 21 2007
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
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
Dec 21 2007
parent bearophile <bearophileHUGS lycos.com> writes:
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
Dec 21 2007