/**
 * Test the first iterator is before the second.
 */
bool_t _rb_tree_iterator_before(_rb_tree_iterator_t it_first, _rb_tree_iterator_t it_second)
{
    _rb_tree_iterator_t it_iter;
    _rb_tree_t*         pt_rb_tree = NULL;

    assert(_rb_tree_iterator_belong_to_rb_tree(_RB_TREE_ITERATOR_TREE(it_first), it_first));
    assert(_rb_tree_iterator_belong_to_rb_tree(_RB_TREE_ITERATOR_TREE(it_second), it_second));
    assert(_RB_TREE_ITERATOR_TREE(it_first) == _RB_TREE_ITERATOR_TREE(it_second));

    /* first iterator equal to second iterator */
    if (_RB_TREE_ITERATOR_COREPOS(it_first) == _RB_TREE_ITERATOR_COREPOS(it_second)) {
        return false;
    }
    /* else travel subtree for search second iterator */
    pt_rb_tree = _RB_TREE_ITERATOR_TREE(it_first);
    for (it_iter = it_first;
         !_rb_tree_iterator_equal(it_iter, _rb_tree_end(pt_rb_tree));
         it_iter = _rb_tree_iterator_next(it_iter)) {
        if (_rb_tree_iterator_equal(it_iter, it_second)) {
            return true;
        }
    }

    return _rb_tree_iterator_equal(it_second, _rb_tree_end(pt_rb_tree)) ? true : false;
}
/**
 * Return iterator reference next element.
 */
_rb_tree_iterator_t _rb_tree_iterator_next(_rb_tree_iterator_t it_iter)
{
    _rbnode_t* pt_next = NULL;  /* next pos */
    _rbnode_t* pt_cur = (_rbnode_t*)_RB_TREE_ITERATOR_COREPOS(it_iter);

    assert(_rb_tree_iterator_belong_to_rb_tree(_RB_TREE_ITERATOR_TREE(it_iter), it_iter));
    assert(!_rb_tree_iterator_equal(it_iter, _rb_tree_end(_RB_TREE_ITERATOR_TREE(it_iter))));

    if (pt_cur->_pt_right != NULL) {
        pt_next = pt_cur->_pt_right;
        while (pt_next->_pt_left != NULL) {
            pt_next = pt_next->_pt_left;
        }

        _RB_TREE_ITERATOR_COREPOS(it_iter) = (_byte_t*)pt_next;
    } else {
        pt_next = pt_cur->_pt_parent;
        while (pt_cur == pt_next->_pt_right) {
            pt_cur = pt_next;
            pt_next = pt_next->_pt_parent;
        }
        /* 
         * this is special condition, when the next pos is root's parent.
         * when the rb tree has only one node, this condition is came.
         */
        if (pt_cur->_pt_right != pt_next) {
            _RB_TREE_ITERATOR_COREPOS(it_iter) = (_byte_t*)pt_next;
        } else {
            _RB_TREE_ITERATOR_COREPOS(it_iter) = (_byte_t*)pt_cur;
        }
    }

    return it_iter;
}
/**
 * Get data value pointer referenced by iterator, but ignore char*.
 */
const void* _rb_tree_iterator_get_pointer_ignore_cstr(_rb_tree_iterator_t it_iter)
{
    assert(_rb_tree_iterator_belong_to_rb_tree(_RB_TREE_ITERATOR_TREE(it_iter), it_iter));
    assert(!_rb_tree_iterator_equal(it_iter, _rb_tree_end(_RB_TREE_ITERATOR_TREE(it_iter))));

    return ((_rbnode_t*)_RB_TREE_ITERATOR_COREPOS(it_iter))->_pby_data;
}
/**
 * Get data value pointer referenced by iterator.
 */
const void* _rb_tree_iterator_get_pointer(_rb_tree_iterator_t it_iter)
{
    assert(_rb_tree_iterator_belong_to_rb_tree(_RB_TREE_ITERATOR_TREE(it_iter), it_iter));
    assert(!_rb_tree_iterator_equal(it_iter, _rb_tree_end(_RB_TREE_ITERATOR_TREE(it_iter))));

    /* char* */
    if (strncmp(_GET_RB_TREE_TYPE_BASENAME(_RB_TREE_ITERATOR_TREE(it_iter)), _C_STRING_TYPE, _TYPE_NAME_SIZE) == 0) {
        return (char*)string_c_str((string_t*)((_rbnode_t*)_RB_TREE_ITERATOR_COREPOS(it_iter))->_pby_data);
    } else {
        return ((_rbnode_t*)_RB_TREE_ITERATOR_COREPOS(it_iter))->_pby_data;
    }
}
void test__rb_tree_iterator_next__end(void** state)
{
    _rb_tree_t* pt_rb_tree = _create_rb_tree("int");
    _rb_tree_iterator_t it_iter;
    _rb_tree_init(pt_rb_tree, NULL);

    it_iter = _rb_tree_end(pt_rb_tree);

    expect_assert_failure(_rb_tree_iterator_next(it_iter));

    _rb_tree_destroy(pt_rb_tree);
}
void test__rb_tree_iterator_get_value__null_value(void** state)
{
    _rb_tree_t* pt_rb_tree = _create_rb_tree("int");
    _rb_tree_iterator_t it_iter;
    _rb_tree_init(pt_rb_tree, NULL);

    it_iter = _rb_tree_end(pt_rb_tree);

    expect_assert_failure(_rb_tree_iterator_get_value(it_iter, NULL));

    _rb_tree_destroy(pt_rb_tree);
}
void test__rb_tree_iterator_prev__end(void** state)
{
    _rb_tree_t* pt_rb_tree = _create_rb_tree("int");
    _rb_tree_iterator_t it_iter;
    int elem = 10;
    _rb_tree_init(pt_rb_tree, NULL);

    _rb_tree_insert_unique(pt_rb_tree, &elem);
    it_iter = _rb_tree_end(pt_rb_tree);

    it_iter = _rb_tree_iterator_prev(it_iter);
    assert_true(_rb_tree_iterator_equal(it_iter, _rb_tree_begin(pt_rb_tree)));

    _rb_tree_destroy(pt_rb_tree);
}
/**
 * Get data value referenced by iterator.
 */
void _rb_tree_iterator_get_value(_rb_tree_iterator_t it_iter, void* pv_value)
{
    assert(pv_value != NULL);
    assert(_rb_tree_iterator_belong_to_rb_tree(_RB_TREE_ITERATOR_TREE(it_iter), it_iter));
    assert(!_rb_tree_iterator_equal(it_iter, _rb_tree_end(_RB_TREE_ITERATOR_TREE(it_iter))));

    /* char* */
    if (strncmp(_GET_RB_TREE_TYPE_BASENAME(_RB_TREE_ITERATOR_TREE(it_iter)), _C_STRING_TYPE, _TYPE_NAME_SIZE) == 0) {
        *(char**)pv_value = (char*)string_c_str((string_t*)((_rbnode_t*)_RB_TREE_ITERATOR_COREPOS(it_iter))->_pby_data);
    } else {
        bool_t b_result = _GET_RB_TREE_TYPE_SIZE(_RB_TREE_ITERATOR_TREE(it_iter));
        _GET_RB_TREE_TYPE_COPY_FUNCTION(_RB_TREE_ITERATOR_TREE(it_iter))(
            pv_value, ((_rbnode_t*)_RB_TREE_ITERATOR_COREPOS(it_iter))->_pby_data, &b_result);
        assert(b_result);
    }
}
void test__rb_tree_iterator_before__false(void** state)
{
    _rb_tree_t* pt_rb_tree = _create_rb_tree("int");
    _rb_tree_iterator_t it_first;
    _rb_tree_iterator_t it_second;
    int elem = 100;

    _rb_tree_init(pt_rb_tree, NULL);
    _rb_tree_insert_unique(pt_rb_tree, &elem);
    elem = 2;
    _rb_tree_insert_unique(pt_rb_tree, &elem);
    it_first = _rb_tree_end(pt_rb_tree);
    it_second = _rb_tree_begin(pt_rb_tree);
    assert_false(_rb_tree_iterator_before(it_first, it_second));

    _rb_tree_destroy(pt_rb_tree);
}
void test__rb_tree_iterator_prev__last(void** state)
{
    _rb_tree_t* pt_rb_tree = _create_rb_tree("int");
    _rb_tree_iterator_t it_iter;
    int elem = 10;
    _rb_tree_init(pt_rb_tree, NULL);

    _rb_tree_insert_unique(pt_rb_tree, &elem);
    elem = 3;
    _rb_tree_insert_unique(pt_rb_tree, &elem);
    it_iter = _rb_tree_iterator_prev(_rb_tree_end(pt_rb_tree));
    assert_true(*(int*)_rb_tree_iterator_get_pointer(it_iter) == 10);
    it_iter = _rb_tree_iterator_prev(it_iter);
    assert_true(*(int*)_rb_tree_iterator_get_pointer(it_iter) == 3);

    _rb_tree_destroy(pt_rb_tree);
}
Beispiel #11
0
multimap_iterator_t multimap_end(const multimap_t* cpt_multimap)
{
    multimap_iterator_t t_newiterator;

    assert(cpt_multimap != NULL);

#ifdef CSTL_MULTIMAP_AVL_TREE
    t_newiterator = _avl_tree_end(_GET_MULTIMAP_AVL_TREE(cpt_multimap));
#else
    t_newiterator = _rb_tree_end(_GET_MULTIMAP_RB_TREE(cpt_multimap));
#endif

    _GET_CONTAINER(&t_newiterator) = (multimap_t*)cpt_multimap;
    _GET_MULTIMAP_CONTAINER_TYPE(&t_newiterator) = _MULTIMAP_CONTAINER;
    _GET_MULTIMAP_ITERATOR_TYPE(&t_newiterator) = _BIDIRECTIONAL_ITERATOR;

    return t_newiterator;
}
Beispiel #12
0
/**
 * Return an iterator that addresses the location succeeding the last element in the set.
 */
set_iterator_t set_end(const set_t* cpset_set)
{
    set_iterator_t it_end;

    assert(cpset_set != NULL);

#ifdef CSTL_SET_AVL_TREE
    it_end = _avl_tree_end(&cpset_set->_t_tree);
#else
    it_end = _rb_tree_end(&cpset_set->_t_tree);
#endif

    _ITERATOR_CONTAINER(it_end) = (set_t*)cpset_set;
    _SET_ITERATOR_CONTAINER_TYPE(it_end) = _SET_CONTAINER;
    _SET_ITERATOR_ITERATOR_TYPE(it_end) = _BIDIRECTIONAL_ITERATOR;

    return it_end;
}
/**
 * Return iterator reference previous element.
 */
_rb_tree_iterator_t _rb_tree_iterator_prev(_rb_tree_iterator_t it_iter)
{
    _rbnode_t* pt_prev = NULL;
    _rbnode_t* pt_cur = (_rbnode_t*)_RB_TREE_ITERATOR_COREPOS(it_iter);

    assert(_rb_tree_iterator_belong_to_rb_tree(_RB_TREE_ITERATOR_TREE(it_iter), it_iter));
    assert(!_rb_tree_iterator_equal(it_iter, _rb_tree_begin(_RB_TREE_ITERATOR_TREE(it_iter))));

    /* previous end */
    if(_rb_tree_iterator_equal(it_iter, _rb_tree_end(_RB_TREE_ITERATOR_TREE(it_iter))))
    {
        _RB_TREE_ITERATOR_COREPOS(it_iter) = (_byte_t*)_RB_TREE_ITERATOR_TREE(it_iter)->_t_rbroot._pt_right;
    }
    else
    {
        if(pt_cur->_pt_left != NULL)
        {
            pt_prev = pt_cur->_pt_left;
            while(pt_prev->_pt_right != NULL)
            {
                pt_prev = pt_prev->_pt_right;
            }

            _RB_TREE_ITERATOR_COREPOS(it_iter) = (_byte_t*)pt_prev;
        }
        else
        {
            pt_prev = pt_cur->_pt_parent;
            while(pt_cur == pt_prev->_pt_left)
            {
                pt_cur = pt_prev;
                pt_prev = pt_prev->_pt_parent;
            }

            /* 
             * there is no same special condition as next, because the begin 
             * iterator is the valid iterator 
             */
            _RB_TREE_ITERATOR_COREPOS(it_iter) = (_byte_t*)pt_prev;
        }
    }

    return it_iter;
}
Beispiel #14
0
/**
 * Return an iterator that addresses the location succeeding the last element in the map.
 */
map_iterator_t map_end(const map_t* cpmap_map)
{
    map_iterator_t it_end;

    assert(cpmap_map != NULL);
    assert(_pair_is_inited(&cpmap_map->_pair_temp));

#ifdef CSTL_MAP_AVL_TREE
    it_end = _avl_tree_end(&cpmap_map->_t_tree);
#else
    it_end = _rb_tree_end(&cpmap_map->_t_tree);
#endif

    _GET_CONTAINER(it_end) = (map_t*)cpmap_map;
    _GET_MAP_CONTAINER_TYPE(it_end) = _MAP_CONTAINER;
    _GET_MAP_ITERATOR_TYPE(it_end) = _BIDIRECTIONAL_ITERATOR;

    return it_end;
}