Last active
September 29, 2016 04:44
-
-
Save teknoman117/cb721cad71aeefe1425e4cc5c03abb67 to your computer and use it in GitHub Desktop.
example of the c object oriented pattern
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <malloc.h> | |
#include <assert.h> | |
#include <string.h> | |
struct c_vector | |
{ | |
size_t element_size; | |
size_t size; | |
size_t capacity; | |
void *contents; | |
}; | |
static struct c_vector* | |
c_vector_new(size_t element_size, size_t reserve) | |
{ | |
struct c_vector* vector = calloc(1, sizeof(struct c_vector)); | |
vector->element_size = element_size; | |
vector->capacity = reserve; | |
vector->contents = calloc(reserve, element_size); | |
return vector; | |
} | |
static void | |
c_vector_delete(struct c_vector* vector) | |
{ | |
assert(vector != NULL); | |
free(vector->contents); | |
free(vector); | |
} | |
static void | |
c_vector_ensure(struct c_vector* vector, size_t reserve) | |
{ | |
assert(vector != NULL); | |
if (vector->capacity < reserve) | |
{ | |
vector->contents = realloc(vector->contents, reserve); | |
vector->capacity = reserve; | |
} | |
} | |
static void | |
c_vector_push_back(struct c_vector* vector, void* element) | |
{ | |
assert(vector != NULL); | |
assert(element != NULL); | |
if (vector->size + 1 > vector->capacity) | |
{ | |
c_vector_ensure(vector, (3 * vector->capacity) / 2); | |
} | |
size_t offset = vector->size * vector->element_size; | |
memcpy(vector->contents + offset, element, vector->element_size); | |
vector->size++; | |
} | |
static int | |
c_vector_pop_back(struct c_vector* vector, void* element) | |
{ | |
assert(vector != NULL); | |
assert(element != NULL); | |
if (!vector->size) | |
{ | |
return 1; | |
} | |
vector->size--; | |
size_t offset = vector->size * vector->element_size; | |
memcpy(element, vector->contents + offset, vector->element_size); | |
return 0; | |
} | |
static int | |
c_vector_remove(struct c_vector* vector, size_t index) | |
{ | |
assert(vector != NULL); | |
if (index >= vector->size) | |
{ | |
return 1; | |
} | |
size_t offset = index * vector->element_size; | |
size_t count = (vector->size - index) - 1; | |
if (count) | |
{ | |
memcpy(vector->contents + offset, vector->contents + offset + vector->element_size, count * vector->element_size); | |
} | |
vector->size--; | |
return 0; | |
} | |
int | |
main () | |
{ | |
struct c_vector* vector = c_vector_new(sizeof(int), 8); | |
for (int i = 0; i < 8; i++) | |
{ | |
printf("pushing: %d\n", i); | |
c_vector_push_back(vector, &i); | |
} | |
c_vector_remove(vector, 4); | |
c_vector_remove(vector, 6); | |
int value; | |
while (!c_vector_pop_back(vector, &value)) | |
{ | |
printf("popped: %d\n", value); | |
} | |
c_vector_delete(vector); | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment