Created
February 25, 2024 14:57
-
-
Save mryndzionek/8eac2991cb11d5bd30b01696ef167b65 to your computer and use it in GitHub Desktop.
An attempt at implementing [heapless vectors](https://docs.rs/heapless/latest/heapless/struct.Vec.html) in C
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
// An attempt at implementing [heapless vectors](https://docs.rs/heapless/latest/heapless/struct.Vec.html) | |
// in C | |
typedef struct { | |
size_t length; | |
const size_t size; | |
const size_t capacity; | |
uint8_t contents[0]; | |
} vec_t; | |
#define _VEC_CONCAT(x, y) x##y | |
#define VEC_CONCAT(x, y) _VEC_CONCAT(x, y) | |
#define VEC_ARGS(_args...) _VEC_ARGS(_args) | |
#define _VEC_ARGS(_args...) _args | |
#define VEC_ASSERT(_a) assert(_a) | |
#define VEC_NEW(_type, _name, _cap) \ | |
typedef struct { \ | |
vec_t inner; \ | |
uint8_t contents[_cap * sizeof(_type)]; \ | |
} VEC_CONCAT(VEC_CONCAT(vec_##_type, __LINE__), _t); \ | |
VEC_CONCAT(VEC_CONCAT(vec_##_type, __LINE__), _t) \ | |
_name = {.inner = {.length = 0, .size = sizeof(_type), .capacity = _cap}, .contents = {0}}; | |
#define VEC_INIT(_type, _name, _data) \ | |
do \ | |
{ \ | |
const _type data[] = {_data}; \ | |
VEC_ASSERT(_name.inner.capacity >= sizeof(data) / sizeof(data[0])); \ | |
for (size_t i = 0; i < sizeof(data) / sizeof(data[0]); i++) \ | |
{ \ | |
for (size_t j = 0; j < _name.inner.size; j++) \ | |
{ \ | |
_name.contents[i * v1.inner.size + j] = ((uint8_t *)&data[i])[j]; \ | |
} \ | |
_name.inner.length = sizeof(data) / sizeof(data[0]); \ | |
} \ | |
} while (0) | |
#define VEC_LEN(_name) (_name.inner.length) | |
#define VEC_CAPACITY(_name) (_name.inner.capacity) | |
#define VEC_FOR_EACH(_type, _name) \ | |
for ( \ | |
struct { \ | |
size_t i; \ | |
_type *item; \ | |
} VEC_CONCAT(_name, _l) = {0, (_type *)&_name.contents[0]}; \ | |
VEC_CONCAT(_name, _l).i < _name.inner.length; \ | |
++VEC_CONCAT(_name, _l).i, ++VEC_CONCAT(_name, _l).item) | |
// VEC_NEW(uint16_t, v1, 5); | |
// VEC_INIT(uint16_t, v1, VEC_ARGS(10, 8, 7, 6)); | |
// | |
// VEC_FOR_EACH(uint16_t, v1) { printf("%d %d\n", VEC_LEN(v1), *v1_l.item); } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment