template<typename T, class P>
-T& List<T, P>::Add(const T& element) {
- if (length_ >= capacity_) {
+void List<T, P>::Add(const T& element) {
+ if (length_ < capacity_) {
+ data_[length_++] = element;
+ } else {
// Grow the list capacity by 50%, but make sure to let it grow
// even when the capacity is zero (possible initial case).
int new_capacity = 1 + capacity_ + (capacity_ >> 1);
T* new_data = NewData(new_capacity);
memcpy(new_data, data_, capacity_ * sizeof(T));
+ // Since the element reference could be an element of the list,
+ // assign it to the new backing store before deleting the old.
+ new_data[length_++] = element;
DeleteData(data_);
data_ = new_data;
capacity_ = new_capacity;
}
- return data_[length_++] = element;
}
template<typename T, class P>
-Vector<T> List<T, P>::AddBlock(const T& element, int count) {
+Vector<T> List<T, P>::AddBlock(T value, int count) {
int start = length_;
- for (int i = 0; i < count; i++)
- Add(element);
+ for (int i = 0; i < count; i++) Add(value);
return Vector<T>(&data_[start], count);
}
template<typename T, class P>
-T& List<T, P>::Insert(int i, const T& element) {
- int free_index = length_ - 1;
- Add(last()); // Add grows the list if necessary.
- while (free_index > i) {
- data_[free_index] = data_[free_index - 1];
- free_index--;
- }
- data_[free_index] = element;
-}
-
-
-template<typename T, class P>
T List<T, P>::Remove(int i) {
T element = at(i);
length_--;
INLINE(void* operator new(size_t size)) { return P::New(size); }
INLINE(void operator delete(void* p, size_t)) { return P::Delete(p); }
+ // Returns a reference to the element at index i. This reference is
+ // not safe to use after operations that can change the list's
+ // backing store (eg, Add).
inline T& operator[](int i) const {
ASSERT(0 <= i && i < length_);
return data_[i];
}
inline T& at(int i) const { return operator[](i); }
inline T& last() const {
- ASSERT(!is_empty());
return at(length_ - 1);
}
// Adds a copy of the given 'element' to the end of the list,
// expanding the list if necessary.
- T& Add(const T& element);
+ void Add(const T& element);
// Added 'count' elements with the value 'value' and returns a
// vector that allows access to the elements. The vector is valid
// until the next change is made to this list.
- Vector<T> AddBlock(const T& value, int count);
-
- // Inserts a copy of the given element at index i in the list. All
- // elements formerly at or above i are moved up and the length of
- // the list increases by one. This function's complexity is linear
- // in the size of the list.
- T& Insert(int i, const T& element);
+ Vector<T> AddBlock(T value, int count);
// Removes the i'th element without deleting it even if T is a
// pointer type; moves all elements above i "down". Returns the