69 lines
2.5 KiB
C
69 lines
2.5 KiB
C
#pragma once
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#define vec(T) T *
|
|
|
|
#define vecFree(vec) ((vec) ? free(_vecheader(vec)),NULL : NULL)
|
|
#define vecCopy(src, dest) (vecFree(dest), vecAdd(dest, vecCount(src)), memcpy(dest, src, vecCount(src)))
|
|
|
|
#define vecAppend(vec, val) (_vecmaygrow(vec, 1), (vec)[_veclen(vec)] = (val), _veclen(vec)++)
|
|
#define vecLen(vec) ((vec) ? _veclen(vec) : 0)
|
|
#define vecCap(vec) ((vec) ? _veccap(vec) : 0)
|
|
|
|
#define vecBeg(vec) (vec)
|
|
#define vecEnd(vec) ((vec) ? (vec) + _veclen(vec) : NULL)
|
|
#define vecBack(vec) ((vec)[_veclen(vec) - 1])
|
|
|
|
#define vecAdd(vec, n) (_vecmaygrow(vec, (n)), _veclen(vec) += (size_type)(n), &(vec)[_veclen(vec)-(n)])
|
|
#define vecReserve(vec, n) (_vecmaygrow(vec, (n)))
|
|
#define vecShrink(vec) (_vecshrink((void **)&(vec), _veclen(vec), sizeof(*(vec))))
|
|
|
|
#define vecClear(vec) ((vec) ? _veclen(vec) = 0 : 0)
|
|
#define vecPop(vec) ((vec)[--_veclen(vec)])
|
|
|
|
// == IMPLEMENTATION ==========================================================================================
|
|
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#include <stdint.h>
|
|
|
|
#ifndef size_type
|
|
#define size_type uint32_t
|
|
#endif
|
|
|
|
#define _vecheader(vec) ((size_type *)(vec) - 2)
|
|
#define _veccap(vec) _vecheader(vec)[0]
|
|
#define _veclen(vec) _vecheader(vec)[1]
|
|
|
|
#define _vecneedgrow(vec, n) ((vec) == NULL || _veclen(vec) + n >= _veccap(vec))
|
|
#define _vecmaygrow(vec, n) (_vecneedgrow(vec, (n)) ? _vecgrow(vec, (size_type)(n)) : (void)0)
|
|
#define _vecgrow(vec, n) _vecgrowimpl((void **)&(vec), (n), sizeof(*(vec)))
|
|
|
|
inline static void _vecgrowimpl(void **arr, size_type increment, size_type itemsize) {
|
|
int newcap = *arr ? 2 * _veccap(*arr) + increment : increment + 1;
|
|
void *ptr = realloc(*arr ? _vecheader(*arr) : 0, itemsize * newcap + sizeof(size_type) * 2);
|
|
assert(ptr);
|
|
if (ptr) {
|
|
if (!*arr) ((size_type *)ptr)[1] = 0;
|
|
*arr = (void *) ((size_type *)ptr + 2);
|
|
_veccap(*arr) = newcap;
|
|
}
|
|
}
|
|
|
|
inline static void _vecshrink(void **arr, size_type newcap, size_t itemsize) {
|
|
if (newcap == _veccap(*arr) || !*arr) return;
|
|
void *ptr = realloc(_vecheader(*arr), itemsize * newcap + sizeof(size_type) * 2);
|
|
assert(ptr);
|
|
if (ptr) {
|
|
*arr = (void *) ((size_type *)ptr + 2);
|
|
if (_veclen(*arr) < newcap) _veclen(*arr) = newcap;
|
|
_veccap(*arr) = newcap;
|
|
}
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
} // extern "C"
|
|
#endif
|