| Thread overview | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
October 03, 2011 Re: Dealing with property function and operator overloads | ||||
|---|---|---|---|---|
| ||||
Looks like I can use some D tricks for this:
import std.stdio;
struct Point
{
int x, y;
void opOpAssign(string op)(int rhs)
{
mixin ("x = x " ~ op ~ " rhs;");
mixin ("y = y " ~ op ~ " rhs;");
}
}
struct Wrapped(T)
{
T payload;
alias payload this;
void delegate() dg;
@property void changed(void delegate() dg)
{
this.dg = dg;
}
void opOpAssign(string op)(int rhs)
{
payload.opOpAssign!op(rhs);
dg();
}
}
struct Wrapper
{
this(int x)
{
point.changed = ¬ifyChanged;
}
void notifyChanged()
{
writeln("changed!");
}
public Wrapped!Point point;
}
void main()
{
auto wrap = Wrapper(1);
wrap.point = Point(1, 1);
assert(wrap.point == Point(1, 1));
wrap.point += 1;
assert(wrap.point == Point(2, 2));
}
Pretty cool. I might even be able to write a Wrapped() template that searches for all operator overloads of a type and creates forwarding functions.
| ||||
October 03, 2011 Re: Dealing with property function and operator overloads | ||||
|---|---|---|---|---|
| ||||
Forgot to add an opAssign in Wrapped as well:
void opAssign(T)(T rhs)
{
payload = rhs;
dg();
}
That takes care of assigning and ops that change the object's state.
| ||||
October 03, 2011 Re: Dealing with property function and operator overloads | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | On Mon, 03 Oct 2011 14:57:33 -0400, Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote:
> Looks like I can use some D tricks for this:
>
> import std.stdio;
>
> struct Point
> {
> int x, y;
>
> void opOpAssign(string op)(int rhs)
> {
> mixin ("x = x " ~ op ~ " rhs;");
> mixin ("y = y " ~ op ~ " rhs;");
> }
> }
Probably slightly off topic, but be very careful with operator overloads without using constraints.
For example, I can do some weird things to your struct:
Point p;
p.opOpAssign!"*x; y+="(5);
I suspect operator overloads are going to be a large hole in the interface design of many objects, but at least they won't be exploitable once compiled.
-Steve
| |||
October 03, 2011 Re: Dealing with property function and operator overloads | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 10/3/11, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
> Probably slightly off topic, but be very careful with operator overloads without using constraints.
>
> For example, I can do some weird things to your struct:
>
> Point p;
>
> p.opOpAssign!"*x; y+="(5);
>
> I suspect operator overloads are going to be a large hole in the interface design of many objects, but at least they won't be exploitable once compiled.
>
> -Steve
>
Generally when I post examples I won't add any constraints, this is to make it easier for other people to read the code. All of the ops have constraints in my code.
| |||
October 03, 2011 Re: Dealing with property function and operator overloads | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | On Mon, 03 Oct 2011 16:07:19 -0400, Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote:
> On 10/3/11, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
>> Probably slightly off topic, but be very careful with operator overloads
>> without using constraints.
>>
>> For example, I can do some weird things to your struct:
>>
>> Point p;
>>
>> p.opOpAssign!"*x; y+="(5);
>>
>> I suspect operator overloads are going to be a large hole in the interface
>> design of many objects, but at least they won't be exploitable once
>> compiled.
>>
>> -Steve
>>
>
> Generally when I post examples I won't add any constraints, this is to
> make it easier for other people to read the code. All of the ops have
> constraints in my code.
Even so, it's better for people who are not familiar with the language to see correct code vs. code open to exploitation.
I've argued in the past that we need some boilerplate constraints for operators (like isValidOpString). Can't remember where that stands.
-Steve
| |||
October 03, 2011 Re: Dealing with property function and operator overloads | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 10/3/11, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
> Even so, it's better for people who are not familiar with the language to see correct code vs. code open to exploitation.
I can see your point. I'll make some simple constraints when I post code samples like this from now on.
| |||
October 03, 2011 Re: Dealing with property function and operator overloads | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Steven Schveighoffer:
> I suspect operator overloads are going to be a large hole in the interface design of many objects, but at least they won't be exploitable once compiled.
Just after the introduction of the new operator overload syntax I have suggested to introduce strict tests to statically forbid strings that don't contain one of the correct accepted operators. Walter didn't appreciate this idea :-(
Bye,
bearophile
| |||
October 04, 2011 Re: Dealing with property function and operator overloads | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | On 2011-10-03 20:57, Andrej Mitrovic wrote: > Looks like I can use some D tricks for this: > > import std.stdio; > > struct Point > { > int x, y; > > void opOpAssign(string op)(int rhs) > { > mixin ("x = x " ~ op ~ " rhs;"); > mixin ("y = y " ~ op ~ " rhs;"); > } > } > > struct Wrapped(T) > { > T payload; > alias payload this; > void delegate() dg; > > @property void changed(void delegate() dg) > { > this.dg = dg; > } > > void opOpAssign(string op)(int rhs) > { > payload.opOpAssign!op(rhs); > dg(); > } > } > > struct Wrapper > { > this(int x) > { > point.changed =¬ifyChanged; > } > > void notifyChanged() > { > writeln("changed!"); > } > > public Wrapped!Point point; > } > > > void main() > { > auto wrap = Wrapper(1); > wrap.point = Point(1, 1); > assert(wrap.point == Point(1, 1)); > > wrap.point += 1; > assert(wrap.point == Point(2, 2)); > } > > Pretty cool. I might even be able to write a Wrapped() template that > searches for all operator overloads of a type and creates forwarding > functions. No "alias this" in the wrapper? -- /Jacob Carlborg | |||
October 04, 2011 Re: Dealing with property function and operator overloads | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On 10/4/11, Jacob Carlborg <doob@me.com> wrote: > No "alias this" in the wrapper? I shouldn't have named it Wrapper, you could better think of it as a Widget with a position field, if that position is changed (and not just read from) then some kind of repaint mechanism would be invoked. However I shouldn't invoke such a mechanism if the value of the payload hasn't actually changed, so I should have a check inside of opAssign/opOpAssign. Additionally, "payload" might have its own functions which change its internal state. So to work around this, I would have to introduce opDispatch as well. Here's what I have so far: http://codepad.org/uSEMcD0g In the sample the Point structure is missing operator overloads, but if it had them they would be trapped by TrackChanges. | |||
October 05, 2011 Re: Dealing with property function and operator overloads | ||||
|---|---|---|---|---|
| ||||
Also I can use a forward function for toString, I didn't realize this until now:
string toString() { return to!string(payload); }
| ||||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply