Advertisement
Guest User

Untitled

a guest
Aug 24th, 2019
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.99 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 = 0;\
  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.         memset(arr, 0, sizeof(NAME));\
  88.     }\
  89. \
  90.     int NAME##Resize(NAME *arr, size_t size){\
  91.         if(size <= arr->capacity){\
  92.             arr->size = size;\
  93.             return CUTILS_OK;\
  94.         }\
  95. \
  96.         TYPE *tmp = realloc(arr->data, sizeof(TYPE)*size);\
  97.         if(tmp == NULL){\
  98.             return CUTILS_NOMEM;\
  99.         }\
  100.         arr->data = tmp;\
  101.         arr->size = size;\
  102.         arr->capacity = size;\
  103.         return CUTILS_OK;\
  104.     }\
  105. \
  106.     int NAME##Reserve(NAME *arr, size_t capacity){\
  107.         TYPE *tmp = realloc(arr->data, sizeof(TYPE)*capacity);\
  108.         if(tmp == NULL){\
  109.             return CUTILS_NOMEM;\
  110.         }\
  111.         arr->data = tmp;\
  112.         arr->capacity = capacity;\
  113.         if(capacity < arr->size){\
  114.             arr->size = capacity;\
  115.         }\
  116.         return CUTILS_OK;\
  117.     }\
  118. \
  119.     int NAME##PushBack(NAME *arr, TYPE x){\
  120.         int err = NAME##Resize(arr, arr->size+1);\
  121.         if(err != CUTILS_OK){\
  122.             return err;\
  123.         }\
  124. \
  125.         arr->data[arr->size] = x;\
  126.         arr->size++;\
  127.         return CUTILS_OK;\
  128.     }\
  129.     int NAME##Insert(NAME *arr, TYPE x, size_t index){\
  130.         if(index > arr->size){\
  131.             return CUTILS_OUT_OF_BOUNDS;\
  132.         }\
  133. \
  134.         int err = NAME##Resize(arr, arr->size+1);\
  135.         if(err != CUTILS_OK){\
  136.             return err;\
  137.         }\
  138. \
  139.         /*this function can act the same as PushBack if index == arr->size*/\
  140.         if(index != arr->size){\
  141.             memmove(arr->data+index+1, arr->data+index, sizeof(TYPE)*(arr->size-index));\
  142.         }\
  143.         arr->data[index] = x;\
  144.         arr->size++;\
  145. \
  146.         return CUTILS_OK;\
  147.     }\
  148.     int NAME##InsertPtr(NAME *arr, TYPE *x, size_t len, size_t index){\
  149.         if(index > arr->size){\
  150.             return CUTILS_OUT_OF_BOUNDS;\
  151.         }\
  152. \
  153.         int err = NAME##Resize(arr, arr->size+len);\
  154.         if(err != CUTILS_OK){\
  155.             return err;\
  156.         }\
  157. \
  158.         if(index != arr->size){\
  159.             memmove(arr->data+index+len, arr->data+index, sizeof(TYPE)*(arr->size-index));\
  160.         }\
  161.         memcpy(arr->data+index, x, sizeof(TYPE)*len);\
  162.         arr->size += len;\
  163. \
  164.         return CUTILS_OK;\
  165.     }\
  166.     int NAME##InsertArr(NAME *arr, NAME *x, size_t index){\
  167.         if(index > arr->size){\
  168.             return CUTILS_OUT_OF_BOUNDS;\
  169.         }\
  170. \
  171.         int err = NAME##Resize(arr, arr->size+x->size);\
  172.         if(err != CUTILS_OK){\
  173.             return err;\
  174.         }\
  175. \
  176.         if(index != arr->size){\
  177.             memmove(arr->data+index+x->size, arr->data+index, sizeof(TYPE)*(arr->size-index));\
  178.         }\
  179.         memcpy(arr->data+index, x, sizeof(TYPE)*x->size);\
  180.         arr->size += x->size;\
  181. \
  182.         return CUTILS_OK;\
  183.     }\
  184.     int NAME##Delete(NAME *arr, size_t index){\
  185.         if(index >= arr->size){\
  186.             return CUTILS_OUT_OF_BOUNDS;\
  187.         }\
  188. \
  189.         memmove(arr->data+index, arr->data+index+1, sizeof(TYPE)*(arr->size-index-1));\
  190.         arr->size--;\
  191. \
  192.         return CUTILS_OK;\
  193.     }\
  194.     int NAME##DeleteRange(NAME *arr, size_t start, size_t end){\
  195.         if(start >= arr->size || end >= arr->size){\
  196.             return CUTILS_OUT_OF_BOUNDS;\
  197.         }\
  198. \
  199.         if(start == 0 && end == arr->size){\
  200.             NAME##Resize(arr, 0);\
  201.             return CUTILS_OK;\
  202.         }\
  203. \
  204.         memmove(arr->data+start, arr->data+end+1, sizeof(TYPE)*(arr->size-end-1));\
  205.         NAME##Resize(arr, arr->size-(end-start)-1);\
  206. \
  207.         return CUTILS_OK;\
  208.     }
  209.  
  210. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement