Main Page | Namespace List | Class Hierarchy | Compound List | File List | Namespace Members | Compound Members | File Members | Related Pages

SegmentNode.hh

Go to the documentation of this file.
00001 #ifndef NO_PTR_CHAIN_NODE_1_H
00002 #define NO_PTR_CHAIN_NODE_1_H
00003 
00023 #include <algorithm> // use std::swap
00024 #include <assert.h>
00025 #include "NoPtrFwd.hh"
00026 #include "nullness.hh"
00027 
00028 namespace NoPtr
00029 {
00030     namespace NoPtrImpl
00031     {
00032 
00033     /* Represent a chain node of a one-segment chain (which isn't 
00034        really a chain, granted). Copying a chain node rather creates 
00035        a new node and connects it to the original. Connection is 
00036        only allowed if other node not already connected. E.g.
00037        \code
00038             SegmentNode node1;
00039             SegmentNode node2(node1); // ok
00040             SegmentNode node3;
00041             node3.connect(node1); // error: assert fails
00042             node3.connect(node2); // error: assert fails
00043         \endcode
00044         The following would also fail, because of the call to func2:
00045         \code
00046         void func1(SegmentNode cn) {func2(cn);}
00047         void func2(SegmentNode) {} // assertion fails here
00048         func1( SegmentNode() );
00049         \endcode
00050        */
00051     class SegmentNode
00052     {
00053         public:
00054             // create unconnected
00055             SegmentNode(): _other(NullPtr) {}
00056             // connect us to \a rhs
00057             SegmentNode(SegmentNode& rhs) {connectBare(rhs);}
00058             // disconnect ourselves
00059            ~SegmentNode() {removeSelf();}
00060             void swap(SegmentNode& rhs) { std::swap(_other, rhs._other); }
00061             // Connect us to another node. This only succeeds if 
00062             // \a rhs is not connected to anything
00063             void connect(SegmentNode& rhs) 
00064             {
00065                 if (this != &rhs)
00066                 {
00067                     removeSelf();
00068                     connectBare(rhs);
00069                 }
00070             }
00071             // disconnect us from the node we were connected to (if any)
00072             void disconnect()
00073             {
00074                 removeSelf();
00075                 _other = NullPtr;
00076             }
00077             // are we connected to another node? 
00078             bool isConnected() const {return _other != NullPtr;}
00079 
00080         private:
00081             // set the mutual links
00082             void connectBare(SegmentNode& rhs)
00083             {
00084                 assert(! rhs.isConnected() );
00085                 rhs._other = this;
00086                 _other = &rhs;
00087             }
00088             // Remove self from _other; leave it up to caller to reset
00089             // _other to something else if necessary;
00090             void removeSelf()
00091             {
00092                 if (_other != NullPtr) 
00093                 {
00094                     assert(_other->_other == this);
00095                     _other->_other = NullPtr;
00096                 }
00097             }
00098 
00099         private:
00100             SegmentNode(const SegmentNode&); // forbidden
00101             SegmentNode& operator=(const SegmentNode&); // forbidden
00102                 
00103         private:
00104             SegmentNode* _other;
00105     };
00106     
00107     } // implementation namespace
00108     
00109 } // namespace
00110 
00111 #endif // NO_PTR_CHAIN_NODE_1_H    

Generated on Mon Aug 4 18:51:24 2003 for NoPtr C++ Library by doxygen 1.3.2