multimap_iterator_t multimap_insert_hint( multimap_t* pt_multimap, multimap_iterator_t t_hint, const pair_t* cpt_pair) { pair_t t_elempair; assert(pt_multimap != NULL && cpt_pair != NULL); assert(_same_multimap_pair_type(&pt_multimap->_t_pair, cpt_pair)); /* initialize the new pair */ t_elempair = _create_pair( pt_multimap->_t_pair._t_firsttypesize, pt_multimap->_t_pair._sz_firsttypename, pt_multimap->_t_pair._t_secondtypesize, pt_multimap->_t_pair._sz_secondtypename); pair_init(&t_elempair); memcpy(t_elempair.first, cpt_pair->first, t_elempair._t_firsttypesize); memcpy(t_elempair.second, cpt_pair->second, t_elempair._t_secondtypesize); /* insert pair into tree */ #ifdef CSTL_MULTIMAP_AVL_TREE t_hint = _avl_tree_insert_equal(_GET_MULTIMAP_AVL_TREE(pt_multimap), &t_elempair); #else t_hint = _rb_tree_insert_equal(_GET_MULTIMAP_RB_TREE(pt_multimap), &t_elempair); #endif /* * There is no need for destroy the elempair, because the pair is copied * to the tree, and it is destroied by tree when tree is desroied. */ _GET_CONTAINER(&t_hint) = pt_multimap; _GET_MULTIMAP_CONTAINER_TYPE(&t_hint) = _MULTIMAP_CONTAINER; _GET_MULTIMAP_ITERATOR_TYPE(&t_hint) = _BIDIRECTIONAL_ITERATOR; return t_hint; }
multimap_iterator_t _multimap_upper_bound_varg( const multimap_t* cpt_multimap, va_list val_elemlist) { multimap_iterator_t t_iterator; assert(cpt_multimap != NULL); _get_varg_value( cpt_multimap->_t_pair.first, val_elemlist, cpt_multimap->_t_pair._t_firsttypesize, cpt_multimap->_t_pair._sz_firsttypename); #ifdef CSTL_MULTIMAP_AVL_TREE t_iterator = _avl_tree_upper_bound( _GET_MULTIMAP_AVL_TREE(cpt_multimap), &cpt_multimap->_t_pair); #else t_iterator = _rb_tree_upper_bound( _GET_MULTIMAP_RB_TREE(cpt_multimap), &cpt_multimap->_t_pair); #endif _GET_CONTAINER(&t_iterator) = (multimap_t*)cpt_multimap; _GET_MULTIMAP_CONTAINER_TYPE(&t_iterator) = _MULTIMAP_CONTAINER; _GET_MULTIMAP_ITERATOR_TYPE(&t_iterator) = _BIDIRECTIONAL_ITERATOR; return t_iterator; }
int _multimap_iterator_distance( const multimap_iterator_t* cpt_begin, const multimap_iterator_t* cpt_end) { assert(cpt_begin != NULL && cpt_end != NULL); assert( _GET_MULTIMAP_CONTAINER_TYPE(cpt_begin) == _MULTIMAP_CONTAINER && _GET_MULTIMAP_ITERATOR_TYPE(cpt_begin) == _BIDIRECTIONAL_ITERATOR && _GET_MULTIMAP_CONTAINER_TYPE(cpt_end) == _MULTIMAP_CONTAINER && _GET_MULTIMAP_ITERATOR_TYPE(cpt_end) == _BIDIRECTIONAL_ITERATOR && _GET_MULTIMAP_CONTAINER(cpt_begin) == _GET_MULTIMAP_CONTAINER(cpt_end)); #ifdef CSTL_MULTIMAP_AVL_TREE return _avl_tree_iterator_distance(cpt_begin, cpt_end); #else return _rb_tree_iterator_distance(cpt_begin, cpt_end); #endif }
pair_t _multimap_equal_range_varg( const multimap_t* cpt_multimap, va_list val_elemlist) { multimap_iterator_t t_first; multimap_iterator_t t_second; pair_t t_pair; #ifdef CSTL_MULTIMAP_AVL_TREE avl_tree_result_pair_t t_avlresult; #else rb_tree_result_pair_t t_rbresult; #endif assert(cpt_multimap != NULL); _get_varg_value( cpt_multimap->_t_pair.first, val_elemlist, cpt_multimap->_t_pair._t_firsttypesize, cpt_multimap->_t_pair._sz_firsttypename); #ifdef CSTL_MULTIMAP_AVL_TREE t_avlresult = _avl_tree_equal_range( _GET_MULTIMAP_AVL_TREE(cpt_multimap), &cpt_multimap->_t_pair); t_first = t_avlresult._t_first; t_second = t_avlresult._t_second._t_iterator; #else t_rbresult = _rb_tree_equal_range( _GET_MULTIMAP_RB_TREE(cpt_multimap), &cpt_multimap->_t_pair); t_first = t_rbresult._t_first; t_second = t_rbresult._t_second._t_iterator; #endif _GET_CONTAINER(&t_first) = (multimap_t*)cpt_multimap; _GET_MULTIMAP_CONTAINER_TYPE(&t_first) = _MULTIMAP_CONTAINER; _GET_MULTIMAP_ITERATOR_TYPE(&t_first) = _BIDIRECTIONAL_ITERATOR; _GET_CONTAINER(&t_second) = (multimap_t*)cpt_multimap; _GET_MULTIMAP_CONTAINER_TYPE(&t_second) = _MULTIMAP_CONTAINER; _GET_MULTIMAP_ITERATOR_TYPE(&t_second) = _BIDIRECTIONAL_ITERATOR; t_pair = create_pair(multimap_iterator_t, multimap_iterator_t); pair_init(&t_pair); memcpy(t_pair.first, &t_first, t_pair._t_firsttypesize); memcpy(t_pair.second, &t_second, t_pair._t_secondtypesize); return t_pair; }
bool_t _multimap_iterator_before( const multimap_iterator_t* cpt_iteratorfirst, const multimap_iterator_t* cpt_iteratorsecond) { assert(cpt_iteratorfirst != NULL && cpt_iteratorsecond != NULL); assert( _GET_MULTIMAP_CONTAINER_TYPE(cpt_iteratorfirst) == _MULTIMAP_CONTAINER && _GET_MULTIMAP_ITERATOR_TYPE(cpt_iteratorfirst) == _BIDIRECTIONAL_ITERATOR && _GET_MULTIMAP_CONTAINER_TYPE(cpt_iteratorsecond) == _MULTIMAP_CONTAINER && _GET_MULTIMAP_ITERATOR_TYPE(cpt_iteratorsecond) == _BIDIRECTIONAL_ITERATOR && _GET_MULTIMAP_CONTAINER(cpt_iteratorfirst) == _GET_MULTIMAP_CONTAINER(cpt_iteratorsecond)); #ifdef CSTL_MULTIMAP_AVL_TREE return _avl_tree_iterator_before(cpt_iteratorfirst, cpt_iteratorsecond); #else return _rb_tree_iterator_before(cpt_iteratorfirst, cpt_iteratorsecond); #endif }
void multimap_erase_range( multimap_t* pt_multimap, multimap_iterator_t t_begin, multimap_iterator_t t_end) { assert(pt_multimap != NULL); assert( _GET_MULTIMAP_CONTAINER_TYPE(&t_begin) == _MULTIMAP_CONTAINER && _GET_MULTIMAP_ITERATOR_TYPE(&t_begin) == _BIDIRECTIONAL_ITERATOR && _GET_MULTIMAP_CONTAINER_TYPE(&t_end) == _MULTIMAP_CONTAINER && _GET_MULTIMAP_ITERATOR_TYPE(&t_end) == _BIDIRECTIONAL_ITERATOR); assert( _GET_MULTIMAP_CONTAINER(&t_begin) == pt_multimap && _GET_MULTIMAP_CONTAINER(&t_end) == pt_multimap); #ifdef CSTL_MULTIMAP_AVL_TREE _avl_tree_erase_range(_GET_MULTIMAP_AVL_TREE(pt_multimap), t_begin, t_end); #else _rb_tree_erase_range(_GET_MULTIMAP_RB_TREE(pt_multimap), t_begin, t_end); #endif }
void multimap_init_copy_range_cmp( multimap_t* pt_multimapdest, multimap_iterator_t t_begin, multimap_iterator_t t_end, int (*pfun_key_cmp)(const void*, const void*)) { assert(pt_multimapdest != NULL); assert( _GET_MULTIMAP_CONTAINER_TYPE(&t_begin) == _MULTIMAP_CONTAINER && _GET_MULTIMAP_ITERATOR_TYPE(&t_begin) == _BIDIRECTIONAL_ITERATOR && _GET_MULTIMAP_CONTAINER_TYPE(&t_end) == _MULTIMAP_CONTAINER && _GET_MULTIMAP_ITERATOR_TYPE(&t_end) == _BIDIRECTIONAL_ITERATOR); assert( _GET_MULTIMAP_CONTAINER(&t_begin) != pt_multimapdest && _GET_MULTIMAP_CONTAINER(&t_end) != pt_multimapdest && _GET_MULTIMAP_CONTAINER(&t_begin) == _GET_MULTIMAP_CONTAINER(&t_end)); assert( pt_multimapdest->_t_pair._t_firsttypesize == _GET_MULTIMAP_CONTAINER(&t_begin)->_t_pair._t_firsttypesize && pt_multimapdest->_t_pair._t_secondtypesize == _GET_MULTIMAP_CONTAINER(&t_begin)->_t_pair._t_secondtypesize); assert( strncmp( pt_multimapdest->_t_pair._sz_firsttypename, _GET_MULTIMAP_CONTAINER(&t_begin)->_t_pair._sz_firsttypename, _ELEM_TYPE_NAME_SIZE) == 0 && strncmp( pt_multimapdest->_t_pair._sz_secondtypename, _GET_MULTIMAP_CONTAINER(&t_begin)->_t_pair._sz_secondtypename, _ELEM_TYPE_NAME_SIZE) == 0); /* initialize dest multimap with src multimap attribute */ multimap_init(pt_multimapdest); pt_multimapdest->_t_pair._pfun_first_cmp = pfun_key_cmp; /* insert all element from src to dest */ if(!multimap_empty(_GET_MULTIMAP_CONTAINER(&t_begin))) { multimap_insert_range(pt_multimapdest, t_begin, t_end); } }
bool_t _multimap_iterator_equal( const struct _tagmultimap* cpt_multimap, const multimap_iterator_t* cpt_iterator, multimap_iterator_t t_iterator) { assert(cpt_multimap != NULL && cpt_iterator != NULL); assert( _GET_MULTIMAP_CONTAINER_TYPE(cpt_iterator) == _MULTIMAP_CONTAINER && _GET_MULTIMAP_ITERATOR_TYPE(cpt_iterator) == _BIDIRECTIONAL_ITERATOR && _GET_MULTIMAP_CONTAINER_TYPE(&t_iterator) == _MULTIMAP_CONTAINER && _GET_MULTIMAP_ITERATOR_TYPE(&t_iterator) == _BIDIRECTIONAL_ITERATOR); assert( _GET_MULTIMAP_CONTAINER(cpt_iterator) == cpt_multimap && _GET_MULTIMAP_CONTAINER(&t_iterator) == cpt_multimap); #ifdef CSTL_MULTIMAP_AVL_TREE return _avl_tree_iterator_equal( _GET_MULTIMAP_AVL_TREE(cpt_multimap), cpt_iterator, t_iterator); #else return _rb_tree_iterator_equal( _GET_MULTIMAP_RB_TREE(cpt_multimap), cpt_iterator, t_iterator); #endif }
/** * Return an iterator range that is equal to a specific element. */ range_t _multimap_equal_range_varg(const multimap_t* cpmmap_map, va_list val_elemlist) { range_t r_range; assert(cpmmap_map != NULL); assert(_pair_is_inited(&cpmmap_map->_pair_temp)); _type_get_varg_value(&((multimap_t*)cpmmap_map)->_pair_temp._t_typeinfofirst, val_elemlist, cpmmap_map->_pair_temp._pv_first); #ifdef CSTL_MULTIMAP_AVL_TREE r_range = _avl_tree_equal_range(&cpmmap_map->_t_tree, &cpmmap_map->_pair_temp); #else r_range = _rb_tree_equal_range(&cpmmap_map->_t_tree, &cpmmap_map->_pair_temp); #endif _GET_CONTAINER(r_range.it_begin) = (multimap_t*)cpmmap_map; _GET_MULTIMAP_CONTAINER_TYPE(r_range.it_begin) = _MULTIMAP_CONTAINER; _GET_MULTIMAP_ITERATOR_TYPE(r_range.it_begin) = _BIDIRECTIONAL_ITERATOR; _GET_CONTAINER(r_range.it_end) = (multimap_t*)cpmmap_map; _GET_MULTIMAP_CONTAINER_TYPE(r_range.it_end) = _MULTIMAP_CONTAINER; _GET_MULTIMAP_ITERATOR_TYPE(r_range.it_end) = _BIDIRECTIONAL_ITERATOR; return r_range; }
void multimap_insert_range( multimap_t* pt_multimap, multimap_iterator_t t_begin, multimap_iterator_t t_end) { multimap_iterator_t t_iterator; assert(pt_multimap != NULL); assert( _GET_MULTIMAP_CONTAINER_TYPE(&t_begin) == _MULTIMAP_CONTAINER && _GET_MULTIMAP_ITERATOR_TYPE(&t_begin) == _BIDIRECTIONAL_ITERATOR && _GET_MULTIMAP_CONTAINER_TYPE(&t_end) == _MULTIMAP_CONTAINER && _GET_MULTIMAP_ITERATOR_TYPE(&t_end) == _BIDIRECTIONAL_ITERATOR); assert( _GET_MULTIMAP_CONTAINER(&t_begin) != pt_multimap && _GET_MULTIMAP_CONTAINER(&t_end) != pt_multimap && _GET_MULTIMAP_CONTAINER(&t_begin) == _GET_MULTIMAP_CONTAINER(&t_end)); for(t_iterator = t_begin; !iterator_equal(&t_iterator, t_end); iterator_next(&t_iterator)) { multimap_insert( pt_multimap, (pair_t*)iterator_get_pointer(&t_iterator)); } }
/* multimap iterator function */ multimap_iterator_t create_multimap_iterator(void) { multimap_iterator_t t_newiterator; #ifdef CSTL_MULTIMAP_AVL_TREE t_newiterator = _create_avl_tree_iterator(); #else t_newiterator = _create_rb_tree_iterator(); #endif _GET_MULTIMAP_CONTAINER_TYPE(&t_newiterator) = _MULTIMAP_CONTAINER; _GET_MULTIMAP_ITERATOR_TYPE(&t_newiterator) = _BIDIRECTIONAL_ITERATOR; return t_newiterator; }
void _multimap_iterator_prev( const struct _tagmultimap* cpt_multimap, multimap_iterator_t* pt_iterator) { assert(cpt_multimap != NULL && pt_iterator != NULL); assert( _GET_MULTIMAP_CONTAINER_TYPE(pt_iterator) == _MULTIMAP_CONTAINER && _GET_MULTIMAP_ITERATOR_TYPE(pt_iterator) == _BIDIRECTIONAL_ITERATOR && _GET_MULTIMAP_CONTAINER(pt_iterator) == cpt_multimap); #ifdef CSTL_MULTIMAP_AVL_TREE _avl_tree_iterator_prev(_GET_MULTIMAP_AVL_TREE(cpt_multimap), pt_iterator); #else _rb_tree_iterator_prev(_GET_MULTIMAP_RB_TREE(cpt_multimap), pt_iterator); #endif }
multimap_reverse_iterator_t multimap_rend(const multimap_t* cpt_multimap) { multimap_reverse_iterator_t t_newiterator; assert(cpt_multimap != NULL); #ifdef CSTL_MULTIMAP_AVL_TREE t_newiterator = _avl_tree_rend(_GET_MULTIMAP_AVL_TREE(cpt_multimap)); #else t_newiterator = _rb_tree_rend(_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; }
void _multimap_iterator_get_value( const struct _tagmultimap* cpt_multimap, const multimap_iterator_t* cpt_iterator, void* pv_value) { assert(cpt_multimap != NULL && cpt_iterator != NULL && pv_value != NULL); assert( _GET_MULTIMAP_CONTAINER_TYPE(cpt_iterator) == _MULTIMAP_CONTAINER && _GET_MULTIMAP_ITERATOR_TYPE(cpt_iterator) == _BIDIRECTIONAL_ITERATOR && _GET_MULTIMAP_CONTAINER(cpt_iterator) == cpt_multimap); #ifdef CSTL_MULTIMAP_AVL_TREE _avl_tree_iterator_get_value( _GET_MULTIMAP_AVL_TREE(cpt_multimap), cpt_iterator, pv_value); #else _rb_tree_iterator_get_value( _GET_MULTIMAP_RB_TREE(cpt_multimap), cpt_iterator, pv_value); #endif }
/** * Return an iterator to the first element that is greater than a specific element. */ multimap_iterator_t _multimap_upper_bound_varg(const multimap_t* cpmmap_map, va_list val_elemlist) { multimap_iterator_t it_iter; assert(cpmmap_map != NULL); assert(_pair_is_inited(&cpmmap_map->_pair_temp)); _type_get_varg_value(&((multimap_t*)cpmmap_map)->_pair_temp._t_typeinfofirst, val_elemlist, cpmmap_map->_pair_temp._pv_first); #ifdef CSTL_MULTIMAP_AVL_TREE it_iter = _avl_tree_upper_bound(&cpmmap_map->_t_tree, &cpmmap_map->_pair_temp); #else it_iter = _rb_tree_upper_bound(&cpmmap_map->_t_tree, &cpmmap_map->_pair_temp); #endif _GET_CONTAINER(it_iter) = (multimap_t*)cpmmap_map; _GET_MULTIMAP_CONTAINER_TYPE(it_iter) = _MULTIMAP_CONTAINER; _GET_MULTIMAP_ITERATOR_TYPE(it_iter) = _BIDIRECTIONAL_ITERATOR; return it_iter; }