/** * 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; }
/** * 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); }
/** * 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); } }
/** * 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); }
/** * 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; }
/** * 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; }
/** * 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); } }
/** * 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; } }
/** * Insert the value into subtree. */ _avl_tree_insert_result_t _avl_tree_insert_avlnode( const _avl_tree_t* cpt_avl_tree, _avlnode_t* pt_root, const void* cpv_value) { _avl_tree_insert_result_t t_insert_result; bool_t b_result = false; assert(cpt_avl_tree != NULL); assert(cpv_value != NULL); assert(_avl_tree_is_inited(cpt_avl_tree)); /* if root is NULL then allocate memory */ if(pt_root == NULL) { pt_root = _alloc_allocate( (_alloc_t*)&cpt_avl_tree->_t_allocator, _AVL_TREE_NODE_SIZE(_GET_AVL_TREE_TYPE_SIZE(cpt_avl_tree)), 1); assert(pt_root != NULL); _avl_tree_init_elem_auxiliary((_avl_tree_t*)cpt_avl_tree, pt_root); pt_root->_pt_left = pt_root->_pt_right = NULL; pt_root->_un_height = 0; t_insert_result._pt_adjust = pt_root; t_insert_result._pt_new = pt_root; b_result = _GET_AVL_TREE_TYPE_SIZE(cpt_avl_tree); _GET_AVL_TREE_TYPE_COPY_FUNCTION(cpt_avl_tree)(pt_root->_pby_data, cpv_value, &b_result); assert(b_result); return t_insert_result; } /* compare the value and current node */ /* if value < current node then insert into left subtree */ b_result = _GET_AVL_TREE_TYPE_SIZE(cpt_avl_tree); _avl_tree_elem_compare_auxiliary(cpt_avl_tree, cpv_value, pt_root->_pby_data, &b_result); if(b_result) { t_insert_result = _avl_tree_insert_avlnode(cpt_avl_tree, pt_root->_pt_left, cpv_value); pt_root->_pt_left = t_insert_result._pt_adjust; pt_root->_pt_left->_pt_parent = pt_root; pt_root = _avl_tree_rebalance(pt_root); t_insert_result._pt_adjust = pt_root; return t_insert_result; } /* else insert into right subtree */ else { t_insert_result = _avl_tree_insert_avlnode(cpt_avl_tree, pt_root->_pt_right, cpv_value); pt_root->_pt_right = t_insert_result._pt_adjust; pt_root->_pt_right->_pt_parent = pt_root; pt_root = _avl_tree_rebalance(pt_root); t_insert_result._pt_adjust = pt_root; return t_insert_result; } }
bool_t _type_register( size_t t_typesize, const char* s_typename, ufun_t t_typeinit, bfun_t t_typecopy, bfun_t t_typeless, ufun_t t_typedestroy) { char s_formalname[_TYPE_NAME_SIZE + 1]; _typestyle_t t_style = _TYPE_INVALID; if (!_gt_typeregister._t_isinit) { _type_init(); } /* the main aim is getting formal name */ t_style = _type_get_style(s_typename, s_formalname); if (t_style == _TYPE_INVALID || _type_is_registered(s_formalname) != NULL || strlen(s_typename) > _TYPE_NAME_SIZE) { return false; } else { size_t t_pos = 0; _typenode_t* pt_node = (_typenode_t*)_alloc_allocate(&_gt_typeregister._t_allocator, sizeof(_typenode_t), 1); _type_t* pt_type = (_type_t*)_alloc_allocate(&_gt_typeregister._t_allocator, sizeof(_type_t), 1); memset(pt_node->_s_typename, '\0', _TYPE_NAME_SIZE + 1); memset(pt_type->_s_typename, '\0', _TYPE_NAME_SIZE + 1); /* register the new type */ strncpy(pt_node->_s_typename, s_formalname, _TYPE_NAME_SIZE); strncpy(pt_type->_s_typename, s_formalname, _TYPE_NAME_SIZE); pt_type->_t_typesize = t_typesize; pt_type->_t_style = t_style; /* save type style for type duplication between different type style */ pt_type->_t_typeinit = t_typeinit != NULL ? t_typeinit : _type_init_default; pt_type->_t_typecopy = t_typecopy != NULL ? t_typecopy : _type_copy_default; pt_type->_t_typeless = t_typeless != NULL ? t_typeless : _type_less_default; pt_type->_t_typedestroy = t_typedestroy != NULL ? t_typedestroy : _type_destroy_default; pt_node->_pt_type = pt_type; t_pos = _type_hash(s_formalname); pt_node->_pt_next = _gt_typeregister._apt_bucket[t_pos]; _gt_typeregister._apt_bucket[t_pos] = pt_node; return true; } }
/** * 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); } }
/** * 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); } }
/** * Add specificed element from variable argument slist at the begin of slist container. */ void _slist_push_front_varg(slist_t* pslist_slist, va_list val_elemlist) { _slistnode_t* pt_node = NULL; assert(pslist_slist != NULL); assert(_slist_is_inited(pslist_slist)); /* allocate memory for new element and copy the element from elemlist */ pt_node = _alloc_allocate(&pslist_slist->_t_allocator, _SLIST_NODE_SIZE(_GET_SLIST_TYPE_SIZE(pslist_slist)), 1); assert(pt_node != NULL); _slist_get_varg_value_auxiliary(pslist_slist, val_elemlist, pt_node); /* insert the element after the head */ pt_node->_pt_next = pslist_slist->_t_head._pt_next; pslist_slist->_t_head._pt_next = pt_node; }
/** * Initialize vector container with mutiple default element. */ void vector_init_n(vector_t* pvec_vector, size_t t_count) { assert(pvec_vector != NULL); assert(_vector_is_created(pvec_vector)); if(t_count > 0) { size_t t_newcapacity = _vector_calculate_new_capacity(0, t_count); pvec_vector->_pby_start = _alloc_allocate(&pvec_vector->_t_allocator, _GET_VECTOR_TYPE_SIZE(pvec_vector), t_newcapacity); assert(pvec_vector->_pby_start != NULL); pvec_vector->_pby_finish = pvec_vector->_pby_start + _GET_VECTOR_TYPE_SIZE(pvec_vector) * t_count; pvec_vector->_pby_endofstorage = pvec_vector->_pby_start + _GET_VECTOR_TYPE_SIZE(pvec_vector) * t_newcapacity; /* initialize all elements */ _vector_init_elem_range_auxiliary(pvec_vector, pvec_vector->_pby_start, pvec_vector->_pby_finish); } }
/** * 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; }
/** * 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; }
bool_t _type_duplicate( size_t t_typesize1, const char* s_typename1, size_t t_typesize2, const char* s_typename2) { _type_t* pt_registered1 = NULL; _type_t* pt_registered2 = false; char s_formalname1[_TYPE_NAME_SIZE + 1]; char s_formalname2[_TYPE_NAME_SIZE + 1]; assert(s_typename1 != NULL); assert(s_typename2 != NULL); if (!_gt_typeregister._t_isinit) { _type_init(); } if (strlen(s_typename1) > _TYPE_NAME_SIZE || strlen(s_typename2) > _TYPE_NAME_SIZE || t_typesize1 != t_typesize2) { return false; } _type_get_style(s_typename1, s_formalname1); _type_get_style(s_typename2, s_formalname2); /* test the type1 and type2 is registered or not */ pt_registered1 = _type_is_registered(s_formalname1); pt_registered2 = _type_is_registered(s_formalname2); if (pt_registered1 == NULL && pt_registered2 == NULL) { /* type1 and type2 all unregistered */ return false; } else if (pt_registered1 != NULL && pt_registered2 != NULL) { /* type1 and type2 all registered */ return pt_registered1 == pt_registered2 ? true : false; } else { /* only one type is registered */ size_t t_pos = 0; char* s_duplicatename = NULL; _typenode_t* pt_duplicate = NULL; _type_t* pt_type = NULL; if (pt_registered1 != NULL && pt_registered2 == NULL) { /* type1 is registered and type2 is unregistered */ pt_type = pt_registered1; s_duplicatename = s_formalname2; } else { /* type1 is unregistered and type2 is registered */ pt_type = pt_registered2; s_duplicatename = s_formalname1; } /* malloc typenode for unregistered type */ pt_duplicate = (_typenode_t*)_alloc_allocate(&_gt_typeregister._t_allocator, sizeof(_typenode_t), 1); memset(pt_duplicate->_s_typename, '\0', _TYPE_NAME_SIZE + 1); strncpy(pt_duplicate->_s_typename, s_duplicatename, _TYPE_NAME_SIZE); pt_duplicate->_pt_type = pt_type; t_pos = _type_hash(s_duplicatename); pt_duplicate->_pt_next = _gt_typeregister._apt_bucket[t_pos]; _gt_typeregister._apt_bucket[t_pos] = pt_duplicate; return true; } }
/** * Inserts an element into a hashtable. */ _hashtable_iterator_t _hashtable_insert_equal(_hashtable_t* pt_hashtable, const void* cpv_value) { size_t t_bucketcount = 0; _hashnode_t* pt_node = NULL; _hashnode_t* pt_cur = NULL; _hashnode_t** ppt_nodelist = NULL; _hashtable_iterator_t it_iter = _create_hashtable_iterator(); bool_t b_result = false; size_t t_tmp = 0; size_t t_pos = 0; bool_t b_less = false; bool_t b_greater = false; assert(pt_hashtable != NULL); assert(cpv_value != NULL); assert(_hashtable_is_inited(pt_hashtable)); /* resize */ _hashtable_resize(pt_hashtable, _hashtable_size(pt_hashtable) + 1); /* allocate node */ pt_node = _alloc_allocate( &pt_hashtable->_t_allocator, _HASHTABLE_NODE_SIZE(_GET_HASHTABLE_TYPE_SIZE(pt_hashtable)), 1); assert(pt_node != NULL); _hashtable_init_elem_auxiliary(pt_hashtable, pt_node); b_result = _GET_HASHTABLE_TYPE_SIZE(pt_hashtable); _GET_HASHTABLE_TYPE_COPY_FUNCTION(pt_hashtable)(pt_node->_pby_data, cpv_value, &b_result); assert(b_result); /* hash */ t_bucketcount = _hashtable_bucket_count(pt_hashtable); t_tmp = _GET_HASHTABLE_TYPE_SIZE(pt_hashtable); _hashtable_hash_auxiliary(pt_hashtable, pt_node->_pby_data, &t_tmp); t_pos = t_tmp % t_bucketcount; /* insert node into hashtable, note the node has same value together */ ppt_nodelist = (_hashnode_t**)vector_at(&pt_hashtable->_vec_bucket, t_pos); assert(ppt_nodelist != NULL); pt_cur = *ppt_nodelist; if(pt_cur == NULL) { pt_node->_pt_next = pt_cur; *ppt_nodelist = pt_node; } else { b_less = b_greater = _GET_HASHTABLE_TYPE_SIZE(pt_hashtable); _hashtable_elem_compare_auxiliary(pt_hashtable, pt_cur->_pby_data, pt_node->_pby_data, &b_less); _hashtable_elem_compare_auxiliary(pt_hashtable, pt_node->_pby_data, pt_cur->_pby_data, &b_greater); if(!b_less && !b_greater) { pt_node->_pt_next = pt_cur; *ppt_nodelist = pt_node; } else { while(pt_cur->_pt_next != NULL) { b_less = b_greater = _GET_HASHTABLE_TYPE_SIZE(pt_hashtable); _hashtable_elem_compare_auxiliary( pt_hashtable, pt_cur->_pt_next->_pby_data, pt_node->_pby_data, &b_less); _hashtable_elem_compare_auxiliary( pt_hashtable, pt_node->_pby_data, pt_cur->_pt_next->_pby_data, &b_greater); if(b_less || b_greater) { pt_cur = pt_cur->_pt_next; } else { break; } } pt_node->_pt_next = pt_cur->_pt_next; pt_cur->_pt_next = pt_node; } } pt_hashtable->_t_nodecount++; _GET_HASHTABLE_BUCKETPOS(it_iter) = (_byte_t*)ppt_nodelist; _GET_HASHTABLE_COREPOS(it_iter) = (_byte_t*)pt_node; _GET_HASHTABLE_POINTER(it_iter) = pt_hashtable; return it_iter; }
/** * Initialize an element according to the type of iterator pointed data. */ void* _iterator_allocate_init_elem(iterator_t it_iter) { void* pv_value = NULL; assert(_iterator_is_valid(it_iter)); switch (it_iter._t_containertype) { case _VECTOR_CONTAINER: pv_value = _alloc_allocate(&((vector_t*)it_iter._pt_container)->_t_allocator, ((vector_t*)it_iter._pt_container)->_t_typeinfo._pt_type->_t_typesize, 1); _vector_init_elem_auxiliary((vector_t*)it_iter._pt_container, pv_value); break; case _DEQUE_CONTAINER: pv_value = _alloc_allocate(&((deque_t*)it_iter._pt_container)->_t_allocator, ((deque_t*)it_iter._pt_container)->_t_typeinfo._pt_type->_t_typesize, 1); _deque_init_elem_auxiliary((deque_t*)it_iter._pt_container, pv_value); break; case _BASIC_STRING_CONTAINER: pv_value = _alloc_allocate(&((basic_string_t*)it_iter._pt_container)->_vec_base._t_allocator, ((basic_string_t*)it_iter._pt_container)->_vec_base._t_typeinfo._pt_type->_t_typesize, 1); _basic_string_init_elem_auxiliary((basic_string_t*)it_iter._pt_container, pv_value); break; case _LIST_CONTAINER: pv_value = _alloc_allocate(&((list_t*)it_iter._pt_container)->_t_allocator, ((list_t*)it_iter._pt_container)->_t_typeinfo._pt_type->_t_typesize, 1); _list_init_elem_auxiliary((list_t*)it_iter._pt_container, pv_value); break; case _SLIST_CONTAINER: pv_value = _alloc_allocate(&((slist_t*)it_iter._pt_container)->_t_allocator, ((slist_t*)it_iter._pt_container)->_t_typeinfo._pt_type->_t_typesize, 1); _slist_init_elem_auxiliary((slist_t*)it_iter._pt_container, pv_value); break; case _SET_CONTAINER: pv_value = _alloc_allocate(&((set_t*)it_iter._pt_container)->_t_tree._t_allocator, ((set_t*)it_iter._pt_container)->_t_tree._t_typeinfo._pt_type->_t_typesize, 1); _set_init_elem_auxiliary((set_t*)it_iter._pt_container, pv_value); break; case _MULTISET_CONTAINER: pv_value = _alloc_allocate(&((multiset_t*)it_iter._pt_container)->_t_tree._t_allocator, ((set_t*)it_iter._pt_container)->_t_tree._t_typeinfo._pt_type->_t_typesize, 1); _multiset_init_elem_auxiliary((multiset_t*)it_iter._pt_container, pv_value); break; case _MAP_CONTAINER: pv_value = _alloc_allocate(&((map_t*)it_iter._pt_container)->_t_tree._t_allocator, ((map_t*)it_iter._pt_container)->_t_tree._t_typeinfo._pt_type->_t_typesize, 1); _map_init_elem_auxiliary((map_t*)it_iter._pt_container, pv_value); break; case _MULTIMAP_CONTAINER: pv_value = _alloc_allocate(&((multimap_t*)it_iter._pt_container)->_t_tree._t_allocator, ((multimap_t*)it_iter._pt_container)->_t_tree._t_typeinfo._pt_type->_t_typesize, 1); _multimap_init_elem_auxiliary((multimap_t*)it_iter._pt_container, pv_value); break; case _HASH_SET_CONTAINER: pv_value = _alloc_allocate(&((hash_set_t*)it_iter._pt_container)->_t_hashtable._t_allocator, ((hash_set_t*)it_iter._pt_container)->_t_hashtable._t_typeinfo._pt_type->_t_typesize, 1); _hash_set_init_elem_auxiliary((hash_set_t*)it_iter._pt_container, pv_value); break; case _HASH_MULTISET_CONTAINER: pv_value = _alloc_allocate(&((hash_multiset_t*)it_iter._pt_container)->_t_hashtable._t_allocator, ((hash_multiset_t*)it_iter._pt_container)->_t_hashtable._t_typeinfo._pt_type->_t_typesize, 1); _hash_multiset_init_elem_auxiliary((hash_multiset_t*)it_iter._pt_container, pv_value); break; case _HASH_MAP_CONTAINER: pv_value = _alloc_allocate(&((hash_map_t*)it_iter._pt_container)->_t_hashtable._t_allocator, ((hash_map_t*)it_iter._pt_container)->_t_hashtable._t_typeinfo._pt_type->_t_typesize, 1); _hash_map_init_elem_auxiliary((hash_map_t*)it_iter._pt_container, pv_value); break; case _HASH_MULTIMAP_CONTAINER: pv_value = _alloc_allocate(&((hash_multimap_t*)it_iter._pt_container)->_t_hashtable._t_allocator, ((hash_multimap_t*)it_iter._pt_container)->_t_hashtable._t_typeinfo._pt_type->_t_typesize, 1); _hash_multimap_init_elem_auxiliary((hash_multimap_t*)it_iter._pt_container, pv_value); break; default: assert(false); pv_value = NULL; break; } return pv_value; }
/** * 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; }
/** * Insert the value into subtree. */ _rbnode_t* _rb_tree_insert_rbnode(_rb_tree_t* pt_rb_tree, const void* cpv_value) { _rbnode_t* pt_parent = NULL; _rbnode_t* pt_cur = NULL; bool_t b_result = false; bool_t b_less = false; assert(pt_rb_tree != NULL); assert(cpv_value != NULL); assert(_rb_tree_is_inited(pt_rb_tree)); /* if the rb tree is empty */ if(_rb_tree_empty(pt_rb_tree)) { /* allocat a new root */ pt_cur = _alloc_allocate( (_alloc_t*)&pt_rb_tree->_t_allocator, _RB_TREE_NODE_SIZE(_GET_RB_TREE_TYPE_SIZE(pt_rb_tree)), 1); assert(pt_cur != NULL); _rb_tree_init_elem_auxiliary(pt_rb_tree, pt_cur); /* set its color is BLACK */ pt_cur->_pt_left = pt_cur->_pt_right = NULL; pt_cur->_t_color = BLACK; pt_cur->_pt_parent = (_rbnode_t*)&pt_rb_tree->_t_rbroot; b_result = _GET_RB_TREE_TYPE_SIZE(pt_rb_tree); _GET_RB_TREE_TYPE_COPY_FUNCTION(pt_rb_tree)(pt_cur->_pby_data, cpv_value, &b_result); assert(b_result); /* insert the node */ pt_rb_tree->_t_rbroot._pt_parent = pt_cur; } else { pt_parent = pt_rb_tree->_t_rbroot._pt_parent; b_less = _GET_RB_TREE_TYPE_SIZE(pt_rb_tree); _rb_tree_elem_compare_auxiliary(pt_rb_tree, cpv_value, pt_parent->_pby_data, &b_less); if(b_less) { pt_cur = pt_parent->_pt_left; } else { pt_cur = pt_parent->_pt_right; } /* from the root to insert position */ while(pt_cur != NULL) { /* next current position */ pt_parent = pt_cur; b_less = _GET_RB_TREE_TYPE_SIZE(pt_rb_tree); _rb_tree_elem_compare_auxiliary(pt_rb_tree, cpv_value, pt_parent->_pby_data, &b_less); if(b_less) { pt_cur = pt_parent->_pt_left; } else { pt_cur = pt_parent->_pt_right; } } /* allocate new node */ pt_cur = _alloc_allocate( (_alloc_t*)&pt_rb_tree->_t_allocator, _RB_TREE_NODE_SIZE(_GET_RB_TREE_TYPE_SIZE(pt_rb_tree)), 1); assert(pt_cur != NULL); _rb_tree_init_elem_auxiliary(pt_rb_tree, pt_cur); pt_cur->_pt_left = pt_cur->_pt_right = NULL; pt_cur->_t_color = RED; pt_cur->_pt_parent = pt_parent; b_result = _GET_RB_TREE_TYPE_SIZE(pt_rb_tree); _GET_RB_TREE_TYPE_COPY_FUNCTION(pt_rb_tree)(pt_cur->_pby_data, cpv_value, &b_result); assert(b_result); if(b_less) { assert(pt_parent->_pt_left == NULL); pt_parent->_pt_left = pt_cur; } else { assert(pt_parent->_pt_right == NULL); pt_parent->_pt_right = pt_cur; } if(_rb_tree_get_color(pt_parent) == RED) { _rb_tree_rebalance(pt_rb_tree, pt_cur); } } return pt_cur; }