summaryrefslogtreecommitdiff
path: root/src/inc/releaseholder.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/inc/releaseholder.h')
-rw-r--r--src/inc/releaseholder.h77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/inc/releaseholder.h b/src/inc/releaseholder.h
new file mode 100644
index 0000000000..b2c42e3928
--- /dev/null
+++ b/src/inc/releaseholder.h
@@ -0,0 +1,77 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+// This class acts a smart pointer which calls the Release method on any object
+// you place in it when the ReleaseHolder class falls out of scope. You may use it
+// just like you would a standard pointer to a COM object (including if (foo),
+// if (!foo), if (foo == 0), etc) except for two caveats:
+// 1. This class never calls AddRef and it always calls Release when it
+// goes out of scope.
+// 2. You should never use & to try to get a pointer to a pointer unless
+// you call Release first, or you will leak whatever this object contains
+// prior to updating its internal pointer.
+template<class T>
+class ReleaseHolder
+{
+public:
+ ReleaseHolder()
+ : m_ptr(NULL)
+ {}
+
+ ReleaseHolder(T* ptr)
+ : m_ptr(ptr)
+ {}
+
+ ~ReleaseHolder()
+ {
+ Release();
+ }
+
+ void operator=(T *ptr)
+ {
+ Release();
+
+ m_ptr = ptr;
+ }
+
+ T* operator->()
+ {
+ return m_ptr;
+ }
+
+ operator T*()
+ {
+ return m_ptr;
+ }
+
+ T** operator&()
+ {
+ return &m_ptr;
+ }
+
+ T* GetPtr() const
+ {
+ return m_ptr;
+ }
+
+ T* Detach()
+ {
+ T* pT = m_ptr;
+ m_ptr = NULL;
+ return pT;
+ }
+
+ void Release()
+ {
+ if (m_ptr != NULL)
+ {
+ m_ptr->Release();
+ m_ptr = NULL;
+ }
+ }
+
+private:
+ T* m_ptr;
+};
+