00001 #ifndef CLASSLIB_PODVECTOR_H
00002 # define CLASSLIB_PODVECTOR_H
00003
00004
00005
00006 # include "classlib/sysapi/system.h"
00007 # include <iterator>
00008
00009 namespace lat {
00010
00011
00012
00013
00014
00015
00016
00023 template <class T>
00024 struct PODVector
00025 {
00026 struct Data
00027 {
00028 T *begin;
00029 T *end;
00030 T *limit;
00031 };
00032
00033 typedef T value_type;
00034 typedef value_type *pointer;
00035 typedef const value_type *const_pointer;
00036 typedef value_type *iterator;
00037 typedef const value_type *const_iterator;
00038 typedef value_type &reference;
00039 typedef const value_type &const_reference;
00040 typedef STDC::size_t size_type;
00041 typedef STDC::ptrdiff_t difference_type;
00042
00043 typedef
00044 REVERSE_ITERATOR(reverse_iterator,
00045 random_access_iterator_tag,
00046 iterator,
00047 value_type,
00048 reference,
00049 pointer,
00050 difference_type) reverse_iterator;
00051 typedef
00052 REVERSE_ITERATOR(reverse_iterator,
00053 random_access_iterator_tag,
00054 const_iterator,
00055 value_type,
00056 const_reference,
00057 const_pointer,
00058 difference_type) const_reverse_iterator;
00059
00060 static iterator begin (Data &vector);
00061 static const_iterator begin (const Data &vector);
00062 static iterator end (Data &vector);
00063 static const_iterator end (const Data &vector);
00064
00065 static reverse_iterator rbegin (Data &vector);
00066 static const_reverse_iterator rbegin (const Data &vector);
00067 static reverse_iterator rend (Data &vector);
00068 static const_reverse_iterator rend (const Data &vector);
00069
00070 static size_type size (const Data &vector);
00071 static size_type max_size (const Data &vector);
00072 static size_type capacity (const Data &vector);
00073 static bool empty (const Data &vector);
00074
00075 static reference front (Data &vector);
00076 static const_reference front (const Data &vector);
00077 static reference back (Data &vector);
00078 static const_reference back (const Data &vector);
00079
00080 static void swap (Data &vector, Data &other);
00081
00082 static void reserve (Data &vector, size_type n);
00083 static void push_back (Data &vector, const T &x);
00084 static iterator insert (Data &vector,
00085 iterator pos, const T &x);
00086 static iterator insert (Data &vector,
00087 iterator pos);
00088 # if HAVE_MEMBER_TEMPLATES
00089
00090
00091
00092 # else
00093
00094
00095
00096 # endif
00097 static void insert (Data &vector, iterator pos,
00098 size_type n, const T &x);
00099 static void insert (Data &vector, iterator pos,
00100 int n, const T &x);
00101 static void insert (Data &vector, iterator pos,
00102 long n, const T &x);
00103
00104 static void pop_back (Data &vector);
00105 static iterator erase (Data &vector, iterator pos);
00106 static iterator erase (Data &vector, iterator first,
00107 iterator last);
00108 static void resize (Data &vector,
00109 size_type new_size,
00110 const T &x);
00111 static void resize (Data &vector,
00112 size_type new_size);
00113 static void clear (Data &vector);
00114
00115 private:
00116 static void insert_grow (Data &vector,
00117 iterator pos, const T &x);
00118 };
00119
00120
00121
00122
00123 template <class T>
00124 inline typename PODVector<T>::iterator
00125 PODVector<T>::begin (Data &vector)
00126 { return vector.begin; }
00127
00128 template <class T>
00129 inline typename PODVector<T>::const_iterator
00130 PODVector<T>::begin (const Data &vector)
00131 { return vector.begin; }
00132
00133 template <class T>
00134 inline typename PODVector<T>::iterator
00135 PODVector<T>::end (Data &vector)
00136 { return vector.end; }
00137
00138 template <class T>
00139 inline typename PODVector<T>::const_iterator
00140 PODVector<T>::end (const Data &vector)
00141 { return vector.end; }
00142
00144 template <class T>
00145 inline typename PODVector<T>::reverse_iterator
00146 PODVector<T>::rbegin (Data &vector)
00147 { return vector.begin; }
00148
00149 template <class T>
00150 inline typename PODVector<T>::const_reverse_iterator
00151 PODVector<T>::rbegin (const Data &vector)
00152 { return vector.begin; }
00153
00154 template <class T>
00155 inline typename PODVector<T>::reverse_iterator
00156 PODVector<T>::rend (Data &vector)
00157 { return vector.end; }
00158
00159 template <class T>
00160 inline typename PODVector<T>::const_reverse_iterator
00161 PODVector<T>::rend (const Data &vector)
00162 { return vector.end; }
00163
00165 template <class T>
00166 inline typename PODVector<T>::size_type
00167 PODVector<T>::size (const Data &vector)
00168 { return vector.begin ? vector.end - vector.begin : 0; }
00169
00170 template <class T>
00171 inline typename PODVector<T>::size_type
00172 PODVector<T>::max_size (const Data & )
00173 { return size_type(-1) / sizeof (T); }
00174
00175 template <class T>
00176 inline typename PODVector<T>::size_type
00177 PODVector<T>::capacity (const Data &vector)
00178 { return vector.begin ? vector.limit - vector.begin : 0; }
00179
00180 template <class T>
00181 inline bool
00182 PODVector<T>::empty (const Data &vector)
00183 { return vector.begin == vector.end; }
00184
00186 template <class T>
00187 inline typename PODVector<T>::reference
00188 PODVector<T>::front (Data &vector)
00189 { return *vector.begin; }
00190
00191 template <class T>
00192 inline typename PODVector<T>::const_reference
00193 PODVector<T>::front (const Data &vector)
00194 { return *vector.begin; }
00195
00196 template <class T>
00197 inline typename PODVector<T>::reference
00198 PODVector<T>::back (Data &vector)
00199 { return *(vector.end-1); }
00200
00201 template <class T>
00202 inline typename PODVector<T>::const_reference
00203 PODVector<T>::back (const Data &vector)
00204 { return *(vector.end-1); }
00205
00207 template <class T>
00208 inline void
00209 PODVector<T>::swap (Data &vector, Data &other)
00210 {
00211 Data tmp = vector;
00212 vector = other;
00213 other = tmp;
00214 }
00215
00217 template <class T>
00218 inline void
00219 PODVector<T>::reserve (Data &vector, size_type new_size)
00220 {
00221 if (capacity (vector) < new_size)
00222 {
00223 size_type old_size = size (vector);
00224 iterator begin = static_cast<iterator> (::operator new (new_size * sizeof (T)));
00225
00226 std::uninitialized_copy (vector.begin, vector.end, begin);
00227 for (iterator first = vector.begin, last = vector.end;
00228 first != last;
00229 ++first)
00230 first->T::~T ();
00231 ::operator delete (vector.begin);
00232
00233 vector.begin = begin;
00234 vector.end = begin + old_size;
00235 vector.limit = begin + new_size;
00236 }
00237 }
00238
00239 template <class T>
00240 inline void
00241 PODVector<T>::insert_grow (Data &vector, iterator pos, const T &x)
00242 {
00243 if (vector.end != vector.limit)
00244 {
00245 new (vector.end) T (*(vector.end-1));
00246 ++vector.end;
00247 std::copy_backward (pos, vector.end-2, vector.end-1);
00248 *pos = x;
00249 }
00250 else
00251 {
00252 size_type old_size = size (vector);
00253 size_type new_size = old_size ? 2*old_size : 1;
00254 iterator begin;
00255 iterator end;
00256
00257 begin = static_cast<iterator> (::operator new (new_size * sizeof (T)));
00258 end = std::uninitialized_copy (vector.begin, pos, begin);
00259 new (end) T (x);
00260 ++end;
00261 end = std::uninitialized_copy (pos, vector.end, end);
00262
00263 for (iterator first = vector.begin, last = vector.end;
00264 first != last;
00265 ++first)
00266 first->T::~T ();
00267 ::operator delete (vector.begin);
00268
00269 vector.begin = begin;
00270 vector.end = end;
00271 vector.limit = begin + new_size;
00272 }
00273 }
00274
00275 template <class T>
00276 inline void
00277 PODVector<T>::push_back (Data &vector, const T &value)
00278 {
00279 if (vector.end != vector.limit)
00280 {
00281 new (vector.end) T (value);
00282 ++vector.end;
00283 }
00284 else
00285 insert_grow (vector, vector.end, value);
00286 }
00287
00288 template <class T>
00289 inline typename PODVector<T>::iterator
00290 PODVector<T>::insert (Data &vector, iterator pos, const T &x)
00291 {
00292 size_type index = pos - begin (vector);
00293 if (vector.end != vector.limit && pos != vector.end)
00294 {
00295 new (vector.end) T (x);
00296 ++vector.end;
00297 }
00298 else
00299 insert_grow (vector, pos, x);
00300
00301 return vector.begin + index;
00302 }
00303
00304 template <class T>
00305 inline typename PODVector<T>::iterator
00306 PODVector<T>::insert (Data &vector, iterator pos)
00307 { return insert (vector, pos, T()); }
00308
00309 # if HAVE_MEMBER_TEMPLATES
00310
00311
00312
00313
00314
00315 # else
00316
00317
00318
00319
00320
00321 # endif
00322
00323
00324
00325
00326
00327
00328 template <class T>
00329 inline void
00330 PODVector<T>::insert (Data &vector, iterator pos, int n, const T &x)
00331 { insert (vector, pos, size_type (n), x); }
00332
00333 template <class T>
00334 inline void
00335 PODVector<T>::insert (Data &vector, iterator pos, long n, const T &x)
00336 { insert (vector, pos, size_type (n), x); }
00337
00339 template <class T>
00340 inline void
00341 PODVector<T>::pop_back (Data &vector)
00342 { --vector.end; vector.end->T::~T (); }
00343
00344 template <class T>
00345 inline typename PODVector<T>::iterator
00346 PODVector<T>::erase (Data &vector, iterator pos)
00347 {
00348 if (pos+1 != vector.end)
00349 std::copy (pos+1, vector.end, pos);
00350 --vector.end;
00351 vector.end->T::~T ();
00352
00353 if (vector.begin == vector.end)
00354 {
00355 ::operator delete (vector.begin);
00356 vector.begin = vector.end = vector.limit = 0;
00357 return 0;
00358 }
00359 else
00360 return pos;
00361 }
00362
00363 template <class T>
00364 inline typename PODVector<T>::iterator
00365 PODVector<T>::erase (Data &vector, iterator first, iterator last)
00366 {
00367 for (first = std::copy (last, vector.end, first);
00368 first != vector.end;
00369 ++first)
00370 first->T::~T ();
00371 vector.end -= last - first;
00372 return first;
00373 }
00374
00375 template <class T>
00376 inline void
00377 PODVector<T>::resize (Data &vector, size_type new_size, const T &x)
00378 {
00379 if (new_size < size ())
00380 erase (vector.begin + new_size, vector.end);
00381 else
00382 insert (vector.end, new_size-size(), x);
00383 }
00384
00385 template <class T>
00386 inline void
00387 PODVector<T>::resize (Data &vector, size_type new_size)
00388 { resize (vector, new_size, T()); }
00389
00390 template <class T>
00391 inline void
00392 PODVector<T>::clear (Data &vector)
00393 { erase (vector.begin, vector.end); }
00394
00395 }
00396 #endif // CLASSLIB_PODVECTOR_H