/** * Finds the position of the first element in an ordered range that has a value greater than or equivalent to a specified value, * where the ordering criterion may be specified by a binary predicate. */ forward_iterator_t _algo_lower_bound_if_varg(forward_iterator_t it_first, forward_iterator_t it_last, bfun_t bfun_op, va_list val_elemlist) { void* pv_value = NULL; bool_t b_result = false; size_t t_len = 0; size_t t_halflen = 0; iterator_t it_middle; assert(_iterator_valid_range(it_first, it_last, _FORWARD_ITERATOR)); if (bfun_op == NULL) { bfun_op = _fun_get_binary(it_first, _LESS_FUN); } pv_value = _iterator_allocate_init_elem(it_first); _type_get_varg_value(_iterator_get_typeinfo(it_first), val_elemlist, pv_value); if (strncmp(_iterator_get_typebasename(it_first), _C_STRING_TYPE, _TYPE_NAME_SIZE) == 0) { t_len = iterator_distance(it_first, it_last); while (t_len > 0) { t_halflen = t_len >> 1; it_middle = iterator_advance(it_first, t_halflen); (*bfun_op)(iterator_get_pointer(it_middle), string_c_str((string_t*)pv_value), &b_result); if (b_result) { /* *it_middle < value */ it_first = iterator_next(it_middle); t_len = t_len - t_halflen - 1; } else { t_len = t_halflen; } } } else {
/** * 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); } }
int main(int argc, char* argv[]) { int i = 0; int n = 101; int last = n - 1; DList* dlist = dlist_create(NULL, NULL); for (i = 0; i < n; i++) { dlist_append(dlist, (void*)i); } Iterator* forward = dlist_iterator_create(dlist); Iterator* backward = dlist_iterator_create(dlist); iterator_advance(backward, last); invert(forward, backward); dlist_foreach(dlist, check_and_dec_int, &last); iterator_destroy(forward); iterator_destroy(backward); dlist_destroy(dlist); return 0; }
/** * Quick sort or heap sort for specify range. */ void _algo_intro_sort_if( random_access_iterator_t it_first, random_access_iterator_t it_last, bfun_t bfun_op, size_t t_depth, void* pv_value) { iterator_t it_pivot; iterator_t it_begin; iterator_t it_end; iterator_t it_prev; bool_t b_result = false; assert(_iterator_valid_range(it_first, it_last, _RANDOM_ACCESS_ITERATOR)); assert(pv_value != NULL); assert(bfun_op != NULL); if (iterator_distance(it_first, it_last) < 2) { return; } if (t_depth == 0){ /* do heap sort */ algo_partial_sort_if(it_first, it_last, it_last, bfun_op); return; } t_depth--; it_pivot = iterator_advance(it_first, iterator_distance(it_first, it_last) / 2); it_prev = iterator_prev(it_last); it_pivot = _algo_median_of_three_if(it_first, it_pivot, it_prev, bfun_op); /* the pv_value must be string_t type when the container type is char* */ if (strncmp(_iterator_get_typebasename(it_first), _C_STRING_TYPE, _TYPE_NAME_SIZE) == 0) { string_assign_cstr((string_t*)pv_value, (char*)iterator_get_pointer(it_pivot)); it_begin = it_first; it_end = it_last; for (;;) { /* move begin */ (*bfun_op)(iterator_get_pointer(it_begin), string_c_str((string_t*)pv_value), &b_result); while (b_result) { it_begin = iterator_next(it_begin); (*bfun_op)(iterator_get_pointer(it_begin), string_c_str((string_t*)pv_value), &b_result); } /* move end */ it_end = iterator_prev(it_end); (*bfun_op)(string_c_str((string_t*)pv_value), iterator_get_pointer(it_end), &b_result); while (b_result) { it_end = iterator_prev(it_end); (*bfun_op)(string_c_str((string_t*)pv_value), iterator_get_pointer(it_end), &b_result); } /* across */ if (!iterator_less(it_begin, it_end)) { it_pivot = it_begin; break; } else { algo_iter_swap(it_begin, it_end); it_begin = iterator_next(it_begin); } } } else { iterator_get_value(it_pivot, pv_value); it_begin = it_first; it_end = it_last; for (;;) { /* move begin */ (*bfun_op)(iterator_get_pointer(it_begin), pv_value, &b_result); while (b_result) { it_begin = iterator_next(it_begin); (*bfun_op)(iterator_get_pointer(it_begin), pv_value, &b_result); } /* move end */ it_end = iterator_prev(it_end); (*bfun_op)(pv_value, iterator_get_pointer(it_end), &b_result); while (b_result) { it_end = iterator_prev(it_end); (*bfun_op)(pv_value, iterator_get_pointer(it_end), &b_result); } /* across */ if (!iterator_less(it_begin, it_end)) { it_pivot = it_begin; break; } else { algo_iter_swap(it_begin, it_end); it_begin = iterator_next(it_begin); } } } /* sort [it_first, it_pivot) */ _algo_intro_sort_if(it_first, it_pivot, bfun_op, t_depth, pv_value); /* sort [it_pivot, it_last) */ _algo_intro_sort_if(it_pivot, it_last, bfun_op, t_depth, pv_value); }