Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
September 03, 2012 Can i rewrite methods in one line? | ||||
---|---|---|---|---|
| ||||
struct Vector(T, uint size) { static assert(size >= 2 && size <= 4); static assert(__traits(isFloating, T); /// Vector components union { T[size] array = 0; struct { static if(size == 1) T x; static if(size == 2) T x, y; static if(size == 3) T x, y, z; static if(size == 4) T x, y, z, w; } } this (T rhs) { array[] = rhs; } this (T[] components...) { array[] = components[]; } this (T* components) { array[] = components[0..size]; } this (T[size] components) { array[] = components[]; } this (Vector rhs) { array[] = rhs.array[]; } Vector opUnary(string op) () if (op == "-") { Vector tmp; tmp.array[] = -array[]; return tmp; } Vector opBinary(string op) (Vector rhs) if(op == "+" || op == "-" || op == "*" || op == "/") { Vector tmp; tmp.array[] = mixin("array[] "~op~" rhs.array[]"); return tmp; } Vector opBinary(string op) (T rhs) if(op == "+" || op == "-" || op == "*" || op == "/") { Vector tmp; tmp.array[] = mixin("array[] "~op~" rhs"); return tmp; } ref Vector opOpAssign(string op) (Vector rhs) if(op == "+" || op == "-" || op == "*" || op == "/") { mixin("array[] "~op~"= rhs.array[];"); return this; } ref Vector opOpAssign(string op) (T rhs) if(op == "+" || op == "-" || op == "*" || op == "/") { mixin("array[] "~op~"= rhs;"); return this; } } I want to rewrite it in something like this: struct Vector(T, uint size) { static assert(size >= 2 && size <= 4); static assert(__traits(isFloating, T); /// Vector components union { T[size] array = 0; struct { static if(size == 1) T x; static if(size == 2) T x, y; static if(size == 3) T x, y, z; static if(size == 4) T x, y, z, w; } } this (T rhs) { array[] = rhs; } this (T[] components...) { array[] = components[]; } this (T* components) { array[] = components[0..size]; } this (T[size] components) { array[] = components[]; } this (Vector rhs) { array[] = rhs.array[]; } Vector opUnary(string op) () if (op == "-") { return Vector(-array); } Vector opBinary(string op) (Vector rhs) if(op == "+" || op == "-" || op == "*" || op == "/") { return Vector(mixin("array[] "~op~" rhs.array[]")); } Vector opBinary(string op) (T rhs) if(op == "+" || op == "-" || op == "*" || op == "/") { return Vector(mixin("array[] "~op~" rhs")); } ref Vector opOpAssign(string op) (Vector rhs) if(op == "+" || op == "-" || op == "*" || op == "/") { return Vector(mixin("array[] "~op~"= rhs.array[]")); } ref Vector opOpAssign(string op) (T rhs) if(op == "+" || op == "-" || op == "*" || op == "/") { return Vector(mixin("array[] "~op~"= rhs")); } } Main goal is to return and constuct in one place. Can I do so? I now that there will take place compiller optimisations and both versions will be the same, but what if not? PS: Sorry for my english. |
September 03, 2012 Re: Can i rewrite methods in one line? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ivan Agafonov | In general, yes, you can construct and return at the same time. As you said, in a language like D where source code is almost always visible, the compiler can apply many optimization techniques. However, some of your operators ended up having semantic differences. opOpAssign used to return a reference to this object: ref Vector opOpAssign(string op) (Vector rhs) if(op == "+" || op == "-" || op == "*" || op == "/") { mixin("array[] "~op~"= rhs.array[];"); return this; } opOpAssign now returns a reference to a newly-created temporary object: ref Vector opOpAssign(string op) (Vector rhs) if(op == "+" || op == "-" || op == "*" || op == "/") { return Vector(mixin("array[] "~op~"= rhs.array[]")); } (It is the same for the other opOpAssign.) Ali |
September 03, 2012 Re: Can i rewrite methods in one line? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Monday, 3 September 2012 at 02:40:09 UTC, Ali Çehreli wrote:
> In general, yes, you can construct and return at the same time. As you said, in a language like D where source code is almost always visible, the compiler can apply many optimization techniques.
>
> However, some of your operators ended up having semantic differences. opOpAssign used to return a reference to this object:
>
> ref Vector opOpAssign(string op) (Vector rhs)
> if(op == "+" || op == "-" || op == "*" || op == "/")
> {
> mixin("array[] "~op~"= rhs.array[];");
> return this;
> }
>
> opOpAssign now returns a reference to a newly-created temporary object:
>
> ref Vector opOpAssign(string op) (Vector rhs)
> if(op == "+" || op == "-" || op == "*" || op == "/")
> { return Vector(mixin("array[] "~op~"= rhs.array[]")); }
>
> (It is the same for the other opOpAssign.)
>
> Ali
I made a mistake here. This operators have already "onelined" :
ref Vector opAssign(Vector rhs) { array[] = rhs.array[]; return this; }
ref Vector opAssign(T[size] rhs) { array[] = rhs[]; return this; }
ref Vector opOpAssign(string op) (T[size] rhs) if(op == "+" || op == "-" || op == "*" || op == "/")
{ mixin("array[] "~op~"= rhs[];"); return this; }
ref Vector opOpAssign(string op) (Vector rhs) if(op == "+" || op == "-" || op == "*" || op == "/")
{ mixin("array[] "~op~"= rhs.array[];"); return this; }
ref Vector opOpAssign(string op) (T rhs) if(op == "+" || op == "-" || op == "*" || op == "/")
{ mixin("array[] "~op~"= rhs;"); return this; }
But i can't write something like this:
return Vector(mixin("array[] "~op~"= rhs.array[]"));
because array[] op= rhs.array[] is not a right expression it does not return an array, it can only be used in assigment to slice like this[]. And expression array op= rhs.array does not make sense too.
|
September 03, 2012 Re: Can i rewrite methods in one line? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ivan Agafonov | Yeah! I did it! How about this solution? What do you think? static assert(size >= 2 && size <= 4); static assert(__traits(isFloating, T)); /// Vector components union { T[size] array = 0; struct { static if(size == 2) T x, y; static if(size == 3) T x, y, z; static if(size == 4) T x, y, z, w; } } this (T rhs) { array[] = rhs; } this (T[] components...) { array[] = components[]; } this (T* components) { array[] = components[0..size]; } this (T[size] components) { array[] = components[]; } this (Vector rhs) { array[] = rhs.array[]; } private static bool isMathOp(string op) { return (op == "+" || op == "-" || op == "*" || op == "/"); } Vector opUnary(string op) () if (op == "-") { return Vector(array.dup[] = -array[]); } Vector opBinary(string op) (Vector rhs) if(isMathOp(op)) { return Vector(mixin("array.dup[] "~op~"= rhs.array[]")); } Vector opBinary(string op) (T rhs) if(isMathOp(op)) { return Vector(mixin("array.dup[] "~op~"= rhs")); } ref Vector opAssign(Vector rhs) { array[] = rhs.array[]; return this; } ref Vector opAssign(T[size] rhs) { array[] = rhs[]; return this; } ref Vector opOpAssign(string op) (T[size] rhs) if(isMathOp(op)) { mixin("array[] "~op~"= rhs[];"); return this; } ref Vector opOpAssign(string op) (Vector rhs) if(isMathOp(op)) { mixin("array[] "~op~"= rhs.array[];"); return this; } ref Vector opOpAssign(string op) (T rhs) if(isMathOp(op)) { mixin("array[] "~op~"= rhs;"); return this; } ... Some other op's ... } |
September 03, 2012 Re: Can i rewrite methods in one line? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ivan Agafonov | On 09/02/2012 07:57 PM, Ivan Agafonov wrote: > ref Vector opOpAssign(string op) (T rhs) if(op == "+" || op == "-" || op > == "*" || op == "/") > { mixin("array[] "~op~"= rhs;"); return this; } > > But i can't write something like this: > return Vector(mixin("array[] "~op~"= rhs.array[]")); You meant it for opOpAssign, right? opOpAssign must 'return this', not a new object. Otherwise chaining operators would be confusing: (v0 += v1) *= v2; If the += operation could return a new object (which it can't), then *= would be operating on that. So your existing version is correct: ref Vector opOpAssign(string op) (T[size] rhs) if(op == "+" || op == "-" || op == "*" || op == "/") { mixin("array[] "~op~"= rhs[];"); return this; } But if you don't care about chained operations you can also return void: void opOpAssign(string op) (T[size] rhs) if(op == "+" || op == "-" || op == "*" || op == "/") { mixin("array[] "~op~"= rhs[];"); } Ali |
September 03, 2012 Re: Can i rewrite methods in one line? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ivan Agafonov | Note that opBinary operators uses op= instead of op : Vector opBinary(string op) (Vector rhs) if(isMathOp(op)) { return Vector(mixin("array.dup[] "~op~"= rhs.array[]")); } Vector opBinary(string op) (T rhs) if(isMathOp(op)) { return Vector(mixin("array.dup[] "~op~"= rhs")); } |
September 03, 2012 Re: Can i rewrite methods in one line? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ivan Agafonov | Note that opBinary operators uses op= instead of op : Vector opBinary(string op) (Vector rhs) if(isMathOp(op)) { return Vector(mixin("array.dup[] "~op~"= rhs.array[]")); } Vector opBinary(string op) (T rhs) if(isMathOp(op)) { return Vector(mixin("array.dup[] "~op~"= rhs")); } |
Copyright © 1999-2021 by the D Language Foundation