www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - AA initialization

reply "Puming" <zhaopuming gmail.com> writes:
I found AA initialization have a strange effect:

```d
	string[string] map; // same as `string[string] map = 
string[string].init;
	writeln(map); // output: []

	string[string] refer = map; // make a reference
	refer["1"] = "2"; // update the reference
	writeln(map); // output: []. The reference does not affect the 
original.
```

But if I do an assignment first, the reference works:


```d
	string[string] map; // same as `string[string] map = 
string[string].init;
	writeln(map); // output: []

         map["1"] = "0";

	string[string] refer = map; // make a reference
	refer["1"] = "2"; // update the reference
	writeln(map); // output: ["1":"2"]. The reference does affect.
```

So if I want an empty AA and want to use a variable to refer to 
it later, I have to do this:

```d
	string[string] map; // same as `string[string] map = 
string[string].init;

         map["1"] = "0";
         map.remove("1"); // assign and then REMOVE!
	writeln(map); // output: []

	string[string] refer = map; // make a reference
	refer["1"] = "2"; // update the reference
	writeln(map); // output: ["1":"2"]. The reference does affect.
```

which looks awkward.

Is it because `string[string].init == null` ? If so, how do I 
specify an empty AA which is not null? Neither `[]` or `[:]` 
seems to work.
Aug 06 2014
parent reply "Kozzi11" <kozzi11 gmail.com> writes:
On Wednesday, 6 August 2014 at 11:32:41 UTC, Puming wrote:
 I found AA initialization have a strange effect:

 ```d
 	string[string] map; // same as `string[string] map = 
 string[string].init;
 	writeln(map); // output: []

 	string[string] refer = map; // make a reference
 	refer["1"] = "2"; // update the reference
 	writeln(map); // output: []. The reference does not affect the 
 original.
 ```

 But if I do an assignment first, the reference works:


 ```d
 	string[string] map; // same as `string[string] map = 
 string[string].init;
 	writeln(map); // output: []

         map["1"] = "0";

 	string[string] refer = map; // make a reference
 	refer["1"] = "2"; // update the reference
 	writeln(map); // output: ["1":"2"]. The reference does affect.
 ```

 So if I want an empty AA and want to use a variable to refer to 
 it later, I have to do this:

 ```d
 	string[string] map; // same as `string[string] map = 
 string[string].init;

         map["1"] = "0";
         map.remove("1"); // assign and then REMOVE!
 	writeln(map); // output: []

 	string[string] refer = map; // make a reference
 	refer["1"] = "2"; // update the reference
 	writeln(map); // output: ["1":"2"]. The reference does affect.
 ```

 which looks awkward.

 Is it because `string[string].init == null` ? If so, how do I 
 specify an empty AA which is not null? Neither `[]` or `[:]` 
 seems to work.
AFAIK there is no easy way to do it. Maybe it would be fine to add some function to phobos. Something like this: auto initAA(VT,KT)() { static struct Entry { Entry *next; size_t hash; } static struct Impl { Entry*[] buckets; size_t nodes; TypeInfo _keyti; Entry*[4] binit; property const(TypeInfo) keyti() const safe pure nothrow nogc { return _keyti; } } static struct AA { Impl* impl; } VT[KT] aaa; AA* aa = cast(AA*)&aaa; if (aa.impl is null) { aa.impl = new Impl(); aa.impl.buckets = aa.impl.binit[]; } aa.impl._keyti = cast() typeid(aaa); return aaa; } Or it would be fine if I could write something like this: auto aa = new VT[KT]();
Aug 06 2014
parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Wednesday, 6 August 2014 at 13:15:27 UTC, Kozzi11 wrote:
 AFAIK there is no easy way to do it. Maybe it would be fine to 
 add some function to phobos. Something like this:


 auto initAA(VT,KT)() {

 	static struct Entry
 	{
 		Entry *next;
 		size_t hash;
 	}
 	
 	static struct Impl
 	{
 		Entry*[] buckets;
 		size_t nodes;
 		TypeInfo _keyti;
 		Entry*[4] binit;
 		
 		 property const(TypeInfo) keyti() const  safe pure nothrow 
  nogc
 		{ return _keyti; }
 	}

 	static struct AA
 	{
 		Impl* impl;
 	}

 	VT[KT] aaa;
 	AA* aa = cast(AA*)&aaa;
 	if (aa.impl is null)
 	{   aa.impl = new Impl();
 		aa.impl.buckets = aa.impl.binit[];
 	}
 	aa.impl._keyti = cast() typeid(aaa);
 	return aaa;
 }


 Or it would be fine if I could write something like this: auto 
 aa = new VT[KT]();
`string[string] aa = [];` would be fine, too, but it currently doesn't compile.
Aug 06 2014
parent reply "Puming" <zhaopuming gmail.com> writes:
On Wednesday, 6 August 2014 at 14:38:34 UTC, Marc Schütz wrote:
 On Wednesday, 6 August 2014 at 13:15:27 UTC, Kozzi11 wrote:
 AFAIK there is no easy way to do it. Maybe it would be fine to 
 add some function to phobos. Something like this:


 auto initAA(VT,KT)() {

 	static struct Entry
 	{
 		Entry *next;
 		size_t hash;
 	}
 	
 	static struct Impl
 	{
 		Entry*[] buckets;
 		size_t nodes;
 		TypeInfo _keyti;
 		Entry*[4] binit;
 		
 		 property const(TypeInfo) keyti() const  safe pure nothrow 
  nogc
 		{ return _keyti; }
 	}

 	static struct AA
 	{
 		Impl* impl;
 	}

 	VT[KT] aaa;
 	AA* aa = cast(AA*)&aaa;
 	if (aa.impl is null)
 	{   aa.impl = new Impl();
 		aa.impl.buckets = aa.impl.binit[];
 	}
 	aa.impl._keyti = cast() typeid(aaa);
 	return aaa;
 }


 Or it would be fine if I could write something like this: auto 
 aa = new VT[KT]();
`string[string] aa = [];` would be fine, too, but it currently doesn't compile.
Thanks for your clarification (and also in the other thread), so this is an implementation issue for builtin AAs.
Aug 06 2014
parent "Kozzi11" <kozzi11 gmail.com> writes:
On Wednesday, 6 August 2014 at 14:40:00 UTC, Puming wrote:
 Thanks for your clarification (and also in the other thread), 
 so this is an implementation issue for builtin AAs.
https://issues.dlang.org/show_bug.cgi?id=10535
Aug 06 2014