Configurable syntax

bearophile bearophileHUGS at lycos.com
Fri May 22 08:51:29 PDT 2009


bearophile:
>To write some templates as compile-time functions you may need to add a new type to D, named "type":<

To see if the idea of compile-time functions that process compile-time variables of type "type" isn't fully crazy I have translated some of the D1 templates of my dlibs into such compile-time functions.

The following code shows a template and its possible translation. The code is of course untested and there can be many mistakes of mine.

// -------------------------------

private template AA_impl(KeyType, ValueType) {
    ValueType[KeyType] result;
    const ValueType[KeyType] res = result;
}

template AA(KeyType, ValueType) {
    const ValueType[KeyType] AA = AA_impl!(KeyType, ValueType).res;
}

TyVal[TyKey] newaa(type TyKey, type TyVal) {
    TyVal[TyKey] aa;
    return aa;
}

// -------------------------------

template AAKeyType(T) {
    alias typeof(T.keys[0]) AAKeyType;
}

template AAValType(T) {
    alias typeof(T.values[0]) AAValType;
}

type aaKeyType(TV, TK)(TV[TK] aa) {
    return TK;
}

type aaValType(TV, TK)(TV[TK] aa) {
    return TV;
}

type aaKeyType(TV, TK)(type TV[TK]) {
    return TK;
}

type aaValType(TV, TK)(type TV[TK]) {
    return TV;
}

// -------------------------------

template ALL(alias Predicate, Types...) {
    static if (Types.length == 0)
        const bool ALL = true;
    else
        const bool ALL = Predicate!(Types[0]) && ALL!(Predicate, Types[1 .. $]);
}

bool All(alias pred, type[] types...) {
    static foreach (T; types)
        static if (!pred(T))
            return false;
    return true;
}

ANY/Any are similar.

// -------------------------------

template BaseTypedef(T) {
    static if( is( T BaseType1 == typedef ) )
        alias BaseTypedef!(BaseType1) BaseTypedef;
    else
        alias T BaseTypedef;
}

type baseTypedef(type T) {
    // the syntax of is() may be improved in many ways
    static while ( is( T BaseType1 == typedef ) )
        T = BaseType1;
    return T;
}

A problem of the "static foreach" (that Walter will face) is that templates are functional, so their values are immutable. And Scheme shows that in a language with no mutability it's not much useful to have for/foreach loops.

In that "static while" loop the variable T of type type, is a mutable.

// -------------------------------

template CastableTypes(Types...) {
    static if (Types.length <= 1)
        const CastableTypes = true;
    else
        const CastableTypes = is(typeof(Types[0] == Types[1])) && CastableTypes!(Types[1 .. $]);
}

bool areCastableTypes(type[] Types)(type... types) {
    static foreach (T; types[1 .. $])
        static if (!is(typeof(Types[0] == Types[1])))
            return false;
    return true;
}

// -------------------------------

template DeconstArrayType(T) {
    static if (IsStaticArray!(T))
        alias typeof(T[0])[] DeconstArrayType;
    else
        alias T DeconstArrayType;
}

(DeconstArrayType works if T isn't a static array, this is very useful in my code)

type deconstArrayType(type T) {
    static if (isStaticArray!(T))
        return typeof(T[0])[];
        //return (T[0]).typeof[];
    else
        return T;
}

// -------------------------------

template IsType(T, Types...) {
    // Original idea by Burton Radons, modified
    static if (Types.length == 0)
        const bool IsType = false;
    else
        const bool IsType = is(T == Types[0]) || IsType!(T, Types[1 .. $]);
}

bool isType(T, type[] types...) {
    static foreach (TX; types)
        // now == works among run-time variables of type "type".
        static if (T == TX)
            return true;
    return false;
}


Or even simpler, if the compiler understands that isType is a compile-time-function-only:

bool isType(T, type[] types...) {
    foreach (TX; types)
        if (T == TX)
            return true;
    return false;
}


With Any() and a compile-time lambda you can write:

bool isType(T, type[] types...) {
    return Any((type TX){ return T == TX; }, types);
}

:-)

// -------------------------------

Bye,
bearophile



More information about the Digitalmars-d mailing list