digitalmars.D.learn - how to determine if type is final/abstract
- JS (18/18) Jul 11 2013 I have some code that needs to determine if a type
- JS (8/27) Jul 11 2013 much of the code used can be found at
- JS (19/55) Jul 11 2013 I've also tried __traits and other stuff. I have access to the
- Jacob Carlborg (5/8) Jul 11 2013 Have you tried using a mixin?
- JS (7/16) Jul 12 2013 yes, I've tried something similar(I used isFinalFunction). When I
- JS (55/64) Jul 12 2013 The issue is with the template being in a different module. Same
- JS (6/6) Jul 12 2013 BTW, the error is
- Jacob Carlborg (12/18) Jul 12 2013 Try this:
- JS (20/40) Jul 12 2013 main is the main module. I've tried your method already but
I have some code that needs to determine if a type isFinalFunction or isAbstractFunction but they don't seem to work: foreach(k, t; TargetMembers) { alias TypeTuple!(t.type)[0] type; if (isFinalFunction!(t)) { ... } } the if statement never gets executed. I've tried using type instead of t and various other things. I suppose the the function is defined as final string foo() { ...} but TargetMembers is "tuple(FuncInfo!("foo", pure nothrow safe string()), FuncInfo!("Value", property int()), FuncInfo!("Value", property int(int value)))" I believe the issue is that isFinalFunction requires an actual function symbol but I'm passing it a string? How can I get this to work?
Jul 11 2013
On Thursday, 11 July 2013 at 22:45:47 UTC, JS wrote:I have some code that needs to determine if a type isFinalFunction or isAbstractFunction but they don't seem to work: foreach(k, t; TargetMembers) { alias TypeTuple!(t.type)[0] type; if (isFinalFunction!(t)) { ... } } the if statement never gets executed. I've tried using type instead of t and various other things. I suppose the the function is defined as final string foo() { ...} but TargetMembers is "tuple(FuncInfo!("foo", pure nothrow safe string()), FuncInfo!("Value", property int()), FuncInfo!("Value", property int(int value)))" I believe the issue is that isFinalFunction requires an actual function symbol but I'm passing it a string? How can I get this to work?much of the code used can be found at http://dpaste.dzfl.pl/209e260b. I can get the attributes of the function no problem and implement the interface except for final functions, which try to get implemented again... hence I need to prevent reimplementation of final functions but seem to have no way to determine if a function is final.
Jul 11 2013
On Thursday, 11 July 2013 at 23:04:20 UTC, JS wrote:On Thursday, 11 July 2013 at 22:45:47 UTC, JS wrote:I've also tried __traits and other stuff. I have access to the interface and I've tried hard coding the name and other stuff... Using them on simple example case works so it is an issue with the code, here is the full code: http://dpaste.dzfl.pl/16bc4a7e just mixin the templates to use use them, e.g., interface A(T) { final string foo() { return ""; } mixin tPropertyBuilder!(0, T); alias Value this; } class B(T) : A!T { property T Value() { return _value; } mixin tPropertyImplementer!(0, T); // implements foo, causes compile time error. should not implement final members. }I have some code that needs to determine if a type isFinalFunction or isAbstractFunction but they don't seem to work: foreach(k, t; TargetMembers) { alias TypeTuple!(t.type)[0] type; if (isFinalFunction!(t)) { ... } } the if statement never gets executed. I've tried using type instead of t and various other things. I suppose the the function is defined as final string foo() { ...} but TargetMembers is "tuple(FuncInfo!("foo", pure nothrow safe string()), FuncInfo!("Value", property int()), FuncInfo!("Value", property int(int value)))" I believe the issue is that isFinalFunction requires an actual function symbol but I'm passing it a string? How can I get this to work?much of the code used can be found at http://dpaste.dzfl.pl/209e260b. I can get the attributes of the function no problem and implement the interface except for final functions, which try to get implemented again... hence I need to prevent reimplementation of final functions but seem to have no way to determine if a function is final.
Jul 11 2013
On 2013-07-12 00:45, JS wrote:I believe the issue is that isFinalFunction requires an actual function symbol but I'm passing it a string? How can I get this to work?Have you tried using a mixin? __traits(isFinalFunction, mixin(className ~ "." ~ member)); -- /Jacob Carlborg
Jul 11 2013
On Friday, 12 July 2013 at 06:38:54 UTC, Jacob Carlborg wrote:On 2013-07-12 00:45, JS wrote:yes, I've tried something similar(I used isFinalFunction). When I try it I get an error about the class not being found... I've tried to add the module name to it but it doesn't work. If I use your code directly on a simple test case it works as expected. Also, if the function is overloaded I do not think I can get it to work correctly?I believe the issue is that isFinalFunction requires an actual function symbol but I'm passing it a string? How can I get this to work?Have you tried using a mixin? __traits(isFinalFunction, mixin(className ~ "." ~ member));
Jul 12 2013
On Friday, 12 July 2013 at 06:38:54 UTC, Jacob Carlborg wrote:On 2013-07-12 00:45, JS wrote:The issue is with the template being in a different module. Same code works fine when in the same module... module main; import std.stdio, std.cstream, std.conv, std.traits, testmodule; template test(alias i) { alias typeof(i) I; static string eval() { enum name = "foo"; //enum qname = moduleName!(I)~"."~I.stringof~"."~name; enum qname = I.stringof~"."~name; pragma(msg, "main: "~qname); return (__traits(isFinalFunction, mixin(qname))).stringof; } enum test = eval(); pragma(msg, "main: isfinal: "~test); } interface A { final void foo() { }; void foo(int x); } int main(string[] argv) { A a; writeln(mixin(test!(a))); writeln(mixin(test2!(a))); din.getc(); return 0; } testmodule.d: module testmodule; import std.traits; template test2(alias i) { alias typeof(i) I; static string eval() { enum name = "foo"; enum qname = moduleName!(I)~"."~I.stringof~"."~name; //enum qname = I.stringof~"."~name; pragma(msg, "testmodule: "~qname); return (__traits(isFinalFunction, mixin(qname))).stringof; } enum test2 = eval(); pragma(msg, "testmodule: isfinal: "~test2); } ------------ note test2 fails even though it is the same code. While this is probably a rather simple fix I would still have the problem of checking if an overloaded function is actually final rather than just the symbol name(which I guess is just the first function).I believe the issue is that isFinalFunction requires an actual function symbol but I'm passing it a string? How can I get this to work?Have you tried using a mixin? __traits(isFinalFunction, mixin(className ~ "." ~ member));
Jul 12 2013
BTW, the error is testmodule.d(14): Error: undefined identifier main which suggests that the template can't find the module. I can import the module and it will work fine but this seems a bit circular. I will try and mixin the module to solve my original problem but still need to figure out how to handle overloads.
Jul 12 2013
On 2013-07-12 09:25, JS wrote:BTW, the error is testmodule.d(14): Error: undefined identifier mainWhere does "main" come from?which suggests that the template can't find the module. I can import the module and it will work fine but this seems a bit circular. I will try and mixin the module to solve my original problem but still need to figure out how to handle overloads.Try this: 1. Iterate over all members 2. Run __traits(getOverloads) for each member 3. Iterate all overloads 3. Run __traits(isFinalFunction) for each overload http://dlang.org/traits.html#getOverloads http://dlang.org/traits.html#allMembers http://dlang.org/traits.html#derivedMembers -- /Jacob Carlborg
Jul 12 2013
On Friday, 12 July 2013 at 11:28:19 UTC, Jacob Carlborg wrote:On 2013-07-12 09:25, JS wrote:main is the main module. I've tried your method already but couldn't get it to work. I think it is ultimately flawed because one still needs to compare against the full definition. I was able to get it to work in any case by modifying std.traits. It has a more advanced GetOverloads template that ignores static functions. I included it to ignore final functions also... this might be a bug in the code as I'm sure if it wants to ignore static it probably should ignore finals. template isMethod(alias f) { static if (is(typeof(&f) F == F*) && is(F == function)) { enum isMethod = !__traits(isStaticFunction, f) && !__traits(isFinalFunction, f); } else enum isMethod = false; }BTW, the error is testmodule.d(14): Error: undefined identifier mainWhere does "main" come from?which suggests that the template can't find the module. I can import the module and it will work fine but this seems a bit circular. I will try and mixin the module to solve my original problem but still need to figure out how to handle overloads.Try this: 1. Iterate over all members 2. Run __traits(getOverloads) for each member 3. Iterate all overloads 3. Run __traits(isFinalFunction) for each overload http://dlang.org/traits.html#getOverloads http://dlang.org/traits.html#allMembers http://dlang.org/traits.html#derivedMembers
Jul 12 2013