1
0

array.h 3.4 KB

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