view lphobos/std/traits.d @ 853:82ad6c0c601c

Add Elrood's patch to output LDC and LLVM source revs.
author Christian Kamm <kamm incasoftware de>
date Sun, 14 Dec 2008 16:51:36 +0100
parents 373489eeaf90
children
line wrap: on
line source


// Written in the D programming language.

/**
 * Templates with which to extract information about
 * types at compile time.
 *
 * Macros:
 *  WIKI = Phobos/StdTraits
 * Copyright:
 *  Public Domain
 */

/*
 * Authors:
 *  Walter Bright, Digital Mars, www.digitalmars.com
 *  Tomasz Stachowiak (isStaticArray, isExpressionTuple)
 */

module std.traits;

/***
 * Get the type of the return value from a function,
 * a pointer to function, or a delegate.
 * Example:
 * ---
 * import std.traits;
 * int foo();
 * ReturnType!(foo) x;   // x is declared as int
 * ---
 */
template ReturnType(alias dg)
{
    alias ReturnType!(typeof(dg)) ReturnType;
}

/** ditto */
template ReturnType(dg)
{
    static if (is(dg R == return))
    alias R ReturnType;
    else
    static assert(0, "argument has no return type");
}

/***
 * Get the types of the paramters to a function,
 * a pointer to function, or a delegate as a tuple.
 * Example:
 * ---
 * import std.traits;
 * int foo(int, long);
 * void bar(ParameterTypeTuple!(foo));      // declares void bar(int, long);
 * void abc(ParameterTypeTuple!(foo)[1]);   // declares void abc(long);
 * ---
 */
template ParameterTypeTuple(alias dg)
{
    alias ParameterTypeTuple!(typeof(dg)) ParameterTypeTuple;
}

/** ditto */
template ParameterTypeTuple(dg)
{
    static if (is(dg P == function))
    alias P ParameterTypeTuple;
    else static if (is(dg P == delegate))
    alias ParameterTypeTuple!(P) ParameterTypeTuple;
    else static if (is(dg P == P*))
    alias ParameterTypeTuple!(P) ParameterTypeTuple;
    else
    static assert(0, "argument has no parameters");
}


/***
 * Get the types of the fields of a struct or class.
 * This consists of the fields that take up memory space,
 * excluding the hidden fields like the virtual function
 * table pointer.
 */

template FieldTypeTuple(S)
{
    static if (is(S == struct) || is(S == class))
    alias typeof(S.tupleof) FieldTypeTuple;
    else
    static assert(0, "argument is not struct or class");
}


/***
 * Get a TypeTuple of the base class and base interfaces of
 * this class or interface.
 * Example:
 * ---
 * import std.traits, std.typetuple, std.stdio;
 * interface I { }
 * class A { }
 * class B : A, I { }
 *
 * void main()
 * {
 *     alias BaseTypeTuple!(B) TL;
 *     writefln(typeid(TL));    // prints: (A,I)
 * }
 * ---
 */

template BaseTypeTuple(A)
{
    static if (is(A P == super))
    alias P BaseTypeTuple;
    else
    static assert(0, "argument is not a class or interface");
}

unittest
{
    interface I { }
    class A { }
    class B : A, I { }

    alias BaseTypeTuple!(B) TL;
    assert(TL.length == 2);
    assert(is (TL[0] == A));
    assert(is (TL[1] == I));
}

/**
 * Detect whether type T is a static array.
 */
template isStaticArray(T)
{
    static if (isArray!(T))
        const bool isStaticArray = !is(T == typeof(T[0])[]);
    else const bool isStaticArray = false;
}


static assert (isStaticArray!(int[51]));
static assert (isStaticArray!(int[][2]));
//static assert (isStaticArray!(char[][int][11]));
static assert (!isStaticArray!(int[]));
//static assert (!isStaticArray!(int[char]));
static assert (!isStaticArray!(int[1][]));

template isArray(T)
{
    const bool isArray=false;
}
template isArray(T: T[])
{
    const bool isArray=true;
}

/**
 * Tells whether the tuple T is an expression tuple.
 */
template isExpressionTuple(T ...)
{
    static if (is(void function(T)))
    const bool isExpressionTuple = false;
    else
    const bool isExpressionTuple = true;
}