mirror of
https://github.com/dlang/phobos.git
synced 2025-05-08 20:19:43 +03:00
Merge branch 'jmdavis-red-black'
Conflicts: std/array.d
This commit is contained in:
commit
db5b27dcd2
3 changed files with 423 additions and 1665 deletions
1599
std/array.d
1599
std/array.d
File diff suppressed because it is too large
Load diff
469
std/container.d
469
std/container.d
|
@ -4105,13 +4105,10 @@ struct RBNode(V)
|
|||
* ignored on insertion. If duplicates are allowed, then new elements are
|
||||
* inserted after all existing duplicate elements.
|
||||
*/
|
||||
struct RedBlackTree(T, alias less = "a < b", bool allowDuplicates = false)
|
||||
if (is(typeof(less(T.init, T.init)) == bool) || is(typeof(less) == string))
|
||||
class RedBlackTree(T, alias less = "a < b", bool allowDuplicates = false)
|
||||
if(is(typeof(binaryFun!less(T.init, T.init))))
|
||||
{
|
||||
static if(is(typeof(less) == string))
|
||||
alias binaryFun!(less) _less;
|
||||
else
|
||||
alias less _less;
|
||||
alias binaryFun!less _less;
|
||||
|
||||
// BUG: this must come first in the struct due to issue 2810
|
||||
|
||||
|
@ -4122,7 +4119,20 @@ if (is(typeof(less(T.init, T.init)) == bool) || is(typeof(less) == string))
|
|||
{
|
||||
Node result;
|
||||
static if(!allowDuplicates)
|
||||
{
|
||||
bool added = true;
|
||||
scope(success)
|
||||
{
|
||||
if(added)
|
||||
++_length;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
scope(success)
|
||||
++_length;
|
||||
}
|
||||
|
||||
if(!_end.left)
|
||||
{
|
||||
_end.left = result = allocate(n);
|
||||
|
@ -4204,11 +4214,6 @@ if (is(typeof(less(T.init, T.init)) == bool) || is(typeof(less) == string))
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static RedBlackTree create(Elem[] elems...)
|
||||
{
|
||||
return RedBlackTree(elems);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4224,9 +4229,11 @@ if (is(typeof(less(T.init, T.init)) == bool) || is(typeof(less) == string))
|
|||
private alias RBNode!Elem.Node Node;
|
||||
|
||||
private Node _end;
|
||||
private size_t _length;
|
||||
|
||||
private void _setup()
|
||||
{
|
||||
assert(!_end); //Make sure that _setup isn't run more than once.
|
||||
_end = allocate();
|
||||
}
|
||||
|
||||
|
@ -4311,10 +4318,17 @@ if (is(typeof(less(T.init, T.init)) == bool) || is(typeof(less) == string))
|
|||
|
||||
static if(doUnittest) unittest
|
||||
{
|
||||
auto ts = create(1, 2, 3, 4, 5);
|
||||
auto ts = new RedBlackTree(1, 2, 3, 4, 5);
|
||||
assert(ts.length == 5);
|
||||
auto r = ts[];
|
||||
assert(std.algorithm.equal(r, cast(T[])[1, 2, 3, 4, 5]));
|
||||
assert(r.front == 1);
|
||||
|
||||
static if(less == "a < b")
|
||||
auto vals = [1, 2, 3, 4, 5];
|
||||
else
|
||||
auto vals = [5, 4, 3, 2, 1];
|
||||
|
||||
assert(std.algorithm.equal(r, vals));
|
||||
assert(r.front == vals.front);
|
||||
assert(r.back != r.front);
|
||||
auto oldfront = r.front;
|
||||
auto oldback = r.back;
|
||||
|
@ -4323,6 +4337,7 @@ if (is(typeof(less(T.init, T.init)) == bool) || is(typeof(less) == string))
|
|||
assert(r.front != r.back);
|
||||
assert(r.front != oldfront);
|
||||
assert(r.back != oldback);
|
||||
assert(ts.length == 5);
|
||||
}
|
||||
|
||||
// find a node based on an element value
|
||||
|
@ -4372,27 +4387,37 @@ if (is(typeof(less(T.init, T.init)) == bool) || is(typeof(less) == string))
|
|||
return _end.left is null;
|
||||
}
|
||||
|
||||
/++
|
||||
Returns the number of elements in the container.
|
||||
|
||||
Complexity: $(BIGOH 1).
|
||||
+/
|
||||
@property size_t length()
|
||||
{
|
||||
return _length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate this container. The resulting container contains a shallow
|
||||
* copy of the elements.
|
||||
*
|
||||
* Complexity: $(BIGOH n)
|
||||
*/
|
||||
RedBlackTree dup()
|
||||
@property RedBlackTree dup()
|
||||
{
|
||||
RedBlackTree result;
|
||||
result._setup();
|
||||
result._end = _end.dup();
|
||||
return result;
|
||||
return new RedBlackTree(_end.dup(), _length);
|
||||
}
|
||||
|
||||
static if(doUnittest) unittest
|
||||
{
|
||||
auto ts = create(1, 2, 3, 4, 5);
|
||||
auto ts2 = ts.dup();
|
||||
auto ts = new RedBlackTree(1, 2, 3, 4, 5);
|
||||
assert(ts.length == 5);
|
||||
auto ts2 = ts.dup;
|
||||
assert(ts2.length == 5);
|
||||
assert(std.algorithm.equal(ts[], ts2[]));
|
||||
ts2.insert(cast(Elem)6);
|
||||
assert(!std.algorithm.equal(ts[], ts2[]));
|
||||
assert(ts.length == 5 && ts2.length == 6);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4425,11 +4450,12 @@ if (is(typeof(less(T.init, T.init)) == bool) || is(typeof(less) == string))
|
|||
return _end.prev.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if an element exists in the container
|
||||
*
|
||||
* Complexity: $(BIGOH log(n))
|
||||
*/
|
||||
/++
|
||||
$(D in) operator. Check to see if the given element exists in the
|
||||
container.
|
||||
|
||||
Complexity: $(BIGOH log(n))
|
||||
+/
|
||||
bool opBinaryRight(string op)(Elem e) if (op == "in")
|
||||
{
|
||||
return _find(e) !is null;
|
||||
|
@ -4437,19 +4463,28 @@ if (is(typeof(less(T.init, T.init)) == bool) || is(typeof(less) == string))
|
|||
|
||||
static if(doUnittest) unittest
|
||||
{
|
||||
auto ts = create(1, 2, 3, 4, 5);
|
||||
auto ts = new RedBlackTree(1, 2, 3, 4, 5);
|
||||
assert(cast(Elem)3 in ts);
|
||||
assert(cast(Elem)6 !in ts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the container of all elements
|
||||
* Removes all elements from the container.
|
||||
*
|
||||
* Complexity: $(BIGOH 1)
|
||||
*/
|
||||
void clear()
|
||||
{
|
||||
_end.left = null;
|
||||
_length = 0;
|
||||
}
|
||||
|
||||
static if(doUnittest) unittest
|
||||
{
|
||||
auto ts = new RedBlackTree(1,2,3,4,5);
|
||||
assert(ts.length == 5);
|
||||
ts.clear();
|
||||
assert(ts.empty && ts.length == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4504,10 +4539,33 @@ if (is(typeof(less(T.init, T.init)) == bool) || is(typeof(less) == string))
|
|||
|
||||
static if(doUnittest) unittest
|
||||
{
|
||||
auto ts = create(1,2,3,4,5);
|
||||
assert(ts.stableInsert(cast(Elem[])[6, 7, 8, 9, 10]) == 5);
|
||||
assert(ts.stableInsert(cast(Elem)11) == 1);
|
||||
auto ts = new RedBlackTree(2,1,3,4,5,2,5);
|
||||
static if(allowDuplicates)
|
||||
{
|
||||
assert(ts.length == 7);
|
||||
assert(ts.stableInsert(cast(Elem[])[7, 8, 6, 9, 10, 8]) == 6);
|
||||
assert(ts.length == 13);
|
||||
assert(ts.stableInsert(cast(Elem)11) == 1 && ts.length == 14);
|
||||
assert(ts.stableInsert(cast(Elem)7) == 1 && ts.length == 15);
|
||||
|
||||
static if(less == "a < b")
|
||||
assert(ts.arrayEqual([1,2,2,3,4,5,5,6,7,7,8,8,9,10,11]));
|
||||
else
|
||||
assert(ts.arrayEqual([11,10,9,8,8,7,7,6,5,5,4,3,2,2,1]));
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(ts.length == 5);
|
||||
assert(ts.stableInsert(cast(Elem[])[7, 8, 6, 9, 10, 8]) == 5);
|
||||
assert(ts.length == 10);
|
||||
assert(ts.stableInsert(cast(Elem)11) == 1 && ts.length == 11);
|
||||
assert(ts.stableInsert(cast(Elem)7) == 0 && ts.length == 11);
|
||||
|
||||
static if(less == "a < b")
|
||||
assert(ts.arrayEqual([1,2,3,4,5,6,7,8,9,10,11]));
|
||||
else
|
||||
assert(ts.arrayEqual([11,10,9,8,7,6,5,4,3,2,1]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4517,6 +4575,8 @@ if (is(typeof(less(T.init, T.init)) == bool) || is(typeof(less) == string))
|
|||
*/
|
||||
Elem removeAny()
|
||||
{
|
||||
scope(success)
|
||||
--_length;
|
||||
auto n = _end.leftmost;
|
||||
auto result = n.value;
|
||||
n.remove(_end);
|
||||
|
@ -4527,8 +4587,10 @@ if (is(typeof(less(T.init, T.init)) == bool) || is(typeof(less) == string))
|
|||
|
||||
static if(doUnittest) unittest
|
||||
{
|
||||
auto ts = create(1,2,3,4,5);
|
||||
auto ts = new RedBlackTree(1,2,3,4,5);
|
||||
assert(ts.length == 5);
|
||||
auto x = ts.removeAny();
|
||||
assert(ts.length == 4);
|
||||
Elem[] arr;
|
||||
foreach(Elem i; 1..6)
|
||||
if(i != x) arr ~= i;
|
||||
|
@ -4542,6 +4604,8 @@ if (is(typeof(less(T.init, T.init)) == bool) || is(typeof(less) == string))
|
|||
*/
|
||||
void removeFront()
|
||||
{
|
||||
scope(success)
|
||||
--_length;
|
||||
_end.leftmost.remove(_end);
|
||||
version(RBDoChecks)
|
||||
check();
|
||||
|
@ -4554,6 +4618,8 @@ if (is(typeof(less(T.init, T.init)) == bool) || is(typeof(less) == string))
|
|||
*/
|
||||
void removeBack()
|
||||
{
|
||||
scope(success)
|
||||
--_length;
|
||||
_end.prev.remove(_end);
|
||||
version(RBDoChecks)
|
||||
check();
|
||||
|
@ -4561,19 +4627,29 @@ if (is(typeof(less(T.init, T.init)) == bool) || is(typeof(less) == string))
|
|||
|
||||
static if(doUnittest) unittest
|
||||
{
|
||||
auto ts = create(1,2,3,4,5);
|
||||
auto ts = new RedBlackTree(1,2,3,4,5);
|
||||
assert(ts.length == 5);
|
||||
ts.removeBack();
|
||||
assert(ts.length == 4);
|
||||
|
||||
static if(less == "a < b")
|
||||
assert(ts.arrayEqual([1,2,3,4]));
|
||||
else
|
||||
assert(ts.arrayEqual([2,3,4,5]));
|
||||
|
||||
ts.removeFront();
|
||||
assert(ts.arrayEqual([2,3,4]));
|
||||
assert(ts.arrayEqual([2,3,4]) && ts.length == 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the given range from the container. Returns a range containing
|
||||
* all the elements that were after the given range.
|
||||
*
|
||||
* Complexity: $(BIGOH m * log(n))
|
||||
*/
|
||||
/++
|
||||
Removes the given range from the container.
|
||||
|
||||
Returns: A range containing all of the elements that were after the
|
||||
given range.
|
||||
|
||||
Complexity: $(BIGOH m * log(n)) (where m is the number of elements in
|
||||
the range)
|
||||
+/
|
||||
Range remove(Range r)
|
||||
{
|
||||
auto b = r._begin;
|
||||
|
@ -4581,6 +4657,7 @@ if (is(typeof(less(T.init, T.init)) == bool) || is(typeof(less) == string))
|
|||
while(b !is e)
|
||||
{
|
||||
b = b.remove(_end);
|
||||
--_length;
|
||||
}
|
||||
version(RBDoChecks)
|
||||
check();
|
||||
|
@ -4589,13 +4666,159 @@ if (is(typeof(less(T.init, T.init)) == bool) || is(typeof(less) == string))
|
|||
|
||||
static if(doUnittest) unittest
|
||||
{
|
||||
auto ts = create(1,2,3,4,5);
|
||||
auto ts = new RedBlackTree(1,2,3,4,5);
|
||||
assert(ts.length == 5);
|
||||
auto r = ts[];
|
||||
r.popFront();
|
||||
r.popBack();
|
||||
assert(ts.length == 5);
|
||||
auto r2 = ts.remove(r);
|
||||
assert(ts.length == 2);
|
||||
assert(ts.arrayEqual([1,5]));
|
||||
|
||||
static if(less == "a < b")
|
||||
assert(std.algorithm.equal(r2, [5]));
|
||||
else
|
||||
assert(std.algorithm.equal(r2, [1]));
|
||||
}
|
||||
|
||||
/++
|
||||
Removes the given $(D Take!Range) from the container
|
||||
|
||||
Returns: A range containing all of the elements that were after the
|
||||
given range.
|
||||
|
||||
Complexity: $(BIGOH m * log(n)) (where m is the number of elements in
|
||||
the range)
|
||||
+/
|
||||
Range remove(Take!Range r)
|
||||
{
|
||||
auto b = r.original._begin;
|
||||
|
||||
while(!r.empty)
|
||||
r.popFront(); // move take range to its last element
|
||||
|
||||
auto e = r.original._begin;
|
||||
|
||||
while(b != e)
|
||||
{
|
||||
b = b.remove(_end);
|
||||
--_length;
|
||||
}
|
||||
|
||||
return Range(e, _end);
|
||||
}
|
||||
|
||||
static if(doUnittest) unittest
|
||||
{
|
||||
auto ts = new RedBlackTree(1,2,3,4,5);
|
||||
auto r = ts[];
|
||||
r.popFront();
|
||||
assert(ts.length == 5);
|
||||
auto r2 = ts.remove(take(r, 0));
|
||||
|
||||
static if(less == "a < b")
|
||||
{
|
||||
assert(std.algorithm.equal(r2, [2,3,4,5]));
|
||||
auto r3 = ts.remove(take(r, 2));
|
||||
assert(ts.arrayEqual([1,4,5]) && ts.length == 3);
|
||||
assert(std.algorithm.equal(r3, [4,5]));
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(std.algorithm.equal(r2, [4,3,2,1]));
|
||||
auto r3 = ts.remove(take(r, 2));
|
||||
assert(ts.arrayEqual([5,2,1]) && ts.length == 3);
|
||||
assert(std.algorithm.equal(r3, [2,1]));
|
||||
}
|
||||
}
|
||||
|
||||
/++
|
||||
Removes elements from the container that are equal to the given values
|
||||
according to the less comparator. One element is removed for each value
|
||||
given which is in the container. If $(D allowDuplicates) is true,
|
||||
duplicates are removed only if duplicate values are given.
|
||||
|
||||
Returns: The number of elements removed.
|
||||
|
||||
Complexity: $(BIGOH m log(n)) (where m is the number of elements to remove)
|
||||
|
||||
Examples:
|
||||
--------------------
|
||||
auto rbt = redBlackTree!true(0, 1, 1, 1, 4, 5, 7);
|
||||
rbt.removeKey(1, 4, 7);
|
||||
assert(std.algorithm.equal(rbt[], [0, 1, 1, 5]));
|
||||
rbt.removeKey(1, 1, 0);
|
||||
assert(std.algorithm.equal(rbt[], [5]));
|
||||
--------------------
|
||||
+/
|
||||
size_t removeKey(U)(U[] elems...)
|
||||
if(isImplicitlyConvertible!(U, Elem))
|
||||
{
|
||||
immutable lenBefore = length;
|
||||
|
||||
foreach(e; elems)
|
||||
{
|
||||
auto beg = _firstGreaterEqual(e);
|
||||
if(beg is _end || _less(e, beg.value))
|
||||
// no values are equal
|
||||
continue;
|
||||
beg.remove(_end);
|
||||
--_length;
|
||||
}
|
||||
|
||||
return lenBefore - length;
|
||||
}
|
||||
|
||||
/++ Ditto +/
|
||||
size_t removeKey(Stuff)(Stuff stuff)
|
||||
if(isInputRange!Stuff &&
|
||||
isImplicitlyConvertible!(ElementType!Stuff, Elem) &&
|
||||
!is(Stuff == Elem[]))
|
||||
{
|
||||
//We use array in case stuff is a Range from this RedBlackTree - either
|
||||
//directly or indirectly.
|
||||
return removeKey(array(stuff));
|
||||
}
|
||||
|
||||
static if(doUnittest) unittest
|
||||
{
|
||||
auto rbt = new RedBlackTree(5, 4, 3, 7, 2, 1, 7, 6, 2, 19, 45);
|
||||
|
||||
static if(allowDuplicates)
|
||||
{
|
||||
assert(rbt.length == 11);
|
||||
assert(rbt.removeKey(cast(Elem)4) == 1 && rbt.length == 10);
|
||||
assert(rbt.arrayEqual([1,2,2,3,5,6,7,7,19,45]) && rbt.length == 10);
|
||||
|
||||
assert(rbt.removeKey(cast(Elem)6, cast(Elem)2, cast(Elem)1) == 3);
|
||||
assert(rbt.arrayEqual([2,3,5,7,7,19,45]) && rbt.length == 7);
|
||||
|
||||
assert(rbt.removeKey(cast(Elem)(42)) == 0 && rbt.length == 7);
|
||||
assert(rbt.removeKey(take(rbt[], 3)) == 3 && rbt.length == 4);
|
||||
|
||||
static if(less == "a < b")
|
||||
assert(std.algorithm.equal(rbt[], [7,7,19,45]));
|
||||
else
|
||||
assert(std.algorithm.equal(rbt[], [7,5,3,2]));
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(rbt.length == 9);
|
||||
assert(rbt.removeKey(cast(Elem)4) == 1 && rbt.length == 8);
|
||||
assert(rbt.arrayEqual([1,2,3,5,6,7,19,45]));
|
||||
|
||||
assert(rbt.removeKey(cast(Elem)6, cast(Elem)2, cast(Elem)1) == 3);
|
||||
assert(rbt.arrayEqual([3,5,7,19,45]) && rbt.length == 5);
|
||||
|
||||
assert(rbt.removeKey(cast(Elem)(42)) == 0 && rbt.length == 5);
|
||||
assert(rbt.removeKey(take(rbt[], 3)) == 3 && rbt.length == 2);
|
||||
|
||||
static if(less == "a < b")
|
||||
assert(std.algorithm.equal(rbt[], [19,45]));
|
||||
else
|
||||
assert(std.algorithm.equal(rbt[], [5,3]));
|
||||
}
|
||||
}
|
||||
|
||||
// find the first node where the value is > e
|
||||
|
@ -4685,18 +4908,28 @@ if (is(typeof(less(T.init, T.init)) == bool) || is(typeof(less) == string))
|
|||
|
||||
static if(doUnittest) unittest
|
||||
{
|
||||
auto ts = create(1, 2, 3, 4, 5);
|
||||
auto r1 = ts.lowerBound(3);
|
||||
assert(std.algorithm.equal(r1, [1,2]));
|
||||
auto r2 = ts.upperBound(3);
|
||||
assert(std.algorithm.equal(r2, [4,5]));
|
||||
auto r3 = ts.equalRange(3);
|
||||
assert(std.algorithm.equal(r3, [3]));
|
||||
auto ts = new RedBlackTree(1, 2, 3, 4, 5);
|
||||
auto rl = ts.lowerBound(3);
|
||||
auto ru = ts.upperBound(3);
|
||||
auto re = ts.equalRange(3);
|
||||
|
||||
static if(less == "a < b")
|
||||
{
|
||||
assert(std.algorithm.equal(rl, [1,2]));
|
||||
assert(std.algorithm.equal(ru, [4,5]));
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(std.algorithm.equal(rl, [5,4]));
|
||||
assert(std.algorithm.equal(ru, [2,1]));
|
||||
}
|
||||
|
||||
assert(std.algorithm.equal(re, [3]));
|
||||
}
|
||||
|
||||
version(RBDoChecks)
|
||||
{
|
||||
/**
|
||||
/*
|
||||
* Print the tree. This prints a sideways view of the tree in ASCII form,
|
||||
* with the number of indentations representing the level of the nodes.
|
||||
* It does not print values, only the tree structure and color of nodes.
|
||||
|
@ -4721,7 +4954,7 @@ if (is(typeof(less(T.init, T.init)) == bool) || is(typeof(less) == string))
|
|||
writeln();
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Check the tree for validity. This is called after every add or remove.
|
||||
* This should only be enabled to debug the implementation of the RB Tree.
|
||||
*/
|
||||
|
@ -4777,6 +5010,11 @@ if (is(typeof(less(T.init, T.init)) == bool) || is(typeof(less) == string))
|
|||
}
|
||||
}
|
||||
|
||||
/+
|
||||
For the moment, using templatized contstructors doesn't seem to work
|
||||
very well (likely due to bug# 436 and/or bug# 1528). The redBlackTree
|
||||
helper function seems to do the job well enough though.
|
||||
|
||||
/**
|
||||
* Constructor. Pass in an array of elements, or individual elements to
|
||||
* initialize the tree with.
|
||||
|
@ -4795,17 +5033,136 @@ if (is(typeof(less(T.init, T.init)) == bool) || is(typeof(less) == string))
|
|||
_setup();
|
||||
stableInsert(stuff);
|
||||
}
|
||||
+/
|
||||
|
||||
/++ +/
|
||||
this()
|
||||
{
|
||||
_setup();
|
||||
}
|
||||
|
||||
/++
|
||||
Constructor. Pass in an array of elements, or individual elements to
|
||||
initialize the tree with.
|
||||
+/
|
||||
this(Elem[] elems...)
|
||||
{
|
||||
_setup();
|
||||
stableInsert(elems);
|
||||
}
|
||||
|
||||
private this(Node end, size_t length)
|
||||
{
|
||||
_end = end;
|
||||
_length = length;
|
||||
}
|
||||
}
|
||||
|
||||
//Verify Example for removeKey.
|
||||
unittest
|
||||
{
|
||||
auto rbt = redBlackTree!true(0, 1, 1, 1, 4, 5, 7);
|
||||
rbt.removeKey(1, 4, 7);
|
||||
assert(std.algorithm.equal(rbt[], [0, 1, 1, 5]));
|
||||
rbt.removeKey(1, 1, 0);
|
||||
assert(std.algorithm.equal(rbt[], [5]));
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
RedBlackTree!uint rt1;
|
||||
RedBlackTree!int rt2;
|
||||
RedBlackTree!ushort rt3;
|
||||
RedBlackTree!short rt4;
|
||||
RedBlackTree!ubyte rt5;
|
||||
RedBlackTree!byte rt6;
|
||||
void test(T)()
|
||||
{
|
||||
auto rt1 = new RedBlackTree!(T, "a < b", false)();
|
||||
auto rt2 = new RedBlackTree!(T, "a < b", true)();
|
||||
auto rt3 = new RedBlackTree!(T, "a > b", false)();
|
||||
auto rt4 = new RedBlackTree!(T, "a > b", true)();
|
||||
}
|
||||
|
||||
test!long();
|
||||
test!ulong();
|
||||
test!int();
|
||||
test!uint();
|
||||
test!short();
|
||||
test!ushort();
|
||||
test!byte();
|
||||
test!byte();
|
||||
}
|
||||
|
||||
/++
|
||||
Convenience function for creating a $(D RedBlackTree!E) from a list of
|
||||
values.
|
||||
|
||||
Examples:
|
||||
--------------------
|
||||
auto rbt1 = redBlackTree(0, 1, 5, 7);
|
||||
auto rbt2 = redBlackTree!string("hello", "world");
|
||||
auto rbt3 = redBlackTree!true(0, 1, 5, 7, 5);
|
||||
auto rbt4 = redBlackTree!"a > b"(0, 1, 5, 7);
|
||||
auto rbt5 = redBlackTree!("a > b", true)(0.1, 1.3, 5.9, 7.2, 5.9);
|
||||
--------------------
|
||||
+/
|
||||
auto redBlackTree(E)(E[] elems...)
|
||||
{
|
||||
return new RedBlackTree!E(elems);
|
||||
}
|
||||
|
||||
/++ Ditto +/
|
||||
auto redBlackTree(bool allowDuplicates, E)(E[] elems...)
|
||||
{
|
||||
return new RedBlackTree!(E, "a < b", allowDuplicates)(elems);
|
||||
}
|
||||
|
||||
/++ Ditto +/
|
||||
auto redBlackTree(alias less, E)(E[] elems...)
|
||||
{
|
||||
return new RedBlackTree!(E, less)(elems);
|
||||
}
|
||||
|
||||
/++ Ditto +/
|
||||
auto redBlackTree(alias less, bool allowDuplicates, E)(E[] elems...)
|
||||
if(is(typeof(binaryFun!less(E.init, E.init))))
|
||||
{
|
||||
//We shouldn't need to instantiate less here, but for some reason,
|
||||
//dmd can't handle it if we don't (even though the template which
|
||||
//takes less but not allowDuplicates works just fine).
|
||||
return new RedBlackTree!(E, binaryFun!less, allowDuplicates)(elems);
|
||||
}
|
||||
|
||||
//Verify Examples.
|
||||
unittest
|
||||
{
|
||||
auto rbt1 = redBlackTree(0, 1, 5, 7);
|
||||
auto rbt2 = redBlackTree!string("hello", "world");
|
||||
auto rbt3 = redBlackTree!true(0, 1, 5, 7, 5);
|
||||
auto rbt4 = redBlackTree!"a > b"(0, 1, 5, 7);
|
||||
auto rbt5 = redBlackTree!("a > b", true)(0.1, 1.3, 5.9, 7.2, 5.9);
|
||||
}
|
||||
|
||||
//Combinations not in examples.
|
||||
unittest
|
||||
{
|
||||
auto rbt1 = redBlackTree!(true, string)("hello", "hello");
|
||||
auto rbt2 = redBlackTree!((a, b){return a < b;}, double)(5.1, 2.3);
|
||||
auto rbt3 = redBlackTree!("a > b", true, string)("hello", "world");
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
auto rt1 = redBlackTree(5, 4, 3, 2, 1);
|
||||
assert(rt1.length == 5);
|
||||
assert(array(rt1[]) == [1, 2, 3, 4, 5]);
|
||||
|
||||
auto rt2 = redBlackTree!"a > b"(1.1, 2.1);
|
||||
assert(rt2.length == 2);
|
||||
assert(array(rt2[]) == [2.1, 1.1]);
|
||||
|
||||
auto rt3 = redBlackTree!true(5, 5, 4);
|
||||
assert(rt3.length == 3);
|
||||
assert(array(rt3[]) == [4, 5, 5]);
|
||||
|
||||
auto rt4 = redBlackTree!string("hello", "hello");
|
||||
assert(rt4.length == 1);
|
||||
assert(array(rt4[]) == ["hello"]);
|
||||
}
|
||||
|
||||
version(unittest) struct UnittestMe {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue