X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2Fstlplus%2Fcontainers%2Fsafe_iterator.hpp;h=6d8b5635617e5aa2390f3ebfb27d53de4bf72770;hp=74126878247eded69f19959f38b507e4b59f8c3b;hb=4f6e4488a55f7e3ba3f7485d78177f793c0eab9a;hpb=574af38ed616d1adfa5e6ce35f67cda1f707f89d diff --git a/src/stlplus/containers/safe_iterator.hpp b/src/stlplus/containers/safe_iterator.hpp index 7412687..6d8b563 100644 --- a/src/stlplus/containers/safe_iterator.hpp +++ b/src/stlplus/containers/safe_iterator.hpp @@ -1,155 +1,155 @@ -#ifndef STLPLUS_SAFE_ITERATOR -#define STLPLUS_SAFE_ITERATOR -//////////////////////////////////////////////////////////////////////////////// - -// Author: Andy Rushton -// Copyright: (c) Southampton University 1999-2004 -// (c) Andy Rushton 2004-2009 -// License: BSD License, see ../docs/license.html - -// The STLplus safe_iterator superclasses. This implements the STLplus safe -// iterator principles. Data structures can then be built using subclasses -// of safe_iterator for their iterator objects and they will inherit the -// safe iterator behaviour. - -// The data structure must contain a master iterator for each node in the -// structure. When an iterator is returned to the user, it must be created -// by the master iterator. When a node is removed from the data structure, -// its master iterator is destroyed. This sets all iterators pointing to the -// master iterator to end iterators. - -//////////////////////////////////////////////////////////////////////////////// -#include "containers_fixes.hpp" -#include "exceptions.hpp" - -namespace stlplus -{ - - //////////////////////////////////////////////////////////////////////////////// - // internals - - template - class safe_iterator_body; - - template - class safe_iterator; - - //////////////////////////////////////////////////////////////////////////////// - // Master Iterator - // Create one of these in each node in the data structure - // Generate iterators by obtaining a safe-iterator object from the master iterator - //////////////////////////////////////////////////////////////////////////////// - - template - class master_iterator - { - public: - - // construct a valid master iterator connected to the node - master_iterator(const O* owner, N* node) throw(); - - // destructor - disconnects all iterators from the node - ~master_iterator(void) throw(); - - // dereference - N* node(void) const throw(); - const O* owner(void) const throw(); - - // when you move a node from one owner to another, call this on the node's master iterator - // this effectively moves all other iterators to the node so that they are owned by the new owner too - void change_owner(const O* owner) throw(); - - friend class safe_iterator; - private: - master_iterator(const master_iterator&) throw(); - master_iterator& operator=(const master_iterator&) throw(); - safe_iterator_body* m_body; - }; - - //////////////////////////////////////////////////////////////////////////////// - // Safe Iterator - //////////////////////////////////////////////////////////////////////////////// - - template - class safe_iterator - { - public: - - // construct a null iterator - safe_iterator(void) throw(); - - // construct a valid iterator by aliasing from the owner node's master iterator - safe_iterator(const master_iterator&) throw(); - - // copy constructor does aliasing - safe_iterator(const safe_iterator&) throw(); - - // alias an iterator by assignment - safe_iterator& operator=(const safe_iterator&) throw(); - - // destructor - ~safe_iterator(void) throw(); - - // reassignment to another node used in increment/decrement operation - void set(const master_iterator&) throw(); - - // dereference - N* node(void) const throw(); - const O* owner(void) const throw(); - - // change to a null iterator - i.e. one that does not belong to any object - // this does not affect any other iterators pointing to the same node - void set_null(void) throw(); - - //////////////////////////////////////////////////////////////////////////////// - // 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 set(master_end) - - // construct an end iterator - safe_iterator(const O* owner) throw(); - - // change to an end iterator - e.g. as a result of incrementing off the end - void set_end(void) throw(); - - //////////////////////////////////////////////////////////////////////////////// - // tests - - // comparison - bool equal(const safe_iterator& right) const throw(); - int compare(const safe_iterator& right) const throw(); - - // a null iterator is one that has not been initialised with a value yet - // i.e. you just declared it but didn't assign to it - bool null(void) const throw(); - - // an end iterator is one that points to the end element of the list of nodes - // in STL conventions this is one past the last valid element and must not be dereferenced - bool end(void) const throw(); - - // a valid iterator is one that can be dereferenced - // i.e. non-null and non-end - bool valid(void) const throw(); - - // check the rules for a valid iterator that can be dereferenced - // optionally also check that the iterator is owned by the owner - void assert_valid(void) const throw(null_dereference,end_dereference); - void assert_valid(const O* owner) const throw(wrong_object,null_dereference,end_dereference); - // assert the rules for a non-null iterator - i.e. valid or end, values that occur in increment operations - void assert_non_null(void) const throw(null_dereference); - // assert that this iterator is owned by this container - void assert_owner(const O* owner) const throw(wrong_object); - - //////////////////////////////////////////////////////////////////////////////// - - friend class master_iterator; - private: - safe_iterator_body* m_body; - }; - - //////////////////////////////////////////////////////////////////////////////// - -} // end namespace stlplus - -#include "safe_iterator.tpp" -#endif +#ifndef STLPLUS_SAFE_ITERATOR +#define STLPLUS_SAFE_ITERATOR +//////////////////////////////////////////////////////////////////////////////// + +// Author: Andy Rushton +// Copyright: (c) Southampton University 1999-2004 +// (c) Andy Rushton 2004 onwards +// License: BSD License, see ../docs/license.html + +// The STLplus safe_iterator superclasses. This implements the STLplus safe +// iterator principles. Data structures can then be built using subclasses +// of safe_iterator for their iterator objects and they will inherit the +// safe iterator behaviour. + +// The data structure must contain a master iterator for each node in the +// structure. When an iterator is returned to the user, it must be created +// by the master iterator. When a node is removed from the data structure, +// its master iterator is destroyed. This sets all iterators pointing to the +// master iterator to end iterators. + +//////////////////////////////////////////////////////////////////////////////// +#include "containers_fixes.hpp" +#include "exceptions.hpp" + +namespace stlplus +{ + + //////////////////////////////////////////////////////////////////////////////// + // internals + + template + class safe_iterator_body; + + template + class safe_iterator; + + //////////////////////////////////////////////////////////////////////////////// + // Master Iterator + // Create one of these in each node in the data structure + // Generate iterators by obtaining a safe-iterator object from the master iterator + //////////////////////////////////////////////////////////////////////////////// + + template + class master_iterator + { + public: + + // construct a valid master iterator connected to the node + master_iterator(const O* owner, N* node) throw(); + + // destructor - disconnects all iterators from the node + ~master_iterator(void) throw(); + + // dereference + N* node(void) const throw(); + const O* owner(void) const throw(); + + // when you move a node from one owner to another, call this on the node's master iterator + // this effectively moves all other iterators to the node so that they are owned by the new owner too + void change_owner(const O* owner) throw(); + + friend class safe_iterator; + private: + master_iterator(const master_iterator&) throw(); + master_iterator& operator=(const master_iterator&) throw(); + safe_iterator_body* m_body; + }; + + //////////////////////////////////////////////////////////////////////////////// + // Safe Iterator + //////////////////////////////////////////////////////////////////////////////// + + template + class safe_iterator + { + public: + + // construct a null iterator + safe_iterator(void) throw(); + + // construct a valid iterator by aliasing from the owner node's master iterator + safe_iterator(const master_iterator&) throw(); + + // copy constructor does aliasing + safe_iterator(const safe_iterator&) throw(); + + // alias an iterator by assignment + safe_iterator& operator=(const safe_iterator&) throw(); + + // destructor + ~safe_iterator(void) throw(); + + // reassignment to another node used in increment/decrement operation + void set(const master_iterator&) throw(); + + // dereference + N* node(void) const throw(); + const O* owner(void) const throw(); + + // change to a null iterator - i.e. one that does not belong to any object + // this does not affect any other iterators pointing to the same node + void set_null(void) throw(); + + //////////////////////////////////////////////////////////////////////////////// + // 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 set(master_end) + + // construct an end iterator + safe_iterator(const O* owner) throw(); + + // change to an end iterator - e.g. as a result of incrementing off the end + void set_end(void) throw(); + + //////////////////////////////////////////////////////////////////////////////// + // tests + + // comparison + bool equal(const safe_iterator& right) const throw(); + int compare(const safe_iterator& right) const throw(); + + // a null iterator is one that has not been initialised with a value yet + // i.e. you just declared it but didn't assign to it + bool null(void) const throw(); + + // an end iterator is one that points to the end element of the list of nodes + // in STL conventions this is one past the last valid element and must not be dereferenced + bool end(void) const throw(); + + // a valid iterator is one that can be dereferenced + // i.e. non-null and non-end + bool valid(void) const throw(); + + // check the rules for a valid iterator that can be dereferenced + // optionally also check that the iterator is owned by the owner + void assert_valid(void) const throw(null_dereference,end_dereference); + void assert_valid(const O* owner) const throw(wrong_object,null_dereference,end_dereference); + // assert the rules for a non-null iterator - i.e. valid or end, values that occur in increment operations + void assert_non_null(void) const throw(null_dereference); + // assert that this iterator is owned by this container + void assert_owner(const O* owner) const throw(wrong_object); + + //////////////////////////////////////////////////////////////////////////////// + + friend class master_iterator; + private: + safe_iterator_body* m_body; + }; + + //////////////////////////////////////////////////////////////////////////////// + +} // end namespace stlplus + +#include "safe_iterator.tpp" +#endif