aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/ptr.h18
-rw-r--r--test/common/ptr.h23
2 files changed, 32 insertions, 9 deletions
diff --git a/common/ptr.h b/common/ptr.h
index 30a61a2f5b..a4aa6d0707 100644
--- a/common/ptr.h
+++ b/common/ptr.h
@@ -51,6 +51,16 @@ private:
T *_ptr;
};
+template<class T, class D>
+class SharedPtrDeletionDeleterImpl : public SharedPtrDeletionInternal {
+public:
+ SharedPtrDeletionDeleterImpl(T *ptr, D d) : _ptr(ptr), _deleter(d) {}
+ ~SharedPtrDeletionDeleterImpl() { _deleter(_ptr); }
+private:
+ T *_ptr;
+ D _deleter;
+};
+
/**
* A simple shared pointer implementation modelled after boost.
*
@@ -72,10 +82,9 @@ private:
* ->, which does the same as the -> operator on a normal pointer.
*
* Be sure you are using new to initialize the pointer you want to manage.
- * Pointers pointing to memory not allocated by new, will cause undefined
- * behavior on deletion. That is for example the case on pointers created
- * with malloc (or similar) and new[]. This prevents the use of SharedPtr
- * for arrays!
+ * If you do not use new for allocating, you have to supply a deleter as
+ * second parameter when creating a SharedPtr object. The deleter has to
+ * implement operator() which takes the pointer it should free as argument.
*
* Note that you have to specify the type itself not the pointer type as
* template parameter.
@@ -105,6 +114,7 @@ public:
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) {}
+ template<class T2, class D> SharedPtr(T2 *p, D d) : _refCount(new RefValue(1)), _deletion(new SharedPtrDeletionDeleterImpl<T2, D>(p, d)), _pointer(p) {}
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); }
diff --git a/test/common/ptr.h b/test/common/ptr.h
index 7102a819cf..b7ed637040 100644
--- a/test/common/ptr.h
+++ b/test/common/ptr.h
@@ -34,6 +34,24 @@ class PtrTestSuite : public CxxTest::TestSuite
TS_ASSERT(p1.unique());
}
+ template<class T>
+ struct Deleter {
+ bool *test;
+ void operator()(T *ptr) { *test = true; delete ptr; }
+ };
+
+ void test_deleter() {
+ Deleter<int> myDeleter;
+ myDeleter.test = new bool(false);
+
+ {
+ Common::SharedPtr<int> p(new int(1), myDeleter);
+ }
+
+ TS_ASSERT_EQUALS(*myDeleter.test, true);
+ delete myDeleter.test;
+ }
+
void test_compare() {
Common::SharedPtr<int> p1(new int(1));
Common::SharedPtr<int> p2;
@@ -43,10 +61,5 @@ class PtrTestSuite : public CxxTest::TestSuite
TS_ASSERT(p1 != 0);
TS_ASSERT(p2 == 0);
-
- // Note: The following two currently do *not* work, contrary to
- // what the Doxygen comments of SharedPtr claim.
- TS_ASSERT(p1 != (int *)0);
- TS_ASSERT(p2 == (int *)0);
}
};