Skip to content

Misc fixes #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
249 changes: 139 additions & 110 deletions include/generic_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,121 +7,150 @@
#include <stdlib.h>
#include <string.h>

// Todo:
// Todo:
// bool add_range(type_name* list, value_type* values, unsigned int count);
// bool insert_range(type_name* list, unsigned int index, value_type* values, unsigned int count);

#define LIST_DEFINE_H(type_name, function_prefix, value_type) \
typedef struct type_name { \
value_type* buffer; \
unsigned int count; \
unsigned int capacity; \
} type_name; \
\
type_name* function_prefix ## _create(void); \
bool function_prefix ## _init(type_name* list); \
bool function_prefix ## _init_capacity(type_name* list, unsigned int capacity); \
bool function_prefix ## _add(type_name* list, value_type value); \
bool function_prefix ## _insert(type_name* list, unsigned int index, value_type value); \
\
static inline void function_prefix ## _clear(type_name* list) { list->count = 0; } \
\
static inline unsigned int function_prefix ## _count(type_name* list) { return list->count; } \
\
static inline void function_prefix ## _free_resources(type_name* list) { free(list->buffer); } \
\
static inline void function_prefix ## _free(type_name* list) { free(list->buffer); free(list); } \
\
static inline value_type function_prefix ## _get(type_name* list, unsigned int index) { \
assert(index < list->count); \
return list->buffer[index]; \
} \
\
static inline void function_prefix ## _set(type_name* list, unsigned int index, value_type value) { \
assert(index <= list->count); \
if(index == list->count) \
function_prefix ## _add(list, value); \
else \
list->buffer[index] = value; \
} \
\
static inline void function_prefix ## _remove(type_name* list, unsigned int index) { \
assert(index < list->count); \
if(index == --list->count) \
return; \
else \
memmove(list->buffer + index, list->buffer + index + 1, (list->count - index) * sizeof(value_type)); \
} \
\
static inline value_type function_prefix ## _peek(type_name* list) { \
assert(list->count); \
return list->buffer[list->count - 1]; \
} \
\
static inline value_type function_prefix ## _pop(type_name* list) { \
assert(list->count); \
return list->buffer[--list->count]; \
} \
\
static inline void function_prefix ## _shrink_to_fit(type_name* list) { \
list->buffer = realloc(list->buffer, (list->count == 0 ? 1 : list->count) * sizeof(value_type)); \
list->capacity = list->count == 0 ? 1 : list->count; \
} \
#define LIST_DEFINE_H(type_name, function_prefix, value_type) \
typedef struct type_name { \
value_type* buffer; \
unsigned int count; \
unsigned int capacity; \
} type_name; \
\
type_name* function_prefix##_create(void); \
bool function_prefix##_init(type_name* list); \
bool function_prefix##_init_capacity(type_name* list, unsigned int capacity); \
bool function_prefix##_add(type_name* list, value_type value); \
bool function_prefix##_addAligned(type_name* list, value_type value); \
bool function_prefix##_insert(type_name* list, unsigned int index, value_type value); \
\
static inline void function_prefix##_clear(type_name* list) { \
list->count = 0; \
} \
\
static inline unsigned int function_prefix##_count(type_name* list) { \
return list->count; \
} \
\
static inline void function_prefix##_free_resources(type_name* list) { \
free(list->buffer); \
} \
\
static inline void function_prefix##_free(type_name* list) { \
free(list->buffer); \
free(list); \
} \
\
static inline value_type function_prefix##_get(type_name* list, unsigned int index) { \
assert(index < list->count); \
return list->buffer[index]; \
} \
\
static inline void function_prefix##_set(type_name* list, unsigned int index, value_type value) { \
assert(index <= list->count); \
if (index == list->count) \
function_prefix##_add(list, value); \
else \
list->buffer[index] = value; \
} \
\
static inline void function_prefix##_remove(type_name* list, unsigned int index) { \
assert(index < list->count); \
if (index == --list->count) \
return; \
else \
memmove(list->buffer + index, list->buffer + index + 1, (list->count - index) * sizeof(value_type)); \
} \
\
static inline value_type function_prefix##_peek(type_name* list) { \
assert(list->count); \
return list->buffer[list->count - 1]; \
} \
\
static inline value_type function_prefix##_pop(type_name* list) { \
assert(list->count); \
return list->buffer[--list->count]; \
} \
\
static inline void function_prefix##_shrink_to_fit(type_name* list) { \
list->buffer = (value_type*) realloc(list->buffer, (list->count == 0 ? 1 : list->count) * sizeof(value_type)); \
list->capacity = list->count == 0 ? 1 : list->count; \
}


#define LIST_DEFINE_C(type_name, function_prefix, value_type) \
type_name* function_prefix ## _create(void) { \
type_name* list = malloc(sizeof(type_name)); \
if(!list) \
return list; \
if(!function_prefix ## _init(list)) { \
free(list); \
return NULL; \
} \
return list; \
} \
\
bool function_prefix ## _init(type_name* list) { \
list->capacity = 4; \
list->count = 0; \
return (list->buffer = malloc(4 * sizeof(value_type))) != NULL; \
} \
\
bool function_prefix ## _init_capacity(type_name* list, unsigned int capacity) { \
assert(capacity); \
list->capacity = capacity; \
list->count = 0; \
return (list->buffer = malloc(capacity * sizeof(value_type))) != NULL; \
} \
\
bool function_prefix ## _add(type_name* list, value_type value) { \
if(list->count == list->capacity) { \
list->capacity *= 2; \
value_type* buffer = realloc(list->buffer, list->capacity * sizeof(value_type)); \
if(!buffer) \
return false; \
list->buffer = buffer; \
} \
list->buffer[list->count++] = value; \
return true; \
} \
\
bool function_prefix ## _insert(type_name* list, unsigned int index, value_type value) { \
if(index > list->count) return false; \
if(index == list->count) \
return function_prefix ## _add(list, value); \
if(list->count == list->capacity) { \
list->capacity *= 2; \
value_type* buffer = realloc(list->buffer, list->capacity * sizeof(value_type)); \
if(!buffer) \
return false; \
list->buffer = buffer; \
} \
memmove(list->buffer + index + 1, list->buffer + index, (list->count++ - index) * sizeof(value_type)); \
list->buffer[index] = value; \
return true; \
} \
#define LIST_DEFINE_C(type_name, function_prefix, value_type) \
type_name* function_prefix##_create(void) { \
type_name* list = malloc(sizeof(type_name)); \
if (!list) \
return list; \
if (!function_prefix##_init(list)) { \
free(list); \
return NULL; \
} \
return list; \
} \
\
bool function_prefix##_init(type_name* list) { \
list->capacity = 4; \
list->count = 0; \
return (list->buffer = aligned_alloc(alignof(value_type), 4 * sizeof(value_type))) != NULL; \
} \
\
bool function_prefix##_init_capacity(type_name* list, unsigned int capacity) { \
assert(capacity); \
list->capacity = capacity; \
list->count = 0; \
return (list->buffer = aligned_alloc(alignof(value_type), capacity * sizeof(value_type))) != NULL; \
} \
\
bool function_prefix##_add(type_name* list, value_type value) { \
if (list->count == list->capacity) { \
list->capacity = (list->capacity == 0) ? 2 : (list->capacity * 2); \
value_type* buffer = ((list->buffer == nullptr) || (list->count == 0)) \
? aligned_alloc(alignof(value_type), list->capacity * sizeof(value_type)) \
: realloc(list->buffer, list->capacity * sizeof(value_type)); \
if (!buffer) \
return false; \
list->buffer = buffer; \
} \
list->buffer[list->count++] = value; \
return true; \
} \
\
bool function_prefix##_addAligned(type_name* list, value_type value) { \
if (list->count == list->capacity) { \
list->capacity = (list->capacity == 0) ? 2 : (list->capacity * 2); \
value_type* buffer = aligned_alloc(alignof(value_type), list->capacity * sizeof(value_type)); \
if (!buffer) \
return false; \
if ((list->buffer != nullptr) && (list->count > 0)) { \
memcpy(buffer, list->buffer, list->count * sizeof(value_type)); \
free(list->buffer); \
} \
list->buffer = buffer; \
} \
list->buffer[list->count++] = value; \
return true; \
} \
\
bool function_prefix##_insert(type_name* list, unsigned int index, value_type value) { \
if (index > list->count) \
return false; \
if (index == list->count) \
return function_prefix##_add(list, value); \
if (list->count == list->capacity) { \
list->capacity = (list->capacity == 0) ? 2 : (list->capacity * 2); \
value_type* buffer = realloc(list->buffer, list->capacity * sizeof(value_type)); \
if (!buffer) \
return false; \
list->buffer = buffer; \
} \
memmove(list->buffer + index + 1, list->buffer + index, (list->count++ - index) * sizeof(value_type)); \
list->buffer[index] = value; \
return true; \
}



#endif
#endif