Главная arrow Программирование С++ arrow Функции вставки

Функции вставки

Стандарт библиотеки STL требует, чтобы последовательный контейнер под^ держивал три варианта функции insert о: один для вставки значения, другой для вставки множественных копий значения и третий для вставки ряда значений. Далее приведен первый вариант функции insert (). // Вставляет val по адресу р. template <class T, class А> typename RangeArray<T, А>::iterator
RangeArray<T, A>::insert(iterator p, const T &val) ¦
{
разработка пользовательского контейнера STL
335
iterator q; size_type i, j;
// Получает необходимую память. Т *tmp = a.allocate(sizeО + 1);
// Копирует существующие элементы в новый массив, // если возможно, вставляет новый элемент. for(i=j=0; i < sizeO; i++, j++) { if(&arrayptr[i] == p)  { tmptj] = val; q = &tmp[j];
j++;
}
tmptj] = arrayptrti];
}
// В противном случае новый элемент перемещается в конец, if(р == endO)  {
tmptj] = val;
q = &tmp[j];
}
// Корректирует длину len и границы. len++;
if (р < &arrayptr [abs( lowerbound) ])
lowerbound—; else
upperbound++;
// Вызывает деструкторы для элементов старого контейнера, for(size_type i=0; i < size()-l; i++) a.destroy(&arrayptr[i]);
// Очищает память, отведенную для старого контейнера. а.deallocate(arrayptr, size()-1);
arrayptr = tmp;
return q;
Первый вариант функции вставляет элемент в позицию, заданную итератором р, передаваемым в ее первом параметре. Функция возвращает итератор указывающий на вставленный элемент. Она выделяет сегмент памяти, д0.! статочный для хранения всех существующих элементов и нового. Затем она копирует существующие элементы во вновь выделенную память, вставляя новый элемент в соответствующее место. Далее функция обновляет переменные-члены len и upperbound или lowerbound соответственно. После этого уничтожаются объекты из исходного контейнера RangeArray, и указателю arrayptr присваивается адрес нового выделенного сегмента памяти. В конце концов, функция возвращает указатель на вставленный объект.
Теперь посмотрите внимательно на фрагмент кода, в котором обновляются значения переменных upperbound или lowerbound. Помните, что массив может увеличиваться как в положительном, так и в отрицательном направлениях, в зависимости от того, в какую его часть, положительную или отрицательную, выполняется вставка. Следовательно, нужно определить, куда вставляется новый элемент, и изменить соответствующую границу. Для этого итератор, передаваемый в параметре р, сравнивается с адресом элемента arrayptr [lowerbound]. Если итератор меньше этого элемента, увеличивается отрицательная часть массива, в противном случае — положительная часть.
Далее приведены следующие два варианта функции insert (), определенные посредством первого варианта.
// Вставляет num копий значения val, начиная с адреса р.
void insert(iterator р, int num, const T &val)
{
for(; num>0; num—) p = insert(p, val) + 1;
}
// Вставляет ряд элементов, заданный значениями start и stop, по адресу р-
void insert(iterator р, iterator start, iterator stop)
{
while(start != stop)  {
p = insert(p, *start) + 1; start++;
}
>