]> gitweb.ps.run Git - chirp/blob - ext/stb_ds.h
add files
[chirp] / ext / stb_ds.h
1 /* stb_ds.h - v0.67 - public domain data structures - Sean Barrett 2019
2
3    This is a single-header-file library that provides easy-to-use
4    dynamic arrays and hash tables for C (also works in C++).
5
6    For a gentle introduction:
7       http://nothings.org/stb_ds
8
9    To use this library, do this in *one* C or C++ file:
10       #define STB_DS_IMPLEMENTATION
11       #include "stb_ds.h"
12
13 TABLE OF CONTENTS
14
15   Table of Contents
16   Compile-time options
17   License
18   Documentation
19   Notes
20   Notes - Dynamic arrays
21   Notes - Hash maps
22   Credits
23
24 COMPILE-TIME OPTIONS
25
26   #define STBDS_NO_SHORT_NAMES
27
28      This flag needs to be set globally.
29
30      By default stb_ds exposes shorter function names that are not qualified
31      with the "stbds_" prefix. If these names conflict with the names in your
32      code, define this flag.
33
34   #define STBDS_SIPHASH_2_4
35
36      This flag only needs to be set in the file containing #define STB_DS_IMPLEMENTATION.
37
38      By default stb_ds.h hashes using a weaker variant of SipHash and a custom hash for
39      4- and 8-byte keys. On 64-bit platforms, you can define the above flag to force
40      stb_ds.h to use specification-compliant SipHash-2-4 for all keys. Doing so makes
41      hash table insertion about 20% slower on 4- and 8-byte keys, 5% slower on
42      64-byte keys, and 10% slower on 256-byte keys on my test computer.
43
44   #define STBDS_REALLOC(context,ptr,size) better_realloc
45   #define STBDS_FREE(context,ptr)         better_free
46
47      These defines only need to be set in the file containing #define STB_DS_IMPLEMENTATION.
48
49      By default stb_ds uses stdlib realloc() and free() for memory management. You can
50      substitute your own functions instead by defining these symbols. You must either
51      define both, or neither. Note that at the moment, 'context' will always be NULL.
52      @TODO add an array/hash initialization function that takes a memory context pointer.
53
54   #define STBDS_UNIT_TESTS
55
56      Defines a function stbds_unit_tests() that checks the functioning of the data structures.
57
58   Note that on older versions of gcc (e.g. 5.x.x) you may need to build with '-std=c++0x'
59      (or equivalentally '-std=c++11') when using anonymous structures as seen on the web
60      page or in STBDS_UNIT_TESTS.
61
62 LICENSE
63
64   Placed in the public domain and also MIT licensed.
65   See end of file for detailed license information.
66
67 DOCUMENTATION
68
69   Dynamic Arrays
70
71     Non-function interface:
72
73       Declare an empty dynamic array of type T
74         T* foo = NULL;
75
76       Access the i'th item of a dynamic array 'foo' of type T, T* foo:
77         foo[i]
78
79     Functions (actually macros)
80
81       arrfree:
82         void arrfree(T*);
83           Frees the array.
84
85       arrlen:
86         ptrdiff_t arrlen(T*);
87           Returns the number of elements in the array.
88
89       arrlenu:
90         size_t arrlenu(T*);
91           Returns the number of elements in the array as an unsigned type.
92
93       arrpop:
94         T arrpop(T* a)
95           Removes the final element of the array and returns it.
96
97       arrput:
98         T arrput(T* a, T b);
99           Appends the item b to the end of array a. Returns b.
100
101       arrins:
102         T arrins(T* a, int p, T b);
103           Inserts the item b into the middle of array a, into a[p],
104           moving the rest of the array over. Returns b.
105
106       arrinsn:
107         void arrinsn(T* a, int p, int n);
108           Inserts n uninitialized items into array a starting at a[p],
109           moving the rest of the array over.
110
111       arraddnptr:
112         T* arraddnptr(T* a, int n)
113           Appends n uninitialized items onto array at the end.
114           Returns a pointer to the first uninitialized item added.
115
116       arraddnindex:
117         size_t arraddnindex(T* a, int n)
118           Appends n uninitialized items onto array at the end.
119           Returns the index of the first uninitialized item added.
120
121       arrdel:
122         void arrdel(T* a, int p);
123           Deletes the element at a[p], moving the rest of the array over.
124
125       arrdeln:
126         void arrdeln(T* a, int p, int n);
127           Deletes n elements starting at a[p], moving the rest of the array over.
128
129       arrdelswap:
130         void arrdelswap(T* a, int p);
131           Deletes the element at a[p], replacing it with the element from
132           the end of the array. O(1) performance.
133
134       arrsetlen:
135         void arrsetlen(T* a, int n);
136           Changes the length of the array to n. Allocates uninitialized
137           slots at the end if necessary.
138
139       arrsetcap:
140         size_t arrsetcap(T* a, int n);
141           Sets the length of allocated storage to at least n. It will not
142           change the length of the array.
143
144       arrcap:
145         size_t arrcap(T* a);
146           Returns the number of total elements the array can contain without
147           needing to be reallocated.
148
149   Hash maps & String hash maps
150
151     Given T is a structure type: struct { TK key; TV value; }. Note that some
152     functions do not require TV value and can have other fields. For string
153     hash maps, TK must be 'char *'.
154
155     Special interface:
156
157       stbds_rand_seed:
158         void stbds_rand_seed(size_t seed);
159           For security against adversarially chosen data, you should seed the
160           library with a strong random number. Or at least seed it with time().
161
162       stbds_hash_string:
163         size_t stbds_hash_string(char *str, size_t seed);
164           Returns a hash value for a string.
165
166       stbds_hash_bytes:
167         size_t stbds_hash_bytes(void *p, size_t len, size_t seed);
168           These functions hash an arbitrary number of bytes. The function
169           uses a custom hash for 4- and 8-byte data, and a weakened version
170           of SipHash for everything else. On 64-bit platforms you can get
171           specification-compliant SipHash-2-4 on all data by defining
172           STBDS_SIPHASH_2_4, at a significant cost in speed.
173
174     Non-function interface:
175
176       Declare an empty hash map of type T
177         T* foo = NULL;
178
179       Access the i'th entry in a hash table T* foo:
180         foo[i]
181
182     Function interface (actually macros):
183
184       hmfree
185       shfree
186         void hmfree(T*);
187         void shfree(T*);
188           Frees the hashmap and sets the pointer to NULL.
189
190       hmlen
191       shlen
192         ptrdiff_t hmlen(T*)
193         ptrdiff_t shlen(T*)
194           Returns the number of elements in the hashmap.
195
196       hmlenu
197       shlenu
198         size_t hmlenu(T*)
199         size_t shlenu(T*)
200           Returns the number of elements in the hashmap.
201
202       hmgeti
203       shgeti
204       hmgeti_ts
205         ptrdiff_t hmgeti(T*, TK key)
206         ptrdiff_t shgeti(T*, char* key)
207         ptrdiff_t hmgeti_ts(T*, TK key, ptrdiff_t tempvar)
208           Returns the index in the hashmap which has the key 'key', or -1
209           if the key is not present.
210
211       hmget
212       hmget_ts
213       shget
214         TV hmget(T*, TK key)
215         TV shget(T*, char* key)
216         TV hmget_ts(T*, TK key, ptrdiff_t tempvar)
217           Returns the value corresponding to 'key' in the hashmap.
218           The structure must have a 'value' field
219
220       hmgets
221       shgets
222         T hmgets(T*, TK key)
223         T shgets(T*, char* key)
224           Returns the structure corresponding to 'key' in the hashmap.
225
226       hmgetp
227       shgetp
228       hmgetp_ts
229       hmgetp_null
230       shgetp_null
231         T* hmgetp(T*, TK key)
232         T* shgetp(T*, char* key)
233         T* hmgetp_ts(T*, TK key, ptrdiff_t tempvar)
234         T* hmgetp_null(T*, TK key)
235         T* shgetp_null(T*, char *key)
236           Returns a pointer to the structure corresponding to 'key' in
237           the hashmap. Functions ending in "_null" return NULL if the key
238           is not present in the hashmap; the others return a pointer to a
239           structure holding the default value (but not the searched-for key).
240
241       hmdefault
242       shdefault
243         TV hmdefault(T*, TV value)
244         TV shdefault(T*, TV value)
245           Sets the default value for the hashmap, the value which will be
246           returned by hmget/shget if the key is not present.
247
248       hmdefaults
249       shdefaults
250         TV hmdefaults(T*, T item)
251         TV shdefaults(T*, T item)
252           Sets the default struct for the hashmap, the contents which will be
253           returned by hmgets/shgets if the key is not present.
254
255       hmput
256       shput
257         TV hmput(T*, TK key, TV value)
258         TV shput(T*, char* key, TV value)
259           Inserts a <key,value> pair into the hashmap. If the key is already
260           present in the hashmap, updates its value.
261
262       hmputs
263       shputs
264         T hmputs(T*, T item)
265         T shputs(T*, T item)
266           Inserts a struct with T.key into the hashmap. If the struct is already
267           present in the hashmap, updates it.
268
269       hmdel
270       shdel
271         int hmdel(T*, TK key)
272         int shdel(T*, char* key)
273           If 'key' is in the hashmap, deletes its entry and returns 1.
274           Otherwise returns 0.
275
276     Function interface (actually macros) for strings only:
277
278       sh_new_strdup
279         void sh_new_strdup(T*);
280           Overwrites the existing pointer with a newly allocated
281           string hashmap which will automatically allocate and free
282           each string key using realloc/free
283
284       sh_new_arena
285         void sh_new_arena(T*);
286           Overwrites the existing pointer with a newly allocated
287           string hashmap which will automatically allocate each string
288           key to a string arena. Every string key ever used by this
289           hash table remains in the arena until the arena is freed.
290           Additionally, any key which is deleted and reinserted will
291           be allocated multiple times in the string arena.
292
293 NOTES
294
295   * These data structures are realloc'd when they grow, and the macro
296     "functions" write to the provided pointer. This means: (a) the pointer
297     must be an lvalue, and (b) the pointer to the data structure is not
298     stable, and you must maintain it the same as you would a realloc'd
299     pointer. For example, if you pass a pointer to a dynamic array to a
300     function which updates it, the function must return back the new
301     pointer to the caller. This is the price of trying to do this in C.
302
303   * The following are the only functions that are thread-safe on a single data
304     structure, i.e. can be run in multiple threads simultaneously on the same
305     data structure
306         hmlen        shlen
307         hmlenu       shlenu
308         hmget_ts     shget_ts
309         hmgeti_ts    shgeti_ts
310         hmgets_ts    shgets_ts
311
312   * You iterate over the contents of a dynamic array and a hashmap in exactly
313     the same way, using arrlen/hmlen/shlen:
314
315       for (i=0; i < arrlen(foo); ++i)
316          ... foo[i] ...
317
318   * All operations except arrins/arrdel are O(1) amortized, but individual
319     operations can be slow, so these data structures may not be suitable
320     for real time use. Dynamic arrays double in capacity as needed, so
321     elements are copied an average of once. Hash tables double/halve
322     their size as needed, with appropriate hysteresis to maintain O(1)
323     performance.
324
325 NOTES - DYNAMIC ARRAY
326
327   * If you know how long a dynamic array is going to be in advance, you can avoid
328     extra memory allocations by using arrsetlen to allocate it to that length in
329     advance and use foo[n] while filling it out, or arrsetcap to allocate the memory
330     for that length and use arrput/arrpush as normal.
331
332   * Unlike some other versions of the dynamic array, this version should
333     be safe to use with strict-aliasing optimizations.
334
335 NOTES - HASH MAP
336
337   * For compilers other than GCC and clang (e.g. Visual Studio), for hmput/hmget/hmdel
338     and variants, the key must be an lvalue (so the macro can take the address of it).
339     Extensions are used that eliminate this requirement if you're using C99 and later
340     in GCC or clang, or if you're using C++ in GCC. But note that this can make your
341     code less portable.
342
343   * To test for presence of a key in a hashmap, just do 'hmgeti(foo,key) >= 0'.
344
345   * The iteration order of your data in the hashmap is determined solely by the
346     order of insertions and deletions. In particular, if you never delete, new
347     keys are always added at the end of the array. This will be consistent
348     across all platforms and versions of the library. However, you should not
349     attempt to serialize the internal hash table, as the hash is not consistent
350     between different platforms, and may change with future versions of the library.
351
352   * Use sh_new_arena() for string hashmaps that you never delete from. Initialize
353     with NULL if you're managing the memory for your strings, or your strings are
354     never freed (at least until the hashmap is freed). Otherwise, use sh_new_strdup().
355     @TODO: make an arena variant that garbage collects the strings with a trivial
356     copy collector into a new arena whenever the table shrinks / rebuilds. Since
357     current arena recommendation is to only use arena if it never deletes, then
358     this can just replace current arena implementation.
359
360   * If adversarial input is a serious concern and you're on a 64-bit platform,
361     enable STBDS_SIPHASH_2_4 (see the 'Compile-time options' section), and pass
362     a strong random number to stbds_rand_seed.
363
364   * The default value for the hash table is stored in foo[-1], so if you
365     use code like 'hmget(T,k)->value = 5' you can accidentally overwrite
366     the value stored by hmdefault if 'k' is not present.
367
368 CREDITS
369
370   Sean Barrett -- library, idea for dynamic array API/implementation
371   Per Vognsen  -- idea for hash table API/implementation
372   Rafael Sachetto -- arrpop()
373   github:HeroicKatora -- arraddn() reworking
374
375   Bugfixes:
376     Andy Durdin
377     Shane Liesegang
378     Vinh Truong
379     Andreas Molzer
380     github:hashitaku
381     github:srdjanstipic
382     Macoy Madson
383     Andreas Vennstrom
384     Tobias Mansfield-Williams
385 */
386
387 #ifdef STBDS_UNIT_TESTS
388 #define _CRT_SECURE_NO_WARNINGS
389 #endif
390
391 #ifndef INCLUDE_STB_DS_H
392 #define INCLUDE_STB_DS_H
393
394 #include <stddef.h>
395 #include <string.h>
396
397 #ifndef STBDS_NO_SHORT_NAMES
398 #define arrlen      stbds_arrlen
399 #define arrlenu     stbds_arrlenu
400 #define arrput      stbds_arrput
401 #define arrpush     stbds_arrput
402 #define arrpop      stbds_arrpop
403 #define arrfree     stbds_arrfree
404 #define arraddn     stbds_arraddn // deprecated, use one of the following instead:
405 #define arraddnptr  stbds_arraddnptr
406 #define arraddnindex stbds_arraddnindex
407 #define arrsetlen   stbds_arrsetlen
408 #define arrlast     stbds_arrlast
409 #define arrins      stbds_arrins
410 #define arrinsn     stbds_arrinsn
411 #define arrdel      stbds_arrdel
412 #define arrdeln     stbds_arrdeln
413 #define arrdelswap  stbds_arrdelswap
414 #define arrcap      stbds_arrcap
415 #define arrsetcap   stbds_arrsetcap
416
417 #define hmput       stbds_hmput
418 #define hmputs      stbds_hmputs
419 #define hmget       stbds_hmget
420 #define hmget_ts    stbds_hmget_ts
421 #define hmgets      stbds_hmgets
422 #define hmgetp      stbds_hmgetp
423 #define hmgetp_ts   stbds_hmgetp_ts
424 #define hmgetp_null stbds_hmgetp_null
425 #define hmgeti      stbds_hmgeti
426 #define hmgeti_ts   stbds_hmgeti_ts
427 #define hmdel       stbds_hmdel
428 #define hmlen       stbds_hmlen
429 #define hmlenu      stbds_hmlenu
430 #define hmfree      stbds_hmfree
431 #define hmdefault   stbds_hmdefault
432 #define hmdefaults  stbds_hmdefaults
433
434 #define shput       stbds_shput
435 #define shputi      stbds_shputi
436 #define shputs      stbds_shputs
437 #define shget       stbds_shget
438 #define shgeti      stbds_shgeti
439 #define shgets      stbds_shgets
440 #define shgetp      stbds_shgetp
441 #define shgetp_null stbds_shgetp_null
442 #define shdel       stbds_shdel
443 #define shlen       stbds_shlen
444 #define shlenu      stbds_shlenu
445 #define shfree      stbds_shfree
446 #define shdefault   stbds_shdefault
447 #define shdefaults  stbds_shdefaults
448 #define sh_new_arena  stbds_sh_new_arena
449 #define sh_new_strdup stbds_sh_new_strdup
450
451 #define stralloc    stbds_stralloc
452 #define strreset    stbds_strreset
453 #endif
454
455 #if defined(STBDS_REALLOC) && !defined(STBDS_FREE) || !defined(STBDS_REALLOC) && defined(STBDS_FREE)
456 #error "You must define both STBDS_REALLOC and STBDS_FREE, or neither."
457 #endif
458 #if !defined(STBDS_REALLOC) && !defined(STBDS_FREE)
459 #include <stdlib.h>
460 #define STBDS_REALLOC(c,p,s) realloc(p,s)
461 #define STBDS_FREE(c,p)      free(p)
462 #endif
463
464 #ifdef _MSC_VER
465 #define STBDS_NOTUSED(v)  (void)(v)
466 #else
467 #define STBDS_NOTUSED(v)  (void)sizeof(v)
468 #endif
469
470 #ifdef __cplusplus
471 extern "C" {
472 #endif
473
474 // for security against attackers, seed the library with a random number, at least time() but stronger is better
475 extern void stbds_rand_seed(size_t seed);
476
477 // these are the hash functions used internally if you want to test them or use them for other purposes
478 extern size_t stbds_hash_bytes(void *p, size_t len, size_t seed);
479 extern size_t stbds_hash_string(char *str, size_t seed);
480
481 // this is a simple string arena allocator, initialize with e.g. 'stbds_string_arena my_arena={0}'.
482 typedef struct stbds_string_arena stbds_string_arena;
483 extern char * stbds_stralloc(stbds_string_arena *a, char *str);
484 extern void   stbds_strreset(stbds_string_arena *a);
485
486 // have to #define STBDS_UNIT_TESTS to call this
487 extern void stbds_unit_tests(void);
488
489 ///////////////
490 //
491 // Everything below here is implementation details
492 //
493
494 extern void * stbds_arrgrowf(void *a, size_t elemsize, size_t addlen, size_t min_cap);
495 extern void   stbds_arrfreef(void *a);
496 extern void   stbds_hmfree_func(void *p, size_t elemsize);
497 extern void * stbds_hmget_key(void *a, size_t elemsize, void *key, size_t keysize, int mode);
498 extern void * stbds_hmget_key_ts(void *a, size_t elemsize, void *key, size_t keysize, ptrdiff_t *temp, int mode);
499 extern void * stbds_hmput_default(void *a, size_t elemsize);
500 extern void * stbds_hmput_key(void *a, size_t elemsize, void *key, size_t keysize, int mode);
501 extern void * stbds_hmdel_key(void *a, size_t elemsize, void *key, size_t keysize, size_t keyoffset, int mode);
502 extern void * stbds_shmode_func(size_t elemsize, int mode);
503
504 #ifdef __cplusplus
505 }
506 #endif
507
508 #if defined(__GNUC__) || defined(__clang__)
509 #define STBDS_HAS_TYPEOF
510 #ifdef __cplusplus
511 //#define STBDS_HAS_LITERAL_ARRAY  // this is currently broken for clang
512 #endif
513 #endif
514
515 #if !defined(__cplusplus)
516 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
517 #define STBDS_HAS_LITERAL_ARRAY
518 #endif
519 #endif
520
521 // this macro takes the address of the argument, but on gcc/clang can accept rvalues
522 #if defined(STBDS_HAS_LITERAL_ARRAY) && defined(STBDS_HAS_TYPEOF)
523   #if __clang__
524   #define STBDS_ADDRESSOF(typevar, value)     ((__typeof__(typevar)[1]){value}) // literal array decays to pointer to value
525   #else
526   #define STBDS_ADDRESSOF(typevar, value)     ((typeof(typevar)[1]){value}) // literal array decays to pointer to value
527   #endif
528 #else
529 #define STBDS_ADDRESSOF(typevar, value)     &(value)
530 #endif
531
532 #define STBDS_OFFSETOF(var,field)           ((char *) &(var)->field - (char *) (var))
533
534 #define stbds_header(t)  ((stbds_array_header *) (t) - 1)
535 #define stbds_temp(t)    stbds_header(t)->temp
536 #define stbds_temp_key(t) (*(char **) stbds_header(t)->hash_table)
537
538 #define stbds_arrsetcap(a,n)   (stbds_arrgrow(a,0,n))
539 #define stbds_arrsetlen(a,n)   ((stbds_arrcap(a) < (size_t) (n) ? stbds_arrsetcap((a),(size_t)(n)),0 : 0), (a) ? stbds_header(a)->length = (size_t) (n) : 0)
540 #define stbds_arrcap(a)        ((a) ? stbds_header(a)->capacity : 0)
541 #define stbds_arrlen(a)        ((a) ? (ptrdiff_t) stbds_header(a)->length : 0)
542 #define stbds_arrlenu(a)       ((a) ?             stbds_header(a)->length : 0)
543 #define stbds_arrput(a,v)      (stbds_arrmaybegrow(a,1), (a)[stbds_header(a)->length++] = (v))
544 #define stbds_arrpush          stbds_arrput  // synonym
545 #define stbds_arrpop(a)        (stbds_header(a)->length--, (a)[stbds_header(a)->length])
546 #define stbds_arraddn(a,n)     ((void)(stbds_arraddnindex(a, n)))    // deprecated, use one of the following instead:
547 #define stbds_arraddnptr(a,n)  (stbds_arrmaybegrow(a,n), (n) ? (stbds_header(a)->length += (n), &(a)[stbds_header(a)->length-(n)]) : (a))
548 #define stbds_arraddnindex(a,n)(stbds_arrmaybegrow(a,n), (n) ? (stbds_header(a)->length += (n), stbds_header(a)->length-(n)) : stbds_arrlen(a))
549 #define stbds_arraddnoff       stbds_arraddnindex
550 #define stbds_arrlast(a)       ((a)[stbds_header(a)->length-1])
551 #define stbds_arrfree(a)       ((void) ((a) ? STBDS_FREE(NULL,stbds_header(a)) : (void)0), (a)=NULL)
552 #define stbds_arrdel(a,i)      stbds_arrdeln(a,i,1)
553 #define stbds_arrdeln(a,i,n)   (memmove(&(a)[i], &(a)[(i)+(n)], sizeof *(a) * (stbds_header(a)->length-(n)-(i))), stbds_header(a)->length -= (n))
554 #define stbds_arrdelswap(a,i)  ((a)[i] = stbds_arrlast(a), stbds_header(a)->length -= 1)
555 #define stbds_arrinsn(a,i,n)   (stbds_arraddn((a),(n)), memmove(&(a)[(i)+(n)], &(a)[i], sizeof *(a) * (stbds_header(a)->length-(n)-(i))))
556 #define stbds_arrins(a,i,v)    (stbds_arrinsn((a),(i),1), (a)[i]=(v))
557
558 #define stbds_arrmaybegrow(a,n)  ((!(a) || stbds_header(a)->length + (n) > stbds_header(a)->capacity) \
559                                   ? (stbds_arrgrow(a,n,0),0) : 0)
560
561 #define stbds_arrgrow(a,b,c)   ((a) = stbds_arrgrowf_wrapper((a), sizeof *(a), (b), (c)))
562
563 #define stbds_hmput(t, k, v) \
564     ((t) = stbds_hmput_key_wrapper((t), sizeof *(t), (void*) STBDS_ADDRESSOF((t)->key, (k)), sizeof (t)->key, 0),   \
565      (t)[stbds_temp((t)-1)].key = (k),    \
566      (t)[stbds_temp((t)-1)].value = (v))
567
568 #define stbds_hmputs(t, s) \
569     ((t) = stbds_hmput_key_wrapper((t), sizeof *(t), &(s).key, sizeof (s).key, STBDS_HM_BINARY), \
570      (t)[stbds_temp((t)-1)] = (s))
571
572 #define stbds_hmgeti(t,k) \
573     ((t) = stbds_hmget_key_wrapper((t), sizeof *(t), (void*) STBDS_ADDRESSOF((t)->key, (k)), sizeof (t)->key, STBDS_HM_BINARY), \
574       stbds_temp((t)-1))
575
576 #define stbds_hmgeti_ts(t,k,temp) \
577     ((t) = stbds_hmget_key_ts_wrapper((t), sizeof *(t), (void*) STBDS_ADDRESSOF((t)->key, (k)), sizeof (t)->key, &(temp), STBDS_HM_BINARY), \
578       (temp))
579
580 #define stbds_hmgetp(t, k) \
581     ((void) stbds_hmgeti(t,k), &(t)[stbds_temp((t)-1)])
582
583 #define stbds_hmgetp_ts(t, k, temp) \
584     ((void) stbds_hmgeti_ts(t,k,temp), &(t)[temp])
585
586 #define stbds_hmdel(t,k) \
587     (((t) = stbds_hmdel_key_wrapper((t),sizeof *(t), (void*) STBDS_ADDRESSOF((t)->key, (k)), sizeof (t)->key, STBDS_OFFSETOF((t),key), STBDS_HM_BINARY)),(t)?stbds_temp((t)-1):0)
588
589 #define stbds_hmdefault(t, v) \
590     ((t) = stbds_hmput_default_wrapper((t), sizeof *(t)), (t)[-1].value = (v))
591
592 #define stbds_hmdefaults(t, s) \
593     ((t) = stbds_hmput_default_wrapper((t), sizeof *(t)), (t)[-1] = (s))
594
595 #define stbds_hmfree(p)        \
596     ((void) ((p) != NULL ? stbds_hmfree_func((p)-1,sizeof*(p)),0 : 0),(p)=NULL)
597
598 #define stbds_hmgets(t, k)    (*stbds_hmgetp(t,k))
599 #define stbds_hmget(t, k)     (stbds_hmgetp(t,k)->value)
600 #define stbds_hmget_ts(t, k, temp)  (stbds_hmgetp_ts(t,k,temp)->value)
601 #define stbds_hmlen(t)        ((t) ? (ptrdiff_t) stbds_header((t)-1)->length-1 : 0)
602 #define stbds_hmlenu(t)       ((t) ?             stbds_header((t)-1)->length-1 : 0)
603 #define stbds_hmgetp_null(t,k)  (stbds_hmgeti(t,k) == -1 ? NULL : &(t)[stbds_temp((t)-1)])
604
605 #define stbds_shput(t, k, v) \
606     ((t) = stbds_hmput_key_wrapper((t), sizeof *(t), (void*) (k), sizeof (t)->key, STBDS_HM_STRING),   \
607      (t)[stbds_temp((t)-1)].value = (v))
608
609 #define stbds_shputi(t, k, v) \
610     ((t) = stbds_hmput_key_wrapper((t), sizeof *(t), (void*) (k), sizeof (t)->key, STBDS_HM_STRING),   \
611      (t)[stbds_temp((t)-1)].value = (v), stbds_temp((t)-1))
612
613 #define stbds_shputs(t, s) \
614     ((t) = stbds_hmput_key_wrapper((t), sizeof *(t), (void*) (s).key, sizeof (s).key, STBDS_HM_STRING), \
615      (t)[stbds_temp((t)-1)] = (s), \
616      (t)[stbds_temp((t)-1)].key = stbds_temp_key((t)-1)) // above line overwrites whole structure, so must rewrite key here if it was allocated internally
617
618 #define stbds_pshput(t, p) \
619     ((t) = stbds_hmput_key_wrapper((t), sizeof *(t), (void*) (p)->key, sizeof (p)->key, STBDS_HM_PTR_TO_STRING), \
620      (t)[stbds_temp((t)-1)] = (p))
621
622 #define stbds_shgeti(t,k) \
623      ((t) = stbds_hmget_key_wrapper((t), sizeof *(t), (void*) (k), sizeof (t)->key, STBDS_HM_STRING), \
624       stbds_temp((t)-1))
625
626 #define stbds_pshgeti(t,k) \
627      ((t) = stbds_hmget_key_wrapper((t), sizeof *(t), (void*) (k), sizeof (*(t))->key, STBDS_HM_PTR_TO_STRING), \
628       stbds_temp((t)-1))
629
630 #define stbds_shgetp(t, k) \
631     ((void) stbds_shgeti(t,k), &(t)[stbds_temp((t)-1)])
632
633 #define stbds_pshget(t, k) \
634     ((void) stbds_pshgeti(t,k), (t)[stbds_temp((t)-1)])
635
636 #define stbds_shdel(t,k) \
637     (((t) = stbds_hmdel_key_wrapper((t),sizeof *(t), (void*) (k), sizeof (t)->key, STBDS_OFFSETOF((t),key), STBDS_HM_STRING)),(t)?stbds_temp((t)-1):0)
638 #define stbds_pshdel(t,k) \
639     (((t) = stbds_hmdel_key_wrapper((t),sizeof *(t), (void*) (k), sizeof (*(t))->key, STBDS_OFFSETOF(*(t),key), STBDS_HM_PTR_TO_STRING)),(t)?stbds_temp((t)-1):0)
640
641 #define stbds_sh_new_arena(t)  \
642     ((t) = stbds_shmode_func_wrapper(t, sizeof *(t), STBDS_SH_ARENA))
643 #define stbds_sh_new_strdup(t) \
644     ((t) = stbds_shmode_func_wrapper(t, sizeof *(t), STBDS_SH_STRDUP))
645
646 #define stbds_shdefault(t, v)  stbds_hmdefault(t,v)
647 #define stbds_shdefaults(t, s) stbds_hmdefaults(t,s)
648
649 #define stbds_shfree       stbds_hmfree
650 #define stbds_shlenu       stbds_hmlenu
651
652 #define stbds_shgets(t, k) (*stbds_shgetp(t,k))
653 #define stbds_shget(t, k)  (stbds_shgetp(t,k)->value)
654 #define stbds_shgetp_null(t,k)  (stbds_shgeti(t,k) == -1 ? NULL : &(t)[stbds_temp((t)-1)])
655 #define stbds_shlen        stbds_hmlen
656
657 typedef struct
658 {
659   size_t      length;
660   size_t      capacity;
661   void      * hash_table;
662   ptrdiff_t   temp;
663 } stbds_array_header;
664
665 typedef struct stbds_string_block
666 {
667   struct stbds_string_block *next;
668   char storage[8];
669 } stbds_string_block;
670
671 struct stbds_string_arena
672 {
673   stbds_string_block *storage;
674   size_t remaining;
675   unsigned char block;
676   unsigned char mode;  // this isn't used by the string arena itself
677 };
678
679 #define STBDS_HM_BINARY         0
680 #define STBDS_HM_STRING         1
681
682 enum
683 {
684    STBDS_SH_NONE,
685    STBDS_SH_DEFAULT,
686    STBDS_SH_STRDUP,
687    STBDS_SH_ARENA
688 };
689
690 #ifdef __cplusplus
691 // in C we use implicit assignment from these void*-returning functions to T*.
692 // in C++ these templates make the same code work
693 template<class T> static T * stbds_arrgrowf_wrapper(T *a, size_t elemsize, size_t addlen, size_t min_cap) {
694   return (T*)stbds_arrgrowf((void *)a, elemsize, addlen, min_cap);
695 }
696 template<class T> static T * stbds_hmget_key_wrapper(T *a, size_t elemsize, void *key, size_t keysize, int mode) {
697   return (T*)stbds_hmget_key((void*)a, elemsize, key, keysize, mode);
698 }
699 template<class T> static T * stbds_hmget_key_ts_wrapper(T *a, size_t elemsize, void *key, size_t keysize, ptrdiff_t *temp, int mode) {
700   return (T*)stbds_hmget_key_ts((void*)a, elemsize, key, keysize, temp, mode);
701 }
702 template<class T> static T * stbds_hmput_default_wrapper(T *a, size_t elemsize) {
703   return (T*)stbds_hmput_default((void *)a, elemsize);
704 }
705 template<class T> static T * stbds_hmput_key_wrapper(T *a, size_t elemsize, void *key, size_t keysize, int mode) {
706   return (T*)stbds_hmput_key((void*)a, elemsize, key, keysize, mode);
707 }
708 template<class T> static T * stbds_hmdel_key_wrapper(T *a, size_t elemsize, void *key, size_t keysize, size_t keyoffset, int mode){
709   return (T*)stbds_hmdel_key((void*)a, elemsize, key, keysize, keyoffset, mode);
710 }
711 template<class T> static T * stbds_shmode_func_wrapper(T *, size_t elemsize, int mode) {
712   return (T*)stbds_shmode_func(elemsize, mode);
713 }
714 #else
715 #define stbds_arrgrowf_wrapper            stbds_arrgrowf
716 #define stbds_hmget_key_wrapper           stbds_hmget_key
717 #define stbds_hmget_key_ts_wrapper        stbds_hmget_key_ts
718 #define stbds_hmput_default_wrapper       stbds_hmput_default
719 #define stbds_hmput_key_wrapper           stbds_hmput_key
720 #define stbds_hmdel_key_wrapper           stbds_hmdel_key
721 #define stbds_shmode_func_wrapper(t,e,m)  stbds_shmode_func(e,m)
722 #endif
723
724 #endif // INCLUDE_STB_DS_H
725
726
727 //////////////////////////////////////////////////////////////////////////////
728 //
729 //   IMPLEMENTATION
730 //
731
732 #ifdef STB_DS_IMPLEMENTATION
733 #include <assert.h>
734 #include <string.h>
735
736 #ifndef STBDS_ASSERT
737 #define STBDS_ASSERT_WAS_UNDEFINED
738 #define STBDS_ASSERT(x)   ((void) 0)
739 #endif
740
741 #ifdef STBDS_STATISTICS
742 #define STBDS_STATS(x)   x
743 size_t stbds_array_grow;
744 size_t stbds_hash_grow;
745 size_t stbds_hash_shrink;
746 size_t stbds_hash_rebuild;
747 size_t stbds_hash_probes;
748 size_t stbds_hash_alloc;
749 size_t stbds_rehash_probes;
750 size_t stbds_rehash_items;
751 #else
752 #define STBDS_STATS(x)
753 #endif
754
755 //
756 // stbds_arr implementation
757 //
758
759 //int *prev_allocs[65536];
760 //int num_prev;
761
762 void *stbds_arrgrowf(void *a, size_t elemsize, size_t addlen, size_t min_cap)
763 {
764   stbds_array_header temp={0}; // force debugging
765   void *b;
766   size_t min_len = stbds_arrlen(a) + addlen;
767   (void) sizeof(temp);
768
769   // compute the minimum capacity needed
770   if (min_len > min_cap)
771     min_cap = min_len;
772
773   if (min_cap <= stbds_arrcap(a))
774     return a;
775
776   // increase needed capacity to guarantee O(1) amortized
777   if (min_cap < 2 * stbds_arrcap(a))
778     min_cap = 2 * stbds_arrcap(a);
779   else if (min_cap < 4)
780     min_cap = 4;
781
782   //if (num_prev < 65536) if (a) prev_allocs[num_prev++] = (int *) ((char *) a+1);
783   //if (num_prev == 2201)
784   //  num_prev = num_prev;
785   b = STBDS_REALLOC(NULL, (a) ? stbds_header(a) : 0, elemsize * min_cap + sizeof(stbds_array_header));
786   //if (num_prev < 65536) prev_allocs[num_prev++] = (int *) (char *) b;
787   b = (char *) b + sizeof(stbds_array_header);
788   if (a == NULL) {
789     stbds_header(b)->length = 0;
790     stbds_header(b)->hash_table = 0;
791     stbds_header(b)->temp = 0;
792   } else {
793     STBDS_STATS(++stbds_array_grow);
794   }
795   stbds_header(b)->capacity = min_cap;
796
797   return b;
798 }
799
800 void stbds_arrfreef(void *a)
801 {
802   STBDS_FREE(NULL, stbds_header(a));
803 }
804
805 //
806 // stbds_hm hash table implementation
807 //
808
809 #ifdef STBDS_INTERNAL_SMALL_BUCKET
810 #define STBDS_BUCKET_LENGTH      4
811 #else
812 #define STBDS_BUCKET_LENGTH      8
813 #endif
814
815 #define STBDS_BUCKET_SHIFT      (STBDS_BUCKET_LENGTH == 8 ? 3 : 2)
816 #define STBDS_BUCKET_MASK       (STBDS_BUCKET_LENGTH-1)
817 #define STBDS_CACHE_LINE_SIZE   64
818
819 #define STBDS_ALIGN_FWD(n,a)   (((n) + (a) - 1) & ~((a)-1))
820
821 typedef struct
822 {
823    size_t    hash [STBDS_BUCKET_LENGTH];
824    ptrdiff_t index[STBDS_BUCKET_LENGTH];
825 } stbds_hash_bucket; // in 32-bit, this is one 64-byte cache line; in 64-bit, each array is one 64-byte cache line
826
827 typedef struct
828 {
829   char * temp_key; // this MUST be the first field of the hash table
830   size_t slot_count;
831   size_t used_count;
832   size_t used_count_threshold;
833   size_t used_count_shrink_threshold;
834   size_t tombstone_count;
835   size_t tombstone_count_threshold;
836   size_t seed;
837   size_t slot_count_log2;
838   stbds_string_arena string;
839   stbds_hash_bucket *storage; // not a separate allocation, just 64-byte aligned storage after this struct
840 } stbds_hash_index;
841
842 #define STBDS_INDEX_EMPTY    -1
843 #define STBDS_INDEX_DELETED  -2
844 #define STBDS_INDEX_IN_USE(x)  ((x) >= 0)
845
846 #define STBDS_HASH_EMPTY      0
847 #define STBDS_HASH_DELETED    1
848
849 static size_t stbds_hash_seed=0x31415926;
850
851 void stbds_rand_seed(size_t seed)
852 {
853   stbds_hash_seed = seed;
854 }
855
856 #define stbds_load_32_or_64(var, temp, v32, v64_hi, v64_lo)                                          \
857   temp = v64_lo ^ v32, temp <<= 16, temp <<= 16, temp >>= 16, temp >>= 16, /* discard if 32-bit */   \
858   var = v64_hi, var <<= 16, var <<= 16,                                    /* discard if 32-bit */   \
859   var ^= temp ^ v32
860
861 #define STBDS_SIZE_T_BITS           ((sizeof (size_t)) * 8)
862
863 static size_t stbds_probe_position(size_t hash, size_t slot_count, size_t slot_log2)
864 {
865   size_t pos;
866   STBDS_NOTUSED(slot_log2);
867   pos = hash & (slot_count-1);
868   #ifdef STBDS_INTERNAL_BUCKET_START
869   pos &= ~STBDS_BUCKET_MASK;
870   #endif
871   return pos;
872 }
873
874 static size_t stbds_log2(size_t slot_count)
875 {
876   size_t n=0;
877   while (slot_count > 1) {
878     slot_count >>= 1;
879     ++n;
880   }
881   return n;
882 }
883
884 static stbds_hash_index *stbds_make_hash_index(size_t slot_count, stbds_hash_index *ot)
885 {
886   stbds_hash_index *t;
887   t = (stbds_hash_index *) STBDS_REALLOC(NULL,0,(slot_count >> STBDS_BUCKET_SHIFT) * sizeof(stbds_hash_bucket) + sizeof(stbds_hash_index) + STBDS_CACHE_LINE_SIZE-1);
888   t->storage = (stbds_hash_bucket *) STBDS_ALIGN_FWD((size_t) (t+1), STBDS_CACHE_LINE_SIZE);
889   t->slot_count = slot_count;
890   t->slot_count_log2 = stbds_log2(slot_count);
891   t->tombstone_count = 0;
892   t->used_count = 0;
893
894   #if 0 // A1
895   t->used_count_threshold        = slot_count*12/16; // if 12/16th of table is occupied, grow
896   t->tombstone_count_threshold   = slot_count* 2/16; // if tombstones are 2/16th of table, rebuild
897   t->used_count_shrink_threshold = slot_count* 4/16; // if table is only 4/16th full, shrink
898   #elif 1 // A2
899   //t->used_count_threshold        = slot_count*12/16; // if 12/16th of table is occupied, grow
900   //t->tombstone_count_threshold   = slot_count* 3/16; // if tombstones are 3/16th of table, rebuild
901   //t->used_count_shrink_threshold = slot_count* 4/16; // if table is only 4/16th full, shrink
902
903   // compute without overflowing
904   t->used_count_threshold        = slot_count - (slot_count>>2);
905   t->tombstone_count_threshold   = (slot_count>>3) + (slot_count>>4);
906   t->used_count_shrink_threshold = slot_count >> 2;
907
908   #elif 0 // B1
909   t->used_count_threshold        = slot_count*13/16; // if 13/16th of table is occupied, grow
910   t->tombstone_count_threshold   = slot_count* 2/16; // if tombstones are 2/16th of table, rebuild
911   t->used_count_shrink_threshold = slot_count* 5/16; // if table is only 5/16th full, shrink
912   #else // C1
913   t->used_count_threshold        = slot_count*14/16; // if 14/16th of table is occupied, grow
914   t->tombstone_count_threshold   = slot_count* 2/16; // if tombstones are 2/16th of table, rebuild
915   t->used_count_shrink_threshold = slot_count* 6/16; // if table is only 6/16th full, shrink
916   #endif
917   // Following statistics were measured on a Core i7-6700 @ 4.00Ghz, compiled with clang 7.0.1 -O2
918     // Note that the larger tables have high variance as they were run fewer times
919   //     A1            A2          B1           C1
920   //    0.10ms :     0.10ms :     0.10ms :     0.11ms :      2,000 inserts creating 2K table
921   //    0.96ms :     0.95ms :     0.97ms :     1.04ms :     20,000 inserts creating 20K table
922   //   14.48ms :    14.46ms :    10.63ms :    11.00ms :    200,000 inserts creating 200K table
923   //  195.74ms :   196.35ms :   203.69ms :   214.92ms :  2,000,000 inserts creating 2M table
924   // 2193.88ms :  2209.22ms :  2285.54ms :  2437.17ms : 20,000,000 inserts creating 20M table
925   //   65.27ms :    53.77ms :    65.33ms :    65.47ms : 500,000 inserts & deletes in 2K table
926   //   72.78ms :    62.45ms :    71.95ms :    72.85ms : 500,000 inserts & deletes in 20K table
927   //   89.47ms :    77.72ms :    96.49ms :    96.75ms : 500,000 inserts & deletes in 200K table
928   //   97.58ms :    98.14ms :    97.18ms :    97.53ms : 500,000 inserts & deletes in 2M table
929   //  118.61ms :   119.62ms :   120.16ms :   118.86ms : 500,000 inserts & deletes in 20M table
930   //  192.11ms :   194.39ms :   196.38ms :   195.73ms : 500,000 inserts & deletes in 200M table
931
932   if (slot_count <= STBDS_BUCKET_LENGTH)
933     t->used_count_shrink_threshold = 0;
934   // to avoid infinite loop, we need to guarantee that at least one slot is empty and will terminate probes
935   STBDS_ASSERT(t->used_count_threshold + t->tombstone_count_threshold < t->slot_count);
936   STBDS_STATS(++stbds_hash_alloc);
937   if (ot) {
938     t->string = ot->string;
939     // reuse old seed so we can reuse old hashes so below "copy out old data" doesn't do any hashing
940     t->seed = ot->seed;
941   } else {
942     size_t a,b,temp;
943     memset(&t->string, 0, sizeof(t->string));
944     t->seed = stbds_hash_seed;
945     // LCG
946     // in 32-bit, a =          2147001325   b =  715136305
947     // in 64-bit, a = 2862933555777941757   b = 3037000493
948     stbds_load_32_or_64(a,temp, 2147001325, 0x27bb2ee6, 0x87b0b0fd);
949     stbds_load_32_or_64(b,temp,  715136305,          0, 0xb504f32d);
950     stbds_hash_seed = stbds_hash_seed  * a + b;
951   }
952
953   {
954     size_t i,j;
955     for (i=0; i < slot_count >> STBDS_BUCKET_SHIFT; ++i) {
956       stbds_hash_bucket *b = &t->storage[i];
957       for (j=0; j < STBDS_BUCKET_LENGTH; ++j)
958         b->hash[j] = STBDS_HASH_EMPTY;
959       for (j=0; j < STBDS_BUCKET_LENGTH; ++j)
960         b->index[j] = STBDS_INDEX_EMPTY;
961     }
962   }
963
964   // copy out the old data, if any
965   if (ot) {
966     size_t i,j;
967     t->used_count = ot->used_count;
968     for (i=0; i < ot->slot_count >> STBDS_BUCKET_SHIFT; ++i) {
969       stbds_hash_bucket *ob = &ot->storage[i];
970       for (j=0; j < STBDS_BUCKET_LENGTH; ++j) {
971         if (STBDS_INDEX_IN_USE(ob->index[j])) {
972           size_t hash = ob->hash[j];
973           size_t pos = stbds_probe_position(hash, t->slot_count, t->slot_count_log2);
974           size_t step = STBDS_BUCKET_LENGTH;
975           STBDS_STATS(++stbds_rehash_items);
976           for (;;) {
977             size_t limit,z;
978             stbds_hash_bucket *bucket;
979             bucket = &t->storage[pos >> STBDS_BUCKET_SHIFT];
980             STBDS_STATS(++stbds_rehash_probes);
981
982             for (z=pos & STBDS_BUCKET_MASK; z < STBDS_BUCKET_LENGTH; ++z) {
983               if (bucket->hash[z] == 0) {
984                 bucket->hash[z] = hash;
985                 bucket->index[z] = ob->index[j];
986                 goto done;
987               }
988             }
989
990             limit = pos & STBDS_BUCKET_MASK;
991             for (z = 0; z < limit; ++z) {
992               if (bucket->hash[z] == 0) {
993                 bucket->hash[z] = hash;
994                 bucket->index[z] = ob->index[j];
995                 goto done;
996               }
997             }
998
999             pos += step;                  // quadratic probing
1000             step += STBDS_BUCKET_LENGTH;
1001             pos &= (t->slot_count-1);
1002           }
1003         }
1004        done:
1005         ;
1006       }
1007     }
1008   }
1009
1010   return t;
1011 }
1012
1013 #define STBDS_ROTATE_LEFT(val, n)   (((val) << (n)) | ((val) >> (STBDS_SIZE_T_BITS - (n))))
1014 #define STBDS_ROTATE_RIGHT(val, n)  (((val) >> (n)) | ((val) << (STBDS_SIZE_T_BITS - (n))))
1015
1016 size_t stbds_hash_string(char *str, size_t seed)
1017 {
1018   size_t hash = seed;
1019   while (*str)
1020      hash = STBDS_ROTATE_LEFT(hash, 9) + (unsigned char) *str++;
1021
1022   // Thomas Wang 64-to-32 bit mix function, hopefully also works in 32 bits
1023   hash ^= seed;
1024   hash = (~hash) + (hash << 18);
1025   hash ^= hash ^ STBDS_ROTATE_RIGHT(hash,31);
1026   hash = hash * 21;
1027   hash ^= hash ^ STBDS_ROTATE_RIGHT(hash,11);
1028   hash += (hash << 6);
1029   hash ^= STBDS_ROTATE_RIGHT(hash,22);
1030   return hash+seed;
1031 }
1032
1033 #ifdef STBDS_SIPHASH_2_4
1034 #define STBDS_SIPHASH_C_ROUNDS 2
1035 #define STBDS_SIPHASH_D_ROUNDS 4
1036 typedef int STBDS_SIPHASH_2_4_can_only_be_used_in_64_bit_builds[sizeof(size_t) == 8 ? 1 : -1];
1037 #endif
1038
1039 #ifndef STBDS_SIPHASH_C_ROUNDS
1040 #define STBDS_SIPHASH_C_ROUNDS 1
1041 #endif
1042 #ifndef STBDS_SIPHASH_D_ROUNDS
1043 #define STBDS_SIPHASH_D_ROUNDS 1
1044 #endif
1045
1046 #ifdef _MSC_VER
1047 #pragma warning(push)
1048 #pragma warning(disable:4127) // conditional expression is constant, for do..while(0) and sizeof()==
1049 #endif
1050
1051 static size_t stbds_siphash_bytes(void *p, size_t len, size_t seed)
1052 {
1053   unsigned char *d = (unsigned char *) p;
1054   size_t i,j;
1055   size_t v0,v1,v2,v3, data;
1056
1057   // hash that works on 32- or 64-bit registers without knowing which we have
1058   // (computes different results on 32-bit and 64-bit platform)
1059   // derived from siphash, but on 32-bit platforms very different as it uses 4 32-bit state not 4 64-bit
1060   v0 = ((((size_t) 0x736f6d65 << 16) << 16) + 0x70736575) ^  seed;
1061   v1 = ((((size_t) 0x646f7261 << 16) << 16) + 0x6e646f6d) ^ ~seed;
1062   v2 = ((((size_t) 0x6c796765 << 16) << 16) + 0x6e657261) ^  seed;
1063   v3 = ((((size_t) 0x74656462 << 16) << 16) + 0x79746573) ^ ~seed;
1064
1065   #ifdef STBDS_TEST_SIPHASH_2_4
1066   // hardcoded with key material in the siphash test vectors
1067   v0 ^= 0x0706050403020100ull ^  seed;
1068   v1 ^= 0x0f0e0d0c0b0a0908ull ^ ~seed;
1069   v2 ^= 0x0706050403020100ull ^  seed;
1070   v3 ^= 0x0f0e0d0c0b0a0908ull ^ ~seed;
1071   #endif
1072
1073   #define STBDS_SIPROUND() \
1074     do {                   \
1075       v0 += v1; v1 = STBDS_ROTATE_LEFT(v1, 13);  v1 ^= v0; v0 = STBDS_ROTATE_LEFT(v0,STBDS_SIZE_T_BITS/2); \
1076       v2 += v3; v3 = STBDS_ROTATE_LEFT(v3, 16);  v3 ^= v2;                                                 \
1077       v2 += v1; v1 = STBDS_ROTATE_LEFT(v1, 17);  v1 ^= v2; v2 = STBDS_ROTATE_LEFT(v2,STBDS_SIZE_T_BITS/2); \
1078       v0 += v3; v3 = STBDS_ROTATE_LEFT(v3, 21);  v3 ^= v0;                                                 \
1079     } while (0)
1080
1081   for (i=0; i+sizeof(size_t) <= len; i += sizeof(size_t), d += sizeof(size_t)) {
1082     data = d[0] | (d[1] << 8) | (d[2] << 16) | (d[3] << 24);
1083     data |= (size_t) (d[4] | (d[5] << 8) | (d[6] << 16) | (d[7] << 24)) << 16 << 16; // discarded if size_t == 4
1084
1085     v3 ^= data;
1086     for (j=0; j < STBDS_SIPHASH_C_ROUNDS; ++j)
1087       STBDS_SIPROUND();
1088     v0 ^= data;
1089   }
1090   data = len << (STBDS_SIZE_T_BITS-8);
1091   switch (len - i) {
1092     case 7: data |= ((size_t) d[6] << 24) << 24; // fall through
1093     case 6: data |= ((size_t) d[5] << 20) << 20; // fall through
1094     case 5: data |= ((size_t) d[4] << 16) << 16; // fall through
1095     case 4: data |= (d[3] << 24); // fall through
1096     case 3: data |= (d[2] << 16); // fall through
1097     case 2: data |= (d[1] << 8); // fall through
1098     case 1: data |= d[0]; // fall through
1099     case 0: break;
1100   }
1101   v3 ^= data;
1102   for (j=0; j < STBDS_SIPHASH_C_ROUNDS; ++j)
1103     STBDS_SIPROUND();
1104   v0 ^= data;
1105   v2 ^= 0xff;
1106   for (j=0; j < STBDS_SIPHASH_D_ROUNDS; ++j)
1107     STBDS_SIPROUND();
1108
1109 #ifdef STBDS_SIPHASH_2_4
1110   return v0^v1^v2^v3;
1111 #else
1112   return v1^v2^v3; // slightly stronger since v0^v3 in above cancels out final round operation? I tweeted at the authors of SipHash about this but they didn't reply
1113 #endif
1114 }
1115
1116 size_t stbds_hash_bytes(void *p, size_t len, size_t seed)
1117 {
1118 #ifdef STBDS_SIPHASH_2_4
1119   return stbds_siphash_bytes(p,len,seed);
1120 #else
1121   unsigned char *d = (unsigned char *) p;
1122
1123   if (len == 4) {
1124     unsigned int hash = d[0] | (d[1] << 8) | (d[2] << 16) | (d[3] << 24);
1125     #if 0
1126     // HASH32-A  Bob Jenkin's hash function w/o large constants
1127     hash ^= seed;
1128     hash -= (hash<<6);
1129     hash ^= (hash>>17);
1130     hash -= (hash<<9);
1131     hash ^= seed;
1132     hash ^= (hash<<4);
1133     hash -= (hash<<3);
1134     hash ^= (hash<<10);
1135     hash ^= (hash>>15);
1136     #elif 1
1137     // HASH32-BB  Bob Jenkin's presumably-accidental version of Thomas Wang hash with rotates turned into shifts.
1138     // Note that converting these back to rotates makes it run a lot slower, presumably due to collisions, so I'm
1139     // not really sure what's going on.
1140     hash ^= seed;
1141     hash = (hash ^ 61) ^ (hash >> 16);
1142     hash = hash + (hash << 3);
1143     hash = hash ^ (hash >> 4);
1144     hash = hash * 0x27d4eb2d;
1145     hash ^= seed;
1146     hash = hash ^ (hash >> 15);
1147     #else  // HASH32-C   -  Murmur3
1148     hash ^= seed;
1149     hash *= 0xcc9e2d51;
1150     hash = (hash << 17) | (hash >> 15);
1151     hash *= 0x1b873593;
1152     hash ^= seed;
1153     hash = (hash << 19) | (hash >> 13);
1154     hash = hash*5 + 0xe6546b64;
1155     hash ^= hash >> 16;
1156     hash *= 0x85ebca6b;
1157     hash ^= seed;
1158     hash ^= hash >> 13;
1159     hash *= 0xc2b2ae35;
1160     hash ^= hash >> 16;
1161     #endif
1162     // Following statistics were measured on a Core i7-6700 @ 4.00Ghz, compiled with clang 7.0.1 -O2
1163     // Note that the larger tables have high variance as they were run fewer times
1164     //  HASH32-A   //  HASH32-BB  //  HASH32-C
1165     //    0.10ms   //    0.10ms   //    0.10ms :      2,000 inserts creating 2K table
1166     //    0.96ms   //    0.95ms   //    0.99ms :     20,000 inserts creating 20K table
1167     //   14.69ms   //   14.43ms   //   14.97ms :    200,000 inserts creating 200K table
1168     //  199.99ms   //  195.36ms   //  202.05ms :  2,000,000 inserts creating 2M table
1169     // 2234.84ms   // 2187.74ms   // 2240.38ms : 20,000,000 inserts creating 20M table
1170     //   55.68ms   //   53.72ms   //   57.31ms : 500,000 inserts & deletes in 2K table
1171     //   63.43ms   //   61.99ms   //   65.73ms : 500,000 inserts & deletes in 20K table
1172     //   80.04ms   //   77.96ms   //   81.83ms : 500,000 inserts & deletes in 200K table
1173     //  100.42ms   //   97.40ms   //  102.39ms : 500,000 inserts & deletes in 2M table
1174     //  119.71ms   //  120.59ms   //  121.63ms : 500,000 inserts & deletes in 20M table
1175     //  185.28ms   //  195.15ms   //  187.74ms : 500,000 inserts & deletes in 200M table
1176     //   15.58ms   //   14.79ms   //   15.52ms : 200,000 inserts creating 200K table with varying key spacing
1177
1178     return (((size_t) hash << 16 << 16) | hash) ^ seed;
1179   } else if (len == 8 && sizeof(size_t) == 8) {
1180     size_t hash = d[0] | (d[1] << 8) | (d[2] << 16) | (d[3] << 24);
1181     hash |= (size_t) (d[4] | (d[5] << 8) | (d[6] << 16) | (d[7] << 24)) << 16 << 16; // avoid warning if size_t == 4
1182     hash ^= seed;
1183     hash = (~hash) + (hash << 21);
1184     hash ^= STBDS_ROTATE_RIGHT(hash,24);
1185     hash *= 265;
1186     hash ^= STBDS_ROTATE_RIGHT(hash,14);
1187     hash ^= seed;
1188     hash *= 21;
1189     hash ^= STBDS_ROTATE_RIGHT(hash,28);
1190     hash += (hash << 31);
1191     hash = (~hash) + (hash << 18);
1192     return hash;
1193   } else {
1194     return stbds_siphash_bytes(p,len,seed);
1195   }
1196 #endif
1197 }
1198 #ifdef _MSC_VER
1199 #pragma warning(pop)
1200 #endif
1201
1202
1203 static int stbds_is_key_equal(void *a, size_t elemsize, void *key, size_t keysize, size_t keyoffset, int mode, size_t i)
1204 {
1205   if (mode >= STBDS_HM_STRING)
1206     return 0==strcmp((char *) key, * (char **) ((char *) a + elemsize*i + keyoffset));
1207   else
1208     return 0==memcmp(key, (char *) a + elemsize*i + keyoffset, keysize);
1209 }
1210
1211 #define STBDS_HASH_TO_ARR(x,elemsize) ((char*) (x) - (elemsize))
1212 #define STBDS_ARR_TO_HASH(x,elemsize) ((char*) (x) + (elemsize))
1213
1214 #define stbds_hash_table(a)  ((stbds_hash_index *) stbds_header(a)->hash_table)
1215
1216 void stbds_hmfree_func(void *a, size_t elemsize)
1217 {
1218   if (a == NULL) return;
1219   if (stbds_hash_table(a) != NULL) {
1220     if (stbds_hash_table(a)->string.mode == STBDS_SH_STRDUP) {
1221       size_t i;
1222       // skip 0th element, which is default
1223       for (i=1; i < stbds_header(a)->length; ++i)
1224         STBDS_FREE(NULL, *(char**) ((char *) a + elemsize*i));
1225     }
1226     stbds_strreset(&stbds_hash_table(a)->string);
1227   }
1228   STBDS_FREE(NULL, stbds_header(a)->hash_table);
1229   STBDS_FREE(NULL, stbds_header(a));
1230 }
1231
1232 static ptrdiff_t stbds_hm_find_slot(void *a, size_t elemsize, void *key, size_t keysize, size_t keyoffset, int mode)
1233 {
1234   void *raw_a = STBDS_HASH_TO_ARR(a,elemsize);
1235   stbds_hash_index *table = stbds_hash_table(raw_a);
1236   size_t hash = mode >= STBDS_HM_STRING ? stbds_hash_string((char*)key,table->seed) : stbds_hash_bytes(key, keysize,table->seed);
1237   size_t step = STBDS_BUCKET_LENGTH;
1238   size_t limit,i;
1239   size_t pos;
1240   stbds_hash_bucket *bucket;
1241
1242   if (hash < 2) hash += 2; // stored hash values are forbidden from being 0, so we can detect empty slots
1243
1244   pos = stbds_probe_position(hash, table->slot_count, table->slot_count_log2);
1245
1246   for (;;) {
1247     STBDS_STATS(++stbds_hash_probes);
1248     bucket = &table->storage[pos >> STBDS_BUCKET_SHIFT];
1249
1250     // start searching from pos to end of bucket, this should help performance on small hash tables that fit in cache
1251     for (i=pos & STBDS_BUCKET_MASK; i < STBDS_BUCKET_LENGTH; ++i) {
1252       if (bucket->hash[i] == hash) {
1253         if (stbds_is_key_equal(a, elemsize, key, keysize, keyoffset, mode, bucket->index[i])) {
1254           return (pos & ~STBDS_BUCKET_MASK)+i;
1255         }
1256       } else if (bucket->hash[i] == STBDS_HASH_EMPTY) {
1257         return -1;
1258       }
1259     }
1260
1261     // search from beginning of bucket to pos
1262     limit = pos & STBDS_BUCKET_MASK;
1263     for (i = 0; i < limit; ++i) {
1264       if (bucket->hash[i] == hash) {
1265         if (stbds_is_key_equal(a, elemsize, key, keysize, keyoffset, mode, bucket->index[i])) {
1266           return (pos & ~STBDS_BUCKET_MASK)+i;
1267         }
1268       } else if (bucket->hash[i] == STBDS_HASH_EMPTY) {
1269         return -1;
1270       }
1271     }
1272
1273     // quadratic probing
1274     pos += step;
1275     step += STBDS_BUCKET_LENGTH;
1276     pos &= (table->slot_count-1);
1277   }
1278   /* NOTREACHED */
1279 }
1280
1281 void * stbds_hmget_key_ts(void *a, size_t elemsize, void *key, size_t keysize, ptrdiff_t *temp, int mode)
1282 {
1283   size_t keyoffset = 0;
1284   if (a == NULL) {
1285     // make it non-empty so we can return a temp
1286     a = stbds_arrgrowf(0, elemsize, 0, 1);
1287     stbds_header(a)->length += 1;
1288     memset(a, 0, elemsize);
1289     *temp = STBDS_INDEX_EMPTY;
1290     // adjust a to point after the default element
1291     return STBDS_ARR_TO_HASH(a,elemsize);
1292   } else {
1293     stbds_hash_index *table;
1294     void *raw_a = STBDS_HASH_TO_ARR(a,elemsize);
1295     // adjust a to point to the default element
1296     table = (stbds_hash_index *) stbds_header(raw_a)->hash_table;
1297     if (table == 0) {
1298       *temp = -1;
1299     } else {
1300       ptrdiff_t slot = stbds_hm_find_slot(a, elemsize, key, keysize, keyoffset, mode);
1301       if (slot < 0) {
1302         *temp = STBDS_INDEX_EMPTY;
1303       } else {
1304         stbds_hash_bucket *b = &table->storage[slot >> STBDS_BUCKET_SHIFT];
1305         *temp = b->index[slot & STBDS_BUCKET_MASK];
1306       }
1307     }
1308     return a;
1309   }
1310 }
1311
1312 void * stbds_hmget_key(void *a, size_t elemsize, void *key, size_t keysize, int mode)
1313 {
1314   ptrdiff_t temp;
1315   void *p = stbds_hmget_key_ts(a, elemsize, key, keysize, &temp, mode);
1316   stbds_temp(STBDS_HASH_TO_ARR(p,elemsize)) = temp;
1317   return p;
1318 }
1319
1320 void * stbds_hmput_default(void *a, size_t elemsize)
1321 {
1322   // three cases:
1323   //   a is NULL <- allocate
1324   //   a has a hash table but no entries, because of shmode <- grow
1325   //   a has entries <- do nothing
1326   if (a == NULL || stbds_header(STBDS_HASH_TO_ARR(a,elemsize))->length == 0) {
1327     a = stbds_arrgrowf(a ? STBDS_HASH_TO_ARR(a,elemsize) : NULL, elemsize, 0, 1);
1328     stbds_header(a)->length += 1;
1329     memset(a, 0, elemsize);
1330     a=STBDS_ARR_TO_HASH(a,elemsize);
1331   }
1332   return a;
1333 }
1334
1335 static char *stbds_strdup(char *str);
1336
1337 void *stbds_hmput_key(void *a, size_t elemsize, void *key, size_t keysize, int mode)
1338 {
1339   size_t keyoffset=0;
1340   void *raw_a;
1341   stbds_hash_index *table;
1342
1343   if (a == NULL) {
1344     a = stbds_arrgrowf(0, elemsize, 0, 1);
1345     memset(a, 0, elemsize);
1346     stbds_header(a)->length += 1;
1347     // adjust a to point AFTER the default element
1348     a = STBDS_ARR_TO_HASH(a,elemsize);
1349   }
1350
1351   // adjust a to point to the default element
1352   raw_a = a;
1353   a = STBDS_HASH_TO_ARR(a,elemsize);
1354
1355   table = (stbds_hash_index *) stbds_header(a)->hash_table;
1356
1357   if (table == NULL || table->used_count >= table->used_count_threshold) {
1358     stbds_hash_index *nt;
1359     size_t slot_count;
1360
1361     slot_count = (table == NULL) ? STBDS_BUCKET_LENGTH : table->slot_count*2;
1362     nt = stbds_make_hash_index(slot_count, table);
1363     if (table)
1364       STBDS_FREE(NULL, table);
1365     else
1366       nt->string.mode = mode >= STBDS_HM_STRING ? STBDS_SH_DEFAULT : 0;
1367     stbds_header(a)->hash_table = table = nt;
1368     STBDS_STATS(++stbds_hash_grow);
1369   }
1370
1371   // we iterate hash table explicitly because we want to track if we saw a tombstone
1372   {
1373     size_t hash = mode >= STBDS_HM_STRING ? stbds_hash_string((char*)key,table->seed) : stbds_hash_bytes(key, keysize,table->seed);
1374     size_t step = STBDS_BUCKET_LENGTH;
1375     size_t pos;
1376     ptrdiff_t tombstone = -1;
1377     stbds_hash_bucket *bucket;
1378
1379     // stored hash values are forbidden from being 0, so we can detect empty slots to early out quickly
1380     if (hash < 2) hash += 2;
1381
1382     pos = stbds_probe_position(hash, table->slot_count, table->slot_count_log2);
1383
1384     for (;;) {
1385       size_t limit, i;
1386       STBDS_STATS(++stbds_hash_probes);
1387       bucket = &table->storage[pos >> STBDS_BUCKET_SHIFT];
1388
1389       // start searching from pos to end of bucket
1390       for (i=pos & STBDS_BUCKET_MASK; i < STBDS_BUCKET_LENGTH; ++i) {
1391         if (bucket->hash[i] == hash) {
1392           if (stbds_is_key_equal(raw_a, elemsize, key, keysize, keyoffset, mode, bucket->index[i])) {
1393             stbds_temp(a) = bucket->index[i];
1394             if (mode >= STBDS_HM_STRING)
1395               stbds_temp_key(a) = * (char **) ((char *) raw_a + elemsize*bucket->index[i] + keyoffset);
1396             return STBDS_ARR_TO_HASH(a,elemsize);
1397           }
1398         } else if (bucket->hash[i] == 0) {
1399           pos = (pos & ~STBDS_BUCKET_MASK) + i;
1400           goto found_empty_slot;
1401         } else if (tombstone < 0) {
1402           if (bucket->index[i] == STBDS_INDEX_DELETED)
1403             tombstone = (ptrdiff_t) ((pos & ~STBDS_BUCKET_MASK) + i);
1404         }
1405       }
1406
1407       // search from beginning of bucket to pos
1408       limit = pos & STBDS_BUCKET_MASK;
1409       for (i = 0; i < limit; ++i) {
1410         if (bucket->hash[i] == hash) {
1411           if (stbds_is_key_equal(raw_a, elemsize, key, keysize, keyoffset, mode, bucket->index[i])) {
1412             stbds_temp(a) = bucket->index[i];
1413             return STBDS_ARR_TO_HASH(a,elemsize);
1414           }
1415         } else if (bucket->hash[i] == 0) {
1416           pos = (pos & ~STBDS_BUCKET_MASK) + i;
1417           goto found_empty_slot;
1418         } else if (tombstone < 0) {
1419           if (bucket->index[i] == STBDS_INDEX_DELETED)
1420             tombstone = (ptrdiff_t) ((pos & ~STBDS_BUCKET_MASK) + i);
1421         }
1422       }
1423
1424       // quadratic probing
1425       pos += step;
1426       step += STBDS_BUCKET_LENGTH;
1427       pos &= (table->slot_count-1);
1428     }
1429    found_empty_slot:
1430     if (tombstone >= 0) {
1431       pos = tombstone;
1432       --table->tombstone_count;
1433     }
1434     ++table->used_count;
1435
1436     {
1437       ptrdiff_t i = (ptrdiff_t) stbds_arrlen(a);
1438       // we want to do stbds_arraddn(1), but we can't use the macros since we don't have something of the right type
1439       if ((size_t) i+1 > stbds_arrcap(a))
1440         *(void **) &a = stbds_arrgrowf(a, elemsize, 1, 0);
1441       raw_a = STBDS_ARR_TO_HASH(a,elemsize);
1442
1443       STBDS_ASSERT((size_t) i+1 <= stbds_arrcap(a));
1444       stbds_header(a)->length = i+1;
1445       bucket = &table->storage[pos >> STBDS_BUCKET_SHIFT];
1446       bucket->hash[pos & STBDS_BUCKET_MASK] = hash;
1447       bucket->index[pos & STBDS_BUCKET_MASK] = i-1;
1448       stbds_temp(a) = i-1;
1449
1450       switch (table->string.mode) {
1451          case STBDS_SH_STRDUP:  stbds_temp_key(a) = *(char **) ((char *) a + elemsize*i) = stbds_strdup((char*) key); break;
1452          case STBDS_SH_ARENA:   stbds_temp_key(a) = *(char **) ((char *) a + elemsize*i) = stbds_stralloc(&table->string, (char*)key); break;
1453          case STBDS_SH_DEFAULT: stbds_temp_key(a) = *(char **) ((char *) a + elemsize*i) = (char *) key; break;
1454          default:                memcpy((char *) a + elemsize*i, key, keysize); break;
1455       }
1456     }
1457     return STBDS_ARR_TO_HASH(a,elemsize);
1458   }
1459 }
1460
1461 void * stbds_shmode_func(size_t elemsize, int mode)
1462 {
1463   void *a = stbds_arrgrowf(0, elemsize, 0, 1);
1464   stbds_hash_index *h;
1465   memset(a, 0, elemsize);
1466   stbds_header(a)->length = 1;
1467   stbds_header(a)->hash_table = h = (stbds_hash_index *) stbds_make_hash_index(STBDS_BUCKET_LENGTH, NULL);
1468   h->string.mode = (unsigned char) mode;
1469   return STBDS_ARR_TO_HASH(a,elemsize);
1470 }
1471
1472 void * stbds_hmdel_key(void *a, size_t elemsize, void *key, size_t keysize, size_t keyoffset, int mode)
1473 {
1474   if (a == NULL) {
1475     return 0;
1476   } else {
1477     stbds_hash_index *table;
1478     void *raw_a = STBDS_HASH_TO_ARR(a,elemsize);
1479     table = (stbds_hash_index *) stbds_header(raw_a)->hash_table;
1480     stbds_temp(raw_a) = 0;
1481     if (table == 0) {
1482       return a;
1483     } else {
1484       ptrdiff_t slot;
1485       slot = stbds_hm_find_slot(a, elemsize, key, keysize, keyoffset, mode);
1486       if (slot < 0)
1487         return a;
1488       else {
1489         stbds_hash_bucket *b = &table->storage[slot >> STBDS_BUCKET_SHIFT];
1490         int i = slot & STBDS_BUCKET_MASK;
1491         ptrdiff_t old_index = b->index[i];
1492         ptrdiff_t final_index = (ptrdiff_t) stbds_arrlen(raw_a)-1-1; // minus one for the raw_a vs a, and minus one for 'last'
1493         STBDS_ASSERT(slot < (ptrdiff_t) table->slot_count);
1494         --table->used_count;
1495         ++table->tombstone_count;
1496         stbds_temp(raw_a) = 1;
1497         STBDS_ASSERT(table->used_count >= 0);
1498         //STBDS_ASSERT(table->tombstone_count < table->slot_count/4);
1499         b->hash[i] = STBDS_HASH_DELETED;
1500         b->index[i] = STBDS_INDEX_DELETED;
1501
1502         if (mode == STBDS_HM_STRING && table->string.mode == STBDS_SH_STRDUP)
1503           STBDS_FREE(NULL, *(char**) ((char *) a+elemsize*old_index));
1504
1505         // if indices are the same, memcpy is a no-op, but back-pointer-fixup will fail, so skip
1506         if (old_index != final_index) {
1507           // swap delete
1508           memmove((char*) a + elemsize*old_index, (char*) a + elemsize*final_index, elemsize);
1509
1510           // now find the slot for the last element
1511           if (mode == STBDS_HM_STRING)
1512             slot = stbds_hm_find_slot(a, elemsize, *(char**) ((char *) a+elemsize*old_index + keyoffset), keysize, keyoffset, mode);
1513           else
1514             slot = stbds_hm_find_slot(a, elemsize,  (char* ) a+elemsize*old_index + keyoffset, keysize, keyoffset, mode);
1515           STBDS_ASSERT(slot >= 0);
1516           b = &table->storage[slot >> STBDS_BUCKET_SHIFT];
1517           i = slot & STBDS_BUCKET_MASK;
1518           STBDS_ASSERT(b->index[i] == final_index);
1519           b->index[i] = old_index;
1520         }
1521         stbds_header(raw_a)->length -= 1;
1522
1523         if (table->used_count < table->used_count_shrink_threshold && table->slot_count > STBDS_BUCKET_LENGTH) {
1524           stbds_header(raw_a)->hash_table = stbds_make_hash_index(table->slot_count>>1, table);
1525           STBDS_FREE(NULL, table);
1526           STBDS_STATS(++stbds_hash_shrink);
1527         } else if (table->tombstone_count > table->tombstone_count_threshold) {
1528           stbds_header(raw_a)->hash_table = stbds_make_hash_index(table->slot_count   , table);
1529           STBDS_FREE(NULL, table);
1530           STBDS_STATS(++stbds_hash_rebuild);
1531         }
1532
1533         return a;
1534       }
1535     }
1536   }
1537   /* NOTREACHED */
1538 }
1539
1540 static char *stbds_strdup(char *str)
1541 {
1542   // to keep replaceable allocator simple, we don't want to use strdup.
1543   // rolling our own also avoids problem of strdup vs _strdup
1544   size_t len = strlen(str)+1;
1545   char *p = (char*) STBDS_REALLOC(NULL, 0, len);
1546   memmove(p, str, len);
1547   return p;
1548 }
1549
1550 #ifndef STBDS_STRING_ARENA_BLOCKSIZE_MIN
1551 #define STBDS_STRING_ARENA_BLOCKSIZE_MIN  512u
1552 #endif
1553 #ifndef STBDS_STRING_ARENA_BLOCKSIZE_MAX
1554 #define STBDS_STRING_ARENA_BLOCKSIZE_MAX  (1u<<20)
1555 #endif
1556
1557 char *stbds_stralloc(stbds_string_arena *a, char *str)
1558 {
1559   char *p;
1560   size_t len = strlen(str)+1;
1561   if (len > a->remaining) {
1562     // compute the next blocksize
1563     size_t blocksize = a->block;
1564
1565     // size is 512, 512, 1024, 1024, 2048, 2048, 4096, 4096, etc., so that
1566     // there are log(SIZE) allocations to free when we destroy the table
1567     blocksize = (size_t) (STBDS_STRING_ARENA_BLOCKSIZE_MIN) << (blocksize>>1);
1568
1569     // if size is under 1M, advance to next blocktype
1570     if (blocksize < (size_t)(STBDS_STRING_ARENA_BLOCKSIZE_MAX))
1571       ++a->block;
1572
1573     if (len > blocksize) {
1574       // if string is larger than blocksize, then just allocate the full size.
1575       // note that we still advance string_block so block size will continue
1576       // increasing, so e.g. if somebody only calls this with 1000-long strings,
1577       // eventually the arena will start doubling and handling those as well
1578       stbds_string_block *sb = (stbds_string_block *) STBDS_REALLOC(NULL, 0, sizeof(*sb)-8 + len);
1579       memmove(sb->storage, str, len);
1580       if (a->storage) {
1581         // insert it after the first element, so that we don't waste the space there
1582         sb->next = a->storage->next;
1583         a->storage->next = sb;
1584       } else {
1585         sb->next = 0;
1586         a->storage = sb;
1587         a->remaining = 0; // this is redundant, but good for clarity
1588       }
1589       return sb->storage;
1590     } else {
1591       stbds_string_block *sb = (stbds_string_block *) STBDS_REALLOC(NULL, 0, sizeof(*sb)-8 + blocksize);
1592       sb->next = a->storage;
1593       a->storage = sb;
1594       a->remaining = blocksize;
1595     }
1596   }
1597
1598   STBDS_ASSERT(len <= a->remaining);
1599   p = a->storage->storage + a->remaining - len;
1600   a->remaining -= len;
1601   memmove(p, str, len);
1602   return p;
1603 }
1604
1605 void stbds_strreset(stbds_string_arena *a)
1606 {
1607   stbds_string_block *x,*y;
1608   x = a->storage;
1609   while (x) {
1610     y = x->next;
1611     STBDS_FREE(NULL, x);
1612     x = y;
1613   }
1614   memset(a, 0, sizeof(*a));
1615 }
1616
1617 #endif
1618
1619 //////////////////////////////////////////////////////////////////////////////
1620 //
1621 //   UNIT TESTS
1622 //
1623
1624 #ifdef STBDS_UNIT_TESTS
1625 #include <stdio.h>
1626 #ifdef STBDS_ASSERT_WAS_UNDEFINED
1627 #undef STBDS_ASSERT
1628 #endif
1629 #ifndef STBDS_ASSERT
1630 #define STBDS_ASSERT assert
1631 #include <assert.h>
1632 #endif
1633
1634 typedef struct { int key,b,c,d; } stbds_struct;
1635 typedef struct { int key[2],b,c,d; } stbds_struct2;
1636
1637 static char buffer[256];
1638 char *strkey(int n)
1639 {
1640 #if defined(_WIN32) && defined(__STDC_WANT_SECURE_LIB__)
1641    sprintf_s(buffer, sizeof(buffer), "test_%d", n);
1642 #else
1643    sprintf(buffer, "test_%d", n);
1644 #endif
1645    return buffer;
1646 }
1647
1648 void stbds_unit_tests(void)
1649 {
1650 #if defined(_MSC_VER) && _MSC_VER <= 1200 && defined(__cplusplus)
1651   // VC6 C++ doesn't like the template<> trick on unnamed structures, so do nothing!
1652   STBDS_ASSERT(0);
1653 #else
1654   const int testsize = 100000;
1655   const int testsize2 = testsize/20;
1656   int *arr=NULL;
1657   struct { int   key;        int value; }  *intmap  = NULL;
1658   struct { char *key;        int value; }  *strmap  = NULL, s;
1659   struct { stbds_struct key; int value; }  *map     = NULL;
1660   stbds_struct                             *map2    = NULL;
1661   stbds_struct2                            *map3    = NULL;
1662   stbds_string_arena                        sa      = { 0 };
1663   int key3[2] = { 1,2 };
1664   ptrdiff_t temp;
1665
1666   int i,j;
1667
1668   STBDS_ASSERT(arrlen(arr)==0);
1669   for (i=0; i < 20000; i += 50) {
1670     for (j=0; j < i; ++j)
1671       arrpush(arr,j);
1672     arrfree(arr);
1673   }
1674
1675   for (i=0; i < 4; ++i) {
1676     arrpush(arr,1); arrpush(arr,2); arrpush(arr,3); arrpush(arr,4);
1677     arrdel(arr,i);
1678     arrfree(arr);
1679     arrpush(arr,1); arrpush(arr,2); arrpush(arr,3); arrpush(arr,4);
1680     arrdelswap(arr,i);
1681     arrfree(arr);
1682   }
1683
1684   for (i=0; i < 5; ++i) {
1685     arrpush(arr,1); arrpush(arr,2); arrpush(arr,3); arrpush(arr,4);
1686     stbds_arrins(arr,i,5);
1687     STBDS_ASSERT(arr[i] == 5);
1688     if (i < 4)
1689       STBDS_ASSERT(arr[4] == 4);
1690     arrfree(arr);
1691   }
1692
1693   i = 1;
1694   STBDS_ASSERT(hmgeti(intmap,i) == -1);
1695   hmdefault(intmap, -2);
1696   STBDS_ASSERT(hmgeti(intmap, i) == -1);
1697   STBDS_ASSERT(hmget (intmap, i) == -2);
1698   for (i=0; i < testsize; i+=2)
1699     hmput(intmap, i, i*5);
1700   for (i=0; i < testsize; i+=1) {
1701     if (i & 1) STBDS_ASSERT(hmget(intmap, i) == -2 );
1702     else       STBDS_ASSERT(hmget(intmap, i) == i*5);
1703     if (i & 1) STBDS_ASSERT(hmget_ts(intmap, i, temp) == -2 );
1704     else       STBDS_ASSERT(hmget_ts(intmap, i, temp) == i*5);
1705   }
1706   for (i=0; i < testsize; i+=2)
1707     hmput(intmap, i, i*3);
1708   for (i=0; i < testsize; i+=1)
1709     if (i & 1) STBDS_ASSERT(hmget(intmap, i) == -2 );
1710     else       STBDS_ASSERT(hmget(intmap, i) == i*3);
1711   for (i=2; i < testsize; i+=4)
1712     hmdel(intmap, i); // delete half the entries
1713   for (i=0; i < testsize; i+=1)
1714     if (i & 3) STBDS_ASSERT(hmget(intmap, i) == -2 );
1715     else       STBDS_ASSERT(hmget(intmap, i) == i*3);
1716   for (i=0; i < testsize; i+=1)
1717     hmdel(intmap, i); // delete the rest of the entries
1718   for (i=0; i < testsize; i+=1)
1719     STBDS_ASSERT(hmget(intmap, i) == -2 );
1720   hmfree(intmap);
1721   for (i=0; i < testsize; i+=2)
1722     hmput(intmap, i, i*3);
1723   hmfree(intmap);
1724
1725   #if defined(__clang__) || defined(__GNUC__)
1726   #ifndef __cplusplus
1727   intmap = NULL;
1728   hmput(intmap, 15, 7);
1729   hmput(intmap, 11, 3);
1730   hmput(intmap,  9, 5);
1731   STBDS_ASSERT(hmget(intmap, 9) == 5);
1732   STBDS_ASSERT(hmget(intmap, 11) == 3);
1733   STBDS_ASSERT(hmget(intmap, 15) == 7);
1734   #endif
1735   #endif
1736
1737   for (i=0; i < testsize; ++i)
1738     stralloc(&sa, strkey(i));
1739   strreset(&sa);
1740
1741   {
1742     s.key = "a", s.value = 1;
1743     shputs(strmap, s);
1744     STBDS_ASSERT(*strmap[0].key == 'a');
1745     STBDS_ASSERT(strmap[0].key == s.key);
1746     STBDS_ASSERT(strmap[0].value == s.value);
1747     shfree(strmap);
1748   }
1749
1750   {
1751     s.key = "a", s.value = 1;
1752     sh_new_strdup(strmap);
1753     shputs(strmap, s);
1754     STBDS_ASSERT(*strmap[0].key == 'a');
1755     STBDS_ASSERT(strmap[0].key != s.key);
1756     STBDS_ASSERT(strmap[0].value == s.value);
1757     shfree(strmap);
1758   }
1759
1760   {
1761     s.key = "a", s.value = 1;
1762     sh_new_arena(strmap);
1763     shputs(strmap, s);
1764     STBDS_ASSERT(*strmap[0].key == 'a');
1765     STBDS_ASSERT(strmap[0].key != s.key);
1766     STBDS_ASSERT(strmap[0].value == s.value);
1767     shfree(strmap);
1768   }
1769
1770   for (j=0; j < 2; ++j) {
1771     STBDS_ASSERT(shgeti(strmap,"foo") == -1);
1772     if (j == 0)
1773       sh_new_strdup(strmap);
1774     else
1775       sh_new_arena(strmap);
1776     STBDS_ASSERT(shgeti(strmap,"foo") == -1);
1777     shdefault(strmap, -2);
1778     STBDS_ASSERT(shgeti(strmap,"foo") == -1);
1779     for (i=0; i < testsize; i+=2)
1780       shput(strmap, strkey(i), i*3);
1781     for (i=0; i < testsize; i+=1)
1782       if (i & 1) STBDS_ASSERT(shget(strmap, strkey(i)) == -2 );
1783       else       STBDS_ASSERT(shget(strmap, strkey(i)) == i*3);
1784     for (i=2; i < testsize; i+=4)
1785       shdel(strmap, strkey(i)); // delete half the entries
1786     for (i=0; i < testsize; i+=1)
1787       if (i & 3) STBDS_ASSERT(shget(strmap, strkey(i)) == -2 );
1788       else       STBDS_ASSERT(shget(strmap, strkey(i)) == i*3);
1789     for (i=0; i < testsize; i+=1)
1790       shdel(strmap, strkey(i)); // delete the rest of the entries
1791     for (i=0; i < testsize; i+=1)
1792       STBDS_ASSERT(shget(strmap, strkey(i)) == -2 );
1793     shfree(strmap);
1794   }
1795
1796   {
1797     struct { char *key; char value; } *hash = NULL;
1798     char name[4] = "jen";
1799     shput(hash, "bob"   , 'h');
1800     shput(hash, "sally" , 'e');
1801     shput(hash, "fred"  , 'l');
1802     shput(hash, "jen"   , 'x');
1803     shput(hash, "doug"  , 'o');
1804
1805     shput(hash, name    , 'l');
1806     shfree(hash);
1807   }
1808
1809   for (i=0; i < testsize; i += 2) {
1810     stbds_struct s = { i,i*2,i*3,i*4 };
1811     hmput(map, s, i*5);
1812   }
1813
1814   for (i=0; i < testsize; i += 1) {
1815     stbds_struct s = { i,i*2,i*3  ,i*4 };
1816     stbds_struct t = { i,i*2,i*3+1,i*4 };
1817     if (i & 1) STBDS_ASSERT(hmget(map, s) == 0);
1818     else       STBDS_ASSERT(hmget(map, s) == i*5);
1819     if (i & 1) STBDS_ASSERT(hmget_ts(map, s, temp) == 0);
1820     else       STBDS_ASSERT(hmget_ts(map, s, temp) == i*5);
1821     //STBDS_ASSERT(hmget(map, t.key) == 0);
1822   }
1823
1824   for (i=0; i < testsize; i += 2) {
1825     stbds_struct s = { i,i*2,i*3,i*4 };
1826     hmputs(map2, s);
1827   }
1828   hmfree(map);
1829
1830   for (i=0; i < testsize; i += 1) {
1831     stbds_struct s = { i,i*2,i*3,i*4 };
1832     stbds_struct t = { i,i*2,i*3+1,i*4 };
1833     if (i & 1) STBDS_ASSERT(hmgets(map2, s.key).d == 0);
1834     else       STBDS_ASSERT(hmgets(map2, s.key).d == i*4);
1835     //STBDS_ASSERT(hmgetp(map2, t.key) == 0);
1836   }
1837   hmfree(map2);
1838
1839   for (i=0; i < testsize; i += 2) {
1840     stbds_struct2 s = { { i,i*2 }, i*3,i*4, i*5 };
1841     hmputs(map3, s);
1842   }
1843   for (i=0; i < testsize; i += 1) {
1844     stbds_struct2 s = { { i,i*2}, i*3, i*4, i*5 };
1845     stbds_struct2 t = { { i,i*2}, i*3+1, i*4, i*5 };
1846     if (i & 1) STBDS_ASSERT(hmgets(map3, s.key).d == 0);
1847     else       STBDS_ASSERT(hmgets(map3, s.key).d == i*5);
1848     //STBDS_ASSERT(hmgetp(map3, t.key) == 0);
1849   }
1850 #endif
1851 }
1852 #endif
1853
1854
1855 /*
1856 ------------------------------------------------------------------------------
1857 This software is available under 2 licenses -- choose whichever you prefer.
1858 ------------------------------------------------------------------------------
1859 ALTERNATIVE A - MIT License
1860 Copyright (c) 2019 Sean Barrett
1861 Permission is hereby granted, free of charge, to any person obtaining a copy of
1862 this software and associated documentation files (the "Software"), to deal in
1863 the Software without restriction, including without limitation the rights to
1864 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
1865 of the Software, and to permit persons to whom the Software is furnished to do
1866 so, subject to the following conditions:
1867 The above copyright notice and this permission notice shall be included in all
1868 copies or substantial portions of the Software.
1869 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1870 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1871 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1872 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1873 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1874 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1875 SOFTWARE.
1876 ------------------------------------------------------------------------------
1877 ALTERNATIVE B - Public Domain (www.unlicense.org)
1878 This is free and unencumbered software released into the public domain.
1879 Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
1880 software, either in source code form or as a compiled binary, for any purpose,
1881 commercial or non-commercial, and by any means.
1882 In jurisdictions that recognize copyright laws, the author or authors of this
1883 software dedicate any and all copyright interest in the software to the public
1884 domain. We make this dedication for the benefit of the public at large and to
1885 the detriment of our heirs and successors. We intend this dedication to be an
1886 overt act of relinquishment in perpetuity of all present and future rights to
1887 this software under copyright law.
1888 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1889 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1890 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1891 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
1892 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
1893 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1894 ------------------------------------------------------------------------------
1895 */