array.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #ifndef HW_ARRAY_H_
  2. #define HW_ARRAY_H_
  3. /*
  4. * array
  5. * at: random access by pos
  6. * @effective
  7. * push_back,pop_back,del_nomove,swap
  8. * @ineffective
  9. * add,del
  10. */
  11. #include <assert.h> // for assert
  12. #include <stdlib.h> // for malloc,realloc,free
  13. #include <string.h> // for memset,memmove
  14. // #include <vector>
  15. // typedef std::vector<type> atype;
  16. #define ARRAY_DECL(type, atype) \
  17. struct atype { \
  18. type* ptr; \
  19. size_t size; \
  20. size_t maxsize;\
  21. }; \
  22. typedef struct atype atype;\
  23. \
  24. static inline type* atype##_data(atype* p) {\
  25. return p->ptr;\
  26. }\
  27. \
  28. static inline int atype##_size(atype* p) {\
  29. return p->size;\
  30. }\
  31. \
  32. static inline int atype##_maxsize(atype* p) {\
  33. return p->maxsize;\
  34. }\
  35. \
  36. static inline int atype##_empty(atype* p) {\
  37. return p->size == 0;\
  38. }\
  39. \
  40. static inline type* atype##_at(atype* p, int pos) {\
  41. if (pos < 0) {\
  42. pos += p->size;\
  43. }\
  44. assert(pos >= 0 && pos < p->size);\
  45. return p->ptr + pos;\
  46. }\
  47. \
  48. static inline type* atype##_front(atype* p) {\
  49. return p->size == 0 ? NULL : p->ptr;\
  50. }\
  51. \
  52. static inline type* atype##_back(atype* p) {\
  53. return p->size == 0 ? NULL : p->ptr+p->size-1;\
  54. }\
  55. \
  56. static inline void atype##_init(atype* p, int maxsize) {\
  57. p->size = 0;\
  58. p->maxsize = maxsize;\
  59. size_t bytes = sizeof(type) * maxsize;\
  60. p->ptr = (type*)malloc(bytes);\
  61. memset(p->ptr, 0, bytes);\
  62. }\
  63. static inline void atype##_clear(atype* p) {\
  64. p->size = 0;\
  65. memset(p->ptr, 0, sizeof(type) * p->maxsize);\
  66. }\
  67. \
  68. static inline void atype##_cleanup(atype* p) {\
  69. if (p->ptr) {\
  70. free(p->ptr);\
  71. p->ptr = NULL;\
  72. }\
  73. p->size = p->maxsize = 0;\
  74. }\
  75. \
  76. static inline void atype##_resize(atype* p, int maxsize) {\
  77. p->maxsize = maxsize;\
  78. int bytes = sizeof(type) * maxsize;\
  79. p->ptr = (type*)realloc(p->ptr, bytes);\
  80. }\
  81. \
  82. static inline void atype##_double_resize(atype* p) {\
  83. assert(p->maxsize != 0);\
  84. return atype##_resize(p, p->maxsize*2);\
  85. }\
  86. \
  87. static inline void atype##_push_back(atype* p, type* elem) {\
  88. if (p->size == p->maxsize) {\
  89. atype##_double_resize(p);\
  90. }\
  91. p->ptr[p->size] = *elem;\
  92. p->size++;\
  93. }\
  94. \
  95. static inline void atype##_pop_back(atype* p) {\
  96. assert(p->size > 0);\
  97. p->size--;\
  98. }\
  99. \
  100. static inline void atype##_add(atype* p, type* elem, int pos) {\
  101. if (pos < 0) {\
  102. pos += p->size;\
  103. }\
  104. assert(pos >= 0 && pos <= p->size);\
  105. if (p->size == p->maxsize) {\
  106. atype##_double_resize(p);\
  107. }\
  108. if (pos < p->size) {\
  109. memmove(p->ptr + pos+1, p->ptr + pos, sizeof(type)*(p->size-pos));\
  110. }\
  111. p->ptr[pos] = *elem;\
  112. p->size++;\
  113. }\
  114. \
  115. static inline void atype##_del(atype* p, int pos) {\
  116. if (pos < 0) {\
  117. pos += p->size;\
  118. }\
  119. assert(pos >= 0 && pos < p->size);\
  120. p->size--;\
  121. if (pos < p->size) {\
  122. memmove(p->ptr + pos, p->ptr + pos+1, sizeof(type)*(p->size-pos));\
  123. }\
  124. }\
  125. \
  126. static inline void atype##_del_nomove(atype* p, int pos) {\
  127. if (pos < 0) {\
  128. pos += p->size;\
  129. }\
  130. assert(pos >= 0 && pos < p->size);\
  131. p->size--;\
  132. if (pos < p->size) {\
  133. p->ptr[pos] = p->ptr[p->size];\
  134. }\
  135. }\
  136. \
  137. static inline void atype##_swap(atype* p, int pos1, int pos2) {\
  138. if (pos1 < 0) {\
  139. pos1 += p->size;\
  140. }\
  141. if (pos2 < 0) {\
  142. pos2 += p->size;\
  143. }\
  144. type tmp = p->ptr[pos1];\
  145. p->ptr[pos1] = p->ptr[pos2];\
  146. p->ptr[pos2] = tmp;\
  147. }\
  148. #endif