Advertisement
_vim_

vector.h

Dec 19th, 2019
247
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.26 KB | None | 0 0
  1. #ifndef VECTOR_H
  2. #define VECTOR_H
  3.  
  4. #include <stddef.h> /* size_t */
  5. #include <stdlib.h> /* malloc/realloc/free */
  6. #include <assert.h> /* assert */
  7. // #include <stdbool.h> /* bool */
  8.  
  9. // enum vector_type
  10. // {
  11. //  VECTOR_INT,
  12. //  VECTOR_FLOAT,
  13. //  VECTOR_BOOLEAN,
  14. //  VECTOR_STRING,
  15. // };
  16.  
  17. // typedef struct vector_value
  18. // {
  19. //  enum vector_type type;
  20.  
  21. //  union {
  22. //      int integer;
  23. //      float float_;
  24. //      char *string;
  25. //      bool boolean;
  26. //  } value;
  27. // } vector_value;
  28.  
  29. /**
  30.  * @brief vector_set_capacity - For internal use, sets the capacity variable of the vector
  31.  * @param vec - the vector
  32.  * @param size - the new capacity to set
  33.  * @return void
  34. */
  35. #define vector_set_capacity(vec, size)      \
  36.     do                                      \
  37.     {                                       \
  38.         if (vec)                            \
  39.             ((size_t *)(vec))[-1] = (size); \
  40.     } while (0)
  41.  
  42. /**
  43.  * @brief vector_set_size - For internal use, sets the size variable of the vector
  44.  * @param vec - the vector
  45.  * @param size - the new capacity to set
  46.  * @return void
  47. */
  48. #define vector_set_size(vec, size)          \
  49.     do                                      \
  50.     {                                       \
  51.         if (vec)                            \
  52.             ((size_t *)(vec))[-2] = (size); \
  53.     } while (0)
  54.  
  55. /**
  56.  * @brief vector_get_capacity - gets the current capacity of the vector
  57.  * @param vec - the vector
  58.  * @return the capacity as a size_t
  59. */
  60. #define vector_get_capacity(vec) ((vec) ? ((size_t *)(vec))[-1] : (size_t)0)
  61.  
  62. /**
  63.  * @brief vector_get_size - gets the current size of the vector
  64.  * @param vec - the vector
  65.  * @return the size as a size_t
  66. */
  67. #define vector_get_size(vec) ((vec) ? ((size_t *)(vec))[-2] : (size_t)0)
  68.  
  69. /**
  70.  * @brief vector_empty - returns non-zero if the vector is empty
  71.  * @param vec - the vector
  72.  * @return non-zero if empty, zero if non-empty
  73. */
  74. #define vector_empty(vec) (vector_get_size(vec) == (size_t)0)
  75.  
  76. /**
  77.  * @brief vector_grow - For internal use, ensures that the vector is at least <count> elements big
  78.  * @param vec - the vector
  79.  * @param size - the new capacity to set
  80.  * @return void
  81. */
  82. #define vector_grow(vec, count)                                                              \
  83.     do                                                                                       \
  84.     {                                                                                        \
  85.         if (!(vec))                                                                          \
  86.         {                                                                                    \
  87.             size_t *__p = malloc((count) * sizeof(*(vec)) + (sizeof(size_t) * 2));           \
  88.             assert(__p);                                                                     \
  89.             (vec) = (void *)(&__p[2]);                                                       \
  90.             vector_set_capacity((vec), (count));                                             \
  91.             vector_set_size((vec), 0);                                                       \
  92.         }                                                                                    \
  93.         else                                                                                 \
  94.         {                                                                                    \
  95.             size_t *__p1 = &((size_t *)(vec))[-2];                                           \
  96.             size_t *__p2 = realloc(__p1, ((count) * sizeof(*(vec)) + (sizeof(size_t) * 2))); \
  97.             assert(__p2);                                                                    \
  98.             (vec) = (void *)(&__p2[2]);                                                      \
  99.             vector_set_capacity((vec), (count));                                             \
  100.         }                                                                                    \
  101.     } while (0)
  102.  
  103. /**
  104.  * @brief vector_pop_back - removes the last element from the vector
  105.  * @param vec - the vector
  106.  * @return void
  107. */
  108. #define vector_pop_back(vec)                              \
  109.     do                                                    \
  110.     {                                                     \
  111.         vector_set_size((vec), vector_get_size(vec) - 1); \
  112.     } while (0)
  113.  
  114. /**
  115.  * @brief vector_erase - removes the element at index i from the vector
  116.  * @param vec - the vector
  117.  * @param i - index of element to remove
  118.  * @return void
  119. */
  120. #define vector_erase(vec, i)                             \
  121.     do                                                   \
  122.     {                                                    \
  123.         if (vec)                                         \
  124.         {                                                \
  125.             const size_t __sz = vector_get_size(vec);    \
  126.             if ((i) < __sz)                              \
  127.             {                                            \
  128.                 vector_set_size((vec), __sz - 1);        \
  129.                 size_t __x;                              \
  130.                 for (__x = (i); __x < (__sz - 1); ++__x) \
  131.                     (vec)[__x] = (vec)[__x + 1];         \
  132.             }                                            \
  133.         }                                                \
  134.     } while (0)
  135.  
  136. /**
  137.  * @brief vector_erase_range - removes a range of elements ([first, last]) not including last from the vector
  138.  * This reduces the vector's size by the number of elements removed, which are destroyed.
  139.  * @param vec - the vector
  140.  * @param first - start index
  141.  * @param last - end index
  142.  * @return void
  143. */
  144. #define vector_erase_range(vec, first, last)                               \
  145.     do                                                                     \
  146.     {                                                                      \
  147.         if (vec)                                                           \
  148.         {                                                                  \
  149.             size_t __sz = vector_get_size(vec);                            \
  150.             if (((first) < __sz) && ((first) < (last)) && ((last) < __sz)) \
  151.             {                                                              \
  152.                 size_t diff = ((last) - (first));                          \
  153.                 vector_set_size((vec), __sz -= diff);                      \
  154.                 size_t __i;                                                \
  155.                 for (__i = (first); __i < (__sz); ++__i)                   \
  156.                     (vec)[__i] = (vec)[((__i) + (diff))];                  \
  157.             }                                                              \
  158.         }                                                                  \
  159.     } while (0)
  160.  
  161. /**
  162.  * @brief vector_free - frees all memory associated with the vector
  163.  * @param vec - the vector
  164.  * @return void
  165. */
  166. #define vector_free(vec)                  \
  167.     do                                    \
  168.     {                                     \
  169.         if (vec)                          \
  170.             free(&((size_t *)(vec))[-2]); \
  171.     } while (0)
  172.  
  173. /**
  174.  * @brief vector_begin - returns an iterator to first element of the vector
  175.  * @param vec - the vector
  176.  * @return a pointer to the first element (or NULL)
  177. */
  178. #define vector_begin(vec) (vec)
  179.  
  180. /**
  181.  * @brief vector_end - returns an iterator to one past the last element of the vector
  182.  * @param vec - the vector
  183.  * @return a pointer to one past the last element (or NULL)
  184. */
  185. #define vector_end(vec) ((vec) ? &((vec)[vector_get_size(vec)]) : NULL)
  186.  
  187. /**
  188.  * @brief vector_push_back - adds an element to the end of the vector
  189.  * @param vec - the vector
  190.  * @param value - the value to add
  191.  * @return void
  192. */
  193.  
  194. #ifdef LOGARITHMIC_GROWTH
  195.  
  196. #define vector_push_back(vec, value)                            \
  197.     do                                                          \
  198.     {                                                           \
  199.         size_t __sz = vector_get_size(vec);                     \
  200.         size_t __cap = vector_get_capacity(vec);                \
  201.         if (__cap <= __sz)                                      \
  202.             vector_grow((vec), !__cap ? __cap + 1 : __cap * 2); \
  203.         vec[__sz] = (value);                                    \
  204.         vector_set_size((vec), __sz + 1);                       \
  205.     } while (0)
  206.  
  207. #else
  208.  
  209. #define vector_push_back(vec, value)             \
  210.     do                                           \
  211.     {                                            \
  212.         size_t __sz = vector_get_size(vec);      \
  213.         size_t __cap = vector_get_capacity(vec); \
  214.         if (__cap <= __sz)                       \
  215.             vector_grow((vec), __cap + 1);       \
  216.         vec[__sz] = (value);                     \
  217.         vector_set_size((vec), __sz + 1);        \
  218.     } while (0)
  219.  
  220. #endif
  221.  
  222. /**
  223.  * @brief vector_insert - adds the element <value> before the one at <pos> to the vector
  224.  * @param vec - the vector
  225.  * @param pos - position in the vector where the new element is inserted
  226.  * @param value - the value to add
  227.  * @return void
  228. */
  229. #define vector_insert(vec, pos, value)           \
  230.     do                                           \
  231.     {                                            \
  232.         size_t __sz = vector_get_size(vec);      \
  233.         size_t __cap = vector_get_capacity(vec); \
  234.         if (__cap <= __sz)                       \
  235.             vector_grow((vec), __cap + 1);       \
  236.         vector_set_size((vec), __sz + 1);        \
  237.         size_t __i;                              \
  238.         for (__i = __sz; __i >= (pos); --__i)    \
  239.             (vec)[__i] = (vec)[__i - 1];         \
  240.         (vec)[(pos)] = (value);                  \
  241.     } while (0)
  242.  
  243. #endif
  244.  
  245. // #define vector_get_elem(vec, i) ((vec) ? (vec)[i] : (NULL))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement