tVector.h
Engine/source/core/util/tVector.h
Classes:
class
A dynamic array template class.
class
Template for vectors of pointers.
class
Public Defines
define
Use the following macro to bind a vector to a particular line of the owning class for memory tracking purposes.
Public Typedefs
qsort_compare_func )(const void *, const void *)
Public Variables
Size of memory blocks to allocate at a time for vectors.
Public Functions
Detailed Description
Public Defines
VECTOR_SET_ASSOCIATION(x)
Use the following macro to bind a vector to a particular line of the owning class for memory tracking purposes.
Public Typedefs
typedef S32(QSORT_CALLBACK * qsort_compare_func )(const void *, const void *)
Public Variables
const S32 VectorBlockSize
Size of memory blocks to allocate at a time for vectors.
Public Functions
VectorResize(U32 * aSize, U32 * aCount, void ** arrayPtr, U32 newCount, U32 elemSize)
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#ifndef _TVECTOR_H_ 25#define _TVECTOR_H_ 26 27// TODO: This shouldn't be included in headers... it should 28// be included by the source file before all other includes. 29#ifndef _PLATFORM_H_ 30#include "platform/platform.h" 31#endif 32#include <algorithm> 33#include "console/engineTypes.h" 34#include "console/engineTypeInfo.h" 35 36//----------------------------------------------------------------------------- 37// Helper definitions for the vector class. 38 39/// Size of memory blocks to allocate at a time for vectors. 40const static S32 VectorBlockSize = 16; 41#ifdef TORQUE_DEBUG_GUARD 42extern bool VectorResize(U32 *aSize, U32 *aCount, void **arrayPtr, U32 newCount, U32 elemSize, 43 const char* fileName, 44 const U32 lineNum); 45#else 46extern bool VectorResize(U32 *aSize, U32 *aCount, void **arrayPtr, U32 newCount, U32 elemSize); 47#endif 48 49/// Use the following macro to bind a vector to a particular line 50/// of the owning class for memory tracking purposes 51#ifdef TORQUE_DEBUG_GUARD 52#define VECTOR_SET_ASSOCIATION(x) x.setFileAssociation(__FILE__, __LINE__) 53#else 54#define VECTOR_SET_ASSOCIATION(x) 55#endif 56 57// ============================================================================= 58/// A dynamic array template class. 59/// 60/// The vector grows as you insert or append 61/// elements. Insertion is fastest at the end of the array. Resizing 62/// of the array can be avoided by pre-allocating space using the 63/// reserve() method. 64/// 65/// @nosubgrouping 66template<class T> 67class Vector 68{ 69 friend class VectorFieldEngineExport; 70 protected: 71 U32 mElementCount; ///< Number of elements currently in the Vector. 72 U32 mArraySize; ///< Number of elements allocated for the Vector. 73 T* mArray; ///< Pointer to the Vector elements. 74 75#ifdef TORQUE_DEBUG_GUARD 76 const char* mFileAssociation; 77 U32 mLineAssociation; 78#endif 79 80 bool resize(U32); // resizes, but does no construction/destruction 81 void destroy(U32 start, U32 end); ///< Destructs elements from <i>start</i> to <i>end-1</i> 82 void construct(U32 start, U32 end); ///< Constructs elements from <i>start</i> to <i>end-1</i> 83 void construct(U32 start, U32 end, const T* array); 84 public: 85 Vector(const U32 initialSize = 0); 86 Vector(const U32 initialSize, const char* fileName, const U32 lineNum); 87 Vector(const char* fileName, const U32 lineNum); 88 Vector(const Vector&); 89 ~Vector(); 90 91#ifdef TORQUE_DEBUG_GUARD 92 void setFileAssociation(const char* file, const U32 line); 93#endif 94 95 /// @name STL interface 96 /// @{ 97 98 typedef T value_type; 99 typedef T& reference; 100 typedef const T& const_reference; 101 102 typedef T* iterator; 103 typedef const T* const_iterator; 104 typedef S32 difference_type; 105 typedef U32 size_type; 106 107 typedef difference_type (QSORT_CALLBACK *compare_func)(const T *a, const T *b); 108 109 Vector<T>& operator=(const Vector<T>& p); 110 111 iterator begin(); 112 const_iterator begin() const; 113 iterator end(); 114 const_iterator end() const; 115 116 S32 size() const; 117 bool empty() const; 118 bool contains(const T&) const; 119 120 void insert(iterator, const T&); 121 void erase(iterator); 122 123 T& front(); 124 const T& front() const; 125 T& back(); 126 const T& back() const; 127 128 void push_front(const T&); 129 void push_back(const T&); 130 U32 push_front_unique(const T&); 131 U32 push_back_unique(const T&); 132 S32 find_next( const T&, U32 start = 0 ) const; 133 void pop_front(); 134 void pop_back(); 135 136 T& operator[](U32); 137 const T& operator[](U32) const; 138 139 T& operator[](S32 i) { return operator[](U32(i)); } 140 const T& operator[](S32 i ) const { return operator[](U32(i)); } 141 142 void reserve(U32); 143 U32 capacity() const; 144 145 /// @} 146 147 /// @name Extended interface 148 /// @{ 149 150 U32 memSize() const; 151 T* address() const; 152 U32 setSize(U32); 153 void increment(); 154 void decrement(); 155 void increment(U32); 156 void decrement(U32); 157 void insert(U32); 158 void insert(U32, const T&); 159 void erase(U32); 160 void erase_fast(U32); 161 void erase(U32 index, U32 count); 162 void erase_fast(iterator); 163 void clear(); 164 void compact(); 165 void sort(compare_func f); 166 void fill( const T& value ); 167 168 /// Finds the first matching element and erases it. 169 /// @return Returns true if a match is found. 170 bool remove( const T& ); 171 172 T& first(); 173 T& last(); 174 const T& first() const; 175 const T& last() const; 176 177 void set(void * addr, U32 sz); 178 179 /// Appends the content of the vector to this one. 180 void merge( const Vector &p ); 181 182 /// Appends the content of the array to the vector. 183 /// 184 /// @param addr A pointer to the first item of the array to merge. 185 /// @param count The number of elements in the array to merge. 186 /// 187 void merge( const T *addr, U32 count ); 188 189 // Reverses the order of elements. 190 void reverse(); 191 192 /// @} 193}; 194 195class VectorFieldEngineExport 196{ 197public: 198 template <class T> 199 static EngineFieldTable::Field getElementCountField() 200 { 201 typedef Vector<T> ThisType; 202 return _FIELD(mElementCount, elementCount, 1, ""); 203 }; 204 template <class T> 205 static EngineFieldTable::Field getArraySizeField() 206 { 207 typedef Vector<T> ThisType; 208 return _FIELD(mArraySize, arraySize, 1, ""); 209 }; 210 template <class T> 211 static EngineFieldTable::Field getArrayField() 212 { 213 typedef Vector<T> ThisType; 214 return _FIELD(mArray, array, 1, ""); 215 }; 216}; 217 218template<class T> inline Vector<T>::~Vector() 219{ 220 clear(); 221 dFree(mArray); 222} 223 224template<class T> inline Vector<T>::Vector(const U32 initialSize) 225{ 226#ifdef TORQUE_DEBUG_GUARD 227 mFileAssociation = NULL; 228 mLineAssociation = 0; 229#endif 230 231 mArray = 0; 232 mElementCount = 0; 233 mArraySize = 0; 234 if(initialSize) 235 reserve(initialSize); 236} 237 238template<class T> inline Vector<T>::Vector(const U32 initialSize, 239 const char* fileName, 240 const U32 lineNum) 241{ 242#ifdef TORQUE_DEBUG_GUARD 243 mFileAssociation = fileName; 244 mLineAssociation = lineNum; 245#else 246// TORQUE_UNUSED(fileName); 247// TORQUE_UNUSED(lineNum); 248#endif 249 250 mArray = 0; 251 mElementCount = 0; 252 mArraySize = 0; 253 if(initialSize) 254 reserve(initialSize); 255} 256 257template<class T> inline Vector<T>::Vector(const char* fileName, 258 const U32 lineNum) 259{ 260#ifdef TORQUE_DEBUG_GUARD 261 mFileAssociation = fileName; 262 mLineAssociation = lineNum; 263#else 264// TORQUE_UNUSED(fileName); 265// TORQUE_UNUSED(lineNum); 266#endif 267 268 mArray = 0; 269 mElementCount = 0; 270 mArraySize = 0; 271} 272 273template<class T> inline Vector<T>::Vector(const Vector& p) 274{ 275#ifdef TORQUE_DEBUG_GUARD 276 mFileAssociation = p.mFileAssociation; 277 mLineAssociation = p.mLineAssociation; 278#endif 279 280 mArray = 0; 281 resize(p.mElementCount); 282 construct(0, p.mElementCount, p.mArray); 283} 284 285 286#ifdef TORQUE_DEBUG_GUARD 287template<class T> inline void Vector<T>::setFileAssociation(const char* file, 288 const U32 line) 289{ 290 mFileAssociation = file; 291 mLineAssociation = line; 292} 293#endif 294 295template<class T> inline void Vector<T>::destroy(U32 start, U32 end) // destroys from start to end-1 296{ 297 // This check is a little generous as we can legitimately get (0,0) as 298 // our parameters... so it won't detect every invalid case but it does 299 // remain simple. 300 AssertFatal(start <= mElementCount && end <= mElementCount, "Vector<T>::destroy - out of bounds start/end."); 301 302 // destroys from start to end-1 303 while(start < end) 304 destructInPlace(&mArray[start++]); 305} 306 307template<class T> inline void Vector<T>::construct(U32 start, U32 end) // destroys from start to end-1 308{ 309 AssertFatal(start <= mElementCount && end <= mElementCount, "Vector<T>::construct - out of bounds start/end."); 310 while(start < end) 311 constructInPlace(&mArray[start++]); 312} 313 314template<class T> inline void Vector<T>::construct(U32 start, U32 end, const T* array) // destroys from start to end-1 315{ 316 AssertFatal(start <= mElementCount && end <= mElementCount, "Vector<T>::construct - out of bounds start/end."); 317 while(start < end) 318 { 319 constructInPlace(&mArray[start], &array[start]); 320 start++; 321 } 322} 323 324template<class T> inline U32 Vector<T>::memSize() const 325{ 326 return capacity() * sizeof(T); 327} 328 329template<class T> inline T* Vector<T>::address() const 330{ 331 return mArray; 332} 333 334template<class T> inline U32 Vector<T>::setSize(U32 size) 335{ 336 const U32 oldSize = mElementCount; 337 338 if(size > mElementCount) 339 { 340 if (size > mArraySize) 341 resize(size); 342 343 // Set count first so we are in a valid state for construct. 344 mElementCount = size; 345 construct(oldSize, size); 346 } 347 else if(size < mElementCount) 348 { 349 destroy(size, oldSize); 350 mElementCount = size; 351 } 352 353 return mElementCount; 354} 355 356template<class T> inline void Vector<T>::increment() 357{ 358 if(mElementCount == mArraySize) 359 resize(mElementCount + 1); 360 else 361 mElementCount++; 362 constructInPlace(&mArray[mElementCount - 1]); 363} 364 365template<class T> inline void Vector<T>::decrement() 366{ 367 AssertFatal(mElementCount != 0, "Vector<T>::decrement - cannot decrement zero-length vector."); 368 mElementCount--; 369 destructInPlace(&mArray[mElementCount]); 370} 371 372template<class T> inline void Vector<T>::increment(U32 delta) 373{ 374 U32 count = mElementCount; 375 if ((mElementCount += delta) > mArraySize) 376 resize(mElementCount); 377 construct(count, mElementCount); 378} 379 380template<class T> inline void Vector<T>::decrement(U32 delta) 381{ 382 AssertFatal(mElementCount != 0, "Vector<T>::decrement - cannot decrement zero-length vector."); 383 384 const U32 count = mElementCount; 385 386 // Determine new count after decrement... 387 U32 newCount = mElementCount; 388 if (mElementCount > delta) 389 newCount -= delta; 390 else 391 newCount = 0; 392 393 // Destruct removed items... 394 destroy(newCount, count); 395 396 // Note new element count. 397 mElementCount = newCount; 398} 399 400template<class T> inline void Vector<T>::insert(U32 index) 401{ 402 AssertFatal(index <= mElementCount, "Vector<T>::insert - out of bounds index."); 403 404 if(mElementCount == mArraySize) 405 resize(mElementCount + 1); 406 else 407 mElementCount++; 408 409 dMemmove(&mArray[index + 1], 410 &mArray[index], 411 (mElementCount - index - 1) * sizeof(value_type)); 412 413 constructInPlace(&mArray[index]); 414} 415 416template<class T> inline void Vector<T>::insert(U32 index,const T& x) 417{ 418 insert(index); 419 mArray[index] = x; 420} 421 422template<class T> inline void Vector<T>::erase(U32 index) 423{ 424 AssertFatal(index < mElementCount, "Vector<T>::erase - out of bounds index!"); 425 426 destructInPlace(&mArray[index]); 427 428 if (index < (mElementCount - 1)) 429 { 430 dMemmove(&mArray[index], 431 &mArray[index + 1], 432 (mElementCount - index - 1) * sizeof(value_type)); 433 } 434 435 mElementCount--; 436} 437 438template<class T> inline bool Vector<T>::remove( const T& x ) 439{ 440 iterator i = begin(); 441 while (i != end()) 442 { 443 if (*i == x) 444 { 445 erase( i ); 446 return true; 447 } 448 449 i++; 450 } 451 452 return false; 453} 454 455template<class T> inline void Vector<T>::erase(U32 index, U32 count) 456{ 457 AssertFatal(index < mElementCount, "Vector<T>::erase - out of bounds index!"); 458 AssertFatal(count > 0, "Vector<T>::erase - count must be greater than zero!"); 459 AssertFatal(index+count <= mElementCount, "Vector<T>::erase - out of bounds count!"); 460 461 destroy( index, index+count ); 462 463 dMemmove( &mArray[index], 464 &mArray[index + count], 465 (mElementCount - index - count) * sizeof(value_type)); 466 467 mElementCount -= count; 468} 469 470template<class T> inline void Vector<T>::erase_fast(U32 index) 471{ 472 AssertFatal(index < mElementCount, "Vector<T>::erase_fast - out of bounds index."); 473 474 // CAUTION: this operator does NOT maintain list order 475 // Copy the last element into the deleted 'hole' and decrement the 476 // size of the vector. 477 destructInPlace(&mArray[index]); 478 if (index < (mElementCount - 1)) 479 dMemmove(&mArray[index], &mArray[mElementCount - 1], sizeof(value_type)); 480 mElementCount--; 481} 482 483template<class T> inline bool Vector<T>::contains(const T& x) const 484{ 485 const_iterator i = begin(); 486 while (i != end()) 487 { 488 if (*i == x) 489 return true; 490 491 i++; 492 } 493 494 return false; 495} 496 497template< class T > inline void Vector< T >::fill( const T& value ) 498{ 499 for( U32 i = 0; i < size(); ++ i ) 500 mArray[ i ] = value; 501} 502 503template<class T> inline T& Vector<T>::first() 504{ 505 AssertFatal(mElementCount != 0, "Vector<T>::first - Error, no first element of a zero sized array!"); 506 return mArray[0]; 507} 508 509template<class T> inline const T& Vector<T>::first() const 510{ 511 AssertFatal(mElementCount != 0, "Vector<T>::first - Error, no first element of a zero sized array! (const)"); 512 return mArray[0]; 513} 514 515template<class T> inline T& Vector<T>::last() 516{ 517 AssertFatal(mElementCount != 0, "Vector<T>::last - Error, no last element of a zero sized array!"); 518 return mArray[mElementCount - 1]; 519} 520 521template<class T> inline const T& Vector<T>::last() const 522{ 523 AssertFatal(mElementCount != 0, "Vector<T>::last - Error, no last element of a zero sized array! (const)"); 524 return mArray[mElementCount - 1]; 525} 526 527template<class T> inline void Vector<T>::clear() 528{ 529 destroy(0, mElementCount); 530 mElementCount = 0; 531} 532 533template<class T> inline void Vector<T>::compact() 534{ 535 resize(mElementCount); 536} 537 538typedef S32 (QSORT_CALLBACK *qsort_compare_func)(const void *, const void *); 539 540template<class T> inline void Vector<T>::sort(compare_func f) 541{ 542 qsort(address(), size(), sizeof(T), (qsort_compare_func) f); 543} 544 545//----------------------------------------------------------------------------- 546 547template<class T> inline Vector<T>& Vector<T>::operator=(const Vector<T>& p) 548{ 549 if(mElementCount > p.mElementCount) 550 { 551 destroy(p.mElementCount, mElementCount); 552 } 553 554 U32 count = getMin( mElementCount, p.mElementCount ); 555 U32 i; 556 for( i=0; i < count; i++ ) 557 { 558 mArray[i] = p.mArray[i]; 559 } 560 561 resize( p.mElementCount ); 562 563 if( i < p.mElementCount ) 564 { 565 construct(i, p.mElementCount, p.mArray); 566 } 567 return *this; 568} 569 570template<class T> inline typename Vector<T>::iterator Vector<T>::begin() 571{ 572 return mArray; 573} 574 575template<class T> inline typename Vector<T>::const_iterator Vector<T>::begin() const 576{ 577 return mArray; 578} 579 580template<class T> inline typename Vector<T>::iterator Vector<T>::end() 581{ 582 return mArray + mElementCount; 583} 584 585template<class T> inline typename Vector<T>::const_iterator Vector<T>::end() const 586{ 587 return mArray +mElementCount; 588} 589 590template<class T> inline S32 Vector<T>::size() const 591{ 592 return (S32)mElementCount; 593} 594 595template<class T> inline bool Vector<T>::empty() const 596{ 597 return (mElementCount == 0); 598} 599 600template<class T> inline void Vector<T>::insert(iterator p,const T& x) 601{ 602 U32 index = (U32) (p - mArray); 603 insert(index); 604 mArray[index] = x; 605} 606 607template<class T> inline void Vector<T>::erase(iterator q) 608{ 609 erase(U32(q - mArray)); 610} 611 612template<class T> inline void Vector<T>::erase_fast(iterator q) 613{ 614 erase_fast(U32(q - mArray)); 615} 616 617template<class T> inline T& Vector<T>::front() 618{ 619 return *begin(); 620} 621 622template<class T> inline const T& Vector<T>::front() const 623{ 624 return *begin(); 625} 626 627template<class T> inline T& Vector<T>::back() 628{ 629 AssertFatal(mElementCount != 0, "Vector<T>::back - cannot access last element of zero-length vector."); 630 return *(end()-1); 631} 632 633template<class T> inline const T& Vector<T>::back() const 634{ 635 AssertFatal(mElementCount != 0, "Vector<T>::back - cannot access last element of zero-length vector."); 636 return *(end()-1); 637} 638 639template<class T> inline void Vector<T>::push_front(const T& x) 640{ 641 insert(0); 642 mArray[0] = x; 643} 644 645template<class T> inline void Vector<T>::push_back(const T& x) 646{ 647 increment(); 648 mArray[mElementCount - 1] = x; 649} 650 651template<class T> inline U32 Vector<T>::push_front_unique(const T& x) 652{ 653 S32 index = find_next(x); 654 655 if (index == -1) 656 { 657 index = 0; 658 659 insert(index); 660 mArray[index] = x; 661 } 662 663 return index; 664} 665 666template<class T> inline U32 Vector<T>::push_back_unique(const T& x) 667{ 668 S32 index = find_next(x); 669 670 if (index == -1) 671 { 672 increment(); 673 674 index = mElementCount - 1; 675 mArray[index] = x; 676 } 677 678 return index; 679} 680 681template<class T> inline S32 Vector<T>::find_next( const T& x, U32 start ) const 682{ 683 S32 index = -1; 684 685 if (start < mElementCount) 686 { 687 for (U32 i = start; i < mElementCount; i++) 688 { 689 if (mArray[i] == x) 690 { 691 index = i; 692 break; 693 } 694 } 695 } 696 697 return index; 698} 699 700template<class T> inline void Vector<T>::pop_front() 701{ 702 AssertFatal(mElementCount != 0, "Vector<T>::pop_front - cannot pop the front of a zero-length vector."); 703 erase(U32(0)); 704} 705 706template<class T> inline void Vector<T>::pop_back() 707{ 708 AssertFatal(mElementCount != 0, "Vector<T>::pop_back - cannot pop the back of a zero-length vector."); 709 decrement(); 710} 711 712template<class T> inline T& Vector<T>::operator[](U32 index) 713{ 714 AssertFatal(index < mElementCount, avar("Vector<T>::operator[%i/%i] - out of bounds array access!", index, mElementCount)); 715 return mArray[index]; 716} 717 718template<class T> inline const T& Vector<T>::operator[](U32 index) const 719{ 720 AssertFatal(index < mElementCount, avar("Vector<T>::operator[%i/%i] - out of bounds array access!", index, mElementCount)); 721 return mArray[index]; 722} 723 724template<class T> inline void Vector<T>::reserve(U32 size) 725{ 726 if (size <= mArraySize) 727 return; 728 729 const U32 ec = mElementCount; 730 if (resize(size)) 731 mElementCount = ec; 732} 733 734template<class T> inline U32 Vector<T>::capacity() const 735{ 736 return mArraySize; 737} 738 739template<class T> inline void Vector<T>::set(void * addr, U32 sz) 740{ 741 if ( !addr ) 742 sz = 0; 743 744 setSize( sz ); 745 746 if ( addr && sz > 0 ) 747 dMemcpy(address(),addr,sz*sizeof(T)); 748} 749 750//----------------------------------------------------------------------------- 751 752template<class T> inline bool Vector<T>::resize(U32 ecount) 753{ 754#ifdef TORQUE_DEBUG_GUARD 755 return VectorResize(&mArraySize, &mElementCount, (void**) &mArray, ecount, sizeof(T), 756 mFileAssociation, mLineAssociation); 757#else 758 return VectorResize(&mArraySize, &mElementCount, (void**) &mArray, ecount, sizeof(T)); 759#endif 760} 761 762template<class T> inline void Vector<T>::merge( const Vector &p ) 763{ 764 if ( !p.size() ) 765 return; 766 767 const U32 oldSize = mElementCount; 768 const U32 newSize = oldSize + p.size(); 769 if ( newSize > mArraySize ) 770 resize( newSize ); 771 772 T *dest = mArray + oldSize; 773 const T *src = p.mArray; 774 while ( dest < mArray + newSize ) 775 constructInPlace( dest++, src++ ); 776 777 mElementCount = newSize; 778} 779 780template<class T> inline void Vector<T>::merge( const T *addr, U32 count ) 781{ 782 const U32 oldSize = mElementCount; 783 const U32 newSize = oldSize + count; 784 if ( newSize > mArraySize ) 785 resize( newSize ); 786 787 T *dest = mArray + oldSize; 788 while ( dest < mArray + newSize ) 789 constructInPlace( dest++, addr++ ); 790 791 mElementCount = newSize; 792} 793 794template<class T> inline void Vector<T>::reverse() 795{ 796 for (U32 i = 0, j = size(); (i != j) && (i != --j); ++i) 797 std::swap( mArray[ i ], mArray[ j ] ); 798} 799 800//----------------------------------------------------------------------------- 801/// Template for vectors of pointers. 802template <class T> 803class VectorPtr : public Vector<void *> 804{ 805 /// @deprecated Disallowed. 806 VectorPtr(const VectorPtr&); // Disallowed 807 808 public: 809 VectorPtr(); 810 VectorPtr(const char* fileName, const U32 lineNum); 811 812 /// @name STL interface 813 /// @{ 814 815 typedef T value_type; 816 typedef T& reference; 817 typedef const T& const_reference; 818 819 typedef T* iterator; 820 typedef const T* const_iterator; 821 typedef U32 difference_type; 822 typedef U32 size_type; 823 824 iterator begin(); 825 const_iterator begin() const; 826 iterator end(); 827 const_iterator end() const; 828 829 void insert(iterator,const T&); 830 void insert(S32 idx) { Parent::insert(idx); } 831 void erase(iterator); 832 833 T& front(); 834 const T& front() const; 835 T& back(); 836 const T& back() const; 837 void push_front(const T&); 838 void push_back(const T&); 839 840 T& operator[](U32); 841 const T& operator[](U32) const; 842 843 /// @} 844 845 /// @name Extended interface 846 /// @{ 847 848 typedef Vector<void*> Parent; 849 T& first(); 850 T& last(); 851 const T& first() const; 852 const T& last() const; 853 void erase_fast(U32); 854 void erase_fast(iterator); 855 856 /// @} 857}; 858 859 860//----------------------------------------------------------------------------- 861template<class T> inline VectorPtr<T>::VectorPtr() 862{ 863 // 864} 865 866template<class T> inline VectorPtr<T>::VectorPtr(const char* fileName, 867 const U32 lineNum) 868 : Vector<void*>(fileName, lineNum) 869{ 870 // 871} 872 873template<class T> inline T& VectorPtr<T>::first() 874{ 875 return (T&)Parent::first(); 876} 877 878template<class T> inline const T& VectorPtr<T>::first() const 879{ 880 return (const T)Parent::first(); 881} 882 883template<class T> inline T& VectorPtr<T>::last() 884{ 885 return (T&)Parent::last(); 886} 887 888template<class T> inline const T& VectorPtr<T>::last() const 889{ 890 return (const T&)Parent::last(); 891} 892 893template<class T> inline typename VectorPtr<T>::iterator VectorPtr<T>::begin() 894{ 895 return (iterator)Parent::begin(); 896} 897 898template<class T> inline typename VectorPtr<T>::const_iterator VectorPtr<T>::begin() const 899{ 900 return (const_iterator)Parent::begin(); 901} 902 903template<class T> inline typename VectorPtr<T>::iterator VectorPtr<T>::end() 904{ 905 return (iterator)Parent::end(); 906} 907 908template<class T> inline typename VectorPtr<T>::const_iterator VectorPtr<T>::end() const 909{ 910 return (const_iterator)Parent::end(); 911} 912 913template<class T> inline void VectorPtr<T>::insert(iterator i,const T& x) 914{ 915 Parent::insert( (Parent::iterator)i, (Parent::reference)x ); 916} 917 918template<class T> inline void VectorPtr<T>::erase(iterator i) 919{ 920 Parent::erase( (Parent::iterator)i ); 921} 922 923template<class T> inline void VectorPtr<T>::erase_fast(U32 index) 924{ 925 AssertFatal(index < mElementCount, "VectorPtr<T>::erase_fast - out of bounds index." ); 926 927 // CAUTION: this operator does not maintain list order 928 // Copy the last element into the deleted 'hole' and decrement the 929 // size of the vector. 930 // Assert: index >= 0 && index < mElementCount 931 if (index < (mElementCount - 1)) 932 mArray[index] = mArray[mElementCount - 1]; 933 decrement(); 934} 935 936template<class T> inline void VectorPtr<T>::erase_fast(iterator i) 937{ 938 erase_fast(U32(i - iterator(mArray))); 939} 940 941template<class T> inline T& VectorPtr<T>::front() 942{ 943 return *begin(); 944} 945 946template<class T> inline const T& VectorPtr<T>::front() const 947{ 948 return *begin(); 949} 950 951template<class T> inline T& VectorPtr<T>::back() 952{ 953 AssertFatal(mElementCount != 0, "Vector<T>::back - cannot access last element of zero-length vector."); 954 return *(end()-1); 955} 956 957template<class T> inline const T& VectorPtr<T>::back() const 958{ 959 AssertFatal(mElementCount != 0, "Vector<T>::back - cannot access last element of zero-length vector."); 960 return *(end()-1); 961} 962 963template<class T> inline void VectorPtr<T>::push_front(const T& x) 964{ 965 Parent::push_front((Parent::const_reference)x); 966} 967 968template<class T> inline void VectorPtr<T>::push_back(const T& x) 969{ 970 Parent::push_back((Parent::const_reference)x); 971} 972 973template<class T> inline T& VectorPtr<T>::operator[](U32 index) 974{ 975 return (T&)Parent::operator[](index); 976} 977 978template<class T> inline const T& VectorPtr<T>::operator[](U32 index) const 979{ 980 return (const T&)Parent::operator[](index); 981} 982 983//------------------------------------------------------------------------------ 984 985template <class T> class VectorSet : public Vector<T> 986{ 987public: 988 void insert(T dat) 989 { 990 if(find(this->begin(), this->end(), dat) == this->end()) 991 push_back(dat); 992 } 993}; 994 995// Include vector specializations 996#ifndef _TVECTORSPEC_H_ 997#include "core/util/tVectorSpecializations.h" 998#endif 999 1000#endif //_TVECTOR_H_ 1001 1002