Thread overview
Template matching and is expression
Dec 30, 2010
Piotr Szturmaj
Dec 30, 2010
Simen kjaeraas
Dec 31, 2010
Piotr Szturmaj
December 30, 2010
Hello,

I'm using D2.051 and following code:

import std.variant;

template Nullable(T)
{
    alias Algebraic!(T, void*) Nullable;
}

template isNullable(T)
{
    static if (is(T X == Nullable!U, U))
        enum isNullable = true;
    else
        enum isNullable = false;
}

static assert(isNullable!(Nullable!int));

and above static assert fails. Neither this works:

template isNullable(T : Nullable!U, U)
{
    enum isNullable = true;
}

template isNullable(T)
{
    enum isNullable = false;
}

static assert(isNullable!(Nullable!int));

Question is, what I'm doing wrong?
December 30, 2010
Piotr Szturmaj <bncrbme@jadamspam.pl> wrote:

> static assert(isNullable!(Nullable!int));
>
> Question is, what I'm doing wrong?

The problem here is that Nullable!T is not a real type. Hence, Nullable!int is actually
Algebraic!(int,void*). Checking for that apparently does not work as simply as one might
hope. So, instead you should create a wrapper. This works:


struct Nullable(T) {
    Algebraic!(T, void*) Nullable;
    alias Nullable this;
}

template isNullable(T) {
    static if (is(T X == Nullable!(U), U))
        enum isNullable = true;
    else
        enum isNullable = false;
}

static assert(isNullable!(Nullable!int));

-- 
Simen
December 31, 2010
Simen kjaeraas wrote:
> Piotr Szturmaj <bncrbme@jadamspam.pl> wrote:
>
>> static assert(isNullable!(Nullable!int));
>>
>> Question is, what I'm doing wrong?
>
> The problem here is that Nullable!T is not a real type. Hence,
> Nullable!int is actually
> Algebraic!(int,void*). Checking for that apparently does not work as
> simply as one might
> hope.

Algebraic is also an alias for VariantN (which is real type):

template Algebraic(T...)
{
    alias VariantN!(maxSize!(T), T) Algebraic;
}

however this check also yields false:

static if (is(T X == VariantN!(U), U...))

but this works:

static if (is(T == Nullable!int))

so, I was a bit confused...

So, instead you should create a wrapper. This works:
>
>
> struct Nullable(T) {
> Algebraic!(T, void*) Nullable;
> alias Nullable this;
> }
>
> template isNullable(T) {
> static if (is(T X == Nullable!(U), U))
> enum isNullable = true;
> else
> enum isNullable = false;
> }
>
> static assert(isNullable!(Nullable!int));
>

Thanks! I've already used wrappers like that, but I though it's possible to match aliases directly.

regards,
Piotr