Jump to page: 1 2 3
Thread overview
Appending static arrays
5 days ago
Nordlöw
5 days ago
ag0aep6g
5 days ago
Nordlöw
5 days ago
ag0aep6g
5 days ago
Nordlöw
5 days ago
Stefan Koch
5 days ago
Nordlöw
5 days ago
Nordlöw
5 days ago
Nordlöw
5 days ago
H. S. Teoh
5 days ago
H. S. Teoh
5 days ago
H. S. Teoh
5 days ago
Nordlöw
5 days ago
H. S. Teoh
5 days ago
Nordlöw
5 days ago
H. S. Teoh
5 days ago
Nordlöw
5 days ago
Nordlöw
4 days ago
Jacob Carlborg
4 days ago
Nordlöw
5 days ago
H. S. Teoh
5 days ago
Nordlöw
5 days ago
H. S. Teoh
4 days ago
Jack Applegame
4 days ago
Stefan Koch
4 days ago
Jack Applegame
5 days ago
I'm want to define a specialization of `append()` that takes only static arrays as inputs and returns a static array being the sum of the lengths of the inputs.

Have anybody already implemented this?

If not, I'm specifically interested in how to most conveniently infer the length (as an enum) of the returned static array from the `.length`s of inputs (which of course must be enum-values too).
5 days ago
On 07/17/2017 07:38 PM, Nordlöw wrote:
> I'm want to define a specialization of `append()` that takes only static arrays as inputs and returns a static array being the sum of the lengths of the inputs.
> 
> Have anybody already implemented this?
> 
> If not, I'm specifically interested in how to most conveniently infer the length (as an enum) of the returned static array from the `.length`s of inputs (which of course must be enum-values too).

Like so?

int[n + m] append(size_t n, size_t m)(int[n] a, int[m] b)
{
    int[n + m] result = a ~ b;
    return result;
}
5 days ago
On Monday, 17 July 2017 at 17:46:42 UTC, ag0aep6g wrote:
> Like so?
>
> int[n + m] append(size_t n, size_t m)(int[n] a, int[m] b)
> {
>     int[n + m] result = a ~ b;
>     return result;
> }

Thanks, but I'm talking about the variadic case where the number of input arguments are unknown (>= 2) where the function header looks something like

import std.traits : allSatisfy, isStaticArray;

auto append(R, Args...)(auto ref Args args)
    if (args.length >= 2 &&
        allSatisfy!(isStaticArray, Args))
    // TODO all ElementTypes have CommonType
{
    // ...
}

5 days ago
On Monday, 17 July 2017 at 17:46:42 UTC, ag0aep6g wrote:
>     int[n + m] result = a ~ b;

Further, the expression `a ~ b` here will allocate and create a copy on the GC-heap before writing `result`.

Maybe LDC optimizes away this now or in the future but DMD cannot.

Yeah I know, kind of dumb but that's how it is currently.
5 days ago
On Monday, 17 July 2017 at 17:38:23 UTC, Nordlöw wrote:
> I'm want to define a specialization of `append()` that takes only static arrays as inputs and returns a static array being the sum of the lengths of the inputs.
>
> Have anybody already implemented this?
>
> If not, I'm specifically interested in how to most conveniently infer the length (as an enum) of the returned static array from the `.length`s of inputs (which of course must be enum-values too).

I just realized that I can use `std.meta.staticMap` to get the lengths but I still need to reduce them and there is no variant of `reduce` in `std.meta`. Why? Hasn't it been written yet?

I know I can always write yet another recursive CT-function, say `SumOfLengths`, but I thought I'd try to reuse `std.meta` this time. :)
5 days ago
On Monday, 17 July 2017 at 18:38:16 UTC, Nordlöw wrote:
> On Monday, 17 July 2017 at 17:46:42 UTC, ag0aep6g wrote:
>>     int[n + m] result = a ~ b;
>
> Further, the expression `a ~ b` here will allocate and create a copy on the GC-heap before writing `result`.
>
> Maybe LDC optimizes away this now or in the future but DMD cannot.
>
> Yeah I know, kind of dumb but that's how it is currently.

we have special code in the compiler to optimize a ~ b ~ c.
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 :)
5 days ago
On Mon, Jul 17, 2017 at 05:38:23PM +0000, Nordlöw via Digitalmars-d-learn wrote:
> I'm want to define a specialization of `append()` that takes only static arrays as inputs and returns a static array being the sum of the lengths of the inputs.
> 
> Have anybody already implemented this?
> 
> If not, I'm specifically interested in how to most conveniently infer
> the length (as an enum) of the returned static array from the
> `.length`s of inputs (which of course must be enum-values too).

Hmm. What about:

	template sumOfLengths(A...)
		if (A.length > 0)
	{
		static if (A.length == 1)
			enum sumOfLengths = A[0].length;
		else
			enum sumOfLengths = A[0].length + sumOfLengths!(A[1 .. $]);
	}

	T[sumOfLengths!StaticArrays] append(StaticArrays...)(StaticArrays arrays)
		if (/* insert static array constraints here */)
	{
		typeof(return) result = void;
		size_t offset = 0;
		foreach (a; arrays)
		{
			result[offset .. offset + a.length] = a[];
		}
		return result;
	}


T

-- 
IBM = I'll Buy Microsoft!
5 days ago
On Mon, Jul 17, 2017 at 12:01:48PM -0700, H. S. Teoh via Digitalmars-d-learn wrote: [...]
> 	T[sumOfLengths!StaticArrays] append(StaticArrays...)(StaticArrays arrays)
> 		if (/* insert static array constraints here */)
> 	{
> 		typeof(return) result = void;
> 		size_t offset = 0;
> 		foreach (a; arrays)
> 		{
> 			result[offset .. offset + a.length] = a[];

Argh, forgot this important line:

			offset += a.length;


> 		}
> 		return result;
> 	}
[...]


T

-- 
Marketing: the art of convincing people to pay for what they didn't need before which you fail to deliver after.
5 days ago
On 07/17/2017 08:35 PM, Nordlöw wrote:
> Thanks, but I'm talking about the variadic case where the number of input arguments are unknown (>= 2) where the function header looks something like
> 
> import std.traits : allSatisfy, isStaticArray;
> 
> auto append(R, Args...)(auto ref Args args)
>      if (args.length >= 2 &&
>          allSatisfy!(isStaticArray, Args))
>      // TODO all ElementTypes have CommonType
> {
>      // ...
> }
> 

I see. Here's what I could come up with:

----
import std.traits : allSatisfy, isStaticArray;

auto append(Args...)(auto ref Args args)
    if (args.length >= 2 &&
        allSatisfy!(isStaticArray, Args))
{
    import std.algorithm : sum;
    import std.meta : staticMap;
    import std.range: ElementType;
    import std.traits : CommonType;

    enum staticArrayLength(A : E[n], E, size_t n) = n;

    alias E = ElementType!(Args[0]);
    static assert(is(CommonType!(staticMap!(ElementType, Args)) : E));
    enum lengths = staticMap!(staticArrayLength, Args);

    E[sum([lengths])] result;
    foreach (i, length; lengths)
    {
        enum offset = sum!(size_t[])([lengths[0 .. i]]);
        result[offset .. offset + length] = args[i];
    }
    return result;
}

@nogc unittest
{
    int[3] a = [1, 2, 3];
    const int[4] b = [4, 5, 6, 7];
    immutable int[5] c = [8, 9, 10, 11, 12];

    auto r = append(a, b, c);
    assert(r == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
    static assert(is(typeof(r) == int[12]));
}
----
5 days ago
On Mon, Jul 17, 2017 at 12:01:48PM -0700, H. S. Teoh via Digitalmars-d-learn wrote: [...]
> 	template sumOfLengths(A...)
> 		if (A.length > 0)
> 	{
> 		static if (A.length == 1)
> 			enum sumOfLengths = A[0].length;
> 		else
> 			enum sumOfLengths = A[0].length + sumOfLengths!(A[1 .. $]);
> 	}
> 
> 	T[sumOfLengths!StaticArrays] append(StaticArrays...)(StaticArrays arrays)
> 		if (/* insert static array constraints here */)
> 	{
> 		typeof(return) result = void;
> 		size_t offset = 0;
> 		foreach (a; arrays)
> 		{
> 			result[offset .. offset + a.length] = a[];
> 		}
> 		return result;
> 	}
[...]

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

-- 
People say I'm indecisive, but I'm not sure about that. -- YHL, CONLANG
« First   ‹ Prev
1 2 3