15 #ifndef AGG_ARRAY_INCLUDED 16 #define AGG_ARRAY_INCLUDED 20 #include "agg_basics.h" 31 m_array(array), m_size(size) {}
33 unsigned size()
const {
return m_size; }
34 const T& operator [] (
unsigned i)
const {
return m_array[i]; }
35 T& operator [] (
unsigned i) {
return m_array[i]; }
36 const T& at(
unsigned i)
const {
return m_array[i]; }
37 T& at(
unsigned i) {
return m_array[i]; }
38 T value_at(
unsigned i)
const {
return m_array[i]; }
56 std::memcpy(m_array, c,
sizeof(T) * Size);
59 const self_type& operator = (
const T* c)
61 std::memcpy(m_array, c,
sizeof(T) * Size);
65 static unsigned size() {
return Size; }
66 const T& operator [] (
unsigned i)
const {
return m_array[i]; }
67 T& operator [] (
unsigned i) {
return m_array[i]; }
68 const T& at(
unsigned i)
const {
return m_array[i]; }
69 T& at(
unsigned i) {
return m_array[i]; }
70 T value_at(
unsigned i)
const {
return m_array[i]; }
86 void remove_all() { m_size = 0; }
87 void clear() { m_size = 0; }
88 void add(
const T& v) { m_array[m_size++] = v; }
89 void push_back(
const T& v) { m_array[m_size++] = v; }
90 void inc_size(
unsigned size) { m_size += size; }
92 unsigned size()
const {
return m_size; }
93 const T& operator [] (
unsigned i)
const {
return m_array[i]; }
94 T& operator [] (
unsigned i) {
return m_array[i]; }
95 const T& at(
unsigned i)
const {
return m_array[i]; }
96 T& at(
unsigned i) {
return m_array[i]; }
97 T value_at(
unsigned i)
const {
return m_array[i]; }
109 typedef T value_type;
124 std::memcpy(m_array, v.m_array,
sizeof(T) * m_size);
127 void resize(
unsigned size)
135 const self_type& operator = (
const self_type& v)
138 std::memcpy(m_array, v.m_array,
sizeof(T) * m_size);
142 unsigned size()
const {
return m_size; }
143 const T& operator [] (
unsigned i)
const {
return m_array[i]; }
144 T& operator [] (
unsigned i) {
return m_array[i]; }
145 const T& at(
unsigned i)
const {
return m_array[i]; }
146 T& at(
unsigned i) {
return m_array[i]; }
147 T value_at(
unsigned i)
const {
return m_array[i]; }
149 const T* data()
const {
return m_array; }
150 T* data() {
return m_array; }
165 typedef T value_type;
168 pod_vector() : m_size(0), m_capacity(0), m_array(0) {}
169 pod_vector(
unsigned cap,
unsigned extra_tail=0);
176 void capacity(
unsigned cap,
unsigned extra_tail=0);
177 unsigned capacity()
const {
return m_capacity; }
181 void allocate(
unsigned size,
unsigned extra_tail=0);
184 void resize(
unsigned new_size);
188 std::memset(m_array, 0,
sizeof(T) * m_size);
191 void add(
const T& v) { m_array[m_size++] = v; }
192 void push_back(
const T& v) { m_array[m_size++] = v; }
193 void insert_at(
unsigned pos,
const T& val);
194 void inc_size(
unsigned size) { m_size += size; }
195 unsigned size()
const {
return m_size; }
196 unsigned byte_size()
const {
return m_size *
sizeof(T); }
197 void serialize(int8u* ptr)
const;
198 void deserialize(
const int8u* data,
unsigned byte_size);
199 const T& operator [] (
unsigned i)
const {
return m_array[i]; }
200 T& operator [] (
unsigned i) {
return m_array[i]; }
201 const T& at(
unsigned i)
const {
return m_array[i]; }
202 T& at(
unsigned i) {
return m_array[i]; }
203 T value_at(
unsigned i)
const {
return m_array[i]; }
205 const T* data()
const {
return m_array; }
206 T* data() {
return m_array; }
208 void remove_all() { m_size = 0; }
209 void clear() { m_size = 0; }
210 void cut_at(
unsigned num) {
if(num < m_size) m_size = num; }
226 m_capacity = cap + extra_tail;
235 capacity(size, extra_tail);
244 if(new_size > m_size)
246 if(new_size > m_capacity)
249 std::memcpy(data, m_array, m_size *
sizeof(T));
263 m_capacity(cap + extra_tail),
269 m_capacity(v.m_capacity),
272 std::memcpy(m_array, v.m_array,
sizeof(T) * v.m_size);
280 if(v.m_size) std::memcpy(m_array, v.m_array,
sizeof(T) * v.m_size);
287 if(m_size) std::memcpy(ptr, m_array, m_size *
sizeof(T));
294 byte_size /=
sizeof(T);
296 if(byte_size) std::memcpy(m_array, data, byte_size *
sizeof(T));
305 m_array[m_size] = val;
309 std::memmove(m_array + pos + 1, m_array + pos, (m_size - pos) *
sizeof(T));
332 block_size = 1 << block_shift,
333 block_mask = block_size - 1
336 typedef T value_type;
346 void remove_all() { m_size = 0; }
347 void clear() { m_size = 0; }
348 void free_all() { free_tail(0); }
349 void free_tail(
unsigned size);
350 void add(
const T& val);
351 void push_back(
const T& val) { add(val); }
352 void modify_last(
const T& val);
355 int allocate_continuous_block(
unsigned num_elements);
357 void add_array(
const T* ptr,
unsigned num_elem)
365 template<
class DataAccessor>
void add_data(DataAccessor& data)
374 void cut_at(
unsigned size)
376 if(size < m_size) m_size = size;
379 unsigned size()
const {
return m_size; }
381 const T& operator [] (
unsigned i)
const 383 return m_blocks[i >> block_shift][i & block_mask];
386 T& operator [] (
unsigned i)
388 return m_blocks[i >> block_shift][i & block_mask];
391 const T& at(
unsigned i)
const 393 return m_blocks[i >> block_shift][i & block_mask];
398 return m_blocks[i >> block_shift][i & block_mask];
401 T value_at(
unsigned i)
const 403 return m_blocks[i >> block_shift][i & block_mask];
406 const T& curr(
unsigned idx)
const 411 T& curr(
unsigned idx)
416 const T& prev(
unsigned idx)
const 418 return (*
this)[(idx + m_size - 1) % m_size];
421 T& prev(
unsigned idx)
423 return (*
this)[(idx + m_size - 1) % m_size];
426 const T& next(
unsigned idx)
const 428 return (*
this)[(idx + 1) % m_size];
431 T& next(
unsigned idx)
433 return (*
this)[(idx + 1) % m_size];
436 const T& last()
const 438 return (*
this)[m_size - 1];
443 return (*
this)[m_size - 1];
446 unsigned byte_size()
const;
447 void serialize(int8u* ptr)
const;
448 void deserialize(
const int8u* data,
unsigned byte_size);
449 void deserialize(
unsigned start,
const T& empty_val,
450 const int8u* data,
unsigned byte_size);
452 template<
class ByteAccessor>
453 void deserialize(ByteAccessor data)
456 unsigned elem_size = data.size() /
sizeof(T);
458 for(
unsigned i = 0; i < elem_size; ++i)
460 int8u* ptr = (int8u*)data_ptr();
461 for(
unsigned j = 0; j <
sizeof(T); ++j)
470 template<
class ByteAccessor>
471 void deserialize(
unsigned start,
const T& empty_val, ByteAccessor data)
473 while(m_size < start)
478 unsigned elem_size = data.size() /
sizeof(T);
479 for(
unsigned i = 0; i < elem_size; ++i)
482 if(start + i < m_size)
484 ptr = (int8u*)(&((*
this)[start + i]));
488 ptr = (int8u*)data_ptr();
491 for(
unsigned j = 0; j <
sizeof(T); ++j)
499 const T* block(
unsigned nb)
const {
return m_blocks[nb]; }
502 void allocate_block(
unsigned nb);
506 unsigned m_num_blocks;
507 unsigned m_max_blocks;
509 unsigned m_block_ptr_inc;
518 T** blk = m_blocks + m_num_blocks - 1;
519 while(m_num_blocks--)
530 template<
class T,
unsigned S>
535 unsigned nb = (size + block_mask) >> block_shift;
536 while(m_num_blocks > nb)
540 if(m_num_blocks == 0)
557 m_block_ptr_inc(block_size)
563 template<
class T,
unsigned S>
564 pod_bvector<T, S>::pod_bvector(
unsigned block_ptr_inc) :
569 m_block_ptr_inc(block_ptr_inc)
575 template<
class T,
unsigned S>
578 m_num_blocks(v.m_num_blocks),
579 m_max_blocks(v.m_max_blocks),
580 m_blocks(v.m_max_blocks ?
583 m_block_ptr_inc(v.m_block_ptr_inc)
586 for(i = 0; i < v.m_num_blocks; ++i)
589 std::memcpy(m_blocks[i], v.m_blocks[i], block_size *
sizeof(T));
595 template<
class T,
unsigned S>
600 for(i = m_num_blocks; i < v.m_num_blocks; ++i)
604 for(i = 0; i < v.m_num_blocks; ++i)
606 std::memcpy(m_blocks[i], v.m_blocks[i], block_size *
sizeof(T));
614 template<
class T,
unsigned S>
617 if(nb >= m_max_blocks)
623 std::memcpy(new_blocks,
625 m_num_blocks *
sizeof(T*));
629 m_blocks = new_blocks;
630 m_max_blocks += m_block_ptr_inc;
639 template<
class T,
unsigned S>
642 unsigned nb = m_size >> block_shift;
643 if(nb >= m_num_blocks)
647 return m_blocks[nb] + (m_size & block_mask);
653 template<
class T,
unsigned S>
662 template<
class T,
unsigned S>
670 template<
class T,
unsigned S>
679 template<
class T,
unsigned S>
682 if(num_elements < block_size)
685 unsigned rest = block_size - (m_size & block_mask);
687 if(num_elements <= rest)
692 m_size += num_elements;
701 m_size += num_elements;
709 template<
class T,
unsigned S>
712 return m_size *
sizeof(T);
717 template<
class T,
unsigned S>
721 for(i = 0; i < m_size; i++)
723 std::memcpy(ptr, &(*
this)[i],
sizeof(T));
729 template<
class T,
unsigned S>
733 byte_size /=
sizeof(T);
734 for(
unsigned i = 0; i < byte_size; ++i)
737 std::memcpy(ptr, data,
sizeof(T));
746 template<
class T,
unsigned S>
748 const int8u* data,
unsigned byte_size)
750 while(m_size < start)
755 byte_size /=
sizeof(T);
756 for(
unsigned i = 0; i < byte_size; ++i)
758 if(start + i < m_size)
760 std::memcpy(&((*
this)[start + i]), data,
sizeof(T));
765 std::memcpy(ptr, data,
sizeof(T));
794 block_type* blk = m_blocks + m_num_blocks - 1;
795 while(m_num_blocks--)
815 m_block_size(block_size),
816 m_block_ptr_inc(block_ptr_inc),
826 int8u* allocate(
unsigned size,
unsigned alignment=1)
828 if(size == 0)
return 0;
831 int8u* ptr = m_buf_ptr;
835 (alignment - unsigned((std::size_t)ptr) % alignment) % alignment;
845 allocate_block(size);
846 return allocate(size - align, alignment);
852 allocate_block(size + alignment - 1);
853 return allocate(size, alignment);
858 void allocate_block(
unsigned size)
860 if(size < m_block_size) size = m_block_size;
861 if(m_num_blocks >= m_max_blocks)
863 block_type* new_blocks =
868 std::memcpy(new_blocks,
870 m_num_blocks *
sizeof(block_type));
873 m_blocks = new_blocks;
874 m_max_blocks += m_block_ptr_inc;
877 m_blocks[m_num_blocks].size = size;
878 m_blocks[m_num_blocks].data =
886 unsigned m_block_size;
887 unsigned m_block_ptr_inc;
888 unsigned m_num_blocks;
889 unsigned m_max_blocks;
890 block_type* m_blocks;
903 enum quick_sort_threshold_e
905 quick_sort_threshold = 9
910 template<
class T>
inline void swap_elements(T& a, T& b)
919 template<
class Array,
class Less>
920 void quick_sort(Array& arr, Less less)
922 if(arr.size() < 2)
return;
924 typename Array::value_type* e1;
925 typename Array::value_type* e2;
929 int limit = arr.size();
934 int len = limit - base;
940 if(len > quick_sort_threshold)
943 pivot = base + len / 2;
944 swap_elements(arr[base], arr[pivot]);
952 if(less(*e1, *e2)) swap_elements(*e1, *e2);
956 if(less(*e1, *e2)) swap_elements(*e1, *e2);
960 if(less(*e1, *e2)) swap_elements(*e1, *e2);
964 do i++;
while( less(arr[i], arr[base]) );
965 do j--;
while( less(arr[base], arr[j]) );
972 swap_elements(arr[i], arr[j]);
975 swap_elements(arr[base], arr[j]);
978 if(j - base > limit - i)
998 for(; i < limit; j = i, i++)
1000 for(; less(*(e1 = &(arr[j + 1])), *(e2 = &(arr[j]))); j--)
1002 swap_elements(*e1, *e2);
1030 template<
class Array,
class Equal>
1031 unsigned remove_duplicates(Array& arr, Equal equal)
1033 if(arr.size() < 2)
return arr.size();
1036 for(i = 1, j = 1; i < arr.size(); i++)
1038 typename Array::value_type& e = arr[i];
1039 if(!equal(e, arr[i - 1]))
1048 template<
class Array>
void invert_container(Array& arr)
1051 int j = arr.size() - 1;
1054 swap_elements(arr[i++], arr[j--]);
1059 template<
class Array,
class Value,
class Less>
1060 unsigned binary_search_pos(
const Array& arr,
const Value& val, Less less)
1062 if(arr.size() == 0)
return 0;
1065 unsigned end = arr.size() - 1;
1067 if(less(val, arr[0]))
return 0;
1068 if(less(arr[end], val))
return end + 1;
1070 while(end - beg > 1)
1072 unsigned mid = (end + beg) >> 1;
1073 if(less(val, arr[mid])) end = mid;
1087 typedef typename Array::value_type value_type;
1089 range_adaptor(Array& array,
unsigned start,
unsigned size) :
1090 m_array(array), m_start(start), m_size(size)
1093 unsigned size()
const {
return m_size; }
1094 const value_type& operator [] (
unsigned i)
const {
return m_array[m_start + i]; }
1095 value_type& operator [] (
unsigned i) {
return m_array[m_start + i]; }
1096 const value_type& at(
unsigned i)
const {
return m_array[m_start + i]; }
1097 value_type& at(
unsigned i) {
return m_array[m_start + i]; }
1098 value_type value_at(
unsigned i)
const {
return m_array[m_start + i]; }
1107 inline bool int_less(
int a,
int b) {
return a < b; }
1110 inline bool int_greater(
int a,
int b) {
return a > b; }
1113 inline bool unsigned_less(
unsigned a,
unsigned b) {
return a < b; }
1116 inline bool unsigned_greater(
unsigned a,
unsigned b) {
return a > b; }