digitalmars.D - feature request: __traits(getTemplate, A!T) => A;
- Timothee Cour (44/44) Jun 22 2013 I've fixed several limitations in std.traits.fullyQualifiedName
- Dicebot (20/20) Jun 22 2013 http://dpaste.1azy.net/22d5eee2
- Timon Gehr (2/22) Jun 22 2013 Only works for types.
- anonymous (8/20) Jun 22 2013 Replacing the static if with template specialization makes it
- Timothee Cour (8/32) Jun 22 2013 great, thanks!
- anonymous (7/12) Jun 22 2013 Just add another overload (is that the correct term?) with alias
- Timothee Cour (6/20) Jun 22 2013 did you test it? doesn't work for me:
- anonymous (5/18) Jun 22 2013 Oh, sorry. I had tested it with generic templates and assumed it
- Timothee Cour (13/34) Jun 22 2013 there's also this case:
- anonymous (6/20) Jun 22 2013 E8!float.A itself is not a template instance, its parent is. I
- Dicebot (2/2) Jun 23 2013 Nice, thanks! Didn't know this syntax is allowed in template
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?
Jun 22 2013
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
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
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
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: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.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; }
Jun 22 2013
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
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: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...)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
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:[...]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.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...)
Jun 22 2013
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: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 ?On Sat, Jun 22, 2013 at 5:07 PM, anonymous <anonymous example.com> wrote:[...]template 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.{ 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...)
Jun 22 2013
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
Nice, thanks! Didn't know this syntax is allowed in template specialization too.
Jun 23 2013









Timon Gehr <timon.gehr gmx.ch> 