On 2009-10-15 17:51:56 +0200, "Robert Jacques" <sandf...@jhu.edu> said:
On Thu, 15 Oct 2009 04:48:57 -0400, Fawzi Mohamed <fmoha...@mac.com> wrote:
[...]
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?
I suppose you would like it ;)
// example 1
class Matrix(T){
T opIndex(size_t i,size_t j){
if (has_(i,j)){
return data[index(i,j)];
} else {
return cast(T)0;
}
}
ref T opIndexLhs(size_t i,size_t j){
if (has_(i,j)){
return &data[index(i,j)];
} else {
//alloc new place and set things so that index(i,j) returns it
return &data[index(i,j)];
}
}
}
then
m[3,4]+=4.0;
would be converted in
m.opIndexLhs(3,4)+=4.0;
typically with just one method (opIndexLhs) all += -=,... are covered
if one needs more control
class AbsMatrix(T){
T opIndex(size_t i,size_t j){
if (has_(i,j)){
return data[index(i,j)];
} else {
return cast(T)0;
}
}
struct Setter{
T* pos;
void opAddAssign(T val){
*pos+=abs(val);
}
}
Setter opIndexLhs(size_t i,size_t j){
Setter pos;
if (has_(i,j)){
res.pos=&data[index(i,j)];
} else {
//alloc new place and set things so that index(i,j) returns it
res.pos=&data[index(i,j)];
}
return res;
}
}
if one does not allow ref T as return type then one can return a pointer and do
static if(is(typeof(*m.opIndexLhs(3,4))))
*m.opIndexLhs(3,4)+=4.0;
else
m.opIndexLhs(3,4)+=4.0;
so that the trick with the struct is still possible.