libdict 1.0.7
Data Structure C Library
Loading...
Searching...
No Matches
dict_private.h
Go to the documentation of this file.
1/*
2 * libdict - private definitions.
3 *
4 * Copyright (c) 2001-2014, Farooq Mela
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#ifndef LIBDICT_DICT_PRIVATE_H__
29#define LIBDICT_DICT_PRIVATE_H__
30
31#include <stdio.h>
32#include <stdlib.h>
33
34#include "dict.h"
35
36/* A feature (or bug) of this macro is that the expression is always evaluated,
37 * regardless of whether NDEBUG is defined or not. This is intentional and
38 * sometimes useful. */
39#ifndef NDEBUG
40# undef ASSERT
41# if defined(__GNUC__) || defined(__clang__)
42# define ASSERT(expr) \
43 do { \
44 if (!__builtin_expect((expr), 1)) { \
45 fprintf(stderr, "\n%s:%d (%s) assertion failed: %s\n", \
46 __FILE__, __LINE__, __func__, #expr); \
47 abort(); \
48 } \
49 } while (0)
50# else
51# define ASSERT(expr) \
52 do { \
53 if (!(expr)) { \
54 fprintf(stderr, "\n%s:%d assertion failed: %s\n", \
55 __FILE__, __LINE__, #expr); \
56 abort(); \
57 } \
58 } while (0)
59# endif
60#else
61# define ASSERT(expr) (void)(expr)
62#endif
63
64#if defined(__GNUC__) || defined(__clang__)
65# define LIKELY(expr) __builtin_expect((expr), 1)
66# define UNLIKELY(expr) __builtin_expect((expr), 0)
67# define VERIFY(expr) \
68 do { \
69 if (!__builtin_expect((expr), 1)) { \
70 fprintf(stderr, "\n%s:%d (%s) verification failed: %s\n", \
71 __FILE__, __LINE__, __func__, #expr); \
72 return false; \
73 } \
74 } while (0)
75#else
76# define LIKELY(expr) (expr)
77# define UNLIKELY(expr) (expr)
78# define VERIFY(expr) \
79 do { \
80 if (!(expr)) { \
81 fprintf(stderr, "\n%s:%d verification failed: %s\n", \
82 __FILE__, __LINE__, #expr); \
83 return false; \
84 } \
85 } while (0)
86#endif
87
88#define MALLOC(n) (*dict_malloc_func)(n)
89#define FREE(p) (*dict_free_func)(p)
90
91#define ABS(a) ((a) < 0 ? -(a) : (a))
92#define MIN(a,b) ((a) < (b) ? (a) : (b))
93#define MAX(a,b) ((a) > (b) ? (a) : (b))
94#define SWAP(a,b,v) do { v = (a); (a) = (b); (b) = v; } while (0)
95
96#if defined(__GNUC__) || defined(__clang__)
97# define GCC_INLINE __inline__
98# define GCC_CONST __attribute__((__const__))
99#else
100# define GCC_INLINE
101# define GCC_CONST
102#endif
103
104extern long random(void);
105static inline unsigned dict_rand(void) { return (unsigned) random(); }
106
107/* Number of low-order bits of dict_rand() that are usable: random() is
108 * specified to return a value in [0, 2^31), so the top bit of an unsigned is
109 * always clear. */
110#define DICT_RAND_BITS 31
111
112/* Count trailing zero bits of |n|, which must be nonzero. Unlike
113 * __builtin_ctz() this is available on every toolchain. */
114static inline unsigned
115dict_ctz(unsigned n)
116{
117 ASSERT(n != 0);
118#if defined(__GNUC__) || defined(__clang__)
119 return (unsigned) __builtin_ctz(n);
120#else
121 unsigned count = 0;
122 while (!(n & 1u)) {
123 n >>= 1;
124 ++count;
125 }
126 return count;
127#endif
128}
129
130/* Allocate an array of |n| elements of |size| bytes, or return NULL if the
131 * byte count does not fit in a size_t, as it may not where size_t is 32 bits.
132 * Without the check the product would wrap and allocate a short array. */
133static inline void*
134dict_malloc_array(size_t n, size_t size)
135{
136 if (size && n > SIZE_MAX / size)
137 return NULL;
138 return MALLOC(n * size);
139}
140
141/* Drop const from a key pointer for the void*-returning dict_key_func slot.
142 * Round-tripping through uintptr_t is well defined and, unlike a direct cast,
143 * does not trigger -Wcast-qual. */
144static inline void* dict_unconst(const void* p) { return (void*)(uintptr_t)p; }
145
146#endif /* !LIBDICT_DICT_PRIVATE_H__ */
long random(void)
#define ASSERT(expr)
#define MALLOC(n)