https://issues.dlang.org/show_bug.cgi?id=12732
Issue ID: 12732 Summary: Add an Appender-like template that recursively builds a structure of Appender fields Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: enhancement Priority: P1 Component: Phobos Assignee: nob...@puremagic.com Reporter: andrej.mitrov...@gmail.com This seems to be a common occurrence in my code: ----- import std.array; alias vec3 = int[3]; /// struct Model { vec3[] indices; vec3[] vertices; vec3[] normals; } Model loadModel(string path) { // note the code duplication here, needs to be tracked // separately to the Model struct. Appender!(vec3[]) indices; Appender!(vec3[]) vertices; Appender!(vec3[]) normals; // ... // indices ~= // vertices ~= return Model(indices.data, vertices.data, normals.data); } void main() { } ----- To avoid this code duplication it would be great to have a helper template that can return an equivalent structure which contains Appender fields for all internal arrays, and a convenience .data property function that returns the original type. Here's one implementation: ----- import std.array; import std.typetuple; alias vec3 = int[3]; alias ApplyAppender(T : E[], E) = Appender!T; alias ApplyAppender(T) = T; struct AppenderWrapper(T) { alias Fields = staticMap!(ApplyAppender, typeof(T.tupleof)); Fields fields; alias fields this; @property T data() { T res; foreach (idx, field; fields) { static if (is(typeof(res.tupleof[idx]) : E[], E)) res.tupleof[idx] = field.data; else res.tupleof[idx] = field; } return res; } } /// struct Model { vec3[] indices; vec3[] vertices; vec3[] normals; } Model loadModel(string path) { AppenderWrapper!(typeof(return)) result; // ... // result.indices ~= // result.vertices ~= return result.data; } void main() { } ----- --