Skip to content

Commit eee5876

Browse files
Added more libs
1 parent c4b0c09 commit eee5876

13 files changed

+7746
-0
lines changed

array.h

+315
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,315 @@
1+
/*
2+
------------------------------------------------------------------------------
3+
Licensing information can be found at the end of the file.
4+
------------------------------------------------------------------------------
5+
6+
array.h - v0.1 - Dynamic array library for C/C++.
7+
8+
Do this:
9+
#define ARRAY_IMPLEMENTATION
10+
before you include this file in *one* C/C++ file to create the implementation.
11+
*/
12+
13+
#ifndef array_h
14+
#define array_h
15+
16+
#ifndef ARRAY_BOOL_T
17+
#define _CRT_NONSTDC_NO_DEPRECATE
18+
#define _CRT_SECURE_NO_WARNINGS
19+
#include <stdbool.h>
20+
#define ARRAY_BOOL_T bool
21+
#endif
22+
23+
#define array_t( type ) struct { int count; type* items; }
24+
#define array_param_t( type ) void
25+
#define array_create( type ) ARRAY_CAST( (void*)internal_array_create( sizeof( type ), NULL ) )
26+
#define array_create_memctx( type, memctx ) ARRAY_CAST( (void*)internal_array_create( sizeof( type ), (memctx) ) )
27+
#define array_destroy( array ) internal_array_destroy( (struct internal_array_t*) (array) )
28+
#define array_add( array, item ) ARRAY_CAST( internal_array_add( (struct internal_array_t*) (array), (void*) (item) ) )
29+
#define array_remove( array, index ) internal_array_remove( (struct internal_array_t*) (array), (index) )
30+
#define array_remove_ordered( array, index ) internal_array_remove_ordered( (struct internal_array_t*) (array), (index) )
31+
#define array_get( array, index, item ) internal_array_get( (struct internal_array_t*) (array), (index), (void*) (item) )
32+
#define array_set( array, index, item ) internal_array_set( (struct internal_array_t*) (array), (index), (void*) (item) )
33+
#define array_count( array ) internal_array_count( (struct internal_array_t*) (array) )
34+
#define array_sort( array, compare ) internal_array_sort( (struct internal_array_t*) (array), (compare) )
35+
#define array_bsearch( array, key, compare ) internal_array_bsearch( (struct internal_array_t*) (array), (void*) (key), (compare) )
36+
#define array_find( array, item ) internal_array_find( (struct internal_array_t*) (array), (void*) (item) )
37+
#define array_item( array, index ) ARRAY_CAST( internal_array_item( (struct internal_array_t*) (array), (index) ) )
38+
39+
40+
// In C, a void* can be implicitly cast to any other kind of pointer, while in C++ you need an explicit cast. In most
41+
// cases, the explicit cast works for both C and C++, but if we consider the case where we have nested structs, then
42+
// the way you refer to them differs between C and C++ (in C++, `parent_type::nested_type`, in C just `nested_type`).
43+
// In addition, with the automatic cast in C, it is possible to use unnamed nested structs and still dynamically
44+
// allocate arrays of that type - this would be desirable when the code is compiled from C++ as well.
45+
// This VOID_CAST macro allows for automatic cast from void* in C++. In C, it does nothing, but for C++ it uses a
46+
// simple template function to define a cast-to-anything operator.
47+
// Use like this:
48+
// struct {
49+
// struct {
50+
// int x;
51+
// } *nested;
52+
// } parent;
53+
// parent.nested = VOID_CAST( malloc( sizeof( *parent.nested ) * count ) );
54+
//
55+
#ifndef ARRAY_CAST
56+
#ifdef __cplusplus
57+
struct array_cast {
58+
inline array_cast( void* x_ ) : x( x_ ) { }
59+
inline array_cast( void const* x_ ) : x( (void*) x_ ) { }
60+
template< typename T > inline operator T() { return (T)x; } // cast to whatever requested
61+
void* x;
62+
};
63+
#define ARRAY_CAST( x ) array_cast( x )
64+
#else
65+
#define ARRAY_CAST( x ) x
66+
#endif
67+
#endif
68+
69+
70+
struct internal_array_t;
71+
72+
struct internal_array_t* internal_array_create( int item_size, void* memctx );
73+
void internal_array_destroy( struct internal_array_t* array );
74+
void* internal_array_add( struct internal_array_t* array, void* item );
75+
void internal_array_remove( struct internal_array_t* array, int index );
76+
void internal_array_remove_ordered( struct internal_array_t* array, int index );
77+
ARRAY_BOOL_T internal_array_get( struct internal_array_t* array, int index, void* item );
78+
ARRAY_BOOL_T internal_array_set( struct internal_array_t* array, int index, void const* item );
79+
int internal_array_count( struct internal_array_t* array );
80+
void internal_array_sort( struct internal_array_t* array, int (*compare)( void const*, void const* ) );
81+
int internal_array_bsearch( struct internal_array_t* array, void* key, int (*compare)( void const*, void const* ) );
82+
int internal_array_find( struct internal_array_t* array, void* item );
83+
void* internal_array_item( struct internal_array_t* array, int index );
84+
85+
#endif /* array_h */
86+
87+
88+
/*
89+
----------------------
90+
IMPLEMENTATION
91+
----------------------
92+
*/
93+
94+
#ifdef ARRAY_IMPLEMENTATION
95+
#undef ARRAY_IMPLEMENTATION
96+
97+
98+
#ifndef ARRAY_MALLOC
99+
#define _CRT_NONSTDC_NO_DEPRECATE
100+
#define _CRT_SECURE_NO_WARNINGS
101+
#include <stdlib.h>
102+
#define ARRAY_MALLOC( ctx, size ) ( malloc( size ) )
103+
#define ARRAY_FREE( ctx, ptr ) ( free( ptr ) )
104+
#endif
105+
106+
#ifndef ARRAY_MEMCPY
107+
#define _CRT_NONSTDC_NO_DEPRECATE
108+
#define _CRT_SECURE_NO_WARNINGS
109+
#include <string.h>
110+
#define ARRAY_MEMCPY( dst, src, cnt ) ( memcpy( (dst), (src), (cnt) ) )
111+
#endif
112+
113+
#ifndef ARRAY_MEMMOVE
114+
#define _CRT_NONSTDC_NO_DEPRECATE
115+
#define _CRT_SECURE_NO_WARNINGS
116+
#include <string.h>
117+
#define ARRAY_MEMMOVE( dst, src, cnt ) ( memcpy( (dst), (src), (cnt) ) )
118+
#endif
119+
120+
#ifndef ARRAY_MEMCMP
121+
#define _CRT_NONSTDC_NO_DEPRECATE
122+
#define _CRT_SECURE_NO_WARNINGS
123+
#include <string.h>
124+
#define ARRAY_MEMCMP( a, b, cnt ) ( memcmp( (a), (b), (cnt) ) )
125+
#endif
126+
127+
#ifndef ARRAY_QSORT
128+
#define _CRT_NONSTDC_NO_DEPRECATE
129+
#define _CRT_SECURE_NO_WARNINGS
130+
#include <stdlib.h>
131+
#define ARRAY_QSORT( base, num, size, cmp ) ( qsort( (base), (num), (size), (cmp) ) )
132+
#endif
133+
134+
#ifndef ARRAY_BSEARCH
135+
#define _CRT_NONSTDC_NO_DEPRECATE
136+
#define _CRT_SECURE_NO_WARNINGS
137+
#include <stdlib.h>
138+
#define ARRAY_BSEARCH( key, base, num, size, cmp ) ( bsearch( (key), (base), (num), (size), (cmp) ) )
139+
#endif
140+
141+
142+
struct internal_array_t {
143+
int count;
144+
void* items;
145+
void* memctx;
146+
int item_size;
147+
int capacity;
148+
};
149+
150+
151+
struct internal_array_t* internal_array_create( int item_size, void* memctx ) {
152+
struct internal_array_t* array = (struct internal_array_t*) ARRAY_MALLOC( memctx, sizeof( struct internal_array_t ) );
153+
array->memctx = memctx;
154+
array->item_size = item_size;
155+
array->capacity = 256;
156+
array->count = 0;
157+
array->items = ARRAY_MALLOC( memctx, (size_t) array->capacity * item_size );
158+
return array;
159+
}
160+
161+
162+
void internal_array_destroy( struct internal_array_t* array ) {
163+
ARRAY_FREE( array->memctx, array->items );
164+
ARRAY_FREE( array->memctx, array );
165+
}
166+
167+
168+
void* internal_array_add( struct internal_array_t* array, void* item ) {
169+
if( array->count >= array->capacity ) {
170+
array->capacity *= 2;
171+
void* items = array->items;
172+
array->items = ARRAY_MALLOC( array->memctx, (size_t) array->capacity * array->item_size );
173+
ARRAY_MEMCPY( array->items, items, (size_t)array->count * array->item_size );
174+
ARRAY_FREE( array->memctx, items );
175+
}
176+
ARRAY_MEMCPY( (void*)( ( (uintptr_t) array->items ) + array->count * array->item_size ), item,
177+
(size_t)array->item_size );
178+
++array->count;
179+
return (void*)( ( (uintptr_t) array->items ) + ( array->count - 1 ) * array->item_size );
180+
}
181+
182+
183+
void internal_array_remove( struct internal_array_t* array, int index ) {
184+
if( index >= 0 && index < array->count ) {
185+
--array->count;
186+
ARRAY_MEMMOVE( (void*)( ( (uintptr_t) array->items ) + index * array->item_size ),
187+
(void*)( ( (uintptr_t) array->items ) + array->count * array->item_size ), (size_t) array->item_size );
188+
}
189+
}
190+
191+
void internal_array_remove_ordered( struct internal_array_t* array, int index ) {
192+
if( index >= 0 && index < array->count ) {
193+
--array->count;
194+
ARRAY_MEMMOVE( (void*)( ( (uintptr_t) array->items ) + index * array->item_size ),
195+
(void*)( ( (uintptr_t) array->items ) + ( index + 1 ) * array->item_size ),
196+
(size_t)array->item_size * ( array->count - index ) );
197+
}
198+
}
199+
200+
ARRAY_BOOL_T internal_array_get( struct internal_array_t* array, int index, void* item ) {
201+
ARRAY_BOOL_T result = index >= 0 && index < array->count;
202+
if( result ) {
203+
ARRAY_MEMCPY( item, (void*)( ( (uintptr_t) array->items ) + index * array->item_size ),
204+
(size_t) array->item_size );
205+
}
206+
return result;
207+
}
208+
209+
ARRAY_BOOL_T internal_array_set( struct internal_array_t* array, int index, void const* item ) {
210+
ARRAY_BOOL_T result = index >= 0 && index < array->count;
211+
if( result ) {
212+
ARRAY_MEMCPY( (void*)( ( (uintptr_t) array->items ) + index * array->item_size ), item,
213+
(size_t) array->item_size );
214+
}
215+
return result;
216+
}
217+
218+
int internal_array_count( struct internal_array_t* array ) {
219+
int count = array->count;
220+
return count;
221+
}
222+
223+
224+
void internal_array_sort( struct internal_array_t* array, int (*compare)( void const*, void const* ) ) {
225+
ARRAY_QSORT( array->items, (size_t) array->count, (size_t) array->item_size, compare );
226+
}
227+
228+
229+
int internal_array_bsearch( struct internal_array_t* array, void* key, int (*compare)( void const*, void const* ) ) {
230+
void* item = ARRAY_BSEARCH( key, array->items, (size_t) array->count, (size_t) array->item_size, compare );
231+
int result = -1;
232+
if( item ) {
233+
result = (int)( ( ((uintptr_t)item) - ((uintptr_t)array->items) ) / array->item_size );
234+
}
235+
return result;
236+
}
237+
238+
239+
int internal_array_find( struct internal_array_t* array, void* item ) {
240+
for( int i = 0; i < array->count; ++i ) {
241+
if( ARRAY_MEMCMP( (void*)( ( (uintptr_t) array->items ) + i * array->item_size ), item,
242+
(size_t) array->item_size) == 0 ) {
243+
244+
return i;
245+
}
246+
}
247+
return -1;
248+
}
249+
250+
251+
void* internal_array_item( struct internal_array_t* array, int index ) {
252+
if( index >= 0 && index < array->count ) {
253+
return (void*)( ( (uintptr_t) array->items ) + index * array->item_size );
254+
} else {
255+
return NULL;
256+
}
257+
}
258+
259+
#endif /* ARRAY_IMPLEMENTATION */
260+
261+
/*
262+
------------------------------------------------------------------------------
263+
264+
This software is available under 2 licenses - you may choose the one you like.
265+
266+
------------------------------------------------------------------------------
267+
268+
ALTERNATIVE A - MIT License
269+
270+
Copyright (c) 2022 Mattias Gustavsson
271+
272+
Permission is hereby granted, free of charge, to any person obtaining a copy of
273+
this software and associated documentation files (the "Software"), to deal in
274+
the Software without restriction, including without limitation the rights to
275+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
276+
of the Software, and to permit persons to whom the Software is furnished to do
277+
so, subject to the following conditions:
278+
279+
The above copyright notice and this permission notice shall be included in all
280+
copies or substantial portions of the Software.
281+
282+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
283+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
284+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
285+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
286+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
287+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
288+
SOFTWARE.
289+
290+
------------------------------------------------------------------------------
291+
292+
ALTERNATIVE B - Public Domain (www.unlicense.org)
293+
294+
This is free and unencumbered software released into the public domain.
295+
296+
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
297+
software, either in source code form or as a compiled binary, for any purpose,
298+
commercial or non-commercial, and by any means.
299+
300+
In jurisdictions that recognize copyright laws, the author or authors of this
301+
software dedicate any and all copyright interest in the software to the public
302+
domain. We make this dedication for the benefit of the public at large and to
303+
the detriment of our heirs and successors. We intend this dedication to be an
304+
overt act of relinquishment in perpetuity of all present and future rights to
305+
this software under copyright law.
306+
307+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
308+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
309+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
310+
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
311+
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
312+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
313+
314+
------------------------------------------------------------------------------
315+
*/

0 commit comments

Comments
 (0)