/** * Inserts an unique element into a set with hint. */ set_iterator_t _set_insert_hint_varg(set_t* pset_set, set_iterator_t it_hint, va_list val_elemlist) { void* pv_varg = NULL; assert(pset_set != NULL); pv_varg = _alloc_allocate(&pset_set->_t_tree._t_allocator, _GET_SET_TYPE_SIZE(pset_set), 1); assert(pv_varg != NULL); _set_get_varg_value_auxiliary(pset_set, val_elemlist, pv_varg); #ifdef CSTL_SET_AVL_TREE it_hint = _avl_tree_insert_unique(&pset_set->_t_tree, pv_varg); #else it_hint = _rb_tree_insert_unique(&pset_set->_t_tree, pv_varg); #endif _set_destroy_varg_value_auxiliary(pset_set, pv_varg); _alloc_deallocate(&pset_set->_t_tree._t_allocator, pv_varg, _GET_SET_TYPE_SIZE(pset_set), 1); _ITERATOR_CONTAINER(it_hint) = pset_set; _SET_ITERATOR_CONTAINER_TYPE(it_hint) = _SET_CONTAINER; _SET_ITERATOR_ITERATOR_TYPE(it_hint) = _BIDIRECTIONAL_ITERATOR; return it_hint; }
/** * Destroy vector container auxiliary function. */ void _vector_destroy_auxiliary(vector_t* pvec_vector) { vector_iterator_t it_iter; vector_iterator_t it_begin; vector_iterator_t it_end; bool_t b_result = false; assert(pvec_vector != NULL); assert(_vector_is_inited(pvec_vector) || _vector_is_created(pvec_vector)); /* destroy all elements */ it_begin = vector_begin(pvec_vector); it_end = vector_end(pvec_vector); for (it_iter = it_begin; !iterator_equal(it_iter, it_end); it_iter = iterator_next(it_iter)) { b_result = _GET_VECTOR_TYPE_SIZE(pvec_vector); _GET_VECTOR_TYPE_DESTROY_FUNCTION(pvec_vector)(_VECTOR_ITERATOR_COREPOS(it_iter), &b_result); assert(b_result); } /* free vector memory */ if (pvec_vector->_pby_start != NULL) { _alloc_deallocate(&pvec_vector->_t_allocator, pvec_vector->_pby_start, _GET_VECTOR_TYPE_SIZE(pvec_vector), (pvec_vector->_pby_endofstorage - pvec_vector->_pby_start) / _GET_VECTOR_TYPE_SIZE(pvec_vector)); } _alloc_destroy(&pvec_vector->_t_allocator); pvec_vector->_pby_start = NULL; pvec_vector->_pby_finish = NULL; pvec_vector->_pby_endofstorage = NULL; }
/** * Return an iterator to the first element that is greater than a specific element. */ set_iterator_t _set_upper_bound_varg(const set_t* cpset_set, va_list val_elemlist) { void* pv_varg = NULL; set_iterator_t it_iter; assert(cpset_set != NULL); pv_varg = _alloc_allocate(&((set_t*)cpset_set)->_t_tree._t_allocator, _GET_SET_TYPE_SIZE(cpset_set), 1); assert(pv_varg != NULL); _set_get_varg_value_auxiliary((set_t*)cpset_set, val_elemlist, pv_varg); #ifdef CSTL_SET_AVL_TREE it_iter = _avl_tree_upper_bound(&cpset_set->_t_tree, pv_varg); #else it_iter = _rb_tree_upper_bound(&cpset_set->_t_tree, pv_varg); #endif _set_destroy_varg_value_auxiliary((set_t*)cpset_set, pv_varg); _alloc_deallocate(&((set_t*)cpset_set)->_t_tree._t_allocator, pv_varg, _GET_SET_TYPE_SIZE(cpset_set), 1); _ITERATOR_CONTAINER(it_iter) = (set_t*)cpset_set; _SET_ITERATOR_CONTAINER_TYPE(it_iter) = _SET_CONTAINER; _SET_ITERATOR_ITERATOR_TYPE(it_iter) = _BIDIRECTIONAL_ITERATOR; return it_iter; }
/** * Destroy slist container auxiliary function. */ void _slist_destroy_auxiliary(slist_t* pslist_slist) { _slistnode_t* pt_node = NULL; bool_t b_result = false; /* test the pslist_slist is valid */ assert(pslist_slist != NULL); assert(_slist_is_inited(pslist_slist) || _slist_is_created(pslist_slist)); /* _alloc_deallocate all nodes in slist */ while (pslist_slist->_t_head._pt_next != NULL) { /* take out each node from the slist */ pt_node = pslist_slist->_t_head._pt_next; pslist_slist->_t_head._pt_next = pt_node->_pt_next; pt_node->_pt_next = NULL; /* destroy the node itself */ b_result = _GET_SLIST_TYPE_SIZE(pslist_slist); _GET_SLIST_TYPE_DESTROY_FUNCTION(pslist_slist)(pt_node->_pby_data, &b_result); assert(b_result); _alloc_deallocate(&pslist_slist->_t_allocator, pt_node, _SLIST_NODE_SIZE(_GET_SLIST_TYPE_SIZE(pslist_slist)), 1); pt_node = NULL; } /* _alloc_deallocate the allocator */ _alloc_destroy(&pslist_slist->_t_allocator); }
/** * Assign vector with variable argument list of specificed element. */ void _vector_assign_elem_varg(vector_t* pvec_vector, size_t t_count, va_list val_elemlist) { iterator_t it_iter; iterator_t it_begin; iterator_t it_end; bool_t b_result = false; void* pv_varg = NULL; assert(pvec_vector != NULL); assert(_vector_is_inited(pvec_vector)); /* get value from varg */ pv_varg = _alloc_allocate(&pvec_vector->_t_allocator, _GET_VECTOR_TYPE_SIZE(pvec_vector), 1); assert(pv_varg != NULL); _vector_get_varg_value_auxiliary(pvec_vector, val_elemlist, pv_varg); /* copy value from varg for each element */ vector_resize(pvec_vector, t_count); it_begin = vector_begin(pvec_vector); it_end = vector_end(pvec_vector); for (it_iter = it_begin; !iterator_equal(it_iter, it_end); it_iter = iterator_next(it_iter)) { b_result = _GET_VECTOR_TYPE_SIZE(pvec_vector); _GET_VECTOR_TYPE_COPY_FUNCTION(pvec_vector)(_VECTOR_ITERATOR_COREPOS(it_iter), pv_varg, &b_result); assert(b_result); } /* destroy varg and free memory */ _vector_destroy_varg_value_auxiliary(pvec_vector, pv_varg); _alloc_deallocate(&pvec_vector->_t_allocator, pv_varg, _GET_VECTOR_TYPE_SIZE(pvec_vector), 1); }
/** * Remove element that specificed by variable argument slist from slist container. */ void _slist_remove_varg(slist_t* pslist_slist, va_list val_elemlist) { slist_iterator_t it_iter; /* for iterate */ _slistnode_t* pt_varg = NULL; bool_t b_less = false; bool_t b_greater = false; /* test the pointer is valid */ assert(pslist_slist != NULL); assert(_slist_is_inited(pslist_slist)); pt_varg = _alloc_allocate(&pslist_slist->_t_allocator, _SLIST_NODE_SIZE(_GET_SLIST_TYPE_SIZE(pslist_slist)), 1); assert(pt_varg != NULL); _slist_get_varg_value_auxiliary(pslist_slist, val_elemlist, pt_varg); it_iter = slist_begin(pslist_slist); while (!iterator_equal(it_iter, slist_end(pslist_slist))) { b_less = b_greater = _GET_SLIST_TYPE_SIZE(pslist_slist); _GET_SLIST_TYPE_LESS_FUNCTION(pslist_slist)( pt_varg->_pby_data, ((_slistnode_t*)_SLIST_ITERATOR_COREPOS(it_iter))->_pby_data, &b_less); _GET_SLIST_TYPE_LESS_FUNCTION(pslist_slist)( ((_slistnode_t*)_SLIST_ITERATOR_COREPOS(it_iter))->_pby_data, pt_varg->_pby_data, &b_greater); if (b_less || b_greater) { it_iter = iterator_next(it_iter); } else { it_iter = slist_erase(pslist_slist, it_iter); } } _slist_destroy_varg_value_auxiliary(pslist_slist, pt_varg); _alloc_deallocate(&pslist_slist->_t_allocator, pt_varg, _SLIST_NODE_SIZE(_GET_SLIST_TYPE_SIZE(pslist_slist)), 1); }
/** * Return an iterator range that is equal to a specific element. */ range_t _set_equal_range_varg(const set_t* cpset_set, va_list val_elemlist) { void* pv_varg = NULL; range_t r_range; assert(cpset_set != NULL); pv_varg = _alloc_allocate(&((set_t*)cpset_set)->_t_tree._t_allocator, _GET_SET_TYPE_SIZE(cpset_set), 1); assert(pv_varg != NULL); _set_get_varg_value_auxiliary((set_t*)cpset_set, val_elemlist, pv_varg); #ifdef CSTL_SET_AVL_TREE r_range = _avl_tree_equal_range(&cpset_set->_t_tree, pv_varg); #else r_range = _rb_tree_equal_range(&cpset_set->_t_tree, pv_varg); #endif _set_destroy_varg_value_auxiliary((set_t*)cpset_set, pv_varg); _alloc_deallocate(&((set_t*)cpset_set)->_t_tree._t_allocator, pv_varg, _GET_SET_TYPE_SIZE(cpset_set), 1); _ITERATOR_CONTAINER(r_range.it_begin) = (set_t*)cpset_set; _SET_ITERATOR_CONTAINER_TYPE(r_range.it_begin) = _SET_CONTAINER; _SET_ITERATOR_ITERATOR_TYPE(r_range.it_begin) = _BIDIRECTIONAL_ITERATOR; _ITERATOR_CONTAINER(r_range.it_end) = (set_t*)cpset_set; _SET_ITERATOR_CONTAINER_TYPE(r_range.it_end) = _SET_CONTAINER; _SET_ITERATOR_ITERATOR_TYPE(r_range.it_end) = _BIDIRECTIONAL_ITERATOR; return r_range; }
/** * Erases all the elements of an hashtable. */ void _hashtable_clear(_hashtable_t* pt_hashtable) { size_t t_bucketcount = 0; size_t i = 0; _hashnode_t* pt_node = NULL; _hashnode_t* pt_deletion = NULL; bool_t b_result = false; assert(pt_hashtable != NULL); assert(_hashtable_is_inited(pt_hashtable) || _hashtable_is_created(pt_hashtable)); t_bucketcount = vector_size(&pt_hashtable->_vec_bucket); /* iterator all bucket node */ for(i = 0; i < t_bucketcount; ++i) { /* iterator all element list for one bucket node */ pt_node = *(_hashnode_t**)vector_at(&pt_hashtable->_vec_bucket, i); *(_hashnode_t**)vector_at(&pt_hashtable->_vec_bucket, i) = NULL; while(pt_node != NULL) { /* delete each element */ pt_deletion = pt_node; pt_node = pt_node->_pt_next; /* destroy element */ b_result = _GET_HASHTABLE_TYPE_SIZE(pt_hashtable); _GET_HASHTABLE_TYPE_DESTROY_FUNCTION(pt_hashtable)(pt_deletion->_pby_data, &b_result); assert(b_result); _alloc_deallocate(&pt_hashtable->_t_allocator, pt_deletion, _HASHTABLE_NODE_SIZE(_GET_HASHTABLE_TYPE_SIZE(pt_hashtable)), 1); } } pt_hashtable->_t_nodecount = 0; }
/** * Initialize vector with variable argument list of specified element. */ void _vector_init_elem_varg(vector_t* pvec_vector, size_t t_count, va_list val_elemlist) { void* pv_varg = NULL; bool_t b_result = false; vector_iterator_t it_iter; assert(pvec_vector != NULL); assert(_vector_is_created(pvec_vector)); /* initialize vector_t */ vector_init_n(pvec_vector, t_count); if(t_count > 0) { /* get varg value only once */ pv_varg = _alloc_allocate(&pvec_vector->_t_allocator, _GET_VECTOR_TYPE_SIZE(pvec_vector), 1); assert(pv_varg != NULL); _vector_get_varg_value_auxiliary(pvec_vector, val_elemlist, pv_varg); /* copy varg value to each element */ for(it_iter = vector_begin(pvec_vector); !iterator_equal(it_iter, vector_end(pvec_vector)); it_iter = iterator_next(it_iter)) { /* copy from varg */ b_result = _GET_VECTOR_TYPE_SIZE(pvec_vector); _GET_VECTOR_TYPE_COPY_FUNCTION(pvec_vector)(_VECTOR_ITERATOR_COREPOS(it_iter), pv_varg, &b_result); assert(b_result); } /* destroy varg value and free memory */ _vector_destroy_varg_value_auxiliary(pvec_vector, pv_varg); _alloc_deallocate(&pvec_vector->_t_allocator, pv_varg, _GET_VECTOR_TYPE_SIZE(pvec_vector), 1); } }
/** * Shrink deque at begin. */ void _deque_shrink_at_begin(deque_t* pdeq_deque, size_t t_shrinksize) { deque_iterator_t it_oldbegin; deque_iterator_t it_newbegin; deque_iterator_t it_iter; _mappointer_t ppby_map = NULL; bool_t b_result = false; assert(pdeq_deque != NULL); assert(_deque_is_inited(pdeq_deque)); it_oldbegin = deque_begin(pdeq_deque); t_shrinksize = t_shrinksize < deque_size(pdeq_deque) ? t_shrinksize : deque_size(pdeq_deque); it_newbegin = iterator_next_n(deque_begin(pdeq_deque), t_shrinksize); assert(_deque_iterator_belong_to_deque(pdeq_deque, it_newbegin)); /* destroy all elements */ for(it_iter = it_oldbegin; !iterator_equal(it_iter, it_newbegin); it_iter = iterator_next(it_iter)) { b_result = _GET_DEQUE_TYPE_SIZE(pdeq_deque); _GET_DEQUE_TYPE_DESTROY_FUNCTION(pdeq_deque)(_deque_iterator_get_pointer_auxiliary(it_iter), &b_result); assert(b_result); } pdeq_deque->_t_start = it_newbegin; for(ppby_map = _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_start) - 1; ppby_map >= _GET_DEQUE_MAP_POINTER(it_oldbegin); --ppby_map) { _alloc_deallocate(&pdeq_deque->_t_allocator, *ppby_map, _GET_DEQUE_TYPE_SIZE(pdeq_deque), _DEQUE_ELEM_COUNT); *ppby_map = NULL; } }
/** * Assign slist with variable argument of specificed element. */ void _slist_assign_elem_varg(slist_t* pslist_slist, size_t t_count, va_list val_elemlist) { slist_iterator_t it_iter; _slistnode_t* pt_varg = NULL; bool_t b_result = false; assert(pslist_slist != NULL); assert(_slist_is_inited(pslist_slist)); slist_resize(pslist_slist, t_count); /* get varg value */ pt_varg = _alloc_allocate(&pslist_slist->_t_allocator, _SLIST_NODE_SIZE(_GET_SLIST_TYPE_SIZE(pslist_slist)), 1); assert(pt_varg != NULL); _slist_get_varg_value_auxiliary(pslist_slist, val_elemlist, pt_varg); /* copy value from varg */ for (it_iter = slist_begin(pslist_slist); !iterator_equal(it_iter, slist_end(pslist_slist)); it_iter = iterator_next(it_iter)) { b_result = _GET_SLIST_TYPE_SIZE(pslist_slist); _GET_SLIST_TYPE_COPY_FUNCTION(pslist_slist)( ((_slistnode_t*)_SLIST_ITERATOR_COREPOS(it_iter))->_pby_data, pt_varg->_pby_data, &b_result); assert(b_result); } /* destroy varg value */ _slist_destroy_varg_value_auxiliary(pslist_slist, pt_varg); _alloc_deallocate(&pslist_slist->_t_allocator, pt_varg, _SLIST_NODE_SIZE(_GET_SLIST_TYPE_SIZE(pslist_slist)), 1); }
/** * Set vector capacity. */ void vector_reserve(vector_t* pvec_vector, size_t t_reservesize) { _byte_t* pby_reservemem = NULL; /* new memory for reserve */ _byte_t* pby_newstart = NULL; _byte_t* pby_newfinish = NULL; _byte_t* pby_newendofstorage = NULL; _byte_t* pby_newpos = NULL; _byte_t* pby_oldpos = NULL; size_t t_oldsize = 0; size_t t_oldcapacity = 0; bool_t b_result = false; assert(pvec_vector != NULL); assert(_vector_is_inited(pvec_vector)); if(vector_capacity(pvec_vector) < t_reservesize) { /* allocate the new vector with reserve size */ pby_reservemem = _alloc_allocate(&pvec_vector->_t_allocator, _GET_VECTOR_TYPE_SIZE(pvec_vector), t_reservesize); assert(pby_reservemem != NULL); /* get the new position */ t_oldsize = pvec_vector->_pby_finish - pvec_vector->_pby_start; t_oldcapacity = pvec_vector->_pby_endofstorage - pvec_vector->_pby_start; pby_newstart = pby_reservemem; pby_newfinish = pby_reservemem + t_oldsize; pby_newendofstorage = pby_reservemem + _GET_VECTOR_TYPE_SIZE(pvec_vector) * t_reservesize; /* initialize new elements */ _vector_init_elem_range_auxiliary(pvec_vector, pby_newstart, pby_newfinish); /* copy elements from old memory and destroy those */ for(pby_newpos = pby_newstart, pby_oldpos = pvec_vector->_pby_start; pby_newpos < pby_newfinish && pby_oldpos < pvec_vector->_pby_finish; pby_newpos += _GET_VECTOR_TYPE_SIZE(pvec_vector), pby_oldpos += _GET_VECTOR_TYPE_SIZE(pvec_vector)) { /* copy from old vector_t memory */ b_result = _GET_VECTOR_TYPE_SIZE(pvec_vector); _GET_VECTOR_TYPE_COPY_FUNCTION(pvec_vector)(pby_newpos, pby_oldpos, &b_result); assert(b_result); /* destroy old vector_t memory */ b_result = _GET_VECTOR_TYPE_SIZE(pvec_vector); _GET_VECTOR_TYPE_DESTROY_FUNCTION(pvec_vector)(pby_oldpos, &b_result); assert(b_result); } assert(pby_newpos == pby_newfinish && pby_oldpos == pvec_vector->_pby_finish); /* free the old vector element */ if(pvec_vector->_pby_start != NULL) { _alloc_deallocate(&pvec_vector->_t_allocator, pvec_vector->_pby_start, _GET_VECTOR_TYPE_SIZE(pvec_vector), t_oldcapacity / _GET_VECTOR_TYPE_SIZE(pvec_vector)); } pvec_vector->_pby_start = pby_newstart; pvec_vector->_pby_finish = pby_newfinish; pvec_vector->_pby_endofstorage = pby_newendofstorage; } }
/** * Reset the size of vector elements, and filled element is from variable argument list. */ void _vector_resize_elem_varg(vector_t* pvec_vector, size_t t_resize, va_list val_elemlist) { vector_iterator_t t_cutpos; /* the cut position */ size_t t_expsize = 0; size_t i = 0; void* pv_varg = NULL; _byte_t* pby_oldfinish = NULL; bool_t b_result = false; assert(pvec_vector != NULL); assert(_vector_is_inited(pvec_vector)); if(t_resize == vector_size(pvec_vector)) { return; } else if(t_resize < vector_size(pvec_vector)) { t_cutpos = vector_begin(pvec_vector); t_cutpos = iterator_next_n(t_cutpos, t_resize); vector_erase_range(pvec_vector, t_cutpos, vector_end(pvec_vector)); } else { t_expsize = t_resize - vector_size(pvec_vector); if(t_resize > vector_capacity(pvec_vector)) { vector_reserve(pvec_vector, _vector_calculate_new_capacity(vector_size(pvec_vector), t_expsize)); } /* get varg value only once */ pv_varg = _alloc_allocate(&pvec_vector->_t_allocator, _GET_VECTOR_TYPE_SIZE(pvec_vector), 1); assert(pv_varg != NULL); _vector_get_varg_value_auxiliary(pvec_vector, val_elemlist, pv_varg); /* initialize new elements */ pby_oldfinish = pvec_vector->_pby_finish; pvec_vector->_pby_finish += t_expsize * _GET_VECTOR_TYPE_SIZE(pvec_vector); _vector_init_elem_range_auxiliary(pvec_vector, pby_oldfinish, pvec_vector->_pby_finish); /* copy value from varg to new elements */ for(i = 0; i < t_expsize; ++i) { b_result = _GET_VECTOR_TYPE_SIZE(pvec_vector); _GET_VECTOR_TYPE_COPY_FUNCTION(pvec_vector)(pby_oldfinish + i * _GET_VECTOR_TYPE_SIZE(pvec_vector), pv_varg, &b_result); assert(b_result); } /* destroy varg */ _vector_destroy_varg_value_auxiliary(pvec_vector, pv_varg); _alloc_deallocate(&pvec_vector->_t_allocator, pv_varg, _GET_VECTOR_TYPE_SIZE(pvec_vector), 1); } }
/** * Reset the size of slist elements, and filled element is from variable argument slist. */ void _slist_resize_elem_varg(slist_t* pslist_slist, size_t t_resize, va_list val_elemlist) { assert(pslist_slist != NULL); assert(_slist_is_inited(pslist_slist)); if (t_resize <= slist_size(pslist_slist)) { slist_iterator_t it_pos = iterator_advance(slist_begin(pslist_slist), t_resize); slist_erase_range(pslist_slist, it_pos, slist_end(pslist_slist)); } else { slist_iterator_t it_pos; _slistnode_t* pt_node = NULL; _slistnode_t* pt_varg = NULL; size_t t_size = slist_size(pslist_slist); size_t i = 0; bool_t b_result = false; if (!slist_empty(pslist_slist)) { it_pos = slist_previous(pslist_slist, slist_end(pslist_slist)); } else { _SLIST_ITERATOR_COREPOS(it_pos) = (_byte_t*)&pslist_slist->_t_head; } /* get varg value only once */ pt_varg = _alloc_allocate(&pslist_slist->_t_allocator, _SLIST_NODE_SIZE(_GET_SLIST_TYPE_SIZE(pslist_slist)), 1); assert(pt_varg != NULL); _slist_get_varg_value_auxiliary(pslist_slist, val_elemlist, pt_varg); for (i = 0; i < t_resize - t_size; ++i) { pt_node = _alloc_allocate(&pslist_slist->_t_allocator, _SLIST_NODE_SIZE(_GET_SLIST_TYPE_SIZE(pslist_slist)), 1); assert(pt_node != NULL); _slist_init_node_auxiliary(pslist_slist, pt_node); /* copy value from varg */ b_result = _GET_SLIST_TYPE_SIZE(pslist_slist); _GET_SLIST_TYPE_COPY_FUNCTION(pslist_slist)(pt_node->_pby_data, pt_varg->_pby_data, &b_result); assert(b_result); pt_node->_pt_next = ((_slistnode_t*)_SLIST_ITERATOR_COREPOS(it_pos))->_pt_next; ((_slistnode_t*)_SLIST_ITERATOR_COREPOS(it_pos))->_pt_next = pt_node; pt_node = NULL; } _slist_destroy_varg_value_auxiliary(pslist_slist, pt_varg); _alloc_deallocate(&pslist_slist->_t_allocator, pt_varg, _SLIST_NODE_SIZE(_GET_SLIST_TYPE_SIZE(pslist_slist)), 1); } }
/* * Erase an element in an hashtable from specificed position. */ void _hashtable_erase_pos(_hashtable_t* pt_hashtable, _hashtable_iterator_t it_pos) { _hashnode_t** ppt_bucket = NULL; _hashnode_t* pt_node = NULL; _hashnode_t* pt_deletion = NULL; bool_t b_result = false; assert(pt_hashtable != NULL); assert(_hashtable_is_inited(pt_hashtable)); assert(_hashtable_iterator_belong_to_hashtable(pt_hashtable, it_pos)); assert(!_hashtable_iterator_equal(it_pos, _hashtable_end(pt_hashtable))); /* get the previous node */ ppt_bucket = (_hashnode_t**)_GET_HASHTABLE_BUCKETPOS(it_pos); pt_node = *ppt_bucket; pt_deletion = (_hashnode_t*)_GET_HASHTABLE_COREPOS(it_pos); if(pt_node == pt_deletion) { /* the deletion node is the first node of node list */ *ppt_bucket = pt_node->_pt_next; } else { while(pt_node->_pt_next != NULL) { if(pt_node->_pt_next == pt_deletion) { pt_node->_pt_next = pt_deletion->_pt_next; break; } else { pt_node = pt_node->_pt_next; } } } /* delete the node */ b_result = _GET_HASHTABLE_TYPE_SIZE(pt_hashtable); _GET_HASHTABLE_TYPE_DESTROY_FUNCTION(pt_hashtable)(pt_deletion->_pby_data, &b_result); assert(b_result); _alloc_deallocate( &pt_hashtable->_t_allocator, pt_deletion, _HASHTABLE_NODE_SIZE(_GET_HASHTABLE_TYPE_SIZE(pt_hashtable)), 1); /* update the hashtable size */ pt_hashtable->_t_nodecount--; }
/** * Destroy the subtree with postorder traverse. */ _avlnode_t* _avl_tree_destroy_subtree(_avl_tree_t* pt_avl_tree, _avlnode_t* pt_root) { bool_t b_result = false; assert(pt_avl_tree != NULL); assert(_avl_tree_is_inited(pt_avl_tree) || _avl_tree_is_created(pt_avl_tree)); if (pt_root != NULL) { pt_root->_pt_left = _avl_tree_destroy_subtree(pt_avl_tree, pt_root->_pt_left); pt_root->_pt_right = _avl_tree_destroy_subtree(pt_avl_tree, pt_root->_pt_right); assert(pt_root->_pt_left == NULL && pt_root->_pt_right == NULL); b_result = _GET_AVL_TREE_TYPE_SIZE(pt_avl_tree); _GET_AVL_TREE_TYPE_DESTROY_FUNCTION(pt_avl_tree)(pt_root->_pby_data, &b_result); assert(b_result); _alloc_deallocate(&pt_avl_tree->_t_allocator, pt_root,_AVL_TREE_NODE_SIZE(_GET_AVL_TREE_TYPE_SIZE(pt_avl_tree)), 1); } return NULL; }
/** * Erase an element from a set that match a specified element. */ size_t _set_erase_varg(set_t* pset_set, va_list val_elemlist) { void* pv_varg = NULL; size_t t_count = 0; assert(pset_set != NULL); pv_varg = _alloc_allocate(&pset_set->_t_tree._t_allocator, _GET_SET_TYPE_SIZE(pset_set), 1); assert(pv_varg != NULL); _set_get_varg_value_auxiliary(pset_set, val_elemlist, pv_varg); #ifdef CSTL_SET_AVL_TREE t_count = _avl_tree_erase(&pset_set->_t_tree, pv_varg); #else t_count = _rb_tree_erase(&pset_set->_t_tree, pv_varg); #endif _set_destroy_varg_value_auxiliary(pset_set, pv_varg); _alloc_deallocate(&pset_set->_t_tree._t_allocator, pv_varg, _GET_SET_TYPE_SIZE(pset_set), 1); return t_count; }
/** * Insert multiple copys of element after specificed position. */ void _slist_insert_after_n_varg(slist_t* pslist_slist, slist_iterator_t it_pos, size_t t_count, va_list val_elemlist) { size_t i = 0; _slistnode_t* pt_node = NULL; _slistnode_t* pt_varg = NULL; bool_t b_result = false; assert(pslist_slist != NULL); assert(_slist_is_inited(pslist_slist)); assert(_slist_iterator_belong_to_slist(pslist_slist, it_pos)); assert(!iterator_equal(it_pos, slist_end(pslist_slist))); /* get varg value only once */ pt_varg = _alloc_allocate(&pslist_slist->_t_allocator, _SLIST_NODE_SIZE(_GET_SLIST_TYPE_SIZE(pslist_slist)), 1); assert(pt_varg != NULL); _slist_get_varg_value_auxiliary(pslist_slist, val_elemlist, pt_varg); for (i = 0; i < t_count; ++i) { /* allocate slist node */ pt_node = _alloc_allocate(&pslist_slist->_t_allocator, _SLIST_NODE_SIZE(_GET_SLIST_TYPE_SIZE(pslist_slist)), 1); assert(pt_node != NULL); _slist_init_node_auxiliary(pslist_slist, pt_node); /* copy value from varg */ b_result = _GET_SLIST_TYPE_SIZE(pslist_slist); _GET_SLIST_TYPE_COPY_FUNCTION(pslist_slist)(pt_node->_pby_data, pt_varg->_pby_data, &b_result); assert(b_result); /* link the node to slist */ pt_node->_pt_next = ((_slistnode_t*)_SLIST_ITERATOR_COREPOS(it_pos))->_pt_next; ((_slistnode_t*)_SLIST_ITERATOR_COREPOS(it_pos))->_pt_next = pt_node; pt_node = NULL; } /* destroy varg value */ _slist_destroy_varg_value_auxiliary(pslist_slist, pt_varg); _alloc_deallocate(&pslist_slist->_t_allocator, pt_varg, _SLIST_NODE_SIZE(_GET_SLIST_TYPE_SIZE(pslist_slist)), 1); }
/** * Initialize slist with variable argument slist of specified element. */ void _slist_init_elem_varg(slist_t* pslist_slist, size_t t_count, va_list val_elemlist) { _slistnode_t* pt_varg = NULL; bool_t b_result = false; assert(pslist_slist != NULL); assert(_slist_is_created(pslist_slist)); /* allocate memory for n_elemcount slist node */ if (t_count > 0) { size_t i = 0; _slistnode_t* pt_node = NULL; /* get varg value only once */ pt_varg = _alloc_allocate(&pslist_slist->_t_allocator, _SLIST_NODE_SIZE(_GET_SLIST_TYPE_SIZE(pslist_slist)), 1); assert(pt_varg != NULL); _slist_get_varg_value_auxiliary(pslist_slist, val_elemlist, pt_varg); for (i = 0; i < t_count; ++i) { pt_node = _alloc_allocate(&pslist_slist->_t_allocator, _SLIST_NODE_SIZE(_GET_SLIST_TYPE_SIZE(pslist_slist)), 1); assert(pt_node != NULL); _slist_init_node_auxiliary(pslist_slist, pt_node); /* copy value from varg */ b_result = _GET_SLIST_TYPE_SIZE(pslist_slist); _GET_SLIST_TYPE_COPY_FUNCTION(pslist_slist)(pt_node->_pby_data, pt_varg->_pby_data, &b_result); assert(b_result); /* insert the new slist node after the head */ pt_node->_pt_next = pslist_slist->_t_head._pt_next; pslist_slist->_t_head._pt_next = pt_node; pt_node = NULL; } _slist_destroy_varg_value_auxiliary(pslist_slist, pt_varg); _alloc_deallocate(&pslist_slist->_t_allocator, pt_varg, _SLIST_NODE_SIZE(_GET_SLIST_TYPE_SIZE(pslist_slist)), 1); } }
/** * Destroy and deallocate element allocated and initialized by _iterator_allocate_init_elem(). */ void _iterator_deallocate_destroy_elem(iterator_t it_iter, void* pv_value) { bool_t b_result = false; assert(_iterator_is_valid(it_iter)); assert(pv_value != NULL); switch (it_iter._t_containertype) { case _VECTOR_CONTAINER: ((vector_t*)it_iter._pt_container)->_t_typeinfo._pt_type->_t_typedestroy(pv_value, &b_result); assert(b_result); _alloc_deallocate(&((vector_t*)it_iter._pt_container)->_t_allocator, pv_value, ((vector_t*)it_iter._pt_container)->_t_typeinfo._pt_type->_t_typesize, 1); break; case _DEQUE_CONTAINER: ((deque_t*)it_iter._pt_container)->_t_typeinfo._pt_type->_t_typedestroy(pv_value, &b_result); assert(b_result); _alloc_deallocate(&((deque_t*)it_iter._pt_container)->_t_allocator, pv_value, ((deque_t*)it_iter._pt_container)->_t_typeinfo._pt_type->_t_typesize, 1); break; case _BASIC_STRING_CONTAINER: ((basic_string_t*)it_iter._pt_container)->_vec_base._t_typeinfo._pt_type->_t_typedestroy(pv_value, &b_result); assert(b_result); _alloc_deallocate(&((basic_string_t*)it_iter._pt_container)->_vec_base._t_allocator, pv_value, ((basic_string_t*)it_iter._pt_container)->_vec_base._t_typeinfo._pt_type->_t_typesize, 1); break; case _LIST_CONTAINER: ((list_t*)it_iter._pt_container)->_t_typeinfo._pt_type->_t_typedestroy(pv_value, &b_result); assert(b_result); _alloc_deallocate(&((list_t*)it_iter._pt_container)->_t_allocator, pv_value, ((list_t*)it_iter._pt_container)->_t_typeinfo._pt_type->_t_typesize, 1); break; case _SLIST_CONTAINER: ((slist_t*)it_iter._pt_container)->_t_typeinfo._pt_type->_t_typedestroy(pv_value, &b_result); assert(b_result); _alloc_deallocate(&((slist_t*)it_iter._pt_container)->_t_allocator, pv_value, ((slist_t*)it_iter._pt_container)->_t_typeinfo._pt_type->_t_typesize, 1); break; case _SET_CONTAINER: ((set_t*)it_iter._pt_container)->_t_tree._t_typeinfo._pt_type->_t_typedestroy(pv_value, &b_result); assert(b_result); _alloc_deallocate(&((set_t*)it_iter._pt_container)->_t_tree._t_allocator, pv_value, ((set_t*)it_iter._pt_container)->_t_tree._t_typeinfo._pt_type->_t_typesize, 1); break; case _MULTISET_CONTAINER: ((multiset_t*)it_iter._pt_container)->_t_tree._t_typeinfo._pt_type->_t_typedestroy(pv_value, &b_result); assert(b_result); _alloc_deallocate(&((multiset_t*)it_iter._pt_container)->_t_tree._t_allocator, pv_value, ((set_t*)it_iter._pt_container)->_t_tree._t_typeinfo._pt_type->_t_typesize, 1); break; case _MAP_CONTAINER: ((map_t*)it_iter._pt_container)->_t_tree._t_typeinfo._pt_type->_t_typedestroy(pv_value, &b_result); assert(b_result); _alloc_deallocate(&((map_t*)it_iter._pt_container)->_t_tree._t_allocator, pv_value, ((map_t*)it_iter._pt_container)->_t_tree._t_typeinfo._pt_type->_t_typesize, 1); break; case _MULTIMAP_CONTAINER: ((multimap_t*)it_iter._pt_container)->_t_tree._t_typeinfo._pt_type->_t_typedestroy(pv_value, &b_result); assert(b_result); _alloc_deallocate(&((multimap_t*)it_iter._pt_container)->_t_tree._t_allocator, pv_value, ((multimap_t*)it_iter._pt_container)->_t_tree._t_typeinfo._pt_type->_t_typesize, 1); break; case _HASH_SET_CONTAINER: ((hash_set_t*)it_iter._pt_container)->_t_hashtable._t_typeinfo._pt_type->_t_typedestroy(pv_value, &b_result); assert(b_result); _alloc_deallocate(&((hash_set_t*)it_iter._pt_container)->_t_hashtable._t_allocator, pv_value, ((hash_set_t*)it_iter._pt_container)->_t_hashtable._t_typeinfo._pt_type->_t_typesize, 1); break; case _HASH_MULTISET_CONTAINER: ((hash_multiset_t*)it_iter._pt_container)->_t_hashtable._t_typeinfo._pt_type->_t_typedestroy(pv_value, &b_result); assert(b_result); _alloc_deallocate(&((hash_multiset_t*)it_iter._pt_container)->_t_hashtable._t_allocator, pv_value, ((hash_multiset_t*)it_iter._pt_container)->_t_hashtable._t_typeinfo._pt_type->_t_typesize, 1); break; case _HASH_MAP_CONTAINER: ((hash_map_t*)it_iter._pt_container)->_t_hashtable._t_typeinfo._pt_type->_t_typedestroy(pv_value, &b_result); assert(b_result); _alloc_deallocate(&((hash_map_t*)it_iter._pt_container)->_t_hashtable._t_allocator, pv_value, ((hash_map_t*)it_iter._pt_container)->_t_hashtable._t_typeinfo._pt_type->_t_typesize, 1); break; case _HASH_MULTIMAP_CONTAINER: ((hash_multimap_t*)it_iter._pt_container)->_t_hashtable._t_typeinfo._pt_type->_t_typedestroy(pv_value, &b_result); assert(b_result); _alloc_deallocate(&((hash_multimap_t*)it_iter._pt_container)->_t_hashtable._t_allocator, pv_value, ((hash_multimap_t*)it_iter._pt_container)->_t_hashtable._t_typeinfo._pt_type->_t_typesize, 1); break; default: assert(false); break; } }
/** * Expand deque at begin. */ deque_iterator_t _deque_expand_at_begin(deque_t* pdeq_deque, size_t t_expandsize, deque_iterator_t* pit_pos) { deque_iterator_t it_oldbegin; size_t t_remainsize = 0; /* the remain size in first container */ assert(pdeq_deque != NULL); assert(_deque_is_inited(pdeq_deque)); #ifndef NDEBUG if(pit_pos != NULL) { assert(_deque_iterator_belong_to_deque(_GET_DEQUE_CONTAINER(*pit_pos), *pit_pos)); } #endif /* NDEBUG */ it_oldbegin = deque_begin(pdeq_deque); /* if the capacity of first container is enough for expand size */ t_remainsize = (_GET_DEQUE_COREPOS(it_oldbegin) - _GET_DEQUE_FIRST_POS(it_oldbegin)) / _GET_DEQUE_TYPE_SIZE(pdeq_deque); if(t_expandsize < t_remainsize) { /* set the new begin iterator */ _GET_DEQUE_COREPOS(pdeq_deque->_t_start) -= t_expandsize * _GET_DEQUE_TYPE_SIZE(pdeq_deque); } else { size_t t_nomemsize = 0; /* the size that they have no memory */ size_t t_chunksize = 0; /* the chunk for new element */ size_t t_prefixsize = 0; /* the valid size in front chunk */ size_t t_remainfrontmapsize = 0; /* the remain space at the map begin */ size_t t_remainmapsize = 0; /* the remain space in the map */ _byte_t** ppby_newchunk = NULL; /* the pointer to new chunk */ size_t i = 0; /* caculate the expand chunk number */ t_nomemsize = t_expandsize - t_remainsize; t_chunksize = (t_nomemsize + _DEQUE_ELEM_COUNT - 1) / _DEQUE_ELEM_COUNT; t_prefixsize = t_nomemsize % _DEQUE_ELEM_COUNT; if(t_prefixsize == 0) { t_chunksize++; } t_remainfrontmapsize = _GET_DEQUE_MAP_POINTER(it_oldbegin) - pdeq_deque->_ppby_map; t_remainmapsize = pdeq_deque->_t_mapsize - (_GET_DEQUE_MAP_POINTER(pdeq_deque->_t_finish) - _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_start) + 1); /* if chunk remain space is not enough for expand size then grow the map for expand chunk */ if(t_chunksize > t_remainmapsize) { size_t t_validmapsize = _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_finish) - _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_start) + 1; int n_newmapstartpos = 0; int n_oldmapstartpos = (pdeq_deque->_t_mapsize - t_validmapsize) / 2; int n_newposofoldchunk = 0; int n_posdistance = 0; /* the distance of pit_pos and map */ size_t t_growsize = (t_chunksize - t_remainmapsize + _DEQUE_MAP_GROW_STEP - 1) / _DEQUE_MAP_GROW_STEP * _DEQUE_MAP_GROW_STEP; /* grow size multiple of eight */ _mappointer_t ppby_oldmap = pdeq_deque->_ppby_map; /* old map */ size_t t_oldmapsize = pdeq_deque->_t_mapsize; /* new map */ pdeq_deque->_t_mapsize += t_growsize; pdeq_deque->_ppby_map = _alloc_allocate(&pdeq_deque->_t_allocator, sizeof(_byte_t*), pdeq_deque->_t_mapsize); assert(pdeq_deque->_ppby_map != NULL); memset(pdeq_deque->_ppby_map, 0x00, sizeof(_byte_t*) * pdeq_deque->_t_mapsize); /* copy the chunk pointer from old map to new map */ n_newmapstartpos = (pdeq_deque->_t_mapsize - (t_validmapsize + t_chunksize)) / 2; n_newposofoldchunk = n_newmapstartpos + t_chunksize; memcpy(pdeq_deque->_ppby_map + n_newposofoldchunk, ppby_oldmap + n_oldmapstartpos, sizeof(_byte_t*) * t_validmapsize); /* get the pit_pos distance */ if(pit_pos != NULL) { n_posdistance = _GET_DEQUE_MAP_POINTER(*pit_pos) - _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_start); } /* reset the start, finish and old front iterator */ _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_start) = pdeq_deque->_ppby_map + n_newposofoldchunk; _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_finish) = pdeq_deque->_ppby_map + n_newposofoldchunk + t_validmapsize - 1; _GET_DEQUE_MAP_POINTER(it_oldbegin) = _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_start); /* modify pit_pos */ if(pit_pos != NULL) { _GET_DEQUE_MAP_POINTER(*pit_pos) = _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_start) + n_posdistance; } _alloc_deallocate(&pdeq_deque->_t_allocator, ppby_oldmap, sizeof(_byte_t*), t_oldmapsize); } /* else if the chunk remain space is enough for expand size */ else if(t_chunksize > t_remainfrontmapsize && t_chunksize <= t_remainmapsize) { size_t t_oldvalidmapsize = _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_finish) - _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_start) + 1; /* old valid chunk count in old map */ size_t t_newvalidmapsize = t_oldvalidmapsize + t_chunksize; /* the valid chunk count in new map */ size_t t_oldstartpossize = (pdeq_deque->_t_mapsize - t_oldvalidmapsize) / 2; /* the chunk start pos in old map */ size_t t_newstartpossize = (pdeq_deque->_t_mapsize - t_newvalidmapsize) / 2; /* the chunk start pos in new map */ size_t t_newposofoldchunk = t_newstartpossize + t_chunksize; /* the chunk in new map pos */ size_t t_movesize = t_newposofoldchunk - t_oldstartpossize; /* the distance of move */ /* move the valid chunk pointer in map */ memmove(_GET_DEQUE_MAP_POINTER(pdeq_deque->_t_start) + t_movesize, _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_start), sizeof(_byte_t*) * t_oldvalidmapsize); /* reset the start, finish and oldend iterator */ _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_start) += t_movesize; _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_finish) += t_movesize; _GET_DEQUE_MAP_POINTER(it_oldbegin) += t_movesize; if(pit_pos != NULL) { _GET_DEQUE_MAP_POINTER(*pit_pos) += t_movesize; } } /* allocate the chunk */ for(i = 0, ppby_newchunk = _GET_DEQUE_MAP_POINTER(it_oldbegin) - 1; i < t_chunksize; ++i, --ppby_newchunk) { *ppby_newchunk = _alloc_allocate(&pdeq_deque->_t_allocator, _GET_DEQUE_TYPE_SIZE(pdeq_deque), _DEQUE_ELEM_COUNT); assert(*ppby_newchunk != NULL); } /* set new start iterator */ _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_start) = _GET_DEQUE_MAP_POINTER(it_oldbegin) - t_chunksize; _GET_DEQUE_FIRST_POS(pdeq_deque->_t_start) = *_GET_DEQUE_MAP_POINTER(pdeq_deque->_t_start); _GET_DEQUE_AFTERLAST_POS(pdeq_deque->_t_start) = _GET_DEQUE_FIRST_POS(pdeq_deque->_t_start) + _DEQUE_ELEM_COUNT * _GET_DEQUE_TYPE_SIZE(pdeq_deque); _GET_DEQUE_COREPOS(pdeq_deque->_t_start) = _GET_DEQUE_AFTERLAST_POS(pdeq_deque->_t_start) - t_prefixsize * _GET_DEQUE_TYPE_SIZE(pdeq_deque); } /* the old front is original front */ if(_GET_DEQUE_COREPOS(it_oldbegin) == _GET_DEQUE_AFTERLAST_POS(it_oldbegin)) { assert(*(_GET_DEQUE_MAP_POINTER(it_oldbegin) + 1) != NULL); _GET_DEQUE_MAP_POINTER(it_oldbegin) += 1; _GET_DEQUE_FIRST_POS(it_oldbegin) = *_GET_DEQUE_MAP_POINTER(it_oldbegin); _GET_DEQUE_AFTERLAST_POS(it_oldbegin) = _GET_DEQUE_FIRST_POS(it_oldbegin) + _DEQUE_ELEM_COUNT * _GET_DEQUE_TYPE_SIZE(pdeq_deque); _GET_DEQUE_COREPOS(it_oldbegin) = _GET_DEQUE_FIRST_POS(it_oldbegin); } /* the *pit_pos is original front */ if(pit_pos != NULL && _GET_DEQUE_COREPOS(*pit_pos) == _GET_DEQUE_AFTERLAST_POS(*pit_pos)) { assert(*(_GET_DEQUE_MAP_POINTER(*pit_pos) + 1) != NULL); _GET_DEQUE_MAP_POINTER(*pit_pos) += 1; _GET_DEQUE_FIRST_POS(*pit_pos) = *_GET_DEQUE_MAP_POINTER(*pit_pos); _GET_DEQUE_AFTERLAST_POS(*pit_pos) = _GET_DEQUE_FIRST_POS(*pit_pos) + _DEQUE_ELEM_COUNT * _GET_DEQUE_TYPE_SIZE(pdeq_deque); _GET_DEQUE_COREPOS(*pit_pos) = _GET_DEQUE_FIRST_POS(*pit_pos); } /* initialize all new elements */ _deque_init_elem_range_auxiliary(pdeq_deque, deque_begin(pdeq_deque), it_oldbegin); return it_oldbegin; }
/** * Insert multiple copys of element befor specificed position, the element is from variable argument list. */ vector_iterator_t _vector_insert_n_varg(vector_t* pvec_vector, vector_iterator_t it_pos, size_t t_count, va_list val_elemlist) { void* pv_varg = NULL; bool_t b_result = false; /* test the vector and iterator is valid */ assert(pvec_vector != NULL); assert(_vector_is_inited(pvec_vector)); assert(_vector_iterator_belong_to_vector(pvec_vector, it_pos)); if (t_count > 0) { size_t i = 0; _byte_t* pby_oldfinish = NULL; _byte_t* pby_pos = NULL; /* for initialize elments and insert elements */ _byte_t* pby_destpos = NULL; /* if the remain capacity is less then the element count */ if (vector_size(pvec_vector) + t_count > vector_capacity(pvec_vector)) { size_t t_insertpos = iterator_distance(vector_begin(pvec_vector), it_pos); /* reserve the new size */ vector_reserve(pvec_vector, _vector_calculate_new_capacity(vector_size(pvec_vector), t_count)); it_pos = iterator_next_n(vector_begin(pvec_vector), t_insertpos); } /* insert the element counts of element to the position */ /* * move the elements from pos to the finish of vector to the * memory that after the pos element count. * +-----------------------------------------+ * | | | | * +-----------------------------------------+ * ^ ^ ^ * | | | * start it_pos finish * _t_count__ * / \ * +-----------------------------------------+ * | | |new element| | * +-----------------------------------------+ * ^ ^ ^ ^ * | | | | * start it_pos pby_oldfinish finish */ /* initialize new elements */ pby_oldfinish = pvec_vector->_pby_finish; assert(pby_oldfinish != NULL); pvec_vector->_pby_finish += t_count * _GET_VECTOR_TYPE_SIZE(pvec_vector); _vector_init_elem_range_auxiliary(pvec_vector, pby_oldfinish, pvec_vector->_pby_finish); /* move element from old finish to new finish */ for (pby_pos = pby_oldfinish - _GET_VECTOR_TYPE_SIZE(pvec_vector), pby_destpos = pvec_vector->_pby_finish - _GET_VECTOR_TYPE_SIZE(pvec_vector); pby_pos >= _VECTOR_ITERATOR_COREPOS(it_pos); pby_pos -= _GET_VECTOR_TYPE_SIZE(pvec_vector), pby_destpos -= _GET_VECTOR_TYPE_SIZE(pvec_vector)) { b_result = _GET_VECTOR_TYPE_SIZE(pvec_vector); _GET_VECTOR_TYPE_COPY_FUNCTION(pvec_vector)(pby_destpos, pby_pos, &b_result); assert(b_result); } /* get varg value only once */ pv_varg = _alloc_allocate(&pvec_vector->_t_allocator, _GET_VECTOR_TYPE_SIZE(pvec_vector), 1); assert(pv_varg != NULL); _vector_get_varg_value_auxiliary(pvec_vector, val_elemlist, pv_varg); /* copy value for varg */ for (i = 0; i < t_count; ++i) { b_result = _GET_VECTOR_TYPE_SIZE(pvec_vector); _GET_VECTOR_TYPE_COPY_FUNCTION(pvec_vector)(_VECTOR_ITERATOR_COREPOS(it_pos) + i * _GET_VECTOR_TYPE_SIZE(pvec_vector), pv_varg, &b_result); assert(b_result); } /* destroy varg and free memory */ _vector_destroy_varg_value_auxiliary(pvec_vector, pv_varg); _alloc_deallocate(&pvec_vector->_t_allocator, pv_varg, _GET_VECTOR_TYPE_SIZE(pvec_vector), 1); } return it_pos; }
/* * Erase an element in an avl tree from specificed position. */ void _avl_tree_erase_pos(_avl_tree_t* pt_avl_tree, _avl_tree_iterator_t it_pos) { _avlnode_t* pt_parent = NULL; _avlnode_t* pt_cur = NULL; bool_t b_result = false; assert(pt_avl_tree != NULL); assert(_avl_tree_is_inited(pt_avl_tree)); assert(_avl_tree_iterator_belong_to_avl_tree(pt_avl_tree, it_pos)); assert(!_avl_tree_iterator_equal(it_pos, _avl_tree_end(pt_avl_tree))); pt_cur = (_avlnode_t*)_AVL_TREE_ITERATOR_COREPOS(it_pos); pt_parent = pt_cur->_pt_parent; /* delete node X express deleting */ if (pt_cur->_pt_left == NULL && pt_cur->_pt_right == NULL) { if (pt_parent == &pt_avl_tree->_t_avlroot) { /* * P P * | => * X */ pt_parent->_pt_parent = NULL; } else if (pt_cur == pt_parent->_pt_left) { /* * P P * / => * X */ pt_parent->_pt_left = NULL; } else { /* * P P * \ => * X */ pt_parent->_pt_right = NULL; } } else if (pt_cur->_pt_left != NULL && pt_cur->_pt_right == NULL) { if (pt_parent == &pt_avl_tree->_t_avlroot) { /* * P P * | | * X => L * / * L */ pt_parent->_pt_parent = pt_cur->_pt_left; pt_parent->_pt_parent->_pt_parent = pt_parent; } else if (pt_cur == pt_parent->_pt_left) { /* * P P * / / * X => L * / * L */ pt_parent->_pt_left = pt_cur->_pt_left; pt_parent->_pt_left->_pt_parent = pt_parent; } else { /* * P P * \ \ * X => L * / * L */ pt_parent->_pt_right = pt_cur->_pt_left; pt_parent->_pt_right->_pt_parent = pt_parent; } } else if (pt_cur->_pt_left == NULL && pt_cur->_pt_right != NULL) { if (pt_parent == &pt_avl_tree->_t_avlroot) { /* * P P * | | * X => R * \ * R */ pt_parent->_pt_parent = pt_cur->_pt_right; pt_parent->_pt_parent->_pt_parent = pt_parent; } else if (pt_cur == pt_parent->_pt_right) { /* * P P * \ \ * X => R * \ * R */ pt_parent->_pt_right = pt_cur->_pt_right; pt_parent->_pt_right->_pt_parent = pt_parent; } else { /* * P R * / / * X => R * \ * R */ pt_parent->_pt_left = pt_cur->_pt_right; pt_parent->_pt_left->_pt_parent = pt_parent; } } else { _avlnode_t* pt_parenttmp = NULL; _avlnode_t* pt_curtmp = NULL; if (pt_parent == &pt_avl_tree->_t_avlroot) { pt_curtmp = _avl_tree_get_min_avlnode(pt_cur->_pt_right); if (pt_cur == pt_curtmp->_pt_parent) { /* * P P * | | * X => B * / \ / \ * A B A C * \ * C */ /* pt_curtmp express B */ pt_curtmp->_pt_left = pt_cur->_pt_left; pt_curtmp->_pt_left->_pt_parent = pt_curtmp; pt_curtmp->_pt_parent = pt_cur->_pt_parent; pt_curtmp->_pt_parent->_pt_parent = pt_curtmp; pt_parent = pt_curtmp; } else { /* * P P * | | * X => S * / \ / \ * A B A B * / \ / \ * S C D C * \ * D */ /* pt_curtmp express S; pt_parenttmp express B */ pt_parenttmp = pt_curtmp->_pt_parent; pt_parenttmp->_pt_left = pt_curtmp->_pt_right; if (pt_parenttmp->_pt_left != NULL) { pt_parenttmp->_pt_left->_pt_parent = pt_parenttmp; } pt_curtmp->_pt_left = pt_cur->_pt_left; pt_curtmp->_pt_left->_pt_parent = pt_curtmp; pt_curtmp->_pt_right = pt_cur->_pt_right; pt_curtmp->_pt_right->_pt_parent = pt_curtmp; pt_curtmp->_pt_parent = pt_cur->_pt_parent; pt_curtmp->_pt_parent->_pt_parent = pt_curtmp; pt_parent = pt_parenttmp; } } else if (pt_cur == pt_parent->_pt_left) { pt_curtmp = _avl_tree_get_min_avlnode(pt_cur->_pt_right); if (pt_cur == pt_curtmp->_pt_parent) { /* * P P * / / * X => B * / \ / \ * A B A C * \ * C */ /* pt_curtmp express B */ pt_curtmp->_pt_left = pt_cur->_pt_left; pt_curtmp->_pt_left->_pt_parent = pt_curtmp; pt_curtmp->_pt_parent = pt_cur->_pt_parent; pt_curtmp->_pt_parent->_pt_left = pt_curtmp; pt_parent = pt_curtmp; } else { /* * P P * / / * X => S * / \ / \ * A B A B * / \ / \ * S C D C * \ * D */ /* pt_curtmp express S; pt_parenttmp express B */ pt_parenttmp = pt_curtmp->_pt_parent; pt_parenttmp->_pt_left = pt_curtmp->_pt_right; if (pt_parenttmp->_pt_left != NULL) { pt_parenttmp->_pt_left->_pt_parent = pt_parenttmp; } pt_curtmp->_pt_left = pt_cur->_pt_left; pt_curtmp->_pt_left->_pt_parent = pt_curtmp; pt_curtmp->_pt_right = pt_cur->_pt_right; pt_curtmp->_pt_right->_pt_parent = pt_curtmp; pt_curtmp->_pt_parent = pt_cur->_pt_parent; pt_curtmp->_pt_parent->_pt_left = pt_curtmp; pt_parent = pt_parenttmp; } } else { pt_curtmp = _avl_tree_get_min_avlnode(pt_cur->_pt_right); if (pt_cur == pt_curtmp->_pt_parent) { /* * P P * \ \ * X => B * / \ / \ * A B A C * \ * C */ /* pt_curtmp express B */ pt_curtmp->_pt_left = pt_cur->_pt_left; pt_curtmp->_pt_left->_pt_parent = pt_curtmp; pt_curtmp->_pt_parent = pt_cur->_pt_parent; pt_curtmp->_pt_parent->_pt_right = pt_curtmp; pt_parent = pt_curtmp; } else { /* * P P * \ \ * X => S * / \ / \ * A B A B * / \ / \ * C D C D * / \ / \ * S E F E * \ * F */ /* pt_curtmp express S; pt_parenttmp express C */ pt_parenttmp = pt_curtmp->_pt_parent; pt_parenttmp->_pt_left = pt_curtmp->_pt_right; if (pt_parenttmp->_pt_left != NULL) { pt_parenttmp->_pt_left->_pt_parent = pt_parenttmp; } pt_curtmp->_pt_left = pt_cur->_pt_left; pt_curtmp->_pt_left->_pt_parent = pt_curtmp; pt_curtmp->_pt_right = pt_cur->_pt_right; pt_curtmp->_pt_right->_pt_parent = pt_curtmp; pt_curtmp->_pt_parent = pt_cur->_pt_parent; pt_curtmp->_pt_parent->_pt_right = pt_curtmp; pt_parent = pt_parenttmp; } } } /* rebalance until to root */ if (pt_parent != &pt_avl_tree->_t_avlroot) { _avlnode_t* pt_newcur = pt_parent; pt_parent = pt_newcur->_pt_parent; while (pt_parent != &pt_avl_tree->_t_avlroot) { if (pt_newcur == pt_parent->_pt_left) { pt_parent->_pt_left = _avl_tree_rebalance(pt_parent->_pt_left); pt_parent->_pt_left->_pt_parent = pt_parent; } else { pt_parent->_pt_right = _avl_tree_rebalance(pt_parent->_pt_right); pt_parent->_pt_right->_pt_parent = pt_parent; } pt_newcur = pt_parent; pt_parent = pt_newcur->_pt_parent; } } /* rebalance root */ if (pt_parent->_pt_parent != NULL) { pt_parent->_pt_parent = _avl_tree_rebalance(pt_parent->_pt_parent); pt_parent->_pt_parent->_pt_parent = pt_parent; } /* destroy node */ b_result = _GET_AVL_TREE_TYPE_SIZE(pt_avl_tree); _GET_AVL_TREE_TYPE_DESTROY_FUNCTION(pt_avl_tree)(pt_cur->_pby_data, &b_result); assert(b_result); _alloc_deallocate(&pt_avl_tree->_t_allocator, pt_cur, _AVL_TREE_NODE_SIZE(_GET_AVL_TREE_TYPE_SIZE(pt_avl_tree)), 1); pt_avl_tree->_t_nodecount--; if (pt_avl_tree->_t_nodecount == 0) { pt_avl_tree->_t_avlroot._pt_parent = NULL; pt_avl_tree->_t_avlroot._pt_left = &pt_avl_tree->_t_avlroot; pt_avl_tree->_t_avlroot._pt_right = &pt_avl_tree->_t_avlroot; } else { pt_avl_tree->_t_avlroot._pt_left = _avl_tree_get_min_avlnode(pt_avl_tree->_t_avlroot._pt_parent); pt_avl_tree->_t_avlroot._pt_right = _avl_tree_get_max_avlnode(pt_avl_tree->_t_avlroot._pt_parent); } }