digitalmars.D.learn - .tupleof for static array
- Dennis (16/16) Aug 10 2021 ```D
- jfondren (22/38) Aug 10 2021 I came up with
- Dennis (5/7) Aug 10 2021 Thanks! I was considering turning the static array into an
- Paul Backus (24/40) Aug 10 2021 ```d
- Dennis (3/4) Aug 10 2021 Do you know more use cases for this?
- Paul Backus (19/23) Aug 10 2021 I've written range pipelines like this:
```D struct Vec { float x, y, z; } void setPosition(float x, float y, float z) { } void main() { Vec posS = Vec(10, 20, 30); setPosition(posS.tupleof); // pass float[3] posA = [10, 20, 30]; setPosition(posA.tupleof); // Error: no property `tupleof` for type `float[3]` } ``` Does anyone know a library utility to make expanding a static array like this work?
Aug 10 2021
On Tuesday, 10 August 2021 at 12:01:24 UTC, Dennis wrote:```D struct Vec { float x, y, z; } void setPosition(float x, float y, float z) { } void main() { Vec posS = Vec(10, 20, 30); setPosition(posS.tupleof); // pass float[3] posA = [10, 20, 30]; setPosition(posA.tupleof); // Error: no property `tupleof` for type `float[3]` } ``` Does anyone know a library utility to make expanding a static array like this work?I came up with ```d auto structOf(T, size_t N)(T[N] xs) { string defstruct(size_t n) { import std.conv : to; string m = "struct S { " ~ T.stringof; foreach (i; 1 .. n) { m ~= " _"; m ~= i.to!string; m ~= ","; } m ~= " _n; }"; return m; } mixin(defstruct(N)); return cast(S) xs; } ``` for `structOf(posA).tupleof` And I don't see very many static-array-generic functions in Phobos.
Aug 10 2021
Thanks! I was considering turning the static array into an AliasSeq directly, but casting it to a struct and doing tupleof on that is pretty smart. On Tuesday, 10 August 2021 at 12:50:55 UTC, jfondren wrote:And I don't see very many static-array-generic functions in Phobos.Indeed, static arrays could use some more love in my opinion.
Aug 10 2021
On Tuesday, 10 August 2021 at 12:01:24 UTC, Dennis wrote:```D struct Vec { float x, y, z; } void setPosition(float x, float y, float z) { } void main() { Vec posS = Vec(10, 20, 30); setPosition(posS.tupleof); // pass float[3] posA = [10, 20, 30]; setPosition(posA.tupleof); // Error: no property `tupleof` for type `float[3]` } ``` Does anyone know a library utility to make expanding a static array like this work?```d import std.traits: isStaticArray; template Iota(size_t n) { import std.meta: AliasSeq; static if (n == 0) alias Iota = AliasSeq!(); else alias Iota = AliasSeq!(Iota!(n - 1), n - 1); } template tupleOf(alias array) if (isStaticArray!(typeof(array))) { import std.meta: Map = staticMap; ref element(size_t i)() { return array[i]; } alias tupleOf = Map!(element, Iota!(array.length)); } ``` Full example: https://run.dlang.io/is/COG7m4 Would definitely be nice to have this in the language, though.
Aug 10 2021
Thanks for this solution as well. On Tuesday, 10 August 2021 at 13:10:23 UTC, Paul Backus wrote:Would definitely be nice to have this in the language, though.Do you know more use cases for this?
Aug 10 2021
On Tuesday, 10 August 2021 at 15:32:25 UTC, Dennis wrote:Thanks for this solution as well. On Tuesday, 10 August 2021 at 13:10:23 UTC, Paul Backus wrote:I've written range pipelines like this: ```d someSourceRange .chunks(2) .map!(chunk => chunk.staticArray!2) // allows random access .each!(pair => doSomethingWith(pair[0], pair[1])); ``` Having to write `pair[0]` and `pair[1]` is a bit awkward, though. Normally I would use something like the following to bind each element to a separate parameter: ```d alias apply(alias fun) = args => fun(args.tupleof); /* ... */ .each!(apply!((first, second) => doSomethingWith(first, second))); ``` ...but `.tupleof` doesn't work with static arrays, so that doesn't compile.Would definitely be nice to have this in the language, though.Do you know more use cases for this?
Aug 10 2021