vector.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #ifndef AL_VECTOR_H
  2. #define AL_VECTOR_H
  3. #include <stdlib.h>
  4. #include <AL/al.h>
  5. /* "Base" vector type, designed to alias with the actual vector types. */
  6. typedef struct vector__s {
  7. size_t Capacity;
  8. size_t Size;
  9. } *vector_;
  10. #define TYPEDEF_VECTOR(T, N) typedef struct { \
  11. size_t Capacity; \
  12. size_t Size; \
  13. T Data[]; \
  14. } _##N; \
  15. typedef _##N* N; \
  16. typedef const _##N* const_##N;
  17. #define VECTOR(T) struct { \
  18. size_t Capacity; \
  19. size_t Size; \
  20. T Data[]; \
  21. }*
  22. #define VECTOR_INIT(_x) do { (_x) = NULL; } while(0)
  23. #define VECTOR_INIT_STATIC() NULL
  24. #define VECTOR_DEINIT(_x) do { free((_x)); (_x) = NULL; } while(0)
  25. /* Helper to increase a vector's reserve. Do not call directly. */
  26. ALboolean vector_reserve(char *ptr, size_t base_size, size_t obj_size, size_t obj_count, ALboolean exact);
  27. #define VECTOR_RESERVE(_x, _c) (vector_reserve((char*)&(_x), sizeof(*(_x)), sizeof((_x)->Data[0]), (_c), AL_TRUE))
  28. ALboolean vector_resize(char *ptr, size_t base_size, size_t obj_size, size_t obj_count);
  29. #define VECTOR_RESIZE(_x, _c) (vector_resize((char*)&(_x), sizeof(*(_x)), sizeof((_x)->Data[0]), (_c)))
  30. #define VECTOR_CAPACITY(_x) ((_x) ? (_x)->Capacity : 0)
  31. #define VECTOR_SIZE(_x) ((_x) ? (_x)->Size : 0)
  32. #define VECTOR_ITER_BEGIN(_x) ((_x) ? (_x)->Data + 0 : NULL)
  33. #define VECTOR_ITER_END(_x) ((_x) ? (_x)->Data + (_x)->Size : NULL)
  34. ALboolean vector_insert(char *ptr, size_t base_size, size_t obj_size, void *ins_pos, const void *datstart, const void *datend);
  35. #ifdef __GNUC__
  36. #define TYPE_CHECK(T1, T2) __builtin_types_compatible_p(T1, T2)
  37. #define VECTOR_INSERT(_x, _i, _s, _e) __extension__({ \
  38. ALboolean _r; \
  39. static_assert(TYPE_CHECK(__typeof((_x)->Data[0]), __typeof(*(_i))), "Incompatible insertion iterator"); \
  40. static_assert(TYPE_CHECK(__typeof((_x)->Data[0]), __typeof(*(_s))), "Incompatible insertion source type"); \
  41. static_assert(TYPE_CHECK(__typeof(*(_s)), __typeof(*(_e))), "Incompatible iterator sources"); \
  42. _r = vector_insert((char*)&(_x), sizeof(*(_x)), sizeof((_x)->Data[0]), (_i), (_s), (_e)); \
  43. _r; \
  44. })
  45. #else
  46. #define VECTOR_INSERT(_x, _i, _s, _e) (vector_insert((char*)&(_x), sizeof(*(_x)), sizeof((_x)->Data[0]), (_i), (_s), (_e)))
  47. #endif
  48. #define VECTOR_PUSH_BACK(_x, _obj) (vector_reserve((char*)&(_x), sizeof(*(_x)), sizeof((_x)->Data[0]), VECTOR_SIZE(_x)+1, AL_FALSE) && \
  49. (((_x)->Data[(_x)->Size++] = (_obj)),AL_TRUE))
  50. #define VECTOR_POP_BACK(_x) ((void)((_x)->Size--))
  51. #define VECTOR_BACK(_x) ((_x)->Data[(_x)->Size-1])
  52. #define VECTOR_FRONT(_x) ((_x)->Data[0])
  53. #define VECTOR_ELEM(_x, _o) ((_x)->Data[(_o)])
  54. #define VECTOR_FOR_EACH(_t, _x, _f) do { \
  55. _t *_iter = VECTOR_ITER_BEGIN((_x)); \
  56. _t *_end = VECTOR_ITER_END((_x)); \
  57. for(;_iter != _end;++_iter) \
  58. _f(_iter); \
  59. } while(0)
  60. #define VECTOR_FOR_EACH_PARAMS(_t, _x, _f, ...) do { \
  61. _t *_iter = VECTOR_ITER_BEGIN((_x)); \
  62. _t *_end = VECTOR_ITER_END((_x)); \
  63. for(;_iter != _end;++_iter) \
  64. _f(__VA_ARGS__, _iter); \
  65. } while(0)
  66. #define VECTOR_FIND_IF(_i, _t, _x, _f) do { \
  67. _t *_iter = VECTOR_ITER_BEGIN((_x)); \
  68. _t *_end = VECTOR_ITER_END((_x)); \
  69. for(;_iter != _end;++_iter) \
  70. { \
  71. if(_f(_iter)) \
  72. break; \
  73. } \
  74. (_i) = _iter; \
  75. } while(0)
  76. #define VECTOR_FIND_IF_PARMS(_i, _t, _x, _f, ...) do { \
  77. _t *_iter = VECTOR_ITER_BEGIN((_x)); \
  78. _t *_end = VECTOR_ITER_END((_x)); \
  79. for(;_iter != _end;++_iter) \
  80. { \
  81. if(_f(__VA_ARGS__, _iter)) \
  82. break; \
  83. } \
  84. (_i) = _iter; \
  85. } while(0)
  86. #endif /* AL_VECTOR_H */