00001 #ifndef INC_ASTRefCount_hpp__
00002 # define INC_ASTRefCount_hpp__
00003
00004
00005
00006
00007
00008
00009
00010
00011 # include <antlr/config.hpp>
00012
00013 #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
00014 namespace antlr {
00015 #endif
00016
00017 class AST;
00018
00019 struct ANTLR_API ASTRef
00020 {
00021 AST* const ptr;
00022 unsigned int count;
00023
00024 ASTRef(AST* p);
00025 ~ASTRef();
00026 ASTRef* increment()
00027 {
00028 ++count;
00029 return this;
00030 }
00031 bool decrement()
00032 {
00033 return (--count==0);
00034 }
00035
00036 static ASTRef* getRef(const AST* p);
00037 private:
00038 ASTRef( const ASTRef& );
00039 ASTRef& operator=( const ASTRef& );
00040 };
00041
00042 template<class T>
00043 class ANTLR_API ASTRefCount
00044 {
00045 private:
00046 ASTRef* ref;
00047
00048 public:
00049 ASTRefCount(const AST* p=0)
00050 : ref(p ? ASTRef::getRef(p) : 0)
00051 {
00052 }
00053 ASTRefCount(const ASTRefCount<T>& other)
00054 : ref(other.ref ? other.ref->increment() : 0)
00055 {
00056 }
00057 ~ASTRefCount()
00058 {
00059 if (ref && ref->decrement())
00060 delete ref;
00061 }
00062 ASTRefCount<T>& operator=(AST* other)
00063 {
00064 ASTRef* tmp = ASTRef::getRef(other);
00065
00066 if (ref && ref->decrement())
00067 delete ref;
00068
00069 ref=tmp;
00070
00071 return *this;
00072 }
00073 ASTRefCount<T>& operator=(const ASTRefCount<T>& other)
00074 {
00075 if( other.ref != ref )
00076 {
00077 ASTRef* tmp = other.ref ? other.ref->increment() : 0;
00078
00079 if (ref && ref->decrement())
00080 delete ref;
00081
00082 ref=tmp;
00083 }
00084 return *this;
00085 }
00086
00087 operator T* () const { return ref ? static_cast<T*>(ref->ptr) : 0; }
00088 T* operator->() const { return ref ? static_cast<T*>(ref->ptr) : 0; }
00089 T* get() const { return ref ? static_cast<T*>(ref->ptr) : 0; }
00090 };
00091
00092 typedef ASTRefCount<AST> RefAST;
00093
00094 #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
00095 }
00096 #endif
00097
00098 #endif //INC_ASTRefCount_hpp__