xref: /reactos/sdk/lib/atl/atlalloc.h (revision 45d33582)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * ReactOS ATL
3c2c66affSColin Finck  *
4c2c66affSColin Finck  * Copyright 2009 Andrew Hill <ash77@reactos.org>
5c2c66affSColin Finck  * Copyright 2016 Mark Jansen
6c2c66affSColin Finck  *
7c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
8c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
9c2c66affSColin Finck  * License as published by the Free Software Foundation; either
10c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
11c2c66affSColin Finck  *
12c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
13c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15c2c66affSColin Finck  * Lesser General Public License for more details.
16c2c66affSColin Finck  *
17c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
18c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
19c2c66affSColin Finck  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20c2c66affSColin Finck  */
21c2c66affSColin Finck 
22c2c66affSColin Finck #pragma once
23c2c66affSColin Finck 
24c2c66affSColin Finck class CCRTAllocator
25c2c66affSColin Finck {
26c2c66affSColin Finck public:
Allocate(_In_ size_t size)27c2c66affSColin Finck     static void* Allocate(_In_ size_t size)
28c2c66affSColin Finck     {
29c2c66affSColin Finck         return malloc(size);
30c2c66affSColin Finck     }
31c2c66affSColin Finck 
Reallocate(_In_opt_ void * ptr,_In_ size_t size)32c2c66affSColin Finck     static void* Reallocate(_In_opt_ void* ptr, _In_ size_t size)
33c2c66affSColin Finck     {
34c2c66affSColin Finck         return realloc(ptr, size);
35c2c66affSColin Finck     }
36c2c66affSColin Finck 
Free(_In_opt_ void * ptr)37c2c66affSColin Finck     static void Free(_In_opt_ void* ptr)
38c2c66affSColin Finck     {
39c2c66affSColin Finck         free(ptr);
40c2c66affSColin Finck     }
41c2c66affSColin Finck };
42c2c66affSColin Finck 
43c2c66affSColin Finck class CLocalAllocator
44c2c66affSColin Finck {
45c2c66affSColin Finck public:
Allocate(_In_ size_t size)46c2c66affSColin Finck     static void* Allocate(_In_ size_t size)
47c2c66affSColin Finck     {
48c2c66affSColin Finck         return ::LocalAlloc(LMEM_FIXED, size);
49c2c66affSColin Finck     }
50c2c66affSColin Finck 
Reallocate(_In_opt_ void * ptr,_In_ size_t size)51c2c66affSColin Finck     static void* Reallocate(_In_opt_ void* ptr, _In_ size_t size)
52c2c66affSColin Finck     {
53c2c66affSColin Finck         if (!ptr)
54c2c66affSColin Finck             return Allocate(size);
55c2c66affSColin Finck         if (size == 0)
56c2c66affSColin Finck         {
57c2c66affSColin Finck             Free(ptr);
58c2c66affSColin Finck             return NULL;
59c2c66affSColin Finck         }
60c2c66affSColin Finck         return ::LocalReAlloc(ptr, size, 0);
61c2c66affSColin Finck     }
62c2c66affSColin Finck 
Free(_In_opt_ void * ptr)63c2c66affSColin Finck     static void Free(_In_opt_ void* ptr)
64c2c66affSColin Finck     {
65c2c66affSColin Finck         ::LocalFree(ptr);
66c2c66affSColin Finck     }
67c2c66affSColin Finck };
68c2c66affSColin Finck 
69c2c66affSColin Finck class CGlobalAllocator
70c2c66affSColin Finck {
71c2c66affSColin Finck public:
Allocate(_In_ size_t size)72c2c66affSColin Finck     static void* Allocate(_In_ size_t size)
73c2c66affSColin Finck     {
74c2c66affSColin Finck         return ::GlobalAlloc(GMEM_FIXED, size);
75c2c66affSColin Finck     }
76c2c66affSColin Finck 
Reallocate(_In_opt_ void * ptr,_In_ size_t size)77c2c66affSColin Finck     static void* Reallocate(_In_opt_ void* ptr, _In_ size_t size)
78c2c66affSColin Finck     {
79c2c66affSColin Finck         if (!ptr)
80c2c66affSColin Finck             return Allocate(size);
81c2c66affSColin Finck         if (size == 0)
82c2c66affSColin Finck         {
83c2c66affSColin Finck             Free(ptr);
84c2c66affSColin Finck             return NULL;
85c2c66affSColin Finck         }
86c2c66affSColin Finck         return ::GlobalReAlloc(ptr, size, 0);
87c2c66affSColin Finck     }
88c2c66affSColin Finck 
Free(_In_opt_ void * ptr)89c2c66affSColin Finck     static void Free(_In_opt_ void* ptr)
90c2c66affSColin Finck     {
91c2c66affSColin Finck         GlobalFree(ptr);
92c2c66affSColin Finck     }
93c2c66affSColin Finck };
94c2c66affSColin Finck 
95c2c66affSColin Finck 
96c2c66affSColin Finck template<class T, class Allocator = CCRTAllocator>
97c2c66affSColin Finck class CHeapPtr
98c2c66affSColin Finck {
99c2c66affSColin Finck public:
CHeapPtr()100c2c66affSColin Finck     CHeapPtr() :
101*45d33582SMark Jansen         m_pData(NULL)
102c2c66affSColin Finck     {
103c2c66affSColin Finck     }
104c2c66affSColin Finck 
CHeapPtr(T * lp)105c2c66affSColin Finck     explicit CHeapPtr(T *lp) :
106*45d33582SMark Jansen         m_pData(lp)
107c2c66affSColin Finck     {
108c2c66affSColin Finck     }
109c2c66affSColin Finck 
CHeapPtr(CHeapPtr<T,Allocator> & lp)110c2c66affSColin Finck     explicit CHeapPtr(CHeapPtr<T, Allocator> &lp)
111c2c66affSColin Finck     {
112*45d33582SMark Jansen         m_pData = lp.Detach();
113c2c66affSColin Finck     }
114c2c66affSColin Finck 
~CHeapPtr()115c2c66affSColin Finck     ~CHeapPtr()
116c2c66affSColin Finck     {
117c2c66affSColin Finck         Free();
118c2c66affSColin Finck     }
119c2c66affSColin Finck 
120c2c66affSColin Finck     CHeapPtr<T, Allocator>& operator = (CHeapPtr<T, Allocator> &lp)
121c2c66affSColin Finck     {
122*45d33582SMark Jansen         if (lp.m_pData != m_pData)
123c2c66affSColin Finck             Attach(lp.Detach());
124c2c66affSColin Finck         return *this;
125c2c66affSColin Finck     }
126c2c66affSColin Finck 
AllocateBytes(_In_ size_t nBytes)127c2c66affSColin Finck     bool AllocateBytes(_In_ size_t nBytes)
128c2c66affSColin Finck     {
129*45d33582SMark Jansen         ATLASSERT(m_pData == NULL);
130*45d33582SMark Jansen         m_pData = static_cast<T*>(Allocator::Allocate(nBytes));
131*45d33582SMark Jansen         return m_pData != NULL;
132c2c66affSColin Finck     }
133c2c66affSColin Finck 
ReallocateBytes(_In_ size_t nBytes)134c2c66affSColin Finck     bool ReallocateBytes(_In_ size_t nBytes)
135c2c66affSColin Finck     {
136*45d33582SMark Jansen         T* newData = static_cast<T*>(Allocator::Reallocate(m_pData, nBytes));
137c2c66affSColin Finck         if (newData == NULL)
138c2c66affSColin Finck             return false;
139*45d33582SMark Jansen         m_pData = newData;
140c2c66affSColin Finck         return true;
141c2c66affSColin Finck     }
142c2c66affSColin Finck 
143c2c66affSColin Finck     bool Allocate(_In_ size_t nElements = 1)
144c2c66affSColin Finck     {
145c2c66affSColin Finck         return AllocateBytes(nElements * sizeof(T));
146c2c66affSColin Finck     }
147c2c66affSColin Finck 
Reallocate(_In_ size_t nElements)148c2c66affSColin Finck     bool Reallocate(_In_ size_t nElements)
149c2c66affSColin Finck     {
150c2c66affSColin Finck         return ReallocateBytes(nElements * sizeof(T));
151c2c66affSColin Finck     }
152c2c66affSColin Finck 
Free()153c2c66affSColin Finck     void Free()
154c2c66affSColin Finck     {
155*45d33582SMark Jansen         if (m_pData)
156c2c66affSColin Finck         {
157*45d33582SMark Jansen             Allocator::Free(m_pData);
158*45d33582SMark Jansen             m_pData = NULL;
159c2c66affSColin Finck         }
160c2c66affSColin Finck     }
161c2c66affSColin Finck 
Attach(T * lp)162c2c66affSColin Finck     void Attach(T *lp)
163c2c66affSColin Finck     {
164*45d33582SMark Jansen         Allocator::Free(m_pData);
165*45d33582SMark Jansen         m_pData = lp;
166c2c66affSColin Finck     }
167c2c66affSColin Finck 
Detach()168c2c66affSColin Finck     T *Detach()
169c2c66affSColin Finck     {
170*45d33582SMark Jansen         T *saveP = m_pData;
171*45d33582SMark Jansen         m_pData = NULL;
172c2c66affSColin Finck         return saveP;
173c2c66affSColin Finck     }
174c2c66affSColin Finck 
175c2c66affSColin Finck     T **operator &()
176c2c66affSColin Finck     {
177*45d33582SMark Jansen         ATLASSERT(m_pData == NULL);
178*45d33582SMark Jansen         return &m_pData;
179c2c66affSColin Finck     }
180c2c66affSColin Finck 
181c2c66affSColin Finck     operator T* () const
182c2c66affSColin Finck     {
183*45d33582SMark Jansen         return m_pData;
184c2c66affSColin Finck     }
185c2c66affSColin Finck 
186c2c66affSColin Finck     T* operator->() const
187c2c66affSColin Finck     {
188*45d33582SMark Jansen         return m_pData;
189c2c66affSColin Finck     }
190c2c66affSColin Finck 
191*45d33582SMark Jansen public:
192*45d33582SMark Jansen     T *m_pData;
193c2c66affSColin Finck };
194c2c66affSColin Finck 
195