92 lines
5.7 KiB
C
92 lines
5.7 KiB
C
/*
|
|
* Copyright Luka Jankovic 2025
|
|
*
|
|
* This file is part of Kubo.
|
|
*
|
|
* Kubo 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, either version 3 of the License, or (at your option) any later
|
|
* version.
|
|
*
|
|
* Kubo 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
|
|
* Kubo. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef KUBO_DYNARRAY_H
|
|
#define KUBO_DYNARRAY_H
|
|
|
|
#include <assert.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#define KUBO_DRYNARRAY_DEFAULT_CAP 4
|
|
|
|
#define KUBO_DYNARRAY_REGISTER(name, type) \
|
|
struct name { \
|
|
type *data; \
|
|
size_t count; \
|
|
size_t capacity; \
|
|
}; \
|
|
\
|
|
static inline void name##_init(struct name *arr) { \
|
|
arr->count = 0; \
|
|
arr->capacity = KUBO_DRYNARRAY_DEFAULT_CAP; \
|
|
arr->data = malloc(sizeof(type) * arr->capacity); \
|
|
} \
|
|
\
|
|
static inline void name##_free(struct name *arr) { free(arr->data); } \
|
|
\
|
|
static inline bool name##_reserve(struct name *arr, size_t new_cap) { \
|
|
if (arr->capacity >= new_cap) \
|
|
return true; \
|
|
type *new_data = realloc(arr->data, sizeof(type) * new_cap); \
|
|
if (!new_data) \
|
|
return false; \
|
|
arr->data = new_data; \
|
|
arr->capacity = new_cap; \
|
|
return true; \
|
|
} \
|
|
\
|
|
static inline bool name##_add(struct name *arr, type new_val) { \
|
|
if (arr->count == arr->capacity - 1) { \
|
|
if (!name##_reserve(arr, arr->capacity * 2)) { \
|
|
return false; \
|
|
} \
|
|
} \
|
|
arr->data[arr->count++] = new_val; \
|
|
return true; \
|
|
} \
|
|
\
|
|
static inline type name##_get(struct name *arr, size_t index) { \
|
|
assert(index < arr->count); \
|
|
return arr->data[index]; \
|
|
} \
|
|
\
|
|
static inline void name##_set(struct name *arr, type new_val, \
|
|
size_t index) { \
|
|
assert(index < arr->count); \
|
|
arr->data[index] = new_val; \
|
|
} \
|
|
\
|
|
static inline void name##_pop(struct name *arr) { \
|
|
if (arr->count > 0) { \
|
|
arr->count--; \
|
|
} \
|
|
} \
|
|
\
|
|
static inline void name##_clear(struct name *arr) { \
|
|
free(arr->data); \
|
|
name##_init(arr); \
|
|
} \
|
|
\
|
|
static inline void name##_del(struct name *arr, size_t index) { \
|
|
assert(index < arr->count); \
|
|
memmove(arr->data + index, arr->data + index + 1, \
|
|
(--arr->count - index) * sizeof(type)); \
|
|
}
|
|
|
|
#endif
|