libhydride/ftgl/vector.c
2017-11-09 22:54:55 +03:00

336 lines
7.4 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);
}