A possible solution for the opIndexXxxAssign morass

Fawzi Mohamed fmohamed at mac.com
Thu Oct 15 01:48:57 PDT 2009


On 2009-10-14 23:09:26 +0200, "Robert Jacques" <sandford at jhu.edu> said:

> On Wed, 14 Oct 2009 16:49:28 -0400, Andrei Alexandrescu  
> <SeeWebsiteForEmail at erdani.org> wrote:
> 
>> Jason House wrote:
>>> Bill Baxter Wrote:
>>> 
>>>> On Wed, Oct 14, 2009 at 7:42 AM, Jason House
>>>> <jason.james.house at gmail.com> wrote:
>>>>> Andrei Alexandrescu Wrote:
>>>>> 
>>>>>> Right now we're in trouble with operators: opIndex and opIndexAssign
>>>>>> don't seem to be up to snuff because they don't catch operations like
>>>>>> 
>>>>>> a[b] += c;
>>>>>> 
>>>>>> with reasonable expressiveness and efficiency.
>>>>> I would hope that *= += /= and friends could all be handled  
>>>>> efficiently with one function written by the programmer. As I see it,  
>>>>> there are 3 basic steps:
>>>>> 1. Look up a value by index
>>>>> 2. Mutate the value
>>>>> 3. Store the result
>>>> And as Chad J reminds us, same goes for in-place property mutations
>>>> like  a.b += c.
>>>> It's just a matter of  accessing  .b  vs .opIndex(b).   And really
>>>> same goes for any function  a.memfun(b) += c could benefit from the
>>>> same thing (a.length(index)+=3 anyone?)
>>>> 
>>>>> it's possible to use opIndex for #1 and opIndexAssign for #3, but  
>>>>> that's not efficient. #1 and #3 should be part of the same function,  
>>>>> but I think #2 shouldnot be. What about defining an opIndexOpOpAssign  
>>>>> that accepts a delegate for #2 and then use compiler magic to  
>>>>> specialize/inline it?
>>>> It could also be done using a template thing to inject the "mutate the
>>>> value" operation:
>>>  The only issue with templates is that they're never virtual
>> 
>> You can make virtuals out of templates, but not templates out of  
>> virtuals. I think Walter is now inclined to look at a template-based  
>> solution for operator overloading. That would save a mighty lot of code 
>>  without preventing classes that prefer virtual dispatch from doing so.
>> 
>> Andrei
> 
> I've done something similar for a SmallVec struct. Most of the operator 
>  overloads are actually aliases of templated functions (one each for  
> uni-ops, bi-ops, bi-op_r and opassign)

I would really like a solution to all the overloading ops, as I missed 
them in NArray, I think that some small rewriting is ok, but it must be 
*small*, no magic as already said by other numerics can be tricky.
Also Andrei proposal seem workable, but there is also another solution:

Note that a ref return for opIndex, could work in most situations.
As Bill correctly pointed out sparse matrix offer the most challenging 
example, there one wants to have two different functions: opIndex and 
opIndexLhs, the second being called when the index is on the left hand 
side of an assignment, so that reading a 0 entry in a matrix returns 0, 
whereas assigning it allocates place for it.
This makes it slightly more complex to control what is being assigned 
(as you need to return a structure overloading opXAssign, but I think 
it would be ok in most cases.

Fawzi




More information about the Digitalmars-d mailing list