libglez/ftgl/vector.c
2017-12-07 17:07:55 +03:00

271 lines
7.0 KiB
C

/* Freetype GL - A C OpenGL Freetype engine
*
* Distributed under the OSI-approved BSD 2-Clause License. See accompanying
* file `LICENSE` for more details.
*/
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "vector.h"
// ------------------------------------------------------------- vector_new ---
vector_t *vector_new(size_t item_size)
{
vector_t *self = (vector_t *) malloc(sizeof(vector_t));
assert(item_size);
if (!self)
{
fprintf(stderr, "line %d: No more memory for allocating data\n",
__LINE__);
exit(EXIT_FAILURE);
}
self->item_size = item_size;
self->size = 0;
self->capacity = 1;
self->items = malloc(self->item_size * self->capacity);
return self;
}
// ---------------------------------------------------------- vector_delete ---
void vector_delete(vector_t *self)
{
assert(self);
free(self->items);
free(self);
}
// ------------------------------------------------------------- vector_get ---
const void *vector_get(const vector_t *self, size_t index)
{
assert(self);
assert(self->size);
assert(index < self->size);
return (char *) (self->items) + index * self->item_size;
}
// ----------------------------------------------------------- vector_front ---
const void *vector_front(const vector_t *self)
{
assert(self);
assert(self->size);
return vector_get(self, 0);
}
// ------------------------------------------------------------ vector_back ---
const void *vector_back(const vector_t *self)
{
assert(self);
assert(self->size);
return vector_get(self, self->size - 1);
}
// -------------------------------------------------------- vector_contains ---
int vector_contains(const vector_t *self, const void *item,
int (*cmp)(const void *, const void *))
{
size_t i;
assert(self);
for (i = 0; i < self->size; ++i)
{
if ((*cmp)(item, vector_get(self, i)) == 0)
{
return 1;
}
}
return 0;
}
// ----------------------------------------------------------- vector_empty ---
int vector_empty(const vector_t *self)
{
assert(self);
return self->size == 0;
}
// ------------------------------------------------------------ vector_size ---
size_t vector_size(const vector_t *self)
{
assert(self);
return self->size;
}
// --------------------------------------------------------- vector_reserve ---
void vector_reserve(vector_t *self, const size_t size)
{
assert(self);
if (self->capacity < size)
{
self->items = realloc(self->items, size * self->item_size);
self->capacity = size;
}
}
// -------------------------------------------------------- vector_capacity ---
size_t vector_capacity(const vector_t *self)
{
assert(self);
return self->capacity;
}
// ---------------------------------------------------------- vector_shrink ---
void vector_shrink(vector_t *self)
{
assert(self);
if (self->capacity > self->size)
{
self->items = realloc(self->items, self->size * self->item_size);
}
self->capacity = self->size;
}
// ----------------------------------------------------------- vector_clear ---
void vector_clear(vector_t *self)
{
assert(self);
self->size = 0;
}
// ------------------------------------------------------------- vector_set ---
void vector_set(vector_t *self, const size_t index, const void *item)
{
assert(self);
assert(self->size);
assert(index < self->size);
memcpy((char *) (self->items) + index * self->item_size, item,
self->item_size);
}
// ---------------------------------------------------------- vector_insert ---
void vector_insert(vector_t *self, const size_t index, const void *item)
{
assert(self);
assert(index <= self->size);
if (self->capacity <= self->size)
{
vector_reserve(self, 2 * self->capacity);
}
if (index < self->size)
{
memmove((char *) (self->items) + (index + 1) * self->item_size,
(char *) (self->items) + (index + 0) * self->item_size,
(self->size - index) * self->item_size);
}
self->size++;
vector_set(self, index, item);
}
// ----------------------------------------------------- vector_erase_range ---
void vector_erase_range(vector_t *self, const size_t first, const size_t last)
{
assert(self);
assert(first < self->size);
assert(last < self->size + 1);
assert(first < last);
memmove((char *) (self->items) + first * self->item_size,
(char *) (self->items) + last * self->item_size,
(self->size - last) * self->item_size);
self->size -= (last - first);
}
// ----------------------------------------------------------- vector_erase ---
void vector_erase(vector_t *self, const size_t index)
{
assert(self);
assert(index < self->size);
vector_erase_range(self, index, index + 1);
}
// ------------------------------------------------------- vector_push_back ---
void vector_push_back(vector_t *self, const void *item)
{
vector_insert(self, self->size, item);
}
// -------------------------------------------------------- vector_pop_back ---
void vector_pop_back(vector_t *self)
{
assert(self);
assert(self->size);
self->size--;
}
// ---------------------------------------------------------- vector_resize ---
void vector_resize(vector_t *self, const size_t size)
{
assert(self);
if (size > self->capacity)
{
vector_reserve(self, size);
self->size = self->capacity;
}
else
{
self->size = size;
}
}
// -------------------------------------------------- vector_push_back_data ---
void vector_push_back_data(vector_t *self, const void *data, const size_t count)
{
assert(self);
assert(data);
assert(count);
if (self->capacity < (self->size + count))
{
vector_reserve(self, self->size + count);
}
memmove((char *) (self->items) + self->size * self->item_size, data,
count * self->item_size);
self->size += count;
}
// ----------------------------------------------------- vector_insert_data ---
void vector_insert_data(vector_t *self, const size_t index, const void *data,
const size_t count)
{
assert(self);
assert(index < self->size);
assert(data);
assert(count);
if (self->capacity < (self->size + count))
{
vector_reserve(self, self->size + count);
}
memmove((char *) (self->items) + (index + count) * self->item_size,
(char *) (self->items) + (index) *self->item_size,
count * self->item_size);
memmove((char *) (self->items) + index * self->item_size, data,
count * self->item_size);
self->size += count;
}
// ------------------------------------------------------------ vector_sort ---
void vector_sort(vector_t *self, int (*cmp)(const void *, const void *))
{
assert(self);
assert(self->size);
qsort(self->items, self->size, self->item_size, cmp);
}