/** * Assign vector element with an exist vector container range. */ void vector_assign_range(vector_t* pvec_vector, vector_iterator_t it_begin, vector_iterator_t it_end) { iterator_t it_dest; iterator_t it_src; bool_t b_result = false; /* assign the two iterator is as the same type as pvec_vector */ assert(pvec_vector != NULL); assert(_vector_is_inited(pvec_vector)); /*assert(!_vector_iterator_belong_to_vector(pvec_vector, it_begin));*/ /*assert(!_vector_iterator_belong_to_vector(pvec_vector, it_end));*/ assert(_vector_same_vector_iterator_type(pvec_vector, it_begin)); assert(_vector_same_vector_iterator_type(pvec_vector, it_end)); assert(iterator_equal(it_begin, it_end) || _vector_iterator_before(it_begin, it_end)); /* copy value from range [it_begin, it_end) for each element */ vector_resize(pvec_vector, iterator_distance(it_begin, it_end)); for(it_dest = vector_begin(pvec_vector), it_src = it_begin; !iterator_equal(it_dest, vector_end(pvec_vector)) && !iterator_equal(it_src, it_end); it_dest = iterator_next(it_dest), it_src = iterator_next(it_src)) { b_result = _GET_VECTOR_TYPE_SIZE(pvec_vector); _GET_VECTOR_TYPE_COPY_FUNCTION(pvec_vector)(_VECTOR_ITERATOR_COREPOS(it_dest), _VECTOR_ITERATOR_COREPOS(it_src), &b_result); assert(b_result); } assert(iterator_equal(it_dest, vector_end(pvec_vector)) && iterator_equal(it_src, it_end)); }
/** * Initialize vector container with an exist vector range. */ void vector_init_copy_range(vector_t* pvec_dest, vector_iterator_t it_begin, vector_iterator_t it_end) { vector_iterator_t it_dest; vector_iterator_t it_src; bool_t b_result = false; assert(pvec_dest != NULL); assert(_vector_is_created(pvec_dest)); assert(_vector_iterator_belong_to_vector(_VECTOR_ITERATOR_CONTAINER(it_begin), it_begin)); assert(_vector_iterator_belong_to_vector(_VECTOR_ITERATOR_CONTAINER(it_end), it_end)); assert(iterator_equal(it_begin, it_end) || _vector_iterator_before(it_begin, it_end)); assert(_vector_same_vector_iterator_type(pvec_dest, it_begin)); assert(_vector_same_vector_iterator_type(pvec_dest, it_end)); /* initialize all elements with default value */ vector_init_n(pvec_dest, iterator_distance(it_begin, it_end)); /* copy values for range */ for(it_dest = vector_begin(pvec_dest), it_src = it_begin; !iterator_equal(it_dest, vector_end(pvec_dest)) && !iterator_equal(it_src, it_end); it_dest = iterator_next(it_dest), it_src = iterator_next(it_src)) { b_result = _GET_VECTOR_TYPE_SIZE(pvec_dest); _GET_VECTOR_TYPE_COPY_FUNCTION(pvec_dest)(_VECTOR_ITERATOR_COREPOS(it_dest), _VECTOR_ITERATOR_COREPOS(it_src), &b_result); assert(b_result); } assert(iterator_equal(it_dest, vector_end(pvec_dest)) && iterator_equal(it_src, it_end)); }
/** * 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 {
cstl_iterator deque_insert_range(cstl_deque *cd, cstl_iterator pos, cstl_iterator beging, cstl_iterator end) { int distance = iterator_distance(end, beging); pos = deque_insert_n(cd, pos, distance, cd->_begin); cstl_iterator new_pos = pos; for (int i = 0; i < distance; i++) { iterator_store(new_pos, iterator_load(beging)); iterator_next(&new_pos); iterator_next(&beging); } return pos; }
/** * Removes a range of elements in vector from specificed position. */ vector_iterator_t vector_erase_range(vector_t* pvec_vector, vector_iterator_t it_begin, vector_iterator_t it_end) { size_t t_erasesize = 0; bool_t b_result = false; vector_iterator_t it_iter; assert(pvec_vector != NULL); assert(_vector_is_inited(pvec_vector)); assert(_vector_iterator_belong_to_vector(pvec_vector, it_begin)); assert(_vector_iterator_belong_to_vector(pvec_vector, it_end)); assert(iterator_equal(it_begin, it_end) || _vector_iterator_before(it_begin, it_end)); if(iterator_equal(it_begin, it_end)) { return it_end; } it_iter = it_begin; t_erasesize = iterator_distance(it_begin, it_end); for(; !iterator_equal(it_end, vector_end(pvec_vector)); it_begin = iterator_next(it_begin), it_end = iterator_next(it_end)) { b_result = _GET_VECTOR_TYPE_SIZE(pvec_vector); _GET_VECTOR_TYPE_COPY_FUNCTION(pvec_vector)(_VECTOR_ITERATOR_COREPOS(it_begin), _VECTOR_ITERATOR_COREPOS(it_end), &b_result); assert(b_result); } assert(_VECTOR_ITERATOR_COREPOS(it_begin) == pvec_vector->_pby_finish - t_erasesize * _GET_VECTOR_TYPE_SIZE(pvec_vector)); /* destroy the deleted elements */ for(; !iterator_equal(it_begin, it_end); it_begin = iterator_next(it_begin)) { b_result = _GET_VECTOR_TYPE_SIZE(pvec_vector); _GET_VECTOR_TYPE_DESTROY_FUNCTION(pvec_vector)(_VECTOR_ITERATOR_COREPOS(it_begin), &b_result); assert(b_result); } pvec_vector->_pby_finish -= t_erasesize * _GET_VECTOR_TYPE_SIZE(pvec_vector); return it_iter; }
/** * Insert multiple copys of element befor specificed position, the element is from variable argument list. */ vector_iterator_t _vector_insert_n_varg(vector_t* pvec_vector, vector_iterator_t it_pos, size_t t_count, va_list val_elemlist) { void* pv_varg = NULL; bool_t b_result = false; /* test the vector and iterator is valid */ assert(pvec_vector != NULL); assert(_vector_is_inited(pvec_vector)); assert(_vector_iterator_belong_to_vector(pvec_vector, it_pos)); if (t_count > 0) { size_t i = 0; _byte_t* pby_oldfinish = NULL; _byte_t* pby_pos = NULL; /* for initialize elments and insert elements */ _byte_t* pby_destpos = NULL; /* if the remain capacity is less then the element count */ if (vector_size(pvec_vector) + t_count > vector_capacity(pvec_vector)) { size_t t_insertpos = iterator_distance(vector_begin(pvec_vector), it_pos); /* reserve the new size */ vector_reserve(pvec_vector, _vector_calculate_new_capacity(vector_size(pvec_vector), t_count)); it_pos = iterator_next_n(vector_begin(pvec_vector), t_insertpos); } /* insert the element counts of element to the position */ /* * move the elements from pos to the finish of vector to the * memory that after the pos element count. * +-----------------------------------------+ * | | | | * +-----------------------------------------+ * ^ ^ ^ * | | | * start it_pos finish * _t_count__ * / \ * +-----------------------------------------+ * | | |new element| | * +-----------------------------------------+ * ^ ^ ^ ^ * | | | | * start it_pos pby_oldfinish finish */ /* initialize new elements */ pby_oldfinish = pvec_vector->_pby_finish; assert(pby_oldfinish != NULL); pvec_vector->_pby_finish += t_count * _GET_VECTOR_TYPE_SIZE(pvec_vector); _vector_init_elem_range_auxiliary(pvec_vector, pby_oldfinish, pvec_vector->_pby_finish); /* move element from old finish to new finish */ for (pby_pos = pby_oldfinish - _GET_VECTOR_TYPE_SIZE(pvec_vector), pby_destpos = pvec_vector->_pby_finish - _GET_VECTOR_TYPE_SIZE(pvec_vector); pby_pos >= _VECTOR_ITERATOR_COREPOS(it_pos); pby_pos -= _GET_VECTOR_TYPE_SIZE(pvec_vector), pby_destpos -= _GET_VECTOR_TYPE_SIZE(pvec_vector)) { b_result = _GET_VECTOR_TYPE_SIZE(pvec_vector); _GET_VECTOR_TYPE_COPY_FUNCTION(pvec_vector)(pby_destpos, pby_pos, &b_result); assert(b_result); } /* get varg value only once */ pv_varg = _alloc_allocate(&pvec_vector->_t_allocator, _GET_VECTOR_TYPE_SIZE(pvec_vector), 1); assert(pv_varg != NULL); _vector_get_varg_value_auxiliary(pvec_vector, val_elemlist, pv_varg); /* copy value for varg */ for (i = 0; i < t_count; ++i) { b_result = _GET_VECTOR_TYPE_SIZE(pvec_vector); _GET_VECTOR_TYPE_COPY_FUNCTION(pvec_vector)(_VECTOR_ITERATOR_COREPOS(it_pos) + i * _GET_VECTOR_TYPE_SIZE(pvec_vector), pv_varg, &b_result); assert(b_result); } /* destroy varg and free memory */ _vector_destroy_varg_value_auxiliary(pvec_vector, pv_varg); _alloc_deallocate(&pvec_vector->_t_allocator, pv_varg, _GET_VECTOR_TYPE_SIZE(pvec_vector), 1); } return it_pos; }
/** * Insert a range of elements into vector at a specificed position. */ void vector_insert_range(vector_t* pvec_vector, vector_iterator_t it_pos, vector_iterator_t it_begin, vector_iterator_t it_end) { size_t t_count = 0; /* the element count */ bool_t b_result = false; vector_iterator_t it_first; vector_iterator_t it_second; _byte_t* pby_oldfinish = NULL; _byte_t* pby_pos = NULL; _byte_t* pby_destpos = NULL; /* test the vector and iterator is valid */ assert(pvec_vector != NULL); assert(_vector_is_inited(pvec_vector)); assert(_vector_iterator_belong_to_vector(pvec_vector, it_pos)); /*assert(!_vector_iterator_belong_to_vector(pvec_vector, it_begin));*/ /*assert(!_vector_iterator_belong_to_vector(pvec_vector, it_end));*/ assert(_vector_same_vector_iterator_type(pvec_vector, it_begin)); assert(_vector_same_vector_iterator_type(pvec_vector, it_end)); assert(iterator_equal(it_begin, it_end) || _vector_iterator_before(it_begin, it_end)); t_count = iterator_distance(it_begin, it_end); if(t_count > 0) { /* if the remain capacity is less then the element count */ if(vector_size(pvec_vector) + t_count > vector_capacity(pvec_vector)) { size_t t_distance = _VECTOR_ITERATOR_COREPOS(it_pos) - pvec_vector->_pby_start; /* reserve the new size */ vector_reserve(pvec_vector, _vector_calculate_new_capacity(vector_size(pvec_vector), t_count)); _VECTOR_ITERATOR_COREPOS(it_pos) = pvec_vector->_pby_start + t_distance; } /* initialize new elements */ pby_oldfinish = pvec_vector->_pby_finish; assert(pby_oldfinish != NULL); pvec_vector->_pby_finish += t_count * _GET_VECTOR_TYPE_SIZE(pvec_vector); _vector_init_elem_range_auxiliary(pvec_vector, pby_oldfinish, pvec_vector->_pby_finish); /* move element from old finish to new finish */ for(pby_pos = pby_oldfinish - _GET_VECTOR_TYPE_SIZE(pvec_vector), pby_destpos = pvec_vector->_pby_finish - _GET_VECTOR_TYPE_SIZE(pvec_vector); pby_pos >= _VECTOR_ITERATOR_COREPOS(it_pos); pby_pos -= _GET_VECTOR_TYPE_SIZE(pvec_vector), pby_destpos -= _GET_VECTOR_TYPE_SIZE(pvec_vector)) { b_result = _GET_VECTOR_TYPE_SIZE(pvec_vector); _GET_VECTOR_TYPE_COPY_FUNCTION(pvec_vector)(pby_destpos, pby_pos, &b_result); assert(b_result); } /* insert element counts copys to the pos */ for(it_first = it_pos, it_second = it_begin; !iterator_equal(it_second, it_end); it_first = iterator_next(it_first), it_second = iterator_next(it_second)) { b_result = _GET_VECTOR_TYPE_SIZE(pvec_vector); _GET_VECTOR_TYPE_COPY_FUNCTION(pvec_vector)(_VECTOR_ITERATOR_COREPOS(it_first), _VECTOR_ITERATOR_COREPOS(it_second), &b_result); assert(b_result); } assert(_VECTOR_ITERATOR_COREPOS(it_first) == _VECTOR_ITERATOR_COREPOS(it_pos) + (_VECTOR_ITERATOR_COREPOS(it_end) - _VECTOR_ITERATOR_COREPOS(it_begin))); } }
/** * 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); }