www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - some mixin utilities

reply "Dan" <dbdavidson yahoo.com> writes:
I've created some mixins that I think will help me with structs, 
and being new to D would like some constructive 
criticism/suggestions on the code. The code is at 
https://github.com/patefacio/d-help/blob/master/d-help/opmix/mix.d

Some questions:
- I have done a bit of casting in a few places and would like to 
know if they are safe.
- I'm no hashing expert so any suggestions on approach 
appreciated.
- If mixin(Dup) encounters a plain pointer and it can create a 
target on the heap it does. Is this safe?
- The focus is structs because for now I'm afraid of classes. 
Could they be incorporated or would that be a can of worms?

Hopefully the comments convey the intent well enough and if there 
are better approaches please let me know.
Any feedback appreciated.

Thanks
Dan
Nov 05 2012
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Dan:

 https://github.com/patefacio/d-help/blob/master/d-help/opmix/mix.d

 Overcomes this problem:
 writeln( [1: 2] == [1: 2] ); // true
 writeln(S([1: 2]) == S([1: 2])); // false

That will be fixed in the core language. Bye, bearophile
Nov 05 2012
prev sibling next sibling parent Tobias Pankrath <lists pankrath.net> writes:
On 05.11.2012 18:30, Dan wrote:
 I've created some mixins that I think will help me with structs, and
 being new to D would like some constructive criticism/suggestions on the
 code. The code is at
 https://github.com/patefacio/d-help/blob/master/d-help/opmix/mix.d

 Some questions:
 - I have done a bit of casting in a few places and would like to know if
 they are safe.
 - I'm no hashing expert so any suggestions on approach appreciated.
 - If mixin(Dup) encounters a plain pointer and it can create a target on
 the heap it does. Is this safe?
 - The focus is structs because for now I'm afraid of classes. Could they
 be incorporated or would that be a can of worms?

 Hopefully the comments convey the intent well enough and if there are
 better approaches please let me know.
 Any feedback appreciated.

 Thanks
 Dan

I like the general style. However this provokes a invinite loop: ----- struct A { A* other; } import std.stdio; void main() { A a, b; b.other = &a; a.other = &b; writeln(typesDeepEqual(a, b)); } ----- And I would find the comparison more useful, if it uses the user defined opEquals for a field if there is one.
Nov 05 2012
prev sibling parent "Dan" <dbdavidson yahoo.com> writes:
On Monday, 5 November 2012 at 18:53:20 UTC, Tobias Pankrath wrote:


 I like the general style. However this provokes a invinite loop:

Good catch. Fixed. There may be more complex scenarios of nested locking references that cause similar loop.
 And I would find the comparison more useful, if it uses the 
 user defined opEquals for a field if there is one.

Good point, this could be changed easily enough. The point for OpEquals was to use this for the issues pointed out in the thread. A benefit of just always using typesDeepEqual within typesDeepEqual is if I forget a mixin(OpEquals) in some class A, agreggated in some B, I'm still covered. So, below my deep equals works as expected for B even though A has no suitable opEquals. I think this should work even if I do not own A, which is a plus. The downside is if there is a custom opEquals for a struct that is more efficient it wont get called. As bearophile pointed out this issue will change anyway. At that point I think the OpEquals becomes mute. I hope I'm covered by just turning its implementation into a no-op and my classes don't change. Thanks Dan -------------- struct A { void pushOne() { i ~= 1; } private: int[] i; } struct B { mixin(OpEquals); A a; } void main() { A a1, a2; a1.pushOne(); a2.pushOne(); B b1 = {a1}, b2 = {a2}; writeln(a1==a2); // false writeln(b1==b2); // true }
Nov 05 2012