![]() |
|
|
Generated: 8 Jan 2009 |
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 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 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