vector.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. #pragma once
  2. #include <string.h>
  3. #include <stdbool.h>
  4. #include "pocketpy/common/algorithm.h"
  5. typedef struct c11_vector {
  6. void* data;
  7. int length;
  8. int capacity;
  9. int elem_size;
  10. } c11_vector;
  11. void c11_vector__ctor(c11_vector* self, int elem_size);
  12. void c11_vector__dtor(c11_vector* self);
  13. c11_vector c11_vector__copy(const c11_vector* self);
  14. void c11_vector__reserve(c11_vector* self, int capacity);
  15. void c11_vector__clear(c11_vector* self);
  16. void* c11_vector__emplace(c11_vector* self);
  17. bool c11_vector__contains(const c11_vector* self, void* elem);
  18. void* c11_vector__submit(c11_vector* self, int* length);
  19. void c11_vector__swap(c11_vector* self, c11_vector* other);
  20. int c11_vector__nextcap(c11_vector* self);
  21. void c11_vector__extend(c11_vector* self, const void* p, int size);
  22. #define c11__getitem(T, self, index) (((T*)(self)->data)[index])
  23. #define c11__setitem(T, self, index, value) ((T*)(self)->data)[index] = value;
  24. #define c11__at(T, self, index) ((T*)(self)->data + index)
  25. #define c11_vector__push(T, self, elem) \
  26. do { \
  27. if((self)->length == (self)->capacity) { \
  28. c11_vector__reserve((self), c11_vector__nextcap((self))); \
  29. } \
  30. ((T*)(self)->data)[(self)->length] = (elem); \
  31. (self)->length++; \
  32. } while(0)
  33. #define c11_vector__pop(self) (--(self)->length)
  34. #define c11_vector__back(T, self) (((T*)(self)->data)[(self)->length - 1])
  35. #define c11_vector__insert(T, self, index, elem) \
  36. do { \
  37. if((self)->length == (self)->capacity) { \
  38. c11_vector__reserve((self), c11_vector__nextcap(self)); \
  39. } \
  40. T* p = (T*)(self)->data + (index); \
  41. memmove(p + 1, p, ((self)->length - (index)) * sizeof(T)); \
  42. *p = (elem); \
  43. (self)->length++; \
  44. } while(0)
  45. #define c11_vector__erase(T, self, index) \
  46. do { \
  47. T* p = (T*)(self)->data + (index); \
  48. memmove(p, p + 1, ((self)->length - (index)-1) * sizeof(T)); \
  49. (self)->length--; \
  50. } while(0)
  51. #define c11__reverse(T, self) \
  52. do { \
  53. if(!self->data) break; \
  54. T* p = (T*)(self)->data; \
  55. T* q = (T*)(self)->data + (self)->length - 1; \
  56. while(p < q) { \
  57. T tmp = *p; \
  58. *p = *q; \
  59. *q = tmp; \
  60. p++; \
  61. q--; \
  62. } \
  63. } while(0)
  64. // NOTE: here we do an extra NULL check for it to avoid UB
  65. #define c11__foreach(T, self, it) \
  66. for(T* it = (self)->data; it && it != (T*)(self)->data + (self)->length; it++)