1
0

array.h 3.5 KB

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