VirtualBox

source: vbox/trunk/include/iprt/cpp/list.h@ 36563

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

iprt-cpp: More RTC*List methods. Added explicit constructors to the specializations.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.1 KB
Line 
1/** @file
2 * IPRT - Generic List Class.
3 */
4
5/*
6 * Copyright (C) 2011 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_list_h
27#define ___iprt_cpp_list_h
28
29#include <iprt/cpp/meta.h>
30#include <iprt/mem.h>
31#include <iprt/string.h> /* for memcpy */
32
33#include <new> /* For std::bad_alloc */
34
35/** @defgroup grp_rt_cpp_list C++ List support
36 * @ingroup grp_rt_cpp
37 *
38 * @brief Generic C++ list class support.
39 *
40 * This list classes manage any amount of data in a fast and easy to use way.
41 * They have no dependencies on STL, only on generic memory management methods
42 * of IRPT. This allows list handling in situations where the use of STL
43 * container classes is forbidden.
44 *
45 * Not all of the functionality of STL container classes is implemented. There
46 * are no iterators or any other high level access/modifier methods (e.g.
47 * std::algorithms).
48 *
49 * The implementation is array based which allows fast access to the items.
50 * Appending items is usually also fast, cause the internal array is
51 * preallocated. To minimize the memory overhead, native types (that is
52 * everything smaller then the size of void*) are directly saved in the array.
53 * If bigger types are used (e.g. RTCString) the internal array is an array of
54 * pointers to the objects.
55 *
56 * The size of the internal array will usually not shrink, but grow
57 * automatically. Only certain methods, like RTCList::clear or the "=" operator
58 * will reset any previously allocated memory. You can call
59 * RTCList::setCapacity for manual adjustment. If the size of an new list will
60 * be known, calling the constructor with the necessary capacity will speed up
61 * the insertion of the new items.
62 *
63 * For the full public interface these list classes offer see RTCListBase.
64 *
65 * There are some requirements for the types used which follow:
66 * -# They need a default and a copy constructor.
67 * -# If the type is some complex class (that is, having a constructor which
68 * allocates members on the heap) it has to be greater than sizeof(void*) to
69 * be used correctly. If this is not the case you can manually overwrite the
70 * list behavior. Just add T* as a second parameter to the list template if
71 * your class is called T. Another possibility is to specialize the list for
72 * your target class. See below for more information.
73 *
74 * The native types like int, bool, ptr, ..., are meeting this criteria, so
75 * they are save to use.
76 *
77 * Please note that the return type of some of the getter methods are slightly
78 * different depending on the list type. Native types return the item by value,
79 * items with a size greater than sizeof(void*) by reference. As native types
80 * saved directly in the internal array, returning a reference to them (and
81 * saving them in a reference as well) would make them invalid (or pointing to
82 * a wrong item) when the list is changed in the meanwhile. Returning a
83 * reference for bigger types isn't problematic and makes sure we get out the
84 * best speed of the list. The one exception to this rule is the index
85 * operator[]. This operator always return a reference to make it possible to
86 * use it as a lvalue. Its your responsibility to make sure the list isn't
87 * changed when using the value as reference returned by this operator.
88 *
89 * The list class is reentrant. For a thread-safe variant see RTCMTList.
90 *
91 * Implementation details:
92 * It is possible to specialize any type. This might be necessary to get the
93 * best speed out of the list. Examples are the 64-bit types, which use the
94 * native (no pointers) implementation even on a 32-bit host. Consult the
95 * source code for more details.
96 *
97 * Current specialized implementations:
98 * - int64_t: RTCList<int64_t>
99 * - uint64_t: RTCList<uint64_t>
100 *
101 * @{
102 */
103
104/**
105 * The guard definition.
106 */
107template <bool G>
108class RTCListGuard;
109
110/**
111 * The default guard which does nothing.
112 */
113template <>
114class RTCListGuard<false>
115{
116public:
117 inline void enterRead() const {}
118 inline void leaveRead() const {}
119 inline void enterWrite() {}
120 inline void leaveWrite() {}
121};
122
123/**
124 * General helper template for managing native values in RTCListBase.
125 */
126template <typename T1, typename T2>
127class RTCListHelper
128{
129public:
130 static inline void set(T2 *p, size_t i, const T1 &v) { p[i] = v; }
131 static inline T1 & at(T2 *p, size_t i) { return p[i]; }
132 static inline size_t find(T2 *p, const T1 &v, size_t cSize)
133 {
134 size_t i = 0;
135 while(i < cSize)
136 {
137 if (p[i] == v)
138 break;
139 ++i;
140 }
141 return i;
142 }
143 static inline void copyTo(T2 *p, T2 *const p1 , size_t iTo, size_t cSize)
144 {
145 if (cSize > 0)
146 memcpy(&p[iTo], &p1[0], sizeof(T1) * cSize);
147 }
148 static inline void erase(T2 *p, size_t /* i */) { /* Nothing to do here. */ }
149 static inline void eraseRange(T2 * /* p */, size_t /* cFrom */, size_t /* cSize */) { /* Nothing to do here. */ }
150};
151
152/**
153 * Specialized helper template for managing pointer values in RTCListBase.
154 */
155template <typename T1>
156class RTCListHelper<T1, T1*>
157{
158public:
159 static inline void set(T1 **p, size_t i, const T1 &v) { p[i] = new T1(v); }
160 static inline T1 & at(T1 **p, size_t i) { return *p[i]; }
161 static inline size_t find(T1 **p, const T1 &v, size_t cSize)
162 {
163 size_t i = 0;
164 while(i < cSize)
165 {
166 if (*p[i] == v)
167 break;
168 ++i;
169 }
170 return i;
171 }
172 static inline void copyTo(T1 **p, T1 **const p1 , size_t iTo, size_t cSize)
173 {
174 for (size_t i = 0; i < cSize; ++i)
175 p[iTo + i] = new T1(*p1[i]);
176 }
177 static inline void erase(T1 **p, size_t i) { delete p[i]; }
178 static inline void eraseRange(T1 **p, size_t cFrom, size_t cSize)
179 {
180 for (size_t i = cFrom; i < cFrom + cSize; ++i)
181 delete p[i];
182 }
183};
184
185/**
186 * This is the base class for all other list classes. It implements the
187 * necessary list functionality in a type independent way and offers the public
188 * list interface to the user.
189 */
190template <class T, typename ITYPE, bool MT>
191class RTCListBase
192{
193 /**
194 * Defines the return type of most of the getter methods. If the internal
195 * used type is a pointer, we return a reference. If not we return by
196 * value.
197 */
198 typedef typename RTCIfPtr<ITYPE, T&, T>::result GET_RTYPE;
199 typedef typename RTCIfPtr<ITYPE, const T&, T>::result GET_CRTYPE;
200
201public:
202 /**
203 * Creates a new list.
204 *
205 * This preallocates @a cCapacity elements within the list.
206 *
207 * @param cCapacitiy The initial capacity the list has.
208 * @throws std::bad_alloc
209 */
210 RTCListBase(size_t cCapacity = DefaultCapacity)
211 : m_pArray(0)
212 , m_cSize(0)
213 , m_cCapacity(0)
214 {
215 realloc_grow(cCapacity);
216 }
217
218 /**
219 * Creates a copy of another list.
220 *
221 * The other list will be fully copied and the capacity will be the same as
222 * the size if the other list.
223 *
224 * @param other The list to copy.
225 * @throws std::bad_alloc
226 */
227 RTCListBase(const RTCListBase<T, ITYPE, MT>& other)
228 : m_pArray(0)
229 , m_cSize(0)
230 , m_cCapacity(0)
231 {
232 realloc_grow(other.m_cSize);
233 RTCListHelper<T, ITYPE>::copyTo(m_pArray, other.m_pArray, 0, other.m_cSize);
234 m_cSize = other.m_cSize;
235 }
236
237 /**
238 * Destructor.
239 */
240 ~RTCListBase()
241 {
242 RTCListHelper<T, ITYPE>::eraseRange(m_pArray, 0, m_cSize);
243 if (m_pArray)
244 RTMemFree(m_pArray);
245 }
246
247 /**
248 * Sets a new capacity within the list.
249 *
250 * If the new capacity is bigger than the old size, it will be simply
251 * preallocated more space for the new items. If the new capacity is
252 * smaller than the previous size, items at the end of the list will be
253 * deleted.
254 *
255 * @param cCapacity The new capacity within the list.
256 * @throws std::bad_alloc
257 */
258 void setCapacity(size_t cCapacity)
259 {
260 m_guard.enterWrite();
261 realloc(cCapacity);
262 m_guard.leaveWrite();
263 }
264
265 /**
266 * Return the current capacity of the list.
267 *
268 * @return The actual capacity.
269 */
270 size_t capacity() const { return m_cCapacity; }
271
272 /**
273 * Check if an list contains any items.
274 *
275 * @return True if there is more than zero items, false otherwise.
276 */
277 bool isEmpty() const { return m_cSize == 0; }
278
279 /**
280 * Return the current count of elements within the list.
281 *
282 * @return The current element count.
283 */
284 size_t size() const { return m_cSize; }
285
286 /**
287 * Inserts an item to the list at position @a i.
288 *
289 * @param i The position of the new item.
290 * @param val The new item.
291 * @return a reference to this list.
292 * @throws std::bad_alloc
293 */
294 RTCListBase<T, ITYPE, MT> &insert(size_t i, const T &val)
295 {
296 m_guard.enterWrite();
297 if (m_cSize == m_cCapacity)
298 realloc_grow(m_cCapacity + DefaultCapacity);
299 memmove(&m_pArray[i + 1], &m_pArray[i], (m_cSize - i) * sizeof(ITYPE));
300 RTCListHelper<T, ITYPE>::set(m_pArray, i, val);
301 ++m_cSize;
302 m_guard.leaveWrite();
303
304 return *this;
305 }
306
307 /**
308 * Prepend an item to the list.
309 *
310 * @param val The new item.
311 * @return a reference to this list.
312 * @throws std::bad_alloc
313 */
314 RTCListBase<T, ITYPE, MT> &prepend(const T &val)
315 {
316 return insert(0, val);
317 }
318
319 /**
320 * Prepend a list of type T to the list.
321 *
322 * @param other The list to prepend.
323 * @return a reference to this list.
324 * @throws std::bad_alloc
325 */
326 RTCListBase<T, ITYPE, MT> &prepend(const RTCListBase<T, ITYPE, MT> &other)
327 {
328 m_guard.enterWrite();
329 if (m_cCapacity - m_cSize < other.m_cSize)
330 realloc_grow(m_cCapacity + (other.m_cSize - (m_cCapacity - m_cSize)));
331 memmove(&m_pArray[other.m_cSize], &m_pArray[0], m_cSize * sizeof(ITYPE));
332 RTCListHelper<T, ITYPE>::copyTo(m_pArray, other.m_pArray, 0, other.m_cSize);
333 m_cSize += other.m_cSize;
334 m_guard.leaveWrite();
335
336 return *this;
337 }
338
339 /**
340 * Append an item to the list.
341 *
342 * @param val The new item.
343 * @return a reference to this list.
344 * @throws std::bad_alloc
345 */
346 RTCListBase<T, ITYPE, MT> &append(const T &val)
347 {
348 m_guard.enterWrite();
349 if (m_cSize == m_cCapacity)
350 realloc_grow(m_cCapacity + DefaultCapacity);
351 RTCListHelper<T, ITYPE>::set(m_pArray, m_cSize, val);
352 ++m_cSize;
353 m_guard.leaveWrite();
354
355 return *this;
356 }
357
358 /**
359 * Append a list of type T to the list.
360 *
361 * @param other The list to append.
362 * @return a reference to this list.
363 * @throws std::bad_alloc
364 */
365 RTCListBase<T, ITYPE, MT> &append(const RTCListBase<T, ITYPE, MT> &other)
366 {
367 m_guard.enterWrite();
368 if (m_cCapacity - m_cSize < other.m_cSize)
369 realloc_grow(m_cCapacity + (other.m_cSize - (m_cCapacity - m_cSize)));
370 RTCListHelper<T, ITYPE>::copyTo(m_pArray, other.m_pArray, m_cSize, other.m_cSize);
371 m_cSize += other.m_cSize;
372 m_guard.leaveWrite();
373
374 return *this;
375 }
376
377 /**
378 * Copy the items of the other list into this list. All previous items of
379 * this list are deleted.
380 *
381 * @param other The list to copy.
382 * @return a reference to this list.
383 */
384 RTCListBase<T, ITYPE, MT> &operator=(const RTCListBase<T, ITYPE, MT>& other)
385 {
386 /* Prevent self assignment */
387 if (this == &other)
388 return *this;
389
390 m_guard.enterWrite();
391 /* Values cleanup */
392 RTCListHelper<T, ITYPE>::eraseRange(m_pArray, 0, m_cSize);
393
394 /* Copy */
395 if (other.m_cSize != m_cCapacity)
396 realloc_grow(other.m_cSize);
397 m_cSize = other.m_cSize;
398 RTCListHelper<T, ITYPE>::copyTo(m_pArray, other.m_pArray, 0, other.m_cSize);
399 m_guard.leaveWrite();
400
401 return *this;
402 }
403
404 /**
405 * Replace an item in the list.
406 *
407 * @note No boundary checks are done. Make sure @a i is equal or greater zero
408 * and smaller than RTCList::size.
409 *
410 * @param i The position of the item to replace.
411 * @param val The new value.
412 * @return a reference to this list.
413 */
414 RTCListBase<T, ITYPE, MT> &replace(size_t i, const T &val)
415 {
416 m_guard.enterWrite();
417 RTCListHelper<T, ITYPE>::erase(m_pArray, i);
418 RTCListHelper<T, ITYPE>::set(m_pArray, i, val);
419 m_guard.leaveWrite();
420
421 return *this;
422 }
423
424 /**
425 * Return the first item as constant object.
426 *
427 * @note No boundary checks are done. Make sure @a i is equal or greater zero
428 * and smaller than RTCList::size.
429 *
430 * @return The first item.
431 */
432 GET_CRTYPE first() const
433 {
434 m_guard.enterRead();
435 GET_CRTYPE res = RTCListHelper<T, ITYPE>::at(m_pArray, 0);
436 m_guard.leaveRead();
437 return res;
438 }
439
440 /**
441 * Return the first item.
442 *
443 * @note No boundary checks are done. Make sure @a i is equal or greater zero
444 * and smaller than RTCList::size.
445 *
446 * @return The first item.
447 */
448 GET_RTYPE first()
449 {
450 m_guard.enterRead();
451 GET_RTYPE res = RTCListHelper<T, ITYPE>::at(m_pArray, 0);
452 m_guard.leaveRead();
453 return res;
454 }
455
456 /**
457 * Return the last item as constant object.
458 *
459 * @note No boundary checks are done. Make sure @a i is equal or greater zero
460 * and smaller than RTCList::size.
461 *
462 * @return The last item.
463 */
464 GET_CRTYPE last() const
465 {
466 m_guard.enterRead();
467 GET_CRTYPE res = RTCListHelper<T, ITYPE>::at(m_pArray, m_cSize - 1);
468 m_guard.leaveRead();
469 return res;
470 }
471
472 /**
473 * Return the last item.
474 *
475 * @note No boundary checks are done. Make sure @a i is equal or greater zero
476 * and smaller than RTCList::size.
477 *
478 * @return The last item.
479 */
480 GET_RTYPE last()
481 {
482 m_guard.enterRead();
483 GET_RTYPE res = RTCListHelper<T, ITYPE>::at(m_pArray, m_cSize - 1);
484 m_guard.leaveRead();
485 return res;
486 }
487
488 /**
489 * Return the item at position @a i as constant object.
490 *
491 * @note No boundary checks are done. Make sure @a i is equal or greater zero
492 * and smaller than RTCList::size.
493 *
494 * @param i The position of the item to return.
495 * @return The item at position @a i.
496 */
497 GET_CRTYPE at(size_t i) const
498 {
499 m_guard.enterRead();
500 GET_CRTYPE res = RTCListHelper<T, ITYPE>::at(m_pArray, i);
501 m_guard.leaveRead();
502 return res;
503 }
504
505 /**
506 * Return the item at position @a i.
507 *
508 * @note No boundary checks are done. Make sure @a i is equal or greater zero
509 * and smaller than RTCList::size.
510 *
511 * @param i The position of the item to return.
512 * @return The item at position @a i.
513 */
514 GET_RTYPE at(size_t i)
515 {
516 m_guard.enterRead();
517 GET_RTYPE res = RTCListHelper<T, ITYPE>::at(m_pArray, i);
518 m_guard.leaveRead();
519 return res;
520 }
521
522 /**
523 * Return the item at position @a i as mutable reference.
524 *
525 * @note No boundary checks are done. Make sure @a i is equal or greater zero
526 * and smaller than RTCList::size.
527 *
528 * @param i The position of the item to return.
529 * @return The item at position @a i.
530 */
531 T &operator[](size_t i)
532 {
533 m_guard.enterRead();
534 T &res = RTCListHelper<T, ITYPE>::at(m_pArray, i);
535 m_guard.leaveRead();
536 return res;
537 }
538
539 /**
540 * Return the item at position @a i. If @a i isn't valid within the list a
541 * default value is returned.
542 *
543 * @param i The position of the item to return.
544 * @return The item at position @a i.
545 */
546 T value(size_t i) const
547 {
548 m_guard.enterRead();
549 if (i >= m_cSize)
550 {
551 m_guard.leaveRead();
552 return T();
553 }
554 T res = RTCListHelper<T, ITYPE>::at(m_pArray, i);
555 m_guard.leaveRead();
556 return res;
557 }
558
559 /**
560 * Return the item at position @a i. If @a i isn't valid within the list
561 * @a defaultVal is returned.
562 *
563 * @param i The position of the item to return.
564 * @param defaultVal The value to return in case @a i is invalid.
565 * @return The item at position @a i.
566 */
567 T value(size_t i, const T &defaultVal) const
568 {
569 m_guard.enterRead();
570 if (i >= m_cSize)
571 {
572 m_guard.leaveRead();
573 return defaultVal;
574 }
575 T res = RTCListHelper<T, ITYPE>::at(m_pArray, i);
576 m_guard.leaveRead();
577 return res;
578 }
579
580 /**
581 * Check if @a val is contained in the array.
582 *
583 * @param val The value to check for.
584 * @return true if it is found, false otherwise.
585 */
586 bool contains(const T &val) const
587 {
588 m_guard.enterRead();
589 bool res = RTCListHelper<T, ITYPE>::find(m_pArray, val, m_cSize) != m_cSize;
590 m_guard.leaveRead();
591 return res;
592 }
593
594 /**
595 * Remove the first item.
596 *
597 * @note No boundary checks are done. Make sure @a i is equal or greater zero
598 * and smaller than RTCList::size.
599 */
600 void removeFirst()
601 {
602 removeAt(0);
603 }
604
605 /**
606 * Remove the last item.
607 *
608 * @note No boundary checks are done. Make sure @a i is equal or greater zero
609 * and smaller than RTCList::size.
610 */
611 void removeLast()
612 {
613 removeAt(m_cSize - 1);
614 }
615
616 /**
617 * Remove the item at position @a i.
618 *
619 * @note No boundary checks are done. Make sure @a i is equal or greater zero
620 * and smaller than RTCList::size.
621 *
622 * @param i The position of the item to remove.
623 */
624 void removeAt(size_t i)
625 {
626 m_guard.enterWrite();
627 RTCListHelper<T, ITYPE>::erase(m_pArray, i);
628 /* Not last element? */
629 if (i < m_cSize - 1)
630 memmove(&m_pArray[i], &m_pArray[i + 1], (m_cSize - i - 1) * sizeof(ITYPE));
631 --m_cSize;
632 m_guard.leaveWrite();
633 }
634
635 /**
636 * Remove a range of items from the list.
637 *
638 * @note No boundary checks are done. Make sure @a iFrom is equal or
639 * greater zero and smaller than RTCList::size. @a iTo has to be
640 * greater than @a iFrom and equal or smaller than RTCList::size.
641 *
642 * @param iFrom The start position of the items to remove.
643 * @param iTo The end position of the items to remove (excluded).
644 */
645 void removeRange(size_t iFrom, size_t iTo)
646 {
647 m_guard.enterWrite();
648 RTCListHelper<T, ITYPE>::eraseRange(m_pArray, iFrom, iTo - iFrom);
649 /* Not last elements? */
650 if (m_cSize - iTo > 0)
651 memmove(&m_pArray[iFrom], &m_pArray[iTo], (m_cSize - iTo) * sizeof(ITYPE));
652 m_cSize -= iTo - iFrom;
653 m_guard.leaveWrite();
654 }
655
656 /**
657 * Delete all items in the list.
658 */
659 void clear()
660 {
661 m_guard.enterWrite();
662 /* Values cleanup */
663 RTCListHelper<T, ITYPE>::eraseRange(m_pArray, 0, m_cSize);
664 if (m_cSize != DefaultCapacity)
665 realloc_grow(DefaultCapacity);
666 m_cSize = 0;
667 m_guard.leaveWrite();
668 }
669
670 /**
671 * Return the raw array. For native types this is a pointer to continuous
672 * memory of the items. For pointer types this is a continuous memory of
673 * pointers to the items.
674 *
675 * @warning If you change anything in the underlaying list, this memory
676 * will very likely become invalid. So take care when using this
677 * method and better try to avoid using it.
678 *
679 * @returns the raw memory.
680 */
681 ITYPE* raw() const
682 {
683 m_guard.enterRead();
684 ITYPE* res = m_pArray;
685 m_guard.leaveRead();
686 return res;
687 }
688
689 /**
690 * The default capacity of the list. This is also used as grow factor.
691 */
692 static const size_t DefaultCapacity;
693private:
694
695 /**
696 * Generic realloc, which does some kind of boundary checking.
697 */
698 void realloc(size_t cNewSize)
699 {
700 /* Same size? */
701 if (cNewSize == m_cCapacity)
702 return;
703
704 /* If we get smaller we have to delete some of the objects at the end
705 of the list. */
706 if ( cNewSize < m_cSize
707 && m_pArray)
708 {
709 RTCListHelper<T, ITYPE>::eraseRange(m_pArray, cNewSize, m_cSize - cNewSize);
710 m_cSize -= m_cSize - cNewSize;
711 }
712
713 /* If we get zero we delete the array it self. */
714 if ( cNewSize == 0
715 && m_pArray)
716 {
717 RTMemFree(m_pArray);
718 m_pArray = 0;
719 }
720 m_cCapacity = cNewSize;
721
722 /* Resize the array. */
723 if (cNewSize > 0)
724 {
725 m_pArray = static_cast<ITYPE*>(RTMemRealloc(m_pArray, sizeof(ITYPE) * cNewSize));
726 if (!m_pArray)
727 {
728 /** @todo you leak memory. */
729 m_cCapacity = 0;
730 m_cSize = 0;
731#ifdef RT_EXCEPTIONS_ENABLED
732 throw std::bad_alloc();
733#endif
734 }
735 }
736 }
737
738 /**
739 * Special realloc method which require that the array will grow.
740 *
741 * @note No boundary checks are done!
742 */
743 void realloc_grow(size_t cNewSize)
744 {
745 /* Resize the array. */
746 m_cCapacity = cNewSize;
747 m_pArray = static_cast<ITYPE*>(RTMemRealloc(m_pArray, sizeof(ITYPE) * cNewSize));
748 if (!m_pArray)
749 {
750 /** @todo you leak memory. */
751 m_cCapacity = 0;
752 m_cSize = 0;
753#ifdef RT_EXCEPTIONS_ENABLED
754 throw std::bad_alloc();
755#endif
756 }
757 }
758
759 /** The internal list array. */
760 ITYPE *m_pArray;
761 /** The current count of items in use. */
762 size_t m_cSize;
763 /** The current capacity of the internal array. */
764 size_t m_cCapacity;
765 /** The guard used to serialize the access to the items. */
766 RTCListGuard<MT> m_guard;
767};
768
769template <class T, typename ITYPE, bool MT>
770const size_t RTCListBase<T, ITYPE, MT>::DefaultCapacity = 10;
771
772/**
773 * Template class which automatically determines the type of list to use.
774 *
775 * @see RTCListBase
776 */
777template <class T, typename ITYPE = typename RTCIf<(sizeof(T) > sizeof(void*)), T*, T>::result>
778class RTCList : public RTCListBase<T, ITYPE, false>
779{
780 typedef RTCListBase<T, ITYPE, false> BASE;
781public:
782 RTCList(size_t cCapacity = BASE::DefaultCapacity)
783 : BASE(cCapacity) {}
784};
785
786/**
787 * Specialized class for using the native type list for unsigned 64-bit
788 * values even on a 32-bit host.
789 *
790 * @see RTCListBase
791 */
792template <>
793class RTCList<uint64_t>: public RTCListBase<uint64_t, uint64_t, false>
794{
795 typedef RTCListBase<uint64_t, uint64_t, false> BASE;
796public:
797 RTCList(size_t cCapacity = BASE::DefaultCapacity)
798 : BASE(cCapacity) {}
799};
800
801/**
802 * Specialized class for using the native type list for signed 64-bit
803 * values even on a 32-bit host.
804 *
805 * @see RTCListBase
806 */
807template <>
808class RTCList<int64_t>: public RTCListBase<int64_t, int64_t, false>
809{
810 typedef RTCListBase<int64_t, int64_t, false> BASE;
811public:
812 RTCList(size_t cCapacity = BASE::DefaultCapacity)
813 : BASE(cCapacity) {}
814};
815
816/** @} */
817
818#endif /* !___iprt_cpp_list_h */
819
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