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