/**
 * 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 {
Example #2
0
/**
 * 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);
    }
}
Example #3
0
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;
}
Example #4
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);
}