sample
#include <stdio.h> #include "closure.h" #include "vclosures.h" void f(void*) { printf("hello closure!\n"); } void f2(struct closure_void_str* p) { printf("hello %s!\n", p->text); } int main() { vclosures vclosures = VCLOSURES_INIT; vclosures_append(&vclosures, closure_void_new(&f)); vclosures_append(&vclosures, closure_void_str_new(&f2, "thiago")); for (size_t i = 0; i < vclosures_size(&vclosures); i++) { closure_void_call(vclosures_get(&vclosures, i)); } vclosures_destructor(&vclosures); return 0; }
header
#ifndef _vclosures_H #define _vclosures_H #include "closure.h" typedef struct vclosures_t { size_t size; size_t capacity; closure_void** data; } vclosures; #define VCLOSURES_INIT { 0, 0, 0 } void vclosures_destructor(vclosures* p); size_t vclosures_reserve(vclosures* p, size_t size); void vclosures_erase_n(vclosures* p, size_t index, size_t count); size_t vclosures_append(vclosures* p, closure_void* pItem); closure_void* vclosures_get(const vclosures* p, size_t index); size_t vclosures_size(vclosures* p); closure_void* vclosures_back(vclosures* p); closure_void* vclosures_front(vclosures* p); bool vclosures_empty(vclosures* p); void vclosures_clear(vclosures* p); void vclosures_erase(vclosures* p, size_t index); size_t vclosures_capacity(vclosures* p); closure_void** vclosures_data(vclosures* p); #endif //_vclosures_H
source
#include "stdafx.h" #include "vclosures.h" #include <stdlib.h> inline void delete_elements(closure_void** p, size_t nelements) { for (size_t i = 0; i < nelements; i++) { closure_void_delete(p[i]); } } size_t vclosures_reserve(vclosures* p, size_t nelements) { if (nelements > p->capacity) { size_t nelem = nelements; if (p->data == NULL) { p->data = (closure_void**)malloc(nelem * sizeof(closure_void*)); } else { p->data = (closure_void**)realloc((void*)p->data, nelem * sizeof(closure_void*)); } p->capacity = nelements; } return (p->data != 0) ? nelements : 0; } static size_t vclosures_grow(vclosures* p, size_t nelements) { const size_t INITIAL_CAPACITY = 4; const size_t MAX_CAPACITY = (size_t)(UINT_MAX / sizeof(closure_void*)); if (nelements > p->capacity) { size_t newCap = p->capacity == 0 ? INITIAL_CAPACITY : p->capacity; while (newCap < nelements) { newCap *= 2; if (newCap < nelements || newCap > MAX_CAPACITY) { /*overflow check*/ newCap = MAX_CAPACITY; } } return vclosures_reserve(p, newCap); } return p->capacity; } void vclosures_destructor(vclosures* p) { vclosures_clear(p); free(p->data); p->data = 0; } static size_t vclosures_insert_n(vclosures* p, size_t index, closure_void** pSource, size_t nelements) { size_t result = vclosures_grow(p, p->size + nelements); if (result == 0) { delete_elements(pSource, nelements); return 0; } if (index < p->size) { memmove(&p->data[index + nelements], &p->data[index], (sizeof(closure_void*)) * (p->size - index)); } memcpy((void*)&p->data[index], &pSource[0], sizeof(closure_void*) * nelements); p->size += nelements; return nelements; } void vclosures_erase_n(vclosures* p, size_t position, size_t nelements) { if (nelements > 0) { delete_elements(&p->data[position], nelements); memmove(p->data + position, p->data + position + nelements, sizeof(closure_void*) * nelements); p->size = p->size - nelements; } } size_t vclosures_append(vclosures* p, closure_void* pItem) { return vclosures_insert_n(p, p->size, &pItem, 1); } closure_void* vclosures_get(const vclosures* p, size_t index) { return p->data[index]; } size_t vclosures_size(vclosures* p) { return p->size; } closure_void* vclosures_back(vclosures* p) { return vclosures_get(p, vclosures_size(p) - 1); } closure_void* vclosures_front(vclosures* p) { return vclosures_get(p, 0); } bool vclosures_empty(vclosures* p) { return vclosures_size(p) == 0; } void vclosures_clear(vclosures* p) { vclosures_erase_n(p, 0, p->size); } void vclosures_erase(vclosures* p, size_t index) { vclosures_erase_n(p, index, 1); } size_t vclosures_capacity(vclosures* p) { return p->capacity; } closure_void** vclosures_data(vclosures* p) { return p->data; }