4 //ifdef this to nothing if it bothers old broken compilers
5 #define TYPENAME typename
7 #if defined(external_templates)
11 /*******************************************************/
13 /*******************************************************/
17 #include "BPatch_dll.h"
19 #if !defined(DO_INLINE_P)
23 #if !defined(DO_INLINE_F)
27 /** template struct that will be used for default compare
28 * class for BPatch_Set operations.
31 // VG: shouldn't this be a dll export?
34 /** default comparison operator
35 * returns -1 if the first arg < second arg
36 * returns 1 if the first arg > second arg
37 * returns 0 if the first arg == second arg
38 * @param x first argument to be compared
39 * @param y second argument to be compared
41 int operator()(const T& x, const T& y) const {
48 /** template class for BPatch_Set. The implementation is based on red black
49 * tree implementation for efficiency concerns and for getting sorted
50 * elements easier. The template depends on two types. The first one is the
51 * the type of the elements in the BPatch_Set and the second one is the template
52 * structure that is used to compare the elements of the BPatch_Set. The template
53 * structure has to overload () for comparison of two elements as explained above
56 #if defined i386_unknown_nt4_0 || defined mips_unknown_ce2_11 //ccw 6 apr 2001
58 static const bool RED = true;
59 static const bool BLACK = false;
63 template<class T,class Compare = comparison<T> >
64 class BPATCH_DLL_EXPORT BPatch_Set {
67 #if ! (defined i386_unknown_nt4_0 || defined mips_unknown_ce2_11) //ccw 6 apr 2001
68 /** color variable used for red-black tree */
69 static const bool RED = true;
71 /** color variable used for red-black tree */
72 static const bool BLACK = false;
75 /** tree implementation structure. Used to implement the RB tree */
76 typedef struct entry {
77 T data; /* data element */
78 bool color; /* color of the node true=red,false=blue*/
79 struct entry* left; /* left child */
80 struct entry* right; /* right child */
81 struct entry* parent; /* parent of the node */
83 /** constructor for structure */
85 : color(BLACK),left(NULL),right(NULL),parent(NULL) {}
87 /** constructor used for non-nil elements
90 entry(entry* e) //constructor with nil entry
91 : color(RED),left(e),right(e),parent(NULL) {}
94 * @param d data element
97 entry(const T& d,entry* e)
98 : data(d),color(RED),left(e),right(e),parent(NULL){}
101 * @param e the entry structure that will be copied
103 entry(const entry& e) : data(e.data),color(e.color),
104 left(NULL),right(NULL),parent(NULL) {}
107 /** pointer to define the nil element of the tree NULL is not used
108 * since some operations need sentinel nil which may have non-nil
113 /** size of the BPatch_Set */
116 /** pointer to the tree structure */
119 /** the structure that will be used for comparisons. Default is the
120 * the comparsion structure explained above */
123 // method that replicates the tree structure of this tree
124 DO_INLINE_P entry* replicateTree(entry*,entry*,entry*,entry*);
126 // method that implements left rotattion used by RB tree for balanced
127 // tree construction and keeps the RBtree properties.
128 DO_INLINE_P void leftRotate(entry*);
130 // method that implements right rotattion used by RB tree for balanced
131 // tree construction and keeps the RBtree properties.
132 DO_INLINE_P void rightRotate(entry*);
134 // method that modifies the tree structure after deletion for keeping
135 // the RBtree properties.
136 DO_INLINE_P void deleteFixup(entry*);
138 // insertion to a binary search tree. It returns the new element pointer
139 // that is inserted. If element is already there it returns NULL
140 DO_INLINE_P entry* treeInsert(const T&);
142 // finds the elemnts in the tree that will be replaced with the element
143 // being deleted in the deletion. That is the element with the largets
144 // smallest value than the element being deleted.
145 DO_INLINE_P entry* treeSuccessor(entry* ) const;
147 // method that returns the entry pointer for the element that is searched
148 //for. If the entry is not found then it retuns NULL
149 DO_INLINE_P entry* find(const T&) const;
151 // infix traverse of the RB tree. It traverses the tree in ascending order
152 DO_INLINE_P void traverse(T*,entry*,int&) const;
154 // deletes the tree structure for deconstructor.
155 DO_INLINE_P void destroy(entry*);
159 /** constructor. The default comparison structure is used */
160 DO_INLINE_F BPatch_Set() : setSize(0)
164 compareFunc = Compare();
167 /** copy constructor.
168 * @param newBPatch_Set the BPatch_Set which will be copied
170 DO_INLINE_F BPatch_Set(const BPatch_Set<T,Compare>& newBPatch_Set){
172 compareFunc = newBPatch_Set.compareFunc;
173 setSize = newBPatch_Set.setSize;
174 setData = replicateTree(newBPatch_Set.setData,NULL,newBPatch_Set.nil,nil);
177 /** destructor which deletes all tree structure and allocated entries */
178 DO_INLINE_F ~BPatch_Set()
184 /** returns the cardinality of the tree , number of elements */
185 DO_INLINE_F int size() const { return setSize; }
187 /** returns true if tree is empty */
188 DO_INLINE_F bool empty() const { return (setData == nil); }
190 /** inserts the element in the tree
191 * @param 1 element that will be inserted
193 DO_INLINE_F void insert(const T&);
195 /** removes the element in the tree
196 * @param 1 element that will be removed
198 DO_INLINE_F void remove(const T&);
200 /** returns true if the argument is member of the BPatch_Set
201 * @param e the element that will be searched for
203 DO_INLINE_F bool contains(const T&) const;
205 /** fill an buffer array with the sorted
206 * elements of the BPatch_Set in ascending order according to comparison function
207 * if the BPatch_Set is empty it retuns NULL, other wise it returns
208 * the input argument.
210 DO_INLINE_F T* elements(T*) const;
212 /** returns the minimum valued member in the BPatch_Set according to the
213 * comparison function supplied. If the BPatch_Set is empty it retuns
214 * any number. Not safe to use for empty sets
216 DO_INLINE_F T minimum() const;
218 /** returns the maximum valued member in the BPatch_Set according to the
219 * comparison function supplied. If the BPatch_Set is empty it retuns
220 * any number. Not safe to use for empty sets
222 DO_INLINE_F T maximum() const;
224 /** assignment operator for BPatch_Set. It replicate sthe tree
225 * structure into the new BPatch_Set.
226 * @param 1 BPatch_Set that will be used in assignment
228 DO_INLINE_F BPatch_Set<T,Compare>& operator= (const BPatch_Set<T,Compare>&);
230 /** equality comparison for the BPatch_Set
231 * @param 1 BPatch_Set that will be used equality check
233 DO_INLINE_F bool operator== (const BPatch_Set<T,Compare>&) const;
235 /** inequality comparison for the BPatch_Set
236 * @param 1 BPatch_Set that will be used inequality check
238 DO_INLINE_F bool operator!= (const BPatch_Set<T,Compare>&) const;
240 /** insertion in to the BPatch_Set
241 * @param 1 element that will be inserted
243 DO_INLINE_F BPatch_Set<T,Compare>& operator+= (const T&);
245 /** union operation with this BPatch_Set
246 * @param 1 BPatch_Set that will be used in union operation
248 DO_INLINE_F BPatch_Set<T,Compare>& operator|= (const BPatch_Set<T,Compare>&);
250 /** intersection operation with this BPatch_Set
251 * @param 1 BPatch_Set that will be used in intersection operation
253 DO_INLINE_F BPatch_Set<T,Compare>& operator&= (const BPatch_Set<T,Compare>&);
255 /** difference operation with this BPatch_Set
256 * @param 1 BPatch_Set that will be used in difference operation
258 DO_INLINE_F BPatch_Set<T,Compare>& operator-= (const BPatch_Set<T,Compare>&);
261 * @param 1 BPatch_Set that will be used in union operation
263 DO_INLINE_F BPatch_Set<T,Compare> operator| (const BPatch_Set<T,Compare>&) const;
265 /** intersection operation
266 * @param 1 BPatch_Set that will be used in intersection operation
268 DO_INLINE_F BPatch_Set<T,Compare> operator& (const BPatch_Set<T,Compare>&) const;
270 /** difference operation
271 * @param 1 BPatch_Set that will be used in difference operation
273 DO_INLINE_F BPatch_Set<T,Compare> operator- (const BPatch_Set<T,Compare>&) const;
275 /** removes the element in the root of the tree
276 * if the BPatch_Set is empty it return false
277 * @param e refernce to the element that the value of removed
278 * element will be copied.
280 DO_INLINE_F bool extract(T&);
284 // VG(06/15/02): VC.NET doesn't like definitions for dll imports
285 #ifndef BPATCH_DLL_IMPORT
287 template <class T,class Compare>
289 TYPENAME BPatch_Set<T,Compare>::entry*
290 BPatch_Set<T,Compare>::replicateTree(entry* node,entry* parent,
291 entry* oldNil,entry* newNil)
296 entry* newNode = new entry(*node);
297 newNode->parent = parent;
298 newNode->left = replicateTree(node->left,newNode,oldNil,newNil);
299 newNode->right = replicateTree(node->right,newNode,oldNil,newNil);
303 template <class T,class Compare>
305 void BPatch_Set<T,Compare>::destroy(entry* node){
306 if(!node || (node == nil))
308 if(node->left != nil)
310 if(node->right != nil)
311 destroy(node->right);
315 template <class T,class Compare>
317 void BPatch_Set<T,Compare>::traverse(T* all,entry* node,int& n) const{
320 if(node->left != nil)
321 traverse(all,node->left,n);
323 all[n++] = node->data;
324 if(node->right != nil)
325 traverse(all,node->right,n);
327 template <class T,class Compare>
328 DO_INLINE_F T BPatch_Set<T,Compare>::minimum() const{
331 entry* node = setData;
332 while(node->left != nil)
337 template <class T,class Compare>
338 DO_INLINE_F T BPatch_Set<T,Compare>::maximum() const{
341 entry* node = setData;
342 while(node->right != nil)
346 template <class T,class Compare>
347 DO_INLINE_F T* BPatch_Set<T,Compare>::elements(T* buffer) const{
348 if(setData == nil) return NULL;
349 if(!buffer) return NULL;
351 traverse(buffer,setData,tmp);
354 template <class T,class Compare>
355 DO_INLINE_F BPatch_Set<T,Compare>& BPatch_Set<T,Compare>::operator= (const BPatch_Set<T,Compare>& newBPatch_Set){
356 if(this == &newBPatch_Set)
359 compareFunc = newBPatch_Set.compareFunc;
360 setSize = newBPatch_Set.setSize;
362 setData = replicateTree(newBPatch_Set.setData,NULL,newBPatch_Set.nil,nil);
365 template <class T,class Compare>
366 DO_INLINE_F bool BPatch_Set<T,Compare>::operator== (const BPatch_Set<T,Compare>& newBPatch_Set) const{
368 if(this == &newBPatch_Set)
370 T* all = new T[newBPatch_Set.size()];
371 newBPatch_Set.elements(all);
372 for(i=0;i<newBPatch_Set.size();i++)
373 if(!contains(all[i]))
376 all = new T[setSize];
378 for(i=0;i<setSize;i++)
379 if(!newBPatch_Set.contains(all[i]))
384 template <class T,class Compare>
385 DO_INLINE_F bool BPatch_Set<T,Compare>::operator!= (const BPatch_Set<T,Compare>& newBPatch_Set) const{
386 return !(*this == newBPatch_Set);
388 template <class T,class Compare>
389 DO_INLINE_F BPatch_Set<T,Compare>& BPatch_Set<T,Compare>::operator+= (const T& element){
393 template <class T,class Compare>
394 DO_INLINE_F BPatch_Set<T,Compare>& BPatch_Set<T,Compare>::operator|= (const BPatch_Set<T,Compare>& newBPatch_Set){
395 if(this == &newBPatch_Set)
397 T* all = new T[newBPatch_Set.size()];
398 newBPatch_Set.elements(all);
399 for(int i=0;i<newBPatch_Set.size();i++)
404 template <class T,class Compare>
405 DO_INLINE_F BPatch_Set<T,Compare>& BPatch_Set<T,Compare>::operator&= (const BPatch_Set<T,Compare>& newBPatch_Set){
406 if(this == &newBPatch_Set)
408 T* all = new T[setSize];
412 if(!newBPatch_Set.contains(all[i]))
417 template <class T,class Compare>
418 DO_INLINE_F BPatch_Set<T,Compare>& BPatch_Set<T,Compare>::operator-= (const BPatch_Set<T,Compare>& newBPatch_Set){
419 T* all = new T[setSize];
423 if(newBPatch_Set.contains(all[i]))
428 template <class T,class Compare>
429 DO_INLINE_F BPatch_Set<T,Compare> BPatch_Set<T,Compare>::operator| (const BPatch_Set<T,Compare>& newBPatch_Set) const{
430 BPatch_Set<T,Compare> ret;
431 ret |= newBPatch_Set;
435 template <class T,class Compare>
436 DO_INLINE_F BPatch_Set<T,Compare> BPatch_Set<T,Compare>::operator& (const BPatch_Set<T,Compare>& newBPatch_Set) const{
437 BPatch_Set<T,Compare> ret;
438 ret |= newBPatch_Set;
442 template <class T,class Compare>
443 DO_INLINE_F BPatch_Set<T,Compare> BPatch_Set<T,Compare>::operator- (const BPatch_Set<T,Compare>& newBPatch_Set) const{
444 BPatch_Set<T,Compare> ret;
446 ret -= newBPatch_Set;
450 template <class T,class Compare>
452 void BPatch_Set<T,Compare>::leftRotate(entry* pivot){
453 if(!pivot || (pivot == nil))
455 entry* y = pivot->right;
458 pivot->right = y->left;
460 y->left->parent = pivot;
461 y->parent = pivot->parent;
464 else if(pivot == pivot->parent->left)
465 pivot->parent->left = y;
467 pivot->parent->right = y;
471 template <class T,class Compare>
473 void BPatch_Set<T,Compare>::rightRotate(entry* pivot){
474 if(!pivot || (pivot == nil))
476 entry* x = pivot->left;
479 pivot->left = x->right;
481 x->right->parent = pivot;
482 x->parent = pivot->parent;
485 else if(pivot == pivot->parent->left)
486 pivot->parent->left = x;
488 pivot->parent->right = x;
493 template <class T,class Compare>
495 TYPENAME BPatch_Set<T,Compare>::entry*
496 BPatch_Set<T,Compare>::find(const T& element) const{
499 int check = compareFunc(element,x->data);
509 template <class T,class Compare>
510 DO_INLINE_F bool BPatch_Set<T,Compare>::contains(const T& element) const{
513 int check = compareFunc(element,x->data);
523 /** return pointer if the node is inserted, returns NULL if thevalue is
526 template <class T,class Compare>
528 TYPENAME BPatch_Set<T,Compare>::entry*
529 BPatch_Set<T,Compare>::treeInsert(const T& element){
534 int check = compareFunc(element,x->data);
542 entry* z = new entry(element,nil);
547 int check = compareFunc(element,y->data);
556 /** finds the minimum value node when x is being deleted */
557 template <class T,class Compare>
559 TYPENAME BPatch_Set<T,Compare>::entry*
560 BPatch_Set<T,Compare>::treeSuccessor(entry* x) const{
565 while(z->left != nil) z = z->left;
568 entry* y = x->parent;
569 while(y && (x == y->right)){
575 template <class T,class Compare>
577 void BPatch_Set<T,Compare>::deleteFixup(entry* x){
578 while((x != setData) &&
581 if(x == x->parent->left){
582 entry* w = x->parent->right;
585 x->parent->color = RED;
586 leftRotate(x->parent);
587 w = x->parent->right;
589 if((w->left->color == BLACK) &&
590 (w->right->color == BLACK)){
595 if(w->right->color == BLACK){
596 w->left->color = BLACK;
599 w = x->parent->right;
601 w->color = x->parent->color;
602 x->parent->color = BLACK;
603 w->right->color = BLACK;
604 leftRotate(x->parent);
609 entry* w = x->parent->left;
612 x->parent->color = RED;
613 rightRotate(x->parent);
616 if((w->right->color == BLACK) &&
617 (w->left->color == BLACK)){
622 if(w->left->color == BLACK){
623 w->right->color = BLACK;
628 w->color = x->parent->color;
629 x->parent->color = BLACK;
630 w->left->color = BLACK;
631 rightRotate(x->parent);
639 template <class T,class Compare>
640 DO_INLINE_F void BPatch_Set<T,Compare>::insert(const T& element){
641 entry* x = treeInsert(element);
644 while((x != setData) && (x->parent->color == RED)){
645 if(x->parent == x->parent->parent->left){
646 entry* y = x->parent->parent->right;
648 x->parent->color = BLACK;
650 x->parent->parent->color = RED;
651 x = x->parent->parent;
654 if(x == x->parent->right){
658 x->parent->color = BLACK;
659 x->parent->parent->color = RED;
660 rightRotate(x->parent->parent);
664 entry* y = x->parent->parent->left;
666 x->parent->color = BLACK;
668 x->parent->parent->color = RED;
669 x = x->parent->parent;
672 if(x == x->parent->left){
676 x->parent->color = BLACK;
677 x->parent->parent->color = RED;
678 leftRotate(x->parent->parent);
682 setData->color = BLACK;
684 template <class T,class Compare>
685 DO_INLINE_F void BPatch_Set<T,Compare>::remove(const T& element){
686 entry* z = find(element);
689 entry* y=((z->left == nil)||(z->right == nil)) ? z : treeSuccessor(z);
690 entry* x=(y->left != nil) ? y->left : y->right;
691 x->parent = y->parent;
694 else if(y == y->parent->left)
697 y->parent->right = x;
700 if(y->color == BLACK)
705 template <class T,class Compare>
707 bool BPatch_Set<T,Compare>::extract(T& element){
708 element = setData->data;
715 #endif /* BPATCH_DLL_IMPORT */
716 #endif /* _BPatch_Set_h_ */