tree-sitter/src/runtime/array.h

123 lines
3.6 KiB
C
Raw Normal View History

2016-02-17 20:41:29 -08:00
#ifndef RUNTIME_ARRAY_H_
#define RUNTIME_ARRAY_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
2016-01-28 21:18:57 -08:00
#include <stdbool.h>
2016-01-15 15:08:42 -08:00
#include "runtime/alloc.h"
2016-02-17 20:41:29 -08:00
#define Array(T) \
2016-02-17 14:45:00 -08:00
struct { \
T *contents; \
uint32_t size; \
uint32_t capacity; \
2016-02-17 14:45:00 -08:00
}
2016-02-17 20:41:29 -08:00
#define array_init(self) \
2016-02-17 14:45:00 -08:00
((self)->size = 0, (self)->capacity = 0, (self)->contents = NULL)
#define array_new() \
{ NULL, 0, 0 }
2016-02-17 20:41:29 -08:00
#define array_get(self, index) \
(assert((uint32_t)index < (self)->size), &(self)->contents[index])
2016-02-17 20:41:29 -08:00
#define array_front(self) array_get(self, 0)
2016-02-17 20:41:29 -08:00
#define array_back(self) array_get(self, (self)->size - 1)
2016-02-17 20:41:29 -08:00
#define array_clear(self) ((self)->size = 0)
2015-11-20 00:01:53 -08:00
2016-02-17 20:41:29 -08:00
#define array_grow(self, new_capacity) \
array__grow((VoidArray *)(self), array__elem_size(self), new_capacity)
2016-02-17 20:41:29 -08:00
#define array_erase(self, index) \
array__erase((VoidArray *)(self), array__elem_size(self), index)
2016-02-17 20:41:29 -08:00
#define array_delete(self) array__delete((VoidArray *)self)
2015-11-20 00:01:53 -08:00
#define array_push(self, element) \
(array_grow((self), (self)->size + 1), \
(self)->contents[(self)->size++] = (element))
2016-02-17 14:45:00 -08:00
#define array_push_all(self, other) \
array_splice((self), (self)->size, 0, (other)->size, (other)->contents)
#define array_splice(self, index, old_count, new_count, new_elements) \
array__splice((VoidArray *)(self), array__elem_size(self), index, old_count, \
new_count, (new_elements))
#define array_insert(self, index, element) \
array_splice(self, index, 0, 1, &(element))
2016-02-17 20:41:29 -08:00
#define array_pop(self) ((self)->contents[--(self)->size])
2016-02-17 14:45:00 -08:00
// Private
2016-02-17 20:41:29 -08:00
typedef Array(void) VoidArray;
2016-02-17 14:45:00 -08:00
2016-02-17 20:41:29 -08:00
#define array__elem_size(self) sizeof(*(self)->contents)
2016-02-17 14:45:00 -08:00
2016-02-17 20:41:29 -08:00
static inline void array__delete(VoidArray *self) {
2016-02-17 14:45:00 -08:00
ts_free(self->contents);
self->contents = NULL;
self->size = 0;
2016-02-17 14:45:00 -08:00
self->capacity = 0;
}
2016-02-17 20:41:29 -08:00
static inline void array__erase(VoidArray *self, size_t element_size,
uint32_t index) {
assert(index < self->size);
char *contents = (char *)self->contents;
2016-02-17 14:45:00 -08:00
memmove(contents + index * element_size, contents + (index + 1) * element_size,
(self->size - index - 1) * element_size);
self->size--;
}
2016-11-04 09:18:38 -07:00
static inline void array__grow(VoidArray *self, size_t element_size,
uint32_t new_capacity) {
2016-11-04 09:18:38 -07:00
if (new_capacity > self->capacity) {
if (new_capacity < 2 * self->capacity)
new_capacity = 2 * self->capacity;
if (new_capacity < 8)
new_capacity = 8;
2016-11-04 09:18:38 -07:00
if (self->contents)
self->contents = ts_realloc(self->contents, new_capacity * element_size);
2016-11-04 09:18:38 -07:00
else
self->contents = ts_calloc(new_capacity, element_size);
2016-11-04 09:18:38 -07:00
self->capacity = new_capacity;
}
}
2016-11-04 09:18:38 -07:00
static inline void array__splice(VoidArray *self, size_t element_size,
uint32_t index, uint32_t old_count,
uint32_t new_count, void *elements) {
uint32_t new_size = self->size + new_count - old_count;
uint32_t old_end = index + old_count;
uint32_t new_end = index + new_count;
assert(old_end <= self->size);
2016-11-04 09:18:38 -07:00
array__grow(self, element_size, new_size);
char *contents = (char *)self->contents;
if (self->size > old_end)
memmove(contents + new_end * element_size, contents + old_end * element_size,
(self->size - old_end) * element_size);
if (new_count > 0)
memcpy((contents + index * element_size), elements,
new_count * element_size);
self->size += new_count - old_count;
}
#ifdef __cplusplus
}
#endif
2016-02-17 20:41:29 -08:00
#endif // RUNTIME_ARRAY_H_