URI: 
       array.h - ltkx - GUI toolkit for X11 (old)
  HTML git clone git://lumidify.org/ltkx.git (fast, but not encrypted)
  HTML git clone https://lumidify.org/ltkx.git (encrypted, but very slow)
  HTML git clone git://4kcetb7mo7hj6grozzybxtotsub5bempzo4lirzc3437amof2c2impyd.onion/ltkx.git (over tor)
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       array.h (5528B)
       ---
            1 /*
            2  * This file is part of the Lumidify ToolKit (LTK)
            3  * Copyright (c) 2020 lumidify <nobody@lumidify.org>
            4  *
            5  * Permission is hereby granted, free of charge, to any person obtaining a copy
            6  * of this software and associated documentation files (the "Software"), to deal
            7  * in the Software without restriction, including without limitation the rights
            8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
            9  * copies of the Software, and to permit persons to whom the Software is
           10  * furnished to do so, subject to the following conditions:
           11  *
           12  * The above copyright notice and this permission notice shall be included in all
           13  * copies or substantial portions of the Software.
           14  *
           15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
           16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
           17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
           18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
           19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
           20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
           21  * SOFTWARE.
           22  */
           23 
           24 #ifndef _LTK_ARRAY_H_
           25 #define _LTK_ARRAY_H_
           26 
           27 #include <stdio.h>
           28 #include <stdlib.h>
           29 
           30 #define LTK_ARRAY_INIT_DECL(name, type)                                                        \
           31 struct ltk_array_##name {                                                                \
           32         type *buf;                                                                        \
           33         size_t buf_size;                                                                \
           34         size_t len;                                                                        \
           35 };                                                                                        \
           36                                                                                         \
           37 struct ltk_array_##name *ltk_array_create_##name(size_t initial_len);                        \
           38 type ltk_array_pop_##name(struct ltk_array_##name *ar);                                        \
           39 void ltk_array_prepare_gap_##name(                                                        \
           40     struct ltk_array_##name *ar, size_t index, size_t len);                                \
           41 void ltk_array_insert_##name(struct ltk_array_##name *ar, size_t index,                        \
           42     type *elem, size_t len);                                                                \
           43 void ltk_array_resize_##name(struct ltk_array_##name *ar, size_t size);                        \
           44 void ltk_array_destroy_##name(struct ltk_array_##name *ar);                                \
           45 void ltk_array_clear_##name(struct ltk_array_##name *ar);                                \
           46 void ltk_array_append_##name(struct ltk_array_##name *ar, type elem);                        \
           47 void ltk_array_destroy_deep_##name(struct ltk_array_##name *ar,                                \
           48     void (*destroy_func)(type));
           49 
           50 #define LTK_ARRAY_INIT_IMPL(name, type)                                                        \
           51 struct ltk_array_##name *                                                                \
           52 ltk_array_create_##name(size_t initial_len) {                                                \
           53         if (initial_len == 0) {                                                                \
           54                 (void)fprintf(stderr, "Array length is zero\n");                        \
           55                 exit(1);                                                                \
           56         }                                                                                \
           57         struct ltk_array_##name *ar = malloc(sizeof(struct ltk_array_##name));                \
           58         if (!ar) goto error;                                                                \
           59         ar->buf = malloc(initial_len * sizeof(type));                                        \
           60         if (!ar->buf) goto error;                                                        \
           61         ar->buf_size = initial_len;                                                        \
           62         ar->len = 0;                                                                        \
           63         return ar;                                                                        \
           64 error:                                                                                        \
           65         (void)fprintf(stderr, "Out of memory while trying to allocate array\n");        \
           66         exit(1);                                                                        \
           67 }                                                                                        \
           68                                                                                         \
           69 type                                                                                        \
           70 ltk_array_pop_##name(struct ltk_array_##name *ar) {                                        \
           71         if (ar->len == 0) {                                                                \
           72                 (void)fprintf(stderr, "Array empty; cannot pop.\n");                        \
           73                 exit(1);                                                                \
           74         }                                                                                \
           75         ar->len--;                                                                        \
           76         return ar->buf[ar->len];                                                        \
           77 }                                                                                        \
           78                                                                                         \
           79 void                                                                                        \
           80 ltk_array_prepare_gap_##name(struct ltk_array_##name *ar, size_t index, size_t len) {        \
           81         if (index > ar->len) {                                                                \
           82                 (void)fprintf(stderr, "Array index out of bounds\n");                        \
           83                 exit(1);                                                                \
           84         }                                                                                \
           85         ltk_array_resize_##name(ar, ar->len + len);                                        \
           86         ar->len += len;                                                                        \
           87         if (ar->len - len == index)                                                        \
           88                 return;                                                                        \
           89         memmove(ar->buf + index + len, ar->buf + index,                                        \
           90             (ar->len - len - index) * sizeof(type));                                        \
           91 }                                                                                        \
           92                                                                                         \
           93 void                                                                                        \
           94 ltk_array_insert_##name(struct ltk_array_##name *ar, size_t index,                        \
           95     type *elem, size_t len) {                                                                \
           96         ltk_array_prepare_gap_##name(ar, index, len);                                        \
           97         /*ltk_array_resize_##name(ar, ar->len + len);*/                                        \
           98         for (int i = 0; i < len; i++) {                                                        \
           99                 ar->buf[index + i] = elem[i];                                                \
          100         }                                                                                \
          101 }                                                                                        \
          102                                                                                         \
          103 void                                                                                        \
          104 ltk_array_append_##name(struct ltk_array_##name *ar, type elem) {                        \
          105         if (ar->len == ar->buf_size)                                                        \
          106                 ltk_array_resize_##name(ar, ar->len + 1);                                \
          107         ar->buf[ar->len] = elem;                                                        \
          108         ar->len++;                                                                        \
          109 }                                                                                        \
          110                                                                                         \
          111 void                                                                                        \
          112 ltk_array_clear_##name(struct ltk_array_##name *ar) {                                        \
          113         ar->len = 0;                                                                        \
          114         ltk_array_resize_##name(ar, 1);                                                        \
          115 }                                                                                        \
          116                                                                                         \
          117 void                                                                                        \
          118 ltk_array_resize_##name(struct ltk_array_##name *ar, size_t len) {                        \
          119         size_t new_size;                                                                \
          120         if (4 * len <= ar->buf_size) {                                                        \
          121                 new_size = 2 * len;                                                        \
          122         } else if (len > ar->buf_size) {                                                \
          123                 new_size = 2 * len;                                                        \
          124         } else {                                                                        \
          125                 return;                                                                        \
          126         }                                                                                \
          127         type *new = realloc(ar->buf, new_size * sizeof(type));                                \
          128         if (!new) {                                                                        \
          129                 (void)fprintf(stderr, "Cannot realloc array\n");                        \
          130                 exit(1);                                                                \
          131         }                                                                                \
          132         ar->buf = new;                                                                        \
          133         ar->buf_size = new_size;                                                        \
          134         ar->len = ar->len < new_size ? ar->len : new_size;                                \
          135 }                                                                                        \
          136                                                                                         \
          137 void                                                                                        \
          138 ltk_array_destroy_##name(struct ltk_array_##name *ar) {                                        \
          139         free(ar->buf);                                                                        \
          140         ar->buf = NULL;                                                                        \
          141         free(ar);                                                                        \
          142 }                                                                                        \
          143                                                                                         \
          144 void                                                                                        \
          145 ltk_array_destroy_deep_##name(struct ltk_array_##name *ar,                                \
          146     void (*destroy_func)(type)) {                                                        \
          147         for (int i = 0; i < ar->len; i++) {                                                \
          148                 destroy_func(ar->buf[i]);                                                \
          149         }                                                                                \
          150         ltk_array_destroy_##name(ar);                                                        \
          151 }
          152 
          153 #endif /* _LTK_ARRAY_H_ */