00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 #ifndef COH_CHAINED_HANDLE_ELEMENT_HPP
00017 #define COH_CHAINED_HANDLE_ELEMENT_HPP
00018 
00019 #include "coherence/lang/compatibility.hpp"
00020 
00021 #include <stdlib.h>
00022 
00023 COH_OPEN_NAMESPACE2(coherence,lang)
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 class ChainedHandleElement
00035     {
00036     protected:
00037 
00038 
00039 
00040         typedef enum
00041             {
00042             ACTION_NONE   = 0, 
00043             ACTION_FLIP   = 1, 
00044             ACTION_DETACH = 2, 
00045             ACTION_ERROR  = 3  
00046             } Action;
00047 
00048 
00049     
00050 
00051     protected:
00052 
00053 
00054 
00055         ChainedHandleElement(bool fView)
00056             : m_fView(fView)
00057             {
00058             
00059             m_prev = m_next = this;
00060             }
00061 
00062 
00063 
00064 
00065         ChainedHandleElement(const ChainedHandleElement& that, bool fView)
00066             : m_prev(&that), m_next(that.m_next), m_fView(fView)
00067             {
00068             
00069             m_next->m_prev = m_prev->m_next = this;
00070             }
00071 
00072 
00073 
00074 
00075         ChainedHandleElement(const ChainedHandleElement* that, bool fView)
00076             : m_fView(fView)
00077             {
00078             if (that)
00079                 {
00080                 
00081                 m_prev = that;
00082                 m_next = that->m_next;
00083                 m_next->m_prev = m_prev->m_next = this;
00084                 }
00085             else
00086                 {
00087                 
00088                 m_prev = m_next = this;
00089                 }
00090             }
00091 
00092 
00093 
00094 
00095 
00096         
00097 
00098 
00099     
00100 
00101     protected:
00102 
00103 
00104 
00105 
00106 
00107         Action unlink()
00108             {
00109             Action nAction = this == m_prev
00110                 ? this == m_next ? ACTION_DETACH : ACTION_ERROR
00111                 : !m_fView && m_prev->m_fView && m_next->m_fView && scan()
00112                     ? ACTION_FLIP : ACTION_NONE;
00113 
00114             
00115             m_prev->m_next = m_next;
00116             m_next->m_prev = m_prev;
00117 
00118             
00119             m_prev = m_next = this;
00120 
00121             return nAction;
00122             }
00123 
00124 
00125 
00126 
00127 
00128 
00129 
00130 
00131         Action link(const ChainedHandleElement& that)
00132             {
00133             Action nAction = this == m_prev
00134                 ? this == m_next ? ACTION_DETACH : ACTION_ERROR
00135                 : !m_fView && m_prev->m_fView && m_next->m_fView && scan()
00136                     ? ACTION_FLIP : ACTION_NONE;
00137 
00138             
00139             m_prev->m_next = m_next;
00140             m_next->m_prev = m_prev;
00141 
00142             
00143             m_prev = &that;
00144             m_next = that.m_next;
00145 
00146             m_next->m_prev = that.m_next = this;
00147 
00148             return nAction;
00149             }
00150 
00151 
00152 
00153 
00154 
00155 
00156 
00157 
00158         bool scan()
00159             {
00160             
00161             
00162             
00163             
00164             
00165             
00166             
00167             
00168             
00169             
00170             
00171             ChainedHandleElement const* pElm;
00172             for (pElm = m_prev; pElm->m_fView; pElm = pElm->m_prev);
00173             return pElm == this;
00174             }
00175 
00176 
00177     
00178 
00179     private:
00180 
00181 
00182 
00183         static void* operator new(size_t cb);
00184 
00185 
00186     
00187 
00188     protected:
00189 
00190 
00191 
00192         mutable ChainedHandleElement const* m_prev;
00193 
00194 
00195 
00196 
00197         mutable ChainedHandleElement const* m_next;
00198 
00199 
00200 
00201 
00202         bool m_fView;
00203     };
00204 
00205 COH_CLOSE_NAMESPACE2
00206 
00207 #endif // COH_CHAINED_HANDLE_ELEMENT_HPP