www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - static arrays as AA values

reply "Ben Hinkle" <ben.hinkle gmail.com> writes:
A post on D.learn about bit arrays got me thinking about AA indexing 
behavior. In particular how does one insert into an AA with static array 
values. For example

  alias bit[8] test;
  test[int] x;

How does one insert into x? Currently the only way I know if is to use 
l-value indexing expressions like x[10] = blah or x[10] += blah. But when 
the value type is a static array I couldn't figure out any l-value 
expressions that are legal. For example x[10] = test.init isn't allowed. Is 
it possible to have AAs of static arrays?
Aug 07 2005
next sibling parent reply Derek Parnell <derek psych.ward> writes:
On Sun, 7 Aug 2005 11:43:45 -0400, Ben Hinkle wrote:

 A post on D.learn about bit arrays got me thinking about AA indexing 
 behavior. In particular how does one insert into an AA with static array 
 values. For example
 
   alias bit[8] test;
   test[int] x;
 
 How does one insert into x? Currently the only way I know if is to use 
 l-value indexing expressions like x[10] = blah or x[10] += blah. But when 
 the value type is a static array I couldn't figure out any l-value 
 expressions that are legal. For example x[10] = test.init isn't allowed. Is 
 it possible to have AAs of static arrays?

Try ... x[10][] = test.init; The [] indicates an array copy operation. -- Derek Parnell Melbourne, Australia 8/08/2005 7:11:35 AM
Aug 07 2005
parent reply "Ben Hinkle" <ben.hinkle gmail.com> writes:
 Try ...

  x[10][] = test.init;

 The [] indicates an array copy operation.

I did. It didn't insert so it threw an "ArrayBoundsError".
Aug 07 2005
parent Derek Parnell <derek psych.ward> writes:
On Sun, 7 Aug 2005 18:09:26 -0400, Ben Hinkle wrote:

 Try ...

  x[10][] = test.init;

 The [] indicates an array copy operation.

I did. It didn't insert so it threw an "ArrayBoundsError".

You are right. It compiles okay but doesn't run. I agree with you, there doesn't seem to be a way to populate a AA of fixed-length arrays. The best I could come up with is an AA of pointers to fixed-length arrays... <code> import std.stdio; alias char[8] test; void main() { test*[char[]] x; test a; a[] = "qwertyui"; x["abc"] = &a; a[] = "asdfghjk"; x["def"] = &a; foreach( char b; *x["abc"]) writef("%s", b); foreach( char b; *x["def"]) writef("%s", b); } </code> Not really the same thing at all ;-) -- Derek Melbourne, Australia 8/08/2005 9:49:12 AM
Aug 07 2005
prev sibling parent reply Shammah Chancellor <Shammah_member pathlink.com> writes:
In article <dd5a7h$fj4$1 digitaldaemon.com>, Ben Hinkle says...
A post on D.learn about bit arrays got me thinking about AA indexing 
behavior. In particular how does one insert into an AA with static array 
values. For example

  alias bit[8] test;
  test[int] x;

How does one insert into x? Currently the only way I know if is to use 
l-value indexing expressions like x[10] = blah or x[10] += blah. But when 
the value type is a static array I couldn't figure out any l-value 
expressions that are legal. For example x[10] = test.init isn't allowed. Is 
it possible to have AAs of static arrays?

Static arrays are supposed to allocate their memory in one contiguous block. Ie: bit[8][8] x; is a 64 bit space of memory. How is it even defined then to have a dynamic array of statics, or static of dynamics or anything else? The two [] operators seem to know something about each other when allocating the memory. But what if you do bit[8][][8] ?? I ran into this a few days ago, as well as another problem: bit[] nullFoo; typdef bit[] Foo = nullFoo; Guess what, it's impossible to check for nullFoo now. assert( Foo is nullFoo ); // is illegal because of strongly typed typedefs, you have to cast(bit[8]) on Foo in order for it to work. Bleh Also: Foo nullFoo; typedef bit[] Foo = nullFoo; //doesn't work in either order.
Aug 08 2005
parent reply "Ben Hinkle" <bhinkle mathworks.com> writes:
"Shammah Chancellor" <Shammah_member pathlink.com> wrote in message 
news:dd7vvq$2p74$1 digitaldaemon.com...
 In article <dd5a7h$fj4$1 digitaldaemon.com>, Ben Hinkle says...
A post on D.learn about bit arrays got me thinking about AA indexing
behavior. In particular how does one insert into an AA with static array
values. For example

  alias bit[8] test;
  test[int] x;

How does one insert into x? Currently the only way I know if is to use
l-value indexing expressions like x[10] = blah or x[10] += blah. But when
the value type is a static array I couldn't figure out any l-value
expressions that are legal. For example x[10] = test.init isn't allowed. 
Is
it possible to have AAs of static arrays?

Static arrays are supposed to allocate their memory in one contiguous block. Ie: bit[8][8] x; is a 64 bit space of memory. How is it even defined then to have a dynamic array of statics, or static of dynamics or anything else? The two [] operators seem to know something about each other when allocating the memory. But what if you do bit[8][][8] ??

I don't understand what the problem is. The "static" in static arrays means the length is known at compile time. You can have a dynamic array of static arrays just fine: int main() { char[5][] x; x.length = 3; x[2][4] = 'a'; return 0; }
 I ran into this a few days ago, as well as another problem:

 bit[] nullFoo;
 typdef bit[] Foo = nullFoo;

 Guess what, it's impossible to check for nullFoo now.

 assert( Foo is nullFoo ); // is illegal because of strongly typed 
 typedefs, you
 have to cast(bit[8]) on Foo in order for it to work.  Bleh

 Also:

 Foo nullFoo;
 typedef bit[] Foo = nullFoo; //doesn't work in either order.

I don't understand what these examples have to do with inserting static arrays into AAs. Is it the "alias" I used above that made you think of typedef? The alias was just to make the example more readable (plus the thread that spawned this thread had an alias so I just modified that example). Note, though, I think the following would solve your problem: instead of testing for nullFoo test for Foo.init, which has the correct type. For example bit[] nullFoo = new bit[10]; // make it non-trivial typedef bit[] Foo = nullFoo; Foo r; assert( r is Foo.init ); assert( r.length is 10 );
Aug 08 2005
parent reply Shammah Chancellor <Shammah_member pathlink.com> writes:
In article <dd84qe$2u92$1 digitaldaemon.com>, Ben Hinkle says...
"Shammah Chancellor" <Shammah_member pathlink.com> wrote in message 
news:dd7vvq$2p74$1 digitaldaemon.com...
 In article <dd5a7h$fj4$1 digitaldaemon.com>, Ben Hinkle says...
A post on D.learn about bit arrays got me thinking about AA indexing
behavior. In particular how does one insert into an AA with static array
values. For example

  alias bit[8] test;
  test[int] x;

How does one insert into x? Currently the only way I know if is to use
l-value indexing expressions like x[10] = blah or x[10] += blah. But when
the value type is a static array I couldn't figure out any l-value
expressions that are legal. For example x[10] = test.init isn't allowed. 
Is
it possible to have AAs of static arrays?

Static arrays are supposed to allocate their memory in one contiguous block. Ie: bit[8][8] x; is a 64 bit space of memory. How is it even defined then to have a dynamic array of statics, or static of dynamics or anything else? The two [] operators seem to know something about each other when allocating the memory. But what if you do bit[8][][8] ??

I don't understand what the problem is. The "static" in static arrays means the length is known at compile time. You can have a dynamic array of static arrays just fine: int main() { char[5][] x; x.length = 3; x[2][4] = 'a'; return 0; }

The difference is that x is 0 bytes, and a is 8. What would char[2][4][] be when length is finally set to 1? Would a contiguous block be allocated for each element in the dynamic array?
 I ran into this a few days ago, as well as another problem:

 bit[] nullFoo;
 typdef bit[] Foo = nullFoo;

 Guess what, it's impossible to check for nullFoo now.

 assert( Foo is nullFoo ); // is illegal because of strongly typed 
 typedefs, you
 have to cast(bit[8]) on Foo in order for it to work.  Bleh

 Also:

 Foo nullFoo;
 typedef bit[] Foo = nullFoo; //doesn't work in either order.

I don't understand what these examples have to do with inserting static arrays into AAs. Is it the "alias" I used above that made you think of typedef? The alias was just to make the example more readable (plus the thread that spawned this thread had an alias so I just modified that example). Note, though, I think the following would solve your problem: instead of testing for nullFoo test for Foo.init, which has the correct type. For example bit[] nullFoo = new bit[10]; // make it non-trivial typedef bit[] Foo = nullFoo; Foo r; assert( r is Foo.init ); assert( r.length is 10 );

That doesn't fix my problem. The reason being that init might be nullFoo at this point in time, but checking for nullity and default value is not the same. If init changes, you should still be checking for null. However, your example gave me this idea, which does fix my problem: bit[] _nullFoo = new bit[1] typedef bit[] Foo = nullFoo; Foo nullFoo = cast(Foo)_nullFoo; Foo myFoo; assert( myFoo is nullFoo ); //should work now.
Aug 08 2005
parent reply "Ben Hinkle" <bhinkle mathworks.com> writes:
"Shammah Chancellor" <Shammah_member pathlink.com> wrote in message 
news:dd86mr$30q3$1 digitaldaemon.com...
 In article <dd84qe$2u92$1 digitaldaemon.com>, Ben Hinkle says...
"Shammah Chancellor" <Shammah_member pathlink.com> wrote in message
news:dd7vvq$2p74$1 digitaldaemon.com...
 In article <dd5a7h$fj4$1 digitaldaemon.com>, Ben Hinkle says...
A post on D.learn about bit arrays got me thinking about AA indexing
behavior. In particular how does one insert into an AA with static array
values. For example

  alias bit[8] test;
  test[int] x;

How does one insert into x? Currently the only way I know if is to use
l-value indexing expressions like x[10] = blah or x[10] += blah. But 
when
the value type is a static array I couldn't figure out any l-value
expressions that are legal. For example x[10] = test.init isn't allowed.
Is
it possible to have AAs of static arrays?

Static arrays are supposed to allocate their memory in one contiguous block. Ie: bit[8][8] x; is a 64 bit space of memory. How is it even defined then to have a dynamic array of statics, or static of dynamics or anything else? The two [] operators seem to know something about each other when allocating the memory. But what if you do bit[8][][8] ??

I don't understand what the problem is. The "static" in static arrays means the length is known at compile time. You can have a dynamic array of static arrays just fine: int main() { char[5][] x; x.length = 3; x[2][4] = 'a'; return 0; }

The difference is that x is 0 bytes, and a is 8.

You've lost me. x is a dynamic array and 'a' is a char literal.
 What would char[2][4][] be
 when length is finally set to 1?  Would a contiguous block be allocated 
 for each
 element in the dynamic array?

A contiguous block would be allocated. For example try int main() { char[100][10][] x; x.length = 5; assert( cast(uint)(&x[3]) == cast(uint)(&x[0])+100*10*3 ); return 0; }
 I ran into this a few days ago, as well as another problem:

 bit[] nullFoo;
 typdef bit[] Foo = nullFoo;

 Guess what, it's impossible to check for nullFoo now.

 assert( Foo is nullFoo ); // is illegal because of strongly typed
 typedefs, you
 have to cast(bit[8]) on Foo in order for it to work.  Bleh

 Also:

 Foo nullFoo;
 typedef bit[] Foo = nullFoo; //doesn't work in either order.

I don't understand what these examples have to do with inserting static arrays into AAs. Is it the "alias" I used above that made you think of typedef? The alias was just to make the example more readable (plus the thread that spawned this thread had an alias so I just modified that example). Note, though, I think the following would solve your problem: instead of testing for nullFoo test for Foo.init, which has the correct type. For example bit[] nullFoo = new bit[10]; // make it non-trivial typedef bit[] Foo = nullFoo; Foo r; assert( r is Foo.init ); assert( r.length is 10 );

That doesn't fix my problem. The reason being that init might be nullFoo at this point in time, but checking for nullity and default value is not the same.

uh oh :-)
 If init changes, you should still be checking for null.

 However, your example gave me this idea, which does fix my problem:

 bit[] _nullFoo = new bit[1]
 typedef bit[] Foo = nullFoo;
 Foo nullFoo = cast(Foo)_nullFoo;

 Foo myFoo;
 assert( myFoo is nullFoo ); //should work now.

note since assert( nullFoo is Foo.init ); passes you can't tell the difference between nullFoo and Foo.init
Aug 08 2005
parent reply Shammah Chancellor <Shammah_member pathlink.com> writes:
In article <dd87ts$ho$1 digitaldaemon.com>, Ben Hinkle says...
"Shammah Chancellor" <Shammah_member pathlink.com> wrote in message 
news:dd86mr$30q3$1 digitaldaemon.com...
 In article <dd84qe$2u92$1 digitaldaemon.com>, Ben Hinkle says...
"Shammah Chancellor" <Shammah_member pathlink.com> wrote in message
news:dd7vvq$2p74$1 digitaldaemon.com...
 In article <dd5a7h$fj4$1 digitaldaemon.com>, Ben Hinkle says...
A post on D.learn about bit arrays got me thinking about AA indexing
behavior. In particular how does one insert into an AA with static array
values. For example

  alias bit[8] test;
  test[int] x;

How does one insert into x? Currently the only way I know if is to use
l-value indexing expressions like x[10] = blah or x[10] += blah. But 
when
the value type is a static array I couldn't figure out any l-value
expressions that are legal. For example x[10] = test.init isn't allowed.
Is
it possible to have AAs of static arrays?

Static arrays are supposed to allocate their memory in one contiguous block. Ie: bit[8][8] x; is a 64 bit space of memory. How is it even defined then to have a dynamic array of statics, or static of dynamics or anything else? The two [] operators seem to know something about each other when allocating the memory. But what if you do bit[8][][8] ??

I don't understand what the problem is. The "static" in static arrays means the length is known at compile time. You can have a dynamic array of static arrays just fine: int main() { char[5][] x; x.length = 3; x[2][4] = 'a'; return 0; }

The difference is that x is 0 bytes, and a is 8.

You've lost me. x is a dynamic array and 'a' is a char literal.

That's because I lost myself. What I was talking about was this: (Provided this was what you had actually typed, and it wasn't) char[5][] x; char[2][4] a; x allocates 8 bytes of memory due to size and ptr information, but no actual data. a allocates 8 bytes of actual data space (Not sure if static arrays keep their length and ptr in memory the same way..)
 What would char[2][4][] be
 when length is finally set to 1?  Would a contiguous block be allocated 
 for each
 element in the dynamic array?

A contiguous block would be allocated. For example try int main() { char[100][10][] x; x.length = 5; assert( cast(uint)(&x[3]) == cast(uint)(&x[0])+100*10*3 ); return 0; }

I guess the answer to my previous question about length and ptr for static arrays is that it doesn't. Otherwise this example wouldn't work. Anyways your initial problem is still hanging. The problem doesn't seem to be from the [] operator (That's valid) But it's dereferencing before and then attempting to copy, but there's no key. (I assume you realised this.) The array bounds error comes from D trying to lookup that key, and then copy to the static array contained therein. You should be able to do this: AA.add("key") AA["key"][] = otherArr; However, there is no add key method. I swear I read that there was at one point, but there isn't. Experimenting with things I also found a compiler crash: import std.stdio; DMD 0.128 int[8][char[]] Hello; cast(int)(Hello["Hello"]) = 0
 I ran into this a few days ago, as well as another problem:

 bit[] nullFoo;
 typdef bit[] Foo = nullFoo;

 Guess what, it's impossible to check for nullFoo now.

 assert( Foo is nullFoo ); // is illegal because of strongly typed
 typedefs, you
 have to cast(bit[8]) on Foo in order for it to work.  Bleh

 Also:

 Foo nullFoo;
 typedef bit[] Foo = nullFoo; //doesn't work in either order.

I don't understand what these examples have to do with inserting static arrays into AAs. Is it the "alias" I used above that made you think of typedef? The alias was just to make the example more readable (plus the thread that spawned this thread had an alias so I just modified that example). Note, though, I think the following would solve your problem: instead of testing for nullFoo test for Foo.init, which has the correct type. For example bit[] nullFoo = new bit[10]; // make it non-trivial typedef bit[] Foo = nullFoo; Foo r; assert( r is Foo.init ); assert( r.length is 10 );

That doesn't fix my problem. The reason being that init might be nullFoo at this point in time, but checking for nullity and default value is not the same.

uh oh :-)
 If init changes, you should still be checking for null.

 However, your example gave me this idea, which does fix my problem:

 bit[] _nullFoo = new bit[1]
 typedef bit[] Foo = nullFoo;
 Foo nullFoo = cast(Foo)_nullFoo;

 Foo myFoo;
 assert( myFoo is nullFoo ); //should work now.

note since assert( nullFoo is Foo.init ); passes you can't tell the difference between nullFoo and Foo.init

That's true, but if i decide to init Foo with something else later, there would be a difference. (That's why I don't think it's correct to equate the two. ) (I also made a typo in the revised example, the init should have been _nullFoo, not nullFoo )
Aug 08 2005
parent "Ben Hinkle" <ben.hinkle gmail.com> writes:
 You should be able to do this:

 AA.add("key")
 AA["key"][] = otherArr;

 However, there is no add key method.  I swear I read that there was at one
 point, but there isn't.

That's where I was heading, too. Though it would be nice if add("key") returned an lvalue or pointer so that the double-lookup is avoided. In MinTL this "add" method is called "put" and returns a pointer to the value for a given key, inserting if needed.
Aug 08 2005