reactos/sdk/lib/atl/atlalloc.h

195 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_Data(NULL)
{
}
explicit CHeapPtr(T *lp) :
m_Data(lp)
{
}
explicit CHeapPtr(CHeapPtr<T, Allocator> &lp)
{
m_Data = lp.Detach();
}
~CHeapPtr()
{
Free();
}
CHeapPtr<T, Allocator>& operator = (CHeapPtr<T, Allocator> &lp)
{
if (lp.m_Data != m_Data)
Attach(lp.Detach());
return *this;
}
bool AllocateBytes(_In_ size_t nBytes)
{
ATLASSERT(m_Data == NULL);
m_Data = static_cast<T*>(Allocator::Allocate(nBytes));
return m_Data != NULL;
}
bool ReallocateBytes(_In_ size_t nBytes)
{
T* newData = static_cast<T*>(Allocator::Reallocate(m_Data, nBytes));
if (newData == NULL)
return false;
m_Data = 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_Data)
{
Allocator::Free(m_Data);
m_Data = NULL;
}
}
void Attach(T *lp)
{
Allocator::Free(m_Data);
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;
}
T* operator->() const
{
return m_Data;
}
protected:
T *m_Data;
};