VirtualBox

source: vbox/trunk/src/VBox/Main/include/vector.h@ 31676

Last change on this file since 31676 was 31663, checked in by vboxsync, 14 years ago

Main: header fixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.1 KB
Line 
1/** @file
2 * STL-like vector implementation in C
3 * @note functions in this file are inline to prevent warnings about
4 * unused static functions. I assume that in this day and age a
5 * compiler makes its own decisions about whether to actually
6 * inline a function.
7 */
8
9/*
10 * Copyright (C) 2008-2010 Oracle Corporation
11 *
12 * This file is part of VirtualBox Open Source Edition (OSE), as
13 * available from http://www.virtualbox.org. This file is free software;
14 * you can redistribute it and/or modify it under the terms of the GNU
15 * General Public License (GPL) as published by the Free Software
16 * Foundation, in version 2 as it comes in the "COPYING" file of the
17 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19 */
20
21#define VECTOR_CONCAT(a, b) a ## b
22#define VECTOR_XCONCAT(a, b) VECTOR_CONCAT(a, b)
23/** A publicly visible (method, type, etc) name relating to the vector type */
24#define VECTOR_PUBLIC(NAME) VECTOR_XCONCAT(VECTOR_TYPENAME, _ ## NAME)
25/** An implementation-private (method, type, etc) name */
26#define VECTOR_INTERNAL(NAME) VECTOR_XCONCAT(VECTOR_TYPENAME, _internal_ ## NAME)
27/** The size of a vector element */
28#define VECTOR_ELEMENT_SIZE sizeof(VECTOR_TYPE)
29/** The unit by which the vector capacity is increased */
30#define VECTOR_ALLOC_UNIT VECTOR_ELEMENT_SIZE * 16
31
32#ifndef VECTOR_TYPE
33/** VECTOR_TYPE must be defined to the type that the vector will contain. The
34 * macro will be undef-ed again by this header. */
35# error You must define VECTOR_TYPE before including this header!
36#endif
37#ifndef VECTOR_TYPENAME
38/** VECTOR_TYPENAME must be defined to the typename for the vector. The
39 * macro will be undef-ed again by this header. */
40# error You must define VECTOR_TYPENAME before including this header!
41#endif
42#ifndef VECTOR_ALLOCATOR
43/** VECTOR_ALLOCATOR can be defined to an alternative allocator for the
44 * vector's memory. The allocator must be a function with realloc semantics.
45 * The macro will be undef-ed again by this header. */
46# define VECTOR_ALLOCATOR RTMemRealloc
47#endif
48#ifndef VECTOR_DESTRUCTOR
49/** VECTOR_DESTRUCTOR can be defined to be a routine to clean up vector
50 * elements before they are freed. It must return void and take a pointer to
51 * an element as a parameter. The macro will be undef-ed again by this header.
52 */
53# define VECTOR_DESTRUCTOR VECTOR_INTERNAL(empty_destructor)
54#endif
55
56/** Structure describing the vector itself */
57typedef struct VECTOR_TYPENAME
58{
59 /** The beginning of the allocated memory */
60 VECTOR_TYPE *mBegin;
61 /** Pointer to just after the end of the last element */
62 VECTOR_TYPE *mEnd;
63 /** Pointer to just after the end of the allocated memory */
64 VECTOR_TYPE *mCapacity;
65} VECTOR_TYPENAME;
66
67/*** Private methods ***/
68
69/** Destructor that does nothing. */
70static inline void VECTOR_INTERNAL(empty_destructor)(VECTOR_TYPENAME *pSelf)
71{
72 (void) pSelf;
73}
74
75/** Expand an existing vector */
76static inline int VECTOR_INTERNAL(expand)(VECTOR_TYPENAME *pSelf)
77{
78 size_t cNewCap = pSelf->mCapacity - pSelf->mBegin + VECTOR_ALLOC_UNIT;
79 size_t cOffEnd = pSelf->mEnd - pSelf->mBegin;
80 void *pRealloc = VECTOR_ALLOCATOR(pSelf->mBegin, cNewCap);
81 if (!pRealloc)
82 return 0;
83 pSelf->mBegin = (VECTOR_TYPE *)pRealloc;
84 pSelf->mEnd = pSelf->mBegin + cOffEnd;
85 pSelf->mCapacity = pSelf->mBegin + cNewCap / VECTOR_ELEMENT_SIZE;
86 memset(pSelf->mEnd, 0, pSelf->mCapacity - pSelf->mEnd);
87 return 1;
88}
89
90/** Expand an existing vector */
91static inline void VECTOR_INTERNAL(destruct_all)(VECTOR_TYPENAME *pSelf)
92{
93 VECTOR_TYPE *pIter;
94 for (pIter = pSelf->mBegin; pIter < pSelf->mEnd; ++pIter)
95 VECTOR_DESTRUCTOR(pIter);
96}
97
98/*** Public methods ***/
99
100/** Initialise a newly allocated vector. The vector will be zeroed on failure.
101 */
102static inline int VECTOR_PUBLIC(init)(VECTOR_TYPENAME *pSelf)
103{
104 memset(pSelf, 0, sizeof(*pSelf));
105 return VECTOR_INTERNAL(expand)(pSelf);
106}
107
108/** Clean up a vector so that the memory can be returned. For convenience,
109 * this may be used safely on a zeroed vector structure. */
110static inline void VECTOR_PUBLIC(cleanup)(VECTOR_TYPENAME *pSelf)
111{
112 if (pSelf->mBegin)
113 {
114 VECTOR_INTERNAL(destruct_all)(pSelf);
115 VECTOR_ALLOCATOR(pSelf->mBegin, 0);
116 }
117 pSelf->mBegin = pSelf->mEnd = pSelf->mCapacity = NULL;
118}
119
120/** Add a value onto the end of a vector */
121static inline int VECTOR_PUBLIC(push_back)(VECTOR_TYPENAME *pSelf,
122 VECTOR_TYPE *pElement)
123{
124 if (pSelf->mEnd == pSelf->mCapacity && !VECTOR_INTERNAL(expand)(pSelf))
125 return 0;
126 if (pElement)
127 *pSelf->mEnd = *pElement;
128 ++pSelf->mEnd;
129 return 1;
130}
131
132/** Reset the vector */
133static inline void VECTOR_PUBLIC(clear)(VECTOR_TYPENAME *pSelf)
134{
135 VECTOR_INTERNAL(destruct_all)(pSelf);
136 memset(pSelf->mBegin, 0, pSelf->mEnd - pSelf->mBegin);
137 pSelf->mEnd = pSelf->mBegin;
138}
139
140/** Number of elements in the vector */
141static inline size_t VECTOR_PUBLIC(size)(VECTOR_TYPENAME *pSelf)
142{
143 return (pSelf->mEnd - pSelf->mBegin) / VECTOR_ELEMENT_SIZE;
144}
145
146/*** Iterators ***/
147
148/** Non-constant iterator over the vector */
149typedef VECTOR_TYPE *VECTOR_PUBLIC(iterator);
150
151/** Initialise a newly allocated iterator */
152static inline void VECTOR_PUBLIC(iter_init)(VECTOR_PUBLIC(iterator) *pSelf,
153 const VECTOR_PUBLIC(iterator) *pOther)
154{
155 *pSelf = *pOther;
156}
157
158/** Dereference an iterator */
159static inline VECTOR_TYPE *VECTOR_PUBLIC(iter_target)(VECTOR_PUBLIC(iterator) *pSelf)
160{
161 return *pSelf;
162}
163
164/** Increment an iterator */
165static inline void VECTOR_PUBLIC(iter_incr)(VECTOR_PUBLIC(iterator) *pSelf)
166{
167 ++*pSelf;
168}
169
170/** Get the special "begin" iterator for a vector */
171static inline const VECTOR_PUBLIC(iterator) *VECTOR_PUBLIC(begin)
172 (VECTOR_TYPENAME *pSelf)
173{
174 return &pSelf->mBegin;
175}
176
177/** Get the special "end" iterator for a vector */
178static inline const VECTOR_PUBLIC(iterator) *VECTOR_PUBLIC(end)
179 (VECTOR_TYPENAME *pSelf)
180{
181 return &pSelf->mEnd;
182}
183
184/** Test whether an iterator is less than another. */
185static inline int VECTOR_PUBLIC(iter_lt)(const VECTOR_PUBLIC(iterator) *pFirst,
186 const VECTOR_PUBLIC(iterator) *pSecond)
187{
188 return *pFirst < *pSecond;
189}
190
191/** Test whether an iterator is equal to another. The special values
192 * ITERATOR_BEGIN and ITERATOR_END are recognised. */
193static inline int VECTOR_PUBLIC(iter_eq)(const VECTOR_PUBLIC(iterator) *pFirst,
194 const VECTOR_PUBLIC(iterator) *pSecond)
195{
196 return *pFirst == *pSecond;
197}
198
199/* We need to undefine anything we have defined (and for convenience we also
200 * undefine our "parameter" macros) as this header may be included multiple
201 * times in one source file with different parameters. */
202#undef VECTOR_CONCAT
203#undef VECTOR_XCONCAT
204#undef VECTOR_PUBLIC
205#undef VECTOR_INTERN
206#undef VECTOR_ELEMENT_SIZE
207#undef VECTOR_ALLOC_UNIT
208#undef VECTOR_TYPE
209#undef VECTOR_TYPENAME
210#undef VECTOR_ALLOCATOR
211#undef VECTOR_DESTRUCTOR
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