VirtualBox

source: vbox/trunk/include/iprt/nocrt/vector@ 96407

Last change on this file since 96407 was 96407, checked in by vboxsync, 2 years ago

scm copyright and license note update

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.4 KB
Line 
1/** @file
2 * IPRT / No-CRT - Minimal C++ std::vector.
3 */
4
5/*
6 * Copyright (C) 2022 Oracle and/or its affiliates.
7 *
8 * This file is part of VirtualBox base platform packages, as
9 * available from https://www.virtualbox.org.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation, in version 3 of the
14 * License.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, see <https://www.gnu.org/licenses>.
23 *
24 * The contents of this file may alternatively be used under the terms
25 * of the Common Development and Distribution License Version 1.0
26 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
27 * in the VirtualBox distribution, in which case the provisions of the
28 * CDDL are applicable instead of those of the GPL.
29 *
30 * You may elect to license modified versions of this file under the
31 * terms and conditions of either the GPL or the CDDL or both.
32 *
33 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
34 */
35
36#ifndef VBOX_INCLUDED_SRC_nocrt_vector
37#define VBOX_INCLUDED_SRC_nocrt_vector
38#ifndef RT_WITHOUT_PRAGMA_ONCE
39# pragma once
40#endif
41
42#include <iprt/nocrt/memory>
43
44namespace std
45{
46 template<typename a_Type, class a_Container>
47 class RTCNoCrtVectorIterator
48 {
49 public:
50 typedef a_Type &reference;
51 typedef a_Type *pointer;
52 typedef typename a_Container::difference_type difference_type;
53
54 protected:
55 a_Type *m_pItem;
56
57 public:
58 RTCNoCrtVectorIterator() RT_NOEXCEPT
59 : m_pItem(NULL)
60 { }
61
62 RTCNoCrtVectorIterator(a_Type *a_pItem) RT_NOEXCEPT
63 : m_pItem(a_pItem)
64 { }
65
66 ~RTCNoCrtVectorIterator()
67 {
68 m_pItem = NULL;
69 }
70
71 /** @name Moving the iterator.
72 * @{ */
73
74 RTCNoCrtVectorIterator &operator++() RT_NOEXCEPT
75 {
76 ++m_pItem;
77 return *this;
78 }
79
80 RTCNoCrtVectorIterator &operator--() RT_NOEXCEPT
81 {
82 --m_pItem;
83 return *this;
84 }
85
86 RTCNoCrtVectorIterator operator++(int) RT_NOEXCEPT
87 {
88 return RTCNoCrtVectorIterator(m_pItem++);
89 }
90
91 RTCNoCrtVectorIterator operator--(int) RT_NOEXCEPT
92 {
93 return RTCNoCrtVectorIterator(m_pItem--);
94 }
95
96 RTCNoCrtVectorIterator &operator+=(difference_type cItems) RT_NOEXCEPT
97 {
98 m_pItem += cItems;
99 return *this;
100 }
101
102 RTCNoCrtVectorIterator &operator-=(difference_type cItems) RT_NOEXCEPT
103 {
104 m_pItem -= cItems;
105 return *this;
106 }
107
108 RTCNoCrtVectorIterator operator+(difference_type cItems) const RT_NOEXCEPT
109 {
110 return RTCNoCrtVectorIterator(m_pItem + cItems);
111 }
112
113 RTCNoCrtVectorIterator operator-(difference_type cItems) const RT_NOEXCEPT
114 {
115 return RTCNoCrtVectorIterator(m_pItem - cItems);
116 }
117
118 /** @} */
119
120 /** @name Item access
121 * @{ */
122 typename reference operator*() const RT_NOEXCEPT
123 {
124 return *m_pItem;
125 }
126
127 pointer operator->() const RT_NOEXCEPT
128 {
129 return m_pItem;
130 }
131
132 reference operator[](difference_type iItem) const RT_NOEXCEPT
133 {
134 return m_pItem[iItem];
135 }
136
137 /** @} */
138
139 /** Helper for const/non-const iterator comparisons: */
140 inline typename a_Container::const_pointer getConst() const RT_NOEXCEPT
141 {
142 return m_pItem;
143 }
144 };
145
146 template<typename a_TypeLeft, typename a_TypeRight, class a_Container>
147 inline bool operator==(const RTCNoCrtVectorIterator<a_TypeLeft, a_Container> &a_rLeft,
148 const RTCNoCrtVectorIterator<a_TypeRight, a_Container> &a_rRight) RT_NOEXCEPT
149 {
150 return a_rLeft.getConst() == a_rRight.getConst();
151 }
152
153 template<typename a_TypeLeft, typename a_TypeRight, class a_Container>
154 inline bool operator!=(const RTCNoCrtVectorIterator<a_TypeLeft, a_Container> &a_rLeft,
155 const RTCNoCrtVectorIterator<a_TypeRight, a_Container> &a_rRight) RT_NOEXCEPT
156 {
157 return a_rLeft.getConst() == a_rRight.getConst();
158 }
159
160 template<typename a_TypeLeft, typename a_TypeRight, class a_Container>
161 inline bool operator<(const RTCNoCrtVectorIterator<a_TypeLeft, a_Container> &a_rLeft,
162 const RTCNoCrtVectorIterator<a_TypeRight, a_Container> &a_rRight) RT_NOEXCEPT
163 {
164 return (uintptr_t)a_rLeft.getConst() < (uintptr_t)a_rRight.getConst();
165 }
166
167 template<typename a_TypeLeft, typename a_TypeRight, class a_Container>
168 inline bool operator<=(const RTCNoCrtVectorIterator<a_TypeLeft, a_Container> &a_rLeft,
169 const RTCNoCrtVectorIterator<a_TypeRight, a_Container> &a_rRight) RT_NOEXCEPT
170 {
171 return (uintptr_t)a_rLeft.getConst() <= (uintptr_t)a_rRight.getConst();
172 }
173
174 template<typename a_TypeLeft, typename a_TypeRight, class a_Container>
175 inline bool operator>(const RTCNoCrtVectorIterator<a_TypeLeft, a_Container> &a_rLeft,
176 const RTCNoCrtVectorIterator<a_TypeRight, a_Container> &a_rRight) RT_NOEXCEPT
177 {
178 return (uintptr_t)a_rLeft.getConst() > (uintptr_t)a_rRight.getConst();
179 }
180
181 template<typename a_TypeLeft, typename a_TypeRight, class a_Container>
182 inline bool operator>=(const RTCNoCrtVectorIterator<a_TypeLeft, a_Container> &a_rLeft,
183 const RTCNoCrtVectorIterator<a_TypeRight, a_Container> &a_rRight) RT_NOEXCEPT
184 {
185 return (uintptr_t)a_rLeft.getConst() >= (uintptr_t)a_rRight.getConst();
186 }
187
188
189
190 template<class a_Type, class a_Allocator = std::allocator<a_Type> >
191 class vector
192 {
193 public:
194 typedef a_Type value_type;
195 typedef a_Type &reference;
196 typedef a_Type const &const_reference;
197 typedef a_Allocator allocator_type;
198 typedef typename a_Allocator::size_type size_type;
199 typedef typename a_Allocator::difference_type difference_type;
200 typedef typename a_Allocator::pointer pointer;
201 typedef typename a_Allocator::const_pointer const_pointer;
202
203 typedef RTCNoCrtVectorIterator<a_Type, vector> iterator;
204 typedef RTCNoCrtVectorIterator<const a_Type, vector> const_iterator;
205
206 protected:
207 pointer m_paItems;
208 size_t m_cItems;
209 size_t m_cAllocated;
210 allocator_type m_Allocator;
211
212 public:
213 vector() RT_NOEXCEPT
214 : m_paItems(NULL)
215 , m_cItems(0)
216 , m_cAllocated(0)
217 { }
218
219 vector(size_type a_cAllocate)
220 : m_paItems(NULL)
221 , m_cItems(0)
222 , m_cAllocated(0)
223 {
224 m_paItems = m_Allocator.allocate(a_cAllocate);
225 if (m_paItems)
226 m_cAllocated = a_cAllocate;
227 }
228
229 ~vector()
230 {
231 size_type i = m_cItems;
232 while (i-- > 0)
233 {
234 m_Allocator.destroy(&m_paItems[i]);
235 m_cItems = i;
236 }
237 m_Allocator.deallocate(m_paItems, m_cAllocated);
238 m_paItems = NULL;
239 m_cAllocated = 0;
240 }
241
242
243 /** @name Iterators
244 * @{ */
245 iterator begin() RT_NOEXCEPT
246 {
247 return iterator(m_paItems);
248 }
249
250 const_iterator begin() const RT_NOEXCEPT
251 {
252 return const_iterator(m_paItems);
253 }
254
255 const_iterator cbegin() const RT_NOEXCEPT
256 {
257 return const_iterator(m_paItems);
258 }
259
260 iterator end() RT_NOEXCEPT
261 {
262 return iterator(&m_paItems[m_cItems]);
263 }
264
265 const_iterator end() const RT_NOEXCEPT
266 {
267 return const_iterator(&m_paItems[m_cItems]);
268 }
269
270 const_iterator cend() const RT_NOEXCEPT
271 {
272 return const_iterator(&m_paItems[m_cItems]);
273 }
274 /** @} */
275
276 /** @name Element access
277 * @{ */
278 reference operator[](size_type iItem) RT_NOEXCEPT
279 {
280 Assert(iItem < m_cAllocated);
281 return m_paItems[iItem];
282 }
283
284 const_reference operator[](size_type iItem) const RT_NOEXCEPT
285 {
286 Assert(iItem < m_cAllocated);
287 return m_paItems[iItem];
288 }
289
290 reference front() RT_NOEXCEPT
291 {
292 return m_paItems[0];
293 }
294
295 const_reference front() const RT_NOEXCEPT
296 {
297 return m_paItems[0];
298 }
299
300 reference back() RT_NOEXCEPT
301 {
302 return m_paItems[m_cItems - 1];
303 }
304
305 const_reference back() const RT_NOEXCEPT
306 {
307 return m_paItems[m_cItems - 1];
308 }
309
310 pointer data() RT_NOEXCEPT
311 {
312 return m_paItem;
313 }
314
315 const_pointer data() const RT_NOEXCEPT
316 {
317 return m_paItem;
318 }
319
320 /** @} */
321
322 /** @name Capacity
323 * @{ */
324 bool empty() const RT_NOEXCEPT
325 {
326 return m_cItems == 0;
327 }
328
329 size_type size() const RT_NOEXCEPT
330 {
331 return m_cItems;
332 }
333
334 size_type max_size() const RT_NOEXCEPT
335 {
336 return m_Allocator.max_size();
337 }
338
339 void reserve(size_type a_cNewAllocated)
340 {
341 Assert(a_cNewAllocated <= max_size());
342
343 if (a_cNewAllocated > m_cAllocated)
344 {
345 vector Temp(a_cNewAllocated);
346 if (Temp.m_paItems)
347 {
348 /* Copy over the data: */
349 size_type const cItems = m_cItems;
350 const_pointer paSrc = m_paItems;
351 pointer paDst = Temp.m_paItems;
352 for (size_type i = 0; i < cItems; Temp.m_cItems = ++i)
353 m_Allocator.construct(&paDst[i], paSrc[i]);
354
355 /* Swap the data. */
356 size_type const cOldAllocated = m_cAllocated;
357 Temp.m_paItems = m_paItems;
358 m_paItems = paDst;
359 m_cAllocated = Temp.m_cAllocated;
360 Temp.m_cAllocated = cOldAllocated;
361 }
362 }
363 }
364
365 /** @} */
366
367 /** @name Modifiers
368 * @{ */
369 void push_back(const_reference a_rValue)
370 {
371 if (m_cItems < m_cAllocated)
372 { }
373 else
374 {
375 Assert(m_cItems * 2 >= m_cItems);
376 reserve(m_cItems < 8 ? 8 : m_cItems * 2); /* This might be non-standard. */
377 AssertReturnVoid(m_cItems < m_cAllocated);
378 }
379 m_paItems[m_cItems] = a_rValue;
380 m_cItems++;
381 }
382
383 void pop_back() RT_NOEXCEPT
384 {
385 if (m_cItems > 0)
386 m_cItems -= 1;
387 }
388 /** @} */
389
390 };
391
392}
393
394#endif /* !VBOX_INCLUDED_SRC_nocrt_vector */
395
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