]> Dogcows Code - chaz/yoink/blobdiff - src/stlplus/containers/smart_ptr.tpp
import stlplus 3.7
[chaz/yoink] / src / stlplus / containers / smart_ptr.tpp
index 3af02101e92303c3cddf66b78a4fbe70730a16e6..880b69a0789cdb930b402010b05ab6418c612e00 100644 (file)
-////////////////////////////////////////////////////////////////////////////////
-
-//   Author:    Andy Rushton
-//   Copyright: (c) Southampton University 1999-2004
-//              (c) Andy Rushton           2004-2009
-//   License:   BSD License, see ../docs/license.html
-
-////////////////////////////////////////////////////////////////////////////////
-
-namespace stlplus
-{
-
-  ////////////////////////////////////////////////////////////////////////////////
-  // internal holder data structure
-  ////////////////////////////////////////////////////////////////////////////////
-
-  template<typename T>
-  class smart_ptr_holder
-  {
-  private:
-    unsigned m_count;
-    T* m_data;
-
-    // make these private to disallow copying because the holder doesn't know how to copy
-    smart_ptr_holder(const smart_ptr_holder& s) :
-      m_count(0), m_data(0)
-      {
-      }
-
-    smart_ptr_holder& operator=(const smart_ptr_holder& s)
-      {
-        return *this;
-      }
-
-  public:
-    smart_ptr_holder(T* p = 0) :
-      m_count(1), m_data(p)
-      {
-      }
-
-    ~smart_ptr_holder(void)
-      {
-        clear();
-      }
-
-    unsigned count(void) const
-      {
-        return m_count;
-      }
-
-    void increment(void)
-      {
-        ++m_count;
-      }
-
-    bool decrement(void)
-      {
-        --m_count;
-        return m_count == 0;
-      }
-
-    bool null(void)
-      {
-        return m_data == 0;
-      }
-
-    void clear(void)
-      {
-        if(m_data)
-          delete m_data;
-        m_data = 0;
-      }
-
-    void set(T* p = 0)
-      {
-        clear();
-        m_data = p;
-      }
-
-    T*& pointer(void)
-      {
-        return m_data;
-      }
-
-    const T* pointer(void) const
-      {
-        return m_data;
-      }
-
-    T& value(void)
-      {
-        return *m_data;
-      }
-
-    const T& value(void) const
-      {
-        return *m_data;
-      }
-  };
-
-  ////////////////////////////////////////////////////////////////////////////////
-  // smart_ptr_base class
-  ////////////////////////////////////////////////////////////////////////////////
-
-  ////////////////////////////////////////////////////////////////////////////////
-  // constructors, assignments and destructors
-
-  // create a null pointer
-  template <typename T, typename C>
-  smart_ptr_base<T,C>::smart_ptr_base(void) :
-    m_holder(new smart_ptr_holder<T>)
-  {
-  }
-
-  // create a pointer containing a *copy* of the object pointer
-  template <typename T, typename C>
-  smart_ptr_base<T,C>::smart_ptr_base(const T& data) throw(illegal_copy) :
-    m_holder(new smart_ptr_holder<T>)
-  {
-    m_holder->set(C()(data));
-  }
-
-  // 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<type> x(new type(args))
-  template <typename T, typename C>
-  smart_ptr_base<T,C>::smart_ptr_base(T* data) :
-    m_holder(new smart_ptr_holder<T>)
-  {
-    m_holder->set(data);
-  }
-
-  // copy constructor implements counted referencing - no copy is made
-  template <typename T, typename C>
-  smart_ptr_base<T,C>::smart_ptr_base(const smart_ptr_base<T,C>& r) :
-    m_holder(0)
-  {
-    m_holder = r.m_holder;
-    m_holder->increment();
-  }
-
-       // assignment operator - required, else the output of GCC suffers segmentation faults
-  template <typename T, typename C>
-  smart_ptr_base<T,C>& smart_ptr_base<T,C>::operator=(const smart_ptr_base<T,C>& r) 
-  {
-    alias(r);
-    return *this;
-  }
-
-  // destructor decrements the reference count and delete only when the last reference is destroyed
-  template <typename T, typename C>
-  smart_ptr_base<T,C>::~smart_ptr_base(void)
-  {
-    if(m_holder->decrement())
-      delete m_holder;
-  }
-
-  //////////////////////////////////////////////////////////////////////////////
-  // logical tests to see if there is anything contained in the pointer since it can be null
-
-  template <typename T, typename C>
-  bool smart_ptr_base<T,C>::null(void) const
-  {
-    return m_holder->null();
-  }
-
-  template <typename T, typename C>
-  bool smart_ptr_base<T,C>::present(void) const
-  {
-    return !m_holder->null();
-  }
-
-  template <typename T, typename C>
-  bool smart_ptr_base<T,C>::operator!(void) const
-  {
-    return m_holder->null();
-  }
-
-  template <typename T, typename C>
-  smart_ptr_base<T,C>::operator bool(void) const
-  {
-    return !m_holder->null();
-  }
-
-  //////////////////////////////////////////////////////////////////////////////
-  // dereference operators and functions
-
-  template <typename T, typename C>
-  T& smart_ptr_base<T,C>::operator*(void) throw(null_dereference)
-  {
-    if (m_holder->null()) throw null_dereference("null pointer dereferenced in smart_ptr::operator*");
-    return m_holder->value();
-  }
-
-  template <typename T, typename C>
-  const T& smart_ptr_base<T,C>::operator*(void) const throw(null_dereference)
-  {
-    if (m_holder->null()) throw null_dereference("null pointer dereferenced in smart_ptr::operator*");
-    return m_holder->value();
-  }
-
-  template <typename T, typename C>
-  T* smart_ptr_base<T,C>::operator->(void) throw(null_dereference)
-  {
-    if (m_holder->null()) throw null_dereference("null pointer dereferenced in smart_ptr::operator->");
-    return m_holder->pointer();
-  }
-
-  template <typename T, typename C>
-  const T* smart_ptr_base<T,C>::operator->(void) const throw(null_dereference)
-  {
-    if (m_holder->null()) throw null_dereference("null pointer dereferenced in smart_ptr::operator->");
-    return m_holder->pointer();
-  }
-
-  //////////////////////////////////////////////////////////////////////////////
-  // explicit function forms of the above assignment dereference operators
-
-  template <typename T, typename C>
-  void smart_ptr_base<T,C>::set_value(const T& data) throw(illegal_copy)
-  {
-    m_holder->set(C()(data));
-  }
-
-  template <typename T, typename C>
-  T& smart_ptr_base<T,C>::value(void) throw(null_dereference)
-  {
-    if (m_holder->null()) throw null_dereference("null pointer dereferenced in smart_ptr::value");
-    return m_holder->value();
-  }
-
-  template <typename T, typename C>
-  const T& smart_ptr_base<T,C>::value(void) const throw(null_dereference)
-  {
-    if (m_holder->null()) throw null_dereference("null pointer dereferenced in smart_ptr::value");
-    return m_holder->value();
-  }
-
-  template <typename T, typename C>
-  void smart_ptr_base<T,C>::set(T* data)
-  {
-    m_holder->set(data);
-  }
-
-  template <typename T, typename C>
-  T* smart_ptr_base<T,C>::pointer(void)
-  {
-    return m_holder->pointer();
-  }
-
-  template <typename T, typename C>
-  const T* smart_ptr_base<T,C>::pointer(void) const
-  {
-    return m_holder->pointer();
-  }
-
-  ////////////////////////////////////////////////////////////////////////////////
-  // functions to manage counted referencing
-
-  // make this an alias of the passed object
-  template <typename T, typename C>
-  void smart_ptr_base<T,C>::alias(const smart_ptr_base<T,C>& r)
-  {
-    _make_alias(r.m_holder);
-  }
-
-  template <typename T, typename C>
-  bool smart_ptr_base<T,C>::aliases(const smart_ptr_base<T,C>& r) const
-  {
-    return m_holder == r.m_holder;
-  }
-
-  template <typename T, typename C>
-  unsigned smart_ptr_base<T,C>::alias_count(void) const
-  {
-    return m_holder->count();
-  }
-
-  template <typename T, typename C>
-  void smart_ptr_base<T,C>::clear(void)
-  {
-    m_holder->clear();
-  }
-
-  template <typename T, typename C>
-  void smart_ptr_base<T,C>::clear_unique(void)
-  {
-    if (m_holder->count() == 1)
-      m_holder->clear();
-    else
-    {
-      m_holder->decrement();
-      m_holder = 0;
-      m_holder = new smart_ptr_holder<T>;
-    }
-  }
-
-  template <typename T, typename C>
-  void smart_ptr_base<T,C>::make_unique(void) throw(illegal_copy)
-  {
-    if (m_holder->count() > 1)
-    {
-      smart_ptr_holder<T>* old_holder = m_holder;
-      m_holder->decrement();
-      m_holder = 0;
-      m_holder = new smart_ptr_holder<T>;
-      if (old_holder->pointer())
-        m_holder->set(C()(old_holder->value()));
-    }
-  }
-
-  template <typename T, typename C>
-  void smart_ptr_base<T,C>::copy(const smart_ptr_base<T,C>& data) throw(illegal_copy)
-  {
-    alias(data);
-    make_unique();
-  }
-
-  // internal function for distinguishing unique smart_ptr objects
-  // used for example in persistence routines
-
-  template <typename T, typename C>
-  smart_ptr_holder<T>* smart_ptr_base<T,C>::_handle(void) const
-  {
-    return m_holder;
-  }
-
-  template <typename T, typename C>
-  void smart_ptr_base<T,C>::_make_alias(smart_ptr_holder<T>* r_holder)
-  {
-    // make it alias-copy safe - this means that I don't try to do the
-    // assignment if r is either the same object or an alias of it
-    if (m_holder != r_holder)
-    {
-      if (m_holder->decrement())
-        delete m_holder;
-      m_holder = r_holder;
-      m_holder->increment();
-    }
-  }
-
-  ////////////////////////////////////////////////////////////////////////////////
-
-} // end namespace stlplus
-
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+//   Author:    Andy Rushton\r
+//   Copyright: (c) Southampton University 1999-2004\r
+//              (c) Andy Rushton           2004 onwards\r
+//   License:   BSD License, see ../docs/license.html\r
+\r
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+namespace stlplus\r
+{\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+  // internal holder data structure\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+\r
+  template<typename T>\r
+  class smart_ptr_holder\r
+  {\r
+  private:\r
+    unsigned m_count;\r
+    T* m_data;\r
+\r
+    // make these private to disallow copying because the holder doesn't know how to copy\r
+    smart_ptr_holder(const smart_ptr_holder& s) :\r
+      m_count(0), m_data(0)\r
+      {\r
+      }\r
+\r
+    smart_ptr_holder& operator=(const smart_ptr_holder& s)\r
+      {\r
+        return *this;\r
+      }\r
+\r
+  public:\r
+    smart_ptr_holder(T* p = 0) :\r
+      m_count(1), m_data(p)\r
+      {\r
+      }\r
+\r
+    ~smart_ptr_holder(void)\r
+      {\r
+        clear();\r
+      }\r
+\r
+    unsigned count(void) const\r
+      {\r
+        return m_count;\r
+      }\r
+\r
+    void increment(void)\r
+      {\r
+        ++m_count;\r
+      }\r
+\r
+    bool decrement(void)\r
+      {\r
+        --m_count;\r
+        return m_count == 0;\r
+      }\r
+\r
+    bool null(void)\r
+      {\r
+        return m_data == 0;\r
+      }\r
+\r
+    void clear(void)\r
+      {\r
+        if(m_data)\r
+          delete m_data;\r
+        m_data = 0;\r
+      }\r
+\r
+    void set(T* p = 0)\r
+      {\r
+        clear();\r
+        m_data = p;\r
+      }\r
+\r
+    T*& pointer(void)\r
+      {\r
+        return m_data;\r
+      }\r
+\r
+    const T* pointer(void) const\r
+      {\r
+        return m_data;\r
+      }\r
+\r
+    T& value(void)\r
+      {\r
+        return *m_data;\r
+      }\r
+\r
+    const T& value(void) const\r
+      {\r
+        return *m_data;\r
+      }\r
+  };\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+  // smart_ptr_base class\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+  // constructors, assignments and destructors\r
+\r
+  // create a null pointer\r
+  template <typename T, typename C>\r
+  smart_ptr_base<T,C>::smart_ptr_base(void) :\r
+    m_holder(new smart_ptr_holder<T>)\r
+  {\r
+  }\r
+\r
+  // create a pointer containing a *copy* of the object pointer\r
+  template <typename T, typename C>\r
+  smart_ptr_base<T,C>::smart_ptr_base(const T& data) throw(illegal_copy) :\r
+    m_holder(new smart_ptr_holder<T>)\r
+  {\r
+    m_holder->set(C()(data));\r
+  }\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<type> x(new type(args))\r
+  template <typename T, typename C>\r
+  smart_ptr_base<T,C>::smart_ptr_base(T* data) :\r
+    m_holder(new smart_ptr_holder<T>)\r
+  {\r
+    m_holder->set(data);\r
+  }\r
+\r
+  // copy constructor implements counted referencing - no copy is made\r
+  template <typename T, typename C>\r
+  smart_ptr_base<T,C>::smart_ptr_base(const smart_ptr_base<T,C>& r) :\r
+    m_holder(0)\r
+  {\r
+    m_holder = r.m_holder;\r
+    m_holder->increment();\r
+  }\r
+\r
+       // assignment operator - required, else the output of GCC suffers segmentation faults\r
+  template <typename T, typename C>\r
+  smart_ptr_base<T,C>& smart_ptr_base<T,C>::operator=(const smart_ptr_base<T,C>& r) \r
+  {\r
+    alias(r);\r
+    return *this;\r
+  }\r
+\r
+  // destructor decrements the reference count and delete only when the last reference is destroyed\r
+  template <typename T, typename C>\r
+  smart_ptr_base<T,C>::~smart_ptr_base(void)\r
+  {\r
+    if(m_holder->decrement())\r
+      delete m_holder;\r
+  }\r
+\r
+  //////////////////////////////////////////////////////////////////////////////\r
+  // logical tests to see if there is anything contained in the pointer since it can be null\r
+\r
+  template <typename T, typename C>\r
+  bool smart_ptr_base<T,C>::null(void) const\r
+  {\r
+    return m_holder->null();\r
+  }\r
+\r
+  template <typename T, typename C>\r
+  bool smart_ptr_base<T,C>::present(void) const\r
+  {\r
+    return !m_holder->null();\r
+  }\r
+\r
+  template <typename T, typename C>\r
+  bool smart_ptr_base<T,C>::operator!(void) const\r
+  {\r
+    return m_holder->null();\r
+  }\r
+\r
+  template <typename T, typename C>\r
+  smart_ptr_base<T,C>::operator bool(void) const\r
+  {\r
+    return !m_holder->null();\r
+  }\r
+\r
+  //////////////////////////////////////////////////////////////////////////////\r
+  // dereference operators and functions\r
+\r
+  template <typename T, typename C>\r
+  T& smart_ptr_base<T,C>::operator*(void) throw(null_dereference)\r
+  {\r
+    if (m_holder->null()) throw null_dereference("null pointer dereferenced in smart_ptr::operator*");\r
+    return m_holder->value();\r
+  }\r
+\r
+  template <typename T, typename C>\r
+  const T& smart_ptr_base<T,C>::operator*(void) const throw(null_dereference)\r
+  {\r
+    if (m_holder->null()) throw null_dereference("null pointer dereferenced in smart_ptr::operator*");\r
+    return m_holder->value();\r
+  }\r
+\r
+  template <typename T, typename C>\r
+  T* smart_ptr_base<T,C>::operator->(void) throw(null_dereference)\r
+  {\r
+    if (m_holder->null()) throw null_dereference("null pointer dereferenced in smart_ptr::operator->");\r
+    return m_holder->pointer();\r
+  }\r
+\r
+  template <typename T, typename C>\r
+  const T* smart_ptr_base<T,C>::operator->(void) const throw(null_dereference)\r
+  {\r
+    if (m_holder->null()) throw null_dereference("null pointer dereferenced in smart_ptr::operator->");\r
+    return m_holder->pointer();\r
+  }\r
+\r
+  //////////////////////////////////////////////////////////////////////////////\r
+  // explicit function forms of the above assignment dereference operators\r
+\r
+  template <typename T, typename C>\r
+  void smart_ptr_base<T,C>::set_value(const T& data) throw(illegal_copy)\r
+  {\r
+    m_holder->set(C()(data));\r
+  }\r
+\r
+  template <typename T, typename C>\r
+  T& smart_ptr_base<T,C>::value(void) throw(null_dereference)\r
+  {\r
+    if (m_holder->null()) throw null_dereference("null pointer dereferenced in smart_ptr::value");\r
+    return m_holder->value();\r
+  }\r
+\r
+  template <typename T, typename C>\r
+  const T& smart_ptr_base<T,C>::value(void) const throw(null_dereference)\r
+  {\r
+    if (m_holder->null()) throw null_dereference("null pointer dereferenced in smart_ptr::value");\r
+    return m_holder->value();\r
+  }\r
+\r
+  template <typename T, typename C>\r
+  void smart_ptr_base<T,C>::set(T* data)\r
+  {\r
+    m_holder->set(data);\r
+  }\r
+\r
+  template <typename T, typename C>\r
+  T* smart_ptr_base<T,C>::pointer(void)\r
+  {\r
+    return m_holder->pointer();\r
+  }\r
+\r
+  template <typename T, typename C>\r
+  const T* smart_ptr_base<T,C>::pointer(void) const\r
+  {\r
+    return m_holder->pointer();\r
+  }\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+  // functions to manage counted referencing\r
+\r
+  // make this an alias of the passed object\r
+  template <typename T, typename C>\r
+  void smart_ptr_base<T,C>::alias(const smart_ptr_base<T,C>& r)\r
+  {\r
+    _make_alias(r.m_holder);\r
+  }\r
+\r
+  template <typename T, typename C>\r
+  bool smart_ptr_base<T,C>::aliases(const smart_ptr_base<T,C>& r) const\r
+  {\r
+    return m_holder == r.m_holder;\r
+  }\r
+\r
+  template <typename T, typename C>\r
+  unsigned smart_ptr_base<T,C>::alias_count(void) const\r
+  {\r
+    return m_holder->count();\r
+  }\r
+\r
+  template <typename T, typename C>\r
+  void smart_ptr_base<T,C>::clear(void)\r
+  {\r
+    m_holder->clear();\r
+  }\r
+\r
+  template <typename T, typename C>\r
+  void smart_ptr_base<T,C>::clear_unique(void)\r
+  {\r
+    if (m_holder->count() == 1)\r
+      m_holder->clear();\r
+    else\r
+    {\r
+      m_holder->decrement();\r
+      m_holder = 0;\r
+      m_holder = new smart_ptr_holder<T>;\r
+    }\r
+  }\r
+\r
+  template <typename T, typename C>\r
+  void smart_ptr_base<T,C>::make_unique(void) throw(illegal_copy)\r
+  {\r
+    if (m_holder->count() > 1)\r
+    {\r
+      smart_ptr_holder<T>* old_holder = m_holder;\r
+      m_holder->decrement();\r
+      m_holder = 0;\r
+      m_holder = new smart_ptr_holder<T>;\r
+      if (old_holder->pointer())\r
+        m_holder->set(C()(old_holder->value()));\r
+    }\r
+  }\r
+\r
+  template <typename T, typename C>\r
+  void smart_ptr_base<T,C>::copy(const smart_ptr_base<T,C>& data) throw(illegal_copy)\r
+  {\r
+    alias(data);\r
+    make_unique();\r
+  }\r
+\r
+  // internal function for distinguishing unique smart_ptr objects\r
+  // used for example in persistence routines\r
+\r
+  template <typename T, typename C>\r
+  smart_ptr_holder<T>* smart_ptr_base<T,C>::_handle(void) const\r
+  {\r
+    return m_holder;\r
+  }\r
+\r
+  template <typename T, typename C>\r
+  void smart_ptr_base<T,C>::_make_alias(smart_ptr_holder<T>* r_holder)\r
+  {\r
+    // make it alias-copy safe - this means that I don't try to do the\r
+    // assignment if r is either the same object or an alias of it\r
+    if (m_holder != r_holder)\r
+    {\r
+      if (m_holder->decrement())\r
+        delete m_holder;\r
+      m_holder = r_holder;\r
+      m_holder->increment();\r
+    }\r
+  }\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+\r
+} // end namespace stlplus\r
+\r
This page took 0.043911 seconds and 4 git commands to generate.