digitalmars.D.learn - Iterate over symbols in tupleof without instance
- Benjamin Thaut (27/27) Apr 15 2014 I would like to iterate over T.tupleof at compiletime without having a
- Rikki Cattermole (22/49) Apr 15 2014 Kinda like this?
- Dicebot (22/32) Apr 15 2014 Is this acceptable?
- Dicebot (3/3) Apr 15 2014 T.init _is_ effectively an instance of given type here but it is
- Artur Skawina (9/28) Apr 15 2014 void iterate(T)()
- Dicebot (2/10) Apr 15 2014 So ashamed :D
- Artur Skawina (4/14) Apr 15 2014 I would have not thought of that either, if Jacob didn't mention it... :...
- Dicebot (13/29) Apr 15 2014 What I mean is that my initial statement is blatantly wrong - of
- Benjamin Thaut (13/41) Apr 15 2014 I want to iterate over the symbols, not over the types that the symbols
- Dicebot (12/26) Apr 15 2014 So, what is wrong with this?
- Benjamin Thaut (5/15) Apr 15 2014 Nothing, thanks for the solution. It didn't come to my mind, to use the
- monarch_dodra (19/21) Apr 15 2014 *What* exactly are you trying to do? You could iterate over the
I would like to iterate over T.tupleof at compiletime without having a instance of the given type. So fare the only way I found that works is the following void iterateImpl(T, size_t i)() { static if(i < T.tupleof.length) { // do something with T.tupleof[i] iterateImpl!(T, i+1)(); } } void iterate(T)() { iterateImpl!(T, 0)(); } But this is quite ugly, as there will tons of stack frames on the stack during runtime. I really wanted something like: void iterate(T)() { foreach(size_t i, m; T.tupleof) // error message: "Need this to access <member name here>" { // do something with m } } Kind Regards Benjamin Thaut
Apr 15 2014
On Tuesday, 15 April 2014 at 08:18:31 UTC, Benjamin Thaut wrote:I would like to iterate over T.tupleof at compiletime without having a instance of the given type. So fare the only way I found that works is the following void iterateImpl(T, size_t i)() { static if(i < T.tupleof.length) { // do something with T.tupleof[i] iterateImpl!(T, i+1)(); } } void iterate(T)() { iterateImpl!(T, 0)(); } But this is quite ugly, as there will tons of stack frames on the stack during runtime. I really wanted something like: void iterate(T)() { foreach(size_t i, m; T.tupleof) // error message: "Need this to access <member name here>" { // do something with m } } Kind Regards Benjamin ThautKinda like this? import std.stdio; void test(T...)(T args) { if (!__ctfe) writeln(args); foreach(arg; T) { pragma(msg, arg); } } void main() { test("a", "b", "c", 7, 2, 9); } Compilation output: string string string int int int Application output: abc729
Apr 15 2014
On Tuesday, 15 April 2014 at 08:18:31 UTC, Benjamin Thaut wrote:void iterate(T)() { foreach(size_t i, m; T.tupleof) // error message: "Need this to access <member name here>" { // do something with m } } Kind Regards Benjamin ThautIs this acceptable? void iterate(T)() { foreach (index, member; T.init.tupleof) { pragma(msg, __traits(identifier, T.tupleof[index])); } } struct A { int a, b, c; } void main() { iterate!A(); } Reason why you can't naively iterate over T.tupleof is that current tuple foreach tries to look like normal foreach and thus iteration parameters can't be types. If http://wiki.dlang.org/DIP57 is ever to be implemented, this will be fixed.
Apr 15 2014
T.init _is_ effectively an instance of given type here but it is present in application anyway so it shouldn't create any _extra_ instance.
Apr 15 2014
On 04/15/14 12:45, Dicebot wrote:void iterate(T)() { foreach (index, member; T.init.tupleof) { pragma(msg, __traits(identifier, T.tupleof[index])); } } struct A { int a, b, c; } void main() { iterate!A(); } Reason why you can't naively iterate over T.tupleof is that current tuple foreach tries to look like normal foreach and thus iteration parameters can't be types.void iterate(T)() { foreach (index, member; typeof(T.tupleof)) { pragma(msg, __traits(identifier, T.tupleof[index])); } } artur
Apr 15 2014
On Tuesday, 15 April 2014 at 11:25:14 UTC, Artur Skawina wrote:void iterate(T)() { foreach (index, member; typeof(T.tupleof)) { pragma(msg, __traits(identifier, T.tupleof[index])); } } arturSo ashamed :D
Apr 15 2014
On 04/15/14 13:33, Dicebot wrote:On Tuesday, 15 April 2014 at 11:25:14 UTC, Artur Skawina wrote:I would have not thought of that either, if Jacob didn't mention it... :) http://forum.dlang.org/post/jl9gil$i9l$1 digitalmars.com arturvoid iterate(T)() { foreach (index, member; typeof(T.tupleof)) { pragma(msg, __traits(identifier, T.tupleof[index])); } }So ashamed :D
Apr 15 2014
On Tuesday, 15 April 2014 at 12:11:52 UTC, Artur Skawina wrote:On 04/15/14 13:33, Dicebot wrote:What I mean is that my initial statement is blatantly wrong - of course D does support iteration over arbitrary entities, because it does support iteration over TypeTuple!(...). Must have been some sort of brainfart. This trick does make some sense if you think about it. T.tupleof is a list of aggregate field symbols which are normally resolved as values. But you need a context pointer to work with aggregate fields so naive value iteration is not possible. This behavior is necessary to support idioms like this: int a, b; TypeTuple!(a, b)[] = TypeTuple!(42, 42)[]; Error message could have been better though.On Tuesday, 15 April 2014 at 11:25:14 UTC, Artur Skawina wrote:I would have not thought of that either, if Jacob didn't mention it... :) http://forum.dlang.org/post/jl9gil$i9l$1 digitalmars.com arturvoid iterate(T)() { foreach (index, member; typeof(T.tupleof)) { pragma(msg, __traits(identifier, T.tupleof[index])); } }So ashamed :D
Apr 15 2014
Am 15.04.2014 13:25, schrieb Artur Skawina:On 04/15/14 12:45, Dicebot wrote:I want to iterate over the symbols, not over the types that the symbols have. I need to iterate over the symbols, because UDAs are attached to the symbols. Because of that none of the here listed solutions work for me. Here is a small example of what I'm trying to do: http://dpaste.dzfl.pl/4645d6537447 And no, I can not use __traits(allMembers, T) and __traits(getMember, T, m) because some time ago __traits(getMember, ...) was changed so it can no longer access protected members. (obviously it will work if the type that should be iterated over is within the same module, but thats not the case in practice.) Kind Regards Benjamin Thautvoid iterate(T)() { foreach (index, member; T.init.tupleof) { pragma(msg, __traits(identifier, T.tupleof[index])); } } struct A { int a, b, c; } void main() { iterate!A(); } Reason why you can't naively iterate over T.tupleof is that current tuple foreach tries to look like normal foreach and thus iteration parameters can't be types.void iterate(T)() { foreach (index, member; typeof(T.tupleof)) { pragma(msg, __traits(identifier, T.tupleof[index])); } } artur
Apr 15 2014
On Tuesday, 15 April 2014 at 12:30:44 UTC, Benjamin Thaut wrote:I want to iterate over the symbols, not over the types that the symbols have. I need to iterate over the symbols, because UDAs are attached to the symbols. Because of that none of the here listed solutions work for me. Here is a small example of what I'm trying to do: http://dpaste.dzfl.pl/4645d6537447 And no, I can not use __traits(allMembers, T) and __traits(getMember, T, m) because some time ago __traits(getMember, ...) was changed so it can no longer access protected members. (obviously it will work if the type that should be iterated over is within the same module, but thats not the case in practice.) Kind Regards Benjamin ThautSo, what is wrong with this? void main(string[] args) { Bla bla; foreach(index, a; typeof(Bla.tupleof)) { pragma(msg, hasAttribute!(Bla.tupleof[index], Property).stringof); } } http://dpaste.dzfl.pl/b38035362b29
Apr 15 2014
Am 15.04.2014 14:33, schrieb Dicebot:So, what is wrong with this? void main(string[] args) { Bla bla; foreach(index, a; typeof(Bla.tupleof)) { pragma(msg, hasAttribute!(Bla.tupleof[index], Property).stringof); } } http://dpaste.dzfl.pl/b38035362b29Nothing, thanks for the solution. It didn't come to my mind, to use the index from iterating over the type tuple to index the symbol tuple. Kind Regards Benjamin Thaut
Apr 15 2014
On Tuesday, 15 April 2014 at 08:18:31 UTC, Benjamin Thaut wrote:I would like to iterate over T.tupleof at compiletime without having a instance of the given type.*What* exactly are you trying to do? You could iterate over the tupleof *types* instead if you want? Would that work for you? foreach(i, SubT; FieldTypeTuple!T) { ... } You get your static loop, your indexes, and types. And if you need to operate on the subtypes, you can always use `SubT a = SubT.init;` Also, as a general rule, it is "recommended" to not use tupleof directly, but rather: T myData; foreach(i, SubT; FieldTypeTuple!T) { alias subData = myData.tupleof[i]; } This is because FieldTypeTuple will strip the "context pointer field", which you generally don't care about.
Apr 15 2014