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