Skip to content

Commit

Permalink
Merge pull request #363 from jmdavis/redblacktree
Browse files Browse the repository at this point in the history
Fix for Bug #6472. Make RedBlackTree's removeKey work with strings.
  • Loading branch information
andralex committed Feb 5, 2012
2 parents e859e40 + b646e0e commit da2cf56
Showing 1 changed file with 54 additions and 3 deletions.
57 changes: 54 additions & 3 deletions std/container.d
Original file line number Diff line number Diff line change
Expand Up @@ -4169,7 +4169,7 @@ struct RBNode(V)
* ignored on insertion. If duplicates are allowed, then new elements are
* inserted after all existing duplicate elements.
*/
class RedBlackTree(T, alias less = "a < b", bool allowDuplicates = false)
final class RedBlackTree(T, alias less = "a < b", bool allowDuplicates = false)
if(is(typeof(binaryFun!less(T.init, T.init))))
{
alias binaryFun!less _less;
Expand Down Expand Up @@ -4817,7 +4817,19 @@ rbt.removeKey(1, 1, 0);
assert(std.algorithm.equal(rbt[], [5]));
--------------------
+/
size_t removeKey(U)(U[] elems...)
size_t removeKey(U...)(U elems)
if(allSatisfy!(isImplicitlyConvertibleToElem, U))
{
Elem[U.length] toRemove;

foreach(i, e; elems)
toRemove[i] = e;

return removeKey(toRemove[]);
}

/++ Ditto +/
size_t removeKey(U)(U[] elems)
if(isImplicitlyConvertible!(U, Elem))
{
immutable lenBefore = length;
Expand All @@ -4839,17 +4851,26 @@ assert(std.algorithm.equal(rbt[], [5]));
size_t removeKey(Stuff)(Stuff stuff)
if(isInputRange!Stuff &&
isImplicitlyConvertible!(ElementType!Stuff, Elem) &&
!is(Stuff == Elem[]))
!isDynamicArray!Stuff)
{
//We use array in case stuff is a Range from this RedBlackTree - either
//directly or indirectly.
return removeKey(array(stuff));
}

//Helper for removeKey.
private template isImplicitlyConvertibleToElem(U)
{
enum isImplicitlyConvertibleToElem = isImplicitlyConvertible!(U, Elem);
}

static if(doUnittest) unittest
{
auto rbt = new RedBlackTree(5, 4, 3, 7, 2, 1, 7, 6, 2, 19, 45);

//The cast(Elem) is because these tests are instantiated with a variety
//of numeric types, and the literals are all int, which is not always
//implicitly convertible to Elem (e.g. short).
static if(allowDuplicates)
{
assert(rbt.length == 11);
Expand Down Expand Up @@ -5133,6 +5154,36 @@ unittest
assert(std.algorithm.equal(rbt[], [5]));
}

//Tests for removeKey
unittest
{
{
auto rbt = redBlackTree(["hello", "world", "foo", "bar"]);
assert(equal(rbt[], ["bar", "foo", "hello", "world"]));
assert(rbt.removeKey("hello") == 1);
assert(equal(rbt[], ["bar", "foo", "world"]));
assert(rbt.removeKey("hello") == 0);
assert(equal(rbt[], ["bar", "foo", "world"]));
assert(rbt.removeKey("hello", "foo", "bar") == 2);
assert(equal(rbt[], ["world"]));
assert(rbt.removeKey(["", "world", "hello"]) == 1);
assert(rbt.empty);
}

{
auto rbt = redBlackTree([1, 2, 12, 27, 4, 500]);
assert(equal(rbt[], [1, 2, 4, 12, 27, 500]));
assert(rbt.removeKey(1u) == 1);
assert(equal(rbt[], [2, 4, 12, 27, 500]));
assert(rbt.removeKey(cast(byte)1) == 0);
assert(equal(rbt[], [2, 4, 12, 27, 500]));
assert(rbt.removeKey(1, 12u, cast(byte)27) == 2);
assert(equal(rbt[], [2, 4, 500]));
assert(rbt.removeKey([cast(short)0, cast(short)500, cast(short)1]) == 1);
assert(equal(rbt[], [2, 4]));
}
}

unittest
{
void test(T)()
Expand Down

0 comments on commit da2cf56

Please sign in to comment.