"inout return type" and "inout variable"
Regan Heath
regan at netwin.co.nz
Sat Mar 18 03:51:48 PST 2006
On Sat, 18 Mar 2006 11:02:53 +0000 (UTC), Hong Wing
<Hong_member at pathlink.com> wrote:
> Hi, yes! exactly that's the problem for me, I am writing a protein
> modeling software and use vector and matrices heavily, and I start to
> see things like:*result = (*v1) + (*v2) * (*v3)
>
> notice how all the * * * starts to make things very cluttered.
Yeah, I see the problem.
You could call the operator overloads directly, eg.
result = v1.opAdd(v2.opMul(v3));
but that's almost as bad.
If you have opAdd(T *) and opMul(T *) then doesn't this work:
*result = v1 + *v2 * v3;
I just tried it, and it seems to (example below).
However, isn't your bigger problem all the temporary structs being created
and copied in the examples above?
eg. (*v2) * (*v3) produces a temporary struct, which is then added to
(*v1) producing another temporary struct, which is then copied to *result.
Can the compiler ever optimise any of those temporaries away?
Example:
*result = (*v1) + (*v2) * (*v3)
could be rewritten:
*result = *v3; //copy struct
*result *= v2; //opMulAssign(T *rhs)
*result += v1; //opAddAssign(T *rhs)
Here the opXAssign operators can access the rhs and add/mul them to/with
result directly to avoid the temporary struct copy.
Example:
import std.string;
import std.stdio;
struct Foo
{
int x;
int y;
int z;
char[] toString() { return
"("~std.string.toString(x)~","~std.string.toString(y)~","~std.string.toString(z)~")";
}
Foo opAdd(Foo rhs)
{
return opAdd(&rhs);
}
Foo opAdd(Foo* rhs)
{
Foo n;
n.x = x+rhs.x;
n.y = y+rhs.y;
n.z = z+rhs.z;
return n;
}
Foo opMul(Foo rhs)
{
return opAdd(&rhs);
}
Foo opMul(Foo* rhs)
{
Foo n;
n.x = x*rhs.x;
n.y = y*rhs.y;
n.z = z*rhs.z;
return n;
}
Foo* opAddAssign(Foo *rhs)
{
x += rhs.x;
y += rhs.y;
z += rhs.z;
return this;
}
Foo* opMulAssign(Foo *rhs)
{
x *= rhs.x;
y *= rhs.y;
z *= rhs.z;
return this;
}
}
class Bar
{
private:
Foo m_foo;
public:
Foo* foo() { return &m_foo; }
Foo* foo(Foo* value) { m_foo = *value; return foo(); }
Foo* foo(Foo value) { m_foo = value; return foo(); }
}
void main()
{
Foo* a = new Foo();
Bar b = new Bar();
Bar c = new Bar();
Bar d = new Bar();
b.foo.x = 1;
b.foo.y = 1;
b.foo.z = 1;
c.foo.x = 2;
c.foo.y = 2;
c.foo.z = 2;
d.foo.x = 3;
d.foo.y = 3;
d.foo.z = 3;
*a = b.foo + *c.foo * d.foo;
writefln("%s",(*a).toString());
*a = *d.foo;
*a *= c.foo;
*a += b.foo;
writefln("%s",(*a).toString());
}
Regan
More information about the Digitalmars-d
mailing list