www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - sorting a mutable array of immutable objects

reply Jeff Thompson <nospam example.com> writes:
I can create a mutable array of immutable objects, thanks to the 
answers to my other question 
https://forum.dlang.org/post/nf57f5$e6v$1 digitalmars.com .

Now I want to sort the array, but the sort function doesn't "see" 
the opCmp in class C. Do I need to define a custom compare 
function for each class where I want to use Rebindable? Or can 
Rebindable itself be updated to "pass through" methods like opCmp?

class C {
   this(int x) immutable { this.x = x; }
   override int opCmp(Object o) const { return x - (cast(C)o).x; }
   int x;
}

void main(string[] args)
{
   auto array = new Rebindable!(immutable(C))[2];
   array[0] = new immutable C(20);
   array[1] = new immutable C(10);
   sort(array); // Error: "Invalid predicate passed to sort: "a < 
b""
}
Apr 20 2016
next sibling parent Jeff Thompson <nospam example.com> writes:
On Wednesday, 20 April 2016 at 09:54:13 UTC, Jeff Thompson wrote:
 I can create a mutable array of immutable objects, thanks to 
 the answers to my other question 
 https://forum.dlang.org/post/nf57f5$e6v$1 digitalmars.com .

 Now I want to sort the array, but the sort function doesn't 
 "see" the opCmp in class C. Do I need to define a custom 
 compare function for each class where I want to use Rebindable? 
 Or can Rebindable itself be updated to "pass through" methods 
 like opCmp?

 class C {
   this(int x) immutable { this.x = x; }
   override int opCmp(Object o) const { return x - (cast(C)o).x; 
 }
   int x;
 }

 void main(string[] args)
 {
   auto array = new Rebindable!(immutable(C))[2];
   array[0] = new immutable C(20);
   array[1] = new immutable C(10);
   sort(array); // Error: "Invalid predicate passed to sort: "a 
 < b""
 }
Actually, maybe my problem is that the opCmp override should take a const Object (for comparing with an immutable object). Is there a way to do that?
Apr 20 2016
prev sibling parent reply Jeff Thompson <nospam example.com> writes:
On Wednesday, 20 April 2016 at 09:54:13 UTC, Jeff Thompson wrote:
 I can create a mutable array of immutable objects, thanks to 
 the answers to my other question 
 https://forum.dlang.org/post/nf57f5$e6v$1 digitalmars.com .

 Now I want to sort the array.
I found a solution, but I'm not sure it is the best way. Instead of overriding opCmp, class C just defines a static comparison to use with sort (which automatically works with Rebindable). Is there a way to do this where I don't need to specify C.isLess every time I sort? class C { this(int x) immutable { this.x = x; } static bool isLess(const C a, const C b) safe pure nothrow { return a.x < b.x; } int x; } void main(string[] args) { auto array = new Rebindable!(immutable(C))[2]; array[0] = new immutable C(20); array[1] = new immutable C(10); sort!(C.isLess)(array); }
Apr 20 2016
parent reply Anonymouse <asdf asdf.com> writes:
On Wednesday, 20 April 2016 at 10:32:42 UTC, Jeff Thompson wrote:
 On Wednesday, 20 April 2016 at 09:54:13 UTC, Jeff Thompson 
 wrote:
 I can create a mutable array of immutable objects, thanks to 
 the answers to my other question 
 https://forum.dlang.org/post/nf57f5$e6v$1 digitalmars.com .

 Now I want to sort the array.
I found a solution, but I'm not sure it is the best way. Instead of overriding opCmp, class C just defines a static comparison to use with sort (which automatically works with Rebindable). Is there a way to do this where I don't need to specify C.isLess every time I sort? class C { this(int x) immutable { this.x = x; } static bool isLess(const C a, const C b) safe pure nothrow { return a.x < b.x; } int x; } void main(string[] args) { auto array = new Rebindable!(immutable(C))[2]; array[0] = new immutable C(20); array[1] = new immutable C(10); sort!(C.isLess)(array); }
int opCmp(immutable Object o) immutable {} That seems to work for me. You want to make it const Object and inout if you want it to work on const and mutable C's as well. Also note that sort (std.algorithm.sorting : sort) returns a range and doesn't sort in place. (Lastly this is probably more at home in the Learn forum.)
Apr 20 2016
next sibling parent Anonymouse <asdf asdf.com> writes:
On Wednesday, 20 April 2016 at 12:34:28 UTC, Anonymouse wrote:
 On Wednesday, 20 April 2016 at 10:32:42 UTC, Jeff Thompson [...]
 Also note that sort (std.algorithm.sorting : sort) returns a 
 range and doesn't sort in place.

 (Lastly this is probably more at home in the Learn forum.)
It does sort in place as well apparently, my bad.
Apr 20 2016
prev sibling parent Jeff Thompson <nospam example.com> writes:
On Wednesday, 20 April 2016 at 12:34:28 UTC, Anonymouse wrote:
 On Wednesday, 20 April 2016 at 10:32:42 UTC, Jeff Thompson 
 wrote:
 On Wednesday, 20 April 2016 at 09:54:13 UTC, Jeff Thompson 
 wrote:
 I can create a mutable array of immutable objects, thanks to 
 the answers to my other question 
 https://forum.dlang.org/post/nf57f5$e6v$1 digitalmars.com .

 Now I want to sort the array.
I found a solution, but I'm not sure it is the best way. Instead of overriding opCmp, class C just defines a static comparison to use with sort (which automatically works with Rebindable). Is there a way to do this where I don't need to specify C.isLess every time I sort? class C { this(int x) immutable { this.x = x; } static bool isLess(const C a, const C b) safe pure nothrow { return a.x < b.x; } int x; } void main(string[] args) { auto array = new Rebindable!(immutable(C))[2]; array[0] = new immutable C(20); array[1] = new immutable C(10); sort!(C.isLess)(array); }
int opCmp(immutable Object o) immutable {}
Thanks for a better solution, but I never would have thought to try opCmp without "override" since I assumed that sort was looking for the opCmp defined by Object. So many counter-intuitive mysteries in D. That's why this forum is indipensable.
Apr 20 2016