The object operator
Timon Gehr via Digitalmars-d
digitalmars-d at puremagic.com
Fri Aug 14 07:20:56 PDT 2015
On 08/14/2015 06:17 AM, TheHamster wrote:
> For class types, a special operator is defined to return the class
> object for method calls rather than the return value from the call
> itself. The use of the operator places the return types in special
> variables to be accessed easily. The operator is simply a syntax helper
> and is along the lines of UFCS.
>
> e.g.,
>
> class myClass
> {
> Do(int x) { return x + 2; }
>
> }
>
> auto myObj = new myClass();
> assert(@@myObj.Do(3).Do(4).Do(5) == 7);
>
> Of course, such a silly example is not very helpful but demonstrates the
> concept.
>
> To make such a syntax work well, I believe one then needs a further
> operator to access the last return value.
>
> e.g.,
>
> assert(@@myObj.Do(3).Do(@).Do(@2) == 9);
>
> Where the same symbol is used for there return value placeholders and
> indices are used to access nested calls return value with @ defaulting
> to @1.
>
> Essentially such syntax allows for easily doing nested calls.
>
> The only down side is that the operator could only be used on one method
> call at a type in the nesting. (or multiple or parameritized operators
> would be required)
>
> Obviously @ would not be the symbol of choice.
>
>
Close enough? :o)
import std.typecons; // (workaround for lack of seq return)
class MyClass{
int do_(int x){ return x+2; }
}
void main(){
auto myObj=new MyClass();
assert(op(myObj).do_(3).do_(4).do_(5).val==7);
assert(op(myObj).do_(3).do_[$[0]].do_[$[1]].val==9);
}
alias Seq(T...)=T;
struct Op(T,S...){
T wrap;
S vals;
static if(vals.length) alias val=vals[$-1];
template opDispatch(string s){
auto opDispatch(A...)(A args){
static struct Wrap{
Op* outer; // (workaround)
auto opCall(B...)(B args){
static if(is(typeof(mixin(`outer.wrap.`~s)(args))==void)){
mixin(`outer.wrap.`~s)(args);
return Op!(T,S,void[0])(outer.wrap,outer.vals,[]);
}else{
auto cur=mixin(`outer.wrap.`~s)(args);
return Op!(T,S,typeof(cur))(outer.wrap,outer.vals,cur);
}
}
auto opIndex(T...)(T args){ return opCall(args); }
@property opDollar(){ return tuple(outer.vals); }
}
Wrap w;
w.outer=&this;
static if(args.length) return w(args);
else return w;
}
}
}
auto op(T)(T t){
return Op!T(t);
}
More information about the Digitalmars-d
mailing list