CMS 3D CMS Logo

PODVector.h

Go to the documentation of this file.
00001 #ifndef CLASSLIB_PODVECTOR_H
00002 # define CLASSLIB_PODVECTOR_H
00003 
00004 //<<<<<< INCLUDES                                                       >>>>>>
00005 
00006 # include "classlib/sysapi/system.h"
00007 # include <iterator>
00008 
00009 namespace lat {
00010 //<<<<<< PUBLIC DEFINES                                                 >>>>>>
00011 //<<<<<< PUBLIC CONSTANTS                                               >>>>>>
00012 //<<<<<< PUBLIC TYPES                                                   >>>>>>
00013 //<<<<<< PUBLIC VARIABLES                                               >>>>>>
00014 //<<<<<< PUBLIC FUNCTIONS                                               >>>>>>
00015 //<<<<<< CLASS DECLARATIONS                                             >>>>>>
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     // template <class InIter>
00090     // static void                              insert (Data &vector, iterator pos,
00091     //                                          InIter first, InIter last);
00092 # else
00093     // static void                              insert (Data &vector, iterator pos,
00094     //                                          const_iterator first,
00095     //                                          const_iterator last);
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 //<<<<<< INLINE PUBLIC FUNCTIONS                                        >>>>>>
00121 //<<<<<< INLINE MEMBER FUNCTIONS                                        >>>>>>
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 & /* vector */)
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 // template <class T>
00311 // template <class InIter>
00312 // inline void
00313 // PODVector<T>::insert (Data &vector, iterator pos, InIter first, InIter last)
00314 // { FIXME; }
00315 # else
00316 // template <class T>
00317 // inline void
00318 // PODVector<T>::insert (Data &vector, iterator pos, const_iterator first,
00319 //                       const_iterator last)
00320 // { FIXME; }
00321 # endif
00322 
00323 // template <class T>
00324 // inline typename PODVector<T>::iterator
00325 // PODVector<T>::insert (Data &vector, iterator pos, size_type n, const T &x)
00326 // { FIXME: }
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 } // namespace lat
00396 #endif // CLASSLIB_PODVECTOR_H

Generated on Tue Jun 9 17:38:55 2009 for CMSSW by  doxygen 1.5.4