VirtualBox

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

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

Main/HostHardwareLinux: switch the stl vectors to a C implementation

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