Thread overview | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
August 23, 2010 Ways to initialize static arrays | ||||
---|---|---|---|---|
| ||||
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? -- |
August 23, 2010 Re: Ways to initialize static arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stanislav Blinov | 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
|
August 23, 2010 Re: Ways to initialize static arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | 23.08.2010 16:31, bearophile wrote: > 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. > 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. |
August 25, 2010 Re: Ways to initialize static arrays | ||||
---|---|---|---|---|
| ||||
Attachments:
| 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
|
August 26, 2010 Re: Ways to initialize static arrays | ||||
---|---|---|---|---|
| ||||
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! |
August 26, 2010 Re: Ways to initialize static arrays | ||||
---|---|---|---|---|
| ||||
Attachments:
| 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? >> >> Yes! Beautiful, thanks! 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. > > 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 |
August 26, 2010 Re: Ways to initialize static arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Philippe Sigaud | 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? |
August 26, 2010 Re: Ways to initialize static arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stanislav Blinov Attachments:
| 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. |
August 26, 2010 Re: Ways to initialize static arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Philippe Sigaud | 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).
|
August 28, 2010 Re: Ways to initialize static arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stanislav Blinov | Done: http://d.puremagic.com/issues/show_bug.cgi?id=4745 |
Copyright © 1999-2021 by the D Language Foundation