Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
July 11, 2013 how to determine if type is final/abstract | ||||
---|---|---|---|---|
| ||||
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? |
July 11, 2013 Re: how to determine if type is final/abstract | ||||
---|---|---|---|---|
| ||||
Posted in reply to JS | 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. |
July 11, 2013 Re: how to determine if type is final/abstract | ||||
---|---|---|---|---|
| ||||
Posted in reply to JS | 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 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. 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. } |
July 12, 2013 Re: how to determine if type is final/abstract | ||||
---|---|---|---|---|
| ||||
Posted in reply to JS | 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 |
July 12, 2013 Re: how to determine if type is final/abstract | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Friday, 12 July 2013 at 06:38:54 UTC, Jacob Carlborg wrote:
> 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));
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?
|
July 12, 2013 Re: how to determine if type is final/abstract | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Friday, 12 July 2013 at 06:38:54 UTC, Jacob Carlborg wrote: > 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)); 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). |
July 12, 2013 Re: how to determine if type is final/abstract | ||||
---|---|---|---|---|
| ||||
Posted in reply to JS | 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. |
July 12, 2013 Re: how to determine if type is final/abstract | ||||
---|---|---|---|---|
| ||||
Posted in reply to JS | On 2013-07-12 09:25, JS wrote: > BTW, the error is > > testmodule.d(14): Error: undefined identifier main Where 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 |
July 12, 2013 Re: how to determine if type is final/abstract | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Friday, 12 July 2013 at 11:28:19 UTC, Jacob Carlborg wrote:
> On 2013-07-12 09:25, JS wrote:
>> BTW, the error is
>>
>> testmodule.d(14): Error: undefined identifier main
>
> Where 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
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;
}
|
Copyright © 1999-2021 by the D Language Foundation