ProteoWizard
auto_vector.h
Go to the documentation of this file.
1 #if !defined AUTO_VECTOR_H
2 #define AUTO_VECTOR_H
3 // $Id: auto_vector.h 3300 2012-02-15 22:38:20Z chambm $
4 //------------------------------------
5 // Reliable Software (c) 2003
6 // www.relisoft.com
7 // Any use, commercial or noncommercial of this code
8 // is hereby granted, under the condition
9 // that this copyright notice be not removed.
10 //------------------------------------
11 
12 #include <memory>
13 #include <vector>
14 #include <cassert>
15 #include <algorithm>
16 
17 //---------------------------------
18 // Dynamic array of owned pointers.
19 // Ownership transfer semantics.
20 //---------------------------------
21 
22 template <class T>
24 {
25 public:
27  {
28  public:
29  auto_lvalue (T * & p) : _p (p) {}
30  operator T * () const { return _p; }
31  T * operator-> () const { return _p; }
32  auto_lvalue & operator= (std::auto_ptr<T> ap)
33  {
34  delete _p;
35  _p = ap.release ();
36  return *this;
37  }
38  private:
39  T * & _p;
40  };
41 public:
42 
43  explicit auto_vector (size_t capacity = 0);
44  ~auto_vector ();
45 
46  // memory management
47  size_t size () const { return _arr.size (); }
48  size_t capacity () const { return _arr.capacity (); }
49  void reserve (size_t count);
50  void resize (unsigned int newSize);
51  void erase (size_t idx);
52  void clear ();
53  void compact ();
54  void swap (auto_vector<T> & other)
55  {
56  _arr.swap (other._arr);
57  }
58  // array access
59  T const * operator [] (size_t i) const { return _arr [i]; }
61  {
62  return auto_lvalue (_arr [i]);
63  }
64  void assign (size_t i, std::auto_ptr<T> p);
65  void assign_direct (size_t i, T * p);
66  void insert (size_t idx, std::auto_ptr<T> p);
67  // stack access
68  void push_back (std::auto_ptr<T> p);
69  std::auto_ptr<T> pop_back (); // non-standard
70  T * back () { return _arr.back (); }
71  T const * back () const { return _arr.back (); }
72  T * front () { return _arr.front (); }
73  T const * front () const { return _arr.front (); }
74  // iterators
75  typedef typename std::vector<T*>::iterator iterator;
76  typedef typename std::vector<T*>::const_iterator const_iterator;
77  typedef typename std::vector<T*>::reverse_iterator reverse_iterator;
78  typedef typename std::vector<T*>::const_reverse_iterator const_reverse_iterator;
79 
80 
81  iterator begin () { return _arr.begin (); }
82  iterator end () { return _arr.end (); }
83  const_iterator begin () const { return _arr.begin (); }
84  const_iterator end () const { return _arr.end (); }
85  reverse_iterator rbegin() { return _arr.rbegin (); }
86  reverse_iterator rend() { return _arr.rend (); }
87  const_reverse_iterator rbegin() const { return _arr.rbegin (); }
88  const_reverse_iterator rend() const { return _arr.rend (); }
89 
90  iterator erase (iterator it);
91 
92  // iterator/index conversion
93  size_t ToIndex (iterator const & it);
94  size_t ToIndex (reverse_iterator const & rit);
95  iterator ToIter (size_t idx);
96  reverse_iterator ToRIter (size_t idx);
97 private:
98  auto_vector (auto_vector<T> const & src);
100 private:
101  std::vector<T*> _arr;
102 };
103 
104 template <class T>
106 {
107  _arr.reserve (capacity);
108 }
109 
110 template <class T>
112 {
113  clear ();
114 }
115 
116 template <class T>
117 void auto_vector<T>::push_back (std::auto_ptr<T> ptr)
118 {
119  _arr.push_back (ptr.get ());
120  ptr.release ();
121 }
122 
123 template <class T>
124 inline std::auto_ptr<T> auto_vector<T>::pop_back ()
125 {
126  assert (size () != 0);
127  T * p = _arr.back ();
128  _arr.pop_back ();
129  return std::auto_ptr<T> (p);
130 }
131 
132 template <class T>
134 {
135 public:
136  void operator () (T * p)
137  {
138  delete p;
139  }
140 };
141 
142 template <class T>
144 {
145  std::for_each (begin (), end (), DeletePtr<T> ());
146  _arr.clear ();
147 }
148 
149 template <class T>
150 inline void auto_vector<T>::assign_direct (size_t i, T * p)
151 {
152  assert (i < size ());
153  if (_arr [i] != p)
154  delete _arr [i];
155  _arr [i] = p;
156 }
157 
158 template <class T>
159 inline void auto_vector<T>::assign (size_t i, std::auto_ptr<T> p)
160 {
161  assert (i < size ());
162  if (_arr [i] != p.get ())
163  delete _arr [i];
164  _arr [i] = p.release ();
165 }
166 
167 template <class T>
168 void auto_vector<T>::erase (size_t idx)
169 {
170  assert (idx < size ());
171  // Delete item
172  delete _arr [idx];
173  // Compact array
174  _arr.erase (ToIter (idx));
175 }
176 
177 template <class T>
179 {
180  assert (it < end ());
181  delete *it;
182  return _arr.erase (it);
183 }
184 
185 template <class T>
187 {
188  // move null pointers to the end
189  T * null = 0;
190  iterator pos = std::remove (begin (), end (), null);
191  _arr.resize (pos - begin ());
192 }
193 
194 template <class T>
195 size_t auto_vector<T>::ToIndex (iterator const & it)
196 {
197  assert (it - begin () >= 0);
198  return static_cast<size_t> (it - begin ());
199 }
200 
201 template <class T>
203 {
204  iterator it = rit.base ();
205  --it;
206  assert (it - begin () >= 0);
207  return static_cast<size_t> (it - begin ());
208 }
209 
210 template <class T>
212 {
213  return begin () + idx;
214 }
215 
216 template <class T>
218 {
219  ++idx;
220  return reverse_iterator (ToIter (idx));
221 }
222 
223 
224 template <class T>
225 inline void auto_vector <T>::reserve (size_t count)
226 {
227  _arr.reserve (count);
228 }
229 
230 template <class T>
231 inline void auto_vector<T>::resize (unsigned int newSize)
232 {
233  if (newSize < size ())
234  std::for_each (ToIter (newSize), end (), DeletePtr<T> ());
235  _arr.resize (newSize);
236 }
237 
238 template <class T>
239 void auto_vector<T>::insert (size_t idx, std::auto_ptr<T> p)
240 {
241  assert (idx <= size ());
242  _arr.insert (ToIter (idx), p.get ());
243  p.release ();
244 }
245 
246 #endif