ltkx

GUI toolkit for X11 (old)
git clone git://lumidify.org/ltkx.git (fast, but not encrypted)
git clone https://lumidify.org/ltkx.git (encrypted, but very slow)
git clone git://4kcetb7mo7hj6grozzybxtotsub5bempzo4lirzc3437amof2c2impyd.onion/ltkx.git (over tor)
Log | Files | Refs | README | 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_ */