VirtualBox

source: vbox/trunk/include/iprt/cpp/restarray.h@ 74075

Last change on this file since 74075 was 74025, checked in by vboxsync, 7 years ago

IPRT/rest: split up restbase.h into several files to make it more managable. bugref:9167

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.3 KB
Line 
1/** @file
2 * IPRT - C++ Representational State Transfer (REST) Array Template Class.
3 */
4
5/*
6 * Copyright (C) 2008-2018 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_restarray_h
27#define ___iprt_cpp_restarray_h
28
29#include <iprt/cpp/restbase.h>
30
31
32/** @defgroup grp_rt_cpp_restarray C++ Representational State Transfer (REST) Array Template Class.
33 * @ingroup grp_rt_cpp
34 * @{
35 */
36
37/**
38 * Abstract base class for the RTCRestArray template.
39 */
40class RT_DECL_CLASS RTCRestArrayBase : public RTCRestObjectBase
41{
42public:
43 /** Default destructor. */
44 RTCRestArrayBase();
45 /** Destructor. */
46 virtual ~RTCRestArrayBase();
47
48 /* Overridden methods: */
49 virtual int resetToDefault() RT_OVERRIDE;
50 virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
51 virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
52 virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const RT_OVERRIDE;
53 virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
54 uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
55 virtual kTypeClass typeClass(void) const RT_OVERRIDE;
56 virtual const char *typeName(void) const RT_OVERRIDE;
57
58 /**
59 * Clear the content of the map.
60 */
61 void clear();
62
63 /**
64 * Check if an list contains any items.
65 *
66 * @return True if there is more than zero items, false otherwise.
67 */
68 bool isEmpty() const
69 {
70 return m_cElements == 0;
71 }
72
73 /**
74 * Gets the number of entries in the map.
75 */
76 size_t size() const
77 {
78 return m_cElements;
79 }
80
81 /**
82 * Returns the base object pointer at a given index.
83 *
84 * @returns The base object at @a a_idx, NULL if out of range.
85 * @param a_idx The array index.
86 */
87 RTCRestObjectBase *atBase(size_t a_idx)
88 {
89 if (a_idx < m_cElements)
90 return m_papElements[a_idx];
91 return NULL;
92 }
93
94 /**
95 * Returns the const base object pointer at a given index.
96 *
97 * @returns The base object at @a a_idx, NULL if out of range.
98 * @param a_idx The array index.
99 */
100 RTCRestObjectBase const *atBase(size_t a_idx) const
101 {
102 if (a_idx < m_cElements)
103 return m_papElements[a_idx];
104 return NULL;
105 }
106
107 /**
108 * Removes the element at @a a_idx.
109 * @returns true if @a a_idx is valid, false if out of range.
110 * @param a_idx The index of the element to remove.
111 * The value ~(size_t)0 is an alias for the final element.
112 */
113 bool removeAt(size_t a_idx);
114
115 /**
116 * Makes sure the array can hold at the given number of entries.
117 *
118 * @returns VINF_SUCCESS or VERR_NO_MEMORY.
119 * @param a_cEnsureCapacity The number of elements to ensure capacity to hold.
120 */
121 int ensureCapacity(size_t a_cEnsureCapacity);
122
123
124protected:
125 /** The array. */
126 RTCRestObjectBase **m_papElements;
127 /** Number of elements in the array. */
128 size_t m_cElements;
129 /** The number of elements m_papElements can hold.
130 * The difference between m_cCapacity and m_cElements are all NULLs. */
131 size_t m_cCapacity;
132
133 /**
134 * Wrapper around the value constructor.
135 *
136 * @returns Pointer to new value object on success, NULL if out of memory.
137 */
138 virtual RTCRestObjectBase *createValue(void) = 0;
139
140 /**
141 * Wrapper around the value copy constructor.
142 *
143 * @returns Pointer to copy on success, NULL if out of memory.
144 * @param a_pSrc The value to copy.
145 */
146 virtual RTCRestObjectBase *createValueCopy(RTCRestObjectBase const *a_pSrc) = 0;
147
148 /**
149 * Worker for the copy constructor and the assignment operator.
150 *
151 * This will use createEntryCopy to do the copying.
152 *
153 * @returns VINF_SUCCESS on success, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
154 * @param a_rThat The array to copy. Caller makes 100% sure the it has
155 * the same type as the destination.
156 * @param a_fThrow Whether to throw error.
157 */
158 int copyArrayWorker(RTCRestArrayBase const &a_rThat, bool a_fThrow);
159
160 /**
161 * Worker for performing inserts.
162 *
163 * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
164 * VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
165 * @param a_idx Where to insert it. The value ~(size_t)0 is an alias for m_cElements.
166 * @param a_pValue The value to insert. Ownership is transferred to the map on success.
167 * @param a_fReplace Whether to replace existing entry rather than insert.
168 */
169 int insertWorker(size_t a_idx, RTCRestObjectBase *a_pValue, bool a_fReplace);
170
171 /**
172 * Worker for performing inserts.
173 *
174 * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
175 * VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
176 * @param a_idx Where to insert it. The value ~(size_t)0 is an alias for m_cElements.
177 * @param a_rValue The value to copy into the map.
178 * @param a_fReplace Whether to replace existing key-value pair with matching key.
179 */
180 int insertCopyWorker(size_t a_idx, RTCRestObjectBase const &a_rValue, bool a_fReplace);
181
182private:
183 /** Copy constructor on this class should never be used. */
184 RTCRestArrayBase(RTCRestArrayBase const &a_rThat);
185 /** Copy assignment operator on this class should never be used. */
186 RTCRestArrayBase &operator=(RTCRestArrayBase const &a_rThat);
187};
188
189
190
191/**
192 * Limited array class.
193 */
194template<class ElementType> class RTCRestArray : public RTCRestArrayBase
195{
196public:
197 /** Default constructor - empty array. */
198 RTCRestArray()
199 : RTCRestArrayBase()
200 {
201 }
202
203 /** Destructor. */
204 ~RTCRestArray()
205 {
206 }
207
208 /** Copy constructor. */
209 RTCRestArray(RTCRestArray const &a_rThat)
210 : RTCRestArrayBase()
211 {
212 copyArrayWorker(a_rThat, true /*fThrow*/);
213 }
214
215 /** Copy assignment operator. */
216 RTCRestArray &operator=(RTCRestArray const &a_rThat)
217 {
218 copyArrayWorker(a_rThat, true /*fThrow*/);
219 return *this;
220 }
221
222 /** Safe copy assignment method. */
223 int assignCopy(RTCRestArray const &a_rThat)
224 {
225 return copyArrayWorker(a_rThat, false /*fThrow*/);
226 }
227
228 /** Factory method. */
229 static DECLCALLBACK(RTCRestObjectBase *) createInstance(void)
230 {
231 return new (std::nothrow) RTCRestArray<ElementType>();
232 }
233
234 /** Factory method for elements. */
235 static DECLCALLBACK(RTCRestObjectBase *) createElementInstance(void)
236 {
237 return new (std::nothrow) ElementType();
238 }
239
240
241 /**
242 * Insert the given object at the specified index.
243 *
244 * @returns VINF_SUCCESS on success.
245 * VERR_INVALID_POINTER, VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
246 * @param a_idx The insertion index. ~(size_t)0 is an alias for the end.
247 * @param a_pThat The object to insert. The array takes ownership of the object on success.
248 */
249 int insert(size_t a_idx, ElementType *a_pThat)
250 {
251 return insertWorker(a_idx, a_pThat, false /*a_fReplace*/);
252 }
253
254 /**
255 * Insert a copy of the object at the specified index.
256 *
257 * @returns VINF_SUCCESS on success.
258 * VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
259 * @param a_idx The insertion index. ~(size_t)0 is an alias for the end.
260 * @param a_rThat The object to insert a copy of.
261 */
262 int insertCopy(size_t a_idx, ElementType const &a_rThat)
263 {
264 return insertCopyWorker(a_idx, a_rThat, false /*a_fReplace*/);
265 }
266
267 /**
268 * Appends the given object to the array.
269 *
270 * @returns VINF_SUCCESS on success.
271 * VERR_INVALID_POINTER, VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
272 * @param a_pThat The object to insert. The array takes ownership of the object on success.
273 */
274 int append(ElementType *a_pThat)
275 {
276 return insertWorker(~(size_t)0, a_pThat, false /*a_fReplace*/);
277 }
278
279 /**
280 * Appends a copy of the object at the specified index.
281 *
282 * @returns VINF_SUCCESS on success.
283 * VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
284 * @param a_rThat The object to insert a copy of.
285 */
286 int appendCopy(ElementType const &a_rThat)
287 {
288 return insertCopyWorker(~(size_t)0, a_rThat, false /*a_fReplace*/);
289 }
290
291 /**
292 * Prepends the given object to the array.
293 *
294 * @returns VINF_SUCCESS on success.
295 * VERR_INVALID_POINTER, VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
296 * @param a_pThat The object to insert. The array takes ownership of the object on success.
297 */
298 int prepend(ElementType *a_pThat)
299 {
300 return insertWorker(0, a_pThat, false /*a_fReplace*/);
301 }
302
303 /**
304 * Prepends a copy of the object at the specified index.
305 *
306 * @returns VINF_SUCCESS on success.
307 * VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
308 * @param a_rThat The object to insert a copy of.
309 */
310 int prependCopy(ElementType const &a_rThat)
311 {
312 return insertCopyWorker(0, a_rThat, false /*a_fReplace*/);
313 }
314
315 /**
316 * Insert the given object at the specified index.
317 *
318 * @returns VINF_SUCCESS on success.
319 * VERR_INVALID_POINTER, VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
320 * @param a_idx The index of the existing object to replace.
321 * @param a_pThat The replacement object. The array takes ownership of the object on success.
322 */
323 int replace(size_t a_idx, ElementType *a_pThat)
324 {
325 return insertWorker(a_idx, a_pThat, true /*a_fReplace*/);
326 }
327
328 /**
329 * Insert a copy of the object at the specified index.
330 *
331 * @returns VINF_SUCCESS on success.
332 * VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
333 * @param a_idx The index of the existing object to replace.
334 * @param a_rThat The object to insert a copy of.
335 */
336 int replaceCopy(size_t a_idx, ElementType const &a_rThat)
337 {
338 return insertCopyWorker(a_idx, a_rThat, true /*a_fReplace*/);
339 }
340
341 /**
342 * Returns the object at a given index.
343 *
344 * @returns The object at @a a_idx, NULL if out of range.
345 * @param a_idx The array index.
346 */
347 ElementType *at(size_t a_idx)
348 {
349 if (a_idx < m_cElements)
350 return (ElementType *)m_papElements[a_idx];
351 return NULL;
352 }
353
354 /**
355 * Returns the object at a given index, const variant.
356 *
357 * @returns The object at @a a_idx, NULL if out of range.
358 * @param a_idx The array index.
359 */
360 ElementType const *at(size_t a_idx) const
361 {
362 if (a_idx < m_cElements)
363 return (ElementType const *)m_papElements[a_idx];
364 return NULL;
365 }
366
367 /**
368 * Returns the first object in the array.
369 * @returns The first object, NULL if empty.
370 */
371 ElementType *first()
372 {
373 return at(0);
374 }
375
376 /**
377 * Returns the first object in the array, const variant.
378 * @returns The first object, NULL if empty.
379 */
380 ElementType const *first() const
381 {
382 return at(0);
383 }
384
385 /**
386 * Returns the last object in the array.
387 * @returns The last object, NULL if empty.
388 */
389 ElementType *last()
390 {
391 return at(m_cElements - 1);
392 }
393
394 /**
395 * Returns the last object in the array, const variant.
396 * @returns The last object, NULL if empty.
397 */
398 ElementType const *last() const
399 {
400 return at(m_cElements - 1);
401 }
402
403
404protected:
405 virtual RTCRestObjectBase *createValue(void) RT_OVERRIDE
406 {
407 return new (std::nothrow) ElementType();
408 }
409
410 virtual RTCRestObjectBase *createValueCopy(RTCRestObjectBase const *a_pSrc) RT_OVERRIDE
411 {
412 ElementType *pCopy = new (std::nothrow) ElementType();
413 if (pCopy)
414 {
415 int rc = pCopy->assignCopy(*(ElementType const *)a_pSrc);
416 if (RT_SUCCESS(rc))
417 return pCopy;
418 delete pCopy;
419 }
420 return NULL;
421 }
422};
423
424
425/** @} */
426
427#endif
428
Note: See TracBrowser for help on using the repository browser.

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