]> Dogcows Code - chaz/yoink/blobdiff - src/stlplus/containers/simple_ptr.hpp
import stlplus 3.7
[chaz/yoink] / src / stlplus / containers / simple_ptr.hpp
index 72d1db7e16d0bf15efed1cd6c9dba1103fd1efb3..ffe2c8afeee60a56feeab042205db5a54f5b013f 100644 (file)
-#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
+#ifndef STLPLUS_SIMPLE_PTR\r
+#define STLPLUS_SIMPLE_PTR\r
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+//   Author:    Daniel Milton\r
+//   Copyright: (c) Daniel Milton           2002 onwards\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 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
+    // 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
+    // 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
+    // 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
+\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
+\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
+#ifdef STLPLUS_MEMBER_TEMPLATES\r
+    // functions that involve casting\r
+    // moved from base class for two main reasons, though the second is a feature of the first:\r
+\r
+    // 1. GCC cannot cast the previous base result of simple_ptr_base<T2, constructor_copy<T> >\r
+    //    as a simple_ptr<T2> even though it used to look like a duck and quack like a duck.\r
+    //    I think it was really complaining that the copy class was not guaranteed to be the same.\r
+\r
+    // 2. Within the cast routines, one pointer type tried accessing private data of the other\r
+    //    pointer type and even though they are really the same type, was not allowed. Because\r
+    //    of this, the "private" function _make_alias is utilised to get the same result.\r
+\r
+    // By having the cast functions in each derived class, you are guaranteed to use the same\r
+    // copy class - no question. GCC is ok with this.\r
+\r
+    template<typename T2> simple_ptr<T2> dyn_cast(void) const;\r
+    template<typename T2> simple_ptr<T2> stat_cast(void) const;\r
+    template<typename T2> simple_ptr<T2> cast(void) const;\r
+#endif\r
+  };\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+  // simple_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
+#ifdef STLPLUS_MEMBER_TEMPLATES\r
+    // functions that involve casting\r
+    // moved from base class - see simple_ptr above\r
+    template<typename T2> simple_ptr_clone<T2> dyn_cast(void) const;\r
+    template<typename T2> simple_ptr_clone<T2> stat_cast(void) const;\r
+    template<typename T2> simple_ptr_clone<T2> cast(void) const;\r
+#endif\r
+};\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+  // simple_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(T* data) : simple_ptr_base<T, no_copy<T> >(data) {}\r
+    simple_ptr_nocopy<T>& operator=(T* data) {set(data); return *this;}\r
+    ~simple_ptr_nocopy(void) {}\r
+\r
+#ifdef STLPLUS_MEMBER_TEMPLATES\r
+    // functions that involve casting\r
+    // moved from base class - see simple_ptr above\r
+    template<typename T2> simple_ptr_nocopy<T2> dyn_cast(void) const;\r
+    template<typename T2> simple_ptr_nocopy<T2> stat_cast(void) const;\r
+    template<typename T2> simple_ptr_nocopy<T2> cast(void) const;\r
+#endif\r
+  };\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+\r
+} // end namespace stlplus\r
+\r
+#include "simple_ptr.tpp"\r
+#endif\r
This page took 0.025764 seconds and 4 git commands to generate.