00001
00002
00003
00004
00005
00006
00007 #ifndef COH_FINALIZABLE_BLOCK_HPP
00008 #define COH_FINALIZABLE_BLOCK_HPP
00009
00010 #include <stddef.h>
00011
00012 #include "coherence/lang/compatibility.hpp"
00013
00014 COH_OPEN_NAMESPACE2(coherence,lang)
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 class COH_EXPORT FinalizableBlock
00027 {
00028
00029
00030 protected:
00031
00032
00033
00034
00035
00036
00037 FinalizableBlock(FinalizableBlock* pDelegate = NULL)
00038 : m_pDelegate(NULL), m_pFinalizerHead(NULL)
00039 {
00040 initialize(pDelegate);
00041 }
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 FinalizableBlock(const FinalizableBlock& that)
00054 : m_pDelegate(that.m_pDelegate), m_pFinalizerHead(that.m_pFinalizerHead)
00055 {
00056
00057 that.m_pDelegate = const_cast<FinalizableBlock*>(&that);
00058 that.m_pFinalizerHead = NULL;
00059 }
00060
00061
00062
00063
00064
00065
00066
00067
00068 ~FinalizableBlock()
00069 {
00070 if (isTerminal())
00071 {
00072
00073 for (Finalizer* pFinalizer = m_pFinalizerHead; NULL != pFinalizer; )
00074 {
00075 Finalizer* pDelete = pFinalizer;
00076 pFinalizer = pFinalizer->m_pNext;
00077 delete pDelete;
00078 }
00079 }
00080 }
00081
00082
00083
00084
00085 public:
00086
00087
00088
00089
00090
00091 operator bool() const
00092 {
00093 return false;
00094 }
00095
00096 private:
00097
00098
00099
00100 const FinalizableBlock& operator=(const FinalizableBlock&);
00101
00102
00103
00104
00105 static void* operator new(size_t);
00106
00107
00108
00109
00110 public:
00111
00112
00113
00114 class COH_EXPORT Finalizer
00115 {
00116
00117
00118 public:
00119
00120
00121
00122 Finalizer()
00123 : m_pNext(NULL)
00124 {
00125 }
00126
00127
00128
00129
00130 virtual ~Finalizer()
00131 {
00132 }
00133
00134
00135
00136
00137 private:
00138
00139
00140
00141 Finalizer* m_pNext;
00142
00143
00144
00145
00146 friend class FinalizableBlock;
00147 };
00148
00149
00150
00151
00152 public:
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 void pushFinalizer(Finalizer* pFinalizer)
00167 {
00168 if (isTerminal())
00169 {
00170 if (pFinalizer == NULL)
00171 {
00172 coh_throw_illegal_argument("NULL finalizer");
00173 }
00174 pFinalizer->m_pNext = m_pFinalizerHead;
00175 m_pFinalizerHead = pFinalizer;
00176 }
00177 else
00178 {
00179 m_pDelegate->pushFinalizer(pFinalizer);
00180 }
00181 }
00182
00183 protected:
00184
00185
00186
00187
00188
00189
00190
00191 bool isTerminal() const
00192 {
00193 FinalizableBlock* pDelegate = m_pDelegate;
00194 if (pDelegate == this)
00195 {
00196 coh_throw_illegal_state(
00197 "attempt to use invalidated FinalizableBlock");
00198 }
00199 return NULL == pDelegate;
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 void initialize(FinalizableBlock* pDelegate = NULL)
00213 {
00214 if (m_pDelegate != NULL || m_pFinalizerHead != NULL)
00215 {
00216 coh_throw_illegal_state("");
00217 }
00218 m_pDelegate = pDelegate;
00219 }
00220
00221
00222
00223
00224 private:
00225
00226
00227
00228 mutable FinalizableBlock* m_pDelegate;
00229
00230
00231
00232
00233 mutable Finalizer* m_pFinalizerHead;
00234 };
00235
00236 COH_CLOSE_NAMESPACE2
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 #define COH_FINALIZABLE() \
00248 if (coherence::lang::FinalizableBlock finally \
00249 = coherence::lang::FinalizableBlock()) \
00250 { \
00251 COH_THROW(coherence::lang::IllegalStateException::create()); \
00252 } \
00253 else
00254
00255 #endif // COH_FINALIZABLE_BLOCK_HPP