Although the normal use case for an ArrayList is to insert items at the end, we may also want to insert items at specific positions. However, doing so will be much more complex than simply appending to the end.
Imagine we have an ArrayList that contains 10, 20, 30, 40 and we decide that we want to insert 15 at index 1 (between 10 and 20). We donβt want to replace the value at index 1, we still want 20 to be in the list, so that means we need to shift it over to index 2. Which means 30 needs to move to index 3. And 40 needs to move to index 4... Anything after the insertion point will have to shift over so that we end up with 10, 15, 20, 30, 40.
To do this, we will need to start at the end of the list and work backwards, moving each item over one index until we reach the insertion point. Then we can place the new item in the now-empty spot.
We work backwards using the loop counter i which starts at m_size. At each location, we copy the value from m_arr[i - 1] to m_arr[i]. First we copy 40 from index 3 to index 4.
template<typename T>
void ArrayList<T>::insertAt(int location, const T& insertItem) {
// Shift elements up to make room for the new item
for (int i = m_size; i > location; --i) {
m_arr[i] = m_arr[i - 1];
}
m_arr[location] = insertItem;
++m_size;
}
We will want to sanity check the location we are given. Inserting at a negative index makes no sense. Nor does inserting at an index greater than m_size as that would leave a gap. (It does make sense to insert at m_size, even though there is nothing currently there, as that is the location just past the last element.) We also would want to ensure that we have enough capacity to accommodate the new item. So the complete version of the function would look like:
template<typename T>
void ArrayList<T>::insertAt(int location, const T& insertItem) {
if (location < 0 || location > m_size) {
throw std::out_of_range("Index out of range");
}
if (m_size == m_capacity) {
grow();
}
// Shift elements up to make room for the new item
for (int i = m_size; i > location; --i) {
m_arr[i] = m_arr[i - 1];
}
m_arr[location] = insertItem;
++m_size;
}