Created
March 10, 2026 16:22
-
-
Save marzeq/92ab8503292ec329f9b15aadb3a982e7 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 <stdalign.h> | |
| #include <stddef.h> | |
| #include <stdint.h> | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| typedef struct { | |
| size_t count; | |
| size_t capacity; | |
| } Header; | |
| #define ARR_INIT_CAPACITY 8 | |
| #define ARR_GROWTH_FACTOR 1.5 | |
| #define ARR_HDR_SIZE \ | |
| ((sizeof(Header) + alignof(max_align_t) - 1) & \ | |
| ~(alignof(max_align_t) - 1)) | |
| #define arr__hdr(arr) \ | |
| ((Header*)((char*)(arr) - ARR_HDR_SIZE)) | |
| #define arr_len(arr) \ | |
| ((arr) ? arr__hdr(arr)->count : 0) | |
| #define arr_free(arr) \ | |
| do { \ | |
| if (arr) { \ | |
| free(arr__hdr(arr)); \ | |
| (arr) = NULL; \ | |
| } \ | |
| } while (0) | |
| static int arr__push_impl( | |
| void** arr, | |
| size_t elem_size, | |
| const void* value | |
| ) { | |
| if (*arr == NULL) { | |
| size_t cap = ARR_INIT_CAPACITY; | |
| if (cap == 0 || cap > SIZE_MAX / elem_size) return 0; | |
| size_t bytes = ARR_HDR_SIZE + elem_size * cap; | |
| Header* h = malloc(bytes); | |
| if (!h) { | |
| return 0; | |
| } | |
| h->count = 0; | |
| h->capacity = cap; | |
| *arr = (char*)h + ARR_HDR_SIZE; | |
| } | |
| Header* h = arr__hdr(*arr); | |
| if (h->count >= h->capacity) { | |
| size_t newcap = h->capacity * ARR_GROWTH_FACTOR; | |
| if (newcap <= h->capacity || | |
| newcap > SIZE_MAX / elem_size) { | |
| return 0; | |
| } | |
| size_t bytes = ARR_HDR_SIZE + elem_size * newcap; | |
| Header* newh = realloc(h, bytes); | |
| if (!newh) { | |
| return 0; | |
| } | |
| newh->capacity = newcap; | |
| *arr = (char*)newh + ARR_HDR_SIZE; | |
| h = newh; | |
| } | |
| memcpy( | |
| (char*)(*arr) + elem_size * h->count, | |
| value, | |
| elem_size | |
| ); | |
| h->count++; | |
| return 1; | |
| } | |
| #define arr_push(arr, value) \ | |
| arr__push_impl( \ | |
| (void**)&(arr), \ | |
| sizeof(*(arr)), \ | |
| &(typeof(*(arr))){(value)} \ | |
| ) | |
| int main(void) { | |
| uint32_t* numbers = {}; | |
| for (size_t i = 0; i < 256; i++) { | |
| if (!arr_push(numbers, i * i)) { | |
| fprintf(stderr, "Failed to push %zu\n", i * i); | |
| return 1; | |
| } | |
| } | |
| for (size_t i = 0; i < arr_len(numbers); i++) { | |
| printf("%u ", numbers[i]); | |
| } | |
| printf("\n"); | |
| arr_free(numbers); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment