array.h 3.3 KB

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