www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - feature request: __traits(getTemplate, A!T) => A;

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

I've fixed several limitations in std.traits.fullyQualifiedName
/ packageName / moduleName but still have issues with templated types /
functions:

currently:
struct A{}
std.traits.fullyQualifiedName!(A!(int)) => CT error.

attempt to fix it:

----
template Stringof(alias T){
static if (!isCallable!T) enum Stringof = T.stringof;
else enum Stringof = __traits(identifier, T);
}
template isTemplateInstantiation(alias T){
import std.algorithm;
enum isTemplateInstantiation=Stringof!T.canFind(`!`);
}
template fullyQualifiedName(alias T)
{
static if (isTemplateInstantiation!T){
enum s=Stringof!T;
import std.algorithm;
enum s2=s.findSplit("!");
mixin(`alias temp=`~s2[0]~`;`);
enum fullyQualifiedName =fullyQualifiedName!temp~s2[1]~s2[2];
}
        else{...}
}

version(unittest){
  struct A(T1,T2){}
}
unittest{
  static assert(fullyQualifiedName!(A!(int,double)) == "util.traits.A!(int,
double)");
}
----

however, it works only when "A" is visible in the scope of
fullyQualifiedName, so it's pretty useless as it is. A potential fix would
be to require the user to use a mixin
(mixin(fullyQualifiedNameMixin!(A!double)) ) but that's ugly.

What we need:
__traits(getTemplate, A!T) => A
__traits(getTemplateArguments, A!(T,"foo")) => (T,"foo") (ie returns a
tuple as in parameterTypeTuple or similar)

any thoughts?

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

I&#39;ve fixed several limitations in std.traits.fullyQualifiedName /=A0pac=
kageName /=A0moduleName but still have issues with templated types / functi=
ons:<div><br></div><div>currently:</div><div>struct A{}</div><div>std.trait=
s.fullyQualifiedName!(A!(int)) =3D&gt; CT error.</div>
<div><br></div><div>attempt to fix it:</div><div><div><br></div><div>----</=
div><div><div>template Stringof(alias T){</div><div><span class=3D"Apple-ta=
b-span" style=3D"white-space:pre">	</span>static if (!isCallable!T) enum St=
ringof =3D T.stringof;</div>
<div><span class=3D"Apple-tab-span" style=3D"white-space:pre">	</span>else =
enum Stringof =3D __traits(identifier, T);</div><div>}</div></div><div></di=
v><div>template isTemplateInstantiation(alias T){</div><div><span class=3D"=
Apple-tab-span" style=3D"white-space:pre">	</span>import std.algorithm;</di=
v>
<div><span class=3D"Apple-tab-span" style=3D"white-space:pre">	</span>enum =
isTemplateInstantiation=3DStringof!T.canFind(`!`);</div><div>}</div></div><=
div><div>template fullyQualifiedName(alias T)</div></div><div><div>{</div><=
div>
<span class=3D"Apple-tab-span" style=3D"white-space:pre">	</span>static if =
(isTemplateInstantiation!T){</div><div><span class=3D"Apple-tab-span" style=
=3D"white-space:pre">		</span>enum s=3DStringof!T;</div><div><span class=3D=
"Apple-tab-span" style=3D"white-space:pre">		</span>import std.algorithm;</=
div>
<div><span class=3D"Apple-tab-span" style=3D"white-space:pre">		</span>enum=
 s2=3Ds.findSplit(&quot;!&quot;);</div><div><span class=3D"Apple-tab-span" =
style=3D"white-space:pre">		</span>mixin(`alias temp=3D`~s2[0]~`;`);</div><=
div><span class=3D"Apple-tab-span" style=3D"white-space:pre">		</span>enum =
fullyQualifiedName =3DfullyQualifiedName!temp~s2[1]~s2[2];</div>
<div><span class=3D"Apple-tab-span" style=3D"white-space:pre">	</span>}</di=
v></div><div>=A0 =A0 =A0 =A0 else{...}</div><div>}</div><div><br></div><div=
version(unittest){</div><div>=A0 struct A(T1,T2){}</div><div>}</div><div>u=

<div>=A0 static assert(fullyQualifiedName!(A!(int,double)) =3D=3D &quot;uti= l.traits.A!(int, double)&quot;);</div><div>}</div><div><div>----</div><div>= <br></div><div>however, it works only when &quot;A&quot; is visible in the = scope of fullyQualifiedName, so it&#39;s pretty useless as it is. A potenti= al fix would be to require the user to use a mixin (mixin(fullyQualifiedNam= eMixin!(A!double)) ) but that&#39;s ugly.</div> <div><br></div><div>What we need:</div><div><div>__traits(getTemplate, A!T)= =3D&gt; A</div></div><div><div>__traits(getTemplateArguments, A!(T,&quot;f= oo&quot;)) =3D&gt; (T,&quot;foo&quot;) (ie returns a tuple as in parameterT= ypeTuple or similar)</div> </div><div><br></div><div>any thoughts?</div><div></div></div> --089e013cc3965c82c904dfc55cf9--
Jun 22 2013
next sibling parent reply "Dicebot" <public dicebot.lv> writes:
http://dpaste.1azy.net/22d5eee2

------------------------------------

import std.traits;

template getTemplate(T)
{
	static if (is(T == TI!TP, alias TI, TP))
	{
		alias getTemplate = TI;
	}
	else
		static assert (false);
}

private struct A(T)
{
	T x;
}

pragma( msg, fullyQualifiedName!(getTemplate!(A!int)) );

void main()
{
}
Jun 22 2013
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 06/23/2013 01:03 AM, Dicebot wrote:
 http://dpaste.1azy.net/22d5eee2

 ------------------------------------

 import std.traits;

 template getTemplate(T)
 {
      static if (is(T == TI!TP, alias TI, TP))
      {
          alias getTemplate = TI;
      }
      else
          static assert (false);
 }

 private struct A(T)
 {
      T x;
 }

 pragma( msg, fullyQualifiedName!(getTemplate!(A!int)) );

 void main()
 {
 }

Only works for types.
Jun 22 2013
prev sibling next sibling parent "anonymous" <anonymous example.com> writes:
On Saturday, 22 June 2013 at 23:03:17 UTC, Dicebot wrote:
 http://dpaste.1azy.net/22d5eee2

 ------------------------------------

 import std.traits;

 template getTemplate(T)
 {
 	static if (is(T == TI!TP, alias TI, TP))

alias! Of course!
 	{
 		alias getTemplate = TI;
 	}
 	else
 		static assert (false);
 }

Replacing the static if with template specialization makes it shorter: template getTemplate(T : TI!TP, alias TI, TP) { alias getTemplate = TI; }
Jun 22 2013
prev sibling next sibling parent Timothee Cour <thelastmammoth gmail.com> writes:
--089e013cc39698d87304dfc6efda
Content-Type: text/plain; charset=ISO-8859-1

On Sat, Jun 22, 2013 at 4:18 PM, anonymous <anonymous example.com> wrote:

 On Saturday, 22 June 2013 at 23:03:17 UTC, Dicebot wrote:

 http://dpaste.1azy.net/**22d5eee2 <http://dpaste.1azy.net/22d5eee2>

 ------------------------------**------

 import std.traits;

 template getTemplate(T)
 {
         static if (is(T == TI!TP, alias TI, TP))

alias! Of course! {
                 alias getTemplate = TI;
         }
         else
                 static assert (false);
 }

Replacing the static if with template specialization makes it shorter: template getTemplate(T : TI!TP, alias TI, TP) { alias getTemplate = TI; }

great, thanks! improved to support arbitrary number of a template getTemplate(T : TI!TP, alias TI, TP...) { alias getTemplate = TI; } however, indeed seems to work with types only, not functions. --089e013cc39698d87304dfc6efda Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <div><div class=3D"gmail_quote">On Sat, Jun 22, 2013 at 4:18 PM, anonymous = <span dir=3D"ltr">&lt;<a href=3D"mailto:anonymous example.com" target=3D"_b= lank">anonymous example.com</a>&gt;</span> wrote:<br><blockquote class=3D"g= mail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-l= eft:1ex"> <div class=3D"im">On Saturday, 22 June 2013 at 23:03:17 UTC, Dicebot wrote:= <br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> <a href=3D"http://dpaste.1azy.net/22d5eee2" target=3D"_blank">http://dpaste= .1azy.net/<u></u>22d5eee2</a><br> <br> ------------------------------<u></u>------<br> <br> import std.traits;<br> <br> template getTemplate(T)<br> {<br> =A0 =A0 =A0 =A0 static if (is(T =3D=3D TI!TP, alias TI, TP))<br> </blockquote> <br></div> alias! Of course!<div class=3D"im"><br> <br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> =A0 =A0 =A0 =A0 {<br> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 alias getTemplate =3D TI;<br> =A0 =A0 =A0 =A0 }<br> =A0 =A0 =A0 =A0 else<br> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 static assert (false);<br> }<br> </blockquote> <br></div> Replacing the static if with template specialization makes it shorter:<br> template getTemplate(T : TI!TP, alias TI, TP)<br> {<br> =A0 =A0 alias getTemplate =3D TI;<br> }<br> </blockquote></div><br></div><div>great, thanks!<div>improved to support ar= bitrary number of a</div><div><div>template getTemplate(T : TI!TP, alias TI= , TP...)</div><div>{</div><div><span class=3D"Apple-tab-span" style=3D"whit= e-space:pre"> </span>alias getTemplate =3D TI;</div> <div>}</div></div><div><br></div></div><div><br></div><div>however, indeed = seems to work with types only, not functions.=A0</div> --089e013cc39698d87304dfc6efda--
Jun 22 2013
prev sibling next sibling parent "anonymous" <anonymous example.com> writes:
On Saturday, 22 June 2013 at 23:57:17 UTC, Timothee Cour wrote:
 template getTemplate(T : TI!TP, alias TI, TP...)
 {
 alias getTemplate = TI;
 }


 however, indeed seems to work with types only, not functions.

Just add another overload (is that the correct term?) with alias T: template getTemplate(alias T : TI!TP, alias TI, TP...) { alias getTemplate = TI; }
Jun 22 2013
prev sibling next sibling parent Timothee Cour <thelastmammoth gmail.com> writes:
--089e0158ae38228b1104dfc73ba8
Content-Type: text/plain; charset=ISO-8859-1

On Sat, Jun 22, 2013 at 5:07 PM, anonymous <anonymous example.com> wrote:

 On Saturday, 22 June 2013 at 23:57:17 UTC, Timothee Cour wrote:

 template getTemplate(T : TI!TP, alias TI, TP...)
 {
 alias getTemplate = TI;
 }


 however, indeed seems to work with types only, not functions.

Just add another overload (is that the correct term?) with alias T: template getTemplate(alias T : TI!TP, alias TI, TP...) { alias getTemplate = TI; }

did you test it? doesn't work for me: auto fun(T)(T x){return x;} pragma(msg,__LINE__,":",getTemplate!(fun!double)); Error: template instance getTemplate!(fun) does not match template declaration getTemplate(alias T : TI!(TP), alias TI, TP...) --089e0158ae38228b1104dfc73ba8 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <br><br><div class=3D"gmail_quote">On Sat, Jun 22, 2013 at 5:07 PM, anonymo= us <span dir=3D"ltr">&lt;<a href=3D"mailto:anonymous example.com" target=3D= "_blank">anonymous example.com</a>&gt;</span> wrote:<br><blockquote class= =3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd= ing-left:1ex"> <div class=3D"im">On Saturday, 22 June 2013 at 23:57:17 UTC, Timothee Cour = wrote:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> template getTemplate(T : TI!TP, alias TI, TP...)<br> {<br> alias getTemplate =3D TI;<br> }<br> <br> <br> however, indeed seems to work with types only, not functions.<br> </blockquote> <br></div> Just add another overload (is that the correct term?) with alias T:<br> <br> template getTemplate(alias T : TI!TP, alias TI, TP...)<br> {<br> alias getTemplate =3D TI;<br> }<br> </blockquote></div><div><br></div>did you test it? doesn&#39;t work for me:= <br><div><br></div><div> <font face=3D"Menlo"> <span style=3D"color:#009695">auto</span><span style=3D"color:#444444">=A0<= /span><span style=3D"color:#444444">fun</span><span style=3D"color:#444444"=
(</span><span style=3D"color:#444444">T</span><span style=3D"color:#444444=

4">T</span><span style=3D"color:#444444">=A0</span><span style=3D"color:#44= 4444">x</span><span style=3D"color:#444444">)</span><span style=3D"color:#4= 44444">{</span><span style=3D"color:#009695">return</span><span style=3D"co= lor:#444444">=A0</span><span style=3D"color:#444444">x</span><span style=3D= "color:#444444">;</span><span style=3D"color:#444444">}</span></font> </div><div><span style=3D"color:rgb(68,68,68);font-family:Menlo">pragma(msg= ,__LINE__,&quot;:&quot;,getTemplate!(</span><span style=3D"color:rgb(68,68,= 68);font-family:Menlo">fun</span><span style=3D"color:rgb(68,68,68);font-fa= mily:Menlo">!double));</span></div> <div><span style=3D"color:rgb(68,68,68);font-family:Menlo"><br></span></div=
<div><font color=3D"#444444" face=3D"Menlo">Error: template instance getTe=

pan><font color=3D"#444444" face=3D"Menlo">) does not match template declar= ation getTemplate(alias T : TI!(TP), alias TI, TP...)</font></div> --089e0158ae38228b1104dfc73ba8--
Jun 22 2013
prev sibling next sibling parent "anonymous" <anonymous example.com> writes:
On Sunday, 23 June 2013 at 00:18:23 UTC, Timothee Cour wrote:
 On Sat, Jun 22, 2013 at 5:07 PM, anonymous 
 <anonymous example.com> wrote:

 template getTemplate(alias T : TI!TP, alias TI, TP...)
 {
 alias getTemplate = TI;
 }

did you test it? doesn't work for me: auto fun(T)(T x){return x;} pragma(msg,__LINE__,":",getTemplate!(fun!double)); Error: template instance getTemplate!(fun) does not match template declaration getTemplate(alias T : TI!(TP), alias TI, TP...)

Oh, sorry. I had tested it with generic templates and assumed it would work with everything that's not a type. No ideas on how to make it work with function templates then.
Jun 22 2013
prev sibling next sibling parent Timothee Cour <thelastmammoth gmail.com> writes:
--089e013a07721fb5e504dfc7755f
Content-Type: text/plain; charset=ISO-8859-1

On Sat, Jun 22, 2013 at 5:24 PM, anonymous <anonymous example.com> wrote:

 On Sunday, 23 June 2013 at 00:18:23 UTC, Timothee Cour wrote:

 On Sat, Jun 22, 2013 at 5:07 PM, anonymous <anonymous example.com> wrote:

 template getTemplate(alias T : TI!TP, alias TI, TP...)
 {
 alias getTemplate = TI;
 }

auto fun(T)(T x){return x;} pragma(msg,__LINE__,":",**getTemplate!(fun!double)); Error: template instance getTemplate!(fun) does not match template declaration getTemplate(alias T : TI!(TP), alias TI, TP...)

Oh, sorry. I had tested it with generic templates and assumed it would work with everything that's not a type. No ideas on how to make it work with function templates then.

there's also this case: template E8(T){ struct B{} struct A{} } pragma(msg,__LINE__,":",getTemplate!(E8!(float))); => works with template getTemplate(alias T : TI!TP, alias TI, TP...) specialization pragma(msg,__LINE__,":",getTemplate!(E8!(float).A)); => ?? how to make the 2nd work? is there something like: template getTemplate(alias T : TI!TP.TE, alias TI, alias TE, TP...) {...} available ? --089e013a07721fb5e504dfc7755f Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <div class=3D"gmail_quote">On Sat, Jun 22, 2013 at 5:24 PM, anonymous <span= dir=3D"ltr">&lt;<a href=3D"mailto:anonymous example.com" target=3D"_blank"=
anonymous example.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_=

ex"> <div class=3D"im">On Sunday, 23 June 2013 at 00:18:23 UTC, Timothee Cour wr= ote:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> On Sat, Jun 22, 2013 at 5:07 PM, anonymous &lt;<a href=3D"mailto:anonymous = example.com" target=3D"_blank">anonymous example.com</a>&gt; wrote:<br> </blockquote></div> [...]<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"><div class=3D"im"><blockquote class=3D"gmail= _quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:= 1ex"> template getTemplate(alias T : TI!TP, alias TI, TP...)<br> {<br> alias getTemplate =3D TI;<br> }<br> <br> </blockquote> <br></div><div class=3D"im"> did you test it? doesn&#39;t work for me:<br> <br> =A0auto fun(T)(T x){return x;}<br> pragma(msg,__LINE__,&quot;:&quot;,<u></u>getTemplate!(fun!double));<br> <br> Error: template instance getTemplate!(fun) does not match template<br> declaration getTemplate(alias T : TI!(TP), alias TI, TP...)<br> </div></blockquote> <br> Oh, sorry. I had tested it with generic templates and assumed it would work= with everything that&#39;s not a type. No ideas on how to make it work wit= h function templates then.<br> </blockquote></div><br><div><br></div><div>there&#39;s also this case:</div=
<div><div>template E8(T){</div><div><span class=3D"Apple-tab-span" style=

span" style=3D"white-space:pre"> </span>struct A{}</div> <div>}</div></div><div><br></div><div><div>pragma(msg,__LINE__,&quot;:&quot= ;,getTemplate!(E8!(float))); =3D&gt; works with=A0template getTemplate(alia= s T : TI!TP, alias TI, TP...) specialization</div></div><div><br></div><div=

=A0??</div></div><div>how to make the 2nd work?</div><div><br></div><div>i= s there something like:=A0</div><div>template getTemplate(alias T : TI!TP.T= E, alias TI, alias TE, TP...) {...}=A0</div> <div>available ?</div><div><br></div><div><br></div><div><br></div><div><br=
</div><div><br></div>

--089e013a07721fb5e504dfc7755f--
Jun 22 2013
prev sibling next sibling parent "anonymous" <anonymous example.com> writes:
On Sunday, 23 June 2013 at 00:34:36 UTC, Timothee Cour wrote:
 there's also this case:
 template E8(T){
 struct B{}
 struct A{}
 }

 pragma(msg,__LINE__,":",getTemplate!(E8!(float))); => works 
 with template
 getTemplate(alias T : TI!TP, alias TI, TP...) specialization

 pragma(msg,__LINE__,":",getTemplate!(E8!(float).A)); =>  ??
 how to make the 2nd work?

 is there something like:
 template getTemplate(alias T : TI!TP.TE, alias TI, alias TE, 
 TP...) {...}
 available ?

E8!float.A itself is not a template instance, its parent is. I think it's correct for getTemplate to not compile in this case. In the end, putting getTemplate!Foo and getTemplateArguments!Foo back together should lead to Foo again. I don't see what getTemplate!(E8!float.A) could return for that to hold.
Jun 22 2013
prev sibling parent "Dicebot" <public dicebot.lv> writes:
Nice, thanks! Didn't know this syntax is allowed in template 
specialization too.
Jun 23 2013