Jump to page: 1 2 3
Thread overview
inferred size for static array initialization
May 02, 2016
Erik Smith
May 02, 2016
Basile B
May 02, 2016
Basile B
May 02, 2016
Marco Leise
May 02, 2016
ag0aep6g
May 02, 2016
Marco Leise
May 02, 2016
Erik Smith
May 02, 2016
Namespace
May 02, 2016
Namespace
May 02, 2016
Namespace
May 02, 2016
Namespace
May 02, 2016
Namespace
May 02, 2016
Namespace
May 03, 2016
Basile B.
Oct 18, 2016
Nordlöw
Oct 18, 2016
Namespace
May 02, 2016
Is there a way to initialize a static array and have it's size inferred (and that works for arrays of structs using braced literals)?  This would make it easier to maintain longer static array definitions.  The code below doesn't work when removing the array size even though the array is declared as static immutable.

    import std.traits;
    static immutable int[] a  = [1,2,3];
    static assert(isStaticArray!(typeof(a)));  // fails

May 02, 2016
On Monday, 2 May 2016 at 13:00:27 UTC, Erik Smith wrote:
> Is there a way to initialize a static array and have it's size inferred (and that works for arrays of structs using braced literals)?  This would make it easier to maintain longer static array definitions.  The code below doesn't work when removing the array size even though the array is declared as static immutable.
>
>     import std.traits;
>     static immutable int[] a  = [1,2,3];
>     static assert(isStaticArray!(typeof(a)));  // fails

Help yourself with a template:

----
import std.traits;

auto toStaticArray(alias array)()
if (isArray!(typeof(array)))
{
    enum size = array.length;
    alias T = typeof(array.init[0])[size];
    T result = array[0..size];
    return result;
}

enum a = toStaticArray!([1,2,3]);
static assert(isStaticArray!(typeof(a)));  // success
----

Does it fit ?
May 02, 2016
On Monday, 2 May 2016 at 13:22:01 UTC, Basile B wrote:
> On Monday, 2 May 2016 at 13:00:27 UTC, Erik Smith wrote:
>> Is there a way to initialize a static array and have it's size inferred (and that works for arrays of structs using braced literals)?  This would make it easier to maintain longer static array definitions.  The code below doesn't work when removing the array size even though the array is declared as static immutable.
>>
>>     import std.traits;
>>     static immutable int[] a  = [1,2,3];
>>     static assert(isStaticArray!(typeof(a)));  // fails
>
> Help yourself with a template:
>
> ----
> import std.traits;
>
> auto toStaticArray(alias array)()
> if (isArray!(typeof(array)))
> {
>     enum size = array.length;
>     alias T = typeof(array.init[0])[size];
>     T result = array[0..size];
>     return result;
> }
>
> enum a = toStaticArray!([1,2,3]);
> static assert(isStaticArray!(typeof(a)));  // success
> ----
>
> Does it fit ?

Using an enum is probably a bit better

----
auto toStaticArray(alias array)()
if (isDynamicArray!(typeof(array)) && array.length)
{
    alias T = typeof(array[0])[array.length];
    enum T result = array[0..array.length];
    return result;
}
May 02, 2016
Am Mon, 02 May 2016 13:00:27 +0000
schrieb Erik Smith <erik@cruiserhouse.com>:

> Is there a way to initialize a static array and have it's size inferred (and that works for arrays of structs using braced literals)?  This would make it easier to maintain longer static array definitions.  The code below doesn't work when removing the array size even though the array is declared as static immutable.
> 
>      import std.traits;
>      static immutable int[] a  = [1,2,3];
>      static assert(isStaticArray!(typeof(a)));  // fails
> 

Sure,

  struct S { int a, b; }

  immutable tab = { static enum S[] s = [
      {1,2},
      {3,4},
  ]; return cast(typeof(s[0])[s.length])s; }();

  static assert(isStaticArray!(typeof(tab)));  // succeeds

-- 
Marco

May 02, 2016
On 02.05.2016 15:53, Marco Leise wrote:
>    immutable tab = { static enum S[] s = [

`static enum`? What kind of black magic is this?
May 02, 2016
Am Mon, 2 May 2016 18:52:11 +0200
schrieb ag0aep6g <anonymous@example.com>:

> On 02.05.2016 15:53, Marco Leise wrote:
> >    immutable tab = { static enum S[] s = [
> 
> `static enum`? What kind of black magic is this?

I don't know, but it works, haha.

-- 
Marco

May 02, 2016
I tried to combine the two solutions (Basile with the wrapper, Marco with the struct initializer support) but it didn't work. The struct initializer is not a array literal (seems obvious now).   I might go with the 2nd but it's pretty heavy just to get the size.

Thanks.


struct S {
    int a, b;
}

auto toStaticArray(alias array)()
{
    struct S { int a, b; }

    immutable tab = {
        static enum S[] s = array;
        return cast(typeof(s[0])[s.length])s;
    }();
    return tab;
}

enum a = toStaticArray!([{1,2},{3,4}]);  // error

May 02, 2016
On Monday, 2 May 2016 at 13:00:27 UTC, Erik Smith wrote:
> Is there a way to initialize a static array and have it's size inferred (and that works for arrays of structs using braced literals)?  This would make it easier to maintain longer static array definitions.  The code below doesn't work when removing the array size even though the array is declared as static immutable.
>
>     import std.traits;
>     static immutable int[] a  = [1,2,3];
>     static assert(isStaticArray!(typeof(a)));  // fails

I still like
----
auto s(T, size_t n)(T[n] arr) {
	return arr;
}

auto arr = [1, 2, 3].s;
----

But of course this won't work:
----
int[] a  = [1,2,3].s;
static assert(isStaticArray!(typeof(a)));  // fails
----

Since 'a' is just a slice.

But this will work:
----
immutable auto a  = [1,2,3].s;
----
May 02, 2016
On 5/2/16 1:43 PM, Namespace wrote:
> On Monday, 2 May 2016 at 13:00:27 UTC, Erik Smith wrote:
>> Is there a way to initialize a static array and have it's size
>> inferred (and that works for arrays of structs using braced
>> literals)?  This would make it easier to maintain longer static array
>> definitions.  The code below doesn't work when removing the array size
>> even though the array is declared as static immutable.
>>
>>     import std.traits;
>>     static immutable int[] a  = [1,2,3];
>>     static assert(isStaticArray!(typeof(a)));  // fails
>
> I still like
> ----
> auto s(T, size_t n)(T[n] arr) {
>      return arr;
> }

Interesting. But there is a major problem here...

>
> auto arr = [1, 2, 3].s;
> ----
>
> But of course this won't work:
> ----
> int[] a  = [1,2,3].s;
> static assert(isStaticArray!(typeof(a)));  // fails
> ----

And this is the problem.

> Since 'a' is just a slice.

A slice of a no-longer-existing temporary! Admittedly, this is not an issue with your code, but a deeper issue of allowing slicing of rvalues.

>
> But this will work:
> ----
> immutable auto a  = [1,2,3].s;
> ----

You can drop auto. It's just a placeholder for the storage class in the case where a storage class isn't specified.

-Steve
May 02, 2016
> A slice of a no-longer-existing temporary! Admittedly, this is not an issue with your code, but a deeper issue of allowing slicing of rvalues.
This works:
----
int[] as = [1, 2, 3].s;
writeln(as[2]);
----
Bug or feature? Or did I may misunderstood you?

> You can drop auto. It's just a placeholder for the storage class in the case where a storage class isn't specified.
Right, I forgot, it's a bit since I wrote something in D.


« First   ‹ Prev
1 2 3