www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - .tupleof for static array

reply Dennis <dkorpel gmail.com> writes:
```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
next sibling parent reply jfondren <julian.fondren gmail.com> writes:
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
parent Dennis <dkorpel gmail.com> writes:
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
prev sibling parent reply Paul Backus <snarwin gmail.com> writes:
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
parent reply Dennis <dkorpel gmail.com> writes:
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
parent Paul Backus <snarwin gmail.com> writes:
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:
 Would definitely be nice to have this in the language, though.
Do you know more use cases for this?
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.
Aug 10 2021