digitalmars.D.learn - CT filtering of class members
- Sjoerd Nijboer (45/45) Aug 11 2019 The following snippet doesn't compile
- Simen =?UTF-8?B?S2rDpnLDpXM=?= (25/37) Aug 11 2019 This is classic D mix of compile-time and compile-time (no typo).
- Sjoerd Nijboer (2/20) Aug 11 2019 Works beautiful, thank you very much!
The following snippet doesn't compile I am trying to reflect on a class and only do an operation with all member functions of a class. But I can't seem to use a filter to only get the member functions out of a type T. I understand that there are two errors in my snippet. 1) It cannot mixin a `name` because it is a variable from the lambda that `filter()` is using. 2) members.filter!(name => !ctorAndDtor.canFind(name)) does not filter on symbols defined in ctorAndDtor How can I fix these problems and return all member functions whitout ctor and dtor of a type T? Code snippet: void main() { GetFunctionMembers!Foo(); } void GetFunctionMembers(T)() { enum members = [__traits(derivedMembers, T)]; pragma(msg, "Functions: " ~ members.stringof); enum ctorAndDtor = ["this", "__ctor", "__dtor"]; enum memberFunctions = members.filter!(name => !ctorAndDtor.canFind(name) && mixin("isFunction!(T." ~ name ~ ")"))(); pragma(msg, memberFunctions); } class Foo { bool myBool; int k; this() { } ~this() { } void bar(int k) { this.k = k; } void qux() { } }
Aug 11 2019
On Sunday, 11 August 2019 at 15:27:54 UTC, Sjoerd Nijboer wrote:The following snippet doesn't compile I am trying to reflect on a class and only do an operation with all member functions of a class. But I can't seem to use a filter to only get the member functions out of a type T. I understand that there are two errors in my snippet. 1) It cannot mixin a `name` because it is a variable from the lambda that `filter()` is using. 2) members.filter!(name => !ctorAndDtor.canFind(name)) does not filter on symbols defined in ctorAndDtor How can I fix these problems and return all member functions whitout ctor and dtor of a type T?This is classic D mix of compile-time and compile-time (no typo). I suggest reading H.S. Teoh's text on the topic: https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time Now, as for what can actually be done: you should probably use std.meta.Filter (https://dlang.org/library/std/meta/filter.html) to filter the members list. This will require you to define a template to operate on each element. Something like this: import std.meta : Filter; import std.traits : isFunction; import std.algorithm.searching : canFind; enum isNonspecialMemberFunction(string name) = !ctorAndDtor.canFind(name) && isFunction!(__traits(getMember, T, name)); enum memberFunctions = Filter!(isNonspecialMemberFunction, __traits(derivedMembers, T)); Filter operates on AliasSeqs, not arrays. That's why I restated the __traits(derivedMembers, T) part, but this could just as easily be done by changing this line: enum members = [__traits(derivedMembers, T)]; to: alias members = __traits(derivedMembers, T); -- Simen
Aug 11 2019
On Sunday, 11 August 2019 at 16:32:20 UTC, Simen Kjærås wrote:[...] Something like this: import std.meta : Filter; import std.traits : isFunction; import std.algorithm.searching : canFind; enum isNonspecialMemberFunction(string name) = !ctorAndDtor.canFind(name) && isFunction!(__traits(getMember, T, name)); enum memberFunctions = Filter!(isNonspecialMemberFunction, __traits(derivedMembers, T)); Filter operates on AliasSeqs, not arrays. That's why I restated the __traits(derivedMembers, T) part, but this could just as easily be done by changing this line: enum members = [__traits(derivedMembers, T)]; to: alias members = __traits(derivedMembers, T); -- SimenWorks beautiful, thank you very much!
Aug 11 2019