gc++.hpp

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 } // namespace GCpp
00420 
00421 #endif /* SRC_INC_GC_HPP */

Generated on Thu Dec 27 14:01:59 2007 for GC++ by  doxygen 1.5.4