DynArray.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #ifndef DYN_ARRAY_H_
  2. #define DYN_ARRAY_H_
  3. #include <stddef.h>
  4. #include <string.h>
  5. // #define SCUFCONT_BOUNDS_CHECK
  6. #ifdef SCUFCONT_BOUNDS_CHECK
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #endif // SCUFCONT_BOUNDS_CHECK
  10. #define DYN_ARRAY_EXPANDER(macro, type, type_name, func_name) macro(type, DynArray_##type_name, DynArray_##type_name##_##func_name);
  11. #define DYN_ARRAY_IMPL(type, type_name) \
  12. DYN_ARRAY_EXPANDER(DYN_ARRAY_ALLOC, type, type_name, alloc) \
  13. DYN_ARRAY_EXPANDER(DYN_ARRAY_IS_NULL, type, type_name, is_null) \
  14. DYN_ARRAY_EXPANDER(DYN_ARRAY_PUSH_BACK, type, type_name, push_back) \
  15. DYN_ARRAY_EXPANDER(DYN_ARRAY_AT, type, type_name, at)
  16. #define DYN_ARRAY_HEADER(type, type_name) \
  17. DYN_ARRAY_STRUCT(type, type_name) \
  18. DYN_ARRAY_SIGS(type, type_name)
  19. #define DYN_ARRAY_SIGS(type, type_name) \
  20. DYN_ARRAY_EXPANDER(DYN_ARRAY_ALLOC_SIG, type, type_name, alloc) \
  21. DYN_ARRAY_EXPANDER(DYN_ARRAY_IS_NULL_SIG, type, type_name, is_null) \
  22. DYN_ARRAY_EXPANDER(DYN_ARRAY_PUSH_BACK_SIG, type, type_name, push_back) \
  23. DYN_ARRAY_EXPANDER(DYN_ARRAY_AT_SIG, type, type_name, at)
  24. // DYN_ARRAY_ALLOC_SIG(type, DynArray_##type_name, DynArray_##type_name##_alloc); \
  25. // DYN_ARRAY_PUSH_BACK_SIG(type, DynArray_##type_name, DynArray_##type_name##_push_back);
  26. #define DYN_ARRAY_STRUCT(type, type_name) \
  27. typedef struct { \
  28. type* data; \
  29. size_t len; \
  30. size_t capacity; \
  31. } DynArray_##type_name;
  32. // DYN_ARRAY_STRUCT(int);
  33. #define DYN_ARRAY_ALLOC_SIG(type, type_name, func_name) bool func_name(type_name* darr)
  34. #define DYN_ARRAY_ALLOC(type, type_name, func_name) \
  35. DYN_ARRAY_ALLOC_SIG(type, type_name, func_name) { \
  36. darr->data = (type*) calloc(1, sizeof(type)); \
  37. if (darr->data == NULL) { \
  38. return false; \
  39. } \
  40. darr->len = 0; \
  41. darr->capacity = 1; \
  42. return true; \
  43. }
  44. #define DYN_ARRAY_IS_NULL_SIG(type, type_name, func_name) bool func_name(const type_name* darr)
  45. #define DYN_ARRAY_IS_NULL(type, type_name, func_name) \
  46. DYN_ARRAY_IS_NULL_SIG(type, type_name, func_name) { \
  47. return darr->data == NULL; \
  48. }
  49. // DYN_ARRAY_ALLOC(int, DynArray_int, DynArray_int_alloc);
  50. #define DYN_ARRAY_PUSH_BACK_SIG(type, type_name, func_name) int func_name(type_name* darr, const type* new_elem)
  51. #define DYN_ARRAY_PUSH_BACK(type, type_name, func_name) \
  52. DYN_ARRAY_PUSH_BACK_SIG(type, type_name, func_name) { \
  53. if (darr->len + 1 > darr->capacity) { \
  54. darr->capacity *= 2; \
  55. darr->data = (type*) realloc(darr->data, darr->capacity * sizeof(type)); \
  56. if (darr->data == NULL) { \
  57. return -1; \
  58. } \
  59. } \
  60. memcpy(darr->data + darr->len, new_elem, sizeof(type)); \
  61. darr->len++; \
  62. return 1; \
  63. }
  64. #define DYN_ARRAY_AT_SIG(type, type_name, func_name) type* func_name(type_name* darr, const size_t i)
  65. // DYN_ARRAY_PUSH_BACK(int, DynArray_int, DynArray_int_push_back);
  66. #ifdef SCUFCONT_BOUNDS_CHECK
  67. #define DYN_ARRAY_AT(type, type_name, func_name) \
  68. DYN_ARRAY_AT_SIG(type, type_name, func_name) { \
  69. if (i < 0 || i > darr->len) { \
  70. fprintf(stderr, #func_name " out-of-bounds. i: %zu, len: %zu", i, darr->len); \
  71. exit(1); \
  72. } \
  73. \
  74. return darr->data + i; \
  75. }
  76. #else
  77. #define DYN_ARRAY_AT(type, type_name, func_name) \
  78. DYN_ARRAY_AT_SIG(type, type_name, func_name) { \
  79. return darr->data + i; \
  80. }
  81. #endif // SCUFCONT_BOUNDS_CHECK
  82. // DYN_ARRAY_AT(char*, DynArray_charp, DynArray_charp_at)
  83. #endif // DYN_ARRAY_H_