Easteregg: riddle of opIndex<op>Assign solved (nearly)
Manfred Nowak
svv1999 at hotmail.com
Tue Feb 13 12:37:46 PST 2007
The solution uses chaining.
Let me show how to implement a class C that mimics a dynamic array,
like "int[10] data" with _all_ possible "opIndex<op>Assign"
overloads.
The usage of such a class should look like this
void main(){
C a= new C;
a[2]= 5;
a[2]+= 3 ;
writefln( a[2]); // prints 8
}
Here I restrict myself to the "opIndexAddAssign".
C holds a dynamic array "data". The length of this array is
initialized by the constructor.
class C{
int[] data;
this( ulong len){
data.length= len;
}
}
To start chaining I need a static "opCall"
class C{
static C opCall(){
return new C;
}
}
To fetch the lvalue I use "opIndex", which stores the index
temporarily:
class C{
int index;
C opIndex( int inx){
index= inx;
return this;
}
}
To fetch the "opIndexAddAssign" I use "opAddAssign", which uses the
temporarily stored lvalue index to assign to the correct position in
the array:
class C{
C opAddAssign(int p){
data[ index]+= p;
return this;
}
}
That's it.
Drawbacks:
1) The natural rvalue "opIndex" is now used up for an lvalue
"opIndex". Therefore a less natural opindex must be defined to return
the natural "opIndex":
class C{
int opIndex( int inx, int){
return data[inx];
}
}
A solution to avoid that additional parameter would be to let the
compiler emit an "opEOM" on being unable to chain any further, which
I have proposed a long time ago:
http://www.digitalmars.com/d/archives/26477.html
2) Chaining of assignments is not possible under this scheme.
-manfred
Full source:
import std.stdio;
class C{
int[] data;
this(int len){
data.length= len;
}
static C opCall() {
return new C(0);
}
int index;
C opIndex( int inx){
index= inx;
return this;
}
int opIndex( int inx, int){
return data[inx];
}
C opAddAssign(int p){
data[ index]+= p;
return this;
}
void opIndexAssign(int p, int x){
data[ x]= p;
}
}
void main(){
C a= new C(10);
a[2]= 5;
a[2]+= 3 ;
writefln( a[2 ,0]); // an ugly point
}
More information about the Digitalmars-d
mailing list