11 #ifndef DOXYGEN_SHOULD_SKIP_THIS // the whole file
13 inline int iclamp(
int i,
int Min,
int Max) {
15 return std::max(Min, std::min(i, Max));
18 inline float fclamp(
float f,
float Min,
float Max) {
20 return std::max(Min, std::min(f, Max));
23 inline int iabs(
int i) {
if (i < 0)
return -i;
else return i; }
25 int WriteUint32(FILE *fp, uint val);
26 int WriteUint16(FILE *fp,
unsigned short val);
27 int WriteFloat32(FILE *fp,
float val);
28 void WriteByte(FILE* dst, uchar b);
29 uint ReadUint32(FILE *fp);
30 unsigned short ReadUint16(FILE *fp);
31 double ReadDouble64(FILE *fp);
33 int quadtree_node_count(
int depth);
58 array() : m_buffer(0), m_size(0), m_buffer_size(0) {}
59 array(
int size_hint) : m_buffer(0), m_size(0), m_buffer_size(0) { resize(size_hint); }
65 T& operator[](
int index) { assert(index >= 0 && index < m_size);
return m_buffer[index]; }
66 const T& operator[](
int index)
const { assert(index >= 0 && index < m_size);
return m_buffer[index]; }
67 int size()
const {
return m_size; }
69 void push_back(
const T& val)
72 int new_size = m_size + 1;
74 (*this)[new_size-1] = val;
78 T& front() {
return (*
this)[0]; }
79 const T& front()
const {
return (*
this)[0]; }
82 T& back() {
return (*
this)[m_size-1]; }
83 const T& back()
const {
return (*
this)[m_size-1]; }
97 for (
int i = 0; i < m_size; i++) {
98 *(m_buffer + i) = a[i];
102 void resize(
int new_size)
107 assert(new_size >= 0);
109 int old_size = m_size;
113 {
for (
int i = new_size; i < old_size; i++) {
114 (m_buffer + i)->~T();
119 }
else if (m_size <= m_buffer_size && m_size > m_buffer_size >> 1) {
123 m_buffer_size = m_size + (m_size >> 2);
126 reserve(m_buffer_size);
129 {
for (
int i = old_size; i < new_size; i++) {
130 new (m_buffer + i) T;
134 void reserve(
int rsize)
137 m_buffer_size = rsize;
140 if (m_buffer_size == 0) {
147 m_buffer = (T*) realloc(m_buffer,
sizeof(T) * m_buffer_size);
149 m_buffer = (T*) malloc(
sizeof(T) * m_buffer_size);
158 m_buffer = a->m_buffer;
160 m_buffer_size = a->m_buffer_size;
164 a->m_buffer_size = 0;
179 static int compute(
const T& data)
181 uchar* p = (uchar*) &data;
182 int size =
sizeof(T);
188 h = ((h << 5) + h) ^ *p;
202 template<
class T,
class U,
class hash_functor = fixed_size_hash<T> >
211 hash() { m_entry_count = 0; m_size_mask = 0; }
212 hash(
int size_hint) { m_entry_count = 0; m_size_mask = 0; resize(size_hint); }
219 void add(T key, U value)
222 assert(
get(key, NULL) ==
false);
227 int hash_value = hash_functor::compute(key);
232 int index = hash_value & m_size_mask;
233 m_table[index].push_back(e);
239 for (
int i = 0; i < m_table.size(); i++) {
248 bool get(T key, U* value)
260 if (m_table.size() == 0) {
264 int hash_value = hash_functor::compute(key);
265 int index = hash_value % m_table.size();
266 for (
int i = 0; i < m_table[index].size(); i++) {
267 if (m_table[index][i].key == key) {
269 *value = m_table[index][i].value;
281 int new_size = m_table.size();
283 if (m_table.size() == 0 && m_entry_count > 0) {
287 }
else if (m_table.size() * 2 < m_entry_count) {
289 new_size = (m_entry_count * 3) >> 1;
292 if (new_size != m_table.size()) {
298 void resize(
int new_size)
309 int bits = vt_log2(new_size-1) + 1;
310 assert((1 << bits) >= new_size);
312 new_size = 1 << bits;
313 m_size_mask = new_size - 1;
318 {
for (
int i = 0; i < m_table.size(); i++) {
319 for (
int j = 0; j < m_table[i].size(); j++) {
320 entry& e = m_table[i][j];
321 int hash_value = hash_functor::compute(e.key);
323 int index = hash_value & m_size_mask;
324 new_table[index].push_back(e);
331 m_table.transfer_members(&new_table);
346 template<
class data_type>
350 mmap_array(
int width,
int height,
bool writeable,
const char* filename = NULL) :
353 m_writeable(writeable)
355 m_data = malloc(total_bytes());
356 if (m_data == NULL) {
357 throw "mmap_array: can't map memory!";
366 data_type&
get(
int x,
int z)
369 assert(m_writeable ==
true);
373 const data_type&
get(
int x,
int z)
const
376 assert(x >= 0 && x < m_width);
377 assert(z >= 0 && z < m_height);
381 return ((data_type*) m_data)[x + z * m_width];
385 int total_bytes() {
return m_height * m_width *
sizeof(data_type); }
393 #endif // DOXYGEN_SHOULD_SKIP_THIS - the whole file