/** * 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; } }
/** * Transfer the range [it_begin, it_end) to position it_pos. */ void _slist_transfer(slist_iterator_t it_pos, slist_iterator_t it_begin, slist_iterator_t it_end) { assert(_slist_iterator_belong_to_slist(_SLIST_ITERATOR_CONTAINER(it_pos), it_pos)); assert(_slist_iterator_belong_to_slist(_SLIST_ITERATOR_CONTAINER(it_begin), it_begin)); assert(_slist_iterator_belong_to_slist(_SLIST_ITERATOR_CONTAINER(it_end), it_end)); assert(_SLIST_ITERATOR_CONTAINER(it_begin) == _SLIST_ITERATOR_CONTAINER(it_end)); assert(iterator_equal(it_begin, it_end) || _slist_iterator_before(it_begin, it_end)); assert(_slist_same_slist_iterator_type(_SLIST_ITERATOR_CONTAINER(it_pos), it_begin)); /* empty range */ if(iterator_equal(it_begin, it_end)) { return; } /* same slist container */ if(_SLIST_ITERATOR_CONTAINER(it_pos) == _SLIST_ITERATOR_CONTAINER(it_begin)) { assert(iterator_equal(it_pos, it_begin) || iterator_equal(it_pos, it_end) || _slist_iterator_before(it_pos, it_begin) || _slist_iterator_before(it_end, it_pos)); if(iterator_equal(it_pos, it_begin) || iterator_equal(it_pos, it_end)) { return; } } slist_insert_range(_SLIST_ITERATOR_CONTAINER(it_pos), it_pos, it_begin, it_end); slist_erase_range(_SLIST_ITERATOR_CONTAINER(it_begin), it_begin, it_end); }
/** * 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; }
/** * Insert multiple copys of element befor specificed position. */ void _slist_insert_n(slist_t* pslist_slist, slist_iterator_t it_pos, size_t t_count, ...) { va_list val_elemlist; /* test the slist pointer and pos is valid */ assert(pslist_slist != NULL); assert(_slist_is_inited(pslist_slist)); assert(_slist_iterator_belong_to_slist(pslist_slist, it_pos)); /* if the pos is slist begin */ va_start(val_elemlist, t_count); if (iterator_equal(it_pos, slist_begin(pslist_slist))) { size_t i = 0; /* call slist push front t_count times */ for (i = 0; i < t_count; ++i) { va_list val_elemlist_copy; va_copy(val_elemlist_copy, val_elemlist); _slist_push_front_varg(pslist_slist, val_elemlist_copy); va_end(val_elemlist_copy); } } else { _slist_insert_after_n_varg(pslist_slist, slist_previous(pslist_slist, it_pos), t_count, val_elemlist); } va_end(val_elemlist); }
/** * 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; }
/** * 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 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; }
/** * 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; } }
/** * Insert multiple copys of element after specificed position. */ void _slist_insert_after_n(slist_t* pslist_slist, slist_iterator_t it_pos, size_t t_count, ...) { va_list val_elemlist; 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))); va_start(val_elemlist, t_count); _slist_insert_after_n_varg(pslist_slist, it_pos, t_count, val_elemlist); va_end(val_elemlist); }
/** * Insert one copy of element after specificed position. */ slist_iterator_t _slist_insert_after(slist_t* pslist_slist, slist_iterator_t it_pos, ...) { va_list val_elemlist; 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))); va_start(val_elemlist, it_pos); _slist_insert_after_n_varg(pslist_slist, it_pos, 1, val_elemlist); va_end(val_elemlist); return iterator_next(it_pos); }
/** * 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); } }
/** * Insert one copy of element befor specificed position. */ slist_iterator_t _slist_insert(slist_t* pslist_slist, slist_iterator_t it_pos, ...) { va_list val_elemlist; assert(pslist_slist != NULL); assert(_slist_is_inited(pslist_slist)); assert(_slist_iterator_belong_to_slist(pslist_slist, it_pos)); /* if the pos is slist begin iterator */ va_start(val_elemlist, it_pos); if (iterator_equal(it_pos, slist_begin(pslist_slist))) { /* call push front */ _slist_push_front_varg(pslist_slist, val_elemlist); } else { /* call insert_after */ _slist_insert_after_n_varg(pslist_slist, slist_previous(pslist_slist, it_pos), 1, val_elemlist); } va_end(val_elemlist); /* return the new element iterator */ return slist_previous(pslist_slist, it_pos); }
/** * 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); }