associative arrays: how to insert key and return pointer in 1 step to avoid searching twice

Jon Degenhardt via Digitalmars-d digitalmars-d at puremagic.com
Tue Sep 6 21:12:29 PDT 2016


On Tuesday, 6 September 2016 at 04:32:52 UTC, Daniel Kozak wrote:
> Dne 6.9.2016 v 06:14 mogu via Digitalmars-d napsal(a):
>
>> On Tuesday, 6 September 2016 at 01:17:00 UTC, Timothee Cour 
>> wrote:
>>> is there a way to do this efficiently with associative arrays:
>>>
>>> aa[key]=value;
>>> auto ptr=key in aa;
>>>
>>> without suffering the cost of the 2nd search (compiler should 
>>> know ptr during aa[key]=value but it's not exposed it seems)
>>
>> auto pa = &(aa[key] = value);
>
> Yep, but this is a implementation detail, so be careful

My question as well. Occurs often when I use AAs. The above 
technique works in cases I've tried. However, to Daniel's point, 
from the spec I don't find it clear if it's expected to work. It 
would be useful to have better clarity on this. Anyone have more 
details?

Below is a test for simple class and struct cases, they work at 
present. The template is the type of helper I've wanted. I don't 
trust this particular template, but it'd be useful to know if 
there is a way to get something like this.

--Jon

/* Note: Not general template. Fails for nested classes (compile 
error). */
T* getOrInsertNew(T, K)(ref T[K] aa, K key)
     if (is(T == class) || is(T == struct))
{
     T* p = (key in aa);
     static if (is (T == class))
         return (p !is null) ? p : &(aa[key] = new T());
     else static if (is(T == struct))
         return (p !is null) ? p : &(aa[key] = T());
     else
         static assert(0, "Invalid object type");
}

class  FooClass  { int x = 0; }
struct BarStruct { int x = 0; }

void main(string[] args)
{
     FooClass[string] aaFoo;
     BarStruct[string] aaBar;

     /* Class is reference type. Pointer should be to instance in 
AA. */
     auto foo1 = aaFoo.getOrInsertNew("foo1");
     foo1.x = 100;
     auto foo1b = getOrInsertNew(aaFoo, "foo1");
     assert(foo1 == foo1b && foo1.x == foo1b.x && foo1b.x == 100);

     /* Struct is value type. Will pointer be to instance in AA? */
     auto bar1 = aaBar.getOrInsertNew("bar1");
     bar1.x = 100;
     auto bar1b = getOrInsertNew(aaBar, "bar1");
     assert(bar1 == bar1b && bar1.x == bar1b.x && bar1b.x == 100);

     import std.stdio;
     writeln("Success");
}


More information about the Digitalmars-d mailing list