00001 #ifndef NO_PTR_CHAIN_NODE_2_H
00002 #define NO_PTR_CHAIN_NODE_2_H
00003
00023 #include <assert.h>
00024 #include "NoPtrFwd.hh"
00025 #include "nullness.hh"
00026
00027 namespace NoPtr
00028 {
00029 namespace NoPtrImpl
00030 {
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 class ChainNode
00059 {
00060 public:
00061
00062 ChainNode() {others[0] = others[1] = NullPtr;}
00063
00064 ChainNode(ChainNode& rhs)
00065 {
00066 assert(rhs.others[1] == NullPtr);
00067 connectBare(rhs);
00068 }
00069
00070 ~ChainNode() {removeSelf();}
00071
00072
00073 void connect(ChainNode& rhs)
00074 {
00075 if (this != &rhs)
00076 {
00077 removeSelf();
00078 connectBare(rhs);
00079 }
00080 }
00081
00082 void disconnect()
00083 {
00084 removeSelf();
00085 others[0] = others[1] = NullPtr;
00086 }
00087
00088 void swap(ChainNode& rhs)
00089 {
00090
00091 ChainNode* tmp = others[0];
00092 others[0] = rhs.others[0];
00093 rhs.others[0] = tmp;
00094
00095
00096 tmp = others[1];
00097 others[1] = rhs.others[1];
00098 rhs.others[1] = tmp;
00099
00100
00101 reconnect(others[0], &rhs, this);
00102 reconnect(others[1], &rhs, this);
00103
00104
00105 reconnect(rhs.others[0], this, &rhs);
00106 reconnect(rhs.others[1], this, &rhs);
00107 }
00108
00109 bool isConnected() const {return others[0] != NullPtr;}
00110
00111 const ChainNode* const * neighbors() const {return others;}
00112
00113 private:
00114
00115 void connectBare(ChainNode& rhs)
00116 {
00117 rhs.add(this);
00118 others[0] = &rhs;
00119 others[1] = NullPtr;
00120 }
00121
00122
00123 void reconnect(ChainNode* other,
00124 ChainNode* old, ChainNode* nnew)
00125 {
00126
00127 if (other && other != nnew) other->replace(old, nnew);
00128 }
00129
00130
00131
00132 void removeSelf()
00133 {
00134 if (others[1] != NullPtr)
00135 {
00136 others[0]->replace(this, others[1]);
00137 others[1]->replace(this, others[0]);
00138 }
00139 else if (others[0] != NullPtr)
00140
00141 others[0]->remove(this);
00142 }
00143
00144
00145 void add(ChainNode* newNode)
00146 {
00147 if (others[0] == NullPtr)
00148 {
00149 others[0] = newNode;
00150 assert(others[1] == NullPtr);
00151 }
00152 else
00153 {
00154 assert(others[1] != newNode);
00155 others[1] = newNode;
00156 }
00157 }
00158
00159 void remove(ChainNode* obsNode)
00160 {
00161 if (others[0] == obsNode)
00162 {
00163 others[0] = others[1];
00164 others[1] = NullPtr;
00165 }
00166 else
00167 {
00168 assert(others[1] == obsNode);
00169 others[1] = NullPtr;
00170 }
00171 }
00172
00173 void replace(ChainNode* obsNode, ChainNode* newNode)
00174 {
00175 if (others[0] == obsNode)
00176 {
00177 others[0] = newNode;
00178 assert(others[1] != newNode);
00179 }
00180 else
00181 {
00182 assert(others[1] == obsNode);
00183 others[1] = newNode;
00184 }
00185 }
00186
00187 private:
00188 ChainNode(const ChainNode&);
00189 ChainNode& operator=(const ChainNode&);
00190
00191 private:
00192 ChainNode* others[2];
00193 };
00194
00195 }
00196
00197 }
00198
00199 #endif // NO_PTR_CHAIN_NODE_2_H