www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - isCallableCTFE trait to test whether an expression is callable during

reply Timothee Cour <thelastmammoth gmail.com> writes:
--e89a8ff1cf82f9f1c404e132fcdf
Content-Type: text/plain; charset=ISO-8859-1

template isCallableCTFE(alias fun){
template isCallableCTFE_aux(alias T){
enum isCallableCTFE_aux=T;
}
enum isCallableCTFE=__traits(compiles,isCallableCTFE_aux!(fun()));
}

template isCallableCTFE2(fun...){
enum isCallableCTFE2=true;
}


unittest{
int fun1(){
return 1;
}
auto fun1_N(){
import std.array;
//would return Error: gc_malloc cannot be interpreted at compile time,
because it has no available source code due to a bug
return [1].array;
}
int fun2(int x){
return 1;
}
auto fun2_N(int x){
import std.array;
//same as fun1_N
return [1].array;
}

int a1;
enum a2=0;

static assert(!isCallableCTFE!(()=>a1));
static assert(isCallableCTFE!(()=>a2));

static assert(isCallableCTFE!fun1);
static assert(!isCallableCTFE!fun1_N);

static assert(isCallableCTFE!(()=>fun2(0)));
static assert(!isCallableCTFE!(()=>fun2_N(0)));
//NOTE:an alternate syntax which could be implemented would be: static
assert(!isCallableCTFE!(fun2_N,0)));
}

--e89a8ff1cf82f9f1c404e132fcdf
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div>template isCallableCTFE(alias fun){</div><div><span class=3D"Apple-tab=
-span" style=3D"white-space:pre">	</span>template isCallableCTFE_aux(alias =
T){</div><div><span class=3D"Apple-tab-span" style=3D"white-space:pre">		</=
span>enum isCallableCTFE_aux=3DT;</div>
<div><span class=3D"Apple-tab-span" style=3D"white-space:pre">	</span>}</di=
v><div><span class=3D"Apple-tab-span" style=3D"white-space:pre">	</span>enu=
m isCallableCTFE=3D__traits(compiles,isCallableCTFE_aux!(fun()));</div><div=
}</div>

=3D"Apple-tab-span" style=3D"white-space:pre"> </span>enum isCallableCTFE2= =3Dtrue;</div><div>}</div><div><br></div><div><br></div><div>unittest{</div=
<div>

{</div><div><span class=3D"Apple-tab-span" style=3D"white-space:pre"> </sp= an>return 1;</div><div><span class=3D"Apple-tab-span" style=3D"white-space:= pre"> </span>}</div> <div><span class=3D"Apple-tab-span" style=3D"white-space:pre"> </span>auto = fun1_N(){</div><div><span class=3D"Apple-tab-span" style=3D"white-space:pre= "> </span>import std.array;</div><div><span class=3D"Apple-tab-span" style= =3D"white-space:pre"> </span>//would return Error: gc_malloc cannot be int= erpreted at compile time, because it has no available source code due to a = bug</div> <div><span class=3D"Apple-tab-span" style=3D"white-space:pre"> </span>retu= rn [1].array;</div><div><span class=3D"Apple-tab-span" style=3D"white-space= :pre"> </span>}</div><div><span class=3D"Apple-tab-span" style=3D"white-spa= ce:pre"> </span>int fun2(int x){</div> <div><span class=3D"Apple-tab-span" style=3D"white-space:pre"> </span>retu= rn 1;</div><div><span class=3D"Apple-tab-span" style=3D"white-space:pre"> <= /span>}</div><div><span class=3D"Apple-tab-span" style=3D"white-space:pre">= </span>auto fun2_N(int x){</div> <div><span class=3D"Apple-tab-span" style=3D"white-space:pre"> </span>impo= rt std.array;</div><div><span class=3D"Apple-tab-span" style=3D"white-space= :pre"> </span>//same as fun1_N</div><div><span class=3D"Apple-tab-span" st= yle=3D"white-space:pre"> </span>return [1].array;</div> <div><span class=3D"Apple-tab-span" style=3D"white-space:pre"> </span>}</di= v><div><br></div><div><span class=3D"Apple-tab-span" style=3D"white-space:p= re"> </span>int a1;</div><div><span class=3D"Apple-tab-span" style=3D"white= -space:pre"> </span>enum a2=3D0;</div> <div><br></div><div><span class=3D"Apple-tab-span" style=3D"white-space:pre= "> </span>static assert(!isCallableCTFE!(()=3D&gt;a1));</div><div><span cla= ss=3D"Apple-tab-span" style=3D"white-space:pre"> </span>static assert(isCal= lableCTFE!(()=3D&gt;a2));</div> <div><br></div><div><span class=3D"Apple-tab-span" style=3D"white-space:pre= "> </span>static assert(isCallableCTFE!fun1);</div><div><span class=3D"Appl= e-tab-span" style=3D"white-space:pre"> </span>static assert(!isCallableCTFE= !fun1_N);</div> <div><br></div><div><span class=3D"Apple-tab-span" style=3D"white-space:pre= "> </span>static assert(isCallableCTFE!(()=3D&gt;fun2(0)));</div><div><span= class=3D"Apple-tab-span" style=3D"white-space:pre"> </span>static assert(!= isCallableCTFE!(()=3D&gt;fun2_N(0)));</div> <div><span class=3D"Apple-tab-span" style=3D"white-space:pre"> </span>//NOT= E:an alternate syntax which could be implemented would be: static assert(!i= sCallableCTFE!(fun2_N,0)));</div><div>}</div> --e89a8ff1cf82f9f1c404e132fcdf--
Jul 10 2013
next sibling parent "timotheecour" <timothee.cour2 gmail.com> writes:
On Thursday, 11 July 2013 at 02:17:13 UTC, Timothee Cour wrote:
 template isCallableCTFE(alias fun){
 template isCallableCTFE_aux(alias T){
 enum isCallableCTFE_aux=T;
 }
 enum 
 isCallableCTFE=__traits(compiles,isCallableCTFE_aux!(fun()));
 }

 template isCallableCTFE2(fun...){
 enum isCallableCTFE2=true;
 }


 unittest{
 int fun1(){
 return 1;
 }
 auto fun1_N(){
 import std.array;
 //would return Error: gc_malloc cannot be interpreted at 
 compile time,
 because it has no available source code due to a bug
 return [1].array;
 }
 int fun2(int x){
 return 1;
 }
 auto fun2_N(int x){
 import std.array;
 //same as fun1_N
 return [1].array;
 }

 int a1;
 enum a2=0;

 static assert(!isCallableCTFE!(()=>a1));
 static assert(isCallableCTFE!(()=>a2));

 static assert(isCallableCTFE!fun1);
 static assert(!isCallableCTFE!fun1_N);

 static assert(isCallableCTFE!(()=>fun2(0)));
 static assert(!isCallableCTFE!(()=>fun2_N(0)));
 //NOTE:an alternate syntax which could be implemented would be: 
 static
 assert(!isCallableCTFE!(fun2_N,0)));
 }

can we add this to std.traits? it allows (among other things) to write unittests for CTFE, etc.
Jul 10 2013
prev sibling next sibling parent "Kenji Hara" <k.hara.pg gmail.com> writes:
On Thursday, 11 July 2013 at 03:10:38 UTC, timotheecour wrote:
 On Thursday, 11 July 2013 at 02:17:13 UTC, Timothee Cour wrote:

 can we add this to std.traits?
 it allows (among other things) to write unittests for CTFE, etc.

Phobos has an internal helper function for testing CTFEable. https://github.com/D-Programming-Language/phobos/blob/master/std/exception.d#L1322 Kenji Hara
Jul 10 2013
prev sibling parent "timotheecour" <timothee.cour2 gmail.com> writes:
On Thursday, 11 July 2013 at 03:29:13 UTC, Kenji Hara wrote:
 On Thursday, 11 July 2013 at 03:10:38 UTC, timotheecour wrote:
 On Thursday, 11 July 2013 at 02:17:13 UTC, Timothee Cour wrote:

 can we add this to std.traits?
 it allows (among other things) to write unittests for CTFE, 
 etc.

Phobos has an internal helper function for testing CTFEable. https://github.com/D-Programming-Language/phobos/blob/master/std/exception.d#L1322 Kenji Hara

Mine is more flexible. The one you mention can only work in a static assert statement. We could replace it in terms of static assert(isCallableCTFE!dg) but not vice versa.
Jul 10 2013