digitalmars.D.learn - Ways to initialize static arrays
- Stanislav Blinov (44/44) Aug 23 2010 Hello,
- bearophile (4/6) Aug 23 2010 Please explain your purposes a bit better.
- Stanislav Blinov (25/29) Aug 23 2010 I have a struct template (let's call it S) that wraps an array of N
- Philippe Sigaud (46/70) Aug 25 2010 If they work, then they are legal :)
- Stanislav Blinov (9/16) Aug 26 2010 Sorry, I pressed the wrong button so the message was sent to your
- Philippe Sigaud (10/19) Aug 26 2010 Your templates are not clumsy, it's typically the way some other PL woul...
- Stanislav Blinov (24/45) Aug 26 2010 Thanks for friendly shoulder tap :)
- Philippe Sigaud (6/19) Aug 26 2010 Dunno, I never use the = { ... } syntax to create structs. I always do =
- Stanislav Blinov (3/16) Aug 26 2010 Ok, I'll do that once I narrow it down to anything meaningful (I've
- Stanislav Blinov (2/2) Aug 28 2010 Done:
Hello, I was wondering if anyone has suggestions on performing arbitrary initialization of static arrays, size of which is arbitrary at compile time. Consider this: template StaticArray(T,int N,T v) if (N > 0) { static if (N == 1) { enum T[N] StaticArray = cast(T[N])[v]; } else { enum T[N] StaticArray = cast(T[N])([v] ~ StaticArray!(T,N-1,v)); } } T[] generateArray(T,int N,string G=q{a[i] = 0})() { T[] a; foreach(i;0..N) { mixin(G ~ ";"); } return a.dup; } template GenStaticArray(T,int N,string G=q{a[i] = 0}) { enum T[N] GenStaticArray = cast(T[N])generateArray!(T,N,G)(); } struct Vector(int N,T) { T data_[N]; static immutable Vector Identity = { StaticArray!(T,N,1) }; static immutable Vector Zero = { StaticArray!(T,N,0) }; static immutable Vector UnitX = { GenStaticArray!(T,N,q{a[i] = i ? 0 : 1}) }; static immutable Vector UnitY = { GenStaticArray!(T,N,q{a[i] = i != 1 ? 0 : 1}) }; static immutable Vector UnitZ = { GenStaticArray!(T,N,q{a[i] = i != 2 ? 0 : 1}) }; } I don't like those casts in templates. In fact, I'm not even sure if such code is legal. Maybe there is some better way of doing this? --
Aug 23 2010
Stanislav Blinov:I was wondering if anyone has suggestions on performing arbitrary initialization of static arrays, size of which is arbitrary at compile time.Please explain your purposes a bit better. Bye, bearophile
Aug 23 2010
23.08.2010 16:31, bearophile wrote:Stanislav Blinov: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.I was wondering if anyone has suggestions on performing arbitrary initialization of static arrays, size of which is arbitrary at compile time.Please explain your purposes a bit better.
Aug 23 2010
2010/8/23 Stanislav Blinov <blinov 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
Aug 25 2010
Sorry, I pressed the wrong button so the message was sent to your email. Reciting: 26.08.2010 1:53, Philippe Sigaud wrote: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 :)How it would be better for us all if we could always say that :)If I understand correctly what you want, you can achieve it with compile-time-evaluable functions: Does that work for you?Yes! Beautiful, thanks! That beats hell out of my clumsy templates :) When I was on the way to my initial solutions I was under strong impression that T[N] func() won't work. Now I see that was because I didn't bother to fully understand how arrays are returned from functions. I got it now, so thanks a lot again!
Aug 26 2010
On Thu, Aug 26, 2010 at 14:11, Stanislav Blinov <blinov loniir.ru> wrote:Sorry, I pressed the wrong button so the message was sent to your email. Reciting: Does that work for you?Your templates are not clumsy, it's typically the way some other PL would process lists/arrays. I used to write a lot of these. But 6 months ago, CTFE got seven-leagues boots and right now it's much easier on the eye to use CT functions.Yes! Beautiful, thanks! That beats hell out of my clumsy templates :)When I was on the way to my initial solutions I was under strong impression that T[N] func() won't work. Now I see that was because I didn't bother to fully understand how arrays are returned from functions. I got it now, so thanks a lot again!There used to be a time, maybe not 18 months ago where returning static arrays from functions was not possible, IIRC. Right now, I think you can use them with no problem. Maybe someone well-versed in optimization will tell us it's not a good idea, I don't know. Philippe
Aug 26 2010
Philippe Sigaud wrote:That beats hell out of my clumsy templates :) Your templates are not clumsy, it's typically the way some other PL would process lists/arrays. I used to write a lot of these. But 6 months ago, CTFE got seven-leagues boots and right now it's much easier on the eye to use CT functions.Thanks for friendly shoulder tap :) I think I just need to get accustomed with CTFE. I mostly work in C++, and it's templates (much inspired by Andrei's C++ publications as well as Loki, by the way) are telling on me. I constantly tend to forget there are so many constructs in D I can use at compile time without worry.When I was on the way to my initial solutions I was under strong impression that T[N] func() won't work. Now I see that was because I didn't bother to fully understand how arrays are returned from functions. I got it now, so thanks a lot again! There used to be a time, maybe not 18 months ago where returning static arrays from functions was not possible, IIRC..This may have something to do with my assumptions. I haven't tried D much since when shared was introduced (don't remember how long ago it was).Right now, I think you can use them with no problem. Maybe someone well-versed in optimization will tell us it's not a good idea, I don't know.Well, as you've said yourself, if it works... :) PS. I'm not sure as to where to post this, but after I tried your solution I've noticed one interesting (or rather strange) thing: struct S(T,size_t N) { T[N] arr; int foo; // type doesn't seem to matter here, // taking int for clarity static immutable S C1 = { initializeWith!(T,N)(0) 5 }; // Note there is no comma after first initializer ^ } This actually compiles and works, though I have an impression that syntax error is in order. Putting in second array and attempting similar initialization without commas leads to one. I've only tried it with Windows 2.048, though I think the front end would eat this on Linux too. Is this valid, already known or I should report this?
Aug 26 2010
On Thu, Aug 26, 2010 at 23:49, Stanislav Blinov <stanislav.blinov gmail.com>wrote:struct S(T,size_t N) { T[N] arr; int foo; // type doesn't seem to matter here, // taking int for clarity static immutable S C1 = { initializeWith!(T,N)(0) 5 }; // Note there is no comma after first initializer ^ } This actually compiles and works, though I have an impression that syntax error is in order. Putting in second array and attempting similar initialization without commas leads to one. I've only tried it with Windows 2.048, though I think the front end would eat this on Linux too. Is this valid, already known or I should report this?Dunno, I never use the = { ... } syntax to create structs. I always do = S(...); I even thought the literal syntax was being deprecated. Maybe I'm mistaken. In any case, please report this.
Aug 26 2010
Philippe Sigaud wrote:I have an impression that syntax error is in order. Putting in second array and attempting similar initialization without commas leads to one. I've only tried it with Windows 2.048, though I think the front end would eat this on Linux too. Is this valid, already known or I should report this? Dunno, I never use the = { ... } syntax to create structs. I always do = S(...); I even thought the literal syntax was being deprecated. Maybe I'm mistaken. In any case, please report this.Ok, I'll do that once I narrow it down to anything meaningful (I've found that behavior on 2.047 Linux is somewhat different).
Aug 26 2010
Done: http://d.puremagic.com/issues/show_bug.cgi?id=4745
Aug 28 2010