/* * Copyright (C) 2007 Tildeslash Ltd. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation. * * There are special exceptions to the terms and conditions of the GPL * as it is applied to this software. View the full text of the exception * in the file EXCEPTIONS accompanying this software distribution. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "Config.h" #include #include "Util.h" #include "Vector.h" /** * Implementation of the Vector interface. * * @version \$Id: Vector.c,v 1.14 2007/02/07 18:44:05 hauk Exp $ * @file */ /* ----------------------------------------------------------- Definitions */ #define T Vector_T struct T { int length; int capacity; void **array; uint32_T timestamp; }; /* ------------------------------------------------------------ Prototypes */ static void secureCapacity(T V); /* ----------------------------------------------------- Protected methods */ #ifdef PACKAGE_PROTECTED #pragma GCC visibility push(hidden) #endif T Vector_new(int hint) { T V; assert(hint>=0); NEW(V); if(hint==0) hint= 16; V->capacity= hint; V->array= CALLOC(V->capacity, sizeof (void *)); return V; } void Vector_free(T *V) { assert(V && *V); FREE((*V)->array); FREE(*V); } void Vector_insert(T V, int i, void *e) { int j; assert(V); assert(i >= 0 && i <= V->length); V->timestamp++; secureCapacity(V); for(j= V->length++; j>i; j--) V->array[j]= V->array[j-1]; V->array[i]= e; } void *Vector_set(T V, int i, void *e) { void *prev; assert(V); assert(i >= 0 && i < V->length); V->timestamp++; prev= V->array[i]; V->array[i]= e; return prev; } void *Vector_get(T V, int i) { assert(V); assert(i >= 0 && i < V->length); return V->array[i]; } void *Vector_remove(T V, int i) { int j; void *x; assert(V); assert(i >= 0 && i < V->length); V->timestamp++; x= V->array[i]; for(j= i; j < V->length; j++) V->array[j]= V->array[j+1]; V->length--; return x; } void Vector_push(T V, void *e) { assert(V); V->timestamp++; secureCapacity(V); V->array[V->length++]= e; } void *Vector_pop(T V) { assert(V); assert(V->length>0); V->timestamp++; return V->array[--V->length]; } int Vector_isEmpty(T V) { assert(V); return (V->length==0); } int Vector_size(T V) { assert(V); return V->length; } void Vector_map(T V, void apply(const void *element, void *ap), void *ap) { int i; uint32_T stamp; assert(V); assert(apply); stamp= V->timestamp; for(i= 0; i < V->length; i++) apply(V->array[i], ap); assert(V->timestamp == stamp); } void **Vector_toArray(T V, void *end) { int i; void **array; assert(V); array= ALLOC((V->length + 1)*sizeof (*array)); for(i= 0; i < V->length; i++) array[i]= V->array[i]; array[i]= end; return array; } #ifdef PACKAGE_PROTECTED #pragma GCC visibility pop #endif /* ------------------------------------------------------- Private methods */ static void secureCapacity(T V) { if(V->length >= V->capacity) { V->capacity= 2*V->length; RESIZE(V->array, V->capacity * sizeof (void *)); } }