Thread overview
static arrays as AA values
Aug 07, 2005
Ben Hinkle
Aug 07, 2005
Derek Parnell
Aug 07, 2005
Ben Hinkle
Aug 07, 2005
Derek Parnell
Aug 08, 2005
Shammah Chancellor
Aug 08, 2005
Ben Hinkle
Aug 08, 2005
Shammah Chancellor
Aug 08, 2005
Ben Hinkle
Aug 08, 2005
Shammah Chancellor
Aug 08, 2005
Ben Hinkle
August 07, 2005
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
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
> 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
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
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
"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
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
"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
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
> 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.