[Scummvm-cvs-logs] SF.net SVN: scummvm: [31301] scummvm/trunk/common/ptr.h

lordhoto at users.sourceforge.net lordhoto at users.sourceforge.net
Sat Mar 29 21:14:33 CET 2008


Revision: 31301
          http://scummvm.svn.sourceforge.net/scummvm/?rev=31301&view=rev
Author:   lordhoto
Date:     2008-03-29 13:14:32 -0700 (Sat, 29 Mar 2008)

Log Message:
-----------
- allow SharedPtr objects with incomplete type
- updated documentation accordingly
- clarified documentation about comparison operators of SharedPtr

Modified Paths:
--------------
    scummvm/trunk/common/ptr.h

Modified: scummvm/trunk/common/ptr.h
===================================================================
--- scummvm/trunk/common/ptr.h	2008-03-29 13:27:25 UTC (rev 31300)
+++ scummvm/trunk/common/ptr.h	2008-03-29 20:14:32 UTC (rev 31301)
@@ -29,6 +29,28 @@
 
 namespace Common {
 
+class SharedPtrDeletionInternal {
+public:
+	virtual ~SharedPtrDeletionInternal() {}
+};
+
+template<class T>
+class SharedPtrDeletionImpl : public SharedPtrDeletionInternal {
+public:
+	SharedPtrDeletionImpl(T *ptr) : _ptr(ptr) {}
+	~SharedPtrDeletionImpl() {
+		// Checks if the supplied type is not just a plain
+		// forward definition, taken from boost::checked_delete
+		// This makes the user really aware what he tries to do
+		// when using this with an incomplete type.
+		typedef char completeCheck[sizeof(T) ? 1 : -1];
+		(void)sizeof(completeCheck);
+		delete _ptr;
+	}
+private:
+	T *_ptr;
+};
+
 /**
  * A simple shared pointer implementation modelled after boost.
  *
@@ -56,16 +78,20 @@
  * for arrays!
  *
  * Note that you have to specify the type itself not the pointer type as
- * template parameter. You also need to have a real definition of the type
- * you want to use, a simple forward definition is not enough.
+ * template parameter.
  *
+ * When creating a SharedPtr object from a normal pointer you need a real
+ * definition of the type you want SharedPtr to manage, a simple forward
+ * definition is not enough.
+ *
  * The class has implicit upcast support, so if you got a class B derived
  * from class A, you can assign a pointer to B without any problems to a
  * SharedPtr object with template parameter A. The very same applies to 
  * assignment of a SharedPtr<B> object to a SharedPtr<A> object.
  *
  * There are also operators != and == to compare two SharedPtr objects
- * with compatible pointers.
+ * with compatible pointers. Comparision between a SharedPtr object and
+ * a plain pointer is just possible via SharedPtr::get.
  */
 template<class T>
 class SharedPtr {
@@ -74,11 +100,11 @@
 	typedef T ValueType;
 	typedef T *Pointer;
 
-	SharedPtr() : _refCount(0), _pointer(0) {}
-	template<class T2> explicit SharedPtr(T2 *p) : _refCount(new RefValue(1)), _pointer(p) {}
+	SharedPtr() : _refCount(0), _deletion(0), _pointer(0) {}
+	template<class T2> explicit SharedPtr(T2 *p) : _refCount(new RefValue(1)), _deletion(new SharedPtrDeletionImpl<T2>(p)), _pointer(p) {}
 
-	SharedPtr(const SharedPtr &r) : _refCount(r._refCount), _pointer(r._pointer) { if (_refCount) ++(*_refCount); }
-	template<class T2> SharedPtr(const SharedPtr<T2> &r) : _refCount(r._refCount), _pointer(r._pointer) { if (_refCount) ++(*_refCount); }
+	SharedPtr(const SharedPtr &r) : _refCount(r._refCount), _deletion(r._deletion), _pointer(r._pointer) { if (_refCount) ++(*_refCount); }
+	template<class T2> SharedPtr(const SharedPtr<T2> &r) : _refCount(r._refCount), _deletion(r._deletion), _pointer(r._pointer) { if (_refCount) ++(*_refCount); }
 
 	~SharedPtr() { decRef(); }
 
@@ -88,6 +114,7 @@
 		decRef();
 
 		_refCount = r._refCount;
+		_deletion = r._deletion;
 		_pointer = r._pointer;
 
 		return *this;
@@ -100,6 +127,7 @@
 		decRef();
 
 		_refCount = r._refCount;
+		_deletion = r._deletion;
 		_pointer = r._pointer;
 
 		return *this;
@@ -140,7 +168,8 @@
 			--(*_refCount);
 			if (!*_refCount) {
 				delete _refCount;
-				delete _pointer;
+				delete _deletion;
+				_deletion = 0;
 				_refCount = 0;
 				_pointer = 0;
 			}
@@ -148,6 +177,7 @@
 	}
 
 	RefValue *_refCount;
+	SharedPtrDeletionInternal *_deletion;
 	T *_pointer;
 };
 
@@ -166,3 +196,4 @@
 
 #endif
 
+


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list