Advertisement
Guest User

Untitled

a guest
Aug 24th, 2019
153
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.01 KB | None | 0 0
  1. #ifndef CUTILS_DYNARRAY_H
  2. #define CUTILS_DYNARRAY_H
  3.  
  4. #include <stddef.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7.  
  8. #include <stdint.h>
  9. #include <stdbool.h>
  10.  
  11. #include "errors.h"
  12.  
  13. #define CUTILS_DEF_DYNARRAY_H(TYPE, NAME)\
  14.     typedef struct NAME{\
  15.         TYPE *data;\
  16.         size_t size;\
  17.         size_t capacity;\
  18.     } NAME;\
  19. \
  20.     int NAME##Init(NAME *arr, size_t size);\
  21.     NAME* NAME##New(size_t size);\
  22.     int NAME##Copy(NAME *dst, NAME *src);\
  23.     void NAME##Move(NAME *dst, NAME *src);\
  24.     void NAME##Swap(NAME *a, NAME *b);\
  25.     void NAME##Free(NAME *arr);\
  26.     int NAME##Resize(NAME *arr, size_t size);\
  27.     int NAME##Reserve(NAME *arr, size_t capacity);\
  28.     int NAME##PushBack(NAME *arr, TYPE x);\
  29.     int NAME##Insert(NAME *arr, TYPE x, size_t index);\
  30.     int NAME##InsertPtr(NAME *arr, TYPE *x, size_t len, size_t index);\
  31.     int NAME##InsertArr(NAME *arr, NAME *x, size_t index);\
  32.     int NAME##Delete(NAME *arr, size_t index);\
  33.     int NAME##DeleteRange(NAME *arr, size_t start, size_t end);
  34.  
  35. #define CUTILS_DEF_DYNARRAY_C(TYPE, NAME)\
  36.     int NAME##Init(NAME *arr, size_t size){\
  37.         arr->data = malloc(sizeof(TYPE)*size);\
  38.         if(arr->data == NULL){\
  39.             return CUTILS_NOMEM;\
  40.         }\
  41.         arr->capacity = size;\
  42.         arr->size = size;\
  43. \
  44.         return CUTILS_OK;\
  45.     }\
  46. \
  47.     NAME* NAME##New(size_t size){\
  48.         NAME *ret = malloc(sizeof(NAME));\
  49.         if(ret == NULL){\
  50.             return NULL;\
  51.         }\
  52.         if(NAME##Init(ret, size) != CUTILS_OK){\
  53.             free(ret);\
  54.             return NULL;\
  55.         }\
  56.         return ret;\
  57.     }\
  58. \
  59.     int NAME##Copy(NAME *dst, NAME *src){\
  60.         /*allocate the memory first before we free, so that if we cant allocate old mem is not lost*/\
  61.         TYPE *tmp = malloc(sizeof(TYPE)*src->size);\
  62.         if(tmp == NULL){\
  63.             return CUTILS_NOMEM;\
  64.         }\
  65. \
  66.         dst->data = tmp;\
  67.         dst->size = src->size;\
  68.         dst->capacity = dst->size;\
  69.         memcpy(dst->data, src->data, sizeof(TYPE)*dst->size);\
  70. \
  71.         return CUTILS_OK;\
  72.     }\
  73. \
  74.     void NAME##Move(NAME *dst, NAME *src){\
  75.         *dst = *src;\
  76.         memset(src, 0, sizeof(NAME));\
  77.     }\
  78. \
  79.     void NAME##Swap(NAME *a, NAME *b){\
  80.         NAME tmp = *a;\
  81.         *a = *b;\
  82.         *b = tmp;\
  83.     }\
  84. \
  85.     void NAME##Free(NAME *arr){\
  86.         free(arr->data);\
  87.         arr->data = NULL;\
  88.         arr->size = arr->capacity = 0;\
  89.     }\
  90. \
  91.     int NAME##Resize(NAME *arr, size_t size){\
  92.         if(size <= arr->capacity){\
  93.             arr->size = size;\
  94.             return CUTILS_OK;\
  95.         }\
  96. \
  97.         TYPE *tmp = realloc(arr->data, sizeof(TYPE)*size);\
  98.         if(tmp == NULL){\
  99.             return CUTILS_NOMEM;\
  100.         }\
  101.         arr->data = tmp;\
  102.         arr->size = size;\
  103.         arr->capacity = size;\
  104.         return CUTILS_OK;\
  105.     }\
  106. \
  107.     int NAME##Reserve(NAME *arr, size_t capacity){\
  108.         TYPE *tmp = realloc(arr->data, sizeof(TYPE)*capacity);\
  109.         if(tmp == NULL){\
  110.             return CUTILS_NOMEM;\
  111.         }\
  112.         arr->data = tmp;\
  113.         arr->capacity = capacity;\
  114.         if(capacity < arr->size){\
  115.             arr->size = capacity;\
  116.         }\
  117.         return CUTILS_OK;\
  118.     }\
  119. \
  120.     int NAME##PushBack(NAME *arr, TYPE x){\
  121.         int err = NAME##Resize(arr, arr->size+1);\
  122.         if(err != CUTILS_OK){\
  123.             return err;\
  124.         }\
  125. \
  126.         arr->data[arr->size] = x;\
  127.         arr->size++;\
  128.         return CUTILS_OK;\
  129.     }\
  130.     int NAME##Insert(NAME *arr, TYPE x, size_t index){\
  131.         if(index > arr->size){\
  132.             return CUTILS_OUT_OF_BOUNDS;\
  133.         }\
  134. \
  135.         int err = NAME##Resize(arr, arr->size+1);\
  136.         if(err != CUTILS_OK){\
  137.             return err;\
  138.         }\
  139. \
  140.         /*this function can act the same as PushBack if index == arr->size*/\
  141.         if(index != arr->size){\
  142.             memmove(arr->data+index+1, arr->data+index, sizeof(TYPE)*(arr->size-index));\
  143.         }\
  144.         arr->data[index] = x;\
  145.         arr->size++;\
  146. \
  147.         return CUTILS_OK;\
  148.     }\
  149.     int NAME##InsertPtr(NAME *arr, TYPE *x, size_t len, size_t index){\
  150.         if(index > arr->size){\
  151.             return CUTILS_OUT_OF_BOUNDS;\
  152.         }\
  153. \
  154.         int err = NAME##Resize(arr, arr->size+len);\
  155.         if(err != CUTILS_OK){\
  156.             return err;\
  157.         }\
  158. \
  159.         if(index != arr->size){\
  160.             memmove(arr->data+index+len, arr->data+index, sizeof(TYPE)*(arr->size-index));\
  161.         }\
  162.         memcpy(arr->data+index, x, sizeof(TYPE)*len);\
  163.         arr->size += len;\
  164. \
  165.         return CUTILS_OK;\
  166.     }\
  167.     int NAME##InsertArr(NAME *arr, NAME *x, size_t index){\
  168.         if(index > arr->size){\
  169.             return CUTILS_OUT_OF_BOUNDS;\
  170.         }\
  171. \
  172.         int err = NAME##Resize(arr, arr->size+x->size);\
  173.         if(err != CUTILS_OK){\
  174.             return err;\
  175.         }\
  176. \
  177.         if(index != arr->size){\
  178.             memmove(arr->data+index+x->size, arr->data+index, sizeof(TYPE)*(arr->size-index));\
  179.         }\
  180.         memcpy(arr->data+index, x, sizeof(TYPE)*x->size);\
  181.         arr->size += x->size;\
  182. \
  183.         return CUTILS_OK;\
  184.     }\
  185.     int NAME##Delete(NAME *arr, size_t index){\
  186.         if(index >= arr->size){\
  187.             return CUTILS_OUT_OF_BOUNDS;\
  188.         }\
  189. \
  190.         memmove(arr->data+index, arr->data+index+1, sizeof(TYPE)*(arr->size-index-1));\
  191.         arr->size--;\
  192. \
  193.         return CUTILS_OK;\
  194.     }\
  195.     int NAME##DeleteRange(NAME *arr, size_t start, size_t end){\
  196.         if(start >= arr->size || end >= arr->size){\
  197.             return CUTILS_OUT_OF_BOUNDS;\
  198.         }\
  199. \
  200.         if(start == 0 && end == arr->size){\
  201.             NAME##Resize(arr, 0);\
  202.             return CUTILS_OK;\
  203.         }\
  204. \
  205.         memmove(arr->data+start, arr->data+end+1, sizeof(TYPE)*(arr->size-end-1));\
  206.         NAME##Resize(arr, arr->size-(end-start)-1);\
  207. \
  208.         return CUTILS_OK;\
  209.     }
  210.  
  211. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement