A possible solution for the opIndexXxxAssign morass

Robert Jacques sandford at jhu.edu
Thu Oct 15 08:51:56 PDT 2009


On Thu, 15 Oct 2009 04:48:57 -0400, Fawzi Mohamed <fmohamed at mac.com> wrote:

> 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
>

Would you like some example code?



More information about the Digitalmars-d mailing list