+
+ void push_back(const value_type& v)
+ {
+ reserve(size() + 1);
+
+ // use placement new to initialize new object in preallocated place in
+ // m_values and store 'v' in it:
+ void* const place = m_values + m_size;
+ ::new(place) value_type(v);
+
+ // only increase m_size if the ctor didn't throw an exception; notice
+ // that if it _did_ throw, everything is OK, because we only increased
+ // vector's capacity so far and possibly written some data to
+ // uninitialized memory at the end of m_values
+ m_size++;
+ }
+
+ void pop_back()
+ {
+ erase(end() - 1);
+ }
+
+ const value_type& at(size_type idx) const
+ {
+ wxASSERT(idx < m_size);
+ return m_values[idx];
+ }
+
+ value_type& at(size_type idx)
+ {
+ wxASSERT(idx < m_size);
+ return m_values[idx];
+ }
+
+ const value_type& operator[](size_type idx) const { return at(idx); }
+ value_type& operator[](size_type idx) { return at(idx); }
+ const value_type& front() const { return at(0); }
+ value_type& front() { return at(0); }
+ const value_type& back() const { return at(size() - 1); }
+ value_type& back() { return at(size() - 1); }
+
+ const_iterator begin() const { return m_values; }
+ iterator begin() { return m_values; }
+ const_iterator end() const { return m_values + size(); }
+ iterator end() { return m_values + size(); }
+
+ reverse_iterator rbegin() { return reverse_iterator(end() - 1); }
+ reverse_iterator rend() { return reverse_iterator(begin() - 1); }
+
+ iterator insert(iterator it, const value_type& v = value_type())
+ {
+ // NB: this must be done before reserve(), because reserve()
+ // invalidates iterators!
+ const size_t idx = it - begin();
+ const size_t after = end() - it;
+
+ reserve(size() + 1);
+
+ // the place where the new element is going to be inserted
+ value_type * const place = m_values + idx;
+
+ // unless we're inserting at the end, move following elements out of
+ // the way:
+ if ( after > 0 )
+ Ops::MemmoveForward(place + 1, place, after);
+
+ // if the ctor called below throws an exception, we need to move all
+ // the elements back to their original positions in m_values
+ wxScopeGuard moveBack = wxMakeGuard(
+ Ops::MemmoveBackward, place, place + 1, after);
+ if ( !after )
+ moveBack.Dismiss();
+
+ // use placement new to initialize new object in preallocated place in
+ // m_values and store 'v' in it:
+ ::new(place) value_type(v);
+
+ // now that we did successfully add the new element, increment the size
+ // and disable moving the items back
+ moveBack.Dismiss();
+ m_size++;
+
+ return begin() + idx;
+ }
+
+ iterator erase(iterator it)
+ {
+ return erase(it, it + 1);
+ }
+
+ iterator erase(iterator first, iterator last)
+ {
+ if ( first == last )
+ return first;
+ wxASSERT( first < end() && last <= end() );
+
+ const size_type idx = first - begin();
+ const size_type count = last - first;
+ const size_type after = end() - last;
+
+ // erase elements by calling their destructors:
+ for ( iterator i = first; i < last; ++i )
+ i->~T();
+
+ // once that's done, move following elements over to the freed space:
+ if ( after > 0 )
+ {
+ Ops::MemmoveBackward(m_values + idx, m_values + idx + count, after);
+ }
+
+ m_size -= count;
+
+ return begin() + idx;
+ }
+
+#if WXWIN_COMPATIBILITY_2_8
+ wxDEPRECATED( size_type erase(size_type n) );
+#endif // WXWIN_COMPATIBILITY_2_8
+
+private:
+ // VC6 can't compile static const int members
+ enum { ALLOC_INITIAL_SIZE = 16 };
+ enum { ALLOC_MAX_SIZE = 4096 };
+
+ void Copy(const wxVector& vb)
+ {
+ reserve(vb.size());
+
+ for ( const_iterator i = vb.begin(); i != vb.end(); ++i )
+ push_back(*i);
+ }
+
+private:
+ void Shrink(size_type n)
+ {
+ for ( size_type i = n; i < m_size; i++ )
+ m_values[i].~T();
+ m_size = n;
+ }
+
+ void Extend(size_type n, const value_type& v)
+ {
+ reserve(n);
+ for ( size_type i = m_size; i < n; i++ )
+ push_back(v);
+ }
+
+ size_type m_size,
+ m_capacity;
+ value_type *m_values;