smallmap.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #if !defined(SMALLMAP_T__HEADER) && !defined(SMALLMAP_T__SOURCE)
  2. #include "pocketpy/common/vector.h"
  3. #define SMALLMAP_T__HEADER
  4. #define SMALLMAP_T__SOURCE
  5. /* Input */
  6. #define K int
  7. #define V float
  8. #define NAME c11_smallmap_i2f
  9. #endif
  10. /* Optional Input */
  11. #ifndef less
  12. #define less(a, b) ((a) < (b))
  13. #endif
  14. #ifndef equal
  15. #define equal(a, b) ((a) == (b))
  16. #endif
  17. /* Temprary macros */
  18. #define partial_less(a, b) less((a).key, (b))
  19. #define CONCAT(A, B) CONCAT_(A, B)
  20. #define CONCAT_(A, B) A##B
  21. #define KV CONCAT(NAME, _KV)
  22. #define METHOD(name) CONCAT(NAME, CONCAT(__, name))
  23. #ifdef SMALLMAP_T__HEADER
  24. /* Declaration */
  25. typedef struct {
  26. K key;
  27. V value;
  28. } KV;
  29. typedef c11_vector NAME;
  30. void METHOD(ctor)(NAME* self);
  31. void METHOD(dtor)(NAME* self);
  32. NAME* METHOD(new)();
  33. void METHOD(delete)(NAME* self);
  34. void METHOD(set)(NAME* self, K key, V value);
  35. V* METHOD(try_get)(const NAME* self, K key);
  36. V METHOD(get)(const NAME* self, K key, V default_value);
  37. bool METHOD(contains)(const NAME* self, K key);
  38. bool METHOD(del)(NAME* self, K key);
  39. void METHOD(clear)(NAME* self);
  40. #endif
  41. #ifdef SMALLMAP_T__SOURCE
  42. /* Implementation */
  43. void METHOD(ctor)(NAME* self) {
  44. c11_vector__ctor(self, sizeof(KV));
  45. c11_vector__reserve(self, 4);
  46. }
  47. void METHOD(dtor)(NAME* self) {
  48. c11_vector__dtor(self);
  49. }
  50. NAME* METHOD(new)() {
  51. NAME* self = malloc(sizeof(NAME));
  52. METHOD(ctor)(self);
  53. return self;
  54. }
  55. void METHOD(delete)(NAME* self) {
  56. METHOD(dtor)(self);
  57. free(self);
  58. }
  59. void METHOD(set)(NAME* self, K key, V value) {
  60. int index;
  61. c11__lower_bound(KV, self->data, self->count, key, partial_less, &index);
  62. KV* it = c11__at(KV, self, index);
  63. if(index != self->count && equal(it->key, key)) {
  64. it->value = value;
  65. } else {
  66. KV kv = {key, value};
  67. c11_vector__insert(KV, self, index, kv);
  68. }
  69. }
  70. V* METHOD(try_get)(const NAME* self, K key) {
  71. // use `bsearch` which is faster than `lower_bound`
  72. int low = 0;
  73. int high = self->count - 1;
  74. KV* a = self->data;
  75. while(low <= high){
  76. int mid = (low + high) / 2;
  77. if(equal(a[mid].key, key)){
  78. return &a[mid].value;
  79. } else if(less(a[mid].key, key)){
  80. low = mid + 1;
  81. } else {
  82. high = mid - 1;
  83. }
  84. }
  85. return NULL;
  86. }
  87. V METHOD(get)(const NAME* self, K key, V default_value) {
  88. V* p = METHOD(try_get)(self, key);
  89. return p ? *p : default_value;
  90. }
  91. bool METHOD(contains)(const NAME* self, K key) {
  92. return METHOD(try_get)(self, key) != NULL;
  93. }
  94. bool METHOD(del)(NAME* self, K key) {
  95. int index;
  96. c11__lower_bound(KV, self->data, self->count, key, partial_less, &index);
  97. KV* it = c11__at(KV, self, index);
  98. if(index != self->count && equal(it->key, key)) {
  99. c11_vector__erase(KV, self, index);
  100. return true;
  101. }
  102. return false;
  103. }
  104. void METHOD(clear)(NAME* self) {
  105. c11_vector__clear(self);
  106. }
  107. #endif
  108. /* Undefine all macros */
  109. #undef KV
  110. #undef METHOD
  111. #undef CONCAT
  112. #undef CONCAT_
  113. #undef K
  114. #undef V
  115. #undef NAME
  116. #undef less
  117. #undef partial_less
  118. #undef equal