VirtualBox

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

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

IPRT/rest: Early support for polymorphic data objects in the data model. 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.215389.xyz. 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 RTCRestObjectBase *baseClone() const RT_OVERRIDE;
50 virtual int resetToDefault() RT_OVERRIDE;
51 virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
52 virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
53 virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const RT_OVERRIDE;
54 virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
55 uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
56 virtual kTypeClass typeClass(void) const RT_OVERRIDE;
57 virtual const char *typeName(void) const RT_OVERRIDE;
58
59 /**
60 * Clear the content of the map.
61 */
62 void clear();
63
64 /**
65 * Check if an list contains any items.
66 *
67 * @return True if there is more than zero items, false otherwise.
68 */
69 inline bool isEmpty() const
70 {
71 return m_cElements == 0;
72 }
73
74 /**
75 * Gets the number of entries in the map.
76 */
77 inline size_t size() const
78 {
79 return m_cElements;
80 }
81
82 /**
83 * Returns the base object pointer at a given index.
84 *
85 * @returns The base object at @a a_idx, NULL if out of range.
86 * @param a_idx The array index.
87 */
88 inline RTCRestObjectBase *atBase(size_t a_idx)
89 {
90 if (a_idx < m_cElements)
91 return m_papElements[a_idx];
92 return NULL;
93 }
94
95 /**
96 * Returns the const base object pointer at a given index.
97 *
98 * @returns The base object at @a a_idx, NULL if out of range.
99 * @param a_idx The array index.
100 */
101 inline RTCRestObjectBase const *atBase(size_t a_idx) const
102 {
103 if (a_idx < m_cElements)
104 return m_papElements[a_idx];
105 return NULL;
106 }
107
108 /**
109 * Removes the element at @a a_idx.
110 * @returns true if @a a_idx is valid, false if out of range.
111 * @param a_idx The index of the element to remove.
112 * The value ~(size_t)0 is an alias for the final element.
113 */
114 bool removeAt(size_t a_idx);
115
116 /**
117 * Makes sure the array can hold at the given number of entries.
118 *
119 * @returns VINF_SUCCESS or VERR_NO_MEMORY.
120 * @param a_cEnsureCapacity The number of elements to ensure capacity to hold.
121 */
122 int ensureCapacity(size_t a_cEnsureCapacity);
123
124
125protected:
126 /** The array. */
127 RTCRestObjectBase **m_papElements;
128 /** Number of elements in the array. */
129 size_t m_cElements;
130 /** The number of elements m_papElements can hold.
131 * The difference between m_cCapacity and m_cElements are all NULLs. */
132 size_t m_cCapacity;
133
134 /**
135 * Helper for creating a clone.
136 *
137 * @returns Pointer to new array on success, NULL if out of memory.
138 */
139 virtual RTCRestArrayBase *createClone(void) const = 0;
140
141 /**
142 * Wrapper around the value constructor.
143 *
144 * @returns Pointer to new value object on success, NULL if out of memory.
145 */
146 virtual RTCRestObjectBase *createValue(void) = 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 inline RTCRestArray &operator=(RTCRestArray const &a_rThat)
217 {
218 copyArrayWorker(a_rThat, true /*fThrow*/);
219 return *this;
220 }
221
222 /** Safe copy assignment method. */
223 inline int assignCopy(RTCRestArray const &a_rThat)
224 {
225 return copyArrayWorker(a_rThat, false /*fThrow*/);
226 }
227
228 /** Make a clone of this object. */
229 inline RTCRestArray *clone() const
230 {
231 return (RTCRestArray *)baseClone();
232 }
233
234 /** Factory method. */
235 static DECLCALLBACK(RTCRestObjectBase *) createInstance(void)
236 {
237 return new (std::nothrow) RTCRestArray<ElementType>();
238 }
239
240 /** Factory method for elements. */
241 static DECLCALLBACK(RTCRestObjectBase *) createElementInstance(void)
242 {
243 return new (std::nothrow) ElementType();
244 }
245
246
247 /**
248 * Insert the given object at the specified index.
249 *
250 * @returns VINF_SUCCESS on success.
251 * VERR_INVALID_POINTER, VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
252 * @param a_idx The insertion index. ~(size_t)0 is an alias for the end.
253 * @param a_pThat The object to insert. The array takes ownership of the object on success.
254 */
255 inline int insert(size_t a_idx, ElementType *a_pThat)
256 {
257 return insertWorker(a_idx, a_pThat, false /*a_fReplace*/);
258 }
259
260 /**
261 * Insert a copy of the object at the specified index.
262 *
263 * @returns VINF_SUCCESS on success.
264 * VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
265 * @param a_idx The insertion index. ~(size_t)0 is an alias for the end.
266 * @param a_rThat The object to insert a copy of.
267 */
268 inline int insertCopy(size_t a_idx, ElementType const &a_rThat)
269 {
270 return insertCopyWorker(a_idx, a_rThat, false /*a_fReplace*/);
271 }
272
273 /**
274 * Appends the given object to the array.
275 *
276 * @returns VINF_SUCCESS on success.
277 * VERR_INVALID_POINTER, VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
278 * @param a_pThat The object to insert. The array takes ownership of the object on success.
279 */
280 inline int append(ElementType *a_pThat)
281 {
282 return insertWorker(~(size_t)0, a_pThat, false /*a_fReplace*/);
283 }
284
285 /**
286 * Appends a copy of the object at the specified index.
287 *
288 * @returns VINF_SUCCESS on success.
289 * VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
290 * @param a_rThat The object to insert a copy of.
291 */
292 inline int appendCopy(ElementType const &a_rThat)
293 {
294 return insertCopyWorker(~(size_t)0, a_rThat, false /*a_fReplace*/);
295 }
296
297 /**
298 * Prepends the given object to the array.
299 *
300 * @returns VINF_SUCCESS on success.
301 * VERR_INVALID_POINTER, VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
302 * @param a_pThat The object to insert. The array takes ownership of the object on success.
303 */
304 inline int prepend(ElementType *a_pThat)
305 {
306 return insertWorker(0, a_pThat, false /*a_fReplace*/);
307 }
308
309 /**
310 * Prepends a copy of the object at the specified index.
311 *
312 * @returns VINF_SUCCESS on success.
313 * VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
314 * @param a_rThat The object to insert a copy of.
315 */
316 inline int prependCopy(ElementType const &a_rThat)
317 {
318 return insertCopyWorker(0, a_rThat, false /*a_fReplace*/);
319 }
320
321 /**
322 * Insert the given object at the specified index.
323 *
324 * @returns VINF_SUCCESS on success.
325 * VERR_INVALID_POINTER, VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
326 * @param a_idx The index of the existing object to replace.
327 * @param a_pThat The replacement object. The array takes ownership of the object on success.
328 */
329 inline int replace(size_t a_idx, ElementType *a_pThat)
330 {
331 return insertWorker(a_idx, a_pThat, true /*a_fReplace*/);
332 }
333
334 /**
335 * Insert a copy of the object at the specified index.
336 *
337 * @returns VINF_SUCCESS on success.
338 * VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
339 * @param a_idx The index of the existing object to replace.
340 * @param a_rThat The object to insert a copy of.
341 */
342 inline int replaceCopy(size_t a_idx, ElementType const &a_rThat)
343 {
344 return insertCopyWorker(a_idx, a_rThat, true /*a_fReplace*/);
345 }
346
347 /**
348 * Returns the object at a given index.
349 *
350 * @returns The object at @a a_idx, NULL if out of range.
351 * @param a_idx The array index.
352 */
353 inline ElementType *at(size_t a_idx)
354 {
355 if (a_idx < m_cElements)
356 return (ElementType *)m_papElements[a_idx];
357 return NULL;
358 }
359
360 /**
361 * Returns the object at a given index, const variant.
362 *
363 * @returns The object at @a a_idx, NULL if out of range.
364 * @param a_idx The array index.
365 */
366 inline ElementType const *at(size_t a_idx) const
367 {
368 if (a_idx < m_cElements)
369 return (ElementType const *)m_papElements[a_idx];
370 return NULL;
371 }
372
373 /**
374 * Returns the first object in the array.
375 * @returns The first object, NULL if empty.
376 */
377 inline ElementType *first()
378 {
379 return at(0);
380 }
381
382 /**
383 * Returns the first object in the array, const variant.
384 * @returns The first object, NULL if empty.
385 */
386 inline ElementType const *first() const
387 {
388 return at(0);
389 }
390
391 /**
392 * Returns the last object in the array.
393 * @returns The last object, NULL if empty.
394 */
395 inline ElementType *last()
396 {
397 return at(m_cElements - 1);
398 }
399
400 /**
401 * Returns the last object in the array, const variant.
402 * @returns The last object, NULL if empty.
403 */
404 inline ElementType const *last() const
405 {
406 return at(m_cElements - 1);
407 }
408
409
410protected:
411 virtual RTCRestArrayBase *createClone(void) const RT_OVERRIDE
412 {
413 return new (std::nothrow) RTCRestArray();
414 }
415
416 virtual RTCRestObjectBase *createValue(void) RT_OVERRIDE
417 {
418 return new (std::nothrow) ElementType();
419 }
420};
421
422
423/** @} */
424
425#endif
426
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