Flatten a range of static arrays
Steven Schveighoffer
schveiguy at gmail.com
Fri Feb 7 20:31:47 UTC 2020
On 2/7/20 3:13 PM, Dennis wrote:
> If I have an input range with element type `int[3]`, how do I easily
> turn it into a range of `int` so I can map it?
> If it were an int[3][] I could simply cast it to an int[] before
> mapping, but I don't want to eagerly turn it into an array.
> I thought of doing this:
> ```
> range.map!(x => x[]).joiner.map!(x => x*2);
> ```
>
> But it gives:
> Error: returning x[] escapes a reference to parameter x, perhaps
> annotate with return
This is correct. Consider that you did not mark x as ref. So what x
actually is is a function local. If you returned x[], you just returned
a reference to a local, which is about to go out of scope.
> I tried doing:
> ```
> map!((return x) => x[]) // same error
> map!((return ref x) => x[]) // does not match, map.front is not an lvalue
> ```
>
> I can easily work around it with some more code, but I wonder if someone
> knows an easy solution.
This means your actual input range is not an array (map should forward
the lvalueness of it). This means you can't just slice, as you will
again return references to the local stack frame.
The only solution I can provide is to wrap the static array into a range
(maybe something like this exists in Phobos?):
struct SARange(T, size_t N)
{
T[N] storage;
size_t elem;
auto front() { return storage[elem]; }
void popFront() { ++elem; }
bool empty() { return elem >= N; }
}
auto asRange(T : E[N], E, size_t N)(T val) {
return SARange!(E, N)(val);
}
range.map!(x => x.asRange).joiner.map!(x => x*2);
-Steve
More information about the Digitalmars-d-learn
mailing list