lean cpp library
A lean C++ library providing efficient utility classes for high-performance C++ applications.
|
00001 /*****************************************************/ 00002 /* lean Memory (c) Tobias Zirr 2011 */ 00003 /*****************************************************/ 00004 00005 #ifndef LEAN_MEMORY_OBJECT_POOL 00006 #define LEAN_MEMORY_OBJECT_POOL 00007 00008 #include "../lean.h" 00009 #include "../tags/noncopyable.h" 00010 #include "chunk_heap.h" 00011 #include "default_heap.h" 00012 00013 namespace lean 00014 { 00015 namespace memory 00016 { 00017 00019 template <class Element, size_t ChunkSize, class Heap = default_heap, size_t StaticChunkSize = ChunkSize, size_t Alignment = alignof(Element)> 00020 class object_pool : public lean::noncopyable 00021 { 00022 public: 00024 typedef Element value_type; 00026 typedef Heap heap_type; 00028 typedef typename heap_type::size_type size_type; 00030 static const size_type chunk_size = ChunkSize; 00032 static const size_type alignment = Alignment; 00033 00034 private: 00035 typedef chunk_heap<0, Heap, StaticChunkSize * sizeof(Element), Alignment> chunk_heap; 00036 chunk_heap m_heap; 00037 00038 public: 00040 LEAN_INLINE object_pool(size_type chunkSize = ChunkSize) 00041 : m_heap( max(chunkSize * sizeof(Element), sizeof(Element) + (Alignment - 1)) ) { } 00043 LEAN_INLINE ~object_pool() 00044 { 00045 clear(); 00046 } 00047 00049 void clear() 00050 { 00051 char *chunkEnd = m_heap.currentOffset(); 00052 char *chunkBegin = m_heap.clearCurrent(); 00053 00054 while (chunkBegin) 00055 { 00056 const size_t chunkSize = (chunkEnd - chunkBegin); 00057 00058 char *current = align<Alignment>(chunkBegin); 00059 00060 while (sizeof(Element) + static_cast<size_t>(current - chunkBegin) <= chunkSize) 00061 { 00062 reinterpret_cast<Element*>(current)->~Element(); 00063 00064 current = align<Alignment>(current + sizeof(Element)); 00065 } 00066 00067 char *nextChunkBegin = m_heap.clearFreeNext(); 00068 00069 if (nextChunkBegin != chunkBegin) 00070 { 00071 chunkBegin = nextChunkBegin; 00072 chunkEnd = chunkBegin 00073 + ((m_heap.currentStatic()) ? StaticChunkSize * sizeof(Element) : m_heap.nextChunkSize()); 00074 } 00075 else 00076 chunkBegin = nullptr; 00077 } 00078 } 00079 00081 LEAN_INLINE void* allocate() throw() 00082 { 00083 return m_heap.allocate<Alignment>( sizeof(Element) ); 00084 } 00086 LEAN_INLINE Element* place(const Element &value) throw() 00087 { 00088 return new( m_heap.allocate<Alignment>( sizeof(Element) ) ) Element(value); 00089 } 00090 #ifndef LEAN0X_NO_RVALUE_REFERENCES 00091 00092 LEAN_INLINE Element* place(Element &&value) throw() 00093 { 00094 return new( m_heap.allocate<Alignment>( sizeof(Element) ) ) Element( std::move(value) ); 00095 } 00096 #endif 00097 }; 00098 00099 } // namespace 00100 00101 using memory::object_pool; 00102 00103 } // namespace 00104 00105 #endif