digitalmars.D.learn - match class specialization
- mandel (14/14) Apr 25 2007 I like to test if a type is a specialization of a template.
- BCS (11/28) Apr 25 2007 template TestA(U : A!(T))
- mandel (30/46) Apr 25 2007 Thank you for your quick reply!
- Frits van Bommel (51/54) Apr 25 2007 The code provided doesn't compile on GDC ("Error: identifier 'T' is not
- BCS (16/24) Apr 25 2007 template TestA(U : A!(T))
- Frits van Bommel (15/33) Apr 25 2007 There's no mention in the spec (at least, that I or Google can find) of
- BCS (4/44) Apr 25 2007 Exactly, I only said that it "compiles but doesn't work", ... for the
- Jarrett Billingsley (5/7) Apr 25 2007 Have a look at Expressions/IsExpressions, number 6. That feature's been...
- mandel (27/44) Apr 25 2007 Thank you for your quick reply!
I like to test if a type is a specialization of a template. The following code does not work/compile but may show my intention. class A(T) {} void main() { alias A!(int) foo; if(is(foo : A) { /* */ } } I also cannot alter class A(T){} because it's part of a library. If A would inherit from a non template class/interface B, is(A : B) would do the job, but that's not the case. Any ideas?
Apr 25 2007
mandel wrote:I like to test if a type is a specialization of a template. The following code does not work/compile but may show my intention. class A(T) {} void main() { alias A!(int) foo; if(is(foo : A) { /* */ } } I also cannot alter class A(T){} because it's part of a library. If A would inherit from a non template class/interface B, is(A : B) would do the job, but that's not the case. Any ideas?template TestA(U : A!(T)) { const bool TestA = true; } template TestA(U) { const bool TestA = false; } static if(TestA!(foo)) I haven't even tried to run that so...
Apr 25 2007
BCS Wrote:template TestA(U : A!(T)) { const bool TestA = true; } template TestA(U) { const bool TestA = false; } static if(TestA!(foo)) I haven't even tried to run that so...Thank you for your quick reply! I didn't thought the compiler let you use TestA(U : A!(T)) without explicitly declaring T a template variable. Well, you code works fine when foo is A!(T) no matter what T is, but it doesn't work when foo inherits from A!(T). So, the problem still remains.. class A(T) { } class B(T) : A!(T) { } template TestA(U : A!(T)) { const bool TestA = true; } template TestA(U) { const bool TestA = false; } void main() { alias B!(int) foo; //doesn't work //alias A!(int) foo;//work static if(TestA!(foo)) { Stdout("is A(T)\n"); } }
Apr 25 2007
mandel wrote:Well, you code works fine when foo is A!(T) no matter what T is, but it doesn't work when foo inherits from A!(T). So, the problem still remains..The code provided doesn't compile on GDC ("Error: identifier 'T' is not defined")[1] Therefore, the following is for DMD only: To walk up the inheritance tree: ----- import std.stdio; class A(T) {} class B(T) : A!(T) {} template TestA(U : A!(T)) { const TestA = true; } template TestA(U) { static if (is(U Bases == super) && is(Bases[0] == class)) const TestA = TestA!(Bases[0]); else const TestA = false; } void test(U)() { writef(typeid(U)); static if(TestA!(U)) { writefln("\t: A(T)"); } else { writefln("\t: not A(T)"); } } class C {} void main() { test!(B!(int)); test!(A!(int)); test!(int); test!(C); } ----- Assumptions: * A!(whatever) is a class, not an interface. * The first element of the tuple 'returned' by "is(X Tuple == super)" is the base class, if any. I'm not sure if this is guaranteed, but it seems to be the case anyway. If you want to be sure, modify the test to recurse over all base classes. Also note that like the original, it doesn't compile with GDC. [1]: Does anyone know if that's a) a bug in GDC, b) a bug in DMD, c) a consequence of GDC being at DMD v1.007 instead of v1.013, or d) something else? I don't feel like digging into the spec to find out what, if anything, it says about this.
Apr 25 2007
mandel wrote:Thank you for your quick reply! I didn't thought the compiler let you use TestA(U : A!(T)) without explicitly declaring T a template variable. Well, you code works fine when foo is A!(T) no matter what T is, but it doesn't work when foo inherits from A!(T). So, the problem still remains..template TestA(U : A!(T)) { const bool TestA = true; } template TestA(U) { static if(is(U.superof)) const bool TestA = TestA!(U.superof); else const bool TestA = false; } This compiles but doesn't work. I seem to recall that there is no way to get the base class of a type at compile time (that is what .superof is supposed to be doing) If that can be replaced with something that acutely works, the above would work, I think.
Apr 25 2007
BCS wrote:template TestA(U : A!(T)) { const bool TestA = true; } template TestA(U) { static if(is(U.superof)) const bool TestA = TestA!(U.superof); else const bool TestA = false; } This compiles but doesn't work.There's no mention in the spec (at least, that I or Google can find) of a "superof" property. Google did find two previous threads where it's mentioned mentioning in the newsgroup archives, but the only post claiming it should already work seems to be posted by you... By the way, above code probably only compiles because .superof is only mentioned in an is() expression (which therefore evaluates to false) and a syntactically-correct declaration in the false branch of a static if.I seem to recall that there is no way to get the base class of a type at compile time (that is what .superof is supposed to be doing) If that can be replaced with something that acutely works, the above would work, I think.As I posted just before you (you probably missed it while posting), this seems to work: --- static if (is(U Bases == super) && is(Bases[0] == class)) // Bases[0] is th base class } ---
Apr 25 2007
Frits van Bommel wrote:BCS wrote:Exactly, I only said that it "compiles but doesn't work", ... for the exact reason you stated. I only wish it worked.template TestA(U : A!(T)) { const bool TestA = true; } template TestA(U) { static if(is(U.superof)) const bool TestA = TestA!(U.superof); else const bool TestA = false; } This compiles but doesn't work.There's no mention in the spec (at least, that I or Google can find) of a "superof" property. Google did find two previous threads where it's mentioned mentioning in the newsgroup archives, but the only post claiming it should already work seems to be posted by you... By the way, above code probably only compiles because .superof is only mentioned in an is() expression (which therefore evaluates to false) and a syntactically-correct declaration in the false branch of a static if.where dos that come from?? googel gets nothingI seem to recall that there is no way to get the base class of a type at compile time (that is what .superof is supposed to be doing) If that can be replaced with something that acutely works, the above would work, I think.As I posted just before you (you probably missed it while posting), this seems to work: --- static if (is(U Bases == super) && is(Bases[0] == class)) // Bases[0] is th base class } ---
Apr 25 2007
"BCS" <BCS pathlink.com> wrote in message news:f0o7hp$29rs$1 digitalmars.com...Frits van Bommel wrote: where dos that come from?? googel gets nothingHave a look at Expressions/IsExpressions, number 6. That feature's been around for quite some time now. std.traits.BaseTypeTuple looks a little nicer though.
Apr 25 2007
BCS Wrote:template TestA(U : A!(T)) { const bool TestA = true; } template TestA(U) { const bool TestA = false; } static if(TestA!(foo)) I haven't even tried to run that so...Thank you for your quick reply! Your code works when foo is A!(T) for every T, but it doesn't work when foo inherits A!(T): class A(T) { } class B(T) : A!(T) { } template TestA(U : A!(T)) { const bool TestA = true; } template TestA(U) { const bool TestA = false; } void main() { alias B!(int) foo; //doesn't work //alias A!(int) foo;//work static if(TestA!(foo)) { Stdout("is A(T)\n"); } }
Apr 25 2007