oculus1

annotate libovr/Src/Kernel/OVR_Array.h @ 1:e2f9e4603129

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