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