* long overdue update to AGG 2.4
* removed the useless parts of AGG (which are only needed for the interactive examples) * make sure to jam -a libagg.a to solve any linking issues git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17838 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+378
-116
@@ -1,6 +1,6 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.2
|
||||
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
@@ -22,38 +22,191 @@
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//-------------------------------------------------------pod_array_adaptor
|
||||
template<class T> class pod_array_adaptor
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
pod_array_adaptor(T* array, unsigned size) :
|
||||
m_array(array), m_size(size) {}
|
||||
|
||||
unsigned size() const { return m_size; }
|
||||
const T& operator [] (unsigned i) const { return m_array[i]; }
|
||||
T& operator [] (unsigned i) { return m_array[i]; }
|
||||
const T& at(unsigned i) const { return m_array[i]; }
|
||||
T& at(unsigned i) { return m_array[i]; }
|
||||
T value_at(unsigned i) const { return m_array[i]; }
|
||||
|
||||
private:
|
||||
T* m_array;
|
||||
unsigned m_size;
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------------pod_auto_array
|
||||
template<class T, unsigned Size> class pod_auto_array
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef pod_auto_array<T, Size> self_type;
|
||||
|
||||
pod_auto_array() {}
|
||||
explicit pod_auto_array(const T* c)
|
||||
{
|
||||
memcpy(m_array, c, sizeof(T) * Size);
|
||||
}
|
||||
|
||||
const self_type& operator = (const T* c)
|
||||
{
|
||||
memcpy(m_array, c, sizeof(T) * Size);
|
||||
return *this;
|
||||
}
|
||||
|
||||
static unsigned size() { return Size; }
|
||||
const T& operator [] (unsigned i) const { return m_array[i]; }
|
||||
T& operator [] (unsigned i) { return m_array[i]; }
|
||||
const T& at(unsigned i) const { return m_array[i]; }
|
||||
T& at(unsigned i) { return m_array[i]; }
|
||||
T value_at(unsigned i) const { return m_array[i]; }
|
||||
|
||||
private:
|
||||
T m_array[Size];
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------pod_auto_vector
|
||||
template<class T, unsigned Size> class pod_auto_vector
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef pod_auto_vector<T, Size> self_type;
|
||||
|
||||
pod_auto_vector() : m_size(0) {}
|
||||
|
||||
void remove_all() { m_size = 0; }
|
||||
void clear() { m_size = 0; }
|
||||
void add(const T& v) { m_array[m_size++] = v; }
|
||||
void push_back(const T& v) { m_array[m_size++] = v; }
|
||||
void inc_size(unsigned size) { m_size += size; }
|
||||
|
||||
unsigned size() const { return m_size; }
|
||||
const T& operator [] (unsigned i) const { return m_array[i]; }
|
||||
T& operator [] (unsigned i) { return m_array[i]; }
|
||||
const T& at(unsigned i) const { return m_array[i]; }
|
||||
T& at(unsigned i) { return m_array[i]; }
|
||||
T value_at(unsigned i) const { return m_array[i]; }
|
||||
|
||||
private:
|
||||
T m_array[Size];
|
||||
unsigned m_size;
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------------------pod_array
|
||||
// A simple class template to store Plain Old Data, a vector
|
||||
// of a fixed size. The data is continous in memory
|
||||
//------------------------------------------------------------------------
|
||||
template<class T> class pod_array
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef pod_array<T> self_type;
|
||||
|
||||
~pod_array() { delete [] m_array; }
|
||||
pod_array() : m_size(0), m_capacity(0), m_array(0) {}
|
||||
pod_array(unsigned cap, unsigned extra_tail=0);
|
||||
~pod_array() { pod_allocator<T>::deallocate(m_array, m_size); }
|
||||
pod_array() : m_array(0), m_size(0) {}
|
||||
|
||||
pod_array(unsigned size) :
|
||||
m_array(pod_allocator<T>::allocate(size)),
|
||||
m_size(size)
|
||||
{}
|
||||
|
||||
pod_array(const self_type& v) :
|
||||
m_array(pod_allocator<T>::allocate(v.m_size)),
|
||||
m_size(v.m_size)
|
||||
{
|
||||
memcpy(m_array, v.m_array, sizeof(T) * m_size);
|
||||
}
|
||||
|
||||
void resize(unsigned size)
|
||||
{
|
||||
if(size != m_size)
|
||||
{
|
||||
pod_allocator<T>::deallocate(m_array, m_size);
|
||||
m_array = pod_allocator<T>::allocate(m_size = size);
|
||||
}
|
||||
}
|
||||
const self_type& operator = (const self_type& v)
|
||||
{
|
||||
resize(v.size());
|
||||
memcpy(m_array, v.m_array, sizeof(T) * m_size);
|
||||
return *this;
|
||||
}
|
||||
|
||||
unsigned size() const { return m_size; }
|
||||
const T& operator [] (unsigned i) const { return m_array[i]; }
|
||||
T& operator [] (unsigned i) { return m_array[i]; }
|
||||
const T& at(unsigned i) const { return m_array[i]; }
|
||||
T& at(unsigned i) { return m_array[i]; }
|
||||
T value_at(unsigned i) const { return m_array[i]; }
|
||||
|
||||
const T* data() const { return m_array; }
|
||||
T* data() { return m_array; }
|
||||
private:
|
||||
T* m_array;
|
||||
unsigned m_size;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------pod_vector
|
||||
// A simple class template to store Plain Old Data, a vector
|
||||
// of a fixed size. The data is continous in memory
|
||||
//------------------------------------------------------------------------
|
||||
template<class T> class pod_vector
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
|
||||
~pod_vector() { pod_allocator<T>::deallocate(m_array, m_capacity); }
|
||||
pod_vector() : m_size(0), m_capacity(0), m_array(0) {}
|
||||
pod_vector(unsigned cap, unsigned extra_tail=0);
|
||||
|
||||
// Copying
|
||||
pod_array(const pod_array<T>&);
|
||||
const pod_array<T>& operator = (const pod_array<T>&);
|
||||
pod_vector(const pod_vector<T>&);
|
||||
const pod_vector<T>& operator = (const pod_vector<T>&);
|
||||
|
||||
unsigned capacity() const { return m_capacity; }
|
||||
// Set new capacity. All data is lost, size is set to zero.
|
||||
void capacity(unsigned cap, unsigned extra_tail=0);
|
||||
unsigned capacity() const { return m_capacity; }
|
||||
|
||||
// Allocate n elements. All data is lost,
|
||||
// but elements can be accessed in range 0...size-1.
|
||||
void allocate(unsigned size, unsigned extra_tail=0);
|
||||
|
||||
// Resize keeping the content.
|
||||
void resize(unsigned new_size);
|
||||
|
||||
void add(const T& v) { m_array[m_size++] = v; }
|
||||
void inc_size(unsigned size) { m_size += size; }
|
||||
unsigned size() const { return m_size; }
|
||||
unsigned byte_size() const { return m_size * sizeof(T); }
|
||||
void zero()
|
||||
{
|
||||
memset(m_array, 0, sizeof(T) * m_size);
|
||||
}
|
||||
|
||||
void add(const T& v) { m_array[m_size++] = v; }
|
||||
void push_back(const T& v) { m_array[m_size++] = v; }
|
||||
void insert_at(unsigned pos, const T& val);
|
||||
void inc_size(unsigned size) { m_size += size; }
|
||||
unsigned size() const { return m_size; }
|
||||
unsigned byte_size() const { return m_size * sizeof(T); }
|
||||
void serialize(int8u* ptr) const;
|
||||
void deserialize(const int8u* data, unsigned byte_size);
|
||||
const T& operator [] (unsigned idx) const { return m_array[idx]; }
|
||||
T& operator [] (unsigned idx) { return m_array[idx]; }
|
||||
const T& operator [] (unsigned i) const { return m_array[i]; }
|
||||
T& operator [] (unsigned i) { return m_array[i]; }
|
||||
const T& at(unsigned i) const { return m_array[i]; }
|
||||
T& at(unsigned i) { return m_array[i]; }
|
||||
T value_at(unsigned i) const { return m_array[i]; }
|
||||
|
||||
const T* data() const { return m_array; }
|
||||
T* data() { return m_array; }
|
||||
|
||||
void remove_all() { m_size = 0; }
|
||||
void clear() { m_size = 0; }
|
||||
void cut_at(unsigned num) { if(num < m_size) m_size = num; }
|
||||
|
||||
private:
|
||||
@@ -64,28 +217,37 @@ namespace agg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T>
|
||||
void pod_array<T>::capacity(unsigned cap, unsigned extra_tail)
|
||||
void pod_vector<T>::capacity(unsigned cap, unsigned extra_tail)
|
||||
{
|
||||
m_size = 0;
|
||||
if(cap > m_capacity)
|
||||
{
|
||||
delete [] m_array;
|
||||
pod_allocator<T>::deallocate(m_array, m_capacity);
|
||||
m_capacity = cap + extra_tail;
|
||||
m_array = m_capacity ? new T [m_capacity] : 0;
|
||||
m_array = m_capacity ? pod_allocator<T>::allocate(m_capacity) : 0;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T>
|
||||
void pod_array<T>::resize(unsigned new_size)
|
||||
void pod_vector<T>::allocate(unsigned size, unsigned extra_tail)
|
||||
{
|
||||
capacity(size, extra_tail);
|
||||
m_size = size;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T>
|
||||
void pod_vector<T>::resize(unsigned new_size)
|
||||
{
|
||||
if(new_size > m_size)
|
||||
{
|
||||
if(new_size > m_capacity)
|
||||
{
|
||||
T* data = new T[new_size];
|
||||
T* data = pod_allocator<T>::allocate(new_size);
|
||||
memcpy(data, m_array, m_size * sizeof(T));
|
||||
delete [] m_array;
|
||||
pod_allocator<T>::deallocate(m_array, m_capacity);
|
||||
m_array = data;
|
||||
}
|
||||
}
|
||||
@@ -96,81 +258,75 @@ namespace agg
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T> pod_array<T>::pod_array(unsigned cap, unsigned extra_tail) :
|
||||
m_size(0), m_capacity(0), m_array(0)
|
||||
{
|
||||
capacity(cap, extra_tail);
|
||||
}
|
||||
template<class T> pod_vector<T>::pod_vector(unsigned cap, unsigned extra_tail) :
|
||||
m_size(0),
|
||||
m_capacity(cap + extra_tail),
|
||||
m_array(pod_allocator<T>::allocate(m_capacity)) {}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T> pod_array<T>::pod_array(const pod_array<T>& v) :
|
||||
template<class T> pod_vector<T>::pod_vector(const pod_vector<T>& v) :
|
||||
m_size(v.m_size),
|
||||
m_capacity(v.m_capacity),
|
||||
m_array(v.m_capacity ? new T [v.m_capacity] : 0)
|
||||
m_array(v.m_capacity ? pod_allocator<T>::allocate(v.m_capacity) : 0)
|
||||
{
|
||||
memcpy(m_array, v.m_array, sizeof(T) * v.m_size);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T> const pod_array<T>&
|
||||
pod_array<T>::operator = (const pod_array<T>&v)
|
||||
template<class T> const pod_vector<T>&
|
||||
pod_vector<T>::operator = (const pod_vector<T>&v)
|
||||
{
|
||||
capacity(v.m_capacity);
|
||||
allocate(v.m_size);
|
||||
if(v.m_size) memcpy(m_array, v.m_array, sizeof(T) * v.m_size);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T> void pod_array<T>::serialize(int8u* ptr) const
|
||||
template<class T> void pod_vector<T>::serialize(int8u* ptr) const
|
||||
{
|
||||
if(m_size) memcpy(ptr, m_array, m_size * sizeof(T));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T>
|
||||
void pod_array<T>::deserialize(const int8u* data, unsigned byte_size)
|
||||
void pod_vector<T>::deserialize(const int8u* data, unsigned byte_size)
|
||||
{
|
||||
byte_size /= sizeof(T);
|
||||
capacity(byte_size);
|
||||
allocate(byte_size);
|
||||
if(byte_size) memcpy(m_array, data, byte_size * sizeof(T));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T> class pod_array_adaptor
|
||||
template<class T>
|
||||
void pod_vector<T>::insert_at(unsigned pos, const T& val)
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
pod_array_adaptor(T* array, unsigned size) :
|
||||
m_array(array), m_size(size) {}
|
||||
if(pos >= m_size)
|
||||
{
|
||||
m_array[m_size] = val;
|
||||
}
|
||||
else
|
||||
{
|
||||
memmove(m_array + pos + 1, m_array + pos, (m_size - pos) * sizeof(T));
|
||||
m_array[pos] = val;
|
||||
}
|
||||
++m_size;
|
||||
}
|
||||
|
||||
unsigned size() const { return m_size; }
|
||||
const T& operator [] (unsigned idx) const { return m_array[idx]; }
|
||||
T& operator [] (unsigned idx) { return m_array[idx]; }
|
||||
private:
|
||||
T* m_array;
|
||||
unsigned m_size;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------pod_deque
|
||||
//---------------------------------------------------------------pod_bvector
|
||||
// A simple class template to store Plain Old Data, similar to std::deque
|
||||
// It doesn't reallocate memory but instead, uses blocks of data of size
|
||||
// of (1 << S), that is, power of two. The data is NOT continuous in memory,
|
||||
// of (1 << S), that is, power of two. The data is NOT contiguous in memory,
|
||||
// so the only valid access method is operator [] or curr(), prev(), next()
|
||||
//
|
||||
// There reallocs occure only when the pool of pointers to blocks needs
|
||||
// to be extended (it happens very rear). You can control the value
|
||||
// to be extended (it happens very rarely). You can control the value
|
||||
// of increment to reallocate the pointer buffer. See the second constructor.
|
||||
// By default, the incremeent value equals (1 << S), i.e., the block size.
|
||||
//------------------------------------------------------------------------
|
||||
template<class T, unsigned S=6> class pod_deque
|
||||
template<class T, unsigned S=6> class pod_bvector
|
||||
{
|
||||
public:
|
||||
enum
|
||||
enum block_scale_e
|
||||
{
|
||||
block_shift = S,
|
||||
block_size = 1 << block_shift,
|
||||
@@ -179,18 +335,20 @@ namespace agg
|
||||
|
||||
typedef T value_type;
|
||||
|
||||
~pod_deque();
|
||||
pod_deque();
|
||||
pod_deque(unsigned block_ptr_inc);
|
||||
~pod_bvector();
|
||||
pod_bvector();
|
||||
pod_bvector(unsigned block_ptr_inc);
|
||||
|
||||
// Copying
|
||||
pod_deque(const pod_deque<T, S>& v);
|
||||
const pod_deque<T, S>& operator = (const pod_deque<T, S>& v);
|
||||
pod_bvector(const pod_bvector<T, S>& v);
|
||||
const pod_bvector<T, S>& operator = (const pod_bvector<T, S>& v);
|
||||
|
||||
void remove_all() { m_size = 0; }
|
||||
void free_all() { free_tail(0); }
|
||||
void clear() { m_size = 0; }
|
||||
void free_all() { free_tail(0); }
|
||||
void free_tail(unsigned size);
|
||||
void add(const T& val);
|
||||
void push_back(const T& val) { add(val); }
|
||||
void modify_last(const T& val);
|
||||
void remove_last();
|
||||
|
||||
@@ -220,14 +378,29 @@ namespace agg
|
||||
|
||||
unsigned size() const { return m_size; }
|
||||
|
||||
const T& operator [] (unsigned idx) const
|
||||
const T& operator [] (unsigned i) const
|
||||
{
|
||||
return m_blocks[idx >> block_shift][idx & block_mask];
|
||||
return m_blocks[i >> block_shift][i & block_mask];
|
||||
}
|
||||
|
||||
T& operator [] (unsigned idx)
|
||||
T& operator [] (unsigned i)
|
||||
{
|
||||
return m_blocks[idx >> block_shift][idx & block_mask];
|
||||
return m_blocks[i >> block_shift][i & block_mask];
|
||||
}
|
||||
|
||||
const T& at(unsigned i) const
|
||||
{
|
||||
return m_blocks[i >> block_shift][i & block_mask];
|
||||
}
|
||||
|
||||
T& at(unsigned i)
|
||||
{
|
||||
return m_blocks[i >> block_shift][i & block_mask];
|
||||
}
|
||||
|
||||
T value_at(unsigned i) const
|
||||
{
|
||||
return m_blocks[i >> block_shift][i & block_mask];
|
||||
}
|
||||
|
||||
const T& curr(unsigned idx) const
|
||||
@@ -338,31 +511,37 @@ namespace agg
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T, unsigned S> pod_deque<T, S>::~pod_deque()
|
||||
template<class T, unsigned S> pod_bvector<T, S>::~pod_bvector()
|
||||
{
|
||||
if(m_num_blocks)
|
||||
{
|
||||
T** blk = m_blocks + m_num_blocks - 1;
|
||||
while(m_num_blocks--)
|
||||
{
|
||||
delete [] *blk;
|
||||
pod_allocator<T>::deallocate(*blk, block_size);
|
||||
--blk;
|
||||
}
|
||||
delete [] m_blocks;
|
||||
}
|
||||
pod_allocator<T*>::deallocate(m_blocks, m_max_blocks);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T, unsigned S>
|
||||
void pod_deque<T, S>::free_tail(unsigned size)
|
||||
void pod_bvector<T, S>::free_tail(unsigned size)
|
||||
{
|
||||
if(size < m_size)
|
||||
{
|
||||
unsigned nb = (size + block_mask) >> block_shift;
|
||||
while(m_num_blocks > nb)
|
||||
{
|
||||
delete [] m_blocks[--m_num_blocks];
|
||||
pod_allocator<T>::deallocate(m_blocks[--m_num_blocks], block_size);
|
||||
}
|
||||
if(m_num_blocks == 0)
|
||||
{
|
||||
pod_allocator<T*>::deallocate(m_blocks, m_max_blocks);
|
||||
m_blocks = 0;
|
||||
m_max_blocks = 0;
|
||||
}
|
||||
m_size = size;
|
||||
}
|
||||
@@ -370,7 +549,7 @@ namespace agg
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T, unsigned S> pod_deque<T, S>::pod_deque() :
|
||||
template<class T, unsigned S> pod_bvector<T, S>::pod_bvector() :
|
||||
m_size(0),
|
||||
m_num_blocks(0),
|
||||
m_max_blocks(0),
|
||||
@@ -382,7 +561,7 @@ namespace agg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T, unsigned S>
|
||||
pod_deque<T, S>::pod_deque(unsigned block_ptr_inc) :
|
||||
pod_bvector<T, S>::pod_bvector(unsigned block_ptr_inc) :
|
||||
m_size(0),
|
||||
m_num_blocks(0),
|
||||
m_max_blocks(0),
|
||||
@@ -394,17 +573,19 @@ namespace agg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T, unsigned S>
|
||||
pod_deque<T, S>::pod_deque(const pod_deque<T, S>& v) :
|
||||
pod_bvector<T, S>::pod_bvector(const pod_bvector<T, S>& v) :
|
||||
m_size(v.m_size),
|
||||
m_num_blocks(v.m_num_blocks),
|
||||
m_max_blocks(v.m_max_blocks),
|
||||
m_blocks(v.m_max_blocks ? new T* [v.m_max_blocks] : 0),
|
||||
m_blocks(v.m_max_blocks ?
|
||||
pod_allocator<T*>::allocate(v.m_max_blocks) :
|
||||
0),
|
||||
m_block_ptr_inc(v.m_block_ptr_inc)
|
||||
{
|
||||
unsigned i;
|
||||
for(i = 0; i < v.m_num_blocks; ++i)
|
||||
{
|
||||
m_blocks[i] = new T [block_size];
|
||||
m_blocks[i] = pod_allocator<T>::allocate(block_size);
|
||||
memcpy(m_blocks[i], v.m_blocks[i], block_size * sizeof(T));
|
||||
}
|
||||
}
|
||||
@@ -412,7 +593,8 @@ namespace agg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T, unsigned S>
|
||||
const pod_deque<T, S>& pod_deque<T, S>::operator = (const pod_deque<T, S>& v)
|
||||
const pod_bvector<T, S>&
|
||||
pod_bvector<T, S>::operator = (const pod_bvector<T, S>& v)
|
||||
{
|
||||
unsigned i;
|
||||
for(i = m_num_blocks; i < v.m_num_blocks; ++i)
|
||||
@@ -430,11 +612,11 @@ namespace agg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T, unsigned S>
|
||||
void pod_deque<T, S>::allocate_block(unsigned nb)
|
||||
void pod_bvector<T, S>::allocate_block(unsigned nb)
|
||||
{
|
||||
if(nb >= m_max_blocks)
|
||||
{
|
||||
T** new_blocks = new T* [m_max_blocks + m_block_ptr_inc];
|
||||
T** new_blocks = pod_allocator<T*>::allocate(m_max_blocks + m_block_ptr_inc);
|
||||
|
||||
if(m_blocks)
|
||||
{
|
||||
@@ -442,12 +624,12 @@ namespace agg
|
||||
m_blocks,
|
||||
m_num_blocks * sizeof(T*));
|
||||
|
||||
delete [] m_blocks;
|
||||
pod_allocator<T*>::deallocate(m_blocks, m_max_blocks);
|
||||
}
|
||||
m_blocks = new_blocks;
|
||||
m_max_blocks += m_block_ptr_inc;
|
||||
}
|
||||
m_blocks[nb] = new T [block_size];
|
||||
m_blocks[nb] = pod_allocator<T>::allocate(block_size);
|
||||
m_num_blocks++;
|
||||
}
|
||||
|
||||
@@ -455,7 +637,7 @@ namespace agg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T, unsigned S>
|
||||
inline T* pod_deque<T, S>::data_ptr()
|
||||
inline T* pod_bvector<T, S>::data_ptr()
|
||||
{
|
||||
unsigned nb = m_size >> block_shift;
|
||||
if(nb >= m_num_blocks)
|
||||
@@ -469,7 +651,7 @@ namespace agg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T, unsigned S>
|
||||
inline void pod_deque<T, S>::add(const T& val)
|
||||
inline void pod_bvector<T, S>::add(const T& val)
|
||||
{
|
||||
*data_ptr() = val;
|
||||
++m_size;
|
||||
@@ -478,7 +660,7 @@ namespace agg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T, unsigned S>
|
||||
inline void pod_deque<T, S>::remove_last()
|
||||
inline void pod_bvector<T, S>::remove_last()
|
||||
{
|
||||
if(m_size) --m_size;
|
||||
}
|
||||
@@ -486,7 +668,7 @@ namespace agg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T, unsigned S>
|
||||
void pod_deque<T, S>::modify_last(const T& val)
|
||||
void pod_bvector<T, S>::modify_last(const T& val)
|
||||
{
|
||||
remove_last();
|
||||
add(val);
|
||||
@@ -495,7 +677,7 @@ namespace agg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T, unsigned S>
|
||||
int pod_deque<T, S>::allocate_continuous_block(unsigned num_elements)
|
||||
int pod_bvector<T, S>::allocate_continuous_block(unsigned num_elements)
|
||||
{
|
||||
if(num_elements < block_size)
|
||||
{
|
||||
@@ -525,7 +707,7 @@ namespace agg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T, unsigned S>
|
||||
unsigned pod_deque<T, S>::byte_size() const
|
||||
unsigned pod_bvector<T, S>::byte_size() const
|
||||
{
|
||||
return m_size * sizeof(T);
|
||||
}
|
||||
@@ -533,7 +715,7 @@ namespace agg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T, unsigned S>
|
||||
void pod_deque<T, S>::serialize(int8u* ptr) const
|
||||
void pod_bvector<T, S>::serialize(int8u* ptr) const
|
||||
{
|
||||
unsigned i;
|
||||
for(i = 0; i < m_size; i++)
|
||||
@@ -545,7 +727,7 @@ namespace agg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class T, unsigned S>
|
||||
void pod_deque<T, S>::deserialize(const int8u* data, unsigned byte_size)
|
||||
void pod_bvector<T, S>::deserialize(const int8u* data, unsigned byte_size)
|
||||
{
|
||||
remove_all();
|
||||
byte_size /= sizeof(T);
|
||||
@@ -562,8 +744,8 @@ namespace agg
|
||||
// Replace or add a number of elements starting from "start" position
|
||||
//------------------------------------------------------------------------
|
||||
template<class T, unsigned S>
|
||||
void pod_deque<T, S>::deserialize(unsigned start, const T& empty_val,
|
||||
const int8u* data, unsigned byte_size)
|
||||
void pod_bvector<T, S>::deserialize(unsigned start, const T& empty_val,
|
||||
const int8u* data, unsigned byte_size)
|
||||
{
|
||||
while(m_size < start)
|
||||
{
|
||||
@@ -588,7 +770,7 @@ namespace agg
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------pod_allocator
|
||||
//---------------------------------------------------------block_allocator
|
||||
// Allocator for arbitrary POD data. Most usable in different cache
|
||||
// systems for efficient memory allocations.
|
||||
// Memory is allocated with blocks of fixed size ("block_size" in
|
||||
@@ -596,20 +778,26 @@ namespace agg
|
||||
// creates a new block of the required size. However, the most efficient
|
||||
// use is when the average reqired size is much less than the block size.
|
||||
//------------------------------------------------------------------------
|
||||
class pod_allocator
|
||||
class block_allocator
|
||||
{
|
||||
struct block_type
|
||||
{
|
||||
int8u* data;
|
||||
unsigned size;
|
||||
};
|
||||
|
||||
public:
|
||||
void remove_all()
|
||||
{
|
||||
if(m_num_blocks)
|
||||
{
|
||||
int8u** blk = m_blocks + m_num_blocks - 1;
|
||||
block_type* blk = m_blocks + m_num_blocks - 1;
|
||||
while(m_num_blocks--)
|
||||
{
|
||||
delete [] *blk;
|
||||
pod_allocator<int8u>::deallocate(blk->data, blk->size);
|
||||
--blk;
|
||||
}
|
||||
delete [] m_blocks;
|
||||
pod_allocator<block_type>::deallocate(m_blocks, m_max_blocks);
|
||||
}
|
||||
m_num_blocks = 0;
|
||||
m_max_blocks = 0;
|
||||
@@ -618,12 +806,12 @@ namespace agg
|
||||
m_rest = 0;
|
||||
}
|
||||
|
||||
~pod_allocator()
|
||||
~block_allocator()
|
||||
{
|
||||
remove_all();
|
||||
}
|
||||
|
||||
pod_allocator(unsigned block_size, unsigned block_ptr_inc=256-8) :
|
||||
block_allocator(unsigned block_size, unsigned block_ptr_inc=256-8) :
|
||||
m_block_size(block_size),
|
||||
m_block_ptr_inc(block_ptr_inc),
|
||||
m_num_blocks(0),
|
||||
@@ -643,7 +831,9 @@ namespace agg
|
||||
int8u* ptr = m_buf_ptr;
|
||||
if(alignment > 1)
|
||||
{
|
||||
unsigned align = (alignment - unsigned((size_t)ptr) % alignment) % alignment;
|
||||
unsigned align =
|
||||
(alignment - unsigned((size_t)ptr) % alignment) % alignment;
|
||||
|
||||
size += align;
|
||||
ptr += align;
|
||||
if(size <= m_rest)
|
||||
@@ -670,31 +860,36 @@ namespace agg
|
||||
if(size < m_block_size) size = m_block_size;
|
||||
if(m_num_blocks >= m_max_blocks)
|
||||
{
|
||||
int8u** new_blocks = new int8u* [m_max_blocks + m_block_ptr_inc];
|
||||
block_type* new_blocks =
|
||||
pod_allocator<block_type>::allocate(m_max_blocks + m_block_ptr_inc);
|
||||
|
||||
if(m_blocks)
|
||||
{
|
||||
memcpy(new_blocks,
|
||||
m_blocks,
|
||||
m_num_blocks * sizeof(int8u*));
|
||||
|
||||
delete [] m_blocks;
|
||||
m_num_blocks * sizeof(block_type));
|
||||
pod_allocator<block_type>::deallocate(m_blocks, m_max_blocks);
|
||||
}
|
||||
m_blocks = new_blocks;
|
||||
m_max_blocks += m_block_ptr_inc;
|
||||
}
|
||||
m_blocks[m_num_blocks] = m_buf_ptr = new int8u [size];
|
||||
|
||||
m_blocks[m_num_blocks].size = size;
|
||||
m_blocks[m_num_blocks].data =
|
||||
m_buf_ptr =
|
||||
pod_allocator<int8u>::allocate(size);
|
||||
|
||||
m_num_blocks++;
|
||||
m_rest = size;
|
||||
}
|
||||
|
||||
unsigned m_block_size;
|
||||
unsigned m_block_ptr_inc;
|
||||
unsigned m_num_blocks;
|
||||
unsigned m_max_blocks;
|
||||
int8u** m_blocks;
|
||||
int8u* m_buf_ptr;
|
||||
unsigned m_rest;
|
||||
unsigned m_block_size;
|
||||
unsigned m_block_ptr_inc;
|
||||
unsigned m_num_blocks;
|
||||
unsigned m_max_blocks;
|
||||
block_type* m_blocks;
|
||||
int8u* m_buf_ptr;
|
||||
unsigned m_rest;
|
||||
};
|
||||
|
||||
|
||||
@@ -705,7 +900,7 @@ namespace agg
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
enum
|
||||
enum quick_sort_threshold_e
|
||||
{
|
||||
quick_sort_threshold = 9
|
||||
};
|
||||
@@ -829,7 +1024,7 @@ namespace agg
|
||||
|
||||
|
||||
//------------------------------------------------------remove_duplicates
|
||||
// Remove duplicates from a sorted array. It doesn't cut the the
|
||||
// Remove duplicates from a sorted array. It doesn't cut the
|
||||
// tail of the array, it just returns the number of remaining elements.
|
||||
//-----------------------------------------------------------------------
|
||||
template<class Array, class Equal>
|
||||
@@ -849,9 +1044,76 @@ namespace agg
|
||||
return j;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------invert_container
|
||||
template<class Array> void invert_container(Array& arr)
|
||||
{
|
||||
int i = 0;
|
||||
int j = arr.size() - 1;
|
||||
while(i < j)
|
||||
{
|
||||
swap_elements(arr[i++], arr[j--]);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------binary_search_pos
|
||||
template<class Array, class Value, class Less>
|
||||
unsigned binary_search_pos(const Array& arr, const Value& val, Less less)
|
||||
{
|
||||
if(arr.size() == 0) return 0;
|
||||
|
||||
unsigned beg = 0;
|
||||
unsigned end = arr.size() - 1;
|
||||
|
||||
if(less(val, arr[0])) return 0;
|
||||
if(less(arr[end], val)) return end + 1;
|
||||
|
||||
while(end - beg > 1)
|
||||
{
|
||||
unsigned mid = (end + beg) >> 1;
|
||||
if(less(val, arr[mid])) end = mid;
|
||||
else beg = mid;
|
||||
}
|
||||
|
||||
//if(beg <= 0 && less(val, arr[0])) return 0;
|
||||
//if(end >= arr.size() - 1 && less(arr[end], val)) ++end;
|
||||
|
||||
return end;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------range_adaptor
|
||||
template<class Array> class range_adaptor
|
||||
{
|
||||
public:
|
||||
typedef typename Array::value_type value_type;
|
||||
|
||||
range_adaptor(Array& array, unsigned start, unsigned size) :
|
||||
m_array(array), m_start(start), m_size(size)
|
||||
{}
|
||||
|
||||
unsigned size() const { return m_size; }
|
||||
const value_type& operator [] (unsigned i) const { return m_array[m_start + i]; }
|
||||
value_type& operator [] (unsigned i) { return m_array[m_start + i]; }
|
||||
const value_type& at(unsigned i) const { return m_array[m_start + i]; }
|
||||
value_type& at(unsigned i) { return m_array[m_start + i]; }
|
||||
value_type value_at(unsigned i) const { return m_array[m_start + i]; }
|
||||
|
||||
private:
|
||||
Array& m_array;
|
||||
unsigned m_start;
|
||||
unsigned m_size;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------int_less
|
||||
inline bool int_less(int a, int b) { return a < b; }
|
||||
|
||||
//------------------------------------------------------------int_greater
|
||||
inline bool int_greater(int a, int b) { return a > b; }
|
||||
|
||||
//----------------------------------------------------------unsigned_less
|
||||
inline bool unsigned_less(unsigned a, unsigned b) { return a < b; }
|
||||
|
||||
//-------------------------------------------------------unsigned_greater
|
||||
inline bool unsigned_greater(unsigned a, unsigned b) { return a > b; }
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user