Currently (DMD 2.054) this is not allowed, but a vector op like this is sometimes useful to me: struct Foo { int x, y; int[100] array; } void main() { auto foos = new Foo[100]; foos[].y += 10; // ******** } For the programmer I think the meaning of such code is easy enough to understand and use. At the moment I don't see the need to define a operator overload for this too (I mean something like opSliceUnary). Don notes: > An interesting use case: > void main() > { > cdouble[100] foos; > foos[].re = 5.0; > } Wilfried Kirschenmann suggests: > void main() { > auto foos = new Foo[100]; > auto ints = new int[100] > ints = foos[].y; > } > > This would simplify the wrinting of numerous application, especially > in the writing of image/video processing (eg. rgb2yuv conversions) > This would also simplify the writing of template library transforming > "array of struct" to "struct of arrays" in a transparent manner for > the library user. Andrej Mitrovic notes (I don't understand this): > float[] buffers = malloc..; > float*[] CBuffers = buffers[].ptr;
What if I define ref int y(Foo[] f) { return f[0].x; } ?
Another possible purpose. Given this matrix: auto M = new double[][](10, 20); This: M[][1] = 1.0; Means: foreach (row; p) row[1] = 1.0; This replaces some usages of std.range.transversal().
All these operations require the use of strided slices, which would be a huge amount of work to implement. Also, there are a plethora of corner cases.
(In reply to comment #3) > All these operations require the use of strided slices, which would be a huge > amount of work to implement. Also, there are a plethora of corner cases. I see. Those corner cases are bad. If you think this is too much work for the gain I'll close this enhancement request, to leave similar functionalities to matrix libraries.
List comprehensions would cover these and avoid any ambiguity. They are also more expressive and composable than vector ops: > auto foos = new Foo[100]; > foos[].y += 10; // ******** [e.y += 10 for e in foos]; Note this doesn't need to allocate an array as the result is not used. > cdouble[100] foos; > foos[].re = 5.0; [e.re = 5.0 for e in foos]; > auto foos = new Foo[100]; > auto ints = new int[100] > ints = foos[].y; ints = [e.y for e in foos]; > float[] buffers = malloc...; > float*[] CBuffers = buffers[].ptr; float*[] cBuffers = [e.ptr for e in buffers]; Also, type inference could be used `auto cBuffers = ` because the RHS is no longer ambiguous with `float*`. (This would also solve Issue #2548). > auto M = new double[][](10, 20); > M[][1] = 1.0; [e[1] = 1.0 for e in m]; And indexes mean they can cover vector ops too: > a[] = b[] / c[]; a = [b[i] / e for i, e in c]; A benefit is that `b.length` can be larger than `c.length`. Also we can use the index variable e.g. to index b in reverse order. The key benefit however is that we can use expressions not supported by vector ops such as function calls, comparisons and the conditional operator - see issue #5636.
A less drastic change would be this syntax, which also solves the ambiguities: float*[] CBuffers = buffers[#].ptr; m[#][1] = 1.0; c[#] = a[#] < b[#]; // issue #5636 Note: issue #5636 was fixed by simply documenting that comparisons, equality, etc make the operation not a vector op, just an array comparison.
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/18355 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB