grow_array.h 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. // Preprocessor inputs:
  2. // GROWARRAY_NAME - prefix of of functions to define
  3. // GROWARRAY_OBJECT_TYPE - type of structure where array and capacity sizes are
  4. // GROWARRAY_ARRAY_MEMBER - array member
  5. // GROWARRAY_CAPACITY_MEMBER - capacity member
  6. // GROWARRAY_MAX_CAPACITY - max value of capacity member
  7. #include <limits.h>
  8. #include <string.h>
  9. #include <stddef.h>
  10. #include <misc/debug.h>
  11. #include <misc/balloc.h>
  12. #include <misc/merge.h>
  13. #define GrowArrayObject GROWARRAY_OBJECT_TYPE
  14. #define GrowArray_Init MERGE(GROWARRAY_NAME, _Init)
  15. #define GrowArray_Free MERGE(GROWARRAY_NAME, _Free)
  16. #define GrowArray_DoubleUp MERGE(GROWARRAY_NAME, _DoubleUp)
  17. static int GrowArray_Init (GrowArrayObject *o, size_t capacity) WARN_UNUSED;
  18. static void GrowArray_Free (GrowArrayObject *o);
  19. static int GrowArray_DoubleUp (GrowArrayObject *o) WARN_UNUSED;
  20. static int GrowArray_Init (GrowArrayObject *o, size_t capacity)
  21. {
  22. ASSERT(capacity > 0)
  23. if (capacity > GROWARRAY_MAX_CAPACITY) {
  24. return 0;
  25. }
  26. if (!(o->GROWARRAY_ARRAY_MEMBER = BAllocArray(capacity, sizeof(o->GROWARRAY_ARRAY_MEMBER[0])))) {
  27. return 0;
  28. }
  29. o->GROWARRAY_CAPACITY_MEMBER = capacity;
  30. return 1;
  31. }
  32. static void GrowArray_Free (GrowArrayObject *o)
  33. {
  34. BFree(o->GROWARRAY_ARRAY_MEMBER);
  35. }
  36. static int GrowArray_DoubleUp (GrowArrayObject *o)
  37. {
  38. ASSERT(o->GROWARRAY_CAPACITY_MEMBER > 0)
  39. if (o->GROWARRAY_CAPACITY_MEMBER > SIZE_MAX / 2 || o->GROWARRAY_CAPACITY_MEMBER > GROWARRAY_MAX_CAPACITY / 2) {
  40. return 0;
  41. }
  42. size_t newcap = 2 * o->GROWARRAY_CAPACITY_MEMBER;
  43. void *newarr = BAllocArray(newcap, sizeof(o->GROWARRAY_ARRAY_MEMBER[0]));
  44. if (!newarr) {
  45. return 0;
  46. }
  47. memcpy(newarr, o->GROWARRAY_ARRAY_MEMBER, o->GROWARRAY_CAPACITY_MEMBER * sizeof(o->GROWARRAY_ARRAY_MEMBER[0]));
  48. BFree(o->GROWARRAY_ARRAY_MEMBER);
  49. o->GROWARRAY_ARRAY_MEMBER = newarr;
  50. o->GROWARRAY_CAPACITY_MEMBER = newcap;
  51. return 1;
  52. }
  53. #undef GROWARRAY_NAME
  54. #undef GROWARRAY_OBJECT_TYPE
  55. #undef GROWARRAY_ARRAY_MEMBER
  56. #undef GROWARRAY_CAPACITY_MEMBER
  57. #undef GROWARRAY_MAX_CAPACITY
  58. #undef GrowArrayObject
  59. #undef GrowArray_Init
  60. #undef GrowArray_Free
  61. #undef GrowArray_DoubleUp