Fix set (extra) insertion & foreach
This commit is contained in:
		
							parent
							
								
									09acdb5118
								
							
						
					
					
						commit
						c17edda61c
					
				| @ -36,33 +36,38 @@ _Bool libcdsb_vset_find(val_t* x, set_t* s, const void* v, vtype t, _Bool cut) { | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| _Bool libcdsb_vset_insert(set_t* x, const void* v, vtype t) { | _Bool libcdsb_vset_insert(set_t* x, const void* v, vtype t) { | ||||||
|     int cmp; |     int     cmp; | ||||||
|     rbnode_t* n; |     rbnode_t* n; | ||||||
|     rbnode_t* p; |     rbnode_t* p; | ||||||
|  |     vnode_t  vn; | ||||||
| 
 | 
 | ||||||
|     n = x->root; |     n  = x->root; | ||||||
|  |     vn = vnode_tcreate(x->type, v, t); | ||||||
|  |     t  = x->type; | ||||||
|  |     v  = vnode_peek(&vn, t); | ||||||
| 
 | 
 | ||||||
|     if (!rbnode_is_empty(n)) { |     if (!rbnode_is_empty(n)) { | ||||||
|         do { |         do { | ||||||
|             p = n; |             p   = n; | ||||||
|             cmp = vtype_compare(vnode_peek(&n->value, x->type), x->type, v, t); |             cmp = vtype_compare(v, t, vnode_peek(&n->value, t), t); | ||||||
| 
 | 
 | ||||||
|             if (cmp == 0) return false; |             if (cmp == 0) { | ||||||
|  |                 vnode_free(&vn, t); | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|             n = (cmp > 0) ? n->left : n->right; |             n = (cmp < 0) ? n->left : n->right; | ||||||
|         } while (!rbnode_is_empty(n)); |         } while (!rbnode_is_empty(n)); | ||||||
| 
 | 
 | ||||||
|         n = rbnode_create(0, p, 1); |         n = rbnode_create(vn, p, 1); | ||||||
| 
 | 
 | ||||||
|         if (cmp > 0) p->left  = n; |         if (cmp < 0) p->left  = n; | ||||||
|         else         p->right = n; |         else         p->right = n; | ||||||
| 
 | 
 | ||||||
|         if (!rbnode_is_root(n->parent)) |         if (!rbnode_is_root(p)) | ||||||
|             rbnode_fixup(&x->root, n); |             rbnode_fixup(&x->root, n); | ||||||
| 
 | 
 | ||||||
|     } else n = x->root = rbnode_create(0, p, 1); |     } else n = x->root = rbnode_create(vn, rbnode_empty, 0); | ||||||
| 
 |  | ||||||
|     n->value = vnode_tcreate(x->type, v, t); |  | ||||||
| 
 | 
 | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| @ -74,10 +79,11 @@ _Bool libcdsb_vset_insert(set_t* x, const void* v, vtype t) { | |||||||
| int libcdsb_vset_foreach(const vtype_set* x, int (*callback)(const void* value, vtype type)) { | int libcdsb_vset_foreach(const vtype_set* x, int (*callback)(const void* value, vtype type)) { | ||||||
|     rbiter_t i; |     rbiter_t i; | ||||||
|     int      r; |     int      r; | ||||||
|  |     rbnode_t* c; | ||||||
| 
 | 
 | ||||||
|     if (rbiter_init(&i, &x->root, 0)) { |     if (rbiter_init(&i, &x->root, 0)) { | ||||||
|         while (!rbnode_is_empty(rbiter_next(&i))) { |         while (!rbnode_is_empty(c = rbiter_next(&i))) { | ||||||
|             if ((r = callback(vnode_peek(&i.cursor->value, x->type), x->type))) |             if ((r = callback(vnode_peek(&c->value, x->type), x->type))) | ||||||
|                 return r; |                 return r; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user