00001 #if !defined AUTO_VECTOR_H
00002 #define AUTO_VECTOR_H
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <memory>
00012 #include <vector>
00013 #include <cassert>
00014 #include <algorithm>
00015
00016
00017
00018
00019
00020
00021 template <class T>
00022 class auto_vector
00023 {
00024 public:
00025 class auto_lvalue
00026 {
00027 public:
00028 auto_lvalue (T * & p) : _p (p) {}
00029 operator T * () const { return _p; }
00030 T * operator-> () const { return _p; }
00031 auto_lvalue & operator= (std::auto_ptr<T> ap)
00032 {
00033 delete _p;
00034 _p = ap.release ();
00035 return *this;
00036 }
00037 private:
00038 T * & _p;
00039 };
00040 public:
00041 typedef typename std::vector<T*>::size_type size_type;
00042
00043 explicit auto_vector (size_type capacity = 0);
00044 ~auto_vector ();
00045
00046
00047 size_type size () const { return _arr.size (); }
00048 size_type capacity () const { return _arr.capacity (); }
00049 void reserve (size_type count);
00050 void resize (size_type newSize);
00051 void erase (size_type idx);
00052 void clear ();
00053 void compact ();
00054 void swap (auto_vector<T> & other)
00055 {
00056 _arr.swap (other._arr);
00057 }
00058
00059 T const * operator [] (size_type i) const { return _arr [i]; }
00060 auto_lvalue operator [] (size_type i)
00061 {
00062 return auto_lvalue (_arr [i]);
00063 }
00064 void assign (size_type i, std::auto_ptr<T> p);
00065 void assign_direct (size_type i, T * p);
00066 void insert (size_type idx, std::auto_ptr<T> p);
00067
00068 void push_back (std::auto_ptr<T> p);
00069 std::auto_ptr<T> pop_back ();
00070 T * back () { return _arr.back (); }
00071 T const * back () const { return _arr.back (); }
00072 T * front () { return _arr.front (); }
00073 T const * front () const { return _arr.front (); }
00074
00075 typedef typename std::vector<T*>::iterator iterator;
00076 typedef typename std::vector<T*>::const_iterator const_iterator;
00077 typedef typename std::vector<T*>::reverse_iterator reverse_iterator;
00078 typedef typename std::vector<T*>::const_reverse_iterator const_reverse_iterator;
00079
00080
00081 iterator begin () { return _arr.begin (); }
00082 iterator end () { return _arr.end (); }
00083 const_iterator begin () const { return _arr.begin (); }
00084 const_iterator end () const { return _arr.end (); }
00085 reverse_iterator rbegin() { return _arr.rbegin (); }
00086 reverse_iterator rend() { return _arr.rend (); }
00087 const_reverse_iterator rbegin() const { return _arr.rbegin (); }
00088 const_reverse_iterator rend() const { return _arr.rend (); }
00089
00090 iterator erase (iterator it);
00091
00092
00093 size_type ToIndex (iterator const & it);
00094 size_type ToIndex (reverse_iterator const & rit);
00095 iterator ToIter (size_type idx);
00096 reverse_iterator ToRIter (size_type idx);
00097 private:
00098 std::vector<T*> _arr;
00099 };
00100
00101 template <class T>
00102 auto_vector<T>::auto_vector (size_type capacity)
00103 {
00104 _arr.reserve (capacity);
00105 }
00106
00107 template <class T>
00108 auto_vector<T>::~auto_vector ()
00109 {
00110 clear ();
00111 }
00112
00113 template <class T>
00114 void auto_vector<T>::push_back (std::auto_ptr<T> ptr)
00115 {
00116 _arr.push_back (ptr.get ());
00117 ptr.release ();
00118 }
00119
00120 template <class T>
00121 inline std::auto_ptr<T> auto_vector<T>::pop_back ()
00122 {
00123 assert (size () != 0);
00124 T * p = _arr.back ();
00125 _arr.pop_back ();
00126 return std::auto_ptr<T> (p);
00127 }
00128
00129 template <class T>
00130 class DeletePtr
00131 {
00132 public:
00133 void operator () (T * p)
00134 {
00135 delete p;
00136 }
00137 };
00138
00139 template <class T>
00140 void auto_vector<T>::clear ()
00141 {
00142 std::for_each (begin (), end (), DeletePtr<T> ());
00143 _arr.clear ();
00144 }
00145
00146 template <class T>
00147 inline void auto_vector<T>::assign_direct (size_type i, T * p)
00148 {
00149 assert (i < size ());
00150 if (_arr [i] != p)
00151 delete _arr [i];
00152 _arr [i] = p;
00153 }
00154
00155 template <class T>
00156 inline void auto_vector<T>::assign (size_type i, std::auto_ptr<T> p)
00157 {
00158 assert (i < size ());
00159 if (_arr [i] != p.get ())
00160 delete _arr [i];
00161 _arr [i] = p.release ();
00162 }
00163
00164 template <class T>
00165 void auto_vector<T>::erase (size_type idx)
00166 {
00167 assert (idx < size ());
00168
00169 delete _arr [idx];
00170
00171 _arr.erase (ToIter (idx));
00172 }
00173
00174 template <class T>
00175 typename auto_vector<T>::iterator auto_vector<T>::erase (typename auto_vector<T>::iterator it)
00176 {
00177 assert (it < end ());
00178 delete *it;
00179 return _arr.erase (it);
00180 }
00181
00182 template <class T>
00183 void auto_vector<T>::compact ()
00184 {
00185
00186 T * null = 0;
00187 iterator pos = std::remove (begin (), end (), null);
00188 _arr.resize (pos - begin ());
00189 }
00190
00191 template <class T>
00192 typename auto_vector<T>::size_type auto_vector<T>::ToIndex (iterator const & it)
00193 {
00194 assert (it - begin () >= 0);
00195 return static_cast<size_type> (it - begin ());
00196 }
00197
00198 template <class T>
00199 typename auto_vector<T>::size_type auto_vector<T>::ToIndex (reverse_iterator const & rit)
00200 {
00201 iterator it = rit.base ();
00202 --it;
00203 assert (it - begin () >= 0);
00204 return static_cast<size_type> (it - begin ());
00205 }
00206
00207 template <class T>
00208 typename auto_vector<T>::iterator auto_vector<T>::ToIter (size_type idx)
00209 {
00210 return begin () + idx;
00211 }
00212
00213 template <class T>
00214 typename auto_vector<T>::reverse_iterator auto_vector<T>::ToRIter (size_type idx)
00215 {
00216 ++idx;
00217 return reverse_iterator (ToIter (idx));
00218 }
00219
00220
00221 template <class T>
00222 inline void auto_vector <T>::reserve (size_type count)
00223 {
00224 _arr.reserve (count);
00225 }
00226
00227 template <class T>
00228 inline void auto_vector<T>::resize (size_type newSize)
00229 {
00230 if (newSize < size ())
00231 std::for_each (ToIter (newSize), end (), DeletePtr<T> ());
00232 _arr.resize (newSize);
00233 }
00234
00235 template <class T>
00236 void auto_vector<T>::insert (size_type idx, std::auto_ptr<T> p)
00237 {
00238 assert (idx <= size ());
00239 _arr.insert (ToIter (idx), p.get ());
00240 p.release ();
00241 }
00242
00243 #endif