oculus1
diff libovr/Src/Kernel/OVR_Array.h @ 3:b069a5c27388
added a couple more stuff, fixed all the LibOVR line endings
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 15 Sep 2013 04:10:05 +0300 |
parents | e2f9e4603129 |
children |
line diff
1.1 --- a/libovr/Src/Kernel/OVR_Array.h Sat Sep 14 17:51:03 2013 +0300 1.2 +++ b/libovr/Src/Kernel/OVR_Array.h Sun Sep 15 04:10:05 2013 +0300 1.3 @@ -1,1 +1,793 @@ 1.4 -/************************************************************************************ 1.5 1.6 PublicHeader: OVR.h 1.7 Filename : OVR_Array.h 1.8 Content : Template implementation for Array 1.9 Created : September 19, 2012 1.10 Notes : 1.11 1.12 Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. 1.13 1.14 Use of this software is subject to the terms of the Oculus license 1.15 agreement provided at the time of installation or download, or which 1.16 otherwise accompanies this software in either electronic or hard copy form. 1.17 1.18 ************************************************************************************/ 1.19 1.20 #ifndef OVR_Array_h 1.21 #define OVR_Array_h 1.22 1.23 #include "OVR_ContainerAllocator.h" 1.24 1.25 namespace OVR { 1.26 1.27 //----------------------------------------------------------------------------------- 1.28 // ***** ArrayDefaultPolicy 1.29 // 1.30 // Default resize behavior. No minimal capacity, Granularity=4, 1.31 // Shrinking as needed. ArrayConstPolicy actually is the same as 1.32 // ArrayDefaultPolicy, but parametrized with constants. 1.33 // This struct is used only in order to reduce the template "matroska". 1.34 struct ArrayDefaultPolicy 1.35 { 1.36 ArrayDefaultPolicy() : Capacity(0) {} 1.37 ArrayDefaultPolicy(const ArrayDefaultPolicy&) : Capacity(0) {} 1.38 1.39 UPInt GetMinCapacity() const { return 0; } 1.40 UPInt GetGranularity() const { return 4; } 1.41 bool NeverShrinking() const { return 0; } 1.42 1.43 UPInt GetCapacity() const { return Capacity; } 1.44 void SetCapacity(UPInt capacity) { Capacity = capacity; } 1.45 private: 1.46 UPInt Capacity; 1.47 }; 1.48 1.49 1.50 //----------------------------------------------------------------------------------- 1.51 // ***** ArrayConstPolicy 1.52 // 1.53 // Statically parametrized resizing behavior: 1.54 // MinCapacity, Granularity, and Shrinking flag. 1.55 template<int MinCapacity=0, int Granularity=4, bool NeverShrink=false> 1.56 struct ArrayConstPolicy 1.57 { 1.58 typedef ArrayConstPolicy<MinCapacity, Granularity, NeverShrink> SelfType; 1.59 1.60 ArrayConstPolicy() : Capacity(0) {} 1.61 ArrayConstPolicy(const SelfType&) : Capacity(0) {} 1.62 1.63 UPInt GetMinCapacity() const { return MinCapacity; } 1.64 UPInt GetGranularity() const { return Granularity; } 1.65 bool NeverShrinking() const { return NeverShrink; } 1.66 1.67 UPInt GetCapacity() const { return Capacity; } 1.68 void SetCapacity(UPInt capacity) { Capacity = capacity; } 1.69 private: 1.70 UPInt Capacity; 1.71 }; 1.72 1.73 //----------------------------------------------------------------------------------- 1.74 // ***** ArrayDataBase 1.75 // 1.76 // Basic operations with array data: Reserve, Resize, Free, ArrayPolicy. 1.77 // For internal use only: ArrayData,ArrayDataCC and others. 1.78 template<class T, class Allocator, class SizePolicy> 1.79 struct ArrayDataBase 1.80 { 1.81 typedef T ValueType; 1.82 typedef Allocator AllocatorType; 1.83 typedef SizePolicy SizePolicyType; 1.84 typedef ArrayDataBase<T, Allocator, SizePolicy> SelfType; 1.85 1.86 ArrayDataBase() 1.87 : Data(0), Size(0), Policy() {} 1.88 1.89 ArrayDataBase(const SizePolicy& p) 1.90 : Data(0), Size(0), Policy(p) {} 1.91 1.92 ~ArrayDataBase() 1.93 { 1.94 Allocator::DestructArray(Data, Size); 1.95 Allocator::Free(Data); 1.96 } 1.97 1.98 UPInt GetCapacity() const 1.99 { 1.100 return Policy.GetCapacity(); 1.101 } 1.102 1.103 void ClearAndRelease() 1.104 { 1.105 Allocator::DestructArray(Data, Size); 1.106 Allocator::Free(Data); 1.107 Data = 0; 1.108 Size = 0; 1.109 Policy.SetCapacity(0); 1.110 } 1.111 1.112 void Reserve(UPInt newCapacity) 1.113 { 1.114 if (Policy.NeverShrinking() && newCapacity < GetCapacity()) 1.115 return; 1.116 1.117 if (newCapacity < Policy.GetMinCapacity()) 1.118 newCapacity = Policy.GetMinCapacity(); 1.119 1.120 // Resize the buffer. 1.121 if (newCapacity == 0) 1.122 { 1.123 if (Data) 1.124 { 1.125 Allocator::Free(Data); 1.126 Data = 0; 1.127 } 1.128 Policy.SetCapacity(0); 1.129 } 1.130 else 1.131 { 1.132 UPInt gran = Policy.GetGranularity(); 1.133 newCapacity = (newCapacity + gran - 1) / gran * gran; 1.134 if (Data) 1.135 { 1.136 if (Allocator::IsMovable()) 1.137 { 1.138 Data = (T*)Allocator::Realloc(Data, sizeof(T) * newCapacity); 1.139 } 1.140 else 1.141 { 1.142 T* newData = (T*)Allocator::Alloc(sizeof(T) * newCapacity); 1.143 UPInt i, s; 1.144 s = (Size < newCapacity) ? Size : newCapacity; 1.145 for (i = 0; i < s; ++i) 1.146 { 1.147 Allocator::Construct(&newData[i], Data[i]); 1.148 Allocator::Destruct(&Data[i]); 1.149 } 1.150 for (i = s; i < Size; ++i) 1.151 { 1.152 Allocator::Destruct(&Data[i]); 1.153 } 1.154 Allocator::Free(Data); 1.155 Data = newData; 1.156 } 1.157 } 1.158 else 1.159 { 1.160 Data = (T*)Allocator::Alloc(sizeof(T) * newCapacity); 1.161 //memset(Buffer, 0, (sizeof(ValueType) * newSize)); // Do we need this? 1.162 } 1.163 Policy.SetCapacity(newCapacity); 1.164 // OVR_ASSERT(Data); // need to throw (or something) on alloc failure! 1.165 } 1.166 } 1.167 1.168 // This version of Resize DOES NOT construct the elements. 1.169 // It's done to optimize PushBack, which uses a copy constructor 1.170 // instead of the default constructor and assignment 1.171 void ResizeNoConstruct(UPInt newSize) 1.172 { 1.173 UPInt oldSize = Size; 1.174 1.175 if (newSize < oldSize) 1.176 { 1.177 Allocator::DestructArray(Data + newSize, oldSize - newSize); 1.178 if (newSize < (Policy.GetCapacity() >> 1)) 1.179 { 1.180 Reserve(newSize); 1.181 } 1.182 } 1.183 else if(newSize >= Policy.GetCapacity()) 1.184 { 1.185 Reserve(newSize + (newSize >> 2)); 1.186 } 1.187 //! IMPORTANT to modify Size only after Reserve completes, because garbage collectable 1.188 // array may use this array and may traverse it during Reserve (in the case, if 1.189 // collection occurs because of heap limit exceeded). 1.190 Size = newSize; 1.191 } 1.192 1.193 ValueType* Data; 1.194 UPInt Size; 1.195 SizePolicy Policy; 1.196 }; 1.197 1.198 1.199 1.200 //----------------------------------------------------------------------------------- 1.201 // ***** ArrayData 1.202 // 1.203 // General purpose array data. 1.204 // For internal use only in Array, ArrayLH, ArrayPOD and so on. 1.205 template<class T, class Allocator, class SizePolicy> 1.206 struct ArrayData : ArrayDataBase<T, Allocator, SizePolicy> 1.207 { 1.208 typedef T ValueType; 1.209 typedef Allocator AllocatorType; 1.210 typedef SizePolicy SizePolicyType; 1.211 typedef ArrayDataBase<T, Allocator, SizePolicy> BaseType; 1.212 typedef ArrayData <T, Allocator, SizePolicy> SelfType; 1.213 1.214 ArrayData() 1.215 : BaseType() { } 1.216 1.217 ArrayData(int size) 1.218 : BaseType() { Resize(size); } 1.219 1.220 ArrayData(const SelfType& a) 1.221 : BaseType(a.Policy) { Append(a.Data, a.Size); } 1.222 1.223 1.224 void Resize(UPInt newSize) 1.225 { 1.226 UPInt oldSize = this->Size; 1.227 BaseType::ResizeNoConstruct(newSize); 1.228 if(newSize > oldSize) 1.229 Allocator::ConstructArray(this->Data + oldSize, newSize - oldSize); 1.230 } 1.231 1.232 void PushBack(const ValueType& val) 1.233 { 1.234 BaseType::ResizeNoConstruct(this->Size + 1); 1.235 Allocator::Construct(this->Data + this->Size - 1, val); 1.236 } 1.237 1.238 template<class S> 1.239 void PushBackAlt(const S& val) 1.240 { 1.241 BaseType::ResizeNoConstruct(this->Size + 1); 1.242 Allocator::ConstructAlt(this->Data + this->Size - 1, val); 1.243 } 1.244 1.245 // Append the given data to the array. 1.246 void Append(const ValueType other[], UPInt count) 1.247 { 1.248 if (count) 1.249 { 1.250 UPInt oldSize = this->Size; 1.251 BaseType::ResizeNoConstruct(this->Size + count); 1.252 Allocator::ConstructArray(this->Data + oldSize, count, other); 1.253 } 1.254 } 1.255 }; 1.256 1.257 1.258 1.259 //----------------------------------------------------------------------------------- 1.260 // ***** ArrayDataCC 1.261 // 1.262 // A modification of ArrayData that always copy-constructs new elements 1.263 // using a specified DefaultValue. For internal use only in ArrayCC. 1.264 template<class T, class Allocator, class SizePolicy> 1.265 struct ArrayDataCC : ArrayDataBase<T, Allocator, SizePolicy> 1.266 { 1.267 typedef T ValueType; 1.268 typedef Allocator AllocatorType; 1.269 typedef SizePolicy SizePolicyType; 1.270 typedef ArrayDataBase<T, Allocator, SizePolicy> BaseType; 1.271 typedef ArrayDataCC <T, Allocator, SizePolicy> SelfType; 1.272 1.273 ArrayDataCC(const ValueType& defval) 1.274 : BaseType(), DefaultValue(defval) { } 1.275 1.276 ArrayDataCC(const ValueType& defval, int size) 1.277 : BaseType(), DefaultValue(defval) { Resize(size); } 1.278 1.279 ArrayDataCC(const SelfType& a) 1.280 : BaseType(a.Policy), DefaultValue(a.DefaultValue) { Append(a.Data, a.Size); } 1.281 1.282 1.283 void Resize(UPInt newSize) 1.284 { 1.285 UPInt oldSize = this->Size; 1.286 BaseType::ResizeNoConstruct(newSize); 1.287 if(newSize > oldSize) 1.288 Allocator::ConstructArray(this->Data + oldSize, newSize - oldSize, DefaultValue); 1.289 } 1.290 1.291 void PushBack(const ValueType& val) 1.292 { 1.293 BaseType::ResizeNoConstruct(this->Size + 1); 1.294 Allocator::Construct(this->Data + this->Size - 1, val); 1.295 } 1.296 1.297 template<class S> 1.298 void PushBackAlt(const S& val) 1.299 { 1.300 BaseType::ResizeNoConstruct(this->Size + 1); 1.301 Allocator::ConstructAlt(this->Data + this->Size - 1, val); 1.302 } 1.303 1.304 // Append the given data to the array. 1.305 void Append(const ValueType other[], UPInt count) 1.306 { 1.307 if (count) 1.308 { 1.309 UPInt oldSize = this->Size; 1.310 BaseType::ResizeNoConstruct(this->Size + count); 1.311 Allocator::ConstructArray(this->Data + oldSize, count, other); 1.312 } 1.313 } 1.314 1.315 ValueType DefaultValue; 1.316 }; 1.317 1.318 1.319 1.320 1.321 1.322 //----------------------------------------------------------------------------------- 1.323 // ***** ArrayBase 1.324 // 1.325 // Resizable array. The behavior can be POD (suffix _POD) and 1.326 // Movable (no suffix) depending on the allocator policy. 1.327 // In case of _POD the constructors and destructors are not called. 1.328 // 1.329 // Arrays can't handle non-movable objects! Don't put anything in here 1.330 // that can't be moved around by bitwise copy. 1.331 // 1.332 // The addresses of elements are not persistent! Don't keep the address 1.333 // of an element; the array contents will move around as it gets resized. 1.334 template<class ArrayData> 1.335 class ArrayBase 1.336 { 1.337 public: 1.338 typedef typename ArrayData::ValueType ValueType; 1.339 typedef typename ArrayData::AllocatorType AllocatorType; 1.340 typedef typename ArrayData::SizePolicyType SizePolicyType; 1.341 typedef ArrayBase<ArrayData> SelfType; 1.342 1.343 1.344 #undef new 1.345 OVR_MEMORY_REDEFINE_NEW(ArrayBase) 1.346 // Redefine operator 'new' if necessary. 1.347 #if defined(OVR_DEFINE_NEW) 1.348 #define new OVR_DEFINE_NEW 1.349 #endif 1.350 1.351 1.352 ArrayBase() 1.353 : Data() {} 1.354 ArrayBase(int size) 1.355 : Data(size) {} 1.356 ArrayBase(const SelfType& a) 1.357 : Data(a.Data) {} 1.358 1.359 ArrayBase(const ValueType& defval) 1.360 : Data(defval) {} 1.361 ArrayBase(const ValueType& defval, int size) 1.362 : Data(defval, size) {} 1.363 1.364 SizePolicyType* GetSizePolicy() const { return Data.Policy; } 1.365 void SetSizePolicy(const SizePolicyType& p) { Data.Policy = p; } 1.366 1.367 bool NeverShrinking()const { return Data.Policy.NeverShrinking(); } 1.368 UPInt GetSize() const { return Data.Size; } 1.369 bool IsEmpty() const { return Data.Size == 0; } 1.370 UPInt GetCapacity() const { return Data.GetCapacity(); } 1.371 UPInt GetNumBytes() const { return Data.GetCapacity() * sizeof(ValueType); } 1.372 1.373 void ClearAndRelease() { Data.ClearAndRelease(); } 1.374 void Clear() { Data.Resize(0); } 1.375 void Resize(UPInt newSize) { Data.Resize(newSize); } 1.376 1.377 // Reserve can only increase the capacity 1.378 void Reserve(UPInt newCapacity) 1.379 { 1.380 if (newCapacity > Data.GetCapacity()) 1.381 Data.Reserve(newCapacity); 1.382 } 1.383 1.384 // Basic access. 1.385 ValueType& At(UPInt index) 1.386 { 1.387 OVR_ASSERT(index < Data.Size); 1.388 return Data.Data[index]; 1.389 } 1.390 const ValueType& At(UPInt index) const 1.391 { 1.392 OVR_ASSERT(index < Data.Size); 1.393 return Data.Data[index]; 1.394 } 1.395 1.396 ValueType ValueAt(UPInt index) const 1.397 { 1.398 OVR_ASSERT(index < Data.Size); 1.399 return Data.Data[index]; 1.400 } 1.401 1.402 // Basic access. 1.403 ValueType& operator [] (UPInt index) 1.404 { 1.405 OVR_ASSERT(index < Data.Size); 1.406 return Data.Data[index]; 1.407 } 1.408 const ValueType& operator [] (UPInt index) const 1.409 { 1.410 OVR_ASSERT(index < Data.Size); 1.411 return Data.Data[index]; 1.412 } 1.413 1.414 // Raw pointer to the data. Use with caution! 1.415 const ValueType* GetDataPtr() const { return Data.Data; } 1.416 ValueType* GetDataPtr() { return Data.Data; } 1.417 1.418 // Insert the given element at the end of the array. 1.419 void PushBack(const ValueType& val) 1.420 { 1.421 // DO NOT pass elements of your own vector into 1.422 // push_back()! Since we're using references, 1.423 // resize() may munge the element storage! 1.424 // OVR_ASSERT(&val < &Buffer[0] || &val > &Buffer[BufferSize]); 1.425 Data.PushBack(val); 1.426 } 1.427 1.428 template<class S> 1.429 void PushBackAlt(const S& val) 1.430 { 1.431 Data.PushBackAlt(val); 1.432 } 1.433 1.434 // Remove the last element. 1.435 void PopBack(UPInt count = 1) 1.436 { 1.437 OVR_ASSERT(Data.Size >= count); 1.438 Data.Resize(Data.Size - count); 1.439 } 1.440 1.441 ValueType& PushDefault() 1.442 { 1.443 Data.PushBack(ValueType()); 1.444 return Back(); 1.445 } 1.446 1.447 ValueType Pop() 1.448 { 1.449 ValueType t = Back(); 1.450 PopBack(); 1.451 return t; 1.452 } 1.453 1.454 1.455 // Access the first element. 1.456 ValueType& Front() { return At(0); } 1.457 const ValueType& Front() const { return At(0); } 1.458 1.459 // Access the last element. 1.460 ValueType& Back() { return At(Data.Size - 1); } 1.461 const ValueType& Back() const { return At(Data.Size - 1); } 1.462 1.463 // Array copy. Copies the contents of a into this array. 1.464 const SelfType& operator = (const SelfType& a) 1.465 { 1.466 Resize(a.GetSize()); 1.467 for (UPInt i = 0; i < Data.Size; i++) { 1.468 *(Data.Data + i) = a[i]; 1.469 } 1.470 return *this; 1.471 } 1.472 1.473 // Removing multiple elements from the array. 1.474 void RemoveMultipleAt(UPInt index, UPInt num) 1.475 { 1.476 OVR_ASSERT(index + num <= Data.Size); 1.477 if (Data.Size == num) 1.478 { 1.479 Clear(); 1.480 } 1.481 else 1.482 { 1.483 AllocatorType::DestructArray(Data.Data + index, num); 1.484 AllocatorType::CopyArrayForward( 1.485 Data.Data + index, 1.486 Data.Data + index + num, 1.487 Data.Size - num - index); 1.488 Data.Size -= num; 1.489 } 1.490 } 1.491 1.492 // Removing an element from the array is an expensive operation! 1.493 // It compacts only after removing the last element. 1.494 void RemoveAt(UPInt index) 1.495 { 1.496 OVR_ASSERT(index < Data.Size); 1.497 if (Data.Size == 1) 1.498 { 1.499 Clear(); 1.500 } 1.501 else 1.502 { 1.503 AllocatorType::Destruct(Data.Data + index); 1.504 AllocatorType::CopyArrayForward( 1.505 Data.Data + index, 1.506 Data.Data + index + 1, 1.507 Data.Size - 1 - index); 1.508 --Data.Size; 1.509 } 1.510 } 1.511 1.512 // Insert the given object at the given index shifting all the elements up. 1.513 void InsertAt(UPInt index, const ValueType& val = ValueType()) 1.514 { 1.515 OVR_ASSERT(index <= Data.Size); 1.516 1.517 Data.Resize(Data.Size + 1); 1.518 if (index < Data.Size - 1) 1.519 { 1.520 AllocatorType::CopyArrayBackward( 1.521 Data.Data + index + 1, 1.522 Data.Data + index, 1.523 Data.Size - 1 - index); 1.524 } 1.525 AllocatorType::Construct(Data.Data + index, val); 1.526 } 1.527 1.528 // Insert the given object at the given index shifting all the elements up. 1.529 void InsertMultipleAt(UPInt index, UPInt num, const ValueType& val = ValueType()) 1.530 { 1.531 OVR_ASSERT(index <= Data.Size); 1.532 1.533 Data.Resize(Data.Size + num); 1.534 if (index < Data.Size - num) 1.535 { 1.536 AllocatorType::CopyArrayBackward( 1.537 Data.Data + index + num, 1.538 Data.Data + index, 1.539 Data.Size - num - index); 1.540 } 1.541 for (UPInt i = 0; i < num; ++i) 1.542 AllocatorType::Construct(Data.Data + index + i, val); 1.543 } 1.544 1.545 // Append the given data to the array. 1.546 void Append(const SelfType& other) 1.547 { 1.548 Append(other.Data.Data, other.GetSize()); 1.549 } 1.550 1.551 // Append the given data to the array. 1.552 void Append(const ValueType other[], UPInt count) 1.553 { 1.554 Data.Append(other, count); 1.555 } 1.556 1.557 class Iterator 1.558 { 1.559 SelfType* pArray; 1.560 SPInt CurIndex; 1.561 1.562 public: 1.563 Iterator() : pArray(0), CurIndex(-1) {} 1.564 Iterator(SelfType* parr, SPInt idx = 0) : pArray(parr), CurIndex(idx) {} 1.565 1.566 bool operator==(const Iterator& it) const { return pArray == it.pArray && CurIndex == it.CurIndex; } 1.567 bool operator!=(const Iterator& it) const { return pArray != it.pArray || CurIndex != it.CurIndex; } 1.568 1.569 Iterator& operator++() 1.570 { 1.571 if (pArray) 1.572 { 1.573 if (CurIndex < (SPInt)pArray->GetSize()) 1.574 ++CurIndex; 1.575 } 1.576 return *this; 1.577 } 1.578 Iterator operator++(int) 1.579 { 1.580 Iterator it(*this); 1.581 operator++(); 1.582 return it; 1.583 } 1.584 Iterator& operator--() 1.585 { 1.586 if (pArray) 1.587 { 1.588 if (CurIndex >= 0) 1.589 --CurIndex; 1.590 } 1.591 return *this; 1.592 } 1.593 Iterator operator--(int) 1.594 { 1.595 Iterator it(*this); 1.596 operator--(); 1.597 return it; 1.598 } 1.599 Iterator operator+(int delta) const 1.600 { 1.601 return Iterator(pArray, CurIndex + delta); 1.602 } 1.603 Iterator operator-(int delta) const 1.604 { 1.605 return Iterator(pArray, CurIndex - delta); 1.606 } 1.607 SPInt operator-(const Iterator& right) const 1.608 { 1.609 OVR_ASSERT(pArray == right.pArray); 1.610 return CurIndex - right.CurIndex; 1.611 } 1.612 ValueType& operator*() const { OVR_ASSERT(pArray); return (*pArray)[CurIndex]; } 1.613 ValueType* operator->() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; } 1.614 ValueType* GetPtr() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; } 1.615 1.616 bool IsFinished() const { return !pArray || CurIndex < 0 || CurIndex >= (int)pArray->GetSize(); } 1.617 1.618 void Remove() 1.619 { 1.620 if (!IsFinished()) 1.621 pArray->RemoveAt(CurIndex); 1.622 } 1.623 1.624 SPInt GetIndex() const { return CurIndex; } 1.625 }; 1.626 1.627 Iterator Begin() { return Iterator(this); } 1.628 Iterator End() { return Iterator(this, (SPInt)GetSize()); } 1.629 Iterator Last() { return Iterator(this, (SPInt)GetSize() - 1); } 1.630 1.631 class ConstIterator 1.632 { 1.633 const SelfType* pArray; 1.634 SPInt CurIndex; 1.635 1.636 public: 1.637 ConstIterator() : pArray(0), CurIndex(-1) {} 1.638 ConstIterator(const SelfType* parr, SPInt idx = 0) : pArray(parr), CurIndex(idx) {} 1.639 1.640 bool operator==(const ConstIterator& it) const { return pArray == it.pArray && CurIndex == it.CurIndex; } 1.641 bool operator!=(const ConstIterator& it) const { return pArray != it.pArray || CurIndex != it.CurIndex; } 1.642 1.643 ConstIterator& operator++() 1.644 { 1.645 if (pArray) 1.646 { 1.647 if (CurIndex < (int)pArray->GetSize()) 1.648 ++CurIndex; 1.649 } 1.650 return *this; 1.651 } 1.652 ConstIterator operator++(int) 1.653 { 1.654 ConstIterator it(*this); 1.655 operator++(); 1.656 return it; 1.657 } 1.658 ConstIterator& operator--() 1.659 { 1.660 if (pArray) 1.661 { 1.662 if (CurIndex >= 0) 1.663 --CurIndex; 1.664 } 1.665 return *this; 1.666 } 1.667 ConstIterator operator--(int) 1.668 { 1.669 ConstIterator it(*this); 1.670 operator--(); 1.671 return it; 1.672 } 1.673 ConstIterator operator+(int delta) const 1.674 { 1.675 return ConstIterator(pArray, CurIndex + delta); 1.676 } 1.677 ConstIterator operator-(int delta) const 1.678 { 1.679 return ConstIterator(pArray, CurIndex - delta); 1.680 } 1.681 SPInt operator-(const ConstIterator& right) const 1.682 { 1.683 OVR_ASSERT(pArray == right.pArray); 1.684 return CurIndex - right.CurIndex; 1.685 } 1.686 const ValueType& operator*() const { OVR_ASSERT(pArray); return (*pArray)[CurIndex]; } 1.687 const ValueType* operator->() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; } 1.688 const ValueType* GetPtr() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; } 1.689 1.690 bool IsFinished() const { return !pArray || CurIndex < 0 || CurIndex >= (int)pArray->GetSize(); } 1.691 1.692 SPInt GetIndex() const { return CurIndex; } 1.693 }; 1.694 ConstIterator Begin() const { return ConstIterator(this); } 1.695 ConstIterator End() const { return ConstIterator(this, (SPInt)GetSize()); } 1.696 ConstIterator Last() const { return ConstIterator(this, (SPInt)GetSize() - 1); } 1.697 1.698 protected: 1.699 ArrayData Data; 1.700 }; 1.701 1.702 1.703 1.704 //----------------------------------------------------------------------------------- 1.705 // ***** Array 1.706 // 1.707 // General purpose array for movable objects that require explicit 1.708 // construction/destruction. 1.709 template<class T, class SizePolicy=ArrayDefaultPolicy> 1.710 class Array : public ArrayBase<ArrayData<T, ContainerAllocator<T>, SizePolicy> > 1.711 { 1.712 public: 1.713 typedef T ValueType; 1.714 typedef ContainerAllocator<T> AllocatorType; 1.715 typedef SizePolicy SizePolicyType; 1.716 typedef Array<T, SizePolicy> SelfType; 1.717 typedef ArrayBase<ArrayData<T, ContainerAllocator<T>, SizePolicy> > BaseType; 1.718 1.719 Array() : BaseType() {} 1.720 Array(int size) : BaseType(size) {} 1.721 Array(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); } 1.722 Array(const SelfType& a) : BaseType(a) {} 1.723 const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; } 1.724 }; 1.725 1.726 // ***** ArrayPOD 1.727 // 1.728 // General purpose array for movable objects that DOES NOT require 1.729 // construction/destruction. Constructors and destructors are not called! 1.730 // Global heap is in use. 1.731 template<class T, class SizePolicy=ArrayDefaultPolicy> 1.732 class ArrayPOD : public ArrayBase<ArrayData<T, ContainerAllocator_POD<T>, SizePolicy> > 1.733 { 1.734 public: 1.735 typedef T ValueType; 1.736 typedef ContainerAllocator_POD<T> AllocatorType; 1.737 typedef SizePolicy SizePolicyType; 1.738 typedef ArrayPOD<T, SizePolicy> SelfType; 1.739 typedef ArrayBase<ArrayData<T, ContainerAllocator_POD<T>, SizePolicy> > BaseType; 1.740 1.741 ArrayPOD() : BaseType() {} 1.742 ArrayPOD(int size) : BaseType(size) {} 1.743 ArrayPOD(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); } 1.744 ArrayPOD(const SelfType& a) : BaseType(a) {} 1.745 const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; } 1.746 }; 1.747 1.748 1.749 // ***** ArrayCPP 1.750 // 1.751 // General purpose, fully C++ compliant array. Can be used with non-movable data. 1.752 // Global heap is in use. 1.753 template<class T, class SizePolicy=ArrayDefaultPolicy> 1.754 class ArrayCPP : public ArrayBase<ArrayData<T, ContainerAllocator_CPP<T>, SizePolicy> > 1.755 { 1.756 public: 1.757 typedef T ValueType; 1.758 typedef ContainerAllocator_CPP<T> AllocatorType; 1.759 typedef SizePolicy SizePolicyType; 1.760 typedef ArrayCPP<T, SizePolicy> SelfType; 1.761 typedef ArrayBase<ArrayData<T, ContainerAllocator_CPP<T>, SizePolicy> > BaseType; 1.762 1.763 ArrayCPP() : BaseType() {} 1.764 ArrayCPP(int size) : BaseType(size) {} 1.765 ArrayCPP(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); } 1.766 ArrayCPP(const SelfType& a) : BaseType(a) {} 1.767 const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; } 1.768 }; 1.769 1.770 1.771 // ***** ArrayCC 1.772 // 1.773 // A modification of the array that uses the given default value to 1.774 // construct the elements. The constructors and destructors are 1.775 // properly called, the objects must be movable. 1.776 1.777 template<class T, class SizePolicy=ArrayDefaultPolicy> 1.778 class ArrayCC : public ArrayBase<ArrayDataCC<T, ContainerAllocator<T>, SizePolicy> > 1.779 { 1.780 public: 1.781 typedef T ValueType; 1.782 typedef ContainerAllocator<T> AllocatorType; 1.783 typedef SizePolicy SizePolicyType; 1.784 typedef ArrayCC<T, SizePolicy> SelfType; 1.785 typedef ArrayBase<ArrayDataCC<T, ContainerAllocator<T>, SizePolicy> > BaseType; 1.786 1.787 ArrayCC(const ValueType& defval) : BaseType(defval) {} 1.788 ArrayCC(const ValueType& defval, int size) : BaseType(defval, size) {} 1.789 ArrayCC(const ValueType& defval, const SizePolicyType& p) : BaseType(defval) { SetSizePolicy(p); } 1.790 ArrayCC(const SelfType& a) : BaseType(a) {} 1.791 const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; } 1.792 }; 1.793 1.794 } // OVR 1.795 1.796 #endif 1.797 \ No newline at end of file 1.798 +/************************************************************************************ 1.799 + 1.800 +PublicHeader: OVR.h 1.801 +Filename : OVR_Array.h 1.802 +Content : Template implementation for Array 1.803 +Created : September 19, 2012 1.804 +Notes : 1.805 + 1.806 +Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. 1.807 + 1.808 +Use of this software is subject to the terms of the Oculus license 1.809 +agreement provided at the time of installation or download, or which 1.810 +otherwise accompanies this software in either electronic or hard copy form. 1.811 + 1.812 +************************************************************************************/ 1.813 + 1.814 +#ifndef OVR_Array_h 1.815 +#define OVR_Array_h 1.816 + 1.817 +#include "OVR_ContainerAllocator.h" 1.818 + 1.819 +namespace OVR { 1.820 + 1.821 +//----------------------------------------------------------------------------------- 1.822 +// ***** ArrayDefaultPolicy 1.823 +// 1.824 +// Default resize behavior. No minimal capacity, Granularity=4, 1.825 +// Shrinking as needed. ArrayConstPolicy actually is the same as 1.826 +// ArrayDefaultPolicy, but parametrized with constants. 1.827 +// This struct is used only in order to reduce the template "matroska". 1.828 +struct ArrayDefaultPolicy 1.829 +{ 1.830 + ArrayDefaultPolicy() : Capacity(0) {} 1.831 + ArrayDefaultPolicy(const ArrayDefaultPolicy&) : Capacity(0) {} 1.832 + 1.833 + UPInt GetMinCapacity() const { return 0; } 1.834 + UPInt GetGranularity() const { return 4; } 1.835 + bool NeverShrinking() const { return 0; } 1.836 + 1.837 + UPInt GetCapacity() const { return Capacity; } 1.838 + void SetCapacity(UPInt capacity) { Capacity = capacity; } 1.839 +private: 1.840 + UPInt Capacity; 1.841 +}; 1.842 + 1.843 + 1.844 +//----------------------------------------------------------------------------------- 1.845 +// ***** ArrayConstPolicy 1.846 +// 1.847 +// Statically parametrized resizing behavior: 1.848 +// MinCapacity, Granularity, and Shrinking flag. 1.849 +template<int MinCapacity=0, int Granularity=4, bool NeverShrink=false> 1.850 +struct ArrayConstPolicy 1.851 +{ 1.852 + typedef ArrayConstPolicy<MinCapacity, Granularity, NeverShrink> SelfType; 1.853 + 1.854 + ArrayConstPolicy() : Capacity(0) {} 1.855 + ArrayConstPolicy(const SelfType&) : Capacity(0) {} 1.856 + 1.857 + UPInt GetMinCapacity() const { return MinCapacity; } 1.858 + UPInt GetGranularity() const { return Granularity; } 1.859 + bool NeverShrinking() const { return NeverShrink; } 1.860 + 1.861 + UPInt GetCapacity() const { return Capacity; } 1.862 + void SetCapacity(UPInt capacity) { Capacity = capacity; } 1.863 +private: 1.864 + UPInt Capacity; 1.865 +}; 1.866 + 1.867 +//----------------------------------------------------------------------------------- 1.868 +// ***** ArrayDataBase 1.869 +// 1.870 +// Basic operations with array data: Reserve, Resize, Free, ArrayPolicy. 1.871 +// For internal use only: ArrayData,ArrayDataCC and others. 1.872 +template<class T, class Allocator, class SizePolicy> 1.873 +struct ArrayDataBase 1.874 +{ 1.875 + typedef T ValueType; 1.876 + typedef Allocator AllocatorType; 1.877 + typedef SizePolicy SizePolicyType; 1.878 + typedef ArrayDataBase<T, Allocator, SizePolicy> SelfType; 1.879 + 1.880 + ArrayDataBase() 1.881 + : Data(0), Size(0), Policy() {} 1.882 + 1.883 + ArrayDataBase(const SizePolicy& p) 1.884 + : Data(0), Size(0), Policy(p) {} 1.885 + 1.886 + ~ArrayDataBase() 1.887 + { 1.888 + Allocator::DestructArray(Data, Size); 1.889 + Allocator::Free(Data); 1.890 + } 1.891 + 1.892 + UPInt GetCapacity() const 1.893 + { 1.894 + return Policy.GetCapacity(); 1.895 + } 1.896 + 1.897 + void ClearAndRelease() 1.898 + { 1.899 + Allocator::DestructArray(Data, Size); 1.900 + Allocator::Free(Data); 1.901 + Data = 0; 1.902 + Size = 0; 1.903 + Policy.SetCapacity(0); 1.904 + } 1.905 + 1.906 + void Reserve(UPInt newCapacity) 1.907 + { 1.908 + if (Policy.NeverShrinking() && newCapacity < GetCapacity()) 1.909 + return; 1.910 + 1.911 + if (newCapacity < Policy.GetMinCapacity()) 1.912 + newCapacity = Policy.GetMinCapacity(); 1.913 + 1.914 + // Resize the buffer. 1.915 + if (newCapacity == 0) 1.916 + { 1.917 + if (Data) 1.918 + { 1.919 + Allocator::Free(Data); 1.920 + Data = 0; 1.921 + } 1.922 + Policy.SetCapacity(0); 1.923 + } 1.924 + else 1.925 + { 1.926 + UPInt gran = Policy.GetGranularity(); 1.927 + newCapacity = (newCapacity + gran - 1) / gran * gran; 1.928 + if (Data) 1.929 + { 1.930 + if (Allocator::IsMovable()) 1.931 + { 1.932 + Data = (T*)Allocator::Realloc(Data, sizeof(T) * newCapacity); 1.933 + } 1.934 + else 1.935 + { 1.936 + T* newData = (T*)Allocator::Alloc(sizeof(T) * newCapacity); 1.937 + UPInt i, s; 1.938 + s = (Size < newCapacity) ? Size : newCapacity; 1.939 + for (i = 0; i < s; ++i) 1.940 + { 1.941 + Allocator::Construct(&newData[i], Data[i]); 1.942 + Allocator::Destruct(&Data[i]); 1.943 + } 1.944 + for (i = s; i < Size; ++i) 1.945 + { 1.946 + Allocator::Destruct(&Data[i]); 1.947 + } 1.948 + Allocator::Free(Data); 1.949 + Data = newData; 1.950 + } 1.951 + } 1.952 + else 1.953 + { 1.954 + Data = (T*)Allocator::Alloc(sizeof(T) * newCapacity); 1.955 + //memset(Buffer, 0, (sizeof(ValueType) * newSize)); // Do we need this? 1.956 + } 1.957 + Policy.SetCapacity(newCapacity); 1.958 + // OVR_ASSERT(Data); // need to throw (or something) on alloc failure! 1.959 + } 1.960 + } 1.961 + 1.962 + // This version of Resize DOES NOT construct the elements. 1.963 + // It's done to optimize PushBack, which uses a copy constructor 1.964 + // instead of the default constructor and assignment 1.965 + void ResizeNoConstruct(UPInt newSize) 1.966 + { 1.967 + UPInt oldSize = Size; 1.968 + 1.969 + if (newSize < oldSize) 1.970 + { 1.971 + Allocator::DestructArray(Data + newSize, oldSize - newSize); 1.972 + if (newSize < (Policy.GetCapacity() >> 1)) 1.973 + { 1.974 + Reserve(newSize); 1.975 + } 1.976 + } 1.977 + else if(newSize >= Policy.GetCapacity()) 1.978 + { 1.979 + Reserve(newSize + (newSize >> 2)); 1.980 + } 1.981 + //! IMPORTANT to modify Size only after Reserve completes, because garbage collectable 1.982 + // array may use this array and may traverse it during Reserve (in the case, if 1.983 + // collection occurs because of heap limit exceeded). 1.984 + Size = newSize; 1.985 + } 1.986 + 1.987 + ValueType* Data; 1.988 + UPInt Size; 1.989 + SizePolicy Policy; 1.990 +}; 1.991 + 1.992 + 1.993 + 1.994 +//----------------------------------------------------------------------------------- 1.995 +// ***** ArrayData 1.996 +// 1.997 +// General purpose array data. 1.998 +// For internal use only in Array, ArrayLH, ArrayPOD and so on. 1.999 +template<class T, class Allocator, class SizePolicy> 1.1000 +struct ArrayData : ArrayDataBase<T, Allocator, SizePolicy> 1.1001 +{ 1.1002 + typedef T ValueType; 1.1003 + typedef Allocator AllocatorType; 1.1004 + typedef SizePolicy SizePolicyType; 1.1005 + typedef ArrayDataBase<T, Allocator, SizePolicy> BaseType; 1.1006 + typedef ArrayData <T, Allocator, SizePolicy> SelfType; 1.1007 + 1.1008 + ArrayData() 1.1009 + : BaseType() { } 1.1010 + 1.1011 + ArrayData(int size) 1.1012 + : BaseType() { Resize(size); } 1.1013 + 1.1014 + ArrayData(const SelfType& a) 1.1015 + : BaseType(a.Policy) { Append(a.Data, a.Size); } 1.1016 + 1.1017 + 1.1018 + void Resize(UPInt newSize) 1.1019 + { 1.1020 + UPInt oldSize = this->Size; 1.1021 + BaseType::ResizeNoConstruct(newSize); 1.1022 + if(newSize > oldSize) 1.1023 + Allocator::ConstructArray(this->Data + oldSize, newSize - oldSize); 1.1024 + } 1.1025 + 1.1026 + void PushBack(const ValueType& val) 1.1027 + { 1.1028 + BaseType::ResizeNoConstruct(this->Size + 1); 1.1029 + Allocator::Construct(this->Data + this->Size - 1, val); 1.1030 + } 1.1031 + 1.1032 + template<class S> 1.1033 + void PushBackAlt(const S& val) 1.1034 + { 1.1035 + BaseType::ResizeNoConstruct(this->Size + 1); 1.1036 + Allocator::ConstructAlt(this->Data + this->Size - 1, val); 1.1037 + } 1.1038 + 1.1039 + // Append the given data to the array. 1.1040 + void Append(const ValueType other[], UPInt count) 1.1041 + { 1.1042 + if (count) 1.1043 + { 1.1044 + UPInt oldSize = this->Size; 1.1045 + BaseType::ResizeNoConstruct(this->Size + count); 1.1046 + Allocator::ConstructArray(this->Data + oldSize, count, other); 1.1047 + } 1.1048 + } 1.1049 +}; 1.1050 + 1.1051 + 1.1052 + 1.1053 +//----------------------------------------------------------------------------------- 1.1054 +// ***** ArrayDataCC 1.1055 +// 1.1056 +// A modification of ArrayData that always copy-constructs new elements 1.1057 +// using a specified DefaultValue. For internal use only in ArrayCC. 1.1058 +template<class T, class Allocator, class SizePolicy> 1.1059 +struct ArrayDataCC : ArrayDataBase<T, Allocator, SizePolicy> 1.1060 +{ 1.1061 + typedef T ValueType; 1.1062 + typedef Allocator AllocatorType; 1.1063 + typedef SizePolicy SizePolicyType; 1.1064 + typedef ArrayDataBase<T, Allocator, SizePolicy> BaseType; 1.1065 + typedef ArrayDataCC <T, Allocator, SizePolicy> SelfType; 1.1066 + 1.1067 + ArrayDataCC(const ValueType& defval) 1.1068 + : BaseType(), DefaultValue(defval) { } 1.1069 + 1.1070 + ArrayDataCC(const ValueType& defval, int size) 1.1071 + : BaseType(), DefaultValue(defval) { Resize(size); } 1.1072 + 1.1073 + ArrayDataCC(const SelfType& a) 1.1074 + : BaseType(a.Policy), DefaultValue(a.DefaultValue) { Append(a.Data, a.Size); } 1.1075 + 1.1076 + 1.1077 + void Resize(UPInt newSize) 1.1078 + { 1.1079 + UPInt oldSize = this->Size; 1.1080 + BaseType::ResizeNoConstruct(newSize); 1.1081 + if(newSize > oldSize) 1.1082 + Allocator::ConstructArray(this->Data + oldSize, newSize - oldSize, DefaultValue); 1.1083 + } 1.1084 + 1.1085 + void PushBack(const ValueType& val) 1.1086 + { 1.1087 + BaseType::ResizeNoConstruct(this->Size + 1); 1.1088 + Allocator::Construct(this->Data + this->Size - 1, val); 1.1089 + } 1.1090 + 1.1091 + template<class S> 1.1092 + void PushBackAlt(const S& val) 1.1093 + { 1.1094 + BaseType::ResizeNoConstruct(this->Size + 1); 1.1095 + Allocator::ConstructAlt(this->Data + this->Size - 1, val); 1.1096 + } 1.1097 + 1.1098 + // Append the given data to the array. 1.1099 + void Append(const ValueType other[], UPInt count) 1.1100 + { 1.1101 + if (count) 1.1102 + { 1.1103 + UPInt oldSize = this->Size; 1.1104 + BaseType::ResizeNoConstruct(this->Size + count); 1.1105 + Allocator::ConstructArray(this->Data + oldSize, count, other); 1.1106 + } 1.1107 + } 1.1108 + 1.1109 + ValueType DefaultValue; 1.1110 +}; 1.1111 + 1.1112 + 1.1113 + 1.1114 + 1.1115 + 1.1116 +//----------------------------------------------------------------------------------- 1.1117 +// ***** ArrayBase 1.1118 +// 1.1119 +// Resizable array. The behavior can be POD (suffix _POD) and 1.1120 +// Movable (no suffix) depending on the allocator policy. 1.1121 +// In case of _POD the constructors and destructors are not called. 1.1122 +// 1.1123 +// Arrays can't handle non-movable objects! Don't put anything in here 1.1124 +// that can't be moved around by bitwise copy. 1.1125 +// 1.1126 +// The addresses of elements are not persistent! Don't keep the address 1.1127 +// of an element; the array contents will move around as it gets resized. 1.1128 +template<class ArrayData> 1.1129 +class ArrayBase 1.1130 +{ 1.1131 +public: 1.1132 + typedef typename ArrayData::ValueType ValueType; 1.1133 + typedef typename ArrayData::AllocatorType AllocatorType; 1.1134 + typedef typename ArrayData::SizePolicyType SizePolicyType; 1.1135 + typedef ArrayBase<ArrayData> SelfType; 1.1136 + 1.1137 + 1.1138 +#undef new 1.1139 + OVR_MEMORY_REDEFINE_NEW(ArrayBase) 1.1140 +// Redefine operator 'new' if necessary. 1.1141 +#if defined(OVR_DEFINE_NEW) 1.1142 +#define new OVR_DEFINE_NEW 1.1143 +#endif 1.1144 + 1.1145 + 1.1146 + ArrayBase() 1.1147 + : Data() {} 1.1148 + ArrayBase(int size) 1.1149 + : Data(size) {} 1.1150 + ArrayBase(const SelfType& a) 1.1151 + : Data(a.Data) {} 1.1152 + 1.1153 + ArrayBase(const ValueType& defval) 1.1154 + : Data(defval) {} 1.1155 + ArrayBase(const ValueType& defval, int size) 1.1156 + : Data(defval, size) {} 1.1157 + 1.1158 + SizePolicyType* GetSizePolicy() const { return Data.Policy; } 1.1159 + void SetSizePolicy(const SizePolicyType& p) { Data.Policy = p; } 1.1160 + 1.1161 + bool NeverShrinking()const { return Data.Policy.NeverShrinking(); } 1.1162 + UPInt GetSize() const { return Data.Size; } 1.1163 + bool IsEmpty() const { return Data.Size == 0; } 1.1164 + UPInt GetCapacity() const { return Data.GetCapacity(); } 1.1165 + UPInt GetNumBytes() const { return Data.GetCapacity() * sizeof(ValueType); } 1.1166 + 1.1167 + void ClearAndRelease() { Data.ClearAndRelease(); } 1.1168 + void Clear() { Data.Resize(0); } 1.1169 + void Resize(UPInt newSize) { Data.Resize(newSize); } 1.1170 + 1.1171 + // Reserve can only increase the capacity 1.1172 + void Reserve(UPInt newCapacity) 1.1173 + { 1.1174 + if (newCapacity > Data.GetCapacity()) 1.1175 + Data.Reserve(newCapacity); 1.1176 + } 1.1177 + 1.1178 + // Basic access. 1.1179 + ValueType& At(UPInt index) 1.1180 + { 1.1181 + OVR_ASSERT(index < Data.Size); 1.1182 + return Data.Data[index]; 1.1183 + } 1.1184 + const ValueType& At(UPInt index) const 1.1185 + { 1.1186 + OVR_ASSERT(index < Data.Size); 1.1187 + return Data.Data[index]; 1.1188 + } 1.1189 + 1.1190 + ValueType ValueAt(UPInt index) const 1.1191 + { 1.1192 + OVR_ASSERT(index < Data.Size); 1.1193 + return Data.Data[index]; 1.1194 + } 1.1195 + 1.1196 + // Basic access. 1.1197 + ValueType& operator [] (UPInt index) 1.1198 + { 1.1199 + OVR_ASSERT(index < Data.Size); 1.1200 + return Data.Data[index]; 1.1201 + } 1.1202 + const ValueType& operator [] (UPInt index) const 1.1203 + { 1.1204 + OVR_ASSERT(index < Data.Size); 1.1205 + return Data.Data[index]; 1.1206 + } 1.1207 + 1.1208 + // Raw pointer to the data. Use with caution! 1.1209 + const ValueType* GetDataPtr() const { return Data.Data; } 1.1210 + ValueType* GetDataPtr() { return Data.Data; } 1.1211 + 1.1212 + // Insert the given element at the end of the array. 1.1213 + void PushBack(const ValueType& val) 1.1214 + { 1.1215 + // DO NOT pass elements of your own vector into 1.1216 + // push_back()! Since we're using references, 1.1217 + // resize() may munge the element storage! 1.1218 + // OVR_ASSERT(&val < &Buffer[0] || &val > &Buffer[BufferSize]); 1.1219 + Data.PushBack(val); 1.1220 + } 1.1221 + 1.1222 + template<class S> 1.1223 + void PushBackAlt(const S& val) 1.1224 + { 1.1225 + Data.PushBackAlt(val); 1.1226 + } 1.1227 + 1.1228 + // Remove the last element. 1.1229 + void PopBack(UPInt count = 1) 1.1230 + { 1.1231 + OVR_ASSERT(Data.Size >= count); 1.1232 + Data.Resize(Data.Size - count); 1.1233 + } 1.1234 + 1.1235 + ValueType& PushDefault() 1.1236 + { 1.1237 + Data.PushBack(ValueType()); 1.1238 + return Back(); 1.1239 + } 1.1240 + 1.1241 + ValueType Pop() 1.1242 + { 1.1243 + ValueType t = Back(); 1.1244 + PopBack(); 1.1245 + return t; 1.1246 + } 1.1247 + 1.1248 + 1.1249 + // Access the first element. 1.1250 + ValueType& Front() { return At(0); } 1.1251 + const ValueType& Front() const { return At(0); } 1.1252 + 1.1253 + // Access the last element. 1.1254 + ValueType& Back() { return At(Data.Size - 1); } 1.1255 + const ValueType& Back() const { return At(Data.Size - 1); } 1.1256 + 1.1257 + // Array copy. Copies the contents of a into this array. 1.1258 + const SelfType& operator = (const SelfType& a) 1.1259 + { 1.1260 + Resize(a.GetSize()); 1.1261 + for (UPInt i = 0; i < Data.Size; i++) { 1.1262 + *(Data.Data + i) = a[i]; 1.1263 + } 1.1264 + return *this; 1.1265 + } 1.1266 + 1.1267 + // Removing multiple elements from the array. 1.1268 + void RemoveMultipleAt(UPInt index, UPInt num) 1.1269 + { 1.1270 + OVR_ASSERT(index + num <= Data.Size); 1.1271 + if (Data.Size == num) 1.1272 + { 1.1273 + Clear(); 1.1274 + } 1.1275 + else 1.1276 + { 1.1277 + AllocatorType::DestructArray(Data.Data + index, num); 1.1278 + AllocatorType::CopyArrayForward( 1.1279 + Data.Data + index, 1.1280 + Data.Data + index + num, 1.1281 + Data.Size - num - index); 1.1282 + Data.Size -= num; 1.1283 + } 1.1284 + } 1.1285 + 1.1286 + // Removing an element from the array is an expensive operation! 1.1287 + // It compacts only after removing the last element. 1.1288 + void RemoveAt(UPInt index) 1.1289 + { 1.1290 + OVR_ASSERT(index < Data.Size); 1.1291 + if (Data.Size == 1) 1.1292 + { 1.1293 + Clear(); 1.1294 + } 1.1295 + else 1.1296 + { 1.1297 + AllocatorType::Destruct(Data.Data + index); 1.1298 + AllocatorType::CopyArrayForward( 1.1299 + Data.Data + index, 1.1300 + Data.Data + index + 1, 1.1301 + Data.Size - 1 - index); 1.1302 + --Data.Size; 1.1303 + } 1.1304 + } 1.1305 + 1.1306 + // Insert the given object at the given index shifting all the elements up. 1.1307 + void InsertAt(UPInt index, const ValueType& val = ValueType()) 1.1308 + { 1.1309 + OVR_ASSERT(index <= Data.Size); 1.1310 + 1.1311 + Data.Resize(Data.Size + 1); 1.1312 + if (index < Data.Size - 1) 1.1313 + { 1.1314 + AllocatorType::CopyArrayBackward( 1.1315 + Data.Data + index + 1, 1.1316 + Data.Data + index, 1.1317 + Data.Size - 1 - index); 1.1318 + } 1.1319 + AllocatorType::Construct(Data.Data + index, val); 1.1320 + } 1.1321 + 1.1322 + // Insert the given object at the given index shifting all the elements up. 1.1323 + void InsertMultipleAt(UPInt index, UPInt num, const ValueType& val = ValueType()) 1.1324 + { 1.1325 + OVR_ASSERT(index <= Data.Size); 1.1326 + 1.1327 + Data.Resize(Data.Size + num); 1.1328 + if (index < Data.Size - num) 1.1329 + { 1.1330 + AllocatorType::CopyArrayBackward( 1.1331 + Data.Data + index + num, 1.1332 + Data.Data + index, 1.1333 + Data.Size - num - index); 1.1334 + } 1.1335 + for (UPInt i = 0; i < num; ++i) 1.1336 + AllocatorType::Construct(Data.Data + index + i, val); 1.1337 + } 1.1338 + 1.1339 + // Append the given data to the array. 1.1340 + void Append(const SelfType& other) 1.1341 + { 1.1342 + Append(other.Data.Data, other.GetSize()); 1.1343 + } 1.1344 + 1.1345 + // Append the given data to the array. 1.1346 + void Append(const ValueType other[], UPInt count) 1.1347 + { 1.1348 + Data.Append(other, count); 1.1349 + } 1.1350 + 1.1351 + class Iterator 1.1352 + { 1.1353 + SelfType* pArray; 1.1354 + SPInt CurIndex; 1.1355 + 1.1356 + public: 1.1357 + Iterator() : pArray(0), CurIndex(-1) {} 1.1358 + Iterator(SelfType* parr, SPInt idx = 0) : pArray(parr), CurIndex(idx) {} 1.1359 + 1.1360 + bool operator==(const Iterator& it) const { return pArray == it.pArray && CurIndex == it.CurIndex; } 1.1361 + bool operator!=(const Iterator& it) const { return pArray != it.pArray || CurIndex != it.CurIndex; } 1.1362 + 1.1363 + Iterator& operator++() 1.1364 + { 1.1365 + if (pArray) 1.1366 + { 1.1367 + if (CurIndex < (SPInt)pArray->GetSize()) 1.1368 + ++CurIndex; 1.1369 + } 1.1370 + return *this; 1.1371 + } 1.1372 + Iterator operator++(int) 1.1373 + { 1.1374 + Iterator it(*this); 1.1375 + operator++(); 1.1376 + return it; 1.1377 + } 1.1378 + Iterator& operator--() 1.1379 + { 1.1380 + if (pArray) 1.1381 + { 1.1382 + if (CurIndex >= 0) 1.1383 + --CurIndex; 1.1384 + } 1.1385 + return *this; 1.1386 + } 1.1387 + Iterator operator--(int) 1.1388 + { 1.1389 + Iterator it(*this); 1.1390 + operator--(); 1.1391 + return it; 1.1392 + } 1.1393 + Iterator operator+(int delta) const 1.1394 + { 1.1395 + return Iterator(pArray, CurIndex + delta); 1.1396 + } 1.1397 + Iterator operator-(int delta) const 1.1398 + { 1.1399 + return Iterator(pArray, CurIndex - delta); 1.1400 + } 1.1401 + SPInt operator-(const Iterator& right) const 1.1402 + { 1.1403 + OVR_ASSERT(pArray == right.pArray); 1.1404 + return CurIndex - right.CurIndex; 1.1405 + } 1.1406 + ValueType& operator*() const { OVR_ASSERT(pArray); return (*pArray)[CurIndex]; } 1.1407 + ValueType* operator->() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; } 1.1408 + ValueType* GetPtr() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; } 1.1409 + 1.1410 + bool IsFinished() const { return !pArray || CurIndex < 0 || CurIndex >= (int)pArray->GetSize(); } 1.1411 + 1.1412 + void Remove() 1.1413 + { 1.1414 + if (!IsFinished()) 1.1415 + pArray->RemoveAt(CurIndex); 1.1416 + } 1.1417 + 1.1418 + SPInt GetIndex() const { return CurIndex; } 1.1419 + }; 1.1420 + 1.1421 + Iterator Begin() { return Iterator(this); } 1.1422 + Iterator End() { return Iterator(this, (SPInt)GetSize()); } 1.1423 + Iterator Last() { return Iterator(this, (SPInt)GetSize() - 1); } 1.1424 + 1.1425 + class ConstIterator 1.1426 + { 1.1427 + const SelfType* pArray; 1.1428 + SPInt CurIndex; 1.1429 + 1.1430 + public: 1.1431 + ConstIterator() : pArray(0), CurIndex(-1) {} 1.1432 + ConstIterator(const SelfType* parr, SPInt idx = 0) : pArray(parr), CurIndex(idx) {} 1.1433 + 1.1434 + bool operator==(const ConstIterator& it) const { return pArray == it.pArray && CurIndex == it.CurIndex; } 1.1435 + bool operator!=(const ConstIterator& it) const { return pArray != it.pArray || CurIndex != it.CurIndex; } 1.1436 + 1.1437 + ConstIterator& operator++() 1.1438 + { 1.1439 + if (pArray) 1.1440 + { 1.1441 + if (CurIndex < (int)pArray->GetSize()) 1.1442 + ++CurIndex; 1.1443 + } 1.1444 + return *this; 1.1445 + } 1.1446 + ConstIterator operator++(int) 1.1447 + { 1.1448 + ConstIterator it(*this); 1.1449 + operator++(); 1.1450 + return it; 1.1451 + } 1.1452 + ConstIterator& operator--() 1.1453 + { 1.1454 + if (pArray) 1.1455 + { 1.1456 + if (CurIndex >= 0) 1.1457 + --CurIndex; 1.1458 + } 1.1459 + return *this; 1.1460 + } 1.1461 + ConstIterator operator--(int) 1.1462 + { 1.1463 + ConstIterator it(*this); 1.1464 + operator--(); 1.1465 + return it; 1.1466 + } 1.1467 + ConstIterator operator+(int delta) const 1.1468 + { 1.1469 + return ConstIterator(pArray, CurIndex + delta); 1.1470 + } 1.1471 + ConstIterator operator-(int delta) const 1.1472 + { 1.1473 + return ConstIterator(pArray, CurIndex - delta); 1.1474 + } 1.1475 + SPInt operator-(const ConstIterator& right) const 1.1476 + { 1.1477 + OVR_ASSERT(pArray == right.pArray); 1.1478 + return CurIndex - right.CurIndex; 1.1479 + } 1.1480 + const ValueType& operator*() const { OVR_ASSERT(pArray); return (*pArray)[CurIndex]; } 1.1481 + const ValueType* operator->() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; } 1.1482 + const ValueType* GetPtr() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; } 1.1483 + 1.1484 + bool IsFinished() const { return !pArray || CurIndex < 0 || CurIndex >= (int)pArray->GetSize(); } 1.1485 + 1.1486 + SPInt GetIndex() const { return CurIndex; } 1.1487 + }; 1.1488 + ConstIterator Begin() const { return ConstIterator(this); } 1.1489 + ConstIterator End() const { return ConstIterator(this, (SPInt)GetSize()); } 1.1490 + ConstIterator Last() const { return ConstIterator(this, (SPInt)GetSize() - 1); } 1.1491 + 1.1492 +protected: 1.1493 + ArrayData Data; 1.1494 +}; 1.1495 + 1.1496 + 1.1497 + 1.1498 +//----------------------------------------------------------------------------------- 1.1499 +// ***** Array 1.1500 +// 1.1501 +// General purpose array for movable objects that require explicit 1.1502 +// construction/destruction. 1.1503 +template<class T, class SizePolicy=ArrayDefaultPolicy> 1.1504 +class Array : public ArrayBase<ArrayData<T, ContainerAllocator<T>, SizePolicy> > 1.1505 +{ 1.1506 +public: 1.1507 + typedef T ValueType; 1.1508 + typedef ContainerAllocator<T> AllocatorType; 1.1509 + typedef SizePolicy SizePolicyType; 1.1510 + typedef Array<T, SizePolicy> SelfType; 1.1511 + typedef ArrayBase<ArrayData<T, ContainerAllocator<T>, SizePolicy> > BaseType; 1.1512 + 1.1513 + Array() : BaseType() {} 1.1514 + Array(int size) : BaseType(size) {} 1.1515 + Array(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); } 1.1516 + Array(const SelfType& a) : BaseType(a) {} 1.1517 + const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; } 1.1518 +}; 1.1519 + 1.1520 +// ***** ArrayPOD 1.1521 +// 1.1522 +// General purpose array for movable objects that DOES NOT require 1.1523 +// construction/destruction. Constructors and destructors are not called! 1.1524 +// Global heap is in use. 1.1525 +template<class T, class SizePolicy=ArrayDefaultPolicy> 1.1526 +class ArrayPOD : public ArrayBase<ArrayData<T, ContainerAllocator_POD<T>, SizePolicy> > 1.1527 +{ 1.1528 +public: 1.1529 + typedef T ValueType; 1.1530 + typedef ContainerAllocator_POD<T> AllocatorType; 1.1531 + typedef SizePolicy SizePolicyType; 1.1532 + typedef ArrayPOD<T, SizePolicy> SelfType; 1.1533 + typedef ArrayBase<ArrayData<T, ContainerAllocator_POD<T>, SizePolicy> > BaseType; 1.1534 + 1.1535 + ArrayPOD() : BaseType() {} 1.1536 + ArrayPOD(int size) : BaseType(size) {} 1.1537 + ArrayPOD(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); } 1.1538 + ArrayPOD(const SelfType& a) : BaseType(a) {} 1.1539 + const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; } 1.1540 +}; 1.1541 + 1.1542 + 1.1543 +// ***** ArrayCPP 1.1544 +// 1.1545 +// General purpose, fully C++ compliant array. Can be used with non-movable data. 1.1546 +// Global heap is in use. 1.1547 +template<class T, class SizePolicy=ArrayDefaultPolicy> 1.1548 +class ArrayCPP : public ArrayBase<ArrayData<T, ContainerAllocator_CPP<T>, SizePolicy> > 1.1549 +{ 1.1550 +public: 1.1551 + typedef T ValueType; 1.1552 + typedef ContainerAllocator_CPP<T> AllocatorType; 1.1553 + typedef SizePolicy SizePolicyType; 1.1554 + typedef ArrayCPP<T, SizePolicy> SelfType; 1.1555 + typedef ArrayBase<ArrayData<T, ContainerAllocator_CPP<T>, SizePolicy> > BaseType; 1.1556 + 1.1557 + ArrayCPP() : BaseType() {} 1.1558 + ArrayCPP(int size) : BaseType(size) {} 1.1559 + ArrayCPP(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); } 1.1560 + ArrayCPP(const SelfType& a) : BaseType(a) {} 1.1561 + const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; } 1.1562 +}; 1.1563 + 1.1564 + 1.1565 +// ***** ArrayCC 1.1566 +// 1.1567 +// A modification of the array that uses the given default value to 1.1568 +// construct the elements. The constructors and destructors are 1.1569 +// properly called, the objects must be movable. 1.1570 + 1.1571 +template<class T, class SizePolicy=ArrayDefaultPolicy> 1.1572 +class ArrayCC : public ArrayBase<ArrayDataCC<T, ContainerAllocator<T>, SizePolicy> > 1.1573 +{ 1.1574 +public: 1.1575 + typedef T ValueType; 1.1576 + typedef ContainerAllocator<T> AllocatorType; 1.1577 + typedef SizePolicy SizePolicyType; 1.1578 + typedef ArrayCC<T, SizePolicy> SelfType; 1.1579 + typedef ArrayBase<ArrayDataCC<T, ContainerAllocator<T>, SizePolicy> > BaseType; 1.1580 + 1.1581 + ArrayCC(const ValueType& defval) : BaseType(defval) {} 1.1582 + ArrayCC(const ValueType& defval, int size) : BaseType(defval, size) {} 1.1583 + ArrayCC(const ValueType& defval, const SizePolicyType& p) : BaseType(defval) { SetSizePolicy(p); } 1.1584 + ArrayCC(const SelfType& a) : BaseType(a) {} 1.1585 + const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; } 1.1586 +}; 1.1587 + 1.1588 +} // OVR 1.1589 + 1.1590 +#endif