Changeset 36805 in vbox for trunk/src/VBox/Additions
- Timestamp:
- Apr 21, 2011 9:48:52 PM (14 years ago)
- Location:
- trunk/src/VBox/Additions/x11/VBoxClient
- Files:
-
- 1 added
- 1 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/x11/VBoxClient/Makefile.kmk
r35380 r36805 108 108 $(QUIET)$(APPEND) -t "$@" "done" 109 109 110 PROGRAMS += tstVector 111 tstVector_TEMPLATE = VBOXR3TSTEXE 112 tstVector_SOURCES = \ 113 testcase/tstVector.cpp 114 tstVector_INCS = . 115 tstVector_LIBS = \ 116 $(LIB_RUNTIME) 117 110 118 # 111 119 # Additional testcase designed to be run manually, which initiates and starts the Linux -
trunk/src/VBox/Additions/x11/VBoxClient/vector.h
r36670 r36805 1 1 /** @file 2 * IPRT - Vector 2 3 * STL-inspired vector implementation in C 3 * @note functions in this file are inline to prevent warnings about4 * unused static functions. I assume that in this day and age a5 * compiler makes its own decisions about whether to actually6 * inline a function.7 * @note as this header is included in rdesktop-vrdp, we do not include other8 * required header files here (to wit assert.h, err.h, mem.h and9 * types.h). These must be included first. If this moves to iprt, we10 * should write a wrapper around it doing that.11 * @todo can we do more of the type checking at compile time somehow?12 4 */ 13 5 14 6 /* 15 * Copyright (C) 20 08-2010Oracle Corporation7 * Copyright (C) 2011 Oracle Corporation 16 8 * 17 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 22 14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the 23 15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. 24 */ 25 26 #ifndef MAIN_VECTOR_H 27 # define MAIN_VECTOR_H 16 * 17 * The contents of this file may alternatively be used under the terms 18 * of the Common Development and Distribution License Version 1.0 19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the 20 * VirtualBox OSE distribution, in which case the provisions of the 21 * CDDL are applicable instead of those of the GPL. 22 * 23 * You may elect to license modified versions of this file under the 24 * terms and conditions of either the GPL or the CDDL or both. 25 */ 26 27 /** 28 * @todo the right Doxygen tag here 29 * This file defines a set of macros which provide a functionality and an 30 * interface roughly similar to the C++ STL vector container. To create a 31 * vector of a particular type one must first explicitly instantiate such a 32 * vector in the source file, e.g. 33 * RTVEC_DECL(TopLevels, Window *) 34 * without a semi-colon. This macro will define a structure (struct TopLevels) 35 * which contains a dynamically resizeable array of Window * elements. It 36 * will also define a number of inline methods for manipulating the structure, 37 * such as 38 * Window *TopLevelsPushBack(struct TopLevels *) 39 * which adds a new element to the end of the array and returns it, optionally 40 * reallocating the array if there is not enough space for the new element. 41 * (This particular method prototype differs from the STL equivalent - 42 * push_back - more than most of the other methods). 43 * 44 * To create a vector, one simply needs to declare the structure, in this case 45 * struct TopLevels = RTVEC_INITIALIZER; 46 * 47 * There are various other macros for declaring vectors with different 48 * allocators (e.g. RTVEC_DECL_ALLOCATOR) or with clean-up functions 49 * (e.g. RTVEC_DECL_DELETE). See the descriptions of the generic methods and 50 * the declarator macros below. 51 * 52 * One particular use of vectors is to assemble an array of a particular type 53 * in heap memory without knowing - or counting - the number of elements in 54 * advance. To do this, add the elements onto the array using PushBack, then 55 * extract the array from the vector using the (non-STL) Detach method. 56 * 57 * @note functions in this file are inline to prevent warnings about 58 * unused static functions. I assume that in this day and age a 59 * compiler makes its own decisions about whether to actually 60 * inline a function. 61 * @note since vector structures must be explicitly instanciated unlike the 62 * C++ vector template, care must be taken not to instanciate a 63 * particular type twice, e.g. once in a header and once in a code file. 64 * Only using vectors in code files and keeping them out of interfaces 65 * (or passing them as anonymously) makes it easier to take care of this. 66 */ 67 #ifndef ___iprt_vector_h 68 # define ___iprt_vector_h 28 69 29 70 /******************************************************************************* … … 31 72 *******************************************************************************/ 32 73 33 #include <stdlib.h> 34 35 /******************************************************************************* 36 * Helper macros and definitions * 37 *******************************************************************************/ 74 #include <iprt/assert.h> 75 #include <iprt/cdefs.h> 76 #include <iprt/err.h> 77 #include <iprt/mem.h> /** @todo Should the caller include this if they need 78 * it? */ 79 80 81 /** 82 * Generic vector structure 83 */ 84 /** @todo perhaps we should include an additional member for a parameter to 85 * three-argument reallocators, so that we can support e.g. mempools? */ 86 #define RTVEC_DECL_STRUCT(name, type) \ 87 struct name \ 88 { \ 89 /** The number of elements in the vector */ \ 90 size_t mcElements; \ 91 /** The current capacity of the vector */ \ 92 size_t mcCapacity; \ 93 /** The elements themselves */ \ 94 type *mpElements; \ 95 }; 96 97 /** Initialiser for an empty vector structure */ 98 #define RTVEC_INITIALIZER { 0, 0, NULL } 38 99 39 100 /** The unit by which the vector capacity is increased */ 40 #define VECTOR_ALLOC_UNIT 16 41 42 /** Calculate a hash of a string of tokens for sanity type checking */ 43 #define VECTOR_TOKEN_HASH(token) \ 44 ((unsigned) \ 45 ( VECTOR_TOKEN_HASH4(token, 0) \ 46 ^ VECTOR_TOKEN_HASH4(token, 4) \ 47 ^ VECTOR_TOKEN_HASH4(token, 8) \ 48 ^ VECTOR_TOKEN_HASH4(token, 12))) 49 50 /** Helper macro for @a VECTOR_TOKEN_HASH */ 51 #define VECTOR_TOKEN_HASH_VALUE(token, place, mul) \ 52 (sizeof(#token) > place ? #token[place] * mul : 0) 53 54 /** Helper macro for @a VECTOR_TOKEN_HASH */ 55 #define VECTOR_TOKEN_HASH4(token, place) \ 56 VECTOR_TOKEN_HASH_VALUE(token, place, 0x1) \ 57 ^ VECTOR_TOKEN_HASH_VALUE(token, place + 1, 0x100) \ 58 ^ VECTOR_TOKEN_HASH_VALUE(token, place + 2, 0x10000) \ 59 ^ VECTOR_TOKEN_HASH_VALUE(token, place + 3, 0x1000000) 60 61 /** Generic vector structure, used by @a VECTOR_OBJ and @a VECTOR_PTR */ 62 #define VECTOR_STRUCT \ 63 { \ 64 /** The number of elements in the vector */ \ 65 size_t mcElements; \ 66 /** The current capacity of the vector */ \ 67 size_t mcCapacity; \ 68 /** The size of an element */ \ 69 size_t mcbElement; \ 70 /** Hash value of the element type */ \ 71 unsigned muTypeHash; \ 72 /** The elements themselves */ \ 73 void *mpvaElements; \ 74 /** Destructor for elements - takes a pointer to an element. */ \ 75 void (*mpfnCleanup)(void *); \ 76 } 77 78 /*** Structure definitions ***/ 79 80 /** A vector of values or objects */ 81 typedef struct VECTOR_OBJ VECTOR_STRUCT VECTOR_OBJ; 82 83 /** A vector of pointer values. (A handy special case.) */ 84 typedef struct VECTOR_PTR VECTOR_STRUCT VECTOR_PTR; 85 86 /** Convenience macro for annotating the type of the vector. Unfortunately the 87 * type name is only cosmetic. */ 88 /** @todo can we do something useful with the type? */ 89 #define VECTOR_OBJ(type) VECTOR_OBJ 90 91 /** Convenience macro for annotating the type of the vector. Unfortunately the 92 * type name is only cosmetic. */ 93 #define VECTOR_PTR(type) VECTOR_PTR 94 95 /*** Private helper functions and macros ***/ 96 97 #define VEC_GET_ELEMENT_OBJ(pvaElements, cbElement, cElement) \ 98 ((void *)((char *)(pvaElements) + (cElement) * (cbElement))) 99 100 #define VEC_GET_ELEMENT_PTR(pvaElements, cElement) \ 101 (*(void **)VEC_GET_ELEMENT_OBJ(pvaElements, sizeof(void *), cElement)) 102 103 /** Default cleanup function that does nothing. */ 104 DECLINLINE(void) vecNoCleanup(void *pvElement) 101 #define RTVECIMPL_ALLOC_UNIT 16 102 103 /** 104 * Generic method - get the size of a vector 105 */ 106 /** @todo What is the correct way to do doxygen for this sort of macro? */ 107 #define RTVEC_DECLFN_SIZE(name, type) \ 108 DECLINLINE(size_t) name ## Size(struct name *pVec) \ 109 { \ 110 return(pVec->mcElements); \ 111 } 112 113 /** 114 * Generic method - expand a vector 115 */ 116 #define RTVEC_DECLFN_RESERVE(name, type, pfnRealloc) \ 117 DECLINLINE(int) name ## Reserve(struct name *pVec, size_t cNewCapacity) \ 118 { \ 119 void *pvNew; \ 120 \ 121 if (cNewCapacity <= pVec->mcCapacity) \ 122 return VINF_SUCCESS; \ 123 pvNew = pfnRealloc(pVec->mpElements, cNewCapacity * sizeof(type)); \ 124 if (!pvNew) \ 125 return VERR_NO_MEMORY; \ 126 pVec->mcCapacity = cNewCapacity; \ 127 pVec->mpElements = (type *)pvNew; \ 128 return VINF_SUCCESS; \ 129 } 130 131 /** 132 * Generic method - return a pointer to the first element in the vector. 133 */ 134 #define RTVEC_DECLFN_BEGIN(name, type) \ 135 DECLINLINE(type *) name ## Begin(struct name *pVec) \ 136 { \ 137 return(pVec->mpElements); \ 138 } 139 140 /** 141 * Generic method - return a pointer to one past the last element in the 142 * vector. 143 */ 144 #define RTVEC_DECLFN_END(name, type) \ 145 DECLINLINE(type *) name ## End(struct name *pVec) \ 146 { \ 147 return(&pVec->mpElements[pVec->mcElements]); \ 148 } 149 150 /** 151 * Generic method - add a new, uninitialised element onto a vector and return 152 * it. 153 * @note this method differs from the STL equivalent by letting the caller 154 * post-initialise the new element rather than copying it from its 155 * argument. 156 */ 157 #define RTVEC_DECLFN_PUSHBACK(name, type) \ 158 DECLINLINE(type *) name ## PushBack(struct name *pVec) \ 159 { \ 160 Assert(pVec->mcElements <= pVec->mcCapacity); \ 161 if ( pVec->mcElements == pVec->mcCapacity \ 162 && RT_FAILURE(name ## Reserve(pVec, pVec->mcCapacity \ 163 + RTVECIMPL_ALLOC_UNIT))) \ 164 return NULL; \ 165 ++pVec->mcElements; \ 166 return &pVec->mpElements[pVec->mcElements - 1]; \ 167 } 168 169 /** 170 * Generic method - drop the last element from the vector. 171 */ 172 #define RTVEC_DECLFN_POPBACK(name) \ 173 DECLINLINE(void) name ## PopBack(struct name *pVec) \ 174 { \ 175 Assert(pVec->mcElements <= pVec->mcCapacity); \ 176 --pVec->mcElements; \ 177 } 178 179 /** 180 * Generic method - drop the last element from the vector, calling a clean-up 181 * method first. 182 * 183 * By taking an adapter function for the element to be dropped as an 184 * additional macro parameter we can support clean-up by pointer 185 * (pfnAdapter maps T* -> T*) or by value (maps T* -> T). pfnAdapter takes 186 * one argument of type @a type * and must return whatever type pfnDelete 187 * expects. 188 */ 189 /** @todo find a better name for pfnAdapter? */ 190 #define RTVEC_DECLFN_POPBACK_DELETE(name, type, pfnDelete, pfnAdapter) \ 191 DECLINLINE(void) name ## PopBack(struct name *pVec) \ 192 { \ 193 Assert(pVec->mcElements <= pVec->mcCapacity); \ 194 --pVec->mcElements; \ 195 pfnDelete(pfnAdapter(&pVec->mpElements[pVec->mcElements])); \ 196 } 197 198 /** 199 * Generic method - reset a vector to empty. 200 * @note This function does not free any memory 201 */ 202 #define RTVEC_DECLFN_CLEAR(name) \ 203 DECLINLINE(void) name ## Clear(struct name *pVec) \ 204 { \ 205 Assert(pVec->mcElements <= pVec->mcCapacity); \ 206 pVec->mcElements = 0; \ 207 } 208 209 /** 210 * Generic method - reset a vector to empty, calling a clean-up method on each 211 * element first. 212 * @note See @a RTVEC_DECLFN_POPBACK_DELETE for an explanation of pfnAdapter 213 * @note This function does not free any memory 214 * @note The cleanup function is currently called on the elements from first 215 * to last. The testcase expects this. 216 */ 217 #define RTVEC_DECLFN_CLEAR_DELETE(name, pfnDelete, pfnAdapter) \ 218 DECLINLINE(void) name ## Clear(struct name *pVec) \ 219 { \ 220 size_t i; \ 221 \ 222 Assert(pVec->mcElements <= pVec->mcCapacity); \ 223 for (i = 0; i < pVec->mcElements; ++i) \ 224 pfnDelete(pfnAdapter(&pVec->mpElements[i])); \ 225 pVec->mcElements = 0; \ 226 } 227 228 /** 229 * Generic method - detach the array contained inside a vector and reset the 230 * vector to empty. 231 * @note This function does not free any memory 232 */ 233 #define RTVEC_DECLFN_DETACH(name, type) \ 234 DECLINLINE(type *) name ## Detach(struct name *pVec) \ 235 { \ 236 type *pArray = pVec->mpElements; \ 237 \ 238 Assert(pVec->mcElements <= pVec->mcCapacity); \ 239 pVec->mcElements = 0; \ 240 pVec->mpElements = NULL; \ 241 pVec->mcCapacity = 0; \ 242 return pArray; \ 243 } 244 245 /** Common declarations for all vector types */ 246 #define RTVEC_DECL_COMMON(name, type, pfnRealloc) \ 247 RTVEC_DECL_STRUCT(name, type) \ 248 RTVEC_DECLFN_SIZE(name, type) \ 249 RTVEC_DECLFN_RESERVE(name, type, pfnRealloc) \ 250 RTVEC_DECLFN_BEGIN(name, type) \ 251 RTVEC_DECLFN_END(name, type) \ 252 RTVEC_DECLFN_PUSHBACK(name, type) \ 253 RTVEC_DECLFN_DETACH(name, type) 254 255 /** 256 * Declarator macro - declare a vector type 257 * @param name the name of the C struct type describing the vector as 258 * well as the prefix of the functions for manipulating it 259 * @param type the type of the objects contained in the vector 260 * @param pfnRealloc the memory reallocation function used for expanding the 261 * vector 262 */ 263 #define RTVEC_DECL_ALLOCATOR(name, type, pfnRealloc) \ 264 RTVEC_DECL_COMMON(name, type, pfnRealloc) \ 265 RTVEC_DECLFN_POPBACK(name) \ 266 RTVEC_DECLFN_CLEAR(name) 267 268 /** 269 * Generic method - inline id mapping delete adapter function - see the 270 * explanation of pfnAdapter in @a RTVEC_DECLFN_POPBACK_DELETE. 271 */ 272 #define RTVEC_DECLFN_DELETE_ADAPTER_ID(name, type) \ 273 DECLINLINE(type *) name ## DeleteAdapterId(type *arg) \ 274 { \ 275 return arg; \ 276 } 277 278 /** 279 * Generic method - inline pointer-to-value mapping delete adapter function - 280 * see the explanation of pfnAdapter in @a RTVEC_DECLFN_POPBACK_DELETE. 281 */ 282 #define RTVEC_DECLFN_DELETE_ADAPTER_TO_VALUE(name, type) \ 283 DECLINLINE(type) name ## DeleteAdapterToValue(type *arg) \ 284 { \ 285 return *arg; \ 286 } 287 288 /** 289 * Declarator macro - declare a vector type with a cleanup callback to be used 290 * when elements are dropped from the vector. The callback takes a pointer to 291 * @a type, 292 * NOT a value of type @a type. 293 * @param name the name of the C struct type describing the vector as 294 * well as the prefix of the functions for manipulating it 295 * @param type the type of the objects contained in the vector 296 * @param pfnRealloc the memory reallocation function used for expanding the 297 * vector 298 * @param pfnDelete the cleanup callback function - signature 299 * void pfnDelete(type *) 300 */ 301 #define RTVEC_DECL_ALLOCATOR_DELETE(name, type, pfnRealloc, pfnDelete) \ 302 RTVEC_DECL_COMMON(name, type, pfnRealloc) \ 303 RTVEC_DECLFN_DELETE_ADAPTER_ID(name, type) \ 304 RTVEC_DECLFN_POPBACK_DELETE(name, type, pfnDelete, \ 305 name ## DeleteAdapterId) \ 306 RTVEC_DECLFN_CLEAR_DELETE(name, pfnDelete, name ## DeleteAdapterId) 307 308 /** 309 * Declarator macro - declare a vector type with a cleanup callback to be used 310 * when elements are dropped from the vector. The callback takes a parameter 311 * of type @a type, NOT a pointer to @a type. 312 * @param name the name of the C struct type describing the vector as 313 * well as the prefix of the functions for manipulating it 314 * @param type the type of the objects contained in the vector 315 * @param pfnRealloc the memory reallocation function used for expanding the 316 * vector 317 * @param pfnDelete the cleanup callback function - signature 318 * void pfnDelete(type) 319 */ 320 #define RTVEC_DECL_ALLOCATOR_DELETE_BY_VALUE(name, type, pfnRealloc, \ 321 pfnDelete) \ 322 RTVEC_DECL_COMMON(name, type, pfnRealloc) \ 323 RTVEC_DECLFN_DELETE_ADAPTER_TO_VALUE(name, type) \ 324 RTVEC_DECLFN_POPBACK_DELETE(name, type, pfnDelete, \ 325 name ## DeleteAdapterToValue) \ 326 RTVEC_DECLFN_CLEAR_DELETE(name, pfnDelete, \ 327 name ## DeleteAdapterToValue) 328 329 /** 330 * Inline wrapper around RTMemRealloc macro to get a function usable as a 331 * callback. 332 */ 333 DECLINLINE(void *) rtvecReallocDefTag(void *pv, size_t cbNew) 105 334 { 106 (void) pvElement; 107 } 108 109 /** Expand an existing vector, implementation */ 110 DECLINLINE(int) vecExpand(size_t *pcCapacity, void **ppvaElements, 111 size_t cbElement) 112 { 113 size_t cOldCap, cNewCap; 114 void *pRealloc; 115 116 cOldCap = *pcCapacity; 117 cNewCap = cOldCap + VECTOR_ALLOC_UNIT; 118 pRealloc = RTMemRealloc(*ppvaElements, cNewCap * cbElement); 119 if (!pRealloc) 120 return VERR_NO_MEMORY; 121 *pcCapacity = cNewCap; 122 *ppvaElements = pRealloc; 123 return VINF_SUCCESS; 124 } 125 126 /** Expand an existing vector */ 127 #define VEC_EXPAND(pvec) vecExpand(&(pvec)->mcCapacity, &(pvec)->mpvaElements, \ 128 (pvec)->mcbElement) 129 130 /** Reset a vector, cleaning up all its elements. */ 131 DECLINLINE(void) vecClearObj(VECTOR_OBJ *pvec) 132 { 133 unsigned i; 134 135 for (i = 0; i < pvec->mcElements; ++i) 136 pvec->mpfnCleanup(VEC_GET_ELEMENT_OBJ(pvec->mpvaElements, 137 pvec->mcbElement, i)); 138 pvec->mcElements = 0; 139 } 140 141 /** Reset a pointer vector, cleaning up all its elements. */ 142 DECLINLINE(void) vecClearPtr(VECTOR_PTR *pvec) 143 { 144 unsigned i; 145 146 for (i = 0; i < pvec->mcElements; ++i) 147 pvec->mpfnCleanup(VEC_GET_ELEMENT_PTR(pvec->mpvaElements, i)); 148 pvec->mcElements = 0; 149 } 150 151 /** Clean up a vector */ 152 DECLINLINE(void) vecCleanupObj(VECTOR_OBJ *pvec) 153 { 154 vecClearObj(pvec); 155 RTMemFree(pvec->mpvaElements); 156 pvec->mpvaElements = NULL; 157 } 158 159 /** Clean up a pointer vector */ 160 DECLINLINE(void) vecCleanupPtr(VECTOR_PTR *pvec) 161 { 162 vecClearPtr(pvec); 163 RTMemFree(pvec->mpvaElements); 164 pvec->mpvaElements = NULL; 165 } 166 167 /** Initialise a vector structure, implementation */ 168 #define VEC_INIT(pvec, cbElement, uTypeHash, pfnCleanup) \ 169 pvec->mcElements = pvec->mcCapacity = 0; \ 170 pvec->mcbElement = cbElement; \ 171 pvec->muTypeHash = uTypeHash; \ 172 pvec->mpfnCleanup = pfnCleanup ? pfnCleanup : vecNoCleanup; \ 173 pvec->mpvaElements = NULL; 174 175 /** Initialise a vector. */ 176 DECLINLINE(void) vecInitObj(VECTOR_OBJ *pvec, size_t cbElement, 177 unsigned uTypeHash, void (*pfnCleanup)(void *)) 178 { 179 VEC_INIT(pvec, cbElement, uTypeHash, pfnCleanup) 180 } 181 182 /** Initialise a pointer vector. */ 183 DECLINLINE(void) vecInitPtr(VECTOR_PTR *pvec, size_t cbElement, 184 unsigned uTypeHash, void (*pfnCleanup)(void *)) 185 { 186 VEC_INIT(pvec, cbElement, uTypeHash, pfnCleanup) 187 } 188 189 /** Add an element onto the end of a vector */ 190 DECLINLINE(int) vecPushBackObj(VECTOR_OBJ *pvec, unsigned uTypeHash, 191 void *pvElement) 192 { 193 int rc2; 194 AssertReturn(pvec->muTypeHash == uTypeHash, VERR_INVALID_PARAMETER); 195 if ( pvec->mcElements == pvec->mcCapacity 196 && RT_FAILURE((rc2 = VEC_EXPAND(pvec)))) 197 return rc2; 198 memcpy(VEC_GET_ELEMENT_OBJ(pvec->mpvaElements, pvec->mcbElement, 199 pvec->mcElements), pvElement, pvec->mcbElement); 200 ++pvec->mcElements; 201 return VINF_SUCCESS; 202 } 203 204 /** Add a pointer onto the end of a pointer vector */ 205 DECLINLINE(int) vecPushBackPtr(VECTOR_PTR *pvec, unsigned uTypeHash, 206 void *pv) 207 { 208 int rc2; 209 AssertReturn(pvec->muTypeHash == uTypeHash, VERR_INVALID_PARAMETER); 210 if ( pvec->mcElements == pvec->mcCapacity 211 && RT_FAILURE((rc2 = VEC_EXPAND(pvec)))) 212 return rc2; 213 VEC_GET_ELEMENT_PTR(pvec->mpvaElements, pvec->mcElements) = pv; 214 ++pvec->mcElements; 215 return VINF_SUCCESS; 216 } 217 218 /******************************************************************************* 219 * Public interface macros * 220 *******************************************************************************/ 221 222 /** 223 * Initialise a vector structure. Always succeeds. 224 * @param pvec pointer to an uninitialised vector structure 225 * @param type the type of the objects in the vector. As this is 226 * hashed by the preprocessor use of space etc is 227 * important. 228 * @param pfnCleanup cleanup function (void (*pfn)(void *)) that is called 229 * on a pointer to a vector element when that element is 230 * dropped 231 */ 232 #define VEC_INIT_OBJ(pvec, type, pfnCleanup) \ 233 vecInitObj(pvec, sizeof(type), VECTOR_TOKEN_HASH(type), \ 234 (void (*)(void*)) pfnCleanup) 235 236 /** 237 * Initialise a vector-of-pointers structure. Always succeeds. 238 * @param pvec pointer to an uninitialised vector structure 239 * @param type the type of the pointers in the vector, including the 240 * final "*". As this is hashed by the preprocessor use 241 * of space etc is important. 242 * @param pfnCleanup cleanup function (void (*pfn)(void *)) that is called 243 * directly on a vector element when that element is 244 * dropped 245 */ 246 #define VEC_INIT_PTR(pvec, type, pfnCleanup) \ 247 vecInitPtr(pvec, sizeof(type), VECTOR_TOKEN_HASH(type), \ 248 (void (*)(void*)) pfnCleanup) 249 250 /** 251 * Clean up a vector. 252 * @param pvec pointer to the vector to clean up. The clean up function 253 * specified at initialisation (if any) is called for each element 254 * in the vector. After clean up, the vector structure is invalid 255 * until it is re-initialised 256 */ 257 #define VEC_CLEANUP_OBJ vecCleanupObj 258 259 /** 260 * Clean up a vector-of-pointers. 261 * @param pvec pointer to the vector to clean up. The clean up function 262 * specified at initialisation (if any) is called for each element 263 * in the vector. After clean up, the vector structure is invalid 264 * until it is re-initialised 265 */ 266 #define VEC_CLEANUP_PTR vecCleanupPtr 267 268 /** 269 * Reinitialises a vector structure to empty. 270 * @param pvec pointer to the vector to re-initialise. The clean up function 271 * specified at initialisation (if any) is called for each element 272 * in the vector. 273 */ 274 #define VEC_CLEAR_OBJ vecClearObj 275 276 /** 277 * Reinitialises a vector-of-pointers structure to empty. 278 * @param pvec pointer to the vector to re-initialise. The clean up function 279 * specified at initialisation (if any) is called for each element 280 * in the vector. 281 */ 282 #define VEC_CLEAR_PTR vecClearPtr 283 284 /** 285 * Adds an element to the back of a vector. The element will be byte-copied 286 * and become owned by the vector, to be cleaned up by the vector's clean-up 287 * routine when the element is dropped. 288 * @returns iprt status code (VINF_SUCCESS or VERR_NO_MEMORY) 289 * @returns VERR_INVALID_PARAMETER if the type does not match the type given 290 * when the vector was initialised (asserted) 291 * @param pvec pointer to the vector on to which the element should be 292 * added 293 * @param type the type of the vector as specified at initialisation. 294 * Spacing etc is important. 295 * @param pvElement void pointer to the element to be added 296 */ 297 #define VEC_PUSH_BACK_OBJ(pvec, type, pvElement) \ 298 vecPushBackObj(pvec, VECTOR_TOKEN_HASH(type), \ 299 (pvElement) + ((pvElement) - (type *)(pvElement))) 300 301 /** 302 * Adds a pointer to the back of a vector-of-pointers. The pointer will become 303 * owned by the vector, to be cleaned up by the vector's clean-up routine when 304 * it is dropped. 305 * @returns iprt status code (VINF_SUCCESS or VERR_NO_MEMORY) 306 * @returns VERR_INVALID_PARAMETER if the type does not match the type given 307 * when the vector was initialised (asserted) 308 * @param pvec pointer to the vector on to which the element should be 309 * added 310 * @param type the type of the vector as specified at initialisation. 311 * Spacing etc is important. 312 * @param pvElement the pointer to be added, typecast to pointer-to-void 313 */ 314 #define VEC_PUSH_BACK_PTR(pvec, type, pvElement) \ 315 vecPushBackPtr(pvec, VECTOR_TOKEN_HASH(type), \ 316 (pvElement) + ((pvElement) - (type)(pvElement))) 317 318 /** 319 * Returns the count of elements in a vector. 320 * @param pvec pointer to the vector. 321 */ 322 #define VEC_SIZE_OBJ(pvec) (pvec)->mcElements 323 324 /** 325 * Returns the count of elements in a vector-of-pointers. 326 * @param pvec pointer to the vector. 327 */ 328 #define VEC_SIZE_PTR VEC_SIZE_OBJ 329 330 /** 331 * Iterates over the vector elements from first to last and execute the 332 * following instruction or block on each iteration with @a pIterator set to 333 * point to the current element (that is, a pointer to the pointer element for 334 * a vector-of-pointers). Use in the same way as a "for" statement. 335 * @param pvec pointer to the vector to be iterated over 336 * @param type the type of the vector, must match the type specified at 337 * vector initialisation (including whitespace etc) 338 * @todo can we assert the correctness of the type in some way? 339 * @param pIterator a pointer to @a type which will be set to point to the 340 * current vector element on each iteration 341 */ 342 #define VEC_FOR_EACH(pvec, type, pIterator) \ 343 for (pIterator = (type *) (pvec)->mpvaElements; \ 344 (pvec)->muTypeHash == VECTOR_TOKEN_HASH(type) \ 345 && pIterator < (type *) (pvec)->mpvaElements + (pvec)->mcElements; \ 346 ++pIterator) 347 348 #endif /* MAIN_VECTOR_H */ 335 return RTMemRealloc(pv, cbNew); 336 } 337 338 /** 339 * Declarator macro - declare a vector type (see @a RTVEC_DECL_ALLOCATOR) 340 * using RTMemRealloc as a memory allocator 341 * @param name the name of the C struct type describing the vector as 342 * well as the prefix of the functions for manipulating it 343 * @param type the type of the objects contained in the vector 344 */ 345 #define RTVEC_DECL(name, type) \ 346 RTVEC_DECL_ALLOCATOR(name, type, rtvecReallocDefTag) 347 348 /** 349 * Declarator macro - declare a vector type with a cleanup by pointer callback 350 * (see @a RTVEC_DECL_ALLOCATOR_DELETE) using RTMemRealloc as a memory 351 * allocator 352 * @param name the name of the C struct type describing the vector as 353 * well as the prefix of the functions for manipulating it 354 * @param type the type of the objects contained in the vector 355 * @param pfnDelete the cleanup callback function - signature 356 * void pfnDelete(type *) 357 */ 358 #define RTVEC_DECL_DELETE(name, type, pfnDelete) \ 359 RTVEC_DECL_ALLOCATOR_DELETE(name, type, rtvecReallocDefTag, pfnDelete) 360 361 /** 362 * Declarator macro - declare a vector type with a cleanup by value callback 363 * (see @a RTVEC_DECL_ALLOCATOR_DELETE_BY_VALUE) using RTMemRealloc as a memory 364 * allocator 365 * @param name the name of the C struct type describing the vector as 366 * well as the prefix of the functions for manipulating it 367 * @param type the type of the objects contained in the vector 368 * @param pfnDelete the cleanup callback function - signature 369 * void pfnDelete(type) 370 */ 371 #define RTVEC_DECL_DELETE_BY_VALUE(name, type, pfnDelete) \ 372 RTVEC_DECL_ALLOCATOR_DELETE_BY_VALUE(name, type, rtvecReallocDefTag, \ 373 pfnDelete) 374 375 #endif /* ___iprt_vector_h */
Note:
See TracChangeset
for help on using the changeset viewer.