1 //---------------------------------------------------------------------------- 2 // Anti-Grain Geometry - Version 2.2 3 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) 4 // 5 // Permission to copy, use, modify, sell and distribute this software 6 // is granted provided this copyright notice appears in all copies. 7 // This software is provided "as is" without express or implied 8 // warranty, and with no claim as to its suitability for any purpose. 9 // 10 //---------------------------------------------------------------------------- 11 // Contact: mcseem@antigrain.com 12 // mcseemagg@yahoo.com 13 // http://www.antigrain.com 14 //---------------------------------------------------------------------------- 15 #ifndef AGG_ARRAY_INCLUDED 16 #define AGG_ARRAY_INCLUDED 17 18 #include <stddef.h> 19 #include <string.h> 20 #include "agg_basics.h" 21 22 namespace agg 23 { 24 25 //---------------------------------------------------------------pod_array 26 // A simple class template to store Plain Old Data, a vector 27 // of a fixed size. The data is continous in memory 28 //------------------------------------------------------------------------ 29 template<class T> class pod_array 30 { 31 public: 32 typedef T value_type; 33 34 ~pod_array() { delete [] m_array; } 35 pod_array() : m_size(0), m_capacity(0), m_array(0) {} 36 pod_array(unsigned cap, unsigned extra_tail=0); 37 38 // Copying 39 pod_array(const pod_array<T>&); 40 const pod_array<T>& operator = (const pod_array<T>&); 41 42 unsigned capacity() const { return m_capacity; } 43 void capacity(unsigned cap, unsigned extra_tail=0); 44 45 void resize(unsigned new_size); 46 47 void add(const T& v) { m_array[m_size++] = v; } 48 void inc_size(unsigned size) { m_size += size; } 49 unsigned size() const { return m_size; } 50 unsigned byte_size() const { return m_size * sizeof(T); } 51 void serialize(int8u* ptr) const; 52 void deserialize(const int8u* data, unsigned byte_size); 53 const T& operator [] (unsigned idx) const { return m_array[idx]; } 54 T& operator [] (unsigned idx) { return m_array[idx]; } 55 56 void remove_all() { m_size = 0; } 57 void cut_at(unsigned num) { if(num < m_size) m_size = num; } 58 59 private: 60 unsigned m_size; 61 unsigned m_capacity; 62 T* m_array; 63 }; 64 65 //------------------------------------------------------------------------ 66 template<class T> 67 void pod_array<T>::capacity(unsigned cap, unsigned extra_tail) 68 { 69 m_size = 0; 70 if(cap > m_capacity) 71 { 72 delete [] m_array; 73 m_capacity = cap + extra_tail; 74 m_array = m_capacity ? new T [m_capacity] : 0; 75 } 76 } 77 78 //------------------------------------------------------------------------ 79 template<class T> 80 void pod_array<T>::resize(unsigned new_size) 81 { 82 if(new_size > m_size) 83 { 84 if(new_size > m_capacity) 85 { 86 T* data = new T[new_size]; 87 memcpy(data, m_array, m_size * sizeof(T)); 88 delete [] m_array; 89 m_array = data; 90 } 91 } 92 else 93 { 94 m_size = new_size; 95 } 96 } 97 98 //------------------------------------------------------------------------ 99 template<class T> pod_array<T>::pod_array(unsigned cap, unsigned extra_tail) : 100 m_size(0), m_capacity(0), m_array(0) 101 { 102 capacity(cap, extra_tail); 103 } 104 105 //------------------------------------------------------------------------ 106 template<class T> pod_array<T>::pod_array(const pod_array<T>& v) : 107 m_size(v.m_size), 108 m_capacity(v.m_capacity), 109 m_array(v.m_capacity ? new T [v.m_capacity] : 0) 110 { 111 memcpy(m_array, v.m_array, sizeof(T) * v.m_size); 112 } 113 114 //------------------------------------------------------------------------ 115 template<class T> const pod_array<T>& 116 pod_array<T>::operator = (const pod_array<T>&v) 117 { 118 capacity(v.m_capacity); 119 if(v.m_size) memcpy(m_array, v.m_array, sizeof(T) * v.m_size); 120 return *this; 121 } 122 123 //------------------------------------------------------------------------ 124 template<class T> void pod_array<T>::serialize(int8u* ptr) const 125 { 126 if(m_size) memcpy(ptr, m_array, m_size * sizeof(T)); 127 } 128 129 //------------------------------------------------------------------------ 130 template<class T> 131 void pod_array<T>::deserialize(const int8u* data, unsigned byte_size) 132 { 133 byte_size /= sizeof(T); 134 capacity(byte_size); 135 if(byte_size) memcpy(m_array, data, byte_size * sizeof(T)); 136 } 137 138 //------------------------------------------------------------------------ 139 template<class T> class pod_array_adaptor 140 { 141 public: 142 typedef T value_type; 143 pod_array_adaptor(T* array, unsigned size) : 144 m_array(array), m_size(size) {} 145 146 unsigned size() const { return m_size; } 147 const T& operator [] (unsigned idx) const { return m_array[idx]; } 148 T& operator [] (unsigned idx) { return m_array[idx]; } 149 private: 150 T* m_array; 151 unsigned m_size; 152 }; 153 154 155 156 157 158 159 //---------------------------------------------------------------pod_deque 160 // A simple class template to store Plain Old Data, similar to std::deque 161 // It doesn't reallocate memory but instead, uses blocks of data of size 162 // of (1 << S), that is, power of two. The data is NOT continuous in memory, 163 // so the only valid access method is operator [] or curr(), prev(), next() 164 // 165 // There reallocs occure only when the pool of pointers to blocks needs 166 // to be extended (it happens very rear). You can control the value 167 // of increment to reallocate the pointer buffer. See the second constructor. 168 // By default, the incremeent value equals (1 << S), i.e., the block size. 169 //------------------------------------------------------------------------ 170 template<class T, unsigned S=6> class pod_deque 171 { 172 public: 173 enum 174 { 175 block_shift = S, 176 block_size = 1 << block_shift, 177 block_mask = block_size - 1 178 }; 179 180 typedef T value_type; 181 182 ~pod_deque(); 183 pod_deque(); 184 pod_deque(unsigned block_ptr_inc); 185 186 // Copying 187 pod_deque(const pod_deque<T, S>& v); 188 const pod_deque<T, S>& operator = (const pod_deque<T, S>& v); 189 190 void remove_all() { m_size = 0; } 191 void free_all() { free_tail(0); } 192 void free_tail(unsigned size); 193 void add(const T& val); 194 void modify_last(const T& val); 195 void remove_last(); 196 197 int allocate_continuous_block(unsigned num_elements); 198 199 void add_array(const T* ptr, unsigned num_elem) 200 { 201 while(num_elem--) 202 { 203 add(*ptr++); 204 } 205 } 206 207 template<class DataAccessor> void add_data(DataAccessor& data) 208 { 209 while(data.size()) 210 { 211 add(*data); 212 ++data; 213 } 214 } 215 216 void cut_at(unsigned size) 217 { 218 if(size < m_size) m_size = size; 219 } 220 221 unsigned size() const { return m_size; } 222 223 const T& operator [] (unsigned idx) const 224 { 225 return m_blocks[idx >> block_shift][idx & block_mask]; 226 } 227 228 T& operator [] (unsigned idx) 229 { 230 return m_blocks[idx >> block_shift][idx & block_mask]; 231 } 232 233 const T& curr(unsigned idx) const 234 { 235 return (*this)[idx]; 236 } 237 238 T& curr(unsigned idx) 239 { 240 return (*this)[idx]; 241 } 242 243 const T& prev(unsigned idx) const 244 { 245 return (*this)[(idx + m_size - 1) % m_size]; 246 } 247 248 T& prev(unsigned idx) 249 { 250 return (*this)[(idx + m_size - 1) % m_size]; 251 } 252 253 const T& next(unsigned idx) const 254 { 255 return (*this)[(idx + 1) % m_size]; 256 } 257 258 T& next(unsigned idx) 259 { 260 return (*this)[(idx + 1) % m_size]; 261 } 262 263 const T& last() const 264 { 265 return (*this)[m_size - 1]; 266 } 267 268 T& last() 269 { 270 return (*this)[m_size - 1]; 271 } 272 273 unsigned byte_size() const; 274 void serialize(int8u* ptr) const; 275 void deserialize(const int8u* data, unsigned byte_size); 276 void deserialize(unsigned start, const T& empty_val, 277 const int8u* data, unsigned byte_size); 278 279 template<class ByteAccessor> 280 void deserialize(ByteAccessor data) 281 { 282 remove_all(); 283 unsigned elem_size = data.size() / sizeof(T); 284 285 for(unsigned i = 0; i < elem_size; ++i) 286 { 287 int8u* ptr = (int8u*)data_ptr(); 288 for(unsigned j = 0; j < sizeof(T); ++j) 289 { 290 *ptr++ = *data; 291 ++data; 292 } 293 ++m_size; 294 } 295 } 296 297 template<class ByteAccessor> 298 void deserialize(unsigned start, const T& empty_val, ByteAccessor data) 299 { 300 while(m_size < start) 301 { 302 add(empty_val); 303 } 304 305 unsigned elem_size = data.size() / sizeof(T); 306 for(unsigned i = 0; i < elem_size; ++i) 307 { 308 int8u* ptr; 309 if(start + i < m_size) 310 { 311 ptr = (int8u*)(&((*this)[start + i])); 312 } 313 else 314 { 315 ptr = (int8u*)data_ptr(); 316 ++m_size; 317 } 318 for(unsigned j = 0; j < sizeof(T); ++j) 319 { 320 *ptr++ = *data; 321 ++data; 322 } 323 } 324 } 325 326 const T* block(unsigned nb) const { return m_blocks[nb]; } 327 328 private: 329 void allocate_block(unsigned nb); 330 T* data_ptr(); 331 332 unsigned m_size; 333 unsigned m_num_blocks; 334 unsigned m_max_blocks; 335 T** m_blocks; 336 unsigned m_block_ptr_inc; 337 }; 338 339 340 //------------------------------------------------------------------------ 341 template<class T, unsigned S> pod_deque<T, S>::~pod_deque() 342 { 343 if(m_num_blocks) 344 { 345 T** blk = m_blocks + m_num_blocks - 1; 346 while(m_num_blocks--) 347 { 348 delete [] *blk; 349 --blk; 350 } 351 delete [] m_blocks; 352 } 353 } 354 355 356 //------------------------------------------------------------------------ 357 template<class T, unsigned S> 358 void pod_deque<T, S>::free_tail(unsigned size) 359 { 360 if(size < m_size) 361 { 362 unsigned nb = (size + block_mask) >> block_shift; 363 while(m_num_blocks > nb) 364 { 365 delete [] m_blocks[--m_num_blocks]; 366 } 367 m_size = size; 368 } 369 } 370 371 372 //------------------------------------------------------------------------ 373 template<class T, unsigned S> pod_deque<T, S>::pod_deque() : 374 m_size(0), 375 m_num_blocks(0), 376 m_max_blocks(0), 377 m_blocks(0), 378 m_block_ptr_inc(block_size) 379 { 380 } 381 382 383 //------------------------------------------------------------------------ 384 template<class T, unsigned S> 385 pod_deque<T, S>::pod_deque(unsigned block_ptr_inc) : 386 m_size(0), 387 m_num_blocks(0), 388 m_max_blocks(0), 389 m_blocks(0), 390 m_block_ptr_inc(block_ptr_inc) 391 { 392 } 393 394 395 //------------------------------------------------------------------------ 396 template<class T, unsigned S> 397 pod_deque<T, S>::pod_deque(const pod_deque<T, S>& v) : 398 m_size(v.m_size), 399 m_num_blocks(v.m_num_blocks), 400 m_max_blocks(v.m_max_blocks), 401 m_blocks(v.m_max_blocks ? new T* [v.m_max_blocks] : 0), 402 m_block_ptr_inc(v.m_block_ptr_inc) 403 { 404 unsigned i; 405 for(i = 0; i < v.m_num_blocks; ++i) 406 { 407 m_blocks[i] = new T [block_size]; 408 memcpy(m_blocks[i], v.m_blocks[i], block_size * sizeof(T)); 409 } 410 } 411 412 413 //------------------------------------------------------------------------ 414 template<class T, unsigned S> 415 const pod_deque<T, S>& pod_deque<T, S>::operator = (const pod_deque<T, S>& v) 416 { 417 unsigned i; 418 for(i = m_num_blocks; i < v.m_num_blocks; ++i) 419 { 420 allocate_block(i); 421 } 422 for(i = 0; i < v.m_num_blocks; ++i) 423 { 424 memcpy(m_blocks[i], v.m_blocks[i], block_size * sizeof(T)); 425 } 426 m_size = v.m_size; 427 return *this; 428 } 429 430 431 //------------------------------------------------------------------------ 432 template<class T, unsigned S> 433 void pod_deque<T, S>::allocate_block(unsigned nb) 434 { 435 if(nb >= m_max_blocks) 436 { 437 T** new_blocks = new T* [m_max_blocks + m_block_ptr_inc]; 438 439 if(m_blocks) 440 { 441 memcpy(new_blocks, 442 m_blocks, 443 m_num_blocks * sizeof(T*)); 444 445 delete [] m_blocks; 446 } 447 m_blocks = new_blocks; 448 m_max_blocks += m_block_ptr_inc; 449 } 450 m_blocks[nb] = new T [block_size]; 451 m_num_blocks++; 452 } 453 454 455 456 //------------------------------------------------------------------------ 457 template<class T, unsigned S> 458 inline T* pod_deque<T, S>::data_ptr() 459 { 460 unsigned nb = m_size >> block_shift; 461 if(nb >= m_num_blocks) 462 { 463 allocate_block(nb); 464 } 465 return m_blocks[nb] + (m_size & block_mask); 466 } 467 468 469 470 //------------------------------------------------------------------------ 471 template<class T, unsigned S> 472 inline void pod_deque<T, S>::add(const T& val) 473 { 474 *data_ptr() = val; 475 ++m_size; 476 } 477 478 479 //------------------------------------------------------------------------ 480 template<class T, unsigned S> 481 inline void pod_deque<T, S>::remove_last() 482 { 483 if(m_size) --m_size; 484 } 485 486 487 //------------------------------------------------------------------------ 488 template<class T, unsigned S> 489 void pod_deque<T, S>::modify_last(const T& val) 490 { 491 remove_last(); 492 add(val); 493 } 494 495 496 //------------------------------------------------------------------------ 497 template<class T, unsigned S> 498 int pod_deque<T, S>::allocate_continuous_block(unsigned num_elements) 499 { 500 if(num_elements < block_size) 501 { 502 data_ptr(); // Allocate initial block if necessary 503 unsigned rest = block_size - (m_size & block_mask); 504 unsigned index; 505 if(num_elements <= rest) 506 { 507 // The rest of the block is good, we can use it 508 //----------------- 509 index = m_size; 510 m_size += num_elements; 511 return index; 512 } 513 514 // New block 515 //--------------- 516 m_size += rest; 517 data_ptr(); 518 index = m_size; 519 m_size += num_elements; 520 return index; 521 } 522 return -1; // Impossible to allocate 523 } 524 525 526 //------------------------------------------------------------------------ 527 template<class T, unsigned S> 528 unsigned pod_deque<T, S>::byte_size() const 529 { 530 return m_size * sizeof(T); 531 } 532 533 534 //------------------------------------------------------------------------ 535 template<class T, unsigned S> 536 void pod_deque<T, S>::serialize(int8u* ptr) const 537 { 538 unsigned i; 539 for(i = 0; i < m_size; i++) 540 { 541 memcpy(ptr, &(*this)[i], sizeof(T)); 542 ptr += sizeof(T); 543 } 544 } 545 546 //------------------------------------------------------------------------ 547 template<class T, unsigned S> 548 void pod_deque<T, S>::deserialize(const int8u* data, unsigned byte_size) 549 { 550 remove_all(); 551 byte_size /= sizeof(T); 552 for(unsigned i = 0; i < byte_size; ++i) 553 { 554 T* ptr = data_ptr(); 555 memcpy(ptr, data, sizeof(T)); 556 ++m_size; 557 data += sizeof(T); 558 } 559 } 560 561 562 // Replace or add a number of elements starting from "start" position 563 //------------------------------------------------------------------------ 564 template<class T, unsigned S> 565 void pod_deque<T, S>::deserialize(unsigned start, const T& empty_val, 566 const int8u* data, unsigned byte_size) 567 { 568 while(m_size < start) 569 { 570 add(empty_val); 571 } 572 573 byte_size /= sizeof(T); 574 for(unsigned i = 0; i < byte_size; ++i) 575 { 576 if(start + i < m_size) 577 { 578 memcpy(&((*this)[start + i]), data, sizeof(T)); 579 } 580 else 581 { 582 T* ptr = data_ptr(); 583 memcpy(ptr, data, sizeof(T)); 584 ++m_size; 585 } 586 data += sizeof(T); 587 } 588 } 589 590 591 //-----------------------------------------------------------pod_allocator 592 // Allocator for arbitrary POD data. Most usable in different cache 593 // systems for efficient memory allocations. 594 // Memory is allocated with blocks of fixed size ("block_size" in 595 // the constructor). If required size exceeds the block size the allocator 596 // creates a new block of the required size. However, the most efficient 597 // use is when the average reqired size is much less than the block size. 598 //------------------------------------------------------------------------ 599 class pod_allocator 600 { 601 public: 602 void remove_all() 603 { 604 if(m_num_blocks) 605 { 606 int8u** blk = m_blocks + m_num_blocks - 1; 607 while(m_num_blocks--) 608 { 609 delete [] *blk; 610 --blk; 611 } 612 delete [] m_blocks; 613 } 614 m_num_blocks = 0; 615 m_max_blocks = 0; 616 m_blocks = 0; 617 m_buf_ptr = 0; 618 m_rest = 0; 619 } 620 621 ~pod_allocator() 622 { 623 remove_all(); 624 } 625 626 pod_allocator(unsigned block_size, unsigned block_ptr_inc=256-8) : 627 m_block_size(block_size), 628 m_block_ptr_inc(block_ptr_inc), 629 m_num_blocks(0), 630 m_max_blocks(0), 631 m_blocks(0), 632 m_buf_ptr(0), 633 m_rest(0) 634 { 635 } 636 637 638 int8u* allocate(unsigned size, unsigned alignment=1) 639 { 640 if(size == 0) return 0; 641 if(size <= m_rest) 642 { 643 int8u* ptr = m_buf_ptr; 644 if(alignment > 1) 645 { 646 unsigned align = (alignment - unsigned((size_t)ptr) % alignment) % alignment; 647 size += align; 648 ptr += align; 649 if(size <= m_rest) 650 { 651 m_rest -= size; 652 m_buf_ptr += size; 653 return ptr; 654 } 655 allocate_block(size); 656 return allocate(size - align, alignment); 657 } 658 m_rest -= size; 659 m_buf_ptr += size; 660 return ptr; 661 } 662 allocate_block(size + alignment - 1); 663 return allocate(size, alignment); 664 } 665 666 667 private: 668 void allocate_block(unsigned size) 669 { 670 if(size < m_block_size) size = m_block_size; 671 if(m_num_blocks >= m_max_blocks) 672 { 673 int8u** new_blocks = new int8u* [m_max_blocks + m_block_ptr_inc]; 674 675 if(m_blocks) 676 { 677 memcpy(new_blocks, 678 m_blocks, 679 m_num_blocks * sizeof(int8u*)); 680 681 delete [] m_blocks; 682 } 683 m_blocks = new_blocks; 684 m_max_blocks += m_block_ptr_inc; 685 } 686 m_blocks[m_num_blocks] = m_buf_ptr = new int8u [size]; 687 m_num_blocks++; 688 m_rest = size; 689 } 690 691 unsigned m_block_size; 692 unsigned m_block_ptr_inc; 693 unsigned m_num_blocks; 694 unsigned m_max_blocks; 695 int8u** m_blocks; 696 int8u* m_buf_ptr; 697 unsigned m_rest; 698 }; 699 700 701 702 703 704 705 706 707 //------------------------------------------------------------------------ 708 enum 709 { 710 quick_sort_threshold = 9 711 }; 712 713 714 //-----------------------------------------------------------swap_elements 715 template<class T> inline void swap_elements(T& a, T& b) 716 { 717 T temp = a; 718 a = b; 719 b = temp; 720 } 721 722 723 //--------------------------------------------------------------quick_sort 724 template<class Array, class Less> 725 void quick_sort(Array& arr, Less less) 726 { 727 if(arr.size() < 2) return; 728 729 typename Array::value_type* e1; 730 typename Array::value_type* e2; 731 732 int stack[80]; 733 int* top = stack; 734 int limit = arr.size(); 735 int base = 0; 736 737 for(;;) 738 { 739 int len = limit - base; 740 741 int i; 742 int j; 743 int pivot; 744 745 if(len > quick_sort_threshold) 746 { 747 // we use base + len/2 as the pivot 748 pivot = base + len / 2; 749 swap_elements(arr[base], arr[pivot]); 750 751 i = base + 1; 752 j = limit - 1; 753 754 // now ensure that *i <= *base <= *j 755 e1 = &(arr[j]); 756 e2 = &(arr[i]); 757 if(less(*e1, *e2)) swap_elements(*e1, *e2); 758 759 e1 = &(arr[base]); 760 e2 = &(arr[i]); 761 if(less(*e1, *e2)) swap_elements(*e1, *e2); 762 763 e1 = &(arr[j]); 764 e2 = &(arr[base]); 765 if(less(*e1, *e2)) swap_elements(*e1, *e2); 766 767 for(;;) 768 { 769 do i++; while( less(arr[i], arr[base]) ); 770 do j--; while( less(arr[base], arr[j]) ); 771 772 if( i > j ) 773 { 774 break; 775 } 776 777 swap_elements(arr[i], arr[j]); 778 } 779 780 swap_elements(arr[base], arr[j]); 781 782 // now, push the largest sub-array 783 if(j - base > limit - i) 784 { 785 top[0] = base; 786 top[1] = j; 787 base = i; 788 } 789 else 790 { 791 top[0] = i; 792 top[1] = limit; 793 limit = j; 794 } 795 top += 2; 796 } 797 else 798 { 799 // the sub-array is small, perform insertion sort 800 j = base; 801 i = j + 1; 802 803 for(; i < limit; j = i, i++) 804 { 805 for(; less(*(e1 = &(arr[j + 1])), *(e2 = &(arr[j]))); j--) 806 { 807 swap_elements(*e1, *e2); 808 if(j == base) 809 { 810 break; 811 } 812 } 813 } 814 if(top > stack) 815 { 816 top -= 2; 817 base = top[0]; 818 limit = top[1]; 819 } 820 else 821 { 822 break; 823 } 824 } 825 } 826 } 827 828 829 830 831 //------------------------------------------------------remove_duplicates 832 // Remove duplicates from a sorted array. It doesn't cut the the 833 // tail of the array, it just returns the number of remaining elements. 834 //----------------------------------------------------------------------- 835 template<class Array, class Equal> 836 unsigned remove_duplicates(Array& arr, Equal equal) 837 { 838 if(arr.size() < 2) return arr.size(); 839 840 unsigned i, j; 841 for(i = 1, j = 1; i < arr.size(); i++) 842 { 843 typename Array::value_type& e = arr[i]; 844 if(!equal(e, arr[i - 1])) 845 { 846 arr[j++] = e; 847 } 848 } 849 return j; 850 } 851 852 853 854 855 } 856 857 #endif 858