/** * 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); }
/** * Calculate distance between two iterators. */ int _slist_iterator_distance(slist_iterator_t it_first, slist_iterator_t it_second) { int n_distance = 0; _slistnode_t* pt_node = NULL; assert(_iterator_same_type(it_first, it_second)); assert(_SLIST_ITERATOR_CONTAINER(it_first) == _SLIST_ITERATOR_CONTAINER(it_second)); assert(_slist_iterator_belong_to_slist(_SLIST_ITERATOR_CONTAINER(it_first), it_first)); assert(_slist_iterator_belong_to_slist(_SLIST_ITERATOR_CONTAINER(it_second), it_second)); if (_slist_iterator_before(it_first, it_second)) { for (pt_node = (_slistnode_t*)_SLIST_ITERATOR_COREPOS(it_first); pt_node != (_slistnode_t*)_SLIST_ITERATOR_COREPOS(it_second); pt_node = pt_node->_pt_next) { n_distance++; } return n_distance; } else if (_slist_iterator_before(it_second, it_first)) { for (pt_node = (_slistnode_t*)_SLIST_ITERATOR_COREPOS(it_second); pt_node != (_slistnode_t*)_SLIST_ITERATOR_COREPOS(it_first); pt_node = pt_node->_pt_next) { n_distance++; } return -n_distance; } else { return 0; } }
/** * Test iterator referenced data is within the slist. */ bool_t _slist_iterator_belong_to_slist(const slist_t* cpslist_slist, slist_iterator_t it_iter) { _slistnode_t* pt_node = NULL; assert(cpslist_slist != NULL); assert(_slist_is_inited(cpslist_slist)); assert(_SLIST_ITERATOR_CONTAINER(it_iter) == cpslist_slist); assert(_SLIST_ITERATOR_CONTAINER_TYPE(it_iter) == _SLIST_CONTAINER); assert(_SLIST_ITERATOR_ITERATOR_TYPE(it_iter) == _FORWARD_ITERATOR); /* the end iterator of slist corepos is NULL */ if(_SLIST_ITERATOR_COREPOS(it_iter) == NULL) { return true; } for(pt_node = cpslist_slist->_t_head._pt_next; pt_node != NULL; pt_node = pt_node->_pt_next) { if(pt_node == (_slistnode_t*)_SLIST_ITERATOR_COREPOS(it_iter)) { return true; } } return false; }
/** * Return iterator reference next element. */ slist_iterator_t _slist_iterator_next(slist_iterator_t it_iter) { assert(_slist_iterator_belong_to_slist(_SLIST_ITERATOR_CONTAINER(it_iter), it_iter)); assert(!iterator_equal(it_iter, slist_end(_SLIST_ITERATOR_CONTAINER(it_iter)))); _SLIST_ITERATOR_COREPOS(it_iter) = (_byte_t*)(((_slistnode_t*)_SLIST_ITERATOR_COREPOS(it_iter))->_pt_next); return it_iter; }
/** * Test the two slist iterator are equal. */ bool_t _slist_iterator_equal(slist_iterator_t it_first, slist_iterator_t it_second) { assert(_iterator_same_type(it_first, it_second)); assert(_SLIST_ITERATOR_CONTAINER(it_first) == _SLIST_ITERATOR_CONTAINER(it_second)); assert(_slist_iterator_belong_to_slist(_SLIST_ITERATOR_CONTAINER(it_first), it_first)); assert(_slist_iterator_belong_to_slist(_SLIST_ITERATOR_CONTAINER(it_second), it_second)); return _SLIST_ITERATOR_COREPOS(it_first) == _SLIST_ITERATOR_COREPOS(it_second) ? true : false; }
/** * Get data value pointer referenced by iterator. */ const void* _slist_iterator_get_pointer(slist_iterator_t it_iter) { assert(_slist_iterator_belong_to_slist(_SLIST_ITERATOR_CONTAINER(it_iter), it_iter)); assert(!iterator_equal(it_iter, slist_end(_SLIST_ITERATOR_CONTAINER(it_iter)))); /* char* */ if (strncmp(_GET_SLIST_TYPE_BASENAME(_SLIST_ITERATOR_CONTAINER(it_iter)), _C_STRING_TYPE, _TYPE_NAME_SIZE) == 0) { return string_c_str((string_t*)((_slistnode_t*)_SLIST_ITERATOR_COREPOS(it_iter))->_pby_data); } else { return ((_slistnode_t*)_SLIST_ITERATOR_COREPOS(it_iter))->_pby_data; } }
/** * 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 data value referenced by iterator. */ void _slist_iterator_set_value(slist_iterator_t it_iter, const void* cpv_value) { assert(cpv_value != NULL); assert(_slist_iterator_belong_to_slist(_SLIST_ITERATOR_CONTAINER(it_iter), it_iter)); assert(!iterator_equal(it_iter, slist_end(_SLIST_ITERATOR_CONTAINER(it_iter)))); /* char* */ if (strncmp(_GET_SLIST_TYPE_BASENAME(_SLIST_ITERATOR_CONTAINER(it_iter)), _C_STRING_TYPE, _TYPE_NAME_SIZE) == 0) { string_assign_cstr((string_t*)((_slistnode_t*)_SLIST_ITERATOR_COREPOS(it_iter))->_pby_data, (char*)cpv_value); } else { bool_t b_result = _GET_SLIST_TYPE_SIZE(_SLIST_ITERATOR_CONTAINER(it_iter)); _GET_SLIST_TYPE_COPY_FUNCTION(_SLIST_ITERATOR_CONTAINER(it_iter))( ((_slistnode_t*)_SLIST_ITERATOR_COREPOS(it_iter))->_pby_data, cpv_value, &b_result); assert(b_result); } }
/** * Get data value pointer referenced by iterator, but ignore char*. */ const void* _slist_iterator_get_pointer_ignore_cstr(slist_iterator_t it_iter) { assert(_slist_iterator_belong_to_slist(_SLIST_ITERATOR_CONTAINER(it_iter), it_iter)); assert(!iterator_equal(it_iter, slist_end(_SLIST_ITERATOR_CONTAINER(it_iter)))); return ((_slistnode_t*)_SLIST_ITERATOR_COREPOS(it_iter))->_pby_data; }
/** * 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); } }
/** * Create slist iterator. */ slist_iterator_t _create_slist_iterator(void) { slist_iterator_t it_iter; _SLIST_ITERATOR_ITERATOR_TYPE(it_iter) = _FORWARD_ITERATOR; _SLIST_ITERATOR_CONTAINER_TYPE(it_iter) = _SLIST_CONTAINER; _ITERATOR_CONTAINER(it_iter) = NULL; _SLIST_ITERATOR_COREPOS(it_iter) = NULL; return it_iter; }
/** * Test the first iterator is before the second. */ bool_t _slist_iterator_before(slist_iterator_t it_first, slist_iterator_t it_second) { _slistnode_t* pt_node = NULL; assert(_iterator_same_type(it_first, it_second)); assert(_SLIST_ITERATOR_CONTAINER(it_first) == _SLIST_ITERATOR_CONTAINER(it_second)); assert(_slist_iterator_belong_to_slist(_SLIST_ITERATOR_CONTAINER(it_first), it_first)); assert(_slist_iterator_belong_to_slist(_SLIST_ITERATOR_CONTAINER(it_second), it_second)); if (_SLIST_ITERATOR_COREPOS(it_first) == _SLIST_ITERATOR_COREPOS(it_second)) { return false; } for (pt_node = (_slistnode_t*)_SLIST_ITERATOR_COREPOS(it_first); pt_node != NULL; pt_node = pt_node->_pt_next) { if (pt_node == (_slistnode_t*)_SLIST_ITERATOR_COREPOS(it_second)) { return true; } } return _SLIST_ITERATOR_COREPOS(it_second) == NULL ? true : false; }
/** * 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); }