www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Get template and its instantiation parameters

reply Michal Minich <michal minich.sk> writes:
If one has a template instance, is it possible to get template name and
parameter 
type that was used for instantiating, at compile time?

consider:

class List (T) {}

List!(int) lst;
Foo (lst);

I want to create such template Foo which prints:
List!(int)
List
int

Something simiar for Arrays can be created:
int[char] x;
Foo (x);

template Foo (X : T[U], T, U)
{
    void Foo (X arr)
    {
        writeln(typeof(arr).stringof);
        writeln(T.stringof);
        writeln(U.stringof);
    }
}

but similar template for template instances does not work:
template Foo (X : T!(U), T, U) // does not matches List!(int)

when is changed to something more specific, it starts working:
template Foo (X : List!(U), U) // matches List!(int)
Oct 07 2009
parent reply BCS <none anon.com> writes:
Hello Michal,

 If one has a template instance, is it possible to get template name
 and parameter type that was used for instantiating, at compile time?
 
 consider:
 
 class List (T) {}
 
 List!(int) lst;
 Foo (lst);
 I want to create such template Foo which prints:
 List!(int)
 List
 int
You could try parsing T.stringof at compiletime to extract the parts you need.
Oct 07 2009
next sibling parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Wed, Oct 7, 2009 at 12:54 PM, BCS <none anon.com> wrote:
 Hello Michal,

 If one has a template instance, is it possible to get template name
 and parameter type that was used for instantiating, at compile time?

 consider:

 class List (T) {}

 List!(int) lst;
 Foo (lst);
 I want to create such template Foo which prints:
 List!(int)
 List
 int
You could try parsing T.stringof at compiletime to extract the parts you need.
This is *exactly* the kind of bullshit that I hate about string mixins. The thought process just ends up going "oh, why bother having any terse, elegant mechanisms to get at program information when you can *parse arbitrary code at compile time*? And why do you need macros when a string substitution will do?" Is it powerful? Sure. But it's lame, ugly, slow, easy to mess up, lacks hygiene, and is unidiomatic. String mixins are basically just a text preprocessor with user-defined functionality. Neat, but it can only get you so far before you're in tarpit territory.
Oct 07 2009
next sibling parent Michal Minich <michal.minich gmail.com> writes:
On Wed, 07 Oct 2009 13:15:46 -0400, Jarrett Billingsley wrote:

 On Wed, Oct 7, 2009 at 12:54 PM, BCS <none anon.com> wrote:
 Hello Michal,

 If one has a template instance, is it possible to get template name
 and parameter type that was used for instantiating, at compile time?

 consider:

 class List (T) {}

 List!(int) lst;
 Foo (lst);
 I want to create such template Foo which prints: List!(int)
 List
 int
You could try parsing T.stringof at compiletime to extract the parts you need.
This is *exactly* the kind of bullshit that I hate about string mixins. The thought process just ends up going "oh, why bother having any terse, elegant mechanisms to get at program information when you can *parse arbitrary code at compile time*? And why do you need macros when a string substitution will do?" Is it powerful? Sure. But it's lame, ugly, slow, easy to mess up, lacks hygiene, and is unidiomatic. String mixins are basically just a text preprocessor with user-defined functionality. Neat, but it can only get you so far before you're in tarpit territory.
Jarrett, I agree with you except the "lame" and "preprocessor" part. But I wouldn't be so harsh on D. The prospect of parsing D code really does not appeal to me. Also the usage of advanced templates is not very intuitive. But please don't forget that features that are made possible by D templates and/or the ".stringof" + CTFE are not available in many languages. Languages that have such or better type level expressivity as D are few, mostly functional ones: Haskell, ML, OCaml, F# (I don't know of Scala). Also these features in D are more general, and even if kludgy, they are *available*. The answer to my question is: The problem was that parameter T needs to be "alias" because it should match "List" which is not complete type, until is applied to some argument (int); it is just template name. The result for T.stringof is surprising for me, but anyway, I get what I needed. class List (T) {} void main () { List!(int) lst; Foo (lst); } template Foo (C : T!(U), alias T, U) { void Foo (C container) { writeln(C.stringof); // List writeln(T.stringof); // List(T) writeln(U.stringof); // int } } (tested on DMD 2.033)
Oct 07 2009
prev sibling parent BCS <none anon.com> writes:
Hello Jarrett,

 On Wed, Oct 7, 2009 at 12:54 PM, BCS <none anon.com> wrote:
 
 You could try parsing T.stringof at compiletime to extract the parts
 you need.
 
This is *exactly* the kind of bullshit that I hate about string mixins.
The question was how to do somthing now. If the best solution isn't that good, it says a few things, but what it does /not/ say is that you shouldn't do the best solution.
Oct 07 2009
prev sibling parent Christopher Wright <dhasenan gmail.com> writes:
BCS wrote:
 Hello Michal,
 
 If one has a template instance, is it possible to get template name
 and parameter type that was used for instantiating, at compile time?

 consider:

 class List (T) {}

 List!(int) lst;
 Foo (lst);
 I want to create such template Foo which prints:
 List!(int)
 List
 int
You could try parsing T.stringof at compiletime to extract the parts you need.
No, you can't. You can try parsing demangle!(T.mangleof) at compiletime to extract the parts you need. stringof is a morass of inconsistency and partial information. Whenever a template gets within a mile of a type, all bets are off.
Oct 07 2009