mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
194 lines
3.8 KiB
C++
194 lines
3.8 KiB
C++
/*
|
|
* ReactOS ATL
|
|
*
|
|
* Copyright 2009 Andrew Hill <ash77@reactos.org>
|
|
* Copyright 2016 Mark Jansen
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
class CCRTAllocator
|
|
{
|
|
public:
|
|
static void* Allocate(_In_ size_t size)
|
|
{
|
|
return malloc(size);
|
|
}
|
|
|
|
static void* Reallocate(_In_opt_ void* ptr, _In_ size_t size)
|
|
{
|
|
return realloc(ptr, size);
|
|
}
|
|
|
|
static void Free(_In_opt_ void* ptr)
|
|
{
|
|
free(ptr);
|
|
}
|
|
};
|
|
|
|
class CLocalAllocator
|
|
{
|
|
public:
|
|
static void* Allocate(_In_ size_t size)
|
|
{
|
|
return ::LocalAlloc(LMEM_FIXED, size);
|
|
}
|
|
|
|
static void* Reallocate(_In_opt_ void* ptr, _In_ size_t size)
|
|
{
|
|
if (!ptr)
|
|
return Allocate(size);
|
|
if (size == 0)
|
|
{
|
|
Free(ptr);
|
|
return NULL;
|
|
}
|
|
return ::LocalReAlloc(ptr, size, 0);
|
|
}
|
|
|
|
static void Free(_In_opt_ void* ptr)
|
|
{
|
|
::LocalFree(ptr);
|
|
}
|
|
};
|
|
|
|
class CGlobalAllocator
|
|
{
|
|
public:
|
|
static void* Allocate(_In_ size_t size)
|
|
{
|
|
return ::GlobalAlloc(GMEM_FIXED, size);
|
|
}
|
|
|
|
static void* Reallocate(_In_opt_ void* ptr, _In_ size_t size)
|
|
{
|
|
if (!ptr)
|
|
return Allocate(size);
|
|
if (size == 0)
|
|
{
|
|
Free(ptr);
|
|
return NULL;
|
|
}
|
|
return ::GlobalReAlloc(ptr, size, 0);
|
|
}
|
|
|
|
static void Free(_In_opt_ void* ptr)
|
|
{
|
|
GlobalFree(ptr);
|
|
}
|
|
};
|
|
|
|
|
|
template<class T, class Allocator = CCRTAllocator>
|
|
class CHeapPtr
|
|
{
|
|
public:
|
|
CHeapPtr() :
|
|
m_pData(NULL)
|
|
{
|
|
}
|
|
|
|
explicit CHeapPtr(T *lp) :
|
|
m_pData(lp)
|
|
{
|
|
}
|
|
|
|
explicit CHeapPtr(CHeapPtr<T, Allocator> &lp)
|
|
{
|
|
m_pData = lp.Detach();
|
|
}
|
|
|
|
~CHeapPtr()
|
|
{
|
|
Free();
|
|
}
|
|
|
|
CHeapPtr<T, Allocator>& operator = (CHeapPtr<T, Allocator> &lp)
|
|
{
|
|
if (lp.m_pData != m_pData)
|
|
Attach(lp.Detach());
|
|
return *this;
|
|
}
|
|
|
|
bool AllocateBytes(_In_ size_t nBytes)
|
|
{
|
|
ATLASSERT(m_pData == NULL);
|
|
m_pData = static_cast<T*>(Allocator::Allocate(nBytes));
|
|
return m_pData != NULL;
|
|
}
|
|
|
|
bool ReallocateBytes(_In_ size_t nBytes)
|
|
{
|
|
T* newData = static_cast<T*>(Allocator::Reallocate(m_pData, nBytes));
|
|
if (newData == NULL)
|
|
return false;
|
|
m_pData = newData;
|
|
return true;
|
|
}
|
|
|
|
bool Allocate(_In_ size_t nElements = 1)
|
|
{
|
|
return AllocateBytes(nElements * sizeof(T));
|
|
}
|
|
|
|
bool Reallocate(_In_ size_t nElements)
|
|
{
|
|
return ReallocateBytes(nElements * sizeof(T));
|
|
}
|
|
|
|
void Free()
|
|
{
|
|
if (m_pData)
|
|
{
|
|
Allocator::Free(m_pData);
|
|
m_pData = NULL;
|
|
}
|
|
}
|
|
|
|
void Attach(T *lp)
|
|
{
|
|
Allocator::Free(m_pData);
|
|
m_pData = lp;
|
|
}
|
|
|
|
T *Detach()
|
|
{
|
|
T *saveP = m_pData;
|
|
m_pData = NULL;
|
|
return saveP;
|
|
}
|
|
|
|
T **operator &()
|
|
{
|
|
ATLASSERT(m_pData == NULL);
|
|
return &m_pData;
|
|
}
|
|
|
|
operator T* () const
|
|
{
|
|
return m_pData;
|
|
}
|
|
|
|
T* operator->() const
|
|
{
|
|
return m_pData;
|
|
}
|
|
|
|
public:
|
|
T *m_pData;
|
|
};
|
|
|