+
+ 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(); }
+
+ 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);
+
+ // unless we're inserting at the end, move following elements out of
+ // the way:
+ if ( after > 0 )
+ {
+ Ops::MemmoveForward(m_values + idx + 1, m_values + idx, after);
+ }
+
+#if wxUSE_EXCEPTIONS
+ try
+ {
+#endif
+ // use placement new to initialize new object in preallocated place
+ // in m_values and store 'v' in it:
+ void* const place = m_values + idx;
+ new(place) value_type(v);
+#if wxUSE_EXCEPTIONS
+ }
+ catch ( ... )
+ {
+ // if the ctor threw an exception, we need to move all the elements
+ // back to their original positions in m_values
+ if ( after > 0 )
+ {
+ Ops::MemmoveBackward(m_values + idx, m_values + idx + 1, after);
+ }
+
+ throw; // rethrow the exception
+ }
+#endif // wxUSE_EXCEPTIONS
+
+ // increment m_size only if ctor didn't throw -- if it did, we'll be
+ // left with m_values larger than necessary, but number of elements will
+ // be the same
+ 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:
+ size_type m_size,
+ m_capacity;
+ value_type *m_values;