[ATL]
[reactos.git] / reactos / lib / atl / atlbase.h
index 02ceb81..bc9e9e1 100644 (file)
@@ -836,6 +836,94 @@ public:
     }
 };
 
+
+// TODO: When someone needs it, make the allocator a template, so you can use it for both
+//       CoTask* allocations, and CRT-like allocations (malloc, realloc, free)
+template<class T>
+class CComHeapPtr
+{
+public:
+    CComHeapPtr() :
+        m_Data(NULL)
+    {
+    }
+
+    explicit CComHeapPtr(T *lp) :
+        m_Data(lp)
+    {
+    }
+
+    explicit CComHeapPtr(CComHeapPtr<T> &lp)
+    {
+        m_Data = lp.Detach();
+    }
+
+    ~CComHeapPtr()
+    {
+        Release();
+    }
+
+    T *operator = (CComHeapPtr<T> &lp)
+    {
+        if (lp.m_Data != m_Data)
+            Attach(lp.Detach());
+        return *this;
+    }
+
+    bool Allocate(size_t nElements = 1)
+    {
+        ATLASSERT(m_Data == NULL);
+        m_Data = static_cast<T*>(::CoTaskMemAlloc(nElements * sizeof(T)));
+        return m_Data != NULL;
+    }
+
+    bool Reallocate(_In_ size_t nElements)
+    {
+        T* newData = static_cast<T*>(::CoTaskMemRealloc(m_Data, nElements * sizeof(T)));
+        if (newData == NULL)
+            return false;
+        m_Data = newData;
+        return true;
+    }
+
+    void Release()
+    {
+        if (m_Data)
+        {
+            ::CoTaskMemFree(m_Data);
+            m_Data = NULL;
+        }
+    }
+
+    void Attach(T *lp)
+    {
+        Release();
+        m_Data = lp;
+    }
+
+    T *Detach()
+    {
+        T *saveP = m_Data;
+        m_Data = NULL;
+        return saveP;
+    }
+
+    T **operator &()
+    {
+        ATLASSERT(m_Data == NULL);
+        return &m_Data;
+    }
+
+    operator T* () const
+    {
+        return m_Data;
+    }
+
+protected:
+    T *m_Data;
+};
+
+
 class CComBSTR
 {
 public: