-////////////////////////////////////////////////////////////////////////////////
-
-// Author: Daniel Milton
-// Copyright: (c) Daniel Milton 2002-2009
-
-////////////////////////////////////////////////////////////////////////////////
-
-namespace stlplus
-{
-
- ////////////////////////////////////////////////////////////////////////////////
- // simple_ptr_base class
- ////////////////////////////////////////////////////////////////////////////////
-
- ////////////////////////////////////////////////////////////////////////////////
- // constructors, assignments and destructors
-
- // create a null pointer
- template <typename T, typename C>
- simple_ptr_base<T,C>::simple_ptr_base(void) :
- m_pointer(0),
- m_count(new unsigned(1))
- {
- }
-
- // create a pointer containing a *copy* of the object pointer
- template <typename T, typename C>
- simple_ptr_base<T,C>::simple_ptr_base(const T& data) throw(illegal_copy) :
- m_pointer(C()(data)),
- m_count(new unsigned(1))
- {
- }
-
- // 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 simple_ptr<type> x(new type(args))
- template <typename T, typename C>
- simple_ptr_base<T,C>::simple_ptr_base(T* data) :
- m_pointer(data),
- m_count(new unsigned(1))
- {
- }
-
- // copy constructor implements counted referencing - no copy is made
- template <typename T, typename C>
- simple_ptr_base<T,C>::simple_ptr_base(const simple_ptr_base<T,C>& r) :
- m_pointer(r.m_pointer),
- m_count(r.m_count)
- {
- increment();
- }
-
- // assignment operator - required, else the output of GCC suffers segmentation faults
- template <typename T, typename C>
- simple_ptr_base<T,C>& simple_ptr_base<T,C>::operator=(const simple_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>
- simple_ptr_base<T,C>::~simple_ptr_base(void)
- {
- if(decrement())
- {
- delete m_pointer;
- delete m_count;
- }
- }
-
- //////////////////////////////////////////////////////////////////////////////
- // logical tests to see if there is anything contained in the pointer since it can be null
-
- template <typename T, typename C>
- bool simple_ptr_base<T,C>::null(void) const
- {
- return m_pointer==0;
- }
-
- template <typename T, typename C>
- bool simple_ptr_base<T,C>::present(void) const
- {
- return m_pointer!=0;
- }
-
- template <typename T, typename C>
- bool simple_ptr_base<T,C>::operator!(void) const
- {
- return m_pointer==0;
- }
-
- template <typename T, typename C>
- simple_ptr_base<T,C>::operator bool(void) const
- {
- return m_pointer!=0;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- // dereference operators and functions
-
- template <typename T, typename C>
- T& simple_ptr_base<T,C>::operator*(void) throw(null_dereference)
- {
- if (!m_pointer) throw null_dereference("null pointer dereferenced in simple_ptr::operator*");
- return *m_pointer;
- }
-
- template <typename T, typename C>
- const T& simple_ptr_base<T,C>::operator*(void) const throw(null_dereference)
- {
- if (!m_pointer) throw null_dereference("null pointer dereferenced in simple_ptr::operator*");
- return *m_pointer;
- }
-
- template <typename T, typename C>
- T* simple_ptr_base<T,C>::operator->(void) throw(null_dereference)
- {
- if (!m_pointer) throw null_dereference("null pointer dereferenced in simple_ptr::operator->");
- return m_pointer;
- }
-
- template <typename T, typename C>
- const T* simple_ptr_base<T,C>::operator->(void) const throw(null_dereference)
- {
- if (!m_pointer) throw null_dereference("null pointer dereferenced in simple_ptr::operator->");
- return m_pointer;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- // explicit function forms of the above assignment dereference operators
-
- template <typename T, typename C>
- void simple_ptr_base<T,C>::set_value(const T& data) throw(illegal_copy)
- {
- set(C()(data));
- }
-
- template <typename T, typename C>
- T& simple_ptr_base<T,C>::value(void) throw(null_dereference)
- {
- if (!m_pointer) throw null_dereference("null pointer dereferenced in simple_ptr::value");
- return *m_pointer;
- }
-
- template <typename T, typename C>
- const T& simple_ptr_base<T,C>::value(void) const throw(null_dereference)
- {
- if (!m_pointer) throw null_dereference("null pointer dereferenced in simple_ptr::value");
- return *m_pointer;
- }
-
- template <typename T, typename C>
- void simple_ptr_base<T,C>::set(T* data)
- {
- unsigned& count = *m_count;
- if (count<=1)
- delete m_pointer;
- else
- {
- --count;
- m_count = new unsigned(1);
- }
- m_pointer = data;
- }
-
- template <typename T, typename C>
- T* simple_ptr_base<T,C>::pointer(void)
- {
- return m_pointer;
- }
-
- template <typename T, typename C>
- const T* simple_ptr_base<T,C>::pointer(void) const
- {
- return m_pointer;
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // functions to manage counted referencing
-
- template <typename T, typename C>
- void simple_ptr_base<T,C>::increment(void)
- {
- ++(*m_count);
- }
-
- template <typename T, typename C>
- bool simple_ptr_base<T,C>::decrement(void)
- {
- unsigned& count = *m_count;
- --count;
- return count == 0;
- }
-
- // make this an alias of the passed object
- template <typename T, typename C>
- void simple_ptr_base<T,C>::alias(const simple_ptr_base<T,C>& r)
- {
- // 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_pointer==r.m_pointer) return;
- if(decrement()) {
- delete m_pointer;
- delete m_count;
- }
- m_pointer = r.m_pointer;
- m_count = r.m_count;
- increment();
- }
-
- template <typename T, typename C>
- bool simple_ptr_base<T,C>::aliases(const simple_ptr_base<T,C>& r) const
- {
- return m_count == r.m_count;
- }
-
- template <typename T, typename C>
- unsigned simple_ptr_base<T,C>::alias_count(void) const
- {
- return *m_count;
- }
-
- template <typename T, typename C>
- void simple_ptr_base<T,C>::clear(void)
- {
- set(0);
- }
-
- template <typename T, typename C>
- void simple_ptr_base<T,C>::clear_unique(void)
- {
- set(0); // no difference between clear and clear_unique with the simple_ptr
- }
-
- template <typename T, typename C>
- void simple_ptr_base<T,C>::make_unique(void) throw(illegal_copy)
- {
- unsigned& count = *m_count;
- if (count <= 1) return;
- --count;
- if (m_pointer) m_pointer = C()(*m_pointer);
- m_count = new unsigned(1);
- }
-
- template <typename T, typename C>
- void simple_ptr_base<T,C>::copy(const simple_ptr_base<T,C>& data) throw(illegal_copy)
- {
- alias(data);
- make_unique();
- }
-
-#ifdef STLPLUS_MEMBER_TEMPLATES
-
- // dynamic cast of underlying pointer to a derived/parent
- template <typename T, typename C>
- template <typename T2>
- simple_ptr_base<T2,C> simple_ptr_base<T,C>::dyn_cast(void) const
- {
- simple_ptr_base<T2,C> rtn;
- rtn.m_pointer = dynamic_cast<T2*>(m_pointer);
- if (rtn.m_pointer) {
- delete rtn.m_count;
- rtn.m_count = m_count;
- rtn.increment();
- }
- return rtn;
- }
-
- // static cast of underlying pointer to a derived/parent
- template <typename T, typename C>
- template <typename T2>
- simple_ptr_base<T2,C> simple_ptr_base<T,C>::stat_cast(void) const
- {
- simple_ptr_base<T2,C> rtn;
- rtn.m_pointer = static_cast<T2*>(m_pointer);
- if (rtn.m_pointer) {
- delete rtn.m_count;
- rtn.m_count = m_count;
- rtn.increment();
- }
- return rtn;
- }
-
- // cast of underlying pointer to a base - while keeping the same ref-counted object
- template <typename T, typename C>
- template <typename T2>
- simple_ptr_base<T2,C> simple_ptr_base<T,C>::cast(void) const
- {
- simple_ptr_base<T2,C> rtn;
- rtn.m_pointer = (T2*)m_pointer;
- if (rtn.m_pointer) {
- delete rtn.m_count;
- rtn.m_count = m_count;
- rtn.increment();
- }
- return rtn;
- }
-
-#endif
-
- // internal function for distinguishing unique simple_ptr objects
- // used for example in persistence routines
-
- template <typename T, typename C>
- unsigned* simple_ptr_base<T,C>::_count(void) const
- {
- return m_count;
- }
-
- template <typename T, typename C>
- T* simple_ptr_base<T,C>::_pointer(void) const
- {
- return m_pointer;
- }
-
- template <typename T, typename C>
- void simple_ptr_base<T,C>::_make_alias(T* pointer, unsigned* count)
- {
- // 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_count != count)
- {
- if(decrement())
- {
- delete m_pointer;
- delete m_count;
- }
- m_pointer = pointer;
- m_count = count;
- increment();
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////
-
-} // end namespace stlplus
-
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+// Author: Daniel Milton\r
+// Copyright: (c) Daniel Milton 2002 onwards\r
+\r
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+namespace stlplus\r
+{\r
+\r
+ ////////////////////////////////////////////////////////////////////////////////\r
+ // simple_ptr_base class\r
+ ////////////////////////////////////////////////////////////////////////////////\r
+\r
+ ////////////////////////////////////////////////////////////////////////////////\r
+ // constructors, assignments and destructors\r
+\r
+ // create a null pointer\r
+ template <typename T, typename C>\r
+ simple_ptr_base<T,C>::simple_ptr_base(void) :\r
+ m_pointer(0),\r
+ m_count(new unsigned(1))\r
+ {\r
+ }\r
+\r
+ // create a pointer containing a *copy* of the object pointer\r
+ template <typename T, typename C>\r
+ simple_ptr_base<T,C>::simple_ptr_base(const T& data) throw(illegal_copy) :\r
+ m_pointer(C()(data)),\r
+ m_count(new unsigned(1))\r
+ {\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 simple_ptr<type> x(new type(args))\r
+ template <typename T, typename C>\r
+ simple_ptr_base<T,C>::simple_ptr_base(T* data) :\r
+ m_pointer(data),\r
+ m_count(new unsigned(1))\r
+ {\r
+ }\r
+\r
+ // copy constructor implements counted referencing - no copy is made\r
+ template <typename T, typename C>\r
+ simple_ptr_base<T,C>::simple_ptr_base(const simple_ptr_base<T,C>& r) :\r
+ m_pointer(r.m_pointer),\r
+ m_count(r.m_count)\r
+ {\r
+ increment();\r
+ }\r
+\r
+ // assignment operator - required, else the output of GCC suffers segmentation faults\r
+ template <typename T, typename C>\r
+ simple_ptr_base<T,C>& simple_ptr_base<T,C>::operator=(const simple_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
+ simple_ptr_base<T,C>::~simple_ptr_base(void)\r
+ {\r
+ if(decrement()) \r
+ {\r
+ delete m_pointer;\r
+ delete m_count;\r
+ }\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 simple_ptr_base<T,C>::null(void) const\r
+ {\r
+ return m_pointer==0;\r
+ }\r
+\r
+ template <typename T, typename C>\r
+ bool simple_ptr_base<T,C>::present(void) const\r
+ {\r
+ return m_pointer!=0;\r
+ }\r
+\r
+ template <typename T, typename C>\r
+ bool simple_ptr_base<T,C>::operator!(void) const\r
+ {\r
+ return m_pointer==0;\r
+ }\r
+\r
+ template <typename T, typename C>\r
+ simple_ptr_base<T,C>::operator bool(void) const\r
+ {\r
+ return m_pointer!=0;\r
+ }\r
+\r
+ //////////////////////////////////////////////////////////////////////////////\r
+ // dereference operators and functions\r
+\r
+ template <typename T, typename C>\r
+ T& simple_ptr_base<T,C>::operator*(void) throw(null_dereference)\r
+ {\r
+ if (!m_pointer) throw null_dereference("null pointer dereferenced in simple_ptr::operator*");\r
+ return *m_pointer;\r
+ }\r
+\r
+ template <typename T, typename C>\r
+ const T& simple_ptr_base<T,C>::operator*(void) const throw(null_dereference)\r
+ {\r
+ if (!m_pointer) throw null_dereference("null pointer dereferenced in simple_ptr::operator*");\r
+ return *m_pointer;\r
+ }\r
+\r
+ template <typename T, typename C>\r
+ T* simple_ptr_base<T,C>::operator->(void) throw(null_dereference)\r
+ {\r
+ if (!m_pointer) throw null_dereference("null pointer dereferenced in simple_ptr::operator->");\r
+ return m_pointer;\r
+ }\r
+\r
+ template <typename T, typename C>\r
+ const T* simple_ptr_base<T,C>::operator->(void) const throw(null_dereference)\r
+ {\r
+ if (!m_pointer) throw null_dereference("null pointer dereferenced in simple_ptr::operator->");\r
+ return m_pointer;\r
+ }\r
+\r
+ //////////////////////////////////////////////////////////////////////////////\r
+ // explicit function forms of the above assignment dereference operators\r
+\r
+ template <typename T, typename C>\r
+ void simple_ptr_base<T,C>::set_value(const T& data) throw(illegal_copy)\r
+ {\r
+ set(C()(data));\r
+ }\r
+\r
+ template <typename T, typename C>\r
+ T& simple_ptr_base<T,C>::value(void) throw(null_dereference)\r
+ {\r
+ if (!m_pointer) throw null_dereference("null pointer dereferenced in simple_ptr::value");\r
+ return *m_pointer;\r
+ }\r
+\r
+ template <typename T, typename C>\r
+ const T& simple_ptr_base<T,C>::value(void) const throw(null_dereference)\r
+ {\r
+ if (!m_pointer) throw null_dereference("null pointer dereferenced in simple_ptr::value");\r
+ return *m_pointer;\r
+ }\r
+\r
+ template <typename T, typename C>\r
+ void simple_ptr_base<T,C>::set(T* data)\r
+ {\r
+ unsigned& count = *m_count;\r
+ if (count<=1)\r
+ delete m_pointer;\r
+ else\r
+ {\r
+ --count;\r
+ m_count = new unsigned(1);\r
+ }\r
+ m_pointer = data;\r
+ }\r
+\r
+ template <typename T, typename C>\r
+ T* simple_ptr_base<T,C>::pointer(void)\r
+ {\r
+ return m_pointer;\r
+ }\r
+\r
+ template <typename T, typename C>\r
+ const T* simple_ptr_base<T,C>::pointer(void) const\r
+ {\r
+ return m_pointer;\r
+ }\r
+\r
+ ////////////////////////////////////////////////////////////////////////////////\r
+ // functions to manage counted referencing\r
+\r
+ template <typename T, typename C>\r
+ void simple_ptr_base<T,C>::increment(void)\r
+ {\r
+ ++(*m_count);\r
+ }\r
+\r
+ template <typename T, typename C>\r
+ bool simple_ptr_base<T,C>::decrement(void)\r
+ {\r
+ unsigned& count = *m_count;\r
+ --count;\r
+ return count == 0;\r
+ }\r
+\r
+ // make this an alias of the passed object\r
+ template <typename T, typename C>\r
+ void simple_ptr_base<T,C>::alias(const simple_ptr_base<T,C>& r)\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_pointer==r.m_pointer) return;\r
+ if(decrement()) {\r
+ delete m_pointer;\r
+ delete m_count;\r
+ }\r
+ m_pointer = r.m_pointer;\r
+ m_count = r.m_count;\r
+ increment();\r
+ }\r
+\r
+ template <typename T, typename C>\r
+ bool simple_ptr_base<T,C>::aliases(const simple_ptr_base<T,C>& r) const\r
+ {\r
+ return m_count == r.m_count;\r
+ }\r
+\r
+ template <typename T, typename C>\r
+ unsigned simple_ptr_base<T,C>::alias_count(void) const\r
+ {\r
+ return *m_count;\r
+ }\r
+\r
+ template <typename T, typename C>\r
+ void simple_ptr_base<T,C>::clear(void)\r
+ {\r
+ set(0);\r
+ }\r
+\r
+ template <typename T, typename C>\r
+ void simple_ptr_base<T,C>::clear_unique(void)\r
+ {\r
+ set(0); // no difference between clear and clear_unique with the simple_ptr\r
+ }\r
+\r
+ template <typename T, typename C>\r
+ void simple_ptr_base<T,C>::make_unique(void) throw(illegal_copy)\r
+ {\r
+ unsigned& count = *m_count;\r
+ if (count <= 1) return;\r
+ --count;\r
+ if (m_pointer) m_pointer = C()(*m_pointer);\r
+ m_count = new unsigned(1);\r
+ }\r
+\r
+ template <typename T, typename C>\r
+ void simple_ptr_base<T,C>::copy(const simple_ptr_base<T,C>& data) throw(illegal_copy)\r
+ {\r
+ alias(data);\r
+ make_unique();\r
+ }\r
+\r
+ // internal function for distinguishing unique simple_ptr objects\r
+ // used for example in persistence routines\r
+\r
+ template <typename T, typename C>\r
+ unsigned* simple_ptr_base<T,C>::_count(void) const\r
+ {\r
+ return m_count;\r
+ }\r
+\r
+ template <typename T, typename C>\r
+ T* simple_ptr_base<T,C>::_pointer(void) const\r
+ {\r
+ return m_pointer;\r
+ }\r
+\r
+ template <typename T, typename C>\r
+ void simple_ptr_base<T,C>::_make_alias(T* pointer, unsigned* count)\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_count != count)\r
+ {\r
+ if(decrement())\r
+ {\r
+ delete m_pointer;\r
+ delete m_count;\r
+ }\r
+ m_pointer = pointer;\r
+ m_count = count;\r
+ increment();\r
+ }\r
+ }\r
+\r
+\r
+ ////////////////////////////////////////////////////////////////////////////////\r
+ // simple_ptr class\r
+ ////////////////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef STLPLUS_MEMBER_TEMPLATES\r
+\r
+ template <typename T>\r
+ template <typename T2>\r
+ simple_ptr<T2> simple_ptr<T>::dyn_cast(void) const {\r
+ simple_ptr<T2> rtn;\r
+ T2* p = dynamic_cast<T2*>(this->m_pointer);\r
+ if (p) rtn._make_alias(p, this->m_count);\r
+ return rtn;\r
+ }\r
+\r
+ template <typename T>\r
+ template <typename T2>\r
+ simple_ptr<T2> simple_ptr<T>::stat_cast(void) const {\r
+ simple_ptr<T2> rtn;\r
+ T2* p = static_cast<T2*>(this->m_pointer);\r
+ if (p) rtn._make_alias(p, this->m_count);\r
+ return rtn;\r
+ }\r
+\r
+ template <typename T>\r
+ template <typename T2>\r
+ simple_ptr<T2> simple_ptr<T>::cast(void) const {\r
+ simple_ptr<T2> rtn;\r
+ T2* p = (T2*)this->m_pointer;\r
+ if (p) rtn._make_alias(p, this->m_count);\r
+ return rtn;\r
+ }\r
+\r
+#endif\r
+\r
+ ////////////////////////////////////////////////////////////////////////////////\r
+ // simple_ptr_clone class\r
+ ////////////////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef STLPLUS_MEMBER_TEMPLATES\r
+\r
+ template <typename T>\r
+ template <typename T2>\r
+ simple_ptr_clone<T2> simple_ptr_clone<T>::dyn_cast(void) const {\r
+ simple_ptr_clone<T2> rtn;\r
+ T2* p = dynamic_cast<T2*>(this->m_pointer);\r
+ if (p) rtn._make_alias(p, this->m_count);\r
+ return rtn;\r
+ }\r
+\r
+ template <typename T>\r
+ template <typename T2>\r
+ simple_ptr_clone<T2> simple_ptr_clone<T>::stat_cast(void) const {\r
+ simple_ptr_clone<T2> rtn;\r
+ T2* p = static_cast<T2*>(this->m_pointer);\r
+ if (p) rtn._make_alias(p, this->m_count);\r
+ return rtn;\r
+ }\r
+\r
+ template <typename T>\r
+ template <typename T2>\r
+ simple_ptr_clone<T2> simple_ptr_clone<T>::cast(void) const {\r
+ simple_ptr_clone<T2> rtn;\r
+ T2* p = (T2*)this->m_pointer;\r
+ if (p) rtn._make_alias(p, this->m_count);\r
+ return rtn;\r
+ }\r
+\r
+#endif\r
+\r
+ ////////////////////////////////////////////////////////////////////////////////\r
+ // simple_ptr_nocopy class\r
+ ////////////////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef STLPLUS_MEMBER_TEMPLATES\r
+\r
+ template <typename T>\r
+ template <typename T2>\r
+ simple_ptr_nocopy<T2> simple_ptr_nocopy<T>::dyn_cast(void) const {\r
+ simple_ptr_nocopy<T2> rtn;\r
+ T2* p = dynamic_cast<T2*>(this->m_pointer);\r
+ if (p) rtn._make_alias(p, this->m_count);\r
+ return rtn;\r
+ }\r
+\r
+ template <typename T>\r
+ template <typename T2>\r
+ simple_ptr_nocopy<T2> simple_ptr_nocopy<T>::stat_cast(void) const {\r
+ simple_ptr_nocopy<T2> rtn;\r
+ T2* p = static_cast<T2*>(this->m_pointer);\r
+ if (p) rtn._make_alias(p, this->m_count);\r
+ return rtn;\r
+ }\r
+\r
+ template <typename T>\r
+ template <typename T2>\r
+ simple_ptr_nocopy<T2> simple_ptr_nocopy<T>::cast(void) const {\r
+ simple_ptr_nocopy<T2> rtn;\r
+ T2* p = (T2*)this->m_pointer;\r
+ if (p) rtn._make_alias(p, this->m_count);\r
+ return rtn;\r
+ }\r
+\r
+#endif\r
+\r
+ ////////////////////////////////////////////////////////////////////////////////\r
+\r
+} // end namespace stlplus\r
+\r