DArray.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #ifndef SCUFCONT_DARRAY_H_
  2. #define SCUFCONT_DARRAY_H_
  3. #include <stdbool.h>
  4. #include <stddef.h>
  5. #include <stdlib.h> // IWYU pragma: keep
  6. #include <string.h>
  7. #include "scufcont.h"
  8. // #define SCUFCONT_BOUNDS_CHECK
  9. #ifdef SCUFCONT_BOUNDS_CHECK
  10. #include <stdio.h>
  11. #endif // SCUFCONT_BOUNDS_CHECK
  12. #define SCDARRAY_EXPANDER(macro, type, type_name, func_name) macro(type, SCDArray_##type_name, SCDArray_##type_name##_##func_name)
  13. #define SCDARRAY_IMPL(type, type_name) \
  14. SCDARRAY_EXPANDER(SCDARRAY_ALLOC, type, type_name, alloc) \
  15. SCDARRAY_EXPANDER(SCDARRAY_IS_NULL, type, type_name, is_null) \
  16. SCDARRAY_EXPANDER(SCDARRAY_PUSH_BACK, type, type_name, push_back) \
  17. SCDARRAY_EXPANDER(SCDARRAY_AT, type, type_name, at)
  18. #define SCDARRAY_HEADER(type, type_name) \
  19. SCDARRAY_STRUCT(type, type_name) \
  20. SCDARRAY_SIGS(type, type_name)
  21. #define SCDARRAY_SIGS(type, type_name) \
  22. SCDARRAY_EXPANDER(SCDARRAY_ALLOC_SIG, type, type_name, alloc); \
  23. SCDARRAY_EXPANDER(SCDARRAY_IS_NULL_SIG, type, type_name, is_null); \
  24. SCDARRAY_EXPANDER(SCDARRAY_PUSH_BACK_SIG, type, type_name, push_back); \
  25. SCDARRAY_EXPANDER(SCDARRAY_AT_SIG, type, type_name, at);
  26. // SCDARRAY_ALLOC_SIG(type, SCDArray_##type_name, SCDArray_##type_name##_alloc); \
  27. // SCDARRAY_PUSH_BACK_SIG(type, SCDArray_##type_name, SCDArray_##type_name##_push_back);
  28. #define SCDARRAY_STRUCT(type, type_name) \
  29. typedef struct { \
  30. type* data; \
  31. size_t len; \
  32. size_t capacity; \
  33. } SCDArray_##type_name;
  34. // SCDARRAY_STRUCT(int);
  35. #define SCDARRAY_ALLOC_SIG(type, type_name, func_name) ScufContResult func_name(type_name* darr)
  36. #define SCDARRAY_ALLOC(type, type_name, func_name) \
  37. SCDARRAY_ALLOC_SIG(type, type_name, func_name) { \
  38. darr->data = (type*) calloc(1, sizeof(type)); \
  39. if (darr->data == NULL) { \
  40. return SCUFCONT_OUT_OF_MEMORY; \
  41. } \
  42. darr->len = 0; \
  43. darr->capacity = 1; \
  44. return SCUFCONT_SUCCESS; \
  45. }
  46. #define SCDARRAY_IS_NULL_SIG(type, type_name, func_name) bool func_name(const type_name* darr)
  47. #define SCDARRAY_IS_NULL(type, type_name, func_name) \
  48. SCDARRAY_IS_NULL_SIG(type, type_name, func_name) { \
  49. return darr->data == NULL; \
  50. }
  51. // SCDARRAY_ALLOC(int, SCDArray_int, SCDArray_int_alloc);
  52. #define SCDARRAY_PUSH_BACK_SIG(type, type_name, func_name) int func_name(type_name* darr, const type* new_elem)
  53. #define SCDARRAY_PUSH_BACK(type, type_name, func_name) \
  54. SCDARRAY_PUSH_BACK_SIG(type, type_name, func_name) { \
  55. if (darr->len + 1 > darr->capacity) { \
  56. darr->capacity *= 2; \
  57. darr->data = (type*) realloc(darr->data, darr->capacity * sizeof(type)); \
  58. if (darr->data == NULL) { \
  59. return -1; \
  60. } \
  61. } \
  62. memcpy(darr->data + darr->len, new_elem, sizeof(type)); \
  63. darr->len++; \
  64. return 1; \
  65. }
  66. #define SCDARRAY_AT_SIG(type, type_name, func_name) type* func_name(type_name* darr, const size_t i)
  67. // SCDARRAY_PUSH_BACK(int, SCDArray_int, SCDArray_int_push_back);
  68. #ifdef SCUFCONT_BOUNDS_CHECK
  69. #define SCDARRAY_AT(type, type_name, func_name) \
  70. SCDARRAY_AT_SIG(type, type_name, func_name) { \
  71. if (i < 0 || i > darr->len) { \
  72. fprintf(stderr, #func_name " out-of-bounds. i: %zu, len: %zu", i, darr->len); \
  73. exit(1); \
  74. } \
  75. \
  76. return darr->data + i; \
  77. }
  78. #else
  79. #define SCDARRAY_AT(type, type_name, func_name) \
  80. SCDARRAY_AT_SIG(type, type_name, func_name) { \
  81. return darr->data + i; \
  82. }
  83. #endif // SCUFCONT_BOUNDS_CHECK
  84. // SCDARRAY_AT(char*, SCDArray_charp, SCDArray_charp_at)
  85. #endif // SCUFCONT_DARRAY_H_