vector.h 4.9 KB

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