ovr_sdk

view LibOVR/Src/Kernel/OVR_Array.h @ 0:1b39a1b46319

initial 0.4.4
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 14 Jan 2015 06:51:16 +0200
parents
children
line source
1 /************************************************************************************
3 PublicHeader: OVR_Kernel.h
4 Filename : OVR_Array.h
5 Content : Template implementation for Array
6 Created : September 19, 2012
7 Notes :
9 Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
11 Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
12 you may not use the Oculus VR Rift SDK except in compliance with the License,
13 which is provided at the time of installation or download, or which
14 otherwise accompanies this software in either electronic or hard copy form.
16 You may obtain a copy of the License at
18 http://www.oculusvr.com/licenses/LICENSE-3.2
20 Unless required by applicable law or agreed to in writing, the Oculus VR SDK
21 distributed under the License is distributed on an "AS IS" BASIS,
22 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 See the License for the specific language governing permissions and
24 limitations under the License.
26 ************************************************************************************/
28 #ifndef OVR_Array_h
29 #define OVR_Array_h
31 #include "OVR_ContainerAllocator.h"
33 namespace OVR {
35 //-----------------------------------------------------------------------------------
36 // ***** ArrayDefaultPolicy
37 //
38 // Default resize behavior. No minimal capacity, Granularity=4,
39 // Shrinking as needed. ArrayConstPolicy actually is the same as
40 // ArrayDefaultPolicy, but parametrized with constants.
41 // This struct is used only in order to reduce the template "matroska".
42 struct ArrayDefaultPolicy
43 {
44 ArrayDefaultPolicy() : Capacity(0) {}
45 ArrayDefaultPolicy(const ArrayDefaultPolicy&) : Capacity(0) {}
47 size_t GetMinCapacity() const { return 0; }
48 size_t GetGranularity() const { return 4; }
49 bool NeverShrinking() const { return 0; }
51 size_t GetCapacity() const { return Capacity; }
52 void SetCapacity(size_t capacity) { Capacity = capacity; }
53 private:
54 size_t Capacity;
55 };
58 //-----------------------------------------------------------------------------------
59 // ***** ArrayConstPolicy
60 //
61 // Statically parametrized resizing behavior:
62 // MinCapacity, Granularity, and Shrinking flag.
63 template<int MinCapacity=0, int Granularity=4, bool NeverShrink=false>
64 struct ArrayConstPolicy
65 {
66 typedef ArrayConstPolicy<MinCapacity, Granularity, NeverShrink> SelfType;
68 ArrayConstPolicy() : Capacity(0) {}
69 ArrayConstPolicy(const SelfType&) : Capacity(0) {}
71 size_t GetMinCapacity() const { return MinCapacity; }
72 size_t GetGranularity() const { return Granularity; }
73 bool NeverShrinking() const { return NeverShrink; }
75 size_t GetCapacity() const { return Capacity; }
76 void SetCapacity(size_t capacity) { Capacity = capacity; }
77 private:
78 size_t Capacity;
79 };
81 //-----------------------------------------------------------------------------------
82 // ***** ArrayDataBase
83 //
84 // Basic operations with array data: Reserve, Resize, Free, ArrayPolicy.
85 // For internal use only: ArrayData,ArrayDataCC and others.
86 template<class T, class Allocator, class SizePolicy>
87 struct ArrayDataBase
88 {
89 typedef T ValueType;
90 typedef Allocator AllocatorType;
91 typedef SizePolicy SizePolicyType;
92 typedef ArrayDataBase<T, Allocator, SizePolicy> SelfType;
94 ArrayDataBase()
95 : Data(0), Size(0), Policy() {}
97 ArrayDataBase(const SizePolicy& p)
98 : Data(0), Size(0), Policy(p) {}
100 ~ArrayDataBase()
101 {
102 Allocator::DestructArray(Data, Size);
103 Allocator::Free(Data);
104 }
106 size_t GetCapacity() const
107 {
108 return Policy.GetCapacity();
109 }
111 void ClearAndRelease()
112 {
113 Allocator::DestructArray(Data, Size);
114 Allocator::Free(Data);
115 Data = 0;
116 Size = 0;
117 Policy.SetCapacity(0);
118 }
120 void Reserve(size_t newCapacity)
121 {
122 if (Policy.NeverShrinking() && newCapacity < GetCapacity())
123 return;
125 if (newCapacity < Policy.GetMinCapacity())
126 newCapacity = Policy.GetMinCapacity();
128 // Resize the buffer.
129 if (newCapacity == 0)
130 {
131 if (Data)
132 {
133 Allocator::Free(Data);
134 Data = 0;
135 }
136 Policy.SetCapacity(0);
137 }
138 else
139 {
140 size_t gran = Policy.GetGranularity();
141 newCapacity = (newCapacity + gran - 1) / gran * gran;
142 if (Data)
143 {
144 if (Allocator::IsMovable())
145 {
146 Data = (T*)Allocator::Realloc(Data, sizeof(T) * newCapacity);
147 }
148 else
149 {
150 T* newData = (T*)Allocator::Alloc(sizeof(T) * newCapacity);
151 size_t i, s;
152 s = (Size < newCapacity) ? Size : newCapacity;
153 for (i = 0; i < s; ++i)
154 {
155 Allocator::Construct(&newData[i], Data[i]);
156 Allocator::Destruct(&Data[i]);
157 }
158 for (i = s; i < Size; ++i)
159 {
160 Allocator::Destruct(&Data[i]);
161 }
162 Allocator::Free(Data);
163 Data = newData;
164 }
165 }
166 else
167 {
168 Data = (T*)Allocator::Alloc(sizeof(T) * newCapacity);
169 //memset(Buffer, 0, (sizeof(ValueType) * newSize)); // Do we need this?
170 }
171 Policy.SetCapacity(newCapacity);
172 // OVR_ASSERT(Data); // need to throw (or something) on alloc failure!
173 }
174 }
176 // This version of Resize DOES NOT construct the elements.
177 // It's done to optimize PushBack, which uses a copy constructor
178 // instead of the default constructor and assignment
179 void ResizeNoConstruct(size_t newSize)
180 {
181 size_t oldSize = Size;
183 if (newSize < oldSize)
184 {
185 Allocator::DestructArray(Data + newSize, oldSize - newSize);
186 if (newSize < (Policy.GetCapacity() >> 1))
187 {
188 Reserve(newSize);
189 }
190 }
191 else if(newSize >= Policy.GetCapacity())
192 {
193 Reserve(newSize + (newSize >> 2));
194 }
195 //! IMPORTANT to modify Size only after Reserve completes, because garbage collectable
196 // array may use this array and may traverse it during Reserve (in the case, if
197 // collection occurs because of heap limit exceeded).
198 Size = newSize;
199 }
201 ValueType* Data;
202 size_t Size;
203 SizePolicy Policy;
204 };
208 //-----------------------------------------------------------------------------------
209 // ***** ArrayData
210 //
211 // General purpose array data.
212 // For internal use only in Array, ArrayLH, ArrayPOD and so on.
213 template<class T, class Allocator, class SizePolicy>
214 struct ArrayData : ArrayDataBase<T, Allocator, SizePolicy>
215 {
216 typedef T ValueType;
217 typedef Allocator AllocatorType;
218 typedef SizePolicy SizePolicyType;
219 typedef ArrayDataBase<T, Allocator, SizePolicy> BaseType;
220 typedef ArrayData <T, Allocator, SizePolicy> SelfType;
222 ArrayData()
223 : BaseType() { }
225 ArrayData(size_t size)
226 : BaseType() { Resize(size); }
228 ArrayData(const SelfType& a)
229 : BaseType(a.Policy) { Append(a.Data, a.Size); }
232 void Resize(size_t newSize)
233 {
234 size_t oldSize = this->Size;
235 BaseType::ResizeNoConstruct(newSize);
236 if(newSize > oldSize)
237 Allocator::ConstructArray(this->Data + oldSize, newSize - oldSize);
238 }
240 void PushBack(const ValueType& val)
241 {
242 BaseType::ResizeNoConstruct(this->Size + 1);
243 OVR_ASSERT(this->Data != NULL);
244 Allocator::Construct(this->Data + this->Size - 1, val);
245 }
247 template<class S>
248 void PushBackAlt(const S& val)
249 {
250 BaseType::ResizeNoConstruct(this->Size + 1);
251 Allocator::ConstructAlt(this->Data + this->Size - 1, val);
252 }
254 // Append the given data to the array.
255 void Append(const ValueType other[], size_t count)
256 {
257 if (count)
258 {
259 size_t oldSize = this->Size;
260 BaseType::ResizeNoConstruct(this->Size + count);
261 Allocator::ConstructArray(this->Data + oldSize, count, other);
262 }
263 }
264 };
268 //-----------------------------------------------------------------------------------
269 // ***** ArrayDataCC
270 //
271 // A modification of ArrayData that always copy-constructs new elements
272 // using a specified DefaultValue. For internal use only in ArrayCC.
273 template<class T, class Allocator, class SizePolicy>
274 struct ArrayDataCC : ArrayDataBase<T, Allocator, SizePolicy>
275 {
276 typedef T ValueType;
277 typedef Allocator AllocatorType;
278 typedef SizePolicy SizePolicyType;
279 typedef ArrayDataBase<T, Allocator, SizePolicy> BaseType;
280 typedef ArrayDataCC <T, Allocator, SizePolicy> SelfType;
282 ArrayDataCC(const ValueType& defval)
283 : BaseType(), DefaultValue(defval) { }
285 ArrayDataCC(const ValueType& defval, size_t size)
286 : BaseType(), DefaultValue(defval) { Resize(size); }
288 ArrayDataCC(const SelfType& a)
289 : BaseType(a.Policy), DefaultValue(a.DefaultValue) { Append(a.Data, a.Size); }
292 void Resize(size_t newSize)
293 {
294 size_t oldSize = this->Size;
295 BaseType::ResizeNoConstruct(newSize);
296 if(newSize > oldSize)
297 Allocator::ConstructArray(this->Data + oldSize, newSize - oldSize, DefaultValue);
298 }
300 void PushBack(const ValueType& val)
301 {
302 BaseType::ResizeNoConstruct(this->Size + 1);
303 Allocator::Construct(this->Data + this->Size - 1, val);
304 }
306 template<class S>
307 void PushBackAlt(const S& val)
308 {
309 BaseType::ResizeNoConstruct(this->Size + 1);
310 Allocator::ConstructAlt(this->Data + this->Size - 1, val);
311 }
313 // Append the given data to the array.
314 void Append(const ValueType other[], size_t count)
315 {
316 if (count)
317 {
318 size_t oldSize = this->Size;
319 BaseType::ResizeNoConstruct(this->Size + count);
320 Allocator::ConstructArray(this->Data + oldSize, count, other);
321 }
322 }
324 ValueType DefaultValue;
325 };
331 //-----------------------------------------------------------------------------------
332 // ***** ArrayBase
333 //
334 // Resizable array. The behavior can be POD (suffix _POD) and
335 // Movable (no suffix) depending on the allocator policy.
336 // In case of _POD the constructors and destructors are not called.
337 //
338 // Arrays can't handle non-movable objects! Don't put anything in here
339 // that can't be moved around by bitwise copy.
340 //
341 // The addresses of elements are not persistent! Don't keep the address
342 // of an element; the array contents will move around as it gets resized.
343 template<class ArrayData>
344 class ArrayBase
345 {
346 public:
347 typedef typename ArrayData::ValueType ValueType;
348 typedef typename ArrayData::AllocatorType AllocatorType;
349 typedef typename ArrayData::SizePolicyType SizePolicyType;
350 typedef ArrayBase<ArrayData> SelfType;
353 #undef new
354 OVR_MEMORY_REDEFINE_NEW(ArrayBase)
355 // Redefine operator 'new' if necessary.
356 #if defined(OVR_DEFINE_NEW)
357 #define new OVR_DEFINE_NEW
358 #endif
361 ArrayBase()
362 : Data() {}
363 ArrayBase(size_t size)
364 : Data(size) {}
365 ArrayBase(const SelfType& a)
366 : Data(a.Data) {}
368 ArrayBase(const ValueType& defval)
369 : Data(defval) {}
370 ArrayBase(const ValueType& defval, size_t size)
371 : Data(defval, size) {}
373 SizePolicyType* GetSizePolicy() const { return Data.Policy; }
374 void SetSizePolicy(const SizePolicyType& p) { Data.Policy = p; }
376 bool NeverShrinking()const { return Data.Policy.NeverShrinking(); }
377 size_t GetSize() const { return Data.Size; }
378 int GetSizeI() const { return (int)Data.Size; }
379 bool IsEmpty() const { return Data.Size == 0; }
380 size_t GetCapacity() const { return Data.GetCapacity(); }
381 size_t GetNumBytes() const { return Data.GetCapacity() * sizeof(ValueType); }
383 void ClearAndRelease() { Data.ClearAndRelease(); }
384 void Clear() { Data.Resize(0); }
385 void Resize(size_t newSize) { Data.Resize(newSize); }
387 // Reserve can only increase the capacity
388 void Reserve(size_t newCapacity)
389 {
390 if (newCapacity > Data.GetCapacity())
391 Data.Reserve(newCapacity);
392 }
394 // Basic access.
395 ValueType& At(size_t index)
396 {
397 OVR_ASSERT((Data.Data) && (index < Data.Size)); // Asserting that Data.Data is valid helps static analysis tools.
398 return Data.Data[index];
399 }
400 const ValueType& At(size_t index) const
401 {
402 OVR_ASSERT((Data.Data) && (index < Data.Size));
403 return Data.Data[index];
404 }
406 ValueType ValueAt(size_t index) const
407 {
408 OVR_ASSERT((Data.Data) && (index < Data.Size));
409 return Data.Data[index];
410 }
412 // Basic access.
413 ValueType& operator [] (size_t index)
414 {
415 OVR_ASSERT((Data.Data) && (index < Data.Size));
416 return Data.Data[index];
417 }
418 const ValueType& operator [] (size_t index) const
419 {
420 OVR_ASSERT((Data.Data) && (index < Data.Size));
421 return Data.Data[index];
422 }
424 // Raw pointer to the data. Use with caution!
425 const ValueType* GetDataPtr() const { return Data.Data; }
426 ValueType* GetDataPtr() { return Data.Data; }
428 // Insert the given element at the end of the array.
429 void PushBack(const ValueType& val)
430 {
431 // DO NOT pass elements of your own vector into
432 // push_back()! Since we're using references,
433 // resize() may munge the element storage!
434 // OVR_ASSERT(&val < &Buffer[0] || &val > &Buffer[BufferSize]);
435 Data.PushBack(val);
436 }
438 template<class S>
439 void PushBackAlt(const S& val)
440 {
441 Data.PushBackAlt(val);
442 }
444 // Remove the last element.
445 void PopBack(size_t count = 1)
446 {
447 OVR_ASSERT(Data.Size >= count);
448 Data.Resize(Data.Size - count);
449 }
451 ValueType& PushDefault()
452 {
453 Data.PushBack(ValueType());
454 return Back();
455 }
457 ValueType Pop()
458 {
459 OVR_ASSERT((Data.Data) && (Data.Size > 0));
460 ValueType t = Back();
461 PopBack();
462 return t;
463 }
466 // Access the first element.
467 ValueType& Front() { return At(0); }
468 const ValueType& Front() const { return At(0); }
470 // Access the last element.
471 ValueType& Back() { return At(Data.Size - 1); }
472 const ValueType& Back() const { return At(Data.Size - 1); }
474 // Array copy. Copies the contents of a into this array.
475 const SelfType& operator = (const SelfType& a)
476 {
477 Resize(a.GetSize());
478 OVR_ASSERT((Data.Data != NULL) || (Data.Size == 0));
479 for (size_t i = 0; i < Data.Size; i++) {
480 *(Data.Data + i) = a[i];
481 }
482 return *this;
483 }
485 // Removing multiple elements from the array.
486 void RemoveMultipleAt(size_t index, size_t num)
487 {
488 OVR_ASSERT(index + num <= Data.Size);
489 if (Data.Size == num)
490 {
491 Clear();
492 }
493 else
494 {
495 AllocatorType::DestructArray(Data.Data + index, num);
496 AllocatorType::CopyArrayForward(
497 Data.Data + index,
498 Data.Data + index + num,
499 Data.Size - num - index);
500 Data.Size -= num;
501 }
502 }
504 // Removing an element from the array is an expensive operation!
505 // It compacts only after removing the last element.
506 // If order of elements in the array is not important then use
507 // RemoveAtUnordered, that could be much faster than the regular
508 // RemoveAt.
509 void RemoveAt(size_t index)
510 {
511 OVR_ASSERT((Data.Data) && (index < Data.Size));
512 if (Data.Size == 1)
513 {
514 Clear();
515 }
516 else
517 {
518 AllocatorType::Destruct(Data.Data + index);
519 AllocatorType::CopyArrayForward(
520 Data.Data + index,
521 Data.Data + index + 1,
522 Data.Size - 1 - index);
523 --Data.Size;
524 }
525 }
527 // Removes an element from the array without respecting of original order of
528 // elements for better performance. Do not use on array where order of elements
529 // is important, otherwise use it instead of regular RemoveAt().
530 void RemoveAtUnordered(size_t index)
531 {
532 OVR_ASSERT((Data.Data) && (index < Data.Size));
533 if (Data.Size == 1)
534 {
535 Clear();
536 }
537 else
538 {
539 // copy the last element into the 'index' position
540 // and decrement the size (instead of moving all elements
541 // in [index + 1 .. size - 1] range).
542 const size_t lastElemIndex = Data.Size - 1;
543 if (index < lastElemIndex)
544 {
545 AllocatorType::Destruct(Data.Data + index);
546 AllocatorType::Construct(Data.Data + index, Data.Data[lastElemIndex]);
547 }
548 AllocatorType::Destruct(Data.Data + lastElemIndex);
549 --Data.Size;
550 }
551 }
553 // Insert the given object at the given index shifting all the elements up.
554 void InsertAt(size_t index, const ValueType& val = ValueType())
555 {
556 OVR_ASSERT(index <= Data.Size);
558 Data.Resize(Data.Size + 1);
559 if (index < Data.Size - 1)
560 {
561 AllocatorType::CopyArrayBackward(
562 Data.Data + index + 1,
563 Data.Data + index,
564 Data.Size - 1 - index);
565 }
566 AllocatorType::Construct(Data.Data + index, val);
567 }
569 // Insert the given object at the given index shifting all the elements up.
570 void InsertMultipleAt(size_t index, size_t num, const ValueType& val = ValueType())
571 {
572 OVR_ASSERT(index <= Data.Size);
574 Data.Resize(Data.Size + num);
575 if (index < Data.Size - num)
576 {
577 AllocatorType::CopyArrayBackward(
578 Data.Data + index + num,
579 Data.Data + index,
580 Data.Size - num - index);
581 }
582 for (size_t i = 0; i < num; ++i)
583 AllocatorType::Construct(Data.Data + index + i, val);
584 }
586 // Append the given data to the array.
587 void Append(const SelfType& other)
588 {
589 Append(other.Data.Data, other.GetSize());
590 }
592 // Append the given data to the array.
593 void Append(const ValueType other[], size_t count)
594 {
595 Data.Append(other, count);
596 }
598 class Iterator
599 {
600 SelfType* pArray;
601 intptr_t CurIndex;
603 public:
604 Iterator() : pArray(0), CurIndex(-1) {}
605 Iterator(SelfType* parr, intptr_t idx = 0) : pArray(parr), CurIndex(idx) {}
607 bool operator==(const Iterator& it) const { return pArray == it.pArray && CurIndex == it.CurIndex; }
608 bool operator!=(const Iterator& it) const { return pArray != it.pArray || CurIndex != it.CurIndex; }
610 Iterator& operator++()
611 {
612 if (pArray)
613 {
614 if (CurIndex < (intptr_t)pArray->GetSize())
615 ++CurIndex;
616 }
617 return *this;
618 }
619 Iterator operator++(int)
620 {
621 Iterator it(*this);
622 operator++();
623 return it;
624 }
625 Iterator& operator--()
626 {
627 if (pArray)
628 {
629 if (CurIndex >= 0)
630 --CurIndex;
631 }
632 return *this;
633 }
634 Iterator operator--(int)
635 {
636 Iterator it(*this);
637 operator--();
638 return it;
639 }
640 Iterator operator+(int delta) const
641 {
642 return Iterator(pArray, CurIndex + delta);
643 }
644 Iterator operator-(int delta) const
645 {
646 return Iterator(pArray, CurIndex - delta);
647 }
648 intptr_t operator-(const Iterator& right) const
649 {
650 OVR_ASSERT(pArray == right.pArray);
651 return CurIndex - right.CurIndex;
652 }
653 ValueType& operator*() const { OVR_ASSERT(pArray); return (*pArray)[CurIndex]; }
654 ValueType* operator->() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
655 ValueType* GetPtr() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
657 bool IsFinished() const { return !pArray || CurIndex < 0 || CurIndex >= (int)pArray->GetSize(); }
659 void Remove()
660 {
661 if (!IsFinished())
662 pArray->RemoveAt(CurIndex);
663 }
665 intptr_t GetIndex() const { return CurIndex; }
666 };
668 Iterator Begin() { return Iterator(this); }
669 Iterator End() { return Iterator(this, (intptr_t)GetSize()); }
670 Iterator Last() { return Iterator(this, (intptr_t)GetSize() - 1); }
672 class ConstIterator
673 {
674 const SelfType* pArray;
675 intptr_t CurIndex;
677 public:
678 ConstIterator() : pArray(0), CurIndex(-1) {}
679 ConstIterator(const SelfType* parr, intptr_t idx = 0) : pArray(parr), CurIndex(idx) {}
681 bool operator==(const ConstIterator& it) const { return pArray == it.pArray && CurIndex == it.CurIndex; }
682 bool operator!=(const ConstIterator& it) const { return pArray != it.pArray || CurIndex != it.CurIndex; }
684 ConstIterator& operator++()
685 {
686 if (pArray)
687 {
688 if (CurIndex < (int)pArray->GetSize())
689 ++CurIndex;
690 }
691 return *this;
692 }
693 ConstIterator operator++(int)
694 {
695 ConstIterator it(*this);
696 operator++();
697 return it;
698 }
699 ConstIterator& operator--()
700 {
701 if (pArray)
702 {
703 if (CurIndex >= 0)
704 --CurIndex;
705 }
706 return *this;
707 }
708 ConstIterator operator--(int)
709 {
710 ConstIterator it(*this);
711 operator--();
712 return it;
713 }
714 ConstIterator operator+(int delta) const
715 {
716 return ConstIterator(pArray, CurIndex + delta);
717 }
718 ConstIterator operator-(int delta) const
719 {
720 return ConstIterator(pArray, CurIndex - delta);
721 }
722 intptr_t operator-(const ConstIterator& right) const
723 {
724 OVR_ASSERT(pArray == right.pArray);
725 return CurIndex - right.CurIndex;
726 }
727 const ValueType& operator*() const { OVR_ASSERT(pArray); return (*pArray)[CurIndex]; }
728 const ValueType* operator->() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
729 const ValueType* GetPtr() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
731 bool IsFinished() const { return !pArray || CurIndex < 0 || CurIndex >= (int)pArray->GetSize(); }
733 intptr_t GetIndex() const { return CurIndex; }
734 };
735 ConstIterator Begin() const { return ConstIterator(this); }
736 ConstIterator End() const { return ConstIterator(this, (intptr_t)GetSize()); }
737 ConstIterator Last() const { return ConstIterator(this, (intptr_t)GetSize() - 1); }
739 protected:
740 ArrayData Data;
741 };
745 //-----------------------------------------------------------------------------------
746 // ***** Array
747 //
748 // General purpose array for movable objects that require explicit
749 // construction/destruction.
750 template<class T, class SizePolicy=ArrayDefaultPolicy>
751 class Array : public ArrayBase<ArrayData<T, ContainerAllocator<T>, SizePolicy> >
752 {
753 public:
754 typedef T ValueType;
755 typedef ContainerAllocator<T> AllocatorType;
756 typedef SizePolicy SizePolicyType;
757 typedef Array<T, SizePolicy> SelfType;
758 typedef ArrayBase<ArrayData<T, ContainerAllocator<T>, SizePolicy> > BaseType;
760 Array() : BaseType() {}
761 Array(size_t size) : BaseType(size) {}
762 Array(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); }
763 Array(const SelfType& a) : BaseType(a) {}
764 const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
765 };
767 // ***** ArrayPOD
768 //
769 // General purpose array for movable objects that DOES NOT require
770 // construction/destruction. Constructors and destructors are not called!
771 // Global heap is in use.
772 template<class T, class SizePolicy=ArrayDefaultPolicy>
773 class ArrayPOD : public ArrayBase<ArrayData<T, ContainerAllocator_POD<T>, SizePolicy> >
774 {
775 public:
776 typedef T ValueType;
777 typedef ContainerAllocator_POD<T> AllocatorType;
778 typedef SizePolicy SizePolicyType;
779 typedef ArrayPOD<T, SizePolicy> SelfType;
780 typedef ArrayBase<ArrayData<T, ContainerAllocator_POD<T>, SizePolicy> > BaseType;
782 ArrayPOD() : BaseType() {}
783 ArrayPOD(size_t size) : BaseType(size) {}
784 ArrayPOD(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); }
785 ArrayPOD(const SelfType& a) : BaseType(a) {}
786 const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
787 };
790 // ***** ArrayCPP
791 //
792 // General purpose, fully C++ compliant array. Can be used with non-movable data.
793 // Global heap is in use.
794 template<class T, class SizePolicy=ArrayDefaultPolicy>
795 class ArrayCPP : public ArrayBase<ArrayData<T, ContainerAllocator_CPP<T>, SizePolicy> >
796 {
797 public:
798 typedef T ValueType;
799 typedef ContainerAllocator_CPP<T> AllocatorType;
800 typedef SizePolicy SizePolicyType;
801 typedef ArrayCPP<T, SizePolicy> SelfType;
802 typedef ArrayBase<ArrayData<T, ContainerAllocator_CPP<T>, SizePolicy> > BaseType;
804 ArrayCPP() : BaseType() {}
805 ArrayCPP(size_t size) : BaseType(size) {}
806 ArrayCPP(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); }
807 ArrayCPP(const SelfType& a) : BaseType(a) {}
808 const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
809 };
812 // ***** ArrayCC
813 //
814 // A modification of the array that uses the given default value to
815 // construct the elements. The constructors and destructors are
816 // properly called, the objects must be movable.
818 template<class T, class SizePolicy=ArrayDefaultPolicy>
819 class ArrayCC : public ArrayBase<ArrayDataCC<T, ContainerAllocator<T>, SizePolicy> >
820 {
821 public:
822 typedef T ValueType;
823 typedef ContainerAllocator<T> AllocatorType;
824 typedef SizePolicy SizePolicyType;
825 typedef ArrayCC<T, SizePolicy> SelfType;
826 typedef ArrayBase<ArrayDataCC<T, ContainerAllocator<T>, SizePolicy> > BaseType;
828 ArrayCC(const ValueType& defval) : BaseType(defval) {}
829 ArrayCC(const ValueType& defval, size_t size) : BaseType(defval, size) {}
830 ArrayCC(const ValueType& defval, const SizePolicyType& p) : BaseType(defval) { SetSizePolicy(p); }
831 ArrayCC(const SelfType& a) : BaseType(a) {}
832 const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
833 };
835 } // OVR
837 #endif