Proof of concept - library AA

IgorStepanov via Digitalmars-d digitalmars-d at puremagic.com
Wed May 27 10:16:51 PDT 2015


On Wednesday, 27 May 2015 at 14:12:02 UTC, Martin Nowak wrote:
> On Sunday, 24 May 2015 at 15:13:41 UTC, Vladimir Panteleev 
> wrote:
>> Could you elaborate on what these magic semantics are?
>>
>>> and no easy solution exists for the ++aa[key1][key2] case.
>>
>> Is this specific to the pre-increment? aa[key1][key2]++ is 
>> generally a useful pattern.
>
> This applies to pre/post increment as well as assignment and 
> opOpAssign.
> When an lvalue is needed the compiler will call a special 
> runtime function GetX to obtain an lvalue for aa[key1], i.e. 
> the entry will be default initialized iff missing.
> If the expression is an rvalue though (aa[key1][key2]), a 
> missing key1 will trigger a range error.
> In an opIndex(Key) you have no idea whether the whole 
> expression I an lvalue or an rvalue.
>
> IIRC the construction/assignment of a value is also handled 
> specifically.

BTW, may be we should create DIP about opIndex extending?
What do you want about following?
Let, if opIndex is template, and the first template argument is a 
bool value, compiler should pass true, if this is a part of 
l-value expression:

struct Foo
{
     Foo[] children;
     this(int value)
     {
         this.value = value;
     }
     int value;

     ref Foo opIndex(bool lvl)(size_t idx)
     {
         if (idx < children.length)
             return children[idx];
         static if (lvl)
         {
             children.length = idx + 1;
             return children[idx];
         }
         else
         {
             throw new Exception("out of bounds");
         }
     }
}


Foo f;
f[5][3] = Foo(42); translates to
     f.opIndex!(true)(5).opIndex!(true)(3) = Foo(42);

auto x = f[5][4]; translates to
     auto x = f.opIndex!(false)(5).opIndex!(false)(3);


More information about the Digitalmars-d mailing list