Advertisement
Guest User

Untitled

a guest
Mar 22nd, 2017
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.25 KB | None | 0 0
  1. /**
  2. * Minimalistic std::vector-like implementation for C
  3. * Now with 50% more macros!
  4. *
  5. * Example usage:
  6. *
  7. * typedef list(int) list_int;
  8. * int main()
  9. * {
  10. * list_int foo;
  11. * list_init(foo);
  12. *
  13. * list_append(foo, 42);
  14. * list_insert(foo, 0, 1337);
  15. * list_set(foo, 1, 123);
  16. *
  17. * printf("foo[0] = %d\n", list_get(foo, 0));
  18. * printf("foo.pop() = %d\n", list_pop(foo));
  19. *
  20. * list_free(foo);
  21. * return 0;
  22. * }
  23. */
  24.  
  25. #include <stdlib.h>
  26. #include <string.h>
  27.  
  28. /**
  29. * Declares a list of type T. This should be used in conjunction with a
  30. * typedef at the global scope, as follows:
  31. *
  32. * typedef list(int) list_int;
  33. * typedef list(float) list_float;
  34. * typedef list(const char *) list_str;
  35. */
  36. #define list(T) struct { \
  37. T *data; \
  38. size_t capacity; \
  39. size_t size; \
  40. }
  41.  
  42. /**
  43. * Internal function that returns the greater of two values.
  44. * Do not call this manually.
  45. */
  46. #define list_max_(a, b) (((a) > (b)) ? (a) : (b))
  47.  
  48. /**
  49. * Internal function for moving elements within the list.
  50. * Do not call this manually.
  51. */
  52. #define list_move_(l, to, from, num) do { \
  53. memmove(&(l).data[(to)], &(l).data[(from)], (num) * sizeof(*(l).data)); \
  54. } while (0)
  55.  
  56. /**
  57. * Internal function for resizing the capacity of the list.
  58. * Do not call this manually.
  59. */
  60. #define list_realloc_(l, cap) do { \
  61. (l).capacity = (cap); \
  62. (l).data = realloc((l).data, (cap) * sizeof(*(l).data)); \
  63. } while (0)
  64.  
  65. /**
  66. * Internal function for growing the list when it becomes full.
  67. * Do not call this manually.
  68. */
  69. #define list_grow_(l) do { \
  70. if ((l).size == (l).capacity) { \
  71. list_realloc_((l), list_max_((l).capacity << 2, 8)); \
  72. } \
  73. } while (0)
  74.  
  75. /**
  76. * Initializes the specified list. This must only be called once per list.
  77. */
  78. #define list_init(l) do { \
  79. (l).data = NULL; \
  80. (l).capacity = 0; \
  81. (l).size = 0; \
  82. } while (0)
  83.  
  84. /**
  85. * Frees the specified list. After calling this, the list is
  86. * invalidated and using it results in undefined behavior.
  87. */
  88. #define list_free(l) do { \
  89. free((l).data); \
  90. (l).data = NULL; \
  91. (l).capacity = 0; \
  92. (l).size = 0; \
  93. } while (0)
  94.  
  95. /**
  96. * Returns the number of elements in the list.
  97. */
  98. #define list_size(l) ((l).size)
  99.  
  100. /**
  101. * Returns the value of the element at the specified index.
  102. */
  103. #define list_get(l, index) ((l).data[(index)])
  104.  
  105. /**
  106. * Sets the value of the element at the specified index.
  107. */
  108. #define list_set(l, index, value) ((l).data[(index)] = (value))
  109.  
  110. /**
  111. * Returns the last element in the list. Undefined behavior when size = 0.
  112. */
  113. #define list_peek(l) ((l).data[(l).size - 1])
  114.  
  115. /**
  116. * Removes and returns the last element in the list. Undefined behavior
  117. * when size = 0.
  118. */
  119. #define list_pop(l) ((l).data[--(l).size])
  120.  
  121. /**
  122. * Expands the list capacity to at least the specified value.
  123. * If the new capacity is less than or equal to the current capacity,
  124. * this has no effect.
  125. */
  126. #define list_reserve(l, cap) do { \
  127. if ((cap) > (l).capacity) { \
  128. list_realloc_((l), (cap)); \
  129. } \
  130. } while (0)
  131.  
  132. /**
  133. * Trims the list so that its capacity equals its size.
  134. * Useful for saving memory once you know that no more elements
  135. * will be added to the list.
  136. */
  137. #define list_trim(l) do { \
  138. list_realloc_((l), (l).size); \
  139. } while (0)
  140.  
  141. /**
  142. * Resizes the list to the specified size. If the new size is
  143. * greater than the old size, the new elements have undefined
  144. * initial values.
  145. */
  146. #define list_resize(l, sz) do { \
  147. list_reserve((l), (sz)); \
  148. (l).size = (sz); \
  149. } while (0)
  150.  
  151. /**
  152. * Appends the given value to the end of the list.
  153. */
  154. #define list_append(l, value) do { \
  155. list_grow_((l)); \
  156. (l).data[(l).size++] = (value); \
  157. } while (0);
  158.  
  159. /**
  160. * Inserts the given value at the specified index.
  161. */
  162. #define list_insert(l, index, value) do { \
  163. list_grow_((l)); \
  164. list_move_((l), (index) + 1, (index), (l).size - (index)); \
  165. (l).data[(index)] = (value); \
  166. (l).size++; \
  167. } while (0)
  168.  
  169. /**
  170. * Removes the value at the specified index and shifts the
  171. * remaining elements left.
  172. */
  173. #define list_remove(l, index) do { \
  174. list_move_((l), (index), (index) + 1, (l).size - (index) - 1); \
  175. (l).size--; \
  176. } while (0)
  177.  
  178. /**
  179. * Removes all elements from the list.
  180. */
  181. #define list_clear(l) do { \
  182. (l).size = 0; \
  183. } while (0)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement