View mode: basic / threaded / horizontal-split · Log in · Help
August 07, 2005
static arrays as AA values
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?
August 07, 2005
Re: static arrays as AA values
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
August 07, 2005
Re: static arrays as AA values
> Try ...
>
>  x[10][] = test.init;
>
> The [] indicates an array copy operation.

I did. It didn't insert so it threw an "ArrayBoundsError".
August 07, 2005
Re: static arrays as AA values
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
August 08, 2005
Re: static arrays as AA values
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.
August 08, 2005
Re: static arrays as AA values
"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 );
August 08, 2005
Re: static arrays as AA values
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.
August 08, 2005
Re: static arrays as AA values
"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
August 08, 2005
Re: static arrays as AA values
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 )
August 08, 2005
Re: static arrays as AA values
> 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.
Top | Discussion index | About this forum | D home