Skip to content

Commit

Permalink
Merge pull request #4041 from greenify/docu-rbtree
Browse files Browse the repository at this point in the history
add documentation example for RBTree
  • Loading branch information
schveiguy committed Mar 15, 2016
2 parents 7b3d744 + e2ce2b3 commit e41a799
Showing 1 changed file with 152 additions and 0 deletions.
152 changes: 152 additions & 0 deletions std/container/rbtree.d
Expand Up @@ -19,6 +19,46 @@ Authors: Steven Schveighoffer, $(WEB erdani.com, Andrei Alexandrescu)
*/
module std.container.rbtree;

///
unittest
{
import std.container.rbtree;
import std.algorithm: equal;

auto rbt = redBlackTree(3, 1, 4, 2, 5);
assert(rbt.front == 1);
assert(equal(rbt[], [1, 2, 3, 4, 5]));

rbt.removeKey(1, 4);
assert(equal(rbt[], [2, 3, 5]));

rbt.removeFront();
assert(equal(rbt[], [3, 5]));

rbt.insert([1, 2, 4]);
assert(equal(rbt[], [1, 2, 3, 4, 5]));

// Query bounds in O(log(n))
assert(rbt.lowerBound(3).equal([1, 2]));
assert(rbt.equalRange(3).equal([3]));
assert(rbt.upperBound(3).equal([4, 5]));

// A Red Black tree with the highest element at front:
import std.range: iota;
auto maxTree = redBlackTree!"a > b"(iota(5));
assert(equal(maxTree[], [4, 3, 2, 1, 0]));

// adding duplicates will not add them, but return 0
auto rbt2 = redBlackTree(1, 3);
assert(rbt2.insert(1) == 0);
assert(equal(rbt2[], [1, 3]));
assert(rbt2.insert(2) == 1);

// however you can allow duplicates
auto ubt = redBlackTree!true([0, 1, 0, 1]);
assert(equal(ubt[], [0, 0, 1, 1]));
}

import std.functional : binaryFun;
import std.format;

Expand Down Expand Up @@ -1778,6 +1818,12 @@ pure unittest
/++
Convenience function for creating a $(D RedBlackTree!E) from a list of
values.
Params:
allowDuplicates = Whether duplicates should be allowed (optional, default: false)
less = predicate to sort by (optional)
elems = elements to insert into the rbtree (variadic arguments)
range = range elements to insert into the rbtree (alternative to elems)
+/
auto redBlackTree(E)(E[] elems...)
{
Expand All @@ -1792,6 +1838,7 @@ auto redBlackTree(bool allowDuplicates, E)(E[] elems...)

/++ Ditto +/
auto redBlackTree(alias less, E)(E[] elems...)
if(is(typeof(binaryFun!less(E.init, E.init))))
{
return new RedBlackTree!(E, less)(elems);
}
Expand All @@ -1806,14 +1853,59 @@ auto redBlackTree(alias less, bool allowDuplicates, E)(E[] elems...)
return new RedBlackTree!(E, binaryFun!less, allowDuplicates)(elems);
}


import std.range.primitives: isInputRange, isSomeString, ElementType;
import std.traits: isArray;

/++ Ditto +/
auto redBlackTree(Stuff)(Stuff range)
if (isInputRange!Stuff && !isArray!(Stuff))
{
return new RedBlackTree!(ElementType!Stuff)(range);
}

/++ Ditto +/
auto redBlackTree(bool allowDuplicates, Stuff)(Stuff range)
if (isInputRange!Stuff && !isArray!(Stuff))
{
return new RedBlackTree!(ElementType!Stuff, "a < b", allowDuplicates)(range);
}

/++ Ditto +/
auto redBlackTree(alias less, Stuff)(Stuff range)
if( is(typeof(binaryFun!less((ElementType!Stuff).init, (ElementType!Stuff).init)))
&& isInputRange!Stuff && !isArray!(Stuff))
{
return new RedBlackTree!(ElementType!Stuff, less)(range);
}

/++ Ditto +/
auto redBlackTree(alias less, bool allowDuplicates, Stuff)(Stuff range)
if( is(typeof(binaryFun!less((ElementType!Stuff).init, (ElementType!Stuff).init)))
&& isInputRange!Stuff && !isArray!(Stuff))
{
//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!(ElementType!Stuff, binaryFun!less, allowDuplicates)(range);
}

///
pure unittest
{
import std.range : iota;

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);

// also works with ranges
auto rbt6 = redBlackTree(iota(3));
auto rbt7 = redBlackTree!true(iota(3));
auto rbt8 = redBlackTree!"a > b"(iota(3));
auto rbt9 = redBlackTree!("a > b", true)(iota(3));
}

//Combinations not in examples.
Expand All @@ -1833,6 +1925,62 @@ pure unittest
assert(equal(rbt[], [4, 3, 2, 1, 0]));
}


// construction with arrays
pure unittest
{
import std.algorithm : equal;

auto rbt = redBlackTree!"a > b"([0, 1, 2, 3, 4]);
assert(equal(rbt[], [4, 3, 2, 1, 0]));

auto rbt2 = redBlackTree!"a > b"(["a", "b"]);
assert(equal(rbt2[], ["b", "a"]));

auto rbt3 = redBlackTree!"a > b"([1, 2]);
assert(equal(rbt3[], [2, 1]));

auto rbt4 = redBlackTree([0, 1, 7, 5]);
assert(equal(rbt4[], [0, 1, 5, 7]));

auto rbt5 = redBlackTree(["hello", "world"]);
assert(equal(rbt5[], ["hello", "world"]));

auto rbt6 = redBlackTree!true([0, 1, 5, 7, 5]);
assert(equal(rbt6[], [0, 1, 5, 5, 7]));

auto rbt7 = redBlackTree!"a > b"([0, 1, 5, 7]);
assert(equal(rbt7[], [7, 5, 1, 0]));

auto rbt8 = redBlackTree!("a > b", true)([0.1, 1.3, 5.9, 7.2, 5.9]);
assert(equal(rbt8[], [7.2, 5.9, 5.9, 1.3, 0.1]));
}

// convenience wrapper range construction
pure unittest
{
import std.algorithm : equal;
import std.range : chain, iota;

auto rbt = redBlackTree(iota(3));
assert(equal(rbt[], [0, 1, 2]));

auto rbt2 = redBlackTree!"a > b"(iota(2));
assert(equal(rbt2[], [1, 0]));

auto rbt3 = redBlackTree(chain([0, 1], [7, 5]));
assert(equal(rbt3[], [0, 1, 5, 7]));

auto rbt4 = redBlackTree(chain(["hello"], ["world"]));
assert(equal(rbt4[], ["hello", "world"]));

auto rbt5 = redBlackTree!true(chain([0, 1], [5, 7, 5]));
assert(equal(rbt5[], [0, 1, 5, 5, 7]));

auto rbt6 = redBlackTree!("a > b", true)(chain([0.1, 1.3], [5.9, 7.2, 5.9]));
assert(equal(rbt6[], [7.2, 5.9, 5.9, 1.3, 0.1]));
}

pure unittest
{
import std.array : array;
Expand Down Expand Up @@ -1865,6 +2013,10 @@ unittest {

auto rt3 = redBlackTree!string("hello", "world", "!");
assert(rt3.to!string == "RedBlackTree([\"!\", \"hello\", \"world\"])");

// type deduction can be done automatically
auto rt4 = redBlackTree(["hello"]);
assert(rt4.to!string == "RedBlackTree([\"hello\"])");
}

//constness checks
Expand Down

0 comments on commit e41a799

Please sign in to comment.