-namespace stlplus\r
-{\r
-\r
- ////////////////////////////////////////////////////////////////////////////////\r
- // body class implements the aliasing behaviour\r
-\r
- template<typename O, typename N>\r
- class safe_iterator_body\r
- {\r
- private:\r
- const O* m_owner;\r
- N* m_node;\r
- unsigned m_count;\r
-\r
- public:\r
-\r
- safe_iterator_body(const O* owner, N* node) throw() : \r
- m_owner(owner), m_node(node), m_count(1)\r
- {\r
-// std::cerr << "constructing " \r
-// << std::hex << ((unsigned long)this) \r
-// << " => " << ((unsigned long)m_owner) << ":" << ((unsigned long)m_node)\r
-// << ":" << std::dec << m_count << std::endl;\r
- }\r
-\r
- ~safe_iterator_body(void) throw()\r
- {\r
-// std::cerr << "destroying " \r
-// << std::hex << ((unsigned long)this) \r
-// << " => " << ((unsigned long)m_owner) << ":" << ((unsigned long)m_node)\r
-// << ":" << std::dec << m_count << std::endl;\r
- m_owner = 0;\r
- m_node = 0;\r
- }\r
-\r
- unsigned count(void) const\r
- {\r
- return m_count;\r
- }\r
-\r
- void increment(void)\r
- {\r
- ++m_count;\r
-// std::cerr << "incremented " \r
-// << std::hex << ((unsigned long)this) \r
-// << " => " << ((unsigned long)m_owner) << ":" << ((unsigned long)m_node)\r
-// << ":" << std::dec << m_count << std::endl;\r
- }\r
-\r
- bool decrement(void)\r
- {\r
- --m_count;\r
-// std::cerr << "decremented " \r
-// << std::hex << ((unsigned long)this) \r
-// << " => " << ((unsigned long)m_owner) << ":" << ((unsigned long)m_node)\r
-// << ":" << std::dec << m_count << std::endl;\r
- return m_count == 0;\r
- }\r
-\r
- N* node(void) const throw()\r
- {\r
- return m_node;\r
- }\r
-\r
- const O* owner(void) const throw()\r
- {\r
- return m_owner;\r
- }\r
-\r
- void change_owner(const O* owner)\r
- {\r
- m_owner = owner;\r
- }\r
-\r
- bool equal(const safe_iterator_body<O,N>* right) const throw()\r
- {\r
-// return m_node == right->m_node;\r
- return compare(right) == 0;\r
- }\r
-\r
- int compare(const safe_iterator_body<O,N>* right) const throw()\r
- {\r
- return ((long)m_node) - ((long)right->m_node);\r
- }\r
-\r
- bool null(void) const throw()\r
- {\r
- return m_owner == 0;\r
- }\r
-\r
- bool end(void) const throw()\r
- {\r
- return m_owner != 0 && m_node == 0;\r
- }\r
-\r
- bool valid(void) const throw()\r
- {\r
- return m_owner != 0 && m_node != 0;\r
- }\r
-\r
- void set_end(void) throw()\r
- {\r
- m_node = 0;\r
- }\r
-\r
- void set_null(void) throw()\r
- {\r
- m_owner = 0;\r
- m_node = 0;\r
- }\r
-\r
- void assert_valid(void) const throw(null_dereference,end_dereference)\r
- {\r
- if (null())\r
- throw null_dereference("stlplus::safe_iterator");\r
- if (end())\r
- throw end_dereference("stlplus::safe_iterator");\r
- }\r
-\r
- void assert_non_null(void) const throw(null_dereference)\r
- {\r
- if (null())\r
- throw null_dereference("stlplus::safe_iterator");\r
- }\r
-\r
- void assert_owner(const O* owner) const throw(wrong_object)\r
- {\r
- if (owner != m_owner)\r
- throw wrong_object("stlplus::safe_iterator");\r
- }\r
- };\r
-\r
-\r
- ////////////////////////////////////////////////////////////////////////////////\r
- // Master Iterator\r
- ////////////////////////////////////////////////////////////////////////////////\r
-\r
- // construct a valid iterator\r
- template<typename O, typename N>\r
- master_iterator<O,N>::master_iterator(const O* owner, N* node) throw() :\r
- m_body(new safe_iterator_body<O,N>(owner,node))\r
- {\r
- }\r
-\r
- // destructor - disconnect all iterators from the node\r
- // this usually happens when the node is deleted and must invalidate all aliases\r
- template<typename O, typename N>\r
- master_iterator<O,N>::~master_iterator(void) throw()\r
- {\r
- m_body->set_end();\r
- if(m_body->decrement())\r
- {\r
- delete m_body;\r
- m_body = 0;\r
- }\r
- }\r
-\r
- // dereference\r
- template<typename O, typename N>\r
- N* master_iterator<O,N>::node(void) const throw()\r
- {\r
- return m_body->node();\r
- }\r
-\r
- template<typename O, typename N>\r
- const O* master_iterator<O,N>::owner(void) const throw()\r
- {\r
- return m_body->owner();\r
- }\r
-\r
- // when you move a node from one owner to another, call this on the node's iterator\r
- // this effectively moves all iterators to the node so that they are owned by the new owner too\r
- template<typename O, typename N>\r
- void master_iterator<O,N>::change_owner(const O* owner) throw()\r
- {\r
- m_body->change_owner(owner);\r
- }\r
-\r
- ////////////////////////////////////////////////////////////////////////////////\r
- // Safe Iterator\r
- ////////////////////////////////////////////////////////////////////////////////\r
-\r
- // construct a null iterator\r
- // later assignment of a valid iterator to this is done by using step\r
- template<typename O, typename N>\r
- safe_iterator<O,N>::safe_iterator(void) throw() : \r
- m_body(new safe_iterator_body<O,N>(0,0))\r
- {\r
- }\r
-\r
- // construct a valid iterator by aliasing from the owner node's master iterator\r
- template<typename O, typename N>\r
- safe_iterator<O,N>::safe_iterator(const master_iterator<O,N>& r) throw() :\r
- m_body(0)\r
- {\r
- m_body = r.m_body;\r
- m_body->increment();\r
- }\r
-\r
- // construct a valid iterator by aliasing from the owner node's master iterator\r
- template<typename O, typename N>\r
- safe_iterator<O,N>::safe_iterator(const safe_iterator<O,N>& r) throw() :\r
- m_body(0)\r
- {\r
- m_body = r.m_body;\r
- m_body->increment();\r
- }\r
-\r
- // assignment implements dealiasing followed by aliasing\r
- template<typename O, typename N>\r
- safe_iterator<O,N>& safe_iterator<O,N>::operator=(const safe_iterator<O,N>& r) throw()\r
- {\r
- if (m_body != r.m_body)\r
- {\r
- if (m_body->decrement())\r
- delete m_body;\r
- m_body = r.m_body;\r
- m_body->increment();\r
- }\r
- return *this;\r
- }\r
-\r
- // destructor - implements dealiasing\r
- template<typename O, typename N>\r
- safe_iterator<O,N>::~safe_iterator(void) throw()\r
- {\r
- if(m_body->decrement())\r
- {\r
- delete m_body;\r
- m_body = 0;\r
- }\r
- }\r
-\r
-\r
- // increment/decrement operation\r
- // implements dealiasing followed by aliasing\r
- template<typename O, typename N>\r
- void safe_iterator<O,N>::set(const master_iterator<O,N>& r) throw()\r
- {\r
- if (m_body != r.m_body)\r
- {\r
- if (m_body->decrement())\r
- delete m_body;\r
- m_body = r.m_body;\r
- m_body->increment();\r
- }\r
- }\r
-\r
- // dereference\r
- template<typename O, typename N>\r
- N* safe_iterator<O,N>::node(void) const throw()\r
- {\r
- return m_body->node();\r
- }\r
-\r
- template<typename O, typename N>\r
- const O* safe_iterator<O,N>::owner(void) const throw()\r
- {\r
- return m_body->owner();\r
- }\r
-\r
- // change to a null iterator - i.e. one that doees not belong to any object\r
- // this does not affect any other iterators pointing to the same node\r
- template<typename O, typename N>\r
- void safe_iterator<O,N>::set_null(void) throw()\r
- {\r
- if (m_body->count() == 1)\r
- {\r
- // no aliases, so just make this null\r
- m_body->set_null();\r
- }\r
- else\r
- {\r
- // create a new body which is null so as not to affect any other aliases\r
- m_body->decrement();\r
- m_body = new safe_iterator_body<O,N>(0,0);\r
- }\r
- }\r
-\r
- ////////////////////////////////////////////////////////////////////////////////\r
- // operations for clients that do not have a master end iterator\r
- // alternatively, have a master end iterator as part of the container\r
- // and call constructor(master_end) or step(master_end)\r
-\r
- // construct an end iterator\r
- template<typename O, typename N>\r
- safe_iterator<O,N>::safe_iterator(const O* owner) throw() :\r
- m_body(new safe_iterator_body<O,N>(owner,0))\r
- {\r
- }\r
-\r
- // change to an end iterator - e.g. as a result of incrementing off the end\r
- template<typename O, typename N>\r
- void safe_iterator<O,N>::set_end(void) throw()\r
- {\r
- if (m_body->count() == 1)\r
- {\r
- // no aliases, so just make this an end iterator\r
- m_body->set_end();\r
- }\r
- else\r
- {\r
- // create a new body which is null so as not to affect any other aliases\r
- m_body->decrement();\r
- m_body = new safe_iterator_body<O,N>(owner(),0);\r
- }\r
- }\r
-\r
- ////////////////////////////////////////////////////////////////////////////////\r
- // tests\r
-\r
- // comparison\r
- template<typename O, typename N>\r
- bool safe_iterator<O,N>::equal(const safe_iterator<O,N>& right) const throw()\r
- {\r
- return compare(right) == 0;\r
- }\r
-\r
- template<typename O, typename N>\r
- int safe_iterator<O,N>::compare(const safe_iterator<O,N>& right) const throw()\r
- {\r
- if (m_body == right.m_body) return 0;\r
- return m_body->compare(right.m_body);\r
- }\r
-\r
- // a null iterator is one that has not been initialised with a value yet\r
- template<typename O, typename N>\r
- bool safe_iterator<O,N>::null(void) const throw()\r
- {\r
- return m_body->null();\r
- }\r
-\r
- // an end iterator is one that points to the end element of the list of nodes\r
- template<typename O, typename N>\r
- bool safe_iterator<O,N>::end(void) const throw()\r
- {\r
- return m_body->end();\r
- }\r
-\r
- // a valid iterator is one that can be dereferenced\r
- template<typename O, typename N>\r
- bool safe_iterator<O,N>::valid(void) const throw()\r
- {\r
- return m_body->valid();\r
- }\r
-\r
- // check the rules for a valid iterator that can be dereferenced\r
- template<typename O, typename N>\r
- void safe_iterator<O,N>::assert_valid(void) const throw(null_dereference,end_dereference)\r
- {\r
- m_body->assert_valid();\r
- }\r
-\r
- template<typename O, typename N>\r
- void safe_iterator<O,N>::assert_valid(const O* owner) const throw(wrong_object,null_dereference,end_dereference)\r
- {\r
- m_body->assert_valid();\r
- m_body->assert_owner(owner);\r
- }\r
-\r
- template<typename O, typename N>\r
- void safe_iterator<O,N>::assert_non_null(void) const throw(null_dereference)\r
- {\r
- m_body->assert_non_null();\r
- }\r
-\r
- template<typename O, typename N>\r
- void safe_iterator<O,N>::assert_owner(const O* owner) const throw(wrong_object)\r
- {\r
- m_body->assert_owner(owner);\r
- }\r
-\r
-} // end namespace stlplus\r
+namespace stlplus
+{
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // body class implements the aliasing behaviour
+
+ template<typename O, typename N>
+ class safe_iterator_body
+ {
+ private:
+ const O* m_owner;
+ N* m_node;
+ unsigned m_count;
+
+ public:
+
+ safe_iterator_body(const O* owner, N* node) throw() :
+ m_owner(owner), m_node(node), m_count(1)
+ {
+// std::cerr << "constructing "
+// << std::hex << ((unsigned long)this)
+// << " => " << ((unsigned long)m_owner) << ":" << ((unsigned long)m_node)
+// << ":" << std::dec << m_count << std::endl;
+ }
+
+ ~safe_iterator_body(void) throw()
+ {
+// std::cerr << "destroying "
+// << std::hex << ((unsigned long)this)
+// << " => " << ((unsigned long)m_owner) << ":" << ((unsigned long)m_node)
+// << ":" << std::dec << m_count << std::endl;
+ m_owner = 0;
+ m_node = 0;
+ }
+
+ unsigned count(void) const
+ {
+ return m_count;
+ }
+
+ void increment(void)
+ {
+ ++m_count;
+// std::cerr << "incremented "
+// << std::hex << ((unsigned long)this)
+// << " => " << ((unsigned long)m_owner) << ":" << ((unsigned long)m_node)
+// << ":" << std::dec << m_count << std::endl;
+ }
+
+ bool decrement(void)
+ {
+ --m_count;
+// std::cerr << "decremented "
+// << std::hex << ((unsigned long)this)
+// << " => " << ((unsigned long)m_owner) << ":" << ((unsigned long)m_node)
+// << ":" << std::dec << m_count << std::endl;
+ return m_count == 0;
+ }
+
+ N* node(void) const throw()
+ {
+ return m_node;
+ }
+
+ const O* owner(void) const throw()
+ {
+ return m_owner;
+ }
+
+ void change_owner(const O* owner)
+ {
+ m_owner = owner;
+ }
+
+ bool equal(const safe_iterator_body<O,N>* right) const throw()
+ {
+// return m_node == right->m_node;
+ return compare(right) == 0;
+ }
+
+ int compare(const safe_iterator_body<O,N>* right) const throw()
+ {
+ return ((long)m_node) - ((long)right->m_node);
+ }
+
+ bool null(void) const throw()
+ {
+ return m_owner == 0;
+ }
+
+ bool end(void) const throw()
+ {
+ return m_owner != 0 && m_node == 0;
+ }
+
+ bool valid(void) const throw()
+ {
+ return m_owner != 0 && m_node != 0;
+ }
+
+ void set_end(void) throw()
+ {
+ m_node = 0;
+ }
+
+ void set_null(void) throw()
+ {
+ m_owner = 0;
+ m_node = 0;
+ }
+
+ void assert_valid(void) const throw(null_dereference,end_dereference)
+ {
+ if (null())
+ throw null_dereference("stlplus::safe_iterator");
+ if (end())
+ throw end_dereference("stlplus::safe_iterator");
+ }
+
+ void assert_non_null(void) const throw(null_dereference)
+ {
+ if (null())
+ throw null_dereference("stlplus::safe_iterator");
+ }
+
+ void assert_owner(const O* owner) const throw(wrong_object)
+ {
+ if (owner != m_owner)
+ throw wrong_object("stlplus::safe_iterator");
+ }
+ };
+
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // Master Iterator
+ ////////////////////////////////////////////////////////////////////////////////
+
+ // construct a valid iterator
+ template<typename O, typename N>
+ master_iterator<O,N>::master_iterator(const O* owner, N* node) throw() :
+ m_body(new safe_iterator_body<O,N>(owner,node))
+ {
+ }
+
+ // destructor - disconnect all iterators from the node
+ // this usually happens when the node is deleted and must invalidate all aliases
+ template<typename O, typename N>
+ master_iterator<O,N>::~master_iterator(void) throw()
+ {
+ m_body->set_end();
+ if(m_body->decrement())
+ {
+ delete m_body;
+ m_body = 0;
+ }
+ }
+
+ // dereference
+ template<typename O, typename N>
+ N* master_iterator<O,N>::node(void) const throw()
+ {
+ return m_body->node();
+ }
+
+ template<typename O, typename N>
+ const O* master_iterator<O,N>::owner(void) const throw()
+ {
+ return m_body->owner();
+ }
+
+ // when you move a node from one owner to another, call this on the node's iterator
+ // this effectively moves all iterators to the node so that they are owned by the new owner too
+ template<typename O, typename N>
+ void master_iterator<O,N>::change_owner(const O* owner) throw()
+ {
+ m_body->change_owner(owner);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // Safe Iterator
+ ////////////////////////////////////////////////////////////////////////////////
+
+ // construct a null iterator
+ // later assignment of a valid iterator to this is done by using step
+ template<typename O, typename N>
+ safe_iterator<O,N>::safe_iterator(void) throw() :
+ m_body(new safe_iterator_body<O,N>(0,0))
+ {
+ }
+
+ // construct a valid iterator by aliasing from the owner node's master iterator
+ template<typename O, typename N>
+ safe_iterator<O,N>::safe_iterator(const master_iterator<O,N>& r) throw() :
+ m_body(0)
+ {
+ m_body = r.m_body;
+ m_body->increment();
+ }
+
+ // construct a valid iterator by aliasing from the owner node's master iterator
+ template<typename O, typename N>
+ safe_iterator<O,N>::safe_iterator(const safe_iterator<O,N>& r) throw() :
+ m_body(0)
+ {
+ m_body = r.m_body;
+ m_body->increment();
+ }
+
+ // assignment implements dealiasing followed by aliasing
+ template<typename O, typename N>
+ safe_iterator<O,N>& safe_iterator<O,N>::operator=(const safe_iterator<O,N>& r) throw()
+ {
+ if (m_body != r.m_body)
+ {
+ if (m_body->decrement())
+ delete m_body;
+ m_body = r.m_body;
+ m_body->increment();
+ }
+ return *this;
+ }
+
+ // destructor - implements dealiasing
+ template<typename O, typename N>
+ safe_iterator<O,N>::~safe_iterator(void) throw()
+ {
+ if(m_body->decrement())
+ {
+ delete m_body;
+ m_body = 0;
+ }
+ }
+
+
+ // increment/decrement operation
+ // implements dealiasing followed by aliasing
+ template<typename O, typename N>
+ void safe_iterator<O,N>::set(const master_iterator<O,N>& r) throw()
+ {
+ if (m_body != r.m_body)
+ {
+ if (m_body->decrement())
+ delete m_body;
+ m_body = r.m_body;
+ m_body->increment();
+ }
+ }
+
+ // dereference
+ template<typename O, typename N>
+ N* safe_iterator<O,N>::node(void) const throw()
+ {
+ return m_body->node();
+ }
+
+ template<typename O, typename N>
+ const O* safe_iterator<O,N>::owner(void) const throw()
+ {
+ return m_body->owner();
+ }
+
+ // change to a null iterator - i.e. one that doees not belong to any object
+ // this does not affect any other iterators pointing to the same node
+ template<typename O, typename N>
+ void safe_iterator<O,N>::set_null(void) throw()
+ {
+ if (m_body->count() == 1)
+ {
+ // no aliases, so just make this null
+ m_body->set_null();
+ }
+ else
+ {
+ // create a new body which is null so as not to affect any other aliases
+ m_body->decrement();
+ m_body = new safe_iterator_body<O,N>(0,0);
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // operations for clients that do not have a master end iterator
+ // alternatively, have a master end iterator as part of the container
+ // and call constructor(master_end) or step(master_end)
+
+ // construct an end iterator
+ template<typename O, typename N>
+ safe_iterator<O,N>::safe_iterator(const O* owner) throw() :
+ m_body(new safe_iterator_body<O,N>(owner,0))
+ {
+ }
+
+ // change to an end iterator - e.g. as a result of incrementing off the end
+ template<typename O, typename N>
+ void safe_iterator<O,N>::set_end(void) throw()
+ {
+ if (m_body->count() == 1)
+ {
+ // no aliases, so just make this an end iterator
+ m_body->set_end();
+ }
+ else
+ {
+ // create a new body which is null so as not to affect any other aliases
+ m_body->decrement();
+ m_body = new safe_iterator_body<O,N>(owner(),0);
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // tests
+
+ // comparison
+ template<typename O, typename N>
+ bool safe_iterator<O,N>::equal(const safe_iterator<O,N>& right) const throw()
+ {
+ return compare(right) == 0;
+ }
+
+ template<typename O, typename N>
+ int safe_iterator<O,N>::compare(const safe_iterator<O,N>& right) const throw()
+ {
+ if (m_body == right.m_body) return 0;
+ return m_body->compare(right.m_body);
+ }
+
+ // a null iterator is one that has not been initialised with a value yet
+ template<typename O, typename N>
+ bool safe_iterator<O,N>::null(void) const throw()
+ {
+ return m_body->null();
+ }
+
+ // an end iterator is one that points to the end element of the list of nodes
+ template<typename O, typename N>
+ bool safe_iterator<O,N>::end(void) const throw()
+ {
+ return m_body->end();
+ }
+
+ // a valid iterator is one that can be dereferenced
+ template<typename O, typename N>
+ bool safe_iterator<O,N>::valid(void) const throw()
+ {
+ return m_body->valid();
+ }
+
+ // check the rules for a valid iterator that can be dereferenced
+ template<typename O, typename N>
+ void safe_iterator<O,N>::assert_valid(void) const throw(null_dereference,end_dereference)
+ {
+ m_body->assert_valid();
+ }
+
+ template<typename O, typename N>
+ void safe_iterator<O,N>::assert_valid(const O* owner) const throw(wrong_object,null_dereference,end_dereference)
+ {
+ m_body->assert_valid();
+ m_body->assert_owner(owner);
+ }
+
+ template<typename O, typename N>
+ void safe_iterator<O,N>::assert_non_null(void) const throw(null_dereference)
+ {
+ m_body->assert_non_null();
+ }
+
+ template<typename O, typename N>
+ void safe_iterator<O,N>::assert_owner(const O* owner) const throw(wrong_object)
+ {
+ m_body->assert_owner(owner);
+ }
+
+} // end namespace stlplus