On Sunday, 18 March 2018 at 17:21:58 UTC, Steven Schveighoffer
wrote:
On 3/18/18 8:34 AM, Viktor wrote:
Hey,
I'm trying to convert an old legacy app to D and have a couple
of questions. It has been a very fun weekend!
First, I could not make std.container.rbtree use a delegate
for a comparator. The docs say it should be possible, but I
got a weird error.
I tracked it down to RedBlackTreee.opEquals() using explicit
function when calling equals():
return equal!(function(Elem a, Elem b) => !_less(a,b) &&
!_less(b,a))(thisRange, thatRange);
When I removed the "function" things started compiling (I have
yet to test the code due to question #2 below). I've done a
dub -b unittest without issues so it might be OK.
So, the first...several questions are: do you think this
change is safe and should I raise an issue in the bugzilla or
do a PR for it on github?
Yes, seems like an oversight. RedBlackTree.opEquals was added
almost 6 years ago, and it's possible this wouldn't have worked
back then (https://github.com/dlang/phobos/pull/900)
Should it include a new unittest that makes sure rbtree can be
instantiated with a delegate?
Definitely. Thanks for thinking of this!
The other part I'm still struggling with is about auto types.
Can I store the rbtree type in the following class so it can
be used from another method?
class Indexer(T, alias pred)
{
alias RBType = RedBlackTree!(uint, (a, b) => comp(a, b));
this(T storage)
{
this.storage = storage;
this.index = new RBType();
}
void dumpIndex()
{
// how to get my dirty hands on the index here?
// answer: just use it?
}
bool comp(uint i1, uint i2)
{
auto rec1 = storage[i1];
auto rec2 = storage[i2];
return pred(rec1, rec2);
}
private T storage;
RBType index;
}
-Steve
Hi Steve, thanks for replying!
I've also noticed that RedBlackTree.opEquals() is like this from
the initial pull request and was wondering if noone has been
using a delegate and why...
On the second topic, I've tried that and it doesn't work. I have
a minimal test program that shows the issue.
https://run.dlang.io/is/WNF78H
onlineapp.d(15): Error: need this for less of type bool(int a,
int b)
onlineapp.d(15): instantiated from here: Generic!((a, b)
=> less(a, b))
If I try using an explicit delegate in the alias:
onlineapp.d(15): Error: delegate `onlineapp.Custom.__dgliteral6`
cannot be class members
onlineapp.d(15): instantiated from here: Generic!(delegate
(a, b) => less(a, b))
That seems reasonable to me, since the delegate needs a frame
(for the this pointer) and there is no frame at that point.
I think in the end I'll need to plant an interface that RBTree
will implement and use the interface instead.
The code in question:
class Generic(alias pred)
{
void add(int a, int b)
{
import std.stdio : writeln;
if (pred(a,b))
writeln(a);
else
writeln(b);
}
}
class Custom
{
alias MyGeneric = Generic!( (a,b) => less(a,b) );
private MyGeneric g;
this ()
{
g = new MyGeneric;
}
void test()
{
g.add(5, 6);
}
bool less(int a, int b)
{
import std.stdio : writeln;
writeln("Yup");
return a < b;
}
}
void main()
{
auto t = new Custom;
t.test;
}