tommytypes.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010, Andrea Mazzoleni. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
32#ifndef __TOMMYTYPES_H
33#define __TOMMYTYPES_H
34
35/******************************************************************************/
36/* types */
37
38#include <stddef.h>
39
40#ifdef _MSC_VER
41typedef unsigned tommy_uint32_t;
42typedef unsigned _int64 tommy_uint64_t;
43typedef size_t tommy_uintptr_t;
44#ifdef _WIN64
45#define TOMMY_SIZE_BIT 64
46typedef unsigned _int64 tommy_size_t;
47typedef _int64 tommy_ssize_t;
48#else
49#define TOMMY_SIZE_BIT 32
50typedef unsigned tommy_size_t;
51typedef int tommy_ssize_t;
52#endif
53#else
54#include <stdint.h>
55typedef uint32_t tommy_uint32_t;
56typedef uint64_t tommy_uint64_t;
57typedef uintptr_t tommy_uintptr_t;
58#if SIZE_MAX == UINT64_MAX
59#define TOMMY_SIZE_BIT 64
60typedef uint64_t tommy_size_t;
61typedef int64_t tommy_ssize_t;
62#elif SIZE_MAX == UINT32_MAX
63#define TOMMY_SIZE_BIT 32
64typedef uint32_t tommy_size_t;
65typedef int32_t tommy_ssize_t;
66#else
67#error Unsupported SIZE_MAX
68#endif
69#endif
70
71typedef ptrdiff_t tommy_ptrdiff_t;
72typedef int tommy_bool_t;
81
94#ifdef __cplusplus
95#define tommy_cast(type, value) static_cast<type>(value)
96#else
97#define tommy_cast(type, value) (value)
98#endif
99
100/******************************************************************************/
101/* heap */
102
103/* by default uses malloc/calloc/realloc/free */
104
109#if !defined(tommy_malloc) || !defined(tommy_calloc) || !defined(tommy_realloc) || !defined(tommy_free)
110#include <stdlib.h>
111#endif
112#if !defined(tommy_malloc)
113#define tommy_malloc malloc
114#endif
115#if !defined(tommy_calloc)
116#define tommy_calloc calloc
117#endif
118#if !defined(tommy_realloc)
119#define tommy_realloc realloc
120#endif
121#if !defined(tommy_free)
122#define tommy_free free
123#endif
124
125/******************************************************************************/
126/* modificators */
127
132#if !defined(TOMMY_API)
133#define TOMMY_API
134#endif
135
139#if !defined(tommy_inline)
140#if defined(_MSC_VER) || defined(__GNUC__)
141#define tommy_inline static __inline
142#else
143#define tommy_inline static
144#endif
145#endif
146
150#if !defined(tommy_restrict)
151#if __STDC_VERSION__ >= 199901L
152#define tommy_restrict restrict
153#elif defined(_MSC_VER) || defined(__GNUC__)
154#define tommy_restrict __restrict
155#else
156#define tommy_restrict
157#endif
158#endif
159
163#if !defined(tommy_likely)
164#if defined(__GNUC__)
165#define tommy_likely(x) __builtin_expect(!!(x), 1)
166#else
167#define tommy_likely(x) (x)
168#endif
169#endif
170
174#if !defined(tommy_unlikely)
175#if defined(__GNUC__)
176#define tommy_unlikely(x) __builtin_expect(!!(x), 0)
177#else
178#define tommy_unlikely(x) (x)
179#endif
180#endif
181
182/******************************************************************************/
183/* key/hash */
184
189
194
195/******************************************************************************/
196/* node */
197
211typedef struct tommy_node_struct {
217
223
228 void* data;
229
238
239/******************************************************************************/
240/* compare */
241
269typedef int tommy_compare_func(const void* obj_a, const void* obj_b);
270
307typedef int tommy_search_func(const void* arg, const void* obj);
308
318typedef void tommy_foreach_func(void* obj);
319
325typedef void tommy_foreach_arg_func(void* arg, void* obj);
326
327/******************************************************************************/
328/* bit hacks */
329
330#if defined(_MSC_VER) && !defined(__cplusplus)
331#include <intrin.h>
332#pragma intrinsic(_BitScanReverse)
333#pragma intrinsic(_BitScanForward)
334#if TOMMY_SIZE_BIT == 64
335#pragma intrinsic(_BitScanReverse64)
336#pragma intrinsic(_BitScanForward64)
337#endif
338#endif
339
344#define TOMMY_ILOG2(value) ((value) == 256 ? 8 : (value) == 128 ? 7 : (value) == 64 ? 6 : (value) == 32 ? 5 : (value) == 16 ? 4 : (value) == 8 ? 3 : (value) == 4 ? 2 : (value) == 2 ? 1 : 0)
345
365{
366#if defined(_MSC_VER)
367 unsigned long count;
368 _BitScanReverse(&count, value);
369 return count;
370#elif defined(__GNUC__)
371 /*
372 * GCC implements __builtin_clz(x) as "__builtin_clz(x) = bsr(x) ^ 31"
373 *
374 * Where "x ^ 31 = 31 - x", but gcc does not optimize "31 - __builtin_clz(x)" to bsr(x),
375 * but generates 31 - (bsr(x) xor 31).
376 *
377 * So we write "__builtin_clz(x) ^ 31" instead of "31 - __builtin_clz(x)",
378 * to allow the double xor to be optimized out.
379 */
380 return __builtin_clz(value) ^ 31;
381#else
382 /* Find the log base 2 of an N-bit integer in O(lg(N)) operations with multiply and lookup */
383 /* from http://graphics.stanford.edu/~seander/bithacks.html */
384 static unsigned char TOMMY_DE_BRUIJN_INDEX_ILOG2[32] = {
385 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
386 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
387 };
388
389 value |= value >> 1;
390 value |= value >> 2;
391 value |= value >> 4;
392 value |= value >> 8;
393 value |= value >> 16;
394
395 return TOMMY_DE_BRUIJN_INDEX_ILOG2[(tommy_uint32_t)(value * 0x07C4ACDDU) >> 27];
396#endif
397}
398
399#if TOMMY_SIZE_BIT == 64
404{
405#if defined(_MSC_VER)
406 unsigned long count;
407 _BitScanReverse64(&count, value);
408 return count;
409#elif defined(__GNUC__)
410 return __builtin_clzll(value) ^ 63;
411#else
412 tommy_uint32_t l = value & 0xFFFFFFFFU;
413 tommy_uint32_t h = value >> 32;
414 if (h)
415 return tommy_ilog2_u32(h) + 32;
416 else
417 return tommy_ilog2_u32(l);
418#endif
419}
420#endif
421
431{
432#if defined(_MSC_VER)
433 unsigned long count;
434 _BitScanForward(&count, value);
435 return count;
436#elif defined(__GNUC__)
437 return __builtin_ctz(value);
438#else
439 /* Count the consecutive zero bits (trailing) on the right with multiply and lookup */
440 /* from http://graphics.stanford.edu/~seander/bithacks.html */
441 static const unsigned char TOMMY_DE_BRUIJN_INDEX_CTZ[32] = {
442 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
443 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
444 };
445
446 return TOMMY_DE_BRUIJN_INDEX_CTZ[(tommy_uint32_t)(((value & - value) * 0x077CB531U)) >> 27];
447#endif
448}
449
450#if TOMMY_SIZE_BIT == 64
455{
456#if defined(_MSC_VER)
457 unsigned long count;
458 _BitScanForward64(&count, value);
459 return count;
460#elif defined(__GNUC__)
461 return __builtin_ctzll(value);
462#else
463 tommy_uint32_t l = value & 0xFFFFFFFFU;
464 tommy_uint32_t h = value >> 32;
465 if (l)
466 return tommy_ctz_u32(l);
467 else
468 return tommy_ctz_u32(h) + 32;
469#endif
470}
471#endif
472
479{
480 /* Round up to the next highest power of 2 */
481 /* from http://graphics.stanford.edu/~seander/bithacks.html */
482
483 --value;
484 value |= value >> 1;
485 value |= value >> 2;
486 value |= value >> 4;
487 value |= value >> 8;
488 value |= value >> 16;
489 ++value;
490
491 return value;
492}
493
498{
499 --value;
500 value |= value >> 1;
501 value |= value >> 2;
502 value |= value >> 4;
503 value |= value >> 8;
504 value |= value >> 16;
505 value |= value >> 32;
506 ++value;
507
508 return value;
509}
510
515tommy_inline int tommy_haszero_u32(tommy_uint32_t value)
516{
517 return ((value - 0x01010101) & ~value & 0x80808080) != 0;
518}
519
520/*
521 * Bit depth mapping.
522 */
523#if TOMMY_SIZE_BIT == 64
524#define tommy_ilog2 tommy_ilog2_u64
525#define tommy_ctz tommy_ctz_u64
526#define tommy_roundup_pow2 tommy_roundup_pow2_u64
527#else
528#define tommy_ilog2 tommy_ilog2_u32
529#define tommy_ctz tommy_ctz_u32
530#define tommy_roundup_pow2 tommy_roundup_pow2_u32
531#endif
532
533#endif
Data structure node.
Definition: tommytypes.h:211
tommy_size_t index
Index of the node.
Definition: tommytypes.h:236
struct tommy_node_struct * next
Next node.
Definition: tommytypes.h:216
struct tommy_node_struct * prev
Previous node.
Definition: tommytypes.h:222
void * data
Pointer to the object containing the node.
Definition: tommytypes.h:228
uint64_t tommy_uint64_t
Generic uint64_t type.
Definition: tommytypes.h:56
struct tommy_node_struct tommy_node
Data structure node.
uint32_t tommy_uint32_t
Generic uint32_t type.
Definition: tommytypes.h:55
int tommy_compare_func(const void *obj_a, const void *obj_b)
Compare function for elements.
Definition: tommytypes.h:269
int tommy_haszero_u32(tommy_uint32_t value)
Check if the specified word has a byte at 0.
Definition: tommytypes.h:515
tommy_uint_t tommy_ctz_u32(tommy_uint32_t value)
Bit scan forward or trailing zero count.
Definition: tommytypes.h:430
tommy_uint64_t tommy_roundup_pow2_u64(tommy_uint64_t value)
Rounds up to the next power of 2 for 64 bits.
Definition: tommytypes.h:497
tommy_uint_t tommy_ctz_u64(tommy_uint64_t value)
Bit scan forward or trailing zero count for 64 bits.
Definition: tommytypes.h:454
ptrdiff_t tommy_ptrdiff_t
Generic ptrdiff_t type.
Definition: tommytypes.h:71
uint64_t tommy_size_t
Generic size_t type.
Definition: tommytypes.h:60
void tommy_foreach_func(void *obj)
Foreach function.
Definition: tommytypes.h:318
int tommy_search_func(const void *arg, const void *obj)
Search function for elements.
Definition: tommytypes.h:307
tommy_uint32_t tommy_roundup_pow2_u32(tommy_uint32_t value)
Rounds up to the next power of 2.
Definition: tommytypes.h:478
tommy_uint_t tommy_ilog2_u32(tommy_uint32_t value)
Bit scan reverse or integer log2.
Definition: tommytypes.h:364
int64_t tommy_ssize_t
Generic ssize_t type.
Definition: tommytypes.h:61
void tommy_foreach_arg_func(void *arg, void *obj)
Foreach function with an argument.
Definition: tommytypes.h:325
tommy_size_t tommy_hash_t
Type used in hashtables to store the hash of an object.
Definition: tommytypes.h:193
tommy_size_t tommy_key_t
Type used in indexed data structures to store the key of an object.
Definition: tommytypes.h:188
tommy_uint32_t tommy_uint_t
Generic unsigned integer type.
Definition: tommytypes.h:80
uintptr_t tommy_uintptr_t
Generic uintptr_t type.
Definition: tommytypes.h:57
tommy_uint_t tommy_ilog2_u64(tommy_uint64_t value)
Bit scan reverse or integer log2 for 64 bits.
Definition: tommytypes.h:403
int tommy_bool_t
Generic boolean type.
Definition: tommytypes.h:72