www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - bug with is(T == TI!TP) expression: captures templated structs but

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

template Test(alias T){
  static if(is(T == TI!TP, alias TI, TP)){
    enum Test=true;
  }
  else{
    enum Test=false;
  }
}

struct A(T){}
void foo(T)(T a){}

void main(){
  static assert(Test!(A!double));
  static assert(!Test!(foo!double)); //why is Test false?
}

This is blocking my pull request to make
fullyQualifiedName/GetTemplateParent/GetTemplateArguments work on
everything: right now it fails on templated functions.

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

<div>template Test(alias T){</div><div>=A0 static if(is(T =3D=3D TI!TP, ali=
as TI, TP)){</div><div>=A0 =A0 enum Test=3Dtrue;</div><div>=A0 }</div><div>=
=A0 else{</div><div>=A0 =A0 enum Test=3Dfalse;</div><div>=A0 }</div><div>}<=
/div><div><br></div><div>
struct A(T){}</div><div>void foo(T)(T a){}</div><div><br></div><div>void ma=
in(){</div><div>=A0 static assert(Test!(A!double));</div><div>=A0 static as=
sert(!Test!(foo!double)); //why is Test false?</div><div>}</div><div><br></=
div>
<div>This is blocking my pull request to make fullyQualifiedName/GetTemplat=
eParent/GetTemplateArguments work on everything: right now it fails on temp=
lated functions.</div><div><br></div>

--089e01538a541e7f2304dff80a63--
Jun 25 2013
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 06/25/2013 12:32 PM, Timothee Cour wrote:

It is not a bug.

 template Test(alias T){
    static if(is(T == TI!TP, alias TI, TP)){
      enum Test=true;
    }
    else{
      enum Test=false;
    }
 }

 struct A(T){}
 void foo(T)(T a){}

 void main(){
    static assert(Test!(A!double));
    static assert(!Test!(foo!double)); //why is Test false?
 }

Because foo!double is not a type. All forms of the is-expression check whether the first argument is a valid type.
 This is blocking my pull request to make
 fullyQualifiedName/GetTemplateParent/GetTemplateArguments work on
 everything: right now it fails on templated functions.

Jun 25 2013
prev sibling next sibling parent "Dicebot" <public dicebot.lv> writes:
On Tuesday, 25 June 2013 at 10:32:14 UTC, Timothee Cour wrote:
 template Test(alias T){
   static if(is(T == TI!TP, alias TI, TP)){
     enum Test=true;
   }
   else{
     enum Test=false;
   }
 }

 struct A(T){}
 void foo(T)(T a){}

 void main(){
   static assert(Test!(A!double));
   static assert(!Test!(foo!double)); //why is Test false?
 }

 This is blocking my pull request to make
 fullyQualifiedName/GetTemplateParent/GetTemplateArguments work 
 on
 everything: right now it fails on templated functions.

As I have already mentiond in comments to that pull (probably was not clear enough), it is not really a bug, but one of many difficulties when working with function types in generic code. When you pass a function there, you pass function symbol, not its type. For aggregates those are interchangeable, not so for functions. Most simple example: void foo(int x) {} pragma( msg, is(foo == function) ); // false pragma( msg, is(typeof(foo) == function) ); // true So you simply can't do any type matching with T when T is function alias. However, when you take typeof(T), all template information gets lost and you get type of specific instantiation. Looks like not a bug, but lack of required tool.
Jun 25 2013
prev sibling parent Timothee Cour <thelastmammoth gmail.com> writes:
--089e01538a5402138604dff85516
Content-Type: text/plain; charset=ISO-8859-1

On Tue, Jun 25, 2013 at 3:47 AM, Dicebot <public dicebot.lv> wrote:

 On Tuesday, 25 June 2013 at 10:32:14 UTC, Timothee Cour wrote:

 template Test(alias T){
   static if(is(T == TI!TP, alias TI, TP)){
     enum Test=true;
   }
   else{
     enum Test=false;
   }
 }

 struct A(T){}
 void foo(T)(T a){}

 void main(){
   static assert(Test!(A!double));
   static assert(!Test!(foo!double)); //why is Test false?
 }

 This is blocking my pull request to make
 fullyQualifiedName/**GetTemplateParent/**GetTemplateArguments work on
 everything: right now it fails on templated functions.

As I have already mentiond in comments to that pull (probably was not clear enough), it is not really a bug, but one of many difficulties when working with function types in generic code. When you pass a function there, you pass function symbol, not its type. For aggregates those are interchangeable, not so for functions. Most simple example: void foo(int x) {} pragma( msg, is(foo == function) ); // false pragma( msg, is(typeof(foo) == function) ); // true So you simply can't do any type matching with T when T is function alias. However, when you take typeof(T), all template information gets lost and you get type of specific instantiation. Looks like not a bug, but lack of required tool.

So how can I decompose alias fun=foo!double into template parent / template arguments? The compiler knows this so there has to be a way to retrieve it. If not, then we're back in my previous proposal, adding: __traits(templateParent, symbol) __traits(templateArguments, symbol) --089e01538a5402138604dff85516 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <div class=3D"gmail_quote">On Tue, Jun 25, 2013 at 3:47 AM, Dicebot <span d= ir=3D"ltr">&lt;<a href=3D"mailto:public dicebot.lv" target=3D"_blank">publi= c dicebot.lv</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" sty= le=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> <div class=3D"im">On Tuesday, 25 June 2013 at 10:32:14 UTC, Timothee Cour w= rote:<br> </div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-l= eft:1px #ccc solid;padding-left:1ex"><div class=3D"im"> template Test(alias T){<br> =A0 static if(is(T =3D=3D TI!TP, alias TI, TP)){<br> =A0 =A0 enum Test=3Dtrue;<br> =A0 }<br> =A0 else{<br> =A0 =A0 enum Test=3Dfalse;<br> =A0 }<br> }<br> <br> struct A(T){}<br> void foo(T)(T a){}<br> <br> void main(){<br> =A0 static assert(Test!(A!double));<br> =A0 static assert(!Test!(foo!double)); //why is Test false?<br> }<br> <br></div><div class=3D"im"> This is blocking my pull request to make<br> fullyQualifiedName/<u></u>GetTemplateParent/<u></u>GetTemplateArguments wor= k on<br> everything: right now it fails on templated functions.<br> </div></blockquote> <br> As I have already mentiond in comments to that pull (probably was not clear= enough), it is not really a bug, but one of many difficulties when working= with function types in generic code.<br> <br> When you pass a function there, you pass function symbol, not its type. For= aggregates those are interchangeable, not so for functions. Most simple ex= ample:<br> <br> =A0 =A0 void foo(int x) {}<br> =A0 =A0 pragma( msg, is(foo =3D=3D function) ); // false<br> =A0 =A0 pragma( msg, is(typeof(foo) =3D=3D function) ); // true<br> <br> So you simply can&#39;t do any type matching with T when T is function alia= s.<br> <br> However, when you take typeof(T), all template information gets lost and yo= u get type of specific instantiation.<br> <br> Looks like not a bug, but lack of required tool.<br> </blockquote></div><br><div><br></div><div><div>So how can I decompose alia= s fun=3Dfoo!double into=A0<font color=3D"#500050" face=3D"arial, sans-serif= ">template parent / template arguments?=A0</font></div><div><font color=3D"= #500050" face=3D"arial, sans-serif">The compiler knows this so there has to= be a way to retrieve it. If not, then we&#39;re back in my previous propos= al, adding:</font></div> <div><div><font color=3D"#500050" face=3D"arial, sans-serif">__traits(templ= ateParent, symbol)</font></div></div></div><div><div><font color=3D"#500050= " face=3D"arial, sans-serif">__traits(templateArguments, symbol)</font></di= v></div> <div><font color=3D"#500050" face=3D"arial, sans-serif"><br></font></div> --089e01538a5402138604dff85516--
Jun 25 2013