ArrayList.c 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. #define ArrayList_NOCREATE
  16. #include "util/ArrayList.h"
  17. #include "util/Bits.h"
  18. #include "util/QSort.h"
  19. #include <stddef.h>
  20. #include <stdlib.h>
  21. struct ArrayList_pvt
  22. {
  23. /** AckTung: The fields in ArrayList.h (struct ArrayList_NAME) must be reflected here first. */
  24. int length;
  25. int capacity;
  26. void** elements;
  27. struct Allocator* alloc;
  28. Identity
  29. };
  30. void* ArrayList_new(struct Allocator* alloc, int initialCapacity)
  31. {
  32. struct ArrayList_pvt* l = Allocator_calloc(alloc, sizeof(struct ArrayList_pvt), 1);
  33. l->elements = Allocator_calloc(alloc, sizeof(char*), initialCapacity);
  34. l->capacity = initialCapacity;
  35. l->alloc = alloc;
  36. Identity_set(l);
  37. return l;
  38. }
  39. void* ArrayList_get(struct ArrayList* vlist, int number)
  40. {
  41. struct ArrayList_pvt* list = Identity_check((struct ArrayList_pvt*) vlist);
  42. if (number >= list->length || number < 0) { return NULL; }
  43. return list->elements[number];
  44. }
  45. void* ArrayList_remove(struct ArrayList* vlist, int number)
  46. {
  47. struct ArrayList_pvt* list = Identity_check((struct ArrayList_pvt*) vlist);
  48. if (number >= list->length) { return NULL; }
  49. void* out = list->elements[number];
  50. if (number < list->length - 1) {
  51. Bits_memmove(&list->elements[number],
  52. &list->elements[number+1],
  53. sizeof(char*) * (list->length - number - 1));
  54. }
  55. list->length--;
  56. return out;
  57. }
  58. int ArrayList_put(struct ArrayList* vlist, int number, void* val)
  59. {
  60. struct ArrayList_pvt* list = Identity_check((struct ArrayList_pvt*) vlist);
  61. Assert_true(number >= 0 && number <= list->length);
  62. if (number >= list->capacity) {
  63. int capacity = list->capacity * 2;
  64. list->elements = Allocator_realloc(list->alloc, list->elements, capacity * sizeof(char*));
  65. for (int i = list->capacity; i < capacity; i++) {
  66. list->elements[i] = NULL;
  67. }
  68. list->capacity = capacity;
  69. }
  70. list->elements[number] = val;
  71. if (number == list->length) { list->length++; }
  72. return number;
  73. }
  74. void ArrayList_sort(struct ArrayList* vlist, int (* compare)(const void* a, const void* b))
  75. {
  76. struct ArrayList_pvt* list = Identity_check((struct ArrayList_pvt*) vlist);
  77. QSort(list->elements, list->length, sizeof(char*), compare);
  78. }
  79. void* ArrayList_clone(struct ArrayList* vlist, struct Allocator* alloc)
  80. {
  81. struct ArrayList_pvt* list = Identity_check((struct ArrayList_pvt*) vlist);
  82. struct ArrayList_pvt* newlist = Allocator_clone(alloc, list);
  83. newlist->elements = Allocator_malloc(alloc, list->capacity * sizeof(char*));
  84. Bits_memcpy(newlist->elements, list->elements, list->capacity * sizeof(char*));
  85. newlist->alloc = alloc;
  86. return newlist;
  87. }