00001 #ifndef SRC_INC_GC_HPP
00002 #define SRC_INC_GC_HPP
00003
00004 #include <common.hpp>
00005 #include <memory_manager.hpp>
00006 #include <intrusive_list.hpp>
00007
00136 #define gcnew(T) new (GCpp::allocator_for_type<T>()->malloc ())T
00137
00138 namespace GCpp
00139 {
00140
00144 const char unknown_tag = '0';
00145 const char root_tag = '1';
00146 const char leaf_tag = '2';
00147
00150 class GCPP_PUBLIC_SYMBOL GCBasePointer
00151 {
00152 protected:
00155 void* f_storage;
00156
00159 char f_state;
00160
00163 char fetch_state ();
00164
00165 public:
00168 GCBasePointer* next;
00169
00172 GCBasePointer* prior;
00173
00174 protected:
00177 GCBasePointer (void* p_storage);
00178
00179 public:
00182 GCBasePointer (const GCBasePointer& p_storage);
00183
00186 virtual ~GCBasePointer ();
00187
00190 void* storage () const
00191 {
00192 return f_storage;
00193 }
00194
00195 virtual bool is_contained ()
00196 {
00197 if (f_state == unknown_tag)
00198 f_state = fetch_state ();
00199
00200 return f_state == leaf_tag;
00201 }
00202
00203 virtual void mark ();
00204
00205 void set_contained ()
00206 {
00207 f_state = leaf_tag;
00208 }
00209
00210 void set_root ()
00211 {
00212 f_state = root_tag;
00213 }
00214
00215 friend void dispatch_root (GCBasePointer& p_item);
00216 friend void dispatch_leaf (GCBasePointer& p_item);
00217 };
00218
00219 extern GCPP_MUTEX create_allocator_mutex;
00220
00221 template <class T>
00222 MemoryAllocator<T>* allocator_for_type ()
00223 {
00224 static MemoryAllocator<T>* res (0);
00225
00226 if (res == 0)
00227 {
00228 GCPP_LOCK lck (create_allocator_mutex);
00229 static MemoryAllocator<T> alc;
00230
00231 res = &alc;
00232 }
00233
00234 return res;
00235 }
00236
00241 template <class T>
00242 class gc_ptr : public GCBasePointer
00243 {
00244 public:
00247 gc_ptr ()
00248 : GCBasePointer (0)
00249 {}
00250
00254 explicit gc_ptr (T* p_item)
00255 : GCBasePointer (p_item)
00256 {}
00257
00260 gc_ptr<T>& operator= (const gc_ptr<T>& p_other)
00261 {
00262 f_storage = p_other.f_storage;
00263 return *this;
00264 }
00265
00268 gc_ptr<T>& operator= (T* p_item)
00269 {
00270 f_storage = p_item;
00271 return *this;
00272 }
00273
00277 operator bool ()
00278 {
00279 return f_storage != 0;
00280 }
00281
00285 T* operator-> () const
00286 {
00287 return static_cast<T*> (f_storage);
00288 }
00289
00295 T& operator* () const
00296 {
00297 return *static_cast<T*> (f_storage);
00298 }
00299 };
00300
00301 inline
00302 void dispatch_root (GCBasePointer& p_item)
00303 {
00304 p_item.f_state = root_tag;
00305 }
00306
00307 inline
00308 void dispatch_leaf (GCBasePointer& p_item)
00309 {
00310 p_item.f_state = leaf_tag;
00311 }
00312
00313 inline
00314 void mark_item (GCBasePointer& p_item)
00315 {
00316 p_item.mark ();
00317 }
00318
00325 template <class T>
00326 class gc_container : public GCBasePointer
00327 {
00328 public:
00331 gc_container ()
00332 : GCBasePointer (0)
00333 {}
00334
00338 explicit gc_container (T* p_item)
00339 : GCBasePointer (p_item)
00340 {}
00341
00344 gc_container<T>& operator= (const gc_container<T>& p_other)
00345 {
00346 f_storage = p_other.f_storage;
00347 return *this;
00348 }
00349
00352 gc_container<T>& operator= (T* p_item)
00353 {
00354 f_storage = p_item;
00355 return *this;
00356 }
00357
00361 operator bool ()
00362 {
00363 return f_storage != 0;
00364 }
00365
00369 T* operator-> () const
00370 {
00371 return static_cast<T*> (f_storage);
00372 }
00373
00379 T& operator* () const
00380 {
00381 return *static_cast<T*> (f_storage);
00382 }
00383
00384 virtual bool is_contained ()
00385 {
00386 bool res (GCBasePointer::is_contained ());
00387 for_each (operator-> ()->begin (), operator-> ()->end (), res ? dispatch_leaf : dispatch_root);
00388 return res;
00389 }
00390
00391 virtual void mark ()
00392 {
00393 GCBasePointer::mark ();
00394 for_each (operator-> ()->begin (), operator-> ()->end (), mark_item);
00395 }
00396 };
00397
00403 class GC_pause
00404 {
00405 public:
00410 GC_pause ();
00411
00416 ~GC_pause ();
00417 };
00418
00419 }
00420
00421 #endif