-#ifndef STLPLUS_SIMPLE_PTR\r
-#define STLPLUS_SIMPLE_PTR\r
-////////////////////////////////////////////////////////////////////////////////\r
-\r
-// Author: Daniel Milton, Andy Rushton\r
-// Copyright: (c) Southampton University 1999-2004\r
-// (c) Daniel Milton, Andy Rushton 2004-2009\r
-// License: BSD License, see ../docs/license.html\r
-\r
-// A smart pointer is a memory-managing pointer to an object. If you like, it\r
-// is a zero-dimensional container.\r
-\r
-// Assignment of smart pointers result in multiple aliases of the same object.\r
-// The term alias is used to differentiate from conventional pointers because\r
-// the semantics are different.\r
-\r
-// Aliases can be turned into copies if the pointed-to class supports copying.\r
-\r
-// These simple_ptr classes from DJDM have slightly different semantics than\r
-// the smart_ptr classes of AJR. There are no cross-pointer side effects\r
-// that occur when the pointer is cleared. The clear() function is effectively\r
-// equivalent to the clear_unique() function of the smart_ptr. The only way\r
-// that a "referenced" object will be deleted is if all simple_ptr's that\r
-// reference the object are cleared (by deletion, manual clearing or reassignment).\r
-\r
-// Also, the simple pointer cannot contain a reference to a shared null pointer\r
-// (which occurs as a side-effect of clearing a multiply referenced object in\r
-// the smart_ptr classes). Which means that if you have a null simple_ptr, then\r
-// the assignment of any other null simple_ptr will NOT reassign the reference of\r
-// any other simple_ptr. Hence, the simple_ptr class acts a little more like a\r
-// normal pointer (with fewer side effects), with the added bonus of containment.\r
-\r
-// Due to the way that the simple_ptr contains the data, it also allows the\r
-// addition of various casting functions, while still keeping the managed data\r
-// containment functionality of the underlying object. This means that you can\r
-// have two simple_ptr's of different template types, both pointing to the same\r
-// data (if the differing template types are derivatives of each other).\r
-\r
-// The base class is simple_ptr_base which defines the common interface. Then\r
-// there are three subclasses which have the same interface but different copy\r
-// semantics:\r
-\r
-// - simple_ptr for simple types and classes which have copy constructors\r
-// - simple_ptr_clone for polymorphic class hierarchies which are copied using a clone method\r
-// - simple_ptr_nocopy for any class that cannot or should not be copied\r
-\r
-////////////////////////////////////////////////////////////////////////////////\r
-#include "containers_fixes.hpp"\r
-#include "exceptions.hpp"\r
-#include "copy_functors.hpp"\r
-#include <map>\r
-#include <string>\r
-\r
-namespace stlplus\r
-{\r
-\r
- ////////////////////////////////////////////////////////////////////////////////\r
- // Base class\r
- ////////////////////////////////////////////////////////////////////////////////\r
-\r
- template<typename T, typename C>\r
- class simple_ptr_base\r
- {\r
- public:\r
- //////////////////////////////////////////////////////////////////////////////\r
- // member type definitions\r
-\r
- typedef T value_type;\r
- typedef T& reference;\r
- typedef const T& const_reference;\r
- typedef C value_copy;\r
-\r
- //////////////////////////////////////////////////////////////////////////////\r
- // constructors and destructors\r
-\r
- // create a null pointer\r
- simple_ptr_base(void);\r
-\r
- // create a pointer containing a *copy* of the object using the template parameter C\r
- // this copy is taken because the pointer class maintains a dynamically allocated object\r
- // and the T& may not be (usually is not) dynamically allocated\r
- explicit simple_ptr_base(const T& data) throw(illegal_copy);\r
-\r
- // create a pointer containing a dynamically created object\r
- // Note: the object must be allocated *by the user* with new\r
- // constructor form - must be called in the form smart_ptr_base<type> x(new type(args))\r
- explicit simple_ptr_base(T* data);\r
-\r
- // copy constructor implements aliasing so no copy is made\r
- // note that the copy constructor should NOT be explicit, as this breaks\r
- // the returning of pointer objects from functions (at least within GCC 4.4)\r
- simple_ptr_base(const simple_ptr_base<T,C>& r);\r
-\r
- // assignment operator - required, else the output of GCC suffers segmentation faults\r
- simple_ptr_base<T,C>& operator=(const simple_ptr_base<T,C>& r);\r
-\r
- // destructor decrements the reference count and delete only when the last reference is destroyed\r
- ~simple_ptr_base(void);\r
-\r
- //////////////////////////////////////////////////////////////////////////////\r
- // logical tests to see if there is anything contained in the pointer since it can be null\r
-\r
- // there are two forms:explicit and implicit\r
- // implicit: if(!r) or if(r)\r
- // explicit: if(r.null()) or if(r.present())\r
- operator bool(void) const;\r
- bool operator!(void) const;\r
- bool present(void) const;\r
- bool null(void) const;\r
-\r
- //////////////////////////////////////////////////////////////////////////////\r
- // dereference operators and functions\r
-\r
- // dereference the smart pointer to get the object - use in the form *p1\r
- T& operator*(void) throw(null_dereference);\r
- const T& operator*(void) const throw(null_dereference);\r
-\r
- // used as a prefix to a member access to the contained object e.g. p1->print() calls T::print()\r
- T* operator->(void) throw(null_dereference);\r
- const T* operator->(void) const throw(null_dereference);\r
-\r
- //////////////////////////////////////////////////////////////////////////////\r
- // explicit function forms of the above assignment and dereference operators\r
-\r
- // set the value - note that this does a copy using the C template parameter\r
- void set_value(const T& data) throw(illegal_copy);\r
- // get the value\r
- T& value(void) throw(null_dereference);\r
- const T& value(void) const throw(null_dereference);\r
-\r
- // set the pointer\r
- // deletes the previous pointer and adopts the passed pointer instead\r
- // Note: the object must be allocated *by the user* with new\r
- // Warning: it is very easy to break the memory management with this operation\r
- void set(T* data = 0);\r
- // get the pointer\r
- T* pointer(void);\r
- const T* pointer(void) const;\r
-\r
- //////////////////////////////////////////////////////////////////////////////\r
- // functions to manage aliases\r
-\r
- // make this an alias of the passed object\r
- void alias(const simple_ptr_base<T,C>&);\r
-\r
- // test whether two pointers point to the same object(known as aliasing the object)\r
- // used in the form if(a.aliases(b))\r
- bool aliases(const simple_ptr_base<T,C>&) const;\r
-\r
- // find the number of aliases - used when you need to know whether an\r
- // object is still referred to from elsewhere (rare!)\r
- unsigned alias_count(void) const;\r
-\r
- // clear the reference to the object, but only delete the object if there are no\r
- // other references to that object. Hence, this does not affect other pointers\r
- // that are pointing to the same object.\r
- void clear(void);\r
-\r
- // This is just an alias of the clear() function, provided for completeness of\r
- // the interface when acting as a replacement for the smart_ptr classes\r
- void clear_unique(void);\r
-\r
- //////////////////////////////////////////////////////////////////////////////\r
- // functions that involve copying\r
-\r
- // these functions use the copy functor passed as the template parameter C\r
- // to copy the object with the right copy semantics. If the copy functor\r
- // is no_copy, an exception will be thrown.\r
-\r
- // make this pointer unique with respect to any other references to the same object\r
- // if this pointer is already unique, it does nothing - otherwise it copies the object\r
- void make_unique(void) throw(illegal_copy);\r
-\r
- // make this pointer a unique copy of the parameter\r
- // useful for expressions like p1.copy(p2) which makes p1 a pointer to a unique copy of the contents of p2\r
- void copy(const simple_ptr_base<T,C>&) throw(illegal_copy);\r
-\r
- //////////////////////////////////////////////////////////////////////////////\r
- // functions that involve casting\r
-\r
-#ifdef STLPLUS_MEMBER_TEMPLATES\r
-\r
- // dynamic cast of underlying pointer to a derived/parent\r
- template<typename T2> simple_ptr_base<T2,C> dyn_cast(void) const;\r
-\r
- // static cast of underlying pointer to a derived/parent\r
- template<typename T2> simple_ptr_base<T2,C> stat_cast(void) const;\r
-\r
- // cast of underlying pointer to a base - while keeping the same ref-counted object\r
- template<typename T2> simple_ptr_base<T2,C> cast(void) const;\r
-\r
-#endif\r
-\r
- //////////////////////////////////////////////////////////////////////////////\r
-\r
- protected:\r
- T* m_pointer;\r
- unsigned* m_count;\r
-\r
- public:\r
- // internal use only - had to make them public because they need to be\r
- // accessed by routines that could not be made friends\r
- // can't have a handle due to the way the simple pointer stores it's data\r
- // in separate counter and pointer objects\r
- unsigned* _count(void) const;\r
- T* _pointer(void) const;\r
- void _make_alias(T* pointer, unsigned* count);\r
-\r
- private:\r
- void increment(void);\r
- bool decrement(void);\r
- };\r
-\r
- ////////////////////////////////////////////////////////////////////////////////\r
- // simple_ptr for simple types and classes which have copy constructors\r
-\r
- template <typename T>\r
- class simple_ptr : public simple_ptr_base<T, constructor_copy<T> >\r
- {\r
- public:\r
- simple_ptr(void) {}\r
- explicit simple_ptr(const T& data) : simple_ptr_base<T, constructor_copy<T> >(data) {}\r
- explicit simple_ptr(T* data) : simple_ptr_base<T, constructor_copy<T> >(data) {}\r
- simple_ptr<T>& operator=(const T& data) {set_value(data); return *this;}\r
- simple_ptr<T>& operator=(T* data) {set(data); return *this;}\r
- ~simple_ptr(void) {}\r
- };\r
-\r
- ////////////////////////////////////////////////////////////////////////////////\r
- // smart_ptr_clone for polymorphic class hierarchies which have a clone method\r
-\r
- template <typename T>\r
- class simple_ptr_clone : public simple_ptr_base<T, clone_copy<T> >\r
- {\r
- public:\r
- simple_ptr_clone(void) {}\r
- explicit simple_ptr_clone(const T& data) : simple_ptr_base<T, clone_copy<T> >(data) {}\r
- explicit simple_ptr_clone(T* data) : simple_ptr_base<T, clone_copy<T> >(data) {}\r
- simple_ptr_clone<T>& operator=(const T& data) {set_value(data); return *this;}\r
- simple_ptr_clone<T>& operator=(T* data) {set(data); return *this;}\r
- ~simple_ptr_clone(void) {}\r
- };\r
-\r
- ////////////////////////////////////////////////////////////////////////////////\r
- // smart_ptr_nocopy for any class that cannot or should not be copied\r
-\r
- template <typename T>\r
- class simple_ptr_nocopy : public simple_ptr_base<T, no_copy<T> >\r
- {\r
- public:\r
- simple_ptr_nocopy(void) {}\r
- explicit simple_ptr_nocopy(const T& data) : simple_ptr_base<T, no_copy<T> >(data) {}\r
- explicit simple_ptr_nocopy(T* data) : simple_ptr_base<T, no_copy<T> >(data) {}\r
- simple_ptr_nocopy<T>& operator=(const T& data) {set_value(data); return *this;}\r
- simple_ptr_nocopy<T>& operator=(T* data) {set(data); return *this;}\r
- ~simple_ptr_nocopy(void) {}\r
- };\r
-\r
- ////////////////////////////////////////////////////////////////////////////////\r
-\r
-} // end namespace stlplus\r
-\r
-#include "simple_ptr.tpp"\r
-#endif\r
+#ifndef STLPLUS_SIMPLE_PTR
+#define STLPLUS_SIMPLE_PTR
+////////////////////////////////////////////////////////////////////////////////
+
+// Author: Daniel Milton, Andy Rushton
+// Copyright: (c) Southampton University 1999-2004
+// (c) Daniel Milton, Andy Rushton 2004-2009
+// License: BSD License, see ../docs/license.html
+
+// A smart pointer is a memory-managing pointer to an object. If you like, it
+// is a zero-dimensional container.
+
+// Assignment of smart pointers result in multiple aliases of the same object.
+// The term alias is used to differentiate from conventional pointers because
+// the semantics are different.
+
+// Aliases can be turned into copies if the pointed-to class supports copying.
+
+// These simple_ptr classes from DJDM have slightly different semantics than
+// the smart_ptr classes of AJR. There are no cross-pointer side effects
+// that occur when the pointer is cleared. The clear() function is effectively
+// equivalent to the clear_unique() function of the smart_ptr. The only way
+// that a "referenced" object will be deleted is if all simple_ptr's that
+// reference the object are cleared (by deletion, manual clearing or reassignment).
+
+// Also, the simple pointer cannot contain a reference to a shared null pointer
+// (which occurs as a side-effect of clearing a multiply referenced object in
+// the smart_ptr classes). Which means that if you have a null simple_ptr, then
+// the assignment of any other null simple_ptr will NOT reassign the reference of
+// any other simple_ptr. Hence, the simple_ptr class acts a little more like a
+// normal pointer (with fewer side effects), with the added bonus of containment.
+
+// Due to the way that the simple_ptr contains the data, it also allows the
+// addition of various casting functions, while still keeping the managed data
+// containment functionality of the underlying object. This means that you can
+// have two simple_ptr's of different template types, both pointing to the same
+// data (if the differing template types are derivatives of each other).
+
+// The base class is simple_ptr_base which defines the common interface. Then
+// there are three subclasses which have the same interface but different copy
+// semantics:
+
+// - simple_ptr for simple types and classes which have copy constructors
+// - simple_ptr_clone for polymorphic class hierarchies which are copied using a clone method
+// - simple_ptr_nocopy for any class that cannot or should not be copied
+
+////////////////////////////////////////////////////////////////////////////////
+#include "containers_fixes.hpp"
+#include "exceptions.hpp"
+#include "copy_functors.hpp"
+#include <map>
+#include <string>
+
+namespace stlplus
+{
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // Base class
+ ////////////////////////////////////////////////////////////////////////////////
+
+ template<typename T, typename C>
+ class simple_ptr_base
+ {
+ public:
+ //////////////////////////////////////////////////////////////////////////////
+ // member type definitions
+
+ typedef T value_type;
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef C value_copy;
+
+ //////////////////////////////////////////////////////////////////////////////
+ // constructors and destructors
+
+ // create a null pointer
+ simple_ptr_base(void);
+
+ // create a pointer containing a *copy* of the object using the template parameter C
+ // this copy is taken because the pointer class maintains a dynamically allocated object
+ // and the T& may not be (usually is not) dynamically allocated
+ explicit simple_ptr_base(const T& data) throw(illegal_copy);
+
+ // create a pointer containing a dynamically created object
+ // Note: the object must be allocated *by the user* with new
+ // constructor form - must be called in the form smart_ptr_base<type> x(new type(args))
+ explicit simple_ptr_base(T* data);
+
+ // copy constructor implements aliasing so no copy is made
+ // note that the copy constructor should NOT be explicit, as this breaks
+ // the returning of pointer objects from functions (at least within GCC 4.4)
+ simple_ptr_base(const simple_ptr_base<T,C>& r);
+
+ // assignment operator - required, else the output of GCC suffers segmentation faults
+ simple_ptr_base<T,C>& operator=(const simple_ptr_base<T,C>& r);
+
+ // destructor decrements the reference count and delete only when the last reference is destroyed
+ ~simple_ptr_base(void);
+
+ //////////////////////////////////////////////////////////////////////////////
+ // logical tests to see if there is anything contained in the pointer since it can be null
+
+ // there are two forms:explicit and implicit
+ // implicit: if(!r) or if(r)
+ // explicit: if(r.null()) or if(r.present())
+ operator bool(void) const;
+ bool operator!(void) const;
+ bool present(void) const;
+ bool null(void) const;
+
+ //////////////////////////////////////////////////////////////////////////////
+ // dereference operators and functions
+
+ // dereference the smart pointer to get the object - use in the form *p1
+ T& operator*(void) throw(null_dereference);
+ const T& operator*(void) const throw(null_dereference);
+
+ // used as a prefix to a member access to the contained object e.g. p1->print() calls T::print()
+ T* operator->(void) throw(null_dereference);
+ const T* operator->(void) const throw(null_dereference);
+
+ //////////////////////////////////////////////////////////////////////////////
+ // explicit function forms of the above assignment and dereference operators
+
+ // set the value - note that this does a copy using the C template parameter
+ void set_value(const T& data) throw(illegal_copy);
+ // get the value
+ T& value(void) throw(null_dereference);
+ const T& value(void) const throw(null_dereference);
+
+ // set the pointer
+ // deletes the previous pointer and adopts the passed pointer instead
+ // Note: the object must be allocated *by the user* with new
+ // Warning: it is very easy to break the memory management with this operation
+ void set(T* data = 0);
+ // get the pointer
+ T* pointer(void);
+ const T* pointer(void) const;
+
+ //////////////////////////////////////////////////////////////////////////////
+ // functions to manage aliases
+
+ // make this an alias of the passed object
+ void alias(const simple_ptr_base<T,C>&);
+
+ // test whether two pointers point to the same object(known as aliasing the object)
+ // used in the form if(a.aliases(b))
+ bool aliases(const simple_ptr_base<T,C>&) const;
+
+ // find the number of aliases - used when you need to know whether an
+ // object is still referred to from elsewhere (rare!)
+ unsigned alias_count(void) const;
+
+ // clear the reference to the object, but only delete the object if there are no
+ // other references to that object. Hence, this does not affect other pointers
+ // that are pointing to the same object.
+ void clear(void);
+
+ // This is just an alias of the clear() function, provided for completeness of
+ // the interface when acting as a replacement for the smart_ptr classes
+ void clear_unique(void);
+
+ //////////////////////////////////////////////////////////////////////////////
+ // functions that involve copying
+
+ // these functions use the copy functor passed as the template parameter C
+ // to copy the object with the right copy semantics. If the copy functor
+ // is no_copy, an exception will be thrown.
+
+ // make this pointer unique with respect to any other references to the same object
+ // if this pointer is already unique, it does nothing - otherwise it copies the object
+ void make_unique(void) throw(illegal_copy);
+
+ // make this pointer a unique copy of the parameter
+ // useful for expressions like p1.copy(p2) which makes p1 a pointer to a unique copy of the contents of p2
+ void copy(const simple_ptr_base<T,C>&) throw(illegal_copy);
+
+ //////////////////////////////////////////////////////////////////////////////
+ // functions that involve casting
+
+#ifdef STLPLUS_MEMBER_TEMPLATES
+
+ // dynamic cast of underlying pointer to a derived/parent
+ template<typename T2> simple_ptr_base<T2,C> dyn_cast(void) const;
+
+ // static cast of underlying pointer to a derived/parent
+ template<typename T2> simple_ptr_base<T2,C> stat_cast(void) const;
+
+ // cast of underlying pointer to a base - while keeping the same ref-counted object
+ template<typename T2> simple_ptr_base<T2,C> cast(void) const;
+
+#endif
+
+ //////////////////////////////////////////////////////////////////////////////
+
+ protected:
+ T* m_pointer;
+ unsigned* m_count;
+
+ public:
+ // internal use only - had to make them public because they need to be
+ // accessed by routines that could not be made friends
+ // can't have a handle due to the way the simple pointer stores it's data
+ // in separate counter and pointer objects
+ unsigned* _count(void) const;
+ T* _pointer(void) const;
+ void _make_alias(T* pointer, unsigned* count);
+
+ private:
+ void increment(void);
+ bool decrement(void);
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // simple_ptr for simple types and classes which have copy constructors
+
+ template <typename T>
+ class simple_ptr : public simple_ptr_base<T, constructor_copy<T> >
+ {
+ public:
+ simple_ptr(void) {}
+ explicit simple_ptr(const T& data) : simple_ptr_base<T, constructor_copy<T> >(data) {}
+ explicit simple_ptr(T* data) : simple_ptr_base<T, constructor_copy<T> >(data) {}
+ simple_ptr<T>& operator=(const T& data) {set_value(data); return *this;}
+ simple_ptr<T>& operator=(T* data) {set(data); return *this;}
+ ~simple_ptr(void) {}
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // smart_ptr_clone for polymorphic class hierarchies which have a clone method
+
+ template <typename T>
+ class simple_ptr_clone : public simple_ptr_base<T, clone_copy<T> >
+ {
+ public:
+ simple_ptr_clone(void) {}
+ explicit simple_ptr_clone(const T& data) : simple_ptr_base<T, clone_copy<T> >(data) {}
+ explicit simple_ptr_clone(T* data) : simple_ptr_base<T, clone_copy<T> >(data) {}
+ simple_ptr_clone<T>& operator=(const T& data) {set_value(data); return *this;}
+ simple_ptr_clone<T>& operator=(T* data) {set(data); return *this;}
+ ~simple_ptr_clone(void) {}
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // smart_ptr_nocopy for any class that cannot or should not be copied
+
+ template <typename T>
+ class simple_ptr_nocopy : public simple_ptr_base<T, no_copy<T> >
+ {
+ public:
+ simple_ptr_nocopy(void) {}
+ explicit simple_ptr_nocopy(const T& data) : simple_ptr_base<T, no_copy<T> >(data) {}
+ explicit simple_ptr_nocopy(T* data) : simple_ptr_base<T, no_copy<T> >(data) {}
+ simple_ptr_nocopy<T>& operator=(const T& data) {set_value(data); return *this;}
+ simple_ptr_nocopy<T>& operator=(T* data) {set(data); return *this;}
+ ~simple_ptr_nocopy(void) {}
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////
+
+} // end namespace stlplus
+
+#include "simple_ptr.tpp"
+#endif