00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00031
00032
00033 #pragma once
00034
00035
00036 #include "../api_core.h"
00037 #include <new>
00038 #include <memory>
00039
00043 class CL_API_CORE CL_MemoryPool
00044 {
00047
00048 public:
00049 virtual ~CL_MemoryPool()
00050 {
00051 }
00052
00053
00057
00058 public:
00060
00061 virtual void *alloc(size_t size) = 0;
00062
00064
00065 virtual void free(void *data) = 0;
00066
00068 static CL_MemoryPool *get_temp_pool();
00070 };
00071
00075 template<typename _Type>
00076 class CL_MemoryPoolAllocator
00077 {
00078 public:
00079 typedef _Type value_type;
00080 typedef value_type* pointer;
00081 typedef const value_type* const_pointer;
00082 typedef value_type& reference;
00083 typedef const value_type& const_reference;
00084 typedef std::size_t size_type;
00085 typedef std::ptrdiff_t difference_type;
00086
00087 CL_MemoryPoolAllocator()
00088 : _memory_pool(0)
00089 {
00090 }
00091
00092 CL_MemoryPoolAllocator(const CL_MemoryPoolAllocator<_Type> &_src)
00093 : _memory_pool(_src._memory_pool)
00094 {
00095 }
00096
00097 template<typename _Other>
00098 CL_MemoryPoolAllocator(const CL_MemoryPoolAllocator<_Other> &_src)
00099 : _memory_pool(_src._memory_pool)
00100 {
00101 }
00102
00103 CL_MemoryPoolAllocator(CL_MemoryPool *_memory_pool)
00104 : _memory_pool(_memory_pool)
00105 {
00106 }
00107
00108 pointer address(reference _x) const
00109 {
00110 return &_x;
00111 }
00112
00113 const_pointer address(const_reference _x) const
00114 {
00115 return &_x;
00116 }
00117
00118 template<typename _Other>
00119 pointer allocate(size_type _count, const _Other *_Hint = 0)
00120 {
00121 if (_memory_pool)
00122 return (pointer) _memory_pool->alloc(_count * sizeof(value_type));
00123 else
00124 _fallback_alloc.allocate(_count, _Hint);
00125 }
00126
00127 void destroy(pointer _ptr, size_type _count)
00128 {
00129 if (_memory_pool)
00130 _memory_pool->free(_ptr);
00131 else
00132 _fallback_alloc.destroy(_ptr);
00133 }
00134
00135 size_type max_size() const
00136 {
00137 return (size_type) -1;
00138 }
00139
00140 template<typename _Other>
00141 struct rebind
00142 {
00143 typedef CL_MemoryPoolAllocator<_Other> other;
00144 };
00145
00146 void construct(pointer _ptr, const _Type &_value)
00147 {
00148 if (_memory_pool)
00149 new((void *) _ptr) _Type(_value);
00150 else
00151 _fallback_alloc.construct(_ptr, _value);
00152 }
00153
00154 void deallocate(pointer _ptr)
00155 {
00156 if (_memory_pool)
00157 _ptr->_Type::~_Type();
00158 else
00159 _fallback_alloc.destroy(_ptr);
00160 }
00161
00162 private:
00163 CL_MemoryPool *_memory_pool;
00164 std::allocator<_Type> _fallback_alloc;
00165 };
00166
00172 inline void *operator new(size_t size, CL_MemoryPool *pool)
00173 {
00174 if (pool)
00175 return pool->alloc(size);
00176 else
00177 return ::operator new(size);
00178 }
00179
00185 inline void operator delete(void *data, CL_MemoryPool *pool)
00186 {
00187 if (pool)
00188 pool->free(data);
00189 else
00190 ::operator delete(data);
00191 }
00192
00198 inline void *operator new[](size_t size, CL_MemoryPool *pool)
00199 {
00200 if (pool)
00201 return pool->alloc(size);
00202 else
00203 return ::operator new[](size);
00204 }
00205
00211 inline void operator delete[](void *data, CL_MemoryPool *pool)
00212 {
00213 if (pool)
00214 pool->free(data);
00215 else
00216 ::operator delete[](data);
00217 }
00218
00222 #define cl_new new
00223
00229 template <typename Type>
00230 void cl_delete(CL_MemoryPool *pool, Type *obj)
00231 {
00232 if (obj)
00233 obj->~Type();
00234 operator delete(obj, pool);
00235 }
00236
00243 template <typename Type>
00244 void cl_delete(CL_MemoryPool *pool, Type *obj, size_t array_size)
00245 {
00246 if (obj)
00247 for (size_t pos = 0; pos < array_size; pos++)
00248 obj[pos].~Type();
00249 #ifdef __GNUC__
00250
00251 void *data = obj;
00252 if (pool)
00253 pool->free(data);
00254 else
00255 ::operator delete[](data);
00256 #else
00257 operator delete[](obj, pool);
00258 #endif
00259 }
00260
00261
00262