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_ */