oculus1

view libovr/Src/Kernel/OVR_Array.h @ 29:9a973ef0e2a3

fixed the performance issue under MacOSX by replacing glutSolidTeapot (which uses glEvalMesh) with my own teapot generator.
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 27 Oct 2013 06:31:18 +0200
parents e2f9e4603129
children
line source
1 /************************************************************************************
3 PublicHeader: OVR.h
4 Filename : OVR_Array.h
5 Content : Template implementation for Array
6 Created : September 19, 2012
7 Notes :
9 Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
11 Use of this software is subject to the terms of the Oculus license
12 agreement provided at the time of installation or download, or which
13 otherwise accompanies this software in either electronic or hard copy form.
15 ************************************************************************************/
17 #ifndef OVR_Array_h
18 #define OVR_Array_h
20 #include "OVR_ContainerAllocator.h"
22 namespace OVR {
24 //-----------------------------------------------------------------------------------
25 // ***** ArrayDefaultPolicy
26 //
27 // Default resize behavior. No minimal capacity, Granularity=4,
28 // Shrinking as needed. ArrayConstPolicy actually is the same as
29 // ArrayDefaultPolicy, but parametrized with constants.
30 // This struct is used only in order to reduce the template "matroska".
31 struct ArrayDefaultPolicy
32 {
33 ArrayDefaultPolicy() : Capacity(0) {}
34 ArrayDefaultPolicy(const ArrayDefaultPolicy&) : Capacity(0) {}
36 UPInt GetMinCapacity() const { return 0; }
37 UPInt GetGranularity() const { return 4; }
38 bool NeverShrinking() const { return 0; }
40 UPInt GetCapacity() const { return Capacity; }
41 void SetCapacity(UPInt capacity) { Capacity = capacity; }
42 private:
43 UPInt Capacity;
44 };
47 //-----------------------------------------------------------------------------------
48 // ***** ArrayConstPolicy
49 //
50 // Statically parametrized resizing behavior:
51 // MinCapacity, Granularity, and Shrinking flag.
52 template<int MinCapacity=0, int Granularity=4, bool NeverShrink=false>
53 struct ArrayConstPolicy
54 {
55 typedef ArrayConstPolicy<MinCapacity, Granularity, NeverShrink> SelfType;
57 ArrayConstPolicy() : Capacity(0) {}
58 ArrayConstPolicy(const SelfType&) : Capacity(0) {}
60 UPInt GetMinCapacity() const { return MinCapacity; }
61 UPInt GetGranularity() const { return Granularity; }
62 bool NeverShrinking() const { return NeverShrink; }
64 UPInt GetCapacity() const { return Capacity; }
65 void SetCapacity(UPInt capacity) { Capacity = capacity; }
66 private:
67 UPInt Capacity;
68 };
70 //-----------------------------------------------------------------------------------
71 // ***** ArrayDataBase
72 //
73 // Basic operations with array data: Reserve, Resize, Free, ArrayPolicy.
74 // For internal use only: ArrayData,ArrayDataCC and others.
75 template<class T, class Allocator, class SizePolicy>
76 struct ArrayDataBase
77 {
78 typedef T ValueType;
79 typedef Allocator AllocatorType;
80 typedef SizePolicy SizePolicyType;
81 typedef ArrayDataBase<T, Allocator, SizePolicy> SelfType;
83 ArrayDataBase()
84 : Data(0), Size(0), Policy() {}
86 ArrayDataBase(const SizePolicy& p)
87 : Data(0), Size(0), Policy(p) {}
89 ~ArrayDataBase()
90 {
91 Allocator::DestructArray(Data, Size);
92 Allocator::Free(Data);
93 }
95 UPInt GetCapacity() const
96 {
97 return Policy.GetCapacity();
98 }
100 void ClearAndRelease()
101 {
102 Allocator::DestructArray(Data, Size);
103 Allocator::Free(Data);
104 Data = 0;
105 Size = 0;
106 Policy.SetCapacity(0);
107 }
109 void Reserve(UPInt newCapacity)
110 {
111 if (Policy.NeverShrinking() && newCapacity < GetCapacity())
112 return;
114 if (newCapacity < Policy.GetMinCapacity())
115 newCapacity = Policy.GetMinCapacity();
117 // Resize the buffer.
118 if (newCapacity == 0)
119 {
120 if (Data)
121 {
122 Allocator::Free(Data);
123 Data = 0;
124 }
125 Policy.SetCapacity(0);
126 }
127 else
128 {
129 UPInt gran = Policy.GetGranularity();
130 newCapacity = (newCapacity + gran - 1) / gran * gran;
131 if (Data)
132 {
133 if (Allocator::IsMovable())
134 {
135 Data = (T*)Allocator::Realloc(Data, sizeof(T) * newCapacity);
136 }
137 else
138 {
139 T* newData = (T*)Allocator::Alloc(sizeof(T) * newCapacity);
140 UPInt i, s;
141 s = (Size < newCapacity) ? Size : newCapacity;
142 for (i = 0; i < s; ++i)
143 {
144 Allocator::Construct(&newData[i], Data[i]);
145 Allocator::Destruct(&Data[i]);
146 }
147 for (i = s; i < Size; ++i)
148 {
149 Allocator::Destruct(&Data[i]);
150 }
151 Allocator::Free(Data);
152 Data = newData;
153 }
154 }
155 else
156 {
157 Data = (T*)Allocator::Alloc(sizeof(T) * newCapacity);
158 //memset(Buffer, 0, (sizeof(ValueType) * newSize)); // Do we need this?
159 }
160 Policy.SetCapacity(newCapacity);
161 // OVR_ASSERT(Data); // need to throw (or something) on alloc failure!
162 }
163 }
165 // This version of Resize DOES NOT construct the elements.
166 // It's done to optimize PushBack, which uses a copy constructor
167 // instead of the default constructor and assignment
168 void ResizeNoConstruct(UPInt newSize)
169 {
170 UPInt oldSize = Size;
172 if (newSize < oldSize)
173 {
174 Allocator::DestructArray(Data + newSize, oldSize - newSize);
175 if (newSize < (Policy.GetCapacity() >> 1))
176 {
177 Reserve(newSize);
178 }
179 }
180 else if(newSize >= Policy.GetCapacity())
181 {
182 Reserve(newSize + (newSize >> 2));
183 }
184 //! IMPORTANT to modify Size only after Reserve completes, because garbage collectable
185 // array may use this array and may traverse it during Reserve (in the case, if
186 // collection occurs because of heap limit exceeded).
187 Size = newSize;
188 }
190 ValueType* Data;
191 UPInt Size;
192 SizePolicy Policy;
193 };
197 //-----------------------------------------------------------------------------------
198 // ***** ArrayData
199 //
200 // General purpose array data.
201 // For internal use only in Array, ArrayLH, ArrayPOD and so on.
202 template<class T, class Allocator, class SizePolicy>
203 struct ArrayData : ArrayDataBase<T, Allocator, SizePolicy>
204 {
205 typedef T ValueType;
206 typedef Allocator AllocatorType;
207 typedef SizePolicy SizePolicyType;
208 typedef ArrayDataBase<T, Allocator, SizePolicy> BaseType;
209 typedef ArrayData <T, Allocator, SizePolicy> SelfType;
211 ArrayData()
212 : BaseType() { }
214 ArrayData(int size)
215 : BaseType() { Resize(size); }
217 ArrayData(const SelfType& a)
218 : BaseType(a.Policy) { Append(a.Data, a.Size); }
221 void Resize(UPInt newSize)
222 {
223 UPInt oldSize = this->Size;
224 BaseType::ResizeNoConstruct(newSize);
225 if(newSize > oldSize)
226 Allocator::ConstructArray(this->Data + oldSize, newSize - oldSize);
227 }
229 void PushBack(const ValueType& val)
230 {
231 BaseType::ResizeNoConstruct(this->Size + 1);
232 Allocator::Construct(this->Data + this->Size - 1, val);
233 }
235 template<class S>
236 void PushBackAlt(const S& val)
237 {
238 BaseType::ResizeNoConstruct(this->Size + 1);
239 Allocator::ConstructAlt(this->Data + this->Size - 1, val);
240 }
242 // Append the given data to the array.
243 void Append(const ValueType other[], UPInt count)
244 {
245 if (count)
246 {
247 UPInt oldSize = this->Size;
248 BaseType::ResizeNoConstruct(this->Size + count);
249 Allocator::ConstructArray(this->Data + oldSize, count, other);
250 }
251 }
252 };
256 //-----------------------------------------------------------------------------------
257 // ***** ArrayDataCC
258 //
259 // A modification of ArrayData that always copy-constructs new elements
260 // using a specified DefaultValue. For internal use only in ArrayCC.
261 template<class T, class Allocator, class SizePolicy>
262 struct ArrayDataCC : ArrayDataBase<T, Allocator, SizePolicy>
263 {
264 typedef T ValueType;
265 typedef Allocator AllocatorType;
266 typedef SizePolicy SizePolicyType;
267 typedef ArrayDataBase<T, Allocator, SizePolicy> BaseType;
268 typedef ArrayDataCC <T, Allocator, SizePolicy> SelfType;
270 ArrayDataCC(const ValueType& defval)
271 : BaseType(), DefaultValue(defval) { }
273 ArrayDataCC(const ValueType& defval, int size)
274 : BaseType(), DefaultValue(defval) { Resize(size); }
276 ArrayDataCC(const SelfType& a)
277 : BaseType(a.Policy), DefaultValue(a.DefaultValue) { Append(a.Data, a.Size); }
280 void Resize(UPInt newSize)
281 {
282 UPInt oldSize = this->Size;
283 BaseType::ResizeNoConstruct(newSize);
284 if(newSize > oldSize)
285 Allocator::ConstructArray(this->Data + oldSize, newSize - oldSize, DefaultValue);
286 }
288 void PushBack(const ValueType& val)
289 {
290 BaseType::ResizeNoConstruct(this->Size + 1);
291 Allocator::Construct(this->Data + this->Size - 1, val);
292 }
294 template<class S>
295 void PushBackAlt(const S& val)
296 {
297 BaseType::ResizeNoConstruct(this->Size + 1);
298 Allocator::ConstructAlt(this->Data + this->Size - 1, val);
299 }
301 // Append the given data to the array.
302 void Append(const ValueType other[], UPInt count)
303 {
304 if (count)
305 {
306 UPInt oldSize = this->Size;
307 BaseType::ResizeNoConstruct(this->Size + count);
308 Allocator::ConstructArray(this->Data + oldSize, count, other);
309 }
310 }
312 ValueType DefaultValue;
313 };
319 //-----------------------------------------------------------------------------------
320 // ***** ArrayBase
321 //
322 // Resizable array. The behavior can be POD (suffix _POD) and
323 // Movable (no suffix) depending on the allocator policy.
324 // In case of _POD the constructors and destructors are not called.
325 //
326 // Arrays can't handle non-movable objects! Don't put anything in here
327 // that can't be moved around by bitwise copy.
328 //
329 // The addresses of elements are not persistent! Don't keep the address
330 // of an element; the array contents will move around as it gets resized.
331 template<class ArrayData>
332 class ArrayBase
333 {
334 public:
335 typedef typename ArrayData::ValueType ValueType;
336 typedef typename ArrayData::AllocatorType AllocatorType;
337 typedef typename ArrayData::SizePolicyType SizePolicyType;
338 typedef ArrayBase<ArrayData> SelfType;
341 #undef new
342 OVR_MEMORY_REDEFINE_NEW(ArrayBase)
343 // Redefine operator 'new' if necessary.
344 #if defined(OVR_DEFINE_NEW)
345 #define new OVR_DEFINE_NEW
346 #endif
349 ArrayBase()
350 : Data() {}
351 ArrayBase(int size)
352 : Data(size) {}
353 ArrayBase(const SelfType& a)
354 : Data(a.Data) {}
356 ArrayBase(const ValueType& defval)
357 : Data(defval) {}
358 ArrayBase(const ValueType& defval, int size)
359 : Data(defval, size) {}
361 SizePolicyType* GetSizePolicy() const { return Data.Policy; }
362 void SetSizePolicy(const SizePolicyType& p) { Data.Policy = p; }
364 bool NeverShrinking()const { return Data.Policy.NeverShrinking(); }
365 UPInt GetSize() const { return Data.Size; }
366 bool IsEmpty() const { return Data.Size == 0; }
367 UPInt GetCapacity() const { return Data.GetCapacity(); }
368 UPInt GetNumBytes() const { return Data.GetCapacity() * sizeof(ValueType); }
370 void ClearAndRelease() { Data.ClearAndRelease(); }
371 void Clear() { Data.Resize(0); }
372 void Resize(UPInt newSize) { Data.Resize(newSize); }
374 // Reserve can only increase the capacity
375 void Reserve(UPInt newCapacity)
376 {
377 if (newCapacity > Data.GetCapacity())
378 Data.Reserve(newCapacity);
379 }
381 // Basic access.
382 ValueType& At(UPInt index)
383 {
384 OVR_ASSERT(index < Data.Size);
385 return Data.Data[index];
386 }
387 const ValueType& At(UPInt index) const
388 {
389 OVR_ASSERT(index < Data.Size);
390 return Data.Data[index];
391 }
393 ValueType ValueAt(UPInt index) const
394 {
395 OVR_ASSERT(index < Data.Size);
396 return Data.Data[index];
397 }
399 // Basic access.
400 ValueType& operator [] (UPInt index)
401 {
402 OVR_ASSERT(index < Data.Size);
403 return Data.Data[index];
404 }
405 const ValueType& operator [] (UPInt index) const
406 {
407 OVR_ASSERT(index < Data.Size);
408 return Data.Data[index];
409 }
411 // Raw pointer to the data. Use with caution!
412 const ValueType* GetDataPtr() const { return Data.Data; }
413 ValueType* GetDataPtr() { return Data.Data; }
415 // Insert the given element at the end of the array.
416 void PushBack(const ValueType& val)
417 {
418 // DO NOT pass elements of your own vector into
419 // push_back()! Since we're using references,
420 // resize() may munge the element storage!
421 // OVR_ASSERT(&val < &Buffer[0] || &val > &Buffer[BufferSize]);
422 Data.PushBack(val);
423 }
425 template<class S>
426 void PushBackAlt(const S& val)
427 {
428 Data.PushBackAlt(val);
429 }
431 // Remove the last element.
432 void PopBack(UPInt count = 1)
433 {
434 OVR_ASSERT(Data.Size >= count);
435 Data.Resize(Data.Size - count);
436 }
438 ValueType& PushDefault()
439 {
440 Data.PushBack(ValueType());
441 return Back();
442 }
444 ValueType Pop()
445 {
446 ValueType t = Back();
447 PopBack();
448 return t;
449 }
452 // Access the first element.
453 ValueType& Front() { return At(0); }
454 const ValueType& Front() const { return At(0); }
456 // Access the last element.
457 ValueType& Back() { return At(Data.Size - 1); }
458 const ValueType& Back() const { return At(Data.Size - 1); }
460 // Array copy. Copies the contents of a into this array.
461 const SelfType& operator = (const SelfType& a)
462 {
463 Resize(a.GetSize());
464 for (UPInt i = 0; i < Data.Size; i++) {
465 *(Data.Data + i) = a[i];
466 }
467 return *this;
468 }
470 // Removing multiple elements from the array.
471 void RemoveMultipleAt(UPInt index, UPInt num)
472 {
473 OVR_ASSERT(index + num <= Data.Size);
474 if (Data.Size == num)
475 {
476 Clear();
477 }
478 else
479 {
480 AllocatorType::DestructArray(Data.Data + index, num);
481 AllocatorType::CopyArrayForward(
482 Data.Data + index,
483 Data.Data + index + num,
484 Data.Size - num - index);
485 Data.Size -= num;
486 }
487 }
489 // Removing an element from the array is an expensive operation!
490 // It compacts only after removing the last element.
491 void RemoveAt(UPInt index)
492 {
493 OVR_ASSERT(index < Data.Size);
494 if (Data.Size == 1)
495 {
496 Clear();
497 }
498 else
499 {
500 AllocatorType::Destruct(Data.Data + index);
501 AllocatorType::CopyArrayForward(
502 Data.Data + index,
503 Data.Data + index + 1,
504 Data.Size - 1 - index);
505 --Data.Size;
506 }
507 }
509 // Insert the given object at the given index shifting all the elements up.
510 void InsertAt(UPInt index, const ValueType& val = ValueType())
511 {
512 OVR_ASSERT(index <= Data.Size);
514 Data.Resize(Data.Size + 1);
515 if (index < Data.Size - 1)
516 {
517 AllocatorType::CopyArrayBackward(
518 Data.Data + index + 1,
519 Data.Data + index,
520 Data.Size - 1 - index);
521 }
522 AllocatorType::Construct(Data.Data + index, val);
523 }
525 // Insert the given object at the given index shifting all the elements up.
526 void InsertMultipleAt(UPInt index, UPInt num, const ValueType& val = ValueType())
527 {
528 OVR_ASSERT(index <= Data.Size);
530 Data.Resize(Data.Size + num);
531 if (index < Data.Size - num)
532 {
533 AllocatorType::CopyArrayBackward(
534 Data.Data + index + num,
535 Data.Data + index,
536 Data.Size - num - index);
537 }
538 for (UPInt i = 0; i < num; ++i)
539 AllocatorType::Construct(Data.Data + index + i, val);
540 }
542 // Append the given data to the array.
543 void Append(const SelfType& other)
544 {
545 Append(other.Data.Data, other.GetSize());
546 }
548 // Append the given data to the array.
549 void Append(const ValueType other[], UPInt count)
550 {
551 Data.Append(other, count);
552 }
554 class Iterator
555 {
556 SelfType* pArray;
557 SPInt CurIndex;
559 public:
560 Iterator() : pArray(0), CurIndex(-1) {}
561 Iterator(SelfType* parr, SPInt idx = 0) : pArray(parr), CurIndex(idx) {}
563 bool operator==(const Iterator& it) const { return pArray == it.pArray && CurIndex == it.CurIndex; }
564 bool operator!=(const Iterator& it) const { return pArray != it.pArray || CurIndex != it.CurIndex; }
566 Iterator& operator++()
567 {
568 if (pArray)
569 {
570 if (CurIndex < (SPInt)pArray->GetSize())
571 ++CurIndex;
572 }
573 return *this;
574 }
575 Iterator operator++(int)
576 {
577 Iterator it(*this);
578 operator++();
579 return it;
580 }
581 Iterator& operator--()
582 {
583 if (pArray)
584 {
585 if (CurIndex >= 0)
586 --CurIndex;
587 }
588 return *this;
589 }
590 Iterator operator--(int)
591 {
592 Iterator it(*this);
593 operator--();
594 return it;
595 }
596 Iterator operator+(int delta) const
597 {
598 return Iterator(pArray, CurIndex + delta);
599 }
600 Iterator operator-(int delta) const
601 {
602 return Iterator(pArray, CurIndex - delta);
603 }
604 SPInt operator-(const Iterator& right) const
605 {
606 OVR_ASSERT(pArray == right.pArray);
607 return CurIndex - right.CurIndex;
608 }
609 ValueType& operator*() const { OVR_ASSERT(pArray); return (*pArray)[CurIndex]; }
610 ValueType* operator->() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
611 ValueType* GetPtr() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
613 bool IsFinished() const { return !pArray || CurIndex < 0 || CurIndex >= (int)pArray->GetSize(); }
615 void Remove()
616 {
617 if (!IsFinished())
618 pArray->RemoveAt(CurIndex);
619 }
621 SPInt GetIndex() const { return CurIndex; }
622 };
624 Iterator Begin() { return Iterator(this); }
625 Iterator End() { return Iterator(this, (SPInt)GetSize()); }
626 Iterator Last() { return Iterator(this, (SPInt)GetSize() - 1); }
628 class ConstIterator
629 {
630 const SelfType* pArray;
631 SPInt CurIndex;
633 public:
634 ConstIterator() : pArray(0), CurIndex(-1) {}
635 ConstIterator(const SelfType* parr, SPInt idx = 0) : pArray(parr), CurIndex(idx) {}
637 bool operator==(const ConstIterator& it) const { return pArray == it.pArray && CurIndex == it.CurIndex; }
638 bool operator!=(const ConstIterator& it) const { return pArray != it.pArray || CurIndex != it.CurIndex; }
640 ConstIterator& operator++()
641 {
642 if (pArray)
643 {
644 if (CurIndex < (int)pArray->GetSize())
645 ++CurIndex;
646 }
647 return *this;
648 }
649 ConstIterator operator++(int)
650 {
651 ConstIterator it(*this);
652 operator++();
653 return it;
654 }
655 ConstIterator& operator--()
656 {
657 if (pArray)
658 {
659 if (CurIndex >= 0)
660 --CurIndex;
661 }
662 return *this;
663 }
664 ConstIterator operator--(int)
665 {
666 ConstIterator it(*this);
667 operator--();
668 return it;
669 }
670 ConstIterator operator+(int delta) const
671 {
672 return ConstIterator(pArray, CurIndex + delta);
673 }
674 ConstIterator operator-(int delta) const
675 {
676 return ConstIterator(pArray, CurIndex - delta);
677 }
678 SPInt operator-(const ConstIterator& right) const
679 {
680 OVR_ASSERT(pArray == right.pArray);
681 return CurIndex - right.CurIndex;
682 }
683 const ValueType& operator*() const { OVR_ASSERT(pArray); return (*pArray)[CurIndex]; }
684 const ValueType* operator->() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
685 const ValueType* GetPtr() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
687 bool IsFinished() const { return !pArray || CurIndex < 0 || CurIndex >= (int)pArray->GetSize(); }
689 SPInt GetIndex() const { return CurIndex; }
690 };
691 ConstIterator Begin() const { return ConstIterator(this); }
692 ConstIterator End() const { return ConstIterator(this, (SPInt)GetSize()); }
693 ConstIterator Last() const { return ConstIterator(this, (SPInt)GetSize() - 1); }
695 protected:
696 ArrayData Data;
697 };
701 //-----------------------------------------------------------------------------------
702 // ***** Array
703 //
704 // General purpose array for movable objects that require explicit
705 // construction/destruction.
706 template<class T, class SizePolicy=ArrayDefaultPolicy>
707 class Array : public ArrayBase<ArrayData<T, ContainerAllocator<T>, SizePolicy> >
708 {
709 public:
710 typedef T ValueType;
711 typedef ContainerAllocator<T> AllocatorType;
712 typedef SizePolicy SizePolicyType;
713 typedef Array<T, SizePolicy> SelfType;
714 typedef ArrayBase<ArrayData<T, ContainerAllocator<T>, SizePolicy> > BaseType;
716 Array() : BaseType() {}
717 Array(int size) : BaseType(size) {}
718 Array(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); }
719 Array(const SelfType& a) : BaseType(a) {}
720 const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
721 };
723 // ***** ArrayPOD
724 //
725 // General purpose array for movable objects that DOES NOT require
726 // construction/destruction. Constructors and destructors are not called!
727 // Global heap is in use.
728 template<class T, class SizePolicy=ArrayDefaultPolicy>
729 class ArrayPOD : public ArrayBase<ArrayData<T, ContainerAllocator_POD<T>, SizePolicy> >
730 {
731 public:
732 typedef T ValueType;
733 typedef ContainerAllocator_POD<T> AllocatorType;
734 typedef SizePolicy SizePolicyType;
735 typedef ArrayPOD<T, SizePolicy> SelfType;
736 typedef ArrayBase<ArrayData<T, ContainerAllocator_POD<T>, SizePolicy> > BaseType;
738 ArrayPOD() : BaseType() {}
739 ArrayPOD(int size) : BaseType(size) {}
740 ArrayPOD(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); }
741 ArrayPOD(const SelfType& a) : BaseType(a) {}
742 const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
743 };
746 // ***** ArrayCPP
747 //
748 // General purpose, fully C++ compliant array. Can be used with non-movable data.
749 // Global heap is in use.
750 template<class T, class SizePolicy=ArrayDefaultPolicy>
751 class ArrayCPP : public ArrayBase<ArrayData<T, ContainerAllocator_CPP<T>, SizePolicy> >
752 {
753 public:
754 typedef T ValueType;
755 typedef ContainerAllocator_CPP<T> AllocatorType;
756 typedef SizePolicy SizePolicyType;
757 typedef ArrayCPP<T, SizePolicy> SelfType;
758 typedef ArrayBase<ArrayData<T, ContainerAllocator_CPP<T>, SizePolicy> > BaseType;
760 ArrayCPP() : BaseType() {}
761 ArrayCPP(int size) : BaseType(size) {}
762 ArrayCPP(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); }
763 ArrayCPP(const SelfType& a) : BaseType(a) {}
764 const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
765 };
768 // ***** ArrayCC
769 //
770 // A modification of the array that uses the given default value to
771 // construct the elements. The constructors and destructors are
772 // properly called, the objects must be movable.
774 template<class T, class SizePolicy=ArrayDefaultPolicy>
775 class ArrayCC : public ArrayBase<ArrayDataCC<T, ContainerAllocator<T>, SizePolicy> >
776 {
777 public:
778 typedef T ValueType;
779 typedef ContainerAllocator<T> AllocatorType;
780 typedef SizePolicy SizePolicyType;
781 typedef ArrayCC<T, SizePolicy> SelfType;
782 typedef ArrayBase<ArrayDataCC<T, ContainerAllocator<T>, SizePolicy> > BaseType;
784 ArrayCC(const ValueType& defval) : BaseType(defval) {}
785 ArrayCC(const ValueType& defval, int size) : BaseType(defval, size) {}
786 ArrayCC(const ValueType& defval, const SizePolicyType& p) : BaseType(defval) { SetSizePolicy(p); }
787 ArrayCC(const SelfType& a) : BaseType(a) {}
788 const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
789 };
791 } // OVR
793 #endif