| # Gaudi Framework, version v21r7 |

Home |  | Generated: 22 Jan 2010

# TransientFastContainer.h

Go to the documentation of this file.

    00001 // $Id: TransientFastContainer.h,v 1.6 2008/10/27 16:41:33 marcocle Exp $
    00002 #ifndef GAUDIKERNEL_TRANSIENTFASTCONTAINER_H
    00003 #define GAUDIKERNEL_TRANSIENTFASTCONTAINER_H 1
    00004
    00005 // Include files
    00006 #include "GaudiKernel/DataObject.h"
    00007 #include <vector>
    00008 #include <stdexcept>
    00009 #include <typeinfo>
    00010 #include <functional>
    00011
    00012
    00021 class GAUDI_API TransientFastContainerBase: public DataObject {
    00022 public:
    00024   virtual ~TransientFastContainerBase();
    00026   virtual void clear() = 0;
    00028   virtual void free() = 0;
    00030   virtual const std::type_info &containedType() const = 0;
    00031 };
    00032
    00033
    00042 template <class T>
    00043 struct DefaultObjectCleaner: public std::unary_function<T*,T*>{
    00046   inline T* operator() (T* obj ) const {
    00047     obj->T::~T(); // call the destructor without deallocating memory
    00048     return new(obj) T(); // call the constructor on the memory
    00049   }
    00053   inline T* operator() (T* obj, const T &rhs ) const {
    00054     obj->T::~T(); // call the destructor without deallocating memory
    00055     return new(obj) T(rhs); // call the copy constructor on the memory
    00056   }
    00058   inline T* destruct(T* obj) const {
    00059     obj->T::~T(); // call the destructor without deallocating memory
    00060     return obj; // just return the pointer to the non-initialized chunk
    00061   }
    00062   //inline T* operator() (T* obj ) { /* obj->clean(); */ return obj; }
    00063 };
    00064
    00065
    00082 template <class T, class CLEANER = DefaultObjectCleaner<T> >
    00083 class GAUDI_API TransientFastContainer: public TransientFastContainerBase {
    00084 public:
    00085   // ---- types
    00086   typedef T                                  contained_type;
    00087   typedef contained_type*                    value_type;
    00088
    00089   typedef value_type                         pointer;
    00090   typedef const value_type                   const_pointer;
    00091
    00092   typedef value_type                         reference;
    00093   typedef const value_type                   const_reference;
    00094
    00095   typedef std::vector<value_type>            storage_type;
    00096
    00097   typedef typename storage_type::size_type               size_type;
    00098
    00099   typedef typename storage_type::iterator                iterator;
    00100   typedef typename storage_type::const_iterator          const_iterator;
    00101
    00102   typedef CLEANER                            cleaner_type;
    00103
    00105   TransientFastContainer(size_type n=0);
    00106
    00108   virtual ~TransientFastContainer( );
    00109
    00110   // ---- TransientFastContainerBase implementation ----
    00111
    00113   virtual void clear();
    00114
    00116   virtual void free();
    00117
    00119   virtual const std::type_info &containedType() const { return typeid(contained_type); }
    00120
    00121   // ---- inlined functions ----
    00122
    00125   inline pointer New() { return ( m_counter++ < m_current_size ) ? m_cleaner(*(m_end++)) : i_new(); }
    00126
    00129   inline pointer Add(const T &rhs) { return ( m_counter++ < m_current_size ) ? m_cleaner(*(m_end++),rhs) : i_new(rhs); }
    00130
    00133   inline pointer NewPointer()
    00134   { return ( m_counter++ < m_current_size ) ?  m_cleaner.destruct(*(m_end++)) : m_cleaner.destruct(i_new()); }
    00135
    00137   inline iterator begin() { return m_storage.begin(); }
    00139   inline const_iterator begin() const { return m_storage.begin(); }
    00140
    00142   inline iterator end() { return m_end; }
    00144   inline const_iterator end() const { return m_end; }
    00145
    00147   inline size_type size() const { return m_counter; }
    00148
    00150   inline pointer operator[] (size_type index)
    00151   { return (index < size()) ? m_storage[index] : throw std::out_of_range("index out of range"), (pointer)NULL; }
    00153   inline const contained_type* operator[] (size_type index) const
    00154   { return (index < size()) ? m_storage[index] : throw std::out_of_range("index out of range"), (const_pointer)NULL; }
    00155
    00157   inline pointer at(size_type index) { return operator[] (index); }
    00159   inline const contained_type* at(size_type index) const { return operator[] (index); }
    00160
    00161 private:
    00162
    00164   pointer i_new();
    00165
    00167   pointer i_new(const T &rhs);
    00168
    00170   size_type      m_counter;
    00171
    00173   size_type      m_current_size;
    00174
    00176   storage_type m_storage;
    00177
    00179   iterator m_end;
    00180
    00182   cleaner_type m_cleaner;
    00183 };
    00184
    00185 template <class T, class CLEANER>
    00186 TransientFastContainer<T,CLEANER>::TransientFastContainer(size_type n):
    00187   TransientFastContainerBase(),
    00188   m_counter(0),
    00189   m_current_size(0),
    00190   m_storage(),
    00191   m_end(m_storage.begin()),
    00192   m_cleaner()
    00193 {
    00194   if (n>0) {
    00195     m_storage.reserve(n);
    00196     for(;n>0;--n) New();
    00197     clear();
    00198   }
    00199 }
    00200
    00201 template <class T, class CLEANER>
    00202 TransientFastContainer<T,CLEANER>::~TransientFastContainer()
    00203 {
    00204   free();
    00205 }
    00206
    00207
    00208 template <class T, class CLEANER>
    00209 void TransientFastContainer<T,CLEANER>::clear() {
    00210   m_counter = 0;
    00211   m_end = m_storage.begin();
    00212 }
    00213
    00214 template <class T, class CLEANER>
    00215 void TransientFastContainer<T,CLEANER>::free() {
    00216   for( typename storage_type::iterator i = m_storage.begin();
    00217        i != m_storage.end();
    00218        ++i ) {
    00219     delete *i;
    00220   }
    00221   m_storage.clear();
    00222   m_counter = m_current_size = 0;
    00223   m_end = m_storage.begin();
    00224 }
    00225
    00226 template <class T, class CLEANER>
    00227 typename TransientFastContainer<T,CLEANER>::pointer TransientFastContainer<T,CLEANER>::i_new() {
    00228   //++m_counter; // already incremented in New()
    00229   ++m_current_size;
    00230   pointer ptr = new T();
    00231   m_storage.push_back(ptr);
    00232   m_end = m_storage.end();
    00233   return ptr;
    00234 }
    00235
    00236 template <class T, class CLEANER>
    00237 typename TransientFastContainer<T,CLEANER>::pointer TransientFastContainer<T,CLEANER>::i_new(const T &rhs) {
    00238   //++m_counter; // already incremented in New()
    00239   ++m_current_size;
    00240   pointer ptr = new T(rhs);
    00241   m_storage.push_back(ptr);
    00242   m_end = m_storage.end();
    00243   return ptr;
    00244 }
    00245
    00246 #endif // GAUDIKERNEL_TRANSIENTFASTCONTAINER_H