www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - template type check syntax

reply gzp <galap freemail.hu> writes:
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
Nov 20 2009
parent reply Bill Baxter <wbaxter gmail.com> writes:
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 ? =A0- 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) {
 =A0 =A0 =A0 =A0enum check1 =3D ...;
 }

 bool check2(T t) {
 =A0 =A0 =A0 =A0return ...;
 }


 void foo(T)(ref T t)
 in {
 =A0 =A0 =A0 =A0static assert( check1!(T) );
 =A0 =A0 =A0 =A0assert(check2(t);
 }
 body {
 =A0 =A0 =A0 =A0static assert( check1!(T) );
 ...
 }
 Or is there a form like (As i've seen mentioned with future coming opBina=
ry)
 void foo(T)(ref T t) if check1!(T)
 {
 =A0 =A0 =A0 =A0in {
 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0assert(check2(t);
 =A0 =A0 =A0 =A0}
 =A0 =A0 =A0 =A0body {
 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0...
 =A0 =A0 =A0 =A0}
 }
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
Nov 20 2009
parent reply Gzp <galap freemail.hu> writes:
 
 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
Nov 21 2009
parent reply "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
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
Nov 22 2009
parent Gzp <galap freemail.hu> writes:
 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 :).
Nov 22 2009