Go to the documentation of this file.00001 #ifndef MEGATREE_STD_SINGLETON_ALLOCATOR
00002 #define MEGATREE_STD_SINGLETON_ALLOCATOR
00003
00004 #include <cstdio>
00005 #include <boost/thread/mutex.hpp>
00006 #include <typeinfo>
00007 #include <vector>
00008
00009 namespace megatree
00010 {
00011
00012 template <class T>
00013 class StdSingletonAllocatorInstance
00014 {
00015 public:
00016 static StdSingletonAllocatorInstance<T>* getInstance(size_t size=0)
00017 {
00018 if (instance_ == NULL)
00019 {
00020 printf("first time construction of instance because instance pointer is %p\n", instance_);
00021 T t;
00022
00023 assert(size != 0);
00024 instance_ = new StdSingletonAllocatorInstance<T>(size);
00025 }
00026
00027
00028
00029
00030 return instance_;
00031 }
00032
00033 size_t max_size() const
00034 {
00035 return size;
00036 }
00037
00038 T* allocate(size_t n)
00039 {
00040 assert(n == 1);
00041 boost::mutex::scoped_lock lock(mutex);
00042 T* obj = mem_vec.back();
00043 mem_vec.pop_back();
00044 return obj;
00045 }
00046
00047 void deallocate(T* obj, size_t n)
00048 {
00049 assert(n == 1);
00050 boost::mutex::scoped_lock lock(mutex);
00051 mem_vec.push_back(obj);
00052 }
00053
00054 void destruct()
00055 {
00056 printf("Free all memory\n");
00057 delete[] mem;
00058 }
00059
00060
00061 private:
00062 StdSingletonAllocatorInstance(size_t size_)
00063 :size(size_)
00064 {
00065 mem = new T[size];
00066 mem_vec.resize(size);
00067 for (size_t i=0; i<size; i++)
00068 mem_vec[i] = &mem[i];
00069 printf("Constructed StdSingletonAllocatorInstance with size %zu\n", size);
00070 }
00071
00072 static StdSingletonAllocatorInstance<T>* instance_;
00073
00074 size_t size;
00075 T* mem;
00076 std::vector<T*> mem_vec;
00077
00078 boost::mutex mutex;
00079
00080 };
00081
00082
00083
00084
00085
00086
00087
00088
00089 template <class T>
00090 class StdSingletonAllocator
00091 {
00092 public:
00093
00094
00095 typedef size_t size_type;
00096 typedef ptrdiff_t difference_type;
00097 typedef T* pointer;
00098 typedef const T* const_pointer;
00099 typedef T& reference;
00100 typedef const T& const_reference;
00101 typedef T value_type;
00102 template <class U> struct rebind { typedef StdSingletonAllocator<U> other; };
00103
00104
00105 StdSingletonAllocator(): allocator_(StdSingletonAllocatorInstance<T>::getInstance()) {};
00106
00107
00108 StdSingletonAllocator(const StdSingletonAllocator<T>& a)
00109 {
00110 allocator_ = a.allocator_;
00111
00112 };
00113
00114 template <class U> StdSingletonAllocator(const StdSingletonAllocator<U>&)
00115 {
00116
00117 }
00118
00119
00120 ~StdSingletonAllocator() {};
00121
00122
00123 pointer address(reference v) const
00124 {
00125 return &v;
00126 }
00127
00128
00129 const_pointer addres(const_reference v) const
00130 {
00131 return &v;
00132 }
00133
00134
00135 size_t max_size() const
00136 {
00137
00138 return allocator_->max_size();
00139 }
00140
00141
00142 pointer allocate(size_type n)
00143 {
00144
00145 return allocator_->allocate(n);
00146 }
00147
00148 void deallocate(pointer obj, size_type n)
00149 {
00150
00151 allocator_->deallocate(obj, n);
00152 }
00153
00154 void construct(pointer p, const_reference v) const
00155 {
00156
00157 new (static_cast<void*>(p)) T(v);
00158 }
00159
00160 void destroy(pointer p) const
00161 {
00162
00163 }
00164
00165
00166 private:
00167 StdSingletonAllocatorInstance<T>* allocator_;
00168 };
00169
00170
00171 template <class T1, class T2>
00172 bool operator ==(const StdSingletonAllocator<T1>& a1, const StdSingletonAllocator<T2>& a2)
00173 {
00174
00175 return true;
00176 }
00177
00178
00179 template <class T1, class T2>
00180 bool operator !=(const StdSingletonAllocator<T1>& a1, const StdSingletonAllocator<T2>& a2)
00181 {
00182
00183 return false;
00184 }
00185
00186
00187 template <class T>
00188 StdSingletonAllocatorInstance<T>* StdSingletonAllocatorInstance<T>::instance_ = NULL;
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 }
00214
00215 #endif