00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef _cvc3__include__smartcdo_h_
00023 #define _cvc3__include__smartcdo_h_
00024
00025 #include "cdo.h"
00026
00027 namespace CVC3 {
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 template <class T>
00052 class SmartCDO {
00053
00054 template <class U>
00055 class RefCDO {
00056 friend class SmartCDO;
00057 unsigned d_refCount;
00058 CDO<U> d_cdo;
00059 bool d_delay;
00060
00061 class RefNotifyObj : public ContextNotifyObj {
00062 friend class RefCDO;
00063 RefCDO<U>* d_ref;
00064
00065 RefNotifyObj(RefCDO<U>* ref, Context* context)
00066 : ContextNotifyObj(context), d_ref(ref) { }
00067 void notifyPre() { d_ref->d_delay = true; }
00068 void notify() {
00069 d_ref->d_delay = false;
00070 d_ref->kill();
00071 }
00072 };
00073
00074 RefNotifyObj* d_notifyObj;
00075
00076 friend class RefNotifyObj;
00077
00078 RefCDO(Context* context): d_refCount(0), d_cdo(context), d_delay(false),
00079 d_notifyObj(new RefNotifyObj(this, context)) {}
00080
00081 RefCDO(Context* context, const U& cdo, int scope = -1)
00082 : d_refCount(0), d_cdo(context, cdo, scope), d_delay(false),
00083 d_notifyObj(new RefNotifyObj(this, context)) {}
00084
00085 ~RefCDO() { delete d_notifyObj; }
00086
00087 void kill() { if(d_refCount==0 && !d_delay) delete this; }
00088 };
00089
00090 RefCDO<T>* d_data;
00091
00092 public:
00093
00094 bool isNull() const { return (d_data==NULL); }
00095
00096 SmartCDO(): d_data(NULL) { }
00097
00098 SmartCDO(Context* context)
00099 { d_data = new RefCDO<T>(context); d_data->d_refCount++; }
00100
00101 SmartCDO(Context* context, const T& data, int scope = -1)
00102 { d_data = new RefCDO<T>(context, data, scope); d_data->d_refCount++; }
00103
00104 ~SmartCDO()
00105 { if (isNull()) return;
00106 if (--d_data->d_refCount == 0) d_data->kill(); }
00107
00108 SmartCDO(const SmartCDO<T>& cdo) : d_data(cdo.d_data)
00109 { if (!isNull()) d_data->d_refCount++; }
00110
00111 SmartCDO<T>& operator=(const SmartCDO<T>& cdo)
00112 {
00113 if (this == &cdo) return *this;
00114 if (!isNull() && --(d_data->d_refCount)) d_data->kill();
00115 d_data = cdo.d_data;
00116 if (!isNull()) ++(d_data->d_refCount);
00117 return *this;
00118 }
00119
00120 void set(const T& data, int scope=-1) const {
00121 DebugAssert(!isNull(), "SmartCDO::set: we are Null");
00122 d_data->d_cdo.set(data, scope);
00123 }
00124 const T& get() const {
00125 DebugAssert(!isNull(), "SmartCDO::get: we are Null");
00126 return d_data->d_cdo.get();
00127 }
00128 operator T() const { return get(); }
00129 const SmartCDO<T>& operator=(const T& data) const {set(data); return *this;}
00130 };
00131
00132 }
00133
00134 #endif