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 #if defined(_MSC_VER)
41 typedef unsigned tommy_uint32_t;
42 typedef unsigned _int64 tommy_uint64_t;
43 typedef size_t tommy_uintptr_t;
44 #else
45 #include <stdint.h>
46 typedef uint32_t tommy_uint32_t;
47 typedef uint64_t tommy_uint64_t;
48 typedef uintptr_t tommy_uintptr_t;
49 #endif
50 typedef size_t tommy_size_t;
51 typedef ptrdiff_t tommy_ptrdiff_t;
52 typedef int tommy_bool_t;
61 
68 
74 #ifdef __cplusplus
75 #define tommy_cast(type, value) static_cast<type>(value)
76 #else
77 #define tommy_cast(type, value) (value)
78 #endif
79 
80 /******************************************************************************/
81 /* heap */
82 
83 /* by default uses malloc/calloc/realloc/free */
84 
89 #if !defined(tommy_malloc) || !defined(tommy_calloc) || !defined(tommy_realloc) || !defined(tommy_free)
90 #include <stdlib.h>
91 #endif
92 #if !defined(tommy_malloc)
93 #define tommy_malloc malloc
94 #endif
95 #if !defined(tommy_calloc)
96 #define tommy_calloc calloc
97 #endif
98 #if !defined(tommy_realloc)
99 #define tommy_realloc realloc
100 #endif
101 #if !defined(tommy_free)
102 #define tommy_free free
103 #endif
104 
105 /******************************************************************************/
106 /* modificators */
107 
111 #if !defined(tommy_inline)
112 #if defined(_MSC_VER) || defined(__GNUC__)
113 #define tommy_inline static __inline
114 #else
115 #define tommy_inline static
116 #endif
117 #endif
118 
122 #if !defined(tommy_restrict)
123 #if __STDC_VERSION__ >= 199901L
124 #define tommy_restrict restrict
125 #elif defined(_MSC_VER) || defined(__GNUC__)
126 #define tommy_restrict __restrict
127 #else
128 #define tommy_restrict
129 #endif
130 #endif
131 
135 #if !defined(tommy_likely)
136 #if defined(__GNUC__)
137 #define tommy_likely(x) __builtin_expect(!!(x), 1)
138 #else
139 #define tommy_likely(x) (x)
140 #endif
141 #endif
142 
146 #if !defined(tommy_unlikely)
147 #if defined(__GNUC__)
148 #define tommy_unlikely(x) __builtin_expect(!!(x), 0)
149 #else
150 #define tommy_unlikely(x) (x)
151 #endif
152 #endif
153 
154 /******************************************************************************/
155 /* key */
156 
161 
165 #define TOMMY_KEY_BIT (sizeof(tommy_key_t) * 8)
166 
167 /******************************************************************************/
168 /* node */
169 
183 typedef struct tommy_node_struct {
189 
195 
200  void* data;
201 
208 } tommy_node;
209 
210 /******************************************************************************/
211 /* compare */
212 
240 typedef int tommy_compare_func(const void* obj_a, const void* obj_b);
241 
278 typedef int tommy_search_func(const void* arg, const void* obj);
279 
289 typedef void tommy_foreach_func(void* obj);
290 
296 typedef void tommy_foreach_arg_func(void* arg, void* obj);
297 
298 /******************************************************************************/
299 /* bit hacks */
300 
301 #if defined(_MSC_VER) && !defined(__cplusplus)
302 #include <intrin.h>
303 #pragma intrinsic(_BitScanReverse)
304 #pragma intrinsic(_BitScanForward)
305 #endif
306 
311 #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)
312 
332 {
333 #if defined(_MSC_VER)
334  unsigned long count;
335  _BitScanReverse(&count, value);
336  return count;
337 #elif defined(__GNUC__)
338  /*
339  * GCC implements __builtin_clz(x) as "__builtin_clz(x) = bsr(x) ^ 31"
340  *
341  * Where "x ^ 31 = 31 - x", but gcc does not optimize "31 - __builtin_clz(x)" to bsr(x),
342  * but generates 31 - (bsr(x) xor 31).
343  *
344  * So we write "__builtin_clz(x) ^ 31" instead of "31 - __builtin_clz(x)",
345  * to allow the double xor to be optimized out.
346  */
347  return __builtin_clz(value) ^ 31;
348 #else
349  /* Find the log base 2 of an N-bit integer in O(lg(N)) operations with multiply and lookup */
350  /* from http://graphics.stanford.edu/~seander/bithacks.html */
351  static unsigned char TOMMY_DE_BRUIJN_INDEX_ILOG2[32] = {
352  0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
353  8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
354  };
355 
356  value |= value >> 1;
357  value |= value >> 2;
358  value |= value >> 4;
359  value |= value >> 8;
360  value |= value >> 16;
361 
362  return TOMMY_DE_BRUIJN_INDEX_ILOG2[(tommy_uint32_t)(value * 0x07C4ACDDU) >> 27];
363 #endif
364 }
365 
375 {
376 #if defined(_MSC_VER)
377  unsigned long count;
378  _BitScanForward(&count, value);
379  return count;
380 #elif defined(__GNUC__)
381  return __builtin_ctz(value);
382 #else
383  /* Count the consecutive zero bits (trailing) on the right with multiply and lookup */
384  /* from http://graphics.stanford.edu/~seander/bithacks.html */
385  static const unsigned char TOMMY_DE_BRUIJN_INDEX_CTZ[32] = {
386  0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
387  31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
388  };
389 
390  return TOMMY_DE_BRUIJN_INDEX_CTZ[(tommy_uint32_t)(((value & - value) * 0x077CB531U)) >> 27];
391 #endif
392 }
393 
400 {
401  /* Round up to the next highest power of 2 */
402  /* from http://graphics.stanford.edu/~seander/bithacks.html */
403 
404  --value;
405  value |= value >> 1;
406  value |= value >> 2;
407  value |= value >> 4;
408  value |= value >> 8;
409  value |= value >> 16;
410  ++value;
411 
412  return value;
413 }
414 
419 tommy_inline int tommy_haszero_u32(tommy_uint32_t value)
420 {
421  return ((value - 0x01010101) & ~value & 0x80808080) != 0;
422 }
423 #endif
424 
struct tommy_node_struct tommy_node
Data structure node.
tommy_uint_t tommy_ctz_u32(tommy_uint32_t value)
Bit scan forward or trailing zero count.
Definition: tommytypes.h:374
tommy_uint_t tommy_ilog2_u32(tommy_uint32_t value)
Bit scan reverse or integer log2.
Definition: tommytypes.h:331
tommy_uint32_t tommy_key_t
Key type used in indexed data structures to store the key or the hash value.
Definition: tommytypes.h:160
tommy_uint32_t tommy_count_t
Generic unsigned integer for counting objects.
Definition: tommytypes.h:67
uint32_t tommy_uint32_t
Generic uint32_t type.
Definition: tommytypes.h:46
ptrdiff_t tommy_ptrdiff_t
Generic ptrdiff_t type.
Definition: tommytypes.h:51
struct tommy_node_struct * next
Next node.
Definition: tommytypes.h:188
struct tommy_node_struct * prev
Previous node.
Definition: tommytypes.h:194
uintptr_t tommy_uintptr_t
Generic uintptr_t type.
Definition: tommytypes.h:48
int tommy_search_func(const void *arg, const void *obj)
Search function for elements.
Definition: tommytypes.h:278
int tommy_compare_func(const void *obj_a, const void *obj_b)
Compare function for elements.
Definition: tommytypes.h:240
int tommy_haszero_u32(tommy_uint32_t value)
Check if the specified word has a byte at 0.
Definition: tommytypes.h:419
tommy_uint32_t tommy_uint_t
Generic unsigned integer type.
Definition: tommytypes.h:60
Data structure node.
Definition: tommytypes.h:183
void tommy_foreach_func(void *obj)
Foreach function.
Definition: tommytypes.h:289
void * data
Pointer to the object containing the node.
Definition: tommytypes.h:200
size_t tommy_size_t
Generic size_t type.
Definition: tommytypes.h:50
uint64_t tommy_uint64_t
Generic uint64_t type.
Definition: tommytypes.h:47
tommy_uint32_t tommy_roundup_pow2_u32(tommy_uint32_t value)
Rounds up to the next power of 2.
Definition: tommytypes.h:399
int tommy_bool_t
Generic boolean type.
Definition: tommytypes.h:52
tommy_key_t key
Key used to store the node.
Definition: tommytypes.h:207
void tommy_foreach_arg_func(void *arg, void *obj)
Foreach function with an argument.
Definition: tommytypes.h:296