Thread overview
template type check syntax
Nov 20, 2009
gzp
Nov 20, 2009
Bill Baxter
Nov 21, 2009
Gzp
Nov 22, 2009
Gzp
November 20, 2009
Which is the preferred form ? Shall I place the static assert into the in part or into the body directly ?

Is there any difference ? Is there a way to toggle if the in part is executed/compiled or not ?  - Like in eifel it can be turned on and off by a compiler flag.

template check1(T) {
	enum check1 = ...;
}

bool check2(T t) {
	return ...;
}


void foo(T)(ref T t)
in {
	static assert( check1!(T) );
	assert(check2(t);
}
body {
	static assert( check1!(T) );
...
}


Or is there a form like (As i've seen mentioned with future coming opBinary)
void foo(T)(ref T t) if check1!(T)
{
	in {
		assert(check2(t);
	}
	body {
		...
	}
}


Thanks,
Gzp
November 20, 2009
2009/11/20 gzp <galap@freemail.hu>:
> Which is the preferred form ? Shall I place the static assert into the in part or into the body directly ?
>
> Is there any difference ? Is there a way to toggle if the in part is executed/compiled or not ?  - Like in eifel it can be turned on and off by a compiler flag.

I think static asserts are always checked.
Regular asserts are turned off by the -release flag.


> template check1(T) {
>        enum check1 = ...;
> }
>
> bool check2(T t) {
>        return ...;
> }
>
>
> void foo(T)(ref T t)
> in {
>        static assert( check1!(T) );
>        assert(check2(t);
> }
> body {
>        static assert( check1!(T) );
> ...
> }

> Or is there a form like (As i've seen mentioned with future coming opBinary)
> void foo(T)(ref T t) if check1!(T)
> {
>        in {
>                assert(check2(t);
>        }
>        body {
>                ...
>        }
> }

This form exists in D2 (with parens around the check1 part), but the
meaning is slightly different.

The static assert version allows the template to get instantiated but causes a failure.

The latter form will pass over instantiation of that version of the
template if the "if check1" fails.
It can then go on and try other forms of the template.

For instance you can have this:

void foo(T)(ref T t) if (isPrime!(T)) { ... }
void foo(T)(ref T t) if (!isPrime!(T)) { ... }

But not this:
void foo(T)(ref T t) {  static assert(isPrime!(T); ... }
void foo(T)(ref T t) {  static assert(!isPrime!(T); ... }

because you can't declare two identical templates.


--bb
November 21, 2009
> 
> void foo(T)(ref T t) if (isPrime!(T)) { ... }
> void foo(T)(ref T t) if (!isPrime!(T)) { ... }
> 

What is the difference b/n
void foo(T)(ref T t) if (isPrime!(T)) { ... }
and
void foo(T)(ref T t) static if (isPrime!(T)) { ... }
as both of them seems to be a compile time check for me.

Thanks, Gzp
November 22, 2009
Gzp wrote:
>>
>> void foo(T)(ref T t) if (isPrime!(T)) { ... }
>> void foo(T)(ref T t) if (!isPrime!(T)) { ... }
>>
> 
> What is the difference b/n
> void foo(T)(ref T t) if (isPrime!(T)) { ... }
> and
> void foo(T)(ref T t) static if (isPrime!(T)) { ... }
> as both of them seems to be a compile time check for me.

I'd say that the main difference is that the last one doesn't compile. :) It's simply not valid D code.

The if clause in a template declaration is used for template parameter matching (like in Bill's examples), whereas static if is a statement that is used for conditional compilation. However, you can achieve more or less the same thing with them both, but in slightly different ways.

    // This function template is instantiated when T is int.
    void foo(T)(T t)  if (is(T == int)) { ... }

    // This function template is instantiated for all other types
    void foo(T)(T t)  if (!is(T == int)) { ... }

With static if you'd do it like this:

    void foo(T)(T t)
    {
        static if (is(T == int))
        {
            // This code is compiled when T is int.
            ...
        }
        else
        {
            // This code is compiled for all other types.
            ...
        }
    }

Be aware that if you are chaining several static ifs, you have to type "static" for each one:

    static if (foo) { ... }
    else static if (bar) { ... }
    else static if (baz) { ... }
    else { ... }

-Lars
November 22, 2009
> I'd say that the main difference is that the last one doesn't compile. :) It's simply not valid D code.
> 

Thanks. I've missed the two extra characters ({}) on the post I've seen before :).