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