arena.h 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. #ifndef ARENA_H
  2. #define ARENA_H
  3. #include <stdint.h>
  4. typedef uint8_t err_t;
  5. struct arena {
  6. uint8_t *data;
  7. size_t cur;
  8. size_t cap;
  9. };
  10. struct void_p_err_t {
  11. void *ptr;
  12. err_t err;
  13. };
  14. struct arena_void_p_err_t {
  15. struct arena arena;
  16. void *ptr;
  17. err_t err;
  18. };
  19. struct arena_err_t {
  20. struct arena arena;
  21. err_t err;
  22. };
  23. enum arena_err {
  24. ARENA_ERR_OK = 0,
  25. ARENA_ERR_MALLOC_FAIL,
  26. ARENA_ERR_HIT_CAP
  27. };
  28. struct arena_err_t arena_create(size_t cap);
  29. err_t arena_destroy(struct arena arena);
  30. struct void_p_err_t arena_alloc(struct arena *arena, size_t size);
  31. struct arena_void_p_err_t arena_alloc_pure(struct arena arena, size_t size);
  32. err_t arena_forget(struct arena *arena);
  33. struct arena_err_t arena_forget_pure(struct arena arena);
  34. #if defined(ARENA_IMP) || defined(IMP)
  35. #include <stdlib.h>
  36. struct arena_err_t
  37. arena_create(size_t cap)
  38. {
  39. void *data = calloc(cap, sizeof(uint8_t));
  40. if ( data == NULL ) {
  41. return (struct arena_err_t) { .err = ARENA_ERR_MALLOC_FAIL };
  42. }
  43. struct arena arena = {
  44. .data = data,
  45. .cap = cap,
  46. .cur = 0
  47. };
  48. return (struct arena_err_t) { .arena = arena, .err = ARENA_ERR_OK };
  49. }
  50. err_t
  51. arena_destroy(struct arena arena)
  52. {
  53. free(arena.data);
  54. return ARENA_ERR_OK;
  55. }
  56. struct void_p_err_t
  57. arena_alloc(struct arena *arena, size_t size)
  58. {
  59. if ( arena->cur + size >= arena->cap ) {
  60. return (struct void_p_err_t) {
  61. .ptr = NULL,
  62. .err = ARENA_ERR_HIT_CAP
  63. };
  64. }
  65. void * ptr = (void *) (arena->data + arena->cur);
  66. arena->cur += size;
  67. return (struct void_p_err_t) {
  68. .ptr = ptr,
  69. .err = ARENA_ERR_OK
  70. };
  71. }
  72. struct arena_void_p_err_t
  73. arena_alloc_pure(struct arena arena, size_t size)
  74. {
  75. struct void_p_err_t vpet = arena_alloc(&arena, size);
  76. return (struct arena_void_p_err_t) {
  77. .arena = arena,
  78. .ptr = vpet.ptr,
  79. .err = vpet.err
  80. };
  81. }
  82. err_t
  83. arena_forget(struct arena *arena)
  84. {
  85. arena->cur = 0;
  86. return ARENA_ERR_OK;
  87. }
  88. struct arena_err_t
  89. arena_forget_pure(struct arena arena)
  90. {
  91. err_t err = arena_forget(&arena);
  92. return (struct arena_err_t) { .arena = arena, .err = err };
  93. }
  94. #endif /* ARENA_IMP || IMPLEMENTATIONS */
  95. #endif /* ARENA_H */