1 /* 2 =========================================================================== 3 Copyright (C) 2000 - 2013, Raven Software, Inc. 4 Copyright (C) 2001 - 2013, Activision, Inc. 5 Copyright (C) 2013 - 2015, OpenJK contributors 6 7 This file is part of the OpenJK source code. 8 9 OpenJK is free software; you can redistribute it and/or modify it 10 under the terms of the GNU General Public License version 2 as 11 published by the Free Software Foundation. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, see <http://www.gnu.org/licenses/>. 20 =========================================================================== 21 */ 22 23 //////////////////////////////////////////////////////////////////////////////////////// 24 // RAVEN STANDARD TEMPLATE LIBRARY 25 // (c) 2002 Activision 26 // 27 // 28 // Vector 29 // ------ 30 // The vector class is a simple addition to the array. It supports some useful additions 31 // like sort and binary search, as well as keeping track of the number of objects 32 // contained within. 33 // 34 // 35 // 36 // 37 // 38 // NOTES: 39 // 40 // 41 //////////////////////////////////////////////////////////////////////////////////////// 42 #if !defined(RATL_VECTOR_VS_INC) 43 #define RATL_VECTOR_VS_INC 44 45 46 //////////////////////////////////////////////////////////////////////////////////////// 47 // Includes 48 //////////////////////////////////////////////////////////////////////////////////////// 49 #if !defined(RATL_COMMON_INC) 50 #include "ratl_common.h" 51 #endif 52 namespace ratl 53 { 54 55 56 //////////////////////////////////////////////////////////////////////////////////////// 57 // The Vector Class 58 //////////////////////////////////////////////////////////////////////////////////////// 59 template<class T> 60 class vector_base : public ratl_base 61 { 62 public: 63 typedef T TStorageTraits; 64 typedef typename T::TValue TTValue; 65 //////////////////////////////////////////////////////////////////////////////////// 66 // Capacity Enum 67 //////////////////////////////////////////////////////////////////////////////////// 68 static const int CAPACITY = T::CAPACITY; 69 private: 70 array_base<TStorageTraits> mArray; // The Memory 71 int mSize; 72 public: 73 74 //////////////////////////////////////////////////////////////////////////////////// 75 // Constructor 76 //////////////////////////////////////////////////////////////////////////////////// vector_base()77 vector_base() 78 { 79 mSize = 0; 80 } 81 82 //////////////////////////////////////////////////////////////////////////////////// 83 // Copy Constructor 84 //////////////////////////////////////////////////////////////////////////////////// vector_base(const vector_base & B)85 vector_base(const vector_base &B) 86 { 87 for (int i=0; i<B.size(); i++) 88 { 89 mArray[i] = B.mArray[i]; 90 } 91 mSize = B.mSize; 92 } 93 94 //////////////////////////////////////////////////////////////////////////////////// 95 // How Many Objects Can Be Added? 96 //////////////////////////////////////////////////////////////////////////////////// capacity()97 int capacity() const 98 { 99 assert(mSize>=0&&mSize<=CAPACITY); 100 return (CAPACITY); 101 } 102 103 //////////////////////////////////////////////////////////////////////////////////// 104 // How Many Objects Have Been Added To This Vector? 105 //////////////////////////////////////////////////////////////////////////////////// size()106 int size() const 107 { 108 assert(mSize>=0&&mSize<=CAPACITY); 109 return (mSize); 110 } 111 112 //////////////////////////////////////////////////////////////////////////////////// 113 // Have Any Objects Have Been Added To This Vector? 114 //////////////////////////////////////////////////////////////////////////////////// empty()115 bool empty() const 116 { 117 assert(mSize>=0&&mSize<=CAPACITY); 118 return (!mSize); 119 } 120 121 //////////////////////////////////////////////////////////////////////////////////// 122 // Have Any Objects Have Been Added To This Vector? 123 //////////////////////////////////////////////////////////////////////////////////// full()124 bool full() const 125 { 126 assert(mSize>=0&&mSize<=CAPACITY); 127 return (mSize==CAPACITY); 128 } 129 130 //////////////////////////////////////////////////////////////////////////////////// 131 // Clear Out Entire Array 132 //////////////////////////////////////////////////////////////////////////////////// clear()133 void clear() 134 { 135 mArray.clear(); 136 mSize = 0; 137 } 138 // Constant Access Operator 139 //////////////////////////////////////////////////////////////////////////////////// 140 const TTValue& operator[](int index) const 141 { 142 assert(index>=0&&index<mSize); 143 return mArray[index]; 144 } 145 146 //////////////////////////////////////////////////////////////////////////////////// 147 // Access Operator 148 //////////////////////////////////////////////////////////////////////////////////// 149 TTValue& operator[](int index) 150 { 151 assert(index>=0&&index<mSize); 152 return mArray[index]; 153 } 154 155 //////////////////////////////////////////////////////////////////////////////////// 156 // Access To The Raw Array Pointer 157 //////////////////////////////////////////////////////////////////////////////////// raw_array()158 TTValue * raw_array() 159 { 160 // this (intentionally) won't compile for anything except value semantics 161 // could be done with object semantics, but I would want to assert that all objects are contructed 162 return T::raw_array(mArray); 163 } 164 165 //////////////////////////////////////////////////////////////////////////////////// 166 // Access To The Raw Array Pointer 167 //////////////////////////////////////////////////////////////////////////////////// raw_array()168 const TTValue* raw_array() const 169 { 170 // this (intentionally) won't compile for anything except value semantics 171 // could be done with object semantics, but I would want to assert that all objects are contructed 172 return T::raw_array(mArray); 173 } 174 175 176 //////////////////////////////////////////////////////////////////////////////////// 177 // Assignment Operator 178 //////////////////////////////////////////////////////////////////////////////////// 179 vector_base& operator=(const vector_base& val) 180 { 181 for (int i=0; i<val.size(); i++) 182 { 183 mArray[i] = val.mArray[i]; 184 } 185 mSize = val.mSize; 186 return *this; 187 } 188 189 //////////////////////////////////////////////////////////////////////////////////// 190 // Add 191 //////////////////////////////////////////////////////////////////////////////////// push_back()192 TTValue & push_back() 193 { 194 assert(mSize>=0&&mSize<CAPACITY); 195 mArray.construct(mSize); 196 mSize++; 197 return (mArray[mSize-1]); 198 } 199 200 //////////////////////////////////////////////////////////////////////////////////// 201 // Add (And Set) 202 //////////////////////////////////////////////////////////////////////////////////// push_back(const TTValue & value)203 void push_back(const TTValue& value) 204 { 205 assert(mSize>=0&&mSize<CAPACITY); 206 mArray.construct(mSize,value); 207 mSize++; 208 } 209 210 //////////////////////////////////////////////////////////////////////////////////// 211 // Add raw 212 //////////////////////////////////////////////////////////////////////////////////// push_back_raw()213 TRatlNew * push_back_raw() 214 { 215 assert(mSize>=0&&mSize<CAPACITY); 216 mSize++; 217 return mArray.alloc_raw(mSize-1); 218 } 219 220 //////////////////////////////////////////////////////////////////////////////////// 221 // Remove 222 //////////////////////////////////////////////////////////////////////////////////// pop_back()223 void pop_back() 224 { 225 assert(mSize>0); 226 mSize--; 227 mArray.destruct(mSize); 228 } 229 230 //////////////////////////////////////////////////////////////////////////////////// 231 // Resizes The Array. If New Elements Are Needed, It Uses The (value) Param 232 //////////////////////////////////////////////////////////////////////////////////// resize(int nSize,const TTValue & value)233 void resize(int nSize, const TTValue& value) 234 { 235 int i; 236 for (i=(mSize-1); i>=nSize; i--) 237 { 238 mArray.destruct(i); 239 mSize--; 240 } 241 for (i=mSize; i<nSize; i++) 242 { 243 mArray.construct(i,value); 244 } 245 mSize = nSize; 246 } 247 248 //////////////////////////////////////////////////////////////////////////////////// 249 // Resizes The Array. If New Elements Are Needed, It Uses The (value) Param 250 //////////////////////////////////////////////////////////////////////////////////// resize(int nSize)251 void resize(int nSize) 252 { 253 int i; 254 for (i=mSize-1; i>=nSize; i--) 255 { 256 mArray.destruct(i); 257 mSize--; 258 } 259 for (i=mSize; i<nSize; i++) 260 { 261 mArray.construct(i); 262 } 263 mSize = nSize; 264 } 265 266 //////////////////////////////////////////////////////////////////////////////////// 267 // Swap the values at two locations 268 //////////////////////////////////////////////////////////////////////////////////// swap(int i,int j)269 void swap(int i,int j) 270 { 271 assert(i<mSize && j<mSize); 272 mArray.swap(i, j); 273 } 274 275 276 277 //////////////////////////////////////////////////////////////////////////////////// 278 // Erase An Iterator Location... NOTE: THIS DOES NOT PRESERVE ORDER IN THE VECTOR!! 279 //////////////////////////////////////////////////////////////////////////////////// erase_swap(int Index)280 void erase_swap(int Index) 281 { 282 assert(Index>=0 && Index<mSize); 283 if (Index != mSize - 1) 284 { 285 mArray.swap(Index, mSize - 1); 286 } 287 pop_back(); 288 } 289 290 291 //////////////////////////////////////////////////////////////////////////////////// 292 // Binary Search 293 //////////////////////////////////////////////////////////////////////////////////// find_index(const TTValue & value)294 int find_index(const TTValue& value) const 295 { 296 int base = 0; 297 int head = mSize-1; 298 299 while (1) 300 { 301 int searchAt = (base+head)/2; 302 303 if (base == head && searchAt == head) 304 { 305 break; 306 } 307 308 if (value < mArray[searchAt]) 309 { 310 head = searchAt-1; 311 } 312 else if (mArray[searchAt] < value) 313 { 314 base = searchAt; 315 } 316 else 317 { 318 return searchAt; 319 } 320 if (head < base) 321 { 322 break; 323 } 324 } 325 326 return mSize; //not found! 327 } 328 329 330 //////////////////////////////////////////////////////////////////////////////////// 331 // Heap Sort 332 // 333 // This sort algorithm has all the advantages of merge sort in terms of guarenteeing 334 // O(n log n) worst case, as well as all the advantages of quick sort in that it is 335 // "in place" and requires no additional storage. 336 // 337 //////////////////////////////////////////////////////////////////////////////////// sort()338 void sort() 339 { 340 // Temporary Data 341 //---------------- 342 int HeapSize; // How Large The Heap Is (Grows In PHASE 1, Shrinks In PHASE 2) 343 int Pos; // The Location We Are AT During "re-heapify" Loops 344 int Compare; // The Location We Are Comparing AGAINST During "re-heapify" Loops 345 346 347 348 349 // PHASE 1, CONSTRUCT THE HEAP O(n log n) 350 //=============================================================================== 351 for (HeapSize=1; HeapSize<mSize; HeapSize++) 352 { 353 // We Now Have An Element At Heap Size Which Is Not In It's Correct Place 354 //------------------------------------------------------------------------ 355 Pos = HeapSize; 356 Compare = parent(Pos); 357 while (mArray[Compare]<mArray[Pos]) 358 { 359 // Swap The Compare Element With The Pos Element 360 //----------------------------------------------- 361 mArray.swap(Compare, Pos); 362 363 // Move Pos To The Current Compare, And Recalc Compare 364 //------------------------------------------------------ 365 Pos = Compare; 366 Compare = parent(Pos); 367 } 368 } 369 370 371 372 373 // PHASE 2, POP OFF THE TOP OF THE HEAP ONE AT A TIME (AND FIX) O(n log n) 374 //=============================================================================== 375 for (HeapSize=(mSize-1); HeapSize>0; HeapSize--) 376 { 377 // Swap The End And Front Of The "Heap" Half Of The Array 378 //-------------------------------------------------------- 379 mArray.swap(0, HeapSize); 380 381 // We Now Have A Bogus Element At The Root, So Fix The Heap 382 //---------------------------------------------------------- 383 Pos = 0; 384 Compare = largest_child(Pos, HeapSize); 385 while (mArray[Pos]<mArray[Compare]) 386 { 387 // Swap The Compare Element With The Pos Element 388 //----------------------------------------------- 389 mArray.swap(Compare, Pos); 390 391 // Move Pos To The Current Compare, And Recalc Compare 392 //------------------------------------------------------ 393 Pos = Compare; 394 Compare = largest_child(Pos, HeapSize); 395 } 396 } 397 } 398 399 400 //////////////////////////////////////////////////////////////////////////////////// 401 // THIS IS A QUICK VALIDATION OF A SORTED LIST 402 //////////////////////////////////////////////////////////////////////////////////// 403 #ifdef _DEBUG sort_validate()404 void sort_validate() const 405 { 406 for (int a=0; a<(mSize-1); a++) 407 { 408 assert(mArray[a] < mArray[a+1]); 409 } 410 } 411 #endif 412 413 private: 414 //////////////////////////////////////////////////////////////////////////////////// 415 // For Heap Sort 416 // Returns The Location Of Node (i)'s Parent Node (The Parent Node Of Zero Is Zero) 417 //////////////////////////////////////////////////////////////////////////////////// parent(int i)418 static int parent(int i) 419 { 420 return ((i-1)/2); 421 } 422 423 //////////////////////////////////////////////////////////////////////////////////// 424 // For Heap Sort 425 // Returns The Location Of Node (i)'s Left Child (The Child Of A Leaf Is The Leaf) 426 //////////////////////////////////////////////////////////////////////////////////// left(int i)427 static int left(int i) 428 { 429 return ((2*i)+1); 430 } 431 432 //////////////////////////////////////////////////////////////////////////////////// 433 // For Heap Sort 434 // Returns The Location Of Node (i)'s Right Child (The Child Of A Leaf Is The Leaf) 435 //////////////////////////////////////////////////////////////////////////////////// right(int i)436 static int right(int i) 437 { 438 return ((2*i)+2); 439 } 440 441 //////////////////////////////////////////////////////////////////////////////////// 442 // For Heap Sort 443 // Returns The Location Of Largest Child Of Node (i) 444 //////////////////////////////////////////////////////////////////////////////////// largest_child(int i,int Size)445 int largest_child(int i, int Size) const 446 { 447 if (left(i)<Size) 448 { 449 if (right(i)<Size) 450 { 451 return ( (mArray[right(i)] < mArray[left(i)]) ? (left(i)) : (right(i)) ); 452 } 453 return left(i); // Node i only has a left child, so by default it is the biggest 454 } 455 return i; // Node i is a leaf, so just return it 456 } 457 458 public: 459 //////////////////////////////////////////////////////////////////////////////////// 460 // Iterator 461 //////////////////////////////////////////////////////////////////////////////////// 462 class const_iterator; 463 class iterator 464 { 465 friend class vector_base<T>; 466 friend class const_iterator; 467 // Data 468 //------ 469 int mLoc; 470 vector_base<T>* mOwner; 471 472 public: 473 // Constructors 474 //-------------- iterator()475 iterator() : mOwner(0), mLoc(0) 476 {} iterator(vector_base<T> * p,int t)477 iterator(vector_base<T>* p, int t) : mOwner(p), mLoc(t) 478 {} 479 iterator(const iterator & t)480 iterator(const iterator &t) : mOwner(t.mOwner), mLoc(t.mLoc) 481 {} 482 483 // Assignment Operator 484 //--------------------- 485 void operator= (const iterator &t) 486 { 487 mOwner = t.mOwner; 488 mLoc = t.mLoc; 489 } 490 491 492 // Equality Operators 493 //-------------------- 494 bool operator!=(const iterator &t) const 495 { 496 return (mLoc!=t.mLoc || mOwner!=t.mOwner); 497 } 498 bool operator==(const iterator &t) const 499 { 500 return (mLoc==t.mLoc && mOwner==t.mOwner); 501 } 502 503 // DeReference Operator 504 //---------------------- 505 TTValue& operator* () const 506 { 507 assert(mLoc>=0 && mLoc<mOwner->mSize); 508 return (mOwner->mArray[mLoc]); 509 } 510 // DeReference Operator 511 //---------------------- value()512 TTValue& value() const 513 { 514 assert(mLoc>=0 && mLoc<mOwner->mSize); 515 return (mOwner->mArray[mLoc]); 516 } 517 518 // DeReference Operator 519 //---------------------- 520 TTValue* operator-> () const 521 { 522 assert(mLoc>=0 && mLoc<mOwner->mSize); 523 return (&mOwner->mArray[mLoc]); 524 } 525 526 // Inc Operator 527 //-------------- 528 iterator operator++(int) //postfix 529 { 530 assert(mLoc>=0 && mLoc<mOwner->mSize); 531 iterator old(*this); 532 mLoc ++; 533 return old; 534 } 535 536 // Inc Operator 537 //-------------- 538 iterator operator++() 539 { 540 assert(mLoc>=0 && mLoc<mOwner->mSize); 541 mLoc ++; 542 return *this; 543 } 544 545 }; 546 547 //////////////////////////////////////////////////////////////////////////////////// 548 // Constant Iterator 549 //////////////////////////////////////////////////////////////////////////////////// 550 class const_iterator 551 { 552 friend class vector_base<T>; 553 554 int mLoc; 555 const vector_base<T>* mOwner; 556 557 public: 558 // Constructors 559 //-------------- const_iterator()560 const_iterator() : mOwner(0), mLoc(0) 561 {} const_iterator(const vector_base<T> * p,int t)562 const_iterator(const vector_base<T>* p, int t) : mOwner(p), mLoc(t) 563 {} const_iterator(const const_iterator & t)564 const_iterator(const const_iterator &t) : mOwner(t.mOwner), mLoc(t.mLoc) 565 {} const_iterator(const iterator & t)566 const_iterator(const iterator &t) : mOwner(t.mOwner), mLoc(t.mLoc) 567 {} 568 569 // Assignment Operator 570 //--------------------- 571 void operator= (const const_iterator &t) 572 { 573 mOwner = t.mOwner; 574 mLoc = t.mLoc; 575 } 576 // Assignment Operator 577 //--------------------- 578 void operator= (const iterator &t) 579 { 580 mOwner = t.mOwner; 581 mLoc = t.mLoc; 582 } 583 584 585 586 // Equality Operators 587 //-------------------- 588 bool operator!=(const iterator &t) const 589 { 590 return (mLoc!=t.mLoc || mOwner!=t.mOwner); 591 } 592 bool operator==(const iterator &t) const 593 { 594 return (mLoc==t.mLoc && mOwner==t.mOwner); 595 } 596 597 // Equality Operators 598 //-------------------- 599 bool operator!=(const const_iterator &t) const 600 { 601 return (mLoc!=t.mLoc || mOwner!=t.mOwner); 602 } 603 bool operator==(const const_iterator &t) const 604 { 605 return (mLoc==t.mLoc && mOwner==t.mOwner); 606 } 607 608 // DeReference Operator 609 //---------------------- 610 const TTValue& operator* () const 611 { 612 assert(mLoc>=0 && mLoc<mOwner->mSize); 613 return (mOwner->mArray[mLoc]); 614 } 615 616 // DeReference Operator 617 //---------------------- value()618 const TTValue& value() const 619 { 620 assert(mLoc>=0 && mLoc<mOwner->mSize); 621 return (mOwner->mArray[mLoc]); 622 } 623 624 // DeReference Operator 625 //---------------------- 626 const TTValue* operator-> () const 627 { 628 assert(mLoc>=0 && mLoc<mOwner->mSize); 629 return (&mOwner->mArray[mLoc]); 630 } 631 632 // Inc Operator 633 //-------------- 634 const_iterator operator++(int) 635 { 636 assert(mLoc>=0 && mLoc<mOwner->mSize); 637 const_iterator old(*this); 638 mLoc ++; 639 return old; 640 } 641 642 // Inc Operator 643 //-------------- 644 const_iterator operator++() 645 { 646 assert(mLoc>=0 && mLoc<mOwner->mSize); 647 mLoc ++; 648 return *this; 649 } 650 651 652 }; 653 friend class iterator; 654 friend class const_iterator; 655 656 657 //////////////////////////////////////////////////////////////////////////////////// 658 // Iterator Begin (Starts At Address 0) 659 //////////////////////////////////////////////////////////////////////////////////// begin()660 iterator begin() 661 { 662 return iterator(this, 0); 663 } 664 665 //////////////////////////////////////////////////////////////////////////////////// 666 // Iterator End (Set To Address mSize) 667 //////////////////////////////////////////////////////////////////////////////////// end()668 iterator end() 669 { 670 return iterator(this, mSize); 671 } 672 673 //////////////////////////////////////////////////////////////////////////////////// 674 // Iterator Begin (Starts At Address 0) 675 //////////////////////////////////////////////////////////////////////////////////// begin()676 const_iterator begin() const 677 { 678 return const_iterator(this, 0); 679 } 680 681 //////////////////////////////////////////////////////////////////////////////////// 682 // Iterator End (Set To Address mSize) 683 //////////////////////////////////////////////////////////////////////////////////// end()684 const_iterator end() const 685 { 686 return const_iterator(this, mSize); 687 } 688 689 //////////////////////////////////////////////////////////////////////////////////// 690 // Iterator Find (If Fails To Find, Returns iterator end() 691 //////////////////////////////////////////////////////////////////////////////////// find(const TTValue & value)692 iterator find(const TTValue& value) 693 { 694 int index = find_index(value); // Call Find By Index 695 if (index<mSize) 696 { 697 return iterator(this, index); // Found It, Return An Iterator To Index 698 } 699 return end(); // Return "end" Iterator If Not Found 700 } 701 702 //////////////////////////////////////////////////////////////////////////////////// 703 // Iterator Find (If Fails To Find, Returns iterator end() 704 //////////////////////////////////////////////////////////////////////////////////// find(const TTValue & value)705 const_iterator find(const TTValue& value) const 706 { 707 int index = find_index(value); // Call Find By Index 708 if (index<mSize) 709 { 710 return const_iterator(this, index); // Found It, Return An Iterator To Index 711 } 712 return end(); // Return "end" Iterator If Not Found 713 } 714 715 //////////////////////////////////////////////////////////////////////////////////// 716 // Erase An Iterator Location... NOTE: THIS DOES NOT PRESERVE ORDER IN THE VECTOR!! 717 //////////////////////////////////////////////////////////////////////////////////// erase_swap(const iterator & it)718 iterator erase_swap(const iterator &it) 719 { 720 assert(it.mLoc>=0 && it.mLoc<it.mOwner->mSize); 721 if (it.mLoc != mSize - 1) 722 { 723 mArray.swap(it.mLoc, mSize - 1); 724 } 725 pop_back(); 726 return it; 727 } 728 template<class CAST_TO> verify_alloc(CAST_TO * p)729 CAST_TO *verify_alloc(CAST_TO *p) const 730 { 731 return mArray.verify_alloc(p); 732 } 733 }; 734 735 template<class T, int ARG_CAPACITY> 736 class vector_vs : public vector_base<storage::value_semantics<T,ARG_CAPACITY> > 737 { 738 public: 739 typedef typename storage::value_semantics<T,ARG_CAPACITY> TStorageTraits; 740 typedef typename TStorageTraits::TValue TTValue; 741 static const int CAPACITY = ARG_CAPACITY; vector_vs()742 vector_vs() {} 743 }; 744 745 template<class T, int ARG_CAPACITY> 746 class vector_os : public vector_base<storage::object_semantics<T,ARG_CAPACITY> > 747 { 748 public: 749 typedef typename storage::object_semantics<T,ARG_CAPACITY> TStorageTraits; 750 typedef typename TStorageTraits::TValue TTValue; 751 static const int CAPACITY = ARG_CAPACITY; vector_os()752 vector_os() {} 753 }; 754 755 template<class T, int ARG_CAPACITY, int ARG_MAX_CLASS_SIZE> 756 class vector_is : public vector_base<storage::virtual_semantics<T,ARG_CAPACITY,ARG_MAX_CLASS_SIZE> > 757 { 758 public: 759 typedef typename storage::virtual_semantics<T,ARG_CAPACITY,ARG_MAX_CLASS_SIZE> TStorageTraits; 760 typedef typename TStorageTraits::TValue TTValue; 761 static const int CAPACITY = ARG_CAPACITY; 762 static const int MAX_CLASS_SIZE = ARG_MAX_CLASS_SIZE; vector_is()763 vector_is() {} 764 }; 765 766 } 767 #endif 768