// 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
+// 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
////////////////////////////////////////////////////////////////////////////////\r
#include "containers_fixes.hpp"\r
#include "exceptions.hpp"\r
+#include "copy_functors.hpp"\r
#include <map>\r
#include <string>\r
\r
smart_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
+ // 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 smart_ptr_base(const T& data) throw(illegal_copy);\r
\r
explicit smart_ptr_base(T* data);\r
\r
// copy constructor implements aliasing so no copy is made\r
- explicit smart_ptr_base(const smart_ptr_base<T,C>& r);\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
+ smart_ptr_base(const smart_ptr_base<T,C>& r);\r
+\r
+ // assignment operator - required, else the output of GCC suffers segmentation faults\r
+ smart_ptr_base<T,C>& operator=(const smart_ptr_base<T,C>& r);\r
\r
// destructor decrements the reference count and delete only when the last reference is destroyed\r
~smart_ptr_base(void);\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
- void* handle(void) const;\r
- void make_alias(void* handle);\r
- };\r
-\r
- ////////////////////////////////////////////////////////////////////////////////\r
- // copy functors implementing the three possible copy semantics\r
-\r
- // constructor_copy uses the copy constructor of the object - used for simple types\r
-\r
- template <typename T>\r
- class constructor_copy\r
- {\r
- public:\r
- T* operator() (const T& from) throw()\r
- {\r
- return new T(from);\r
- }\r
- };\r
-\r
- // clone_copy uses the clone method of the object - used for polymorphic types\r
-\r
- template <typename T>\r
- class clone_copy\r
- {\r
- public:\r
- T* operator() (const T& from) throw()\r
- {\r
- return from.clone();\r
- }\r
- };\r
-\r
- // no_copy throws an exception - used for types that cannot be copied\r
-\r
- template <typename T>\r
- class no_copy\r
- {\r
- public:\r
- T* operator() (const T& from) throw(illegal_copy)\r
- {\r
- throw illegal_copy("no_copy functor called");\r
- return 0;\r
- }\r
+ smart_ptr_holder<T>* _handle(void) const;\r
+ void _make_alias(smart_ptr_holder<T>* handle);\r
};\r
\r
////////////////////////////////////////////////////////////////////////////////\r
explicit smart_ptr(const T& data) : smart_ptr_base<T, constructor_copy<T> >(data) {}\r
explicit smart_ptr(T* data) : smart_ptr_base<T, constructor_copy<T> >(data) {}\r
smart_ptr<T>& operator=(const T& data) {set_value(data); return *this;}\r
- smart_ptr<T>& operator=(const smart_ptr<T>& r) {alias(r); return *this;}\r
+ smart_ptr<T>& operator=(T* data) {set(data); return *this;}\r
~smart_ptr(void) {}\r
};\r
\r
explicit smart_ptr_clone(const T& data) : smart_ptr_base<T, clone_copy<T> >(data) {}\r
explicit smart_ptr_clone(T* data) : smart_ptr_base<T, clone_copy<T> >(data) {}\r
smart_ptr_clone<T>& operator=(const T& data) {set_value(data); return *this;}\r
- smart_ptr_clone<T>& operator=(const smart_ptr_clone<T>& r) {alias(r); return *this;}\r
+ smart_ptr_clone<T>& operator=(T* data) {set(data); return *this;}\r
~smart_ptr_clone(void) {}\r
};\r
\r
explicit smart_ptr_nocopy(const T& data) : smart_ptr_base<T, no_copy<T> >(data) {}\r
explicit smart_ptr_nocopy(T* data) : smart_ptr_base<T, no_copy<T> >(data) {}\r
smart_ptr_nocopy<T>& operator=(const T& data) {set_value(data); return *this;}\r
- smart_ptr_nocopy<T>& operator=(const smart_ptr_nocopy<T>& r) {alias(r); return *this;}\r
+ smart_ptr_nocopy<T>& operator=(T* data) {set(data); return *this;}\r
~smart_ptr_nocopy(void) {}\r
};\r
\r