1 /**
2  * Implementation of a custom allocator red-black tree container.
3  * 
4  * Copyright: Red-black tree code copyright (C) 2008- by Steven Schveighoffer. Other code
5  * copyright 2010- Andrei Alexandrescu. All rights reserved by the respective holders.
6  * License: Distributed under the Boost Software License, Version 1.0.
7  * (See at $(WEB boost.org/LICENSE_1_0.txt)).
8  * Authors: Steven Schveighoffer, $(WEB erdani.com, Andrei Alexandrescu)
9 */
10 module memutils.rbtree;
11 
12 import std.functional; // : binaryFun;
13 import std.traits;
14 import std.range;
15 import std.algorithm : countUntil;
16 import memutils.allocators;
17 import memutils.refcounted;
18 import memutils.vector;
19 import memutils.constants;
20 import memutils.utils;
21 
22 alias RBTreeRef(T,  alias less = "a < b", bool allowDuplicates = true, ALLOC = ThreadMem) = RefCounted!(RBTree!(T, less, allowDuplicates, ALLOC));
23 
24 /**
25  * All inserts, removes, searches, and any function in general has complexity
26  * of $(BIGOH lg(n)).
27  *
28  * To use a different comparison than $(D "a < b"), pass a different operator string
29  * that can be used by $(XREF functional, binaryFun), or pass in a
30  * function, delegate, functor, or any type where $(D less(a, b)) results in a $(D bool)
31  * value.
32  *
33  * Note that less should produce a strict ordering.  That is, for two unequal
34  * elements $(D a) and $(D b), $(D less(a, b) == !less(b, a)). $(D less(a, a)) should
35  * always equal $(D false).
36  *
37  * If $(D allowDuplicates) is set to $(D true), then inserting the same element more than
38  * once continues to add more elements.  If it is $(D false), duplicate elements are
39  * ignored on insertion.  If duplicates are allowed, then new elements are
40  * inserted after all existing duplicate elements.
41  */
42 struct RBTree(T, alias less = "a < b", bool allowDuplicates = true, ALLOC = ThreadMem)
43 	if(is(typeof(binaryFun!less(T.init, T.init))))
44 {
45 	@disable this(this);
46 
47 	import std.range : Take;
48 	import std.typetuple : allSatisfy;
49 	import std.traits;
50 	
51 	alias _less = binaryFun!less;
52 	
53 	// BUG: this must come first in the struct due to issue 2810
54 	
55 	// add an element to the tree, returns the node added, or the existing node
56 	// if it has already been added and allowDuplicates is false
57 	
58 	private auto _add(Elem n)
59 	{
60 		Node result;
61 		static if(!allowDuplicates)
62 			bool added = true;
63 
64 		if(!_end.left)
65 		{
66 			_end.left = _begin = result = allocate(n);
67 		}
68 		else
69 		{
70 			Node newParent = _end.left;
71 			Node nxt = void;
72 			while(true)
73 			{
74 				if(_less(n, newParent.value))
75 				{
76 					nxt = newParent.left;
77 					if(nxt is null)
78 					{
79 						//
80 						// add to right of new parent
81 						//
82 						newParent.left = result = allocate(n);
83 						break;
84 					}
85 				}
86 				else
87 				{
88 					static if(!allowDuplicates)
89 					{
90 						if(!_less(newParent.value, n))
91 						{
92 							result = newParent;
93 							added = false;
94 							break;
95 						}
96 					}
97 					nxt = newParent.right;
98 					if(nxt is null)
99 					{
100 						//
101 						// add to right of new parent
102 						//
103 						newParent.right = result = allocate(n);
104 						break;
105 					}
106 				}
107 				newParent = nxt;
108 			}
109 			if(_begin.left)
110 				_begin = _begin.left;
111 		}
112 		
113 		static if(allowDuplicates)
114 		{
115 			result.setColor(_end);
116 			++_length;
117 			return result;
118 		}
119 		else
120 		{
121 			import std.typecons : Tuple;
122 			
123 			if(added)
124 			{
125 				++_length;
126 				result.setColor(_end);
127 			}
128 			return Tuple!(bool, "added", Node, "n")(added, result);
129 		}
130 	}
131 	
132 	
133 	private enum doUnittest = false;
134 	
135 	/**
136       * Element type for the tree
137       */
138 	alias Elem = T;
139 	
140 	// used for convenience
141 	private alias Node = RBNode!(Elem, ALLOC).Node;
142 
143 	private Node   _root;
144 	private Node   _end;
145 	private Node   _begin;
146 	private size_t _length;
147 
148 	package void _defaultInitialize()
149 	{
150 		if (!_end) {
151 			_begin = _end = _root = allocate();
152 		}
153 	}
154 	
155 	static private Node allocate()
156 	{
157 		return ObjectAllocator!(RBNode!(Elem, ALLOC), ALLOC).alloc();
158 	}
159 	
160 	static private Node allocate(Elem v)
161 	{
162 		auto result = allocate();
163 		logTrace("Allocating node ", cast(void*)result);
164 		result.value = v;
165 		return result;
166 	}
167 	
168 	// find a node based on an element value
169 	private Node _find(Elem e) const
170 	{
171 		static if(allowDuplicates)
172 		{
173 			Node cur = _end.left;
174 			Node result = null;
175 			while(cur)
176 			{
177 				if(_less(cur.value, e))
178 					cur = cur.right;
179 				else if(_less(e, cur.value))
180 					cur = cur.left;
181 				else
182 				{
183 					// want to find the left-most element
184 					result = cur;
185 					cur = cur.left;
186 				}
187 			}
188 			return result;
189 		}
190 		else
191 		{
192 			Node cur = _end.left;
193 			while(cur)
194 			{
195 				if(_less(cur.value, e))
196 					cur = cur.right;
197 				else if(_less(e, cur.value))
198 					cur = cur.left;
199 				else
200 					return cur;
201 			}
202 			return null;
203 		}
204 	}
205 	
206 	
207 	
208 	/**
209      * Check if any elements exist in the container.  Returns $(D false) if at least
210      * one element exists.
211      */
212 	@property bool empty() const
213 	{
214 		return _end.left is null;
215 	}
216 	
217 	/++
218         Returns the number of elements in the container.
219 
220         Complexity: $(BIGOH 1).
221     +/
222 	@property size_t length() const
223 	{
224 		return _length;
225 	}
226 		
227 	/**
228      * Fetch a range that spans all the elements in the container.
229      *
230      * Complexity: $(BIGOH 1)
231      */
232 	RBRange!(Elem, ALLOC) opSlice()
233 	{
234 		_defaultInitialize();
235 		return range(_begin, _end);
236 	}
237 	
238 	/**
239      * The front element in the container
240      *
241      * Complexity: $(BIGOH 1)
242      */
243 	ref Elem front()
244 	{
245 		_defaultInitialize();
246 		return _begin.value;
247 	}
248 	
249 	/**
250      * The last element in the container
251      *
252      * Complexity: $(BIGOH log(n))
253      */
254 	ref Elem back()
255 	{
256 		_defaultInitialize();
257 		return _end.prev.value;
258 	}
259 	
260 	/++
261         $(D in) operator. Check to see if the given element exists in the
262         container.
263 
264        Complexity: $(BIGOH log(n))
265      +/
266 	bool opBinaryRight(string op)(Elem e) const if (op == "in") 
267 	{
268 		return _find(e) !is null;
269 	}
270 	
271 	/**
272      * Removes all elements from the container.
273      *
274      * Complexity: $(BIGOH 1)
275      */
276 	void clear()
277 	{
278 		_defaultInitialize();
279 		logTrace("Clearing rbtree");
280 		while (length > 0)
281 			removeAny();
282 		logTrace(length, " items left");
283 		return;
284 	}
285 	
286 	/**
287      * Insert a single element in the container.  Note that this does not
288      * invalidate any ranges currently iterating the container.
289      *
290      * Complexity: $(BIGOH log(n))
291      */
292 	size_t insert(Stuff)(Stuff stuff) if (isImplicitlyConvertible!(Stuff, Elem))
293 	{
294 		_defaultInitialize();
295 		static if(allowDuplicates)
296 		{
297 			_add(stuff);
298 			return 1;
299 		}
300 		else
301 		{
302 			return(_add(stuff).added ? 1 : 0);
303 		}
304 	}
305 	
306 	/**
307      * Insert a range of elements in the container.  Note that this does not
308      * invalidate any ranges currently iterating the container.
309      *
310      * Complexity: $(BIGOH m * log(n))
311      */
312 	size_t insert(Stuff)(Stuff stuff) if(isInputRange!Stuff && isImplicitlyConvertible!(ElementType!Stuff, Elem))
313 	{
314 		_defaultInitialize();
315 		size_t result = 0;
316 		static if(allowDuplicates)
317 		{
318 			foreach(e; stuff)
319 			{
320 				++result;
321 				_add(e);
322 			}
323 		}
324 		else
325 		{
326 			foreach(e; stuff)
327 			{
328 				if(_add(e).added)
329 					++result;
330 			}
331 		}
332 		return result;
333 	}
334 
335 	
336 	/**
337      * Remove an element from the container and return its value.
338      *
339      * Complexity: $(BIGOH log(n))
340      */
341 	Elem removeAny()
342 	{
343 		_defaultInitialize();
344 		scope(success)
345 			--_length;
346 		auto n = _begin;
347 		auto result = n.value;
348 		_begin = n.remove(_end);
349 		return result;
350 	}
351 	
352 	/**
353      * Remove the front element from the container.
354      *
355      * Complexity: $(BIGOH log(n))
356      */
357 	void removeFront()
358 	{
359 		_defaultInitialize();
360 		scope(success)
361 			--_length;
362 		_begin = _begin.remove(_end);
363 	}
364 	
365 	/**
366      * Remove the back element from the container.
367      *
368      * Complexity: $(BIGOH log(n))
369      */
370 	void removeBack()
371 	{
372 		_defaultInitialize();
373 		scope(success)
374 			--_length;
375 		auto lastnode = _end.prev;
376 		if(lastnode is _begin)
377 			_begin = _begin.remove(_end);
378 		else
379 			lastnode.remove(_end);
380 	}
381 	
382 	/++
383        Removes elements from the container that are equal to the given values
384        according to the less comparator. One element is removed for each value
385        given which is in the container. If $(D allowDuplicates) is true,
386        duplicates are removed only if duplicate values are given.
387 
388        Returns: The number of elements removed.
389 
390        Complexity: $(BIGOH m log(n)) (where m is the number of elements to remove)
391 
392        Examples:
393 --------------------
394 auto rbt = redBlackTree!true(0, 1, 1, 1, 4, 5, 7);
395 rbt.removeKey(1, 4, 7);
396 assert(equal(rbt[], [0, 1, 1, 5]));
397 rbt.removeKey(1, 1, 0);
398 assert(equal(rbt[], [5]));
399 --------------------
400       +/
401 	size_t remove(U...)(U elems)
402 		if(allSatisfy!(isImplicitlyConvertibleToElem, U))
403 	{
404 		_defaultInitialize();
405 		Elem[U.length] toRemove;
406 		
407 		foreach(i, e; elems)
408 			toRemove[i] = e;
409 		
410 		return remove(toRemove[]);
411 	}
412 	
413 	/++ Ditto +/
414 	size_t remove(U)(U[] elems)
415 		if(isImplicitlyConvertible!(U, Elem))
416 	{
417 		_defaultInitialize();
418 		immutable lenBefore = length;
419 		
420 		foreach(e; elems)
421 		{
422 			auto beg = _firstGreaterEqual(e);
423 			if(beg is _end || _less(e, beg.value))
424 				// no values are equal
425 				continue;
426 			immutable isBegin = (beg is _begin);
427 			beg = beg.remove(_end);
428 			if(isBegin)
429 				_begin = beg;
430 			--_length;
431 		}
432 		
433 		return lenBefore - length;
434 	}
435 	
436 	/++ Ditto +/
437 	size_t remove(Stuff)(Stuff stuff)
438 		if(isInputRange!Stuff &&
439 			isImplicitlyConvertible!(ElementType!Stuff, Elem) &&
440 			!isDynamicArray!Stuff)
441 	{
442 		_defaultInitialize();
443 		import std.array : array;
444 		//We use array in case stuff is a Range from this RedBlackTree - either
445 		//directly or indirectly.
446 		return remove(array(stuff));
447 	}
448 	
449 	//Helper for removeKey.
450 	private template isImplicitlyConvertibleToElem(U)
451 	{
452 		enum isImplicitlyConvertibleToElem = isImplicitlyConvertible!(U, Elem);
453 	}
454 	
455 	/**
456      * Compares two trees for equality.
457      *
458      * Complexity: $(BIGOH n*log(n))
459      */
460 	bool opEquals(ref RBTree rhs)
461 	{
462 		_defaultInitialize();
463 		import std.algorithm : equal;
464 		if (rhs.empty) return false;
465 		
466 		// If there aren't the same number of nodes, we can't be equal.
467 		if (this._length != rhs._length) return false;
468 		
469 		auto thisRange = this[];
470 		auto thatRange = rhs[];
471 		return equal!(function(Elem a, Elem b) => !_less(a,b) && !_less(b,a))(thisRange, thatRange);
472 	}
473 	
474 	// find the first node where the value is > e
475 	private Node _firstGreater(Elem e)
476 	{
477 		// can't use _find, because we cannot return null
478 		auto cur = _end.left;
479 		auto result = _end;
480 		while(cur)
481 		{
482 			if(_less(e, cur.value))
483 			{
484 				result = cur;
485 				cur = cur.left;
486 			}
487 			else
488 				cur = cur.right;
489 		}
490 		return result;
491 	}
492 	
493 	// find the first node where the value is >= e
494 	private Node _firstGreaterEqual(Elem e)
495 	{
496 		// can't use _find, because we cannot return null.
497 		auto cur = _end.left;
498 		auto result = _end;
499 		while(cur)
500 		{
501 			if(_less(cur.value, e))
502 				cur = cur.right;
503 			else
504 			{
505 				result = cur;
506 				cur = cur.left;
507 			}
508 			
509 		}
510 		return result;
511 	}
512 	
513 	/**
514      * Get a range from the container with all elements that are > e according
515      * to the less comparator
516      *
517      * Complexity: $(BIGOH log(n))
518      */
519 	auto upperBoundRange(Elem e)
520 	{
521 		_defaultInitialize();
522 		return range(_firstGreater(e), _end);
523 	}
524 	
525 	/**
526      * Get a range from the container with all elements that are < e according
527      * to the less comparator
528      *
529      * Complexity: $(BIGOH log(n))
530      */
531 	auto lowerBoundRange(Elem e)
532 	{
533 		_defaultInitialize();
534 		return range(_begin, _firstGreaterEqual(e));
535 	}
536 	
537 	/**
538      * Get a range from the container with all elements that are == e according
539      * to the less comparator
540      *
541      * Complexity: $(BIGOH log(n))
542      */
543 	auto getValuesAt(Elem e)
544 	{
545 		_defaultInitialize();
546 		auto beg = _firstGreaterEqual(e);
547 		if(beg is _end || _less(e, beg.value))
548 			// no values are equal
549 			return range(beg, beg);
550 		static if(allowDuplicates)
551 		{
552 			return range(beg, _firstGreater(e));
553 		}
554 		else
555 		{
556 			// no sense in doing a full search, no duplicates are allowed,
557 			// so we just get the next node.
558 			return range(beg, beg.next);
559 		}
560 	}
561 
562 	this(size_t elems) {
563 		_defaultInitialize();
564 	}
565 
566 	/**
567      * Constructor. Pass in an array of elements, or individual elements to
568      * initialize the tree with.
569      */
570 	this(Elem[] elems...)
571 	{
572 		_defaultInitialize();
573 		static if (is(Elem == void[])) {
574 			foreach(elem;elems) insert(elem);
575 		}
576 		else
577 			insert(elems);
578 	}
579 	
580 	/**
581      * Constructor. Pass in a range of elements to initialize the tree with.
582      */
583 	this(Stuff)(Stuff stuff) if (isInputRange!Stuff && isImplicitlyConvertible!(ElementType!Stuff, Elem))
584 	{
585 		_defaultInitialize();
586 		insert(stuff);
587 	}
588 
589 	~this() {
590 		if (!_end) return;
591 		clear();
592 		ObjectAllocator!(RBNode!(Elem, ALLOC), ALLOC).free(_root);
593 	}
594 	
595 	private this(Node end, size_t length)
596 	{
597 		_end = end;
598 		_begin = end.leftmost;
599 		_length = length;
600 	}
601 }
602 
603 /*
604  * Implementation for a Red Black node for use in a Red Black Tree (see below)
605  *
606  * this implementation assumes we have a marker Node that is the parent of the
607  * root Node.  This marker Node is not a valid Node, but marks the end of the
608  * collection.  The root is the left child of the marker Node, so it is always
609  * last in the collection.  The marker Node is passed in to the setColor
610  * function, and the Node which has this Node as its parent is assumed to be
611  * the root Node.
612  *
613  * A Red Black tree should have O(lg(n)) insertion, removal, and search time.
614  */
615 struct RBNode(V, ALLOC)
616 {
617 	/*
618      * Convenience alias
619      */
620 	alias Node = RBNode!(V, ALLOC)*;
621 	
622 	private Node _left;
623 	private Node _right;
624 	private Node _parent;
625 	
626 	/**
627      * The value held by this node
628      */
629 	V value;
630 	
631 	/**
632      * Enumeration determining what color the node is.  Null nodes are assumed
633      * to be black.
634      */
635 	enum Color : byte
636 	{
637 		Red,
638 		Black
639 	}
640 	
641 	/**
642      * The color of the node.
643      */
644 	Color color;
645 	
646 	/**
647      * Get the left child
648      */
649 	@property Node left() const
650 	{
651 		return cast(Node)_left;
652 	}
653 	
654 	/**
655      * Get the right child
656      */
657 	@property inout(Node) right() inout
658 	{
659 		return _right;
660 	}
661 	
662 	/**
663      * Get the parent
664      */
665 	@property Node parent()
666 	{
667 		return _parent;
668 	}
669 	
670 	/**
671      * Set the left child.  Also updates the new child's parent node.  This
672      * does not update the previous child.
673      *
674      * Returns newNode
675      */
676 	@property Node left(Node newNode)
677 	{
678 		_left = newNode;
679 		if(newNode !is null)
680 			newNode._parent = &this;
681 		return newNode;
682 	}
683 	
684 	/**
685      * Set the right child.  Also updates the new child's parent node.  This
686      * does not update the previous child.
687      *
688      * Returns newNode
689      */
690 	@property Node right(Node newNode)
691 	{
692 		_right = newNode;
693 		if(newNode !is null)
694 			newNode._parent = &this;
695 		return newNode;
696 	}
697 	
698 	// assume _left is not null
699 	//
700 	// performs rotate-right operation, where this is T, _right is R, _left is
701 	// L, _parent is P:
702 	//
703 	//      P         P
704 	//      |   ->    |
705 	//      T         L
706 	//     / \       / \
707 	//    L   R     a   T
708 	//   / \           / \
709 	//  a   b         b   R
710 	//
711 	/**
712      * Rotate right.  This performs the following operations:
713      *  - The left child becomes the parent of this node.
714      *  - This node becomes the new parent's right child.
715      *  - The old right child of the new parent becomes the left child of this
716      *    node.
717      */
718 	Node rotateR()
719 		in
720 	{
721 		assert(_left !is null);
722 	}
723 	body
724 	{
725 		// sets _left._parent also
726 		if(isLeftNode)
727 			parent.left = _left;
728 		else
729 			parent.right = _left;
730 		Node tmp = _left._right;
731 		
732 		// sets _parent also
733 		_left.right = &this;
734 		
735 		// sets tmp._parent also
736 		left = tmp;
737 		
738 		return &this;
739 	}
740 	
741 	// assumes _right is non null
742 	//
743 	// performs rotate-left operation, where this is T, _right is R, _left is
744 	// L, _parent is P:
745 	//
746 	//      P           P
747 	//      |    ->     |
748 	//      T           R
749 	//     / \         / \
750 	//    L   R       T   b
751 	//       / \     / \
752 	//      a   b   L   a
753 	//
754 	/**
755      * Rotate left.  This performs the following operations:
756      *  - The right child becomes the parent of this node.
757      *  - This node becomes the new parent's left child.
758      *  - The old left child of the new parent becomes the right child of this
759      *    node.
760      */
761 	Node rotateL()
762 		in
763 	{
764 		assert(_right !is null);
765 	}
766 	body
767 	{
768 		// sets _right._parent also
769 		if(isLeftNode)
770 			parent.left = _right;
771 		else
772 			parent.right = _right;
773 		Node tmp = _right._left;
774 		
775 		// sets _parent also
776 		_right.left = &this;
777 		
778 		// sets tmp._parent also
779 		right = tmp;
780 		return &this;
781 	}
782 	
783 	
784 	/**
785      * Returns true if this node is a left child.
786      *
787      * Note that this should always return a value because the root has a
788      * parent which is the marker node.
789      */
790 	@property bool isLeftNode() const
791 	in
792 	{
793 		assert(_parent !is null);
794 	}
795 	body
796 	{
797 		return _parent._left is &this;
798 	}
799 	
800 	/**
801      * Set the color of the node after it is inserted.  This performs an
802      * update to the whole tree, possibly rotating nodes to keep the Red-Black
803      * properties correct.  This is an O(lg(n)) operation, where n is the
804      * number of nodes in the tree.
805      *
806      * end is the marker node, which is the parent of the topmost valid node.
807      */
808 	void setColor(Node end)
809 	{
810 		// test against the marker node
811 		if(_parent !is end)
812 		{
813 			if(_parent.color == Color.Red)
814 			{
815 				Node cur = &this;
816 				while(true)
817 				{
818 					// because root is always black, _parent._parent always exists
819 					if(cur._parent.isLeftNode)
820 					{
821 						// parent is left node, y is 'uncle', could be null
822 						Node y = cur._parent._parent._right;
823 						if(y !is null && y.color == Color.Red)
824 						{
825 							cur._parent.color = Color.Black;
826 							y.color = Color.Black;
827 							cur = cur._parent._parent;
828 							if(cur._parent is end)
829 							{
830 								// root node
831 								cur.color = Color.Black;
832 								break;
833 							}
834 							else
835 							{
836 								// not root node
837 								cur.color = Color.Red;
838 								if(cur._parent.color == Color.Black)
839 									// satisfied, exit the loop
840 									break;
841 							}
842 						}
843 						else
844 						{
845 							if(!cur.isLeftNode)
846 								cur = cur._parent.rotateL();
847 							cur._parent.color = Color.Black;
848 							cur = cur._parent._parent.rotateR();
849 							cur.color = Color.Red;
850 							// tree should be satisfied now
851 							break;
852 						}
853 					}
854 					else
855 					{
856 						// parent is right node, y is 'uncle'
857 						Node y = cur._parent._parent._left;
858 						if(y !is null && y.color == Color.Red)
859 						{
860 							cur._parent.color = Color.Black;
861 							y.color = Color.Black;
862 							cur = cur._parent._parent;
863 							if(cur._parent is end)
864 							{
865 								// root node
866 								cur.color = Color.Black;
867 								break;
868 							}
869 							else
870 							{
871 								// not root node
872 								cur.color = Color.Red;
873 								if(cur._parent.color == Color.Black)
874 									// satisfied, exit the loop
875 									break;
876 							}
877 						}
878 						else
879 						{
880 							if(cur.isLeftNode)
881 								cur = cur._parent.rotateR();
882 							cur._parent.color = Color.Black;
883 							cur = cur._parent._parent.rotateL();
884 							cur.color = Color.Red;
885 							// tree should be satisfied now
886 							break;
887 						}
888 					}
889 				}
890 				
891 			}
892 		}
893 		else
894 		{
895 			//
896 			// this is the root node, color it black
897 			//
898 			color = Color.Black;
899 		}
900 	}
901 	
902 	/**
903      * Remove this node from the tree.  The 'end' node is used as the marker
904      * which is root's parent.  Note that this cannot be null!
905      *
906      * Returns the next highest valued node in the tree after this one, or end
907      * if this was the highest-valued node.
908      */
909 	Node remove(Node end)
910 	{
911 		//
912 		// remove this node from the tree, fixing the color if necessary.
913 		//
914 		Node x;
915 		Node ret = next;
916 		
917 		// if this node has 2 children
918 		if (_left !is null && _right !is null)
919 		{
920 			//
921 			// normally, we can just swap this node's and y's value, but
922 			// because an iterator could be pointing to y and we don't want to
923 			// disturb it, we swap this node and y's structure instead.  This
924 			// can also be a benefit if the value of the tree is a large
925 			// struct, which takes a long time to copy.
926 			//
927 			Node yp, yl, yr;
928 			Node y = ret; // y = next
929 			yp = y._parent;
930 			yl = y._left;
931 			yr = y._right;
932 			auto yc = y.color;
933 			auto isyleft = y.isLeftNode;
934 			
935 			//
936 			// replace y's structure with structure of this node.
937 			//
938 			if(isLeftNode)
939 				_parent.left = y;
940 			else
941 				_parent.right = y;
942 			//
943 			// need special case so y doesn't point back to itself
944 			//
945 			y.left = _left;
946 			if(_right is y)
947 				y.right = &this;
948 			else
949 				y.right = _right;
950 			y.color = color;
951 			
952 			//
953 			// replace this node's structure with structure of y.
954 			//
955 			left = yl;
956 			right = yr;
957 			if(_parent !is y)
958 			{
959 				if(isyleft)
960 					yp.left = &this;
961 				else
962 					yp.right = &this;
963 			}
964 			color = yc;
965 		}
966 		
967 		// if this has less than 2 children, remove it
968 		if(_left !is null)
969 			x = _left;
970 		else
971 			x = _right;
972 		
973 		bool deferedUnlink = false;
974 		if(x is null)
975 		{
976 			// pretend this is a null node, defer unlinking the node
977 			x = &this;
978 			deferedUnlink = true;
979 		}
980 		else if(isLeftNode)
981 			_parent.left = x;
982 		else
983 			_parent.right = x;
984 		
985 		// if the color of this is black, then it needs to be fixed
986 		if(color == color.Black)
987 		{
988 			// need to recolor the tree.
989 			while(x._parent !is end && x.color == Node.Color.Black)
990 			{
991 				if(x.isLeftNode)
992 				{
993 					// left node
994 					Node w = x._parent._right;
995 					if(w.color == Node.Color.Red)
996 					{
997 						w.color = Node.Color.Black;
998 						x._parent.color = Node.Color.Red;
999 						x._parent.rotateL();
1000 						w = x._parent._right;
1001 					}
1002 					Node wl = w.left;
1003 					Node wr = w.right;
1004 					if((wl is null || wl.color == Node.Color.Black) &&
1005 						(wr is null || wr.color == Node.Color.Black))
1006 					{
1007 						w.color = Node.Color.Red;
1008 						x = x._parent;
1009 					}
1010 					else
1011 					{
1012 						if(wr is null || wr.color == Node.Color.Black)
1013 						{
1014 							// wl cannot be null here
1015 							wl.color = Node.Color.Black;
1016 							w.color = Node.Color.Red;
1017 							w.rotateR();
1018 							w = x._parent._right;
1019 						}
1020 						
1021 						w.color = x._parent.color;
1022 						x._parent.color = Node.Color.Black;
1023 						w._right.color = Node.Color.Black;
1024 						x._parent.rotateL();
1025 						x = end.left; // x = root
1026 					}
1027 				}
1028 				else
1029 				{
1030 					// right node
1031 					Node w = x._parent._left;
1032 					if(w.color == Node.Color.Red)
1033 					{
1034 						w.color = Node.Color.Black;
1035 						x._parent.color = Node.Color.Red;
1036 						x._parent.rotateR();
1037 						w = x._parent._left;
1038 					}
1039 					Node wl = w.left;
1040 					Node wr = w.right;
1041 					if((wl is null || wl.color == Node.Color.Black) &&
1042 						(wr is null || wr.color == Node.Color.Black))
1043 					{
1044 						w.color = Node.Color.Red;
1045 						x = x._parent;
1046 					}
1047 					else
1048 					{
1049 						if(wl is null || wl.color == Node.Color.Black)
1050 						{
1051 							// wr cannot be null here
1052 							wr.color = Node.Color.Black;
1053 							w.color = Node.Color.Red;
1054 							w.rotateL();
1055 							w = x._parent._left;
1056 						}
1057 						
1058 						w.color = x._parent.color;
1059 						x._parent.color = Node.Color.Black;
1060 						w._left.color = Node.Color.Black;
1061 						x._parent.rotateR();
1062 						x = end.left; // x = root
1063 					}
1064 				}
1065 			}
1066 			x.color = Node.Color.Black;
1067 		}
1068 		
1069 		if(deferedUnlink)
1070 		{
1071 			//
1072 			// unlink this node from the tree
1073 			//
1074 			if(isLeftNode)
1075 				_parent.left = null;
1076 			else
1077 				_parent.right = null;
1078 			
1079 		}
1080 		
1081 		// clean references to help GC - Bugzilla 12915
1082 		_left = _right = _parent = null;
1083 		
1084 		/// this node object can now be safely deleted
1085 		logTrace("Freeing node ", cast(void*)&this);
1086 		ObjectAllocator!(RBNode!(V, ALLOC), ALLOC).free(cast(RBNode!(V, ALLOC)*)&this);
1087 		
1088 		return ret;
1089 	}
1090 	
1091 	/**
1092      * Return the leftmost descendant of this node.
1093      */
1094 	@property Node leftmost()
1095 	{
1096 		Node result = &this;
1097 		while(result._left !is null)
1098 			result = result._left;
1099 		return result;
1100 	}
1101 	
1102 	/**
1103      * Return the rightmost descendant of this node
1104      */
1105 	@property Node rightmost()
1106 	{
1107 		Node result = &this;
1108 		while(result._right !is null)
1109 			result = result._right;
1110 		return result;
1111 	}
1112 	
1113 	/**
1114      * Returns the next valued node in the tree.
1115      *
1116      * You should never call this on the marker node, as it is assumed that
1117      * there is a valid next node.
1118      */
1119 	@property Node next()
1120 	{
1121 		Node n = &this;
1122 		if(n.right is null)
1123 		{
1124 			while(n._parent && !n.isLeftNode)
1125 				n = n._parent;
1126 			return n._parent;
1127 		}
1128 		else if (n.right !is null) {
1129 			if (!n._parent) return null;
1130 			return n.right.leftmost;
1131 		}
1132 		else return null;
1133 	}
1134 	
1135 	/**
1136      * Returns the previous valued node in the tree.
1137      *
1138      * You should never call this on the leftmost node of the tree as it is
1139      * assumed that there is a valid previous node.
1140      */
1141 	@property Node prev()
1142 	{
1143 		Node n = &this;
1144 		if(n.left is null)
1145 		{
1146 			while(n.isLeftNode)
1147 				n = n._parent;
1148 			return n._parent;
1149 		}
1150 		else
1151 			return n.left.rightmost;
1152 	}
1153 	
1154 	@property Node dup() const
1155 	{
1156 		Node copy = ObjectAllocator!(RBNode!(V, ALLOC), ALLOC).alloc();
1157 		logTrace("Allocating node ", cast(void*)copy);
1158 		copy.value = cast(V)value;
1159 		copy.color = color;
1160 		if(_left !is null)
1161 			copy.left = _left.dup();
1162 		if(_right !is null)
1163 			copy.right = _right.dup();
1164 		return copy;
1165 	}
1166 }
1167 
1168 /**
1169  * The range type for $(D RedBlackTree)
1170  */
1171 struct RBRange(Elem, ALLOC)
1172 {
1173 	alias Node = RBNode!(Elem, ALLOC).Node;
1174 	private Node _begin;
1175 	private Node _end;
1176 	
1177 	private this(Node b, Node e)
1178 	{
1179 		_begin = b;
1180 		_end = e;
1181 	}
1182 
1183 	/**
1184      * Returns $(D true) if the range is _empty
1185      */
1186 	@property bool empty() const
1187 	{
1188 		return _begin is _end || !_begin;
1189 	}
1190 	
1191 	/**
1192      * Returns the first element in the range
1193      */
1194 	@property ref Elem front()
1195 	{
1196 		return _begin.value;
1197 	}
1198 	
1199 	/**
1200          * Returns the last element in the range
1201          */
1202 	@property ref Elem back()
1203 	{
1204 		return _end.prev.value;
1205 	}
1206 	
1207 	/**
1208          * pop the front element from the range
1209          *
1210          * complexity: amortized $(BIGOH 1)
1211          */
1212 	void popFront()
1213 	{
1214 		_begin = _begin.next;
1215 	}
1216 	
1217 	/**
1218          * pop the back element from the range
1219          *
1220          * complexity: amortized $(BIGOH 1)
1221          */
1222 	void popBack()
1223 	{
1224 		_end = _end.prev;
1225 	}
1226 	
1227 	/**
1228          * Trivial _save implementation, needed for $(D isForwardRBRange).
1229          */
1230 	@property RBRange save()
1231 	{
1232 		return *cast(RBRange*)&this;
1233 	}
1234 }
1235 
1236 private auto range(Elem, ALLOC)(RBNode!(Elem, ALLOC)* start, RBNode!(Elem, ALLOC)* end) {
1237 	return RBRange!(Elem, ALLOC)(start, end);
1238 }
1239 
1240 auto vector(Elem, ALLOC)(RBRange!(Elem, ALLOC) r) {
1241 	return Vector!(Unqual!Elem, ALLOC)(r);
1242 }