digitalmars.D.learn - Manually calling postblots recursively
- Johannes Loher (56/56) Jun 18 2017 Hey, I'm trying to work on
- Basile B. (4/10) Jun 18 2017 "@disable" postblits are detected as valid postblits.
- Johannes Loher (73/84) Jun 22 2017 Here is my new version. Additionally to taking care of @disable
Hey, I'm trying to work on https://issues.dlang.org/show_bug.cgi?id=15708 so I decided it might be interesting to find a way to (recursively) call all postblits that belong to certain struct or static array. This is what I came up with so far: import std.traits; void callPostblits(S)(ref S s) { static if (isStaticArray!S && S.length) { foreach (ref elem; s) callPostblits(elem); } else static if (is(S == struct)) { foreach (field; FieldNameTuple!S) { callPostblits(__traits(getMember, s, field)); } static if (hasMember!(S, "__postblit")) { s.__postblit(); } } } safe unittest { struct AnotherTestStruct { int b = 0; this(this) { b = 1; } } struct TestStruct { int a = 0; this(this) { a = 1; } AnotherTestStruct anotherTestStruct; } TestStruct[2] testStructs; assert(testStructs[0].a == 0 && testStructs[0].anotherTestStruct.b == 0); assert(testStructs[1].a == 0 && testStructs[1].anotherTestStruct.b == 0); callPostblits(testStructs); assert(testStructs[0].a == 1 && testStructs[0].anotherTestStruct.b == 1); assert(testStructs[1].a == 1 && testStructs[1].anotherTestStruct.b == 1); } Any suggestions for improvement or cases where this fails?
Jun 18 2017
On Sunday, 18 June 2017 at 09:41:01 UTC, Johannes Loher wrote:Hey, I'm trying to work on https://issues.dlang.org/show_bug.cgi?id=15708 so I decided it might be interesting to find a way to (recursively) call all postblits that belong to certain struct or static array. This is what I came up with so far: [...]" disable" postblits are detected as valid postblits. I think that you have to AndAnd the detection with std.traits.isCopyable
Jun 18 2017
On Sunday, 18 June 2017 at 14:16:03 UTC, Basile B. wrote:On Sunday, 18 June 2017 at 09:41:01 UTC, Johannes Loher wrote:Here is my new version. Additionally to taking care of disable this(this); I added compile time checks if the underlying fields have an "elaborate copy constructor" so that I only call callPostblits on them if needed. Is this reasonable? It increases compiletime, but could possibly decrease runtime a little. On the other hand, the empty function calls should probably just get optimized away...? While doing all that I realized that hasElaborateCopyConstructor is true for structs with disable this(this). Is that intended? It looks a bit weird to me... import std.traits; void callPostblits(S)(ref S s) { static if (isStaticArray!S && S.length && hasElaborateCopyConstructor!(ElementType!S)) { foreach (ref elem; s) callPostblits(elem); } else static if (is(S == struct)) { foreach (field; FieldNameTuple!S) { static if (hasElaborateCopyConstructor!(typeof(__traits(getMember, s, field)))) { callPostblits(__traits(getMember, s, field)); } } static if (hasMember!(S, "__postblit") && isCopyable!S) { s.__postblit(); } } } unittest { struct AnotherTestStruct { int b = 0; this(this) { b = 1; } } struct TestStruct { int a = 0; this(this) { a = 1; } AnotherTestStruct anotherTestStruct; } TestStruct[2] testStructs; assert(testStructs[0].a == 0 && testStructs[0].anotherTestStruct.b == 0); assert(testStructs[1].a == 0 && testStructs[1].anotherTestStruct.b == 0); callPostblits(testStructs); assert(testStructs[0].a == 1 && testStructs[0].anotherTestStruct.b == 1); assert(testStructs[1].a == 1 && testStructs[1].anotherTestStruct.b == 1); struct YetAnotherTestStruct { disable this(this); } YetAnotherTestStruct yetAnotherTestStruct; callPostblits(yetAnotherTestStruct); // This will also compile }Hey, I'm trying to work on https://issues.dlang.org/show_bug.cgi?id=15708 so I decided it might be interesting to find a way to (recursively) call all postblits that belong to certain struct or static array. This is what I came up with so far: [...]" disable" postblits are detected as valid postblits. I think that you have to AndAnd the detection with std.traits.isCopyable
Jun 22 2017