Ways to initialize static arrays

Philippe Sigaud philippe.sigaud at gmail.com
Wed Aug 25 14:53:01 PDT 2010


2010/8/23 Stanislav Blinov <blinov at loniir.ru>

> I have a struct template (let's call it S) that wraps an array of N
> elements. N is set at compile time via template parameter. S uses static
> array as storage (T[N]). I need a set of constants of type S which I'd like
> to be evaluatable at compile time. I can create these constants with the
> following constructs:
>
> static immutable S C1 = { /* initialization of struct fields here */ };
> static immutable S C2 = { /* initialization of struct fields here */ };
>
> Hence, I need some way to initialize a field which is T[N].
>
> Later, I could use those constants like this:
>
> class Foo
> {
>    S s1_ = S.C1;
>    S s2_ = S.C2;
> }
>
> I can write a set of initializers for some values of N, but I'd like them
> to be generic so that I could apply them for arbitrary value of N.
> E.g. one can do things like T[3] a = [ 1, 2, 3 ], but I'd like to be able
> to do T[N] = SomeInitializerForArrayOfNElements;
>
> What I'm trying to achieve is:
>
> 1. Initialize T[N] elements to a specific value.
> 2. Initialize every element of T[N] to some value deduced at compile time
> using it's index.
>
> I came up with the templates in my initial post. They seem to work, but I
> doubt those are legal solutions.
>

If they work, then they are legal :)

If I understand correctly what you want, you can achieve it with
compile-time-evaluable functions:

module main;
import std.stdio;

/**
return a T[N] with all elements equal to t.
*/
T[N] initializeWith(T, size_t N)(T t) if (N>0)
{
    T[N] result;
    foreach(i, _; result)
    {
        result[i] = t;
    }
    return result;
}

/**
Returns a T[N] with all elements equal to foo(index)
*/
T[N] initializeWith(alias fun, T, size_t N)() if (N>0)
{
    T[N] result;
    foreach(i, _; result)
    {
        result[i] = fun(i);
    }
    return result;
}

int foo(int i) { return i*i;}

struct S
{
    static immutable int[10] arr = initializeWith!(foo, int, 10);
}

void main()
{
    auto a = initializeWith!(int,10)(8);

    writeln(a);
    a = initializeWith!(foo,int,10);
    writeln(a);
    S s;
    writeln(s.arr);
}

Does that work for you?

Philippe
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d-learn/attachments/20100825/5afa401b/attachment.html>


More information about the Digitalmars-d-learn mailing list