VirtualBox

source: vbox/trunk/include/iprt/cpp/mem.h@ 45113

Last change on this file since 45113 was 39658, checked in by vboxsync, 13 years ago

iprt/mem.h: missing header

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.5 KB
Line 
1/** @file
2 * IPRT - C++ Memory Resource Management.
3 */
4
5/*
6 * Copyright (C) 2006-2011 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef ___iprt_cpp_mem_h
27#define ___iprt_cpp_mem_h
28
29#include <iprt/cpp/autores.h>
30#include <iprt/assert.h>
31#include <iprt/mem.h>
32#include <iprt/string.h> /* for memset */
33
34/** @defgroup grp_rt_cpp_autores_mem C++ Memory Resource Management
35 * @ingroup grp_rt_cpp_autores
36 * @{
37 */
38
39/**
40 * Template function wrapping RTMemFree to get the correct a_fnDestruct
41 * signature for RTCAutoRes.
42 *
43 * We can't use a more complex template here, because the g++ on RHEL 3
44 * chokes on it with an internal compiler error.
45 *
46 * @tparam T The data type that's being managed.
47 * @param aMem Pointer to the memory that should be free.
48 */
49template <class T>
50inline void RTCMemAutoDestructor(T *aMem) RT_NO_THROW
51{
52 RTMemFree(aMem);
53}
54
55
56/**
57 * RTCMemAutoPtr allocator which uses RTMemTmpAlloc().
58 *
59 * @returns Allocated memory on success, NULL on failure.
60 * @param pvOld What to reallocate, shall always be NULL.
61 * @param cbNew The amount of memory to allocate (in bytes).
62 */
63inline void *RTCMemTmpAutoAllocator(void *pvOld, size_t cbNew) RT_NO_THROW
64{
65 AssertReturn(!pvOld, NULL);
66 return RTMemTmpAlloc(cbNew);
67}
68
69
70/**
71 * Template function wrapping RTMemTmpFree to get the correct a_fnDestruct
72 * signature for RTCAutoRes.
73 *
74 * We can't use a more complex template here, because the g++ on RHEL 3
75 * chokes on it with an internal compiler error.
76 *
77 * @tparam T The data type that's being managed.
78 * @param aMem Pointer to the memory that should be free.
79 */
80template <class T>
81inline void RTCMemTmpAutoDestructor(T *aMem) RT_NO_THROW
82{
83 RTMemTmpFree(aMem);
84}
85
86
87/**
88 * Template function wrapping RTMemEfFree to get the correct a_fnDestruct
89 * signature for RTCAutoRes.
90 *
91 * We can't use a more complex template here, because the g++ on RHEL 3
92 * chokes on it with an internal compiler error.
93 *
94 * @tparam T The data type that's being managed.
95 * @param aMem Pointer to the memory that should be free.
96 */
97template <class T>
98inline void RTCMemEfAutoFree(T *aMem) RT_NO_THROW
99{
100 RTMemEfFreeNP(aMem);
101}
102
103
104/**
105 * Template function wrapping NULL to get the correct NilRes signature
106 * for RTCAutoRes.
107 *
108 * @tparam T The data type that's being managed.
109 * @returns NULL with the right type.
110 */
111template <class T>
112inline T *RTCMemAutoNil(void) RT_NO_THROW
113{
114 return (T *)(NULL);
115}
116
117
118/**
119 * An auto pointer-type template class for managing memory allocating
120 * via C APIs like RTMem (the default).
121 *
122 * The main purpose of this class is to automatically free memory that
123 * isn't explicitly used (release()'ed) when the object goes out of scope.
124 *
125 * As an additional service it can also make the allocations and
126 * reallocations for you if you like, but it can also take of memory
127 * you hand it.
128 *
129 * @tparam T The data type to manage allocations for.
130 * @tparam a_fnDestruct The function to be used to free the resource.
131 * This will default to RTMemFree.
132 * @tparam a_fnAllocator The function to be used to allocate or reallocate
133 * the managed memory.
134 * This is standard realloc() like stuff, so it's
135 * possible to support simple allocation without
136 * actually having to support reallocating memory if
137 * that's a problem. This will default to
138 * RTMemRealloc.
139 */
140template <class T,
141 void a_fnDestruct(T *) = RTCMemAutoDestructor<T>,
142# if defined(RTMEM_WRAP_TO_EF_APIS) && !defined(RTMEM_NO_WRAP_TO_EF_APIS)
143 void *a_fnAllocator(void *, size_t, const char *) = RTMemEfReallocNP
144# else
145 void *a_fnAllocator(void *, size_t, const char *) = RTMemReallocTag
146# endif
147 >
148class RTCMemAutoPtr
149 : public RTCAutoRes<T *, a_fnDestruct, RTCMemAutoNil<T> >
150{
151public:
152 /**
153 * Constructor.
154 *
155 * @param aPtr Memory pointer to manage. Defaults to NULL.
156 */
157 RTCMemAutoPtr(T *aPtr = NULL)
158 : RTCAutoRes<T *, a_fnDestruct, RTCMemAutoNil<T> >(aPtr)
159 {
160 }
161
162 /**
163 * Constructor that allocates memory.
164 *
165 * @param a_cElements The number of elements (of the data type) to allocate.
166 * @param a_fZeroed Whether the memory should be memset with zeros after
167 * the allocation. Defaults to false.
168 */
169 RTCMemAutoPtr(size_t a_cElements, bool a_fZeroed = false)
170 : RTCAutoRes<T *, a_fnDestruct, RTCMemAutoNil<T> >((T *)a_fnAllocator(NULL, a_cElements * sizeof(T), RTMEM_TAG))
171 {
172 if (a_fZeroed && RT_LIKELY(this->get() != NULL))
173 memset(this->get(), '\0', a_cElements * sizeof(T));
174 }
175
176 /**
177 * Free current memory and start managing aPtr.
178 *
179 * @param aPtr Memory pointer to manage.
180 */
181 RTCMemAutoPtr &operator=(T *aPtr)
182 {
183 this->RTCAutoRes<T *, a_fnDestruct, RTCMemAutoNil<T> >::operator=(aPtr);
184 return *this;
185 }
186
187 /**
188 * Dereference with * operator.
189 */
190 T &operator*()
191 {
192 return *this->get();
193 }
194
195 /**
196 * Dereference with -> operator.
197 */
198 T *operator->()
199 {
200 return this->get();
201 }
202
203 /**
204 * Accessed with the subscript operator ([]).
205 *
206 * @returns Reference to the element.
207 * @param a_i The element to access.
208 */
209 T &operator[](size_t a_i)
210 {
211 return this->get()[a_i];
212 }
213
214 /**
215 * Allocates memory and start manage it.
216 *
217 * Any previously managed memory will be freed before making
218 * the new allocation.
219 *
220 * @returns Success indicator.
221 * @retval true if the new allocation succeeds.
222 * @retval false on failure, no memory is associated with the object.
223 *
224 * @param a_cElements The number of elements (of the data type) to allocate.
225 * This defaults to 1.
226 * @param a_fZeroed Whether the memory should be memset with zeros after
227 * the allocation. Defaults to false.
228 */
229 bool alloc(size_t a_cElements = 1, bool a_fZeroed = false)
230 {
231 this->reset(NULL);
232 T *pNewMem = (T *)a_fnAllocator(NULL, a_cElements * sizeof(T), RTMEM_TAG);
233 if (a_fZeroed && RT_LIKELY(pNewMem != NULL))
234 memset(pNewMem, '\0', a_cElements * sizeof(T));
235 this->reset(pNewMem);
236 return pNewMem != NULL;
237 }
238
239 /**
240 * Reallocate or allocates the memory resource.
241 *
242 * Free the old value if allocation fails.
243 *
244 * The content of any additional memory that was allocated is
245 * undefined when using the default allocator.
246 *
247 * @returns Success indicator.
248 * @retval true if the new allocation succeeds.
249 * @retval false on failure, no memory is associated with the object.
250 *
251 * @param a_cElements The new number of elements (of the data type) to
252 * allocate. The size of the allocation is the number of
253 * elements times the size of the data type - this is
254 * currently what's passed down to the a_fnAllocator.
255 * This defaults to 1.
256 */
257 bool realloc(size_t a_cElements = 1)
258 {
259 T *aNewValue = (T *)a_fnAllocator(this->get(), a_cElements * sizeof(T), RTMEM_TAG);
260 if (RT_LIKELY(aNewValue != NULL))
261 this->release();
262 /* We want this both if aNewValue is non-NULL and if it is NULL. */
263 this->reset(aNewValue);
264 return aNewValue != NULL;
265 }
266};
267
268/** @} */
269
270#endif
271
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette