July 17, 2017 Re: Appending static arrays | ||||
---|---|---|---|---|
| ||||
OK, here's an actual, compilable, runnable version:
import std.algorithm : sum;
import std.meta : allSatisfy, staticMap;
import std.range : only;
import std.traits : CommonType, isStaticArray;
alias Elem(A : E[n], E, size_t n) = E;
enum Length(A) = A.length;
enum sumLengths(A...) = sum(only(0, staticMap!(Length, A)));
CommonType!(staticMap!(Elem, A))[sumLengths!A] append(A...)(A arrays)
if (allSatisfy!(isStaticArray, A))
{
typeof(return) result = void;
foreach (i, a; arrays) {
enum offset = sumLengths!(A[0 .. i]);
result[offset .. offset + a.length] = a[];
}
return result;
}
@nogc unittest {
int[2] a = [ 1, 2 ];
int[3] b = [ 3, 4, 5 ];
int[4] c = [ 6, 7, 8, 9 ];
auto d = append(a, b, c);
assert(is(typeof(d) == int[9]));
assert(d == [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]);
}
T
--
Be in denial for long enough, and one day you'll deny yourself of things you wish you hadn't.
|
July 17, 2017 Re: Appending static arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stefan Koch | On Monday, 17 July 2017 at 18:54:31 UTC, Stefan Koch wrote:
> So all you need to do make it so
> auto cat(T[]...)(T args)
> {
> T[] result;
> mixin(() {
> string mix = `result = `;
> foreach(i;args.length)
> {
> mix ~= `args[` ~ itos(i) ~ `] ~`;
> }
> mix[$-1] = ';';
> return mix;
> }());
>
> return result;
> }
>
> that should do it :)
Thanks, but I wan't a @nogc-variant, which was posted below.
|
July 17, 2017 Re: Appending static arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stefan Koch | On Monday, 17 July 2017 at 18:54:31 UTC, Stefan Koch wrote:
> we have special code in the compiler to optimize a ~ b ~ c.
Interesting, can you elaborate on what you mean with "optimize".
In that case, is there a reason why
int x[2];
int y[2];
int z[x.length + y.length] = x ~ y;
isn't @nogc?
|
July 17, 2017 Re: Appending static arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On Mon, Jul 17, 2017 at 08:11:03PM +0000, Nordlöw via Digitalmars-d-learn wrote: [...] > Does this have a place in Phobos? Never know till you try. :-D > If so, > > - under what name: append, concat or cat? I'd vote for concat. > - where: std.algorithm or std.array? std.array, IMO, since it's specific to static arrays. T -- Without outlines, life would be pointless. |
July 17, 2017 Re: Appending static arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On Monday, 17 July 2017 at 19:11:26 UTC, H. S. Teoh wrote:
> Hmm, since we already have sumOfLengths available at compile-time, what about:
>
> T[sumOfLengths!StaticArrays] append(StaticArrays...)(StaticArrays arrays)
> if (allSatisfy!(isStaticArray, StaticArrays))
> {
> typeof(return) result = void;
> foreach (i, a; 0 .. arrays.length)
> {
> enum offset = sumOfLengths!(arrays[0 .. i]);
> result[offset .. offset + a.length] = a[];
> }
> return result;
> }
>
>
> T
Thanks, I'll try this!
Does this have a place in Phobos?
If so,
- under what name: append, concat or cat?
- where: std.algorithm or std.array?
|
July 17, 2017 Re: Appending static arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On Monday, 17 July 2017 at 20:10:31 UTC, H. S. Teoh wrote: > On Mon, Jul 17, 2017 at 08:11:03PM +0000, Nordlöw via Digitalmars-d-learn wrote: [...] >> Does this have a place in Phobos? > > Never know till you try. :-D > > >> If so, >> >> - under what name: append, concat or cat? > > I'd vote for concat. > > >> - where: std.algorithm or std.array? > > std.array, IMO, since it's specific to static arrays. > > > T Made some adjustments with working unittest and put it up on https://github.com/nordlow/phobos-next/blob/master/src/algorithm_ex.d#L2467 I had to special-case foreach body for `i == 0` since `sumOfLengths` couldn't instantiate with empty tuple `()`. Further, should `concat` support `CommonType`? That is, should int[2] x = [1, 2]; const double[2] y = [3, 4]; auto z = concat(x, y); static assert(is(typeof(z) == double[4])); be allowed? |
July 17, 2017 Re: Appending static arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On Mon, Jul 17, 2017 at 08:28:12PM +0000, Nordlöw via Digitalmars-d-learn wrote: [...] > I had to special-case foreach body for `i == 0` since `sumOfLengths` couldn't instantiate with empty tuple `()`. > > Further, should `concat` support `CommonType`? That is, should > > int[2] x = [1, 2]; > const double[2] y = [3, 4]; > auto z = concat(x, y); > static assert(is(typeof(z) == double[4])); > > be allowed? See the working implementation in my latest post on this thread. That version supports CommonType, and works correctly with empty tuples as well. T -- Trying to define yourself is like trying to bite your own teeth. -- Alan Watts |
July 17, 2017 Re: Appending static arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On Monday, 17 July 2017 at 20:53:36 UTC, H. S. Teoh wrote:
> See the working implementation in my latest post on this thread. That version supports CommonType, and works correctly with empty tuples as well.
>
>
> T
Thanks.
|
July 17, 2017 Re: Appending static arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On Monday, 17 July 2017 at 20:01:41 UTC, H. S. Teoh wrote:
> OK, here's an actual, compilable, runnable version:
>
> import std.algorithm : sum;
> import std.meta : allSatisfy, staticMap;
> import std.range : only;
> import std.traits : CommonType, isStaticArray;
>
> alias Elem(A : E[n], E, size_t n) = E;
> enum Length(A) = A.length;
> enum sumLengths(A...) = sum(only(0, staticMap!(Length, A)));
>
> CommonType!(staticMap!(Elem, A))[sumLengths!A] append(A...)(A arrays)
> if (allSatisfy!(isStaticArray, A))
> {
> typeof(return) result = void;
> foreach (i, a; arrays) {
> enum offset = sumLengths!(A[0 .. i]);
> result[offset .. offset + a.length] = a[];
This slice assignment doesn't support conversion between different element-types, for instance from `int[]` to `double[]`.
But I'm not convinced that we should allow `CommonType` when operator ~ doesn't.
|
July 17, 2017 Re: Appending static arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On Mon, Jul 17, 2017 at 10:32:14PM +0000, Nordlöw via Digitalmars-d-learn wrote: > On Monday, 17 July 2017 at 20:01:41 UTC, H. S. Teoh wrote: [...] > > result[offset .. offset + a.length] = a[]; > > This slice assignment doesn't support conversion between different element-types, for instance from `int[]` to `double[]`. > > But I'm not convinced that we should allow `CommonType` when operator ~ doesn't. True. Maybe we should just leave out the `CommonType` thing for now. Not sure how to express that all element types should be equal in the sig constraints, though. (It shouldn't be overly hard to support `CommonType`; just replace the slice assignment with a manual loop. But yeah, probably not worth the effort.) T -- Do not reason with the unreasonable; you lose by definition. |
Copyright © 1999-2021 by the D Language Foundation