/* =========================================================================
* Freetype GL - A C OpenGL Freetype engine
* Platform: Any
* WWW: http://code.google.com/p/freetype-gl/
* -------------------------------------------------------------------------
* Copyright 2011,2012 Nicolas P. Rougier. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY NICOLAS P. ROUGIER ''AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL NICOLAS P. ROUGIER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are
* those of the authors and should not be interpreted as representing official
* policies, either expressed or implied, of Nicolas P. Rougier.
* ========================================================================= */
#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 )
{
assert( item_size );
vector_t *self = (vector_t *) malloc( sizeof(vector_t) );
assert (self);
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 *) )
{
assert( self );
size_t i;
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);
}