Jump to page: 1 2 3
Thread overview
How to initialize static array member variable?
Sep 30, 2010
Philippe Sigaud
Sep 30, 2010
bearophile
Sep 30, 2010
Philippe Sigaud
Oct 01, 2010
bearophile
Oct 01, 2010
Philippe Sigaud
Sep 30, 2010
Jonathan M Davis
Oct 01, 2010
Simen kjaeraas
Sep 30, 2010
bearophile
Sep 30, 2010
Trass3r
Sep 30, 2010
Philippe Sigaud
Sep 30, 2010
Trass3r
Oct 01, 2010
Simen kjaeraas
Oct 01, 2010
Simen kjaeraas
Oct 01, 2010
Philippe Sigaud
Oct 01, 2010
Frank Miller
Oct 29, 2010
Trass3r
Oct 29, 2010
Simen kjaeraas
Oct 29, 2010
Trass3r
September 30, 2010
Hi,

I'm still playing around with DMD 2.049 and my Vector struct. This

struct Vector(alias N,T)
{
    static immutable Vector X=Vector(1,0,0);

    this(T[N] v ...) {
        data=v;
    }

    T data[N];
};

alias Vector!(3,float) Vec3f;

gives

Error	1	Error: Slice operation this.data[] = cast(const(float[]))v cannot be evaluated at compile time		main.d	6

I also tried simply

struct Vector(alias N,T)
{
    static immutable Vector X=Vector(1,0,0);

    this(T x,T y,T z) {
        data[0]=x;
        data[1]=y;
        data[2]=z;
    }

    T data[N];
};

alias Vector!(3,float) Vec3f;

but that gives

Error	1	Error: Index assignment this.data[0u] = x is not yet supported in CTFE		main.d	6
Error	2	Error: Index assignment this.data[1u] = y is not yet supported in CTFE		main.d	7
Error	3	Error: Index assignment this.data[2u] = z is not yet supported in CTFE		main.d	8

Any other ideas how to introduce such an "X" constant?

Thanks.

-- 
Sebastian Schuberth
September 30, 2010
On Thu, Sep 30, 2010 at 21:14, Sebastian Schuberth <sschuberth@gmail.com> wrote:
> Hi,
>
> I'm still playing around with DMD 2.049 and my Vector struct. This
>
> struct Vector(alias N,T)
> {
>    static immutable Vector X=Vector(1,0,0);
>
>    this(T[N] v ...) {
>        data=v;
>    }
>
>    T data[N];
> };

To me, your constructor's signature is saying: "give me any number of T[N]", which I guess is not what you want. You want exactly N T's. Which gives the following constructor:

this(U...)(U v) if (U.length <= N && is(CommonType!U : T))
{
    data = [v];
}

I guess I'll have to explain this: U... is a bunch of values of any
type. With the template constraint I just check that
1) there is the correct number of values (at most N)
2) they can all be changed into T's

as for the  = [v] part, it's just that throwing a tuple in an array constructor will make an array from the tuple.

Btw, "alias N" is a bit dangerous: N could be any symbol. As you use
it as a size, let's give it a size type:  Vector(int N, T) or
Vector(size_t N, T).
Also, T data[N]; is using a C syntax. In D, the idiomatic syntax is T[N] data;
And there is no need for a semicolon at the end of a struct
definition: the compiler knows it ends there.

Which gives us:

import std.traits: CommonType;

struct Vector(size_t N,T)
{
    this(U...)(U v) if (U.length <= N && is(CommonType!U == T))
    {
        data = [v];
    }

    T[N] data;
}


> Any other ideas how to introduce such an "X" constant?

It's doable, but it means modifying your struct a bit: instead of holding the values in an array, you can store them in a tuple. I'll see if anyone as another idea: I'm biased towards tuples.

Philippe
September 30, 2010
On Thursday 30 September 2010 12:14:09 Sebastian Schuberth wrote:
> Hi,
> 
> I'm still playing around with DMD 2.049 and my Vector struct. This
> 
> struct Vector(alias N,T)
> {
>      static immutable Vector X=Vector(1,0,0);
> 
>      this(T[N] v ...) {
>          data=v;
>      }
> 
>      T data[N];
> };
> 
> alias Vector!(3,float) Vec3f;
> 
> gives
> 
> Error	1	Error: Slice operation this.data[] = cast(const(float[]))v
> cannot be evaluated at compile time		main.d	6
> 
> I also tried simply
> 
> struct Vector(alias N,T)
> {
>      static immutable Vector X=Vector(1,0,0);
> 
>      this(T x,T y,T z) {
>          data[0]=x;
>          data[1]=y;
>          data[2]=z;
>      }
> 
>      T data[N];
> };
> 
> alias Vector!(3,float) Vec3f;
> 
> but that gives
> 
> Error	1	Error: Index assignment this.data[0u] = x is not yet supported
> in CTFE		main.d	6
> Error	2	Error: Index assignment this.data[1u] = y is not yet supported
> in CTFE		main.d	7
> Error	3	Error: Index assignment this.data[2u] = z is not yet supported
> in CTFE		main.d	8
> 
> Any other ideas how to introduce such an "X" constant?
> 
> Thanks.

You could initialized it in a static constructor. e.g.

static this()
{
	X = Vector(1, 0, 0);
}

By the way, it's a bit atypical in D at this point to declare constants in all caps - primarily because you often end up with so many in your code that it can get pretty ugly to have so many variables in all caps.

Also, assuming that you could initialize the variable at compile-time (which you obviously having trouble doing here), the typical way to declare such a constant is not to use static but rather enum. e.g.

enum x = Vector(1, 0, 0);

However, since you can't initialize this particular variable at compile-time as it stands, a static variable would be the correct way to go here.

Also, if you declare a variable immutable and initialize directly (as opposed to using a destructor), you don't have to include the type (just like you don't have to include the type for enum). Of course, since you need a static constructor here, it won't work here, but I thought that I'd let you know.

- Jonathan M Davis
September 30, 2010
Sebastian Schuberth:

> struct Vector(alias N,T)
> {
>      static immutable Vector X=Vector(1,0,0);
> 
>      this(T[N] v ...) {
>          data=v;
>      }
> 
>      T data[N];
> };
> 
> alias Vector!(3,float) Vec3f;

This seems to work:

struct Vector(int N, T) {
    static immutable Vector x;

    static this() {
        x = Vector(1, 0, 0);
    }

    this(T[N] v...) {
        data = v;
    }

    T[N] data;
}

alias Vector!(3,float) Vec3f;

void main() {
    auto v = Vec3f(1,2,3);
    v = v.x;
    assert(v.data[0] == 1.0);
}


Your code doesn't work because type safe variadic functions can't be used at compile time yet :-) It's a limitation that I think Don will eventually remove.

Bye,
bearophile
September 30, 2010
Philippe Sigaud:

> It's doable, but it means modifying your struct a bit: instead of holding the values in an array, you can store them in a tuple. I'll see if anyone as another idea: I'm biased towards tuples.

Please, be gentle with the D newbie, don't burn his brain :-) You can't learn a big part of D2 in one day.

Bye,
bearophile
September 30, 2010
> I also tried simply
>
> struct Vector(alias N,T)
> {
>      static immutable Vector X=Vector(1,0,0);
>
>      this(T x,T y,T z) {
>          data[0]=x;
>          data[1]=y;
>          data[2]=z;
>      }
>
>      T data[N];
> };

This sort of constructor shouldn't be necessary since an implicit one will be generated.

You could also try "alias data this;" to make the vector usable like an array.

Here's a basic D2 fixed-size vector implementation for you to study: http://sfml.svn.sourceforge.net/viewvc/sfml/branches/sfml2/DSFML/import/dsfml/system/vector.d?view=markup
September 30, 2010
On Thu, Sep 30, 2010 at 23:10, Trass3r <un@known.com> wrote:
> This sort of constructor shouldn't be necessary since an implicit one will be generated.

Will it convert N T's into a T[N]?
September 30, 2010
On Thu, Sep 30, 2010 at 22:32, bearophile <bearophileHUGS@lycos.com> wrote:
> Philippe Sigaud:
>
>> It's doable, but it means modifying your struct a bit: instead of holding the values in an array, you can store them in a tuple. I'll see if anyone as another idea: I'm biased towards tuples.
>
> Please, be gentle with the D newbie, don't burn his brain :-) You can't learn a big part of D2 in one day.

Well, I did say I was biased :-)  So much so, in fact, that didn't see
at first he was using an array.
I still wonder how the constructor works: how can T[N]v... accept 1,2,3?
September 30, 2010
> Will it convert N T's into a T[N]?

Ah wait, yeah, he uses an array.

What I mentioned works only if you have a struct with members x, y, z, ...
October 01, 2010
On 30.09.2010 22:01, Philippe Sigaud wrote:

> To me, your constructor's signature is saying: "give me any number of
> T[N]", which I guess is not what you want. You want exactly N T's.

You're right, I want exactly N T's, but from reading the section about "Typesafe Variadic Functions" at [1], I thought I'm doing exactly that. The example "For static arrays" has a comment which says for a declaration like

int sum(int[3] ar ...)

this

return sum(2, 3); // error, need 3 values for array

would not work, so I thought "...", if following a statically sized array, is a special syntax to allow the array to be initialized from exactly N scalar values.

In fact, I checked that with my code

auto v=Vec3f(1,0,0);

compiles, but

auto v=Vec3f(1,0);
auto v=Vec3f(1,0,0,0);
auto v=Vec3f([1,0,0],[1,0,0]);

do not compile, just as desired. So I thought I'm doing the right thing :-)

> Which gives the following constructor:
>
> this(U...)(U v) if (U.length<= N&&  is(CommonType!U : T))
> {
>      data = [v];
> }

Well, this makes sense, thank you. I'm just wondering if my solution is any less safe?

> Btw, "alias N" is a bit dangerous: N could be any symbol. As you use
> it as a size, let's give it a size type:  Vector(int N, T) or
> Vector(size_t N, T).
> Also, T data[N]; is using a C syntax. In D, the idiomatic syntax is T[N] data;
> And there is no need for a semicolon at the end of a struct
> definition: the compiler knows it ends there.

Thanks for all the hints!

> It's doable, but it means modifying your struct a bit: instead of
> holding the values in an array, you can store them in a tuple.
> I'll see if anyone as another idea: I'm biased towards tuples.

With tuples, would it still be that sizeof(Vector)==sizeof(T)*N?

[1] http://www.digitalmars.com/d/2.0/function.html

-- 
Sebastian Schuberth
« First   ‹ Prev
1 2 3