libdict 1.0.7
Data Structure C Library
Loading...
Searching...
No Matches
dict.c
Go to the documentation of this file.
1/*
2 * libdict -- generic dictionary implementation.
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#include "dict_private.h"
29
30#define XSTRINGIFY(x) STRINGIFY(x)
31#define STRINGIFY(x) #x
32
36
37void* (*dict_malloc_func)(size_t) = malloc;
38void (*dict_free_func)(void*) = free;
39
40int
41dict_int_cmp(const void* k1, const void* k2)
42{
43 const int a = *(const int*)k1;
44 const int b = *(const int*)k2;
45 return (a > b) - (a < b);
46}
47
48int
49dict_uint_cmp(const void* k1, const void* k2)
50{
51 const unsigned int a = *(const unsigned int*)k1;
52 const unsigned int b = *(const unsigned int*)k2;
53 return (a > b) - (a < b);
54}
55
56int
57dict_long_cmp(const void* k1, const void* k2)
58{
59 const long a = *(const long*)k1;
60 const long b = *(const long*)k2;
61 return (a > b) - (a < b);
62}
63
64int
65dict_ulong_cmp(const void* k1, const void* k2)
66{
67 const unsigned long a = *(const unsigned long*)k1;
68 const unsigned long b = *(const unsigned long*)k2;
69 return (a > b) - (a < b);
70}
71
72int
73dict_ptr_cmp(const void* k1, const void* k2)
74{
75 /* Relational operators on pointers into different objects are undefined
76 * (C11 6.5.8p5); comparing the converted integers is well defined. */
77 const uintptr_t a = (uintptr_t) k1;
78 const uintptr_t b = (uintptr_t) k2;
79 return (a > b) - (a < b);
80}
81
82int
83dict_str_cmp(const void* k1, const void* k2)
84{
85 /* Bytes must be compared as unsigned char, exactly as strcmp() is
86 * specified to: comparing as plain char makes 0xFF sort below 'a' where
87 * char is signed (x86) and above it where it is unsigned (ARM, PowerPC,
88 * s390x), so identical keys would sort differently on different targets. */
89 const unsigned char* a = k1;
90 const unsigned char* b = k2;
91
92 for (;;) {
93 unsigned char p = *a++, q = *b++;
94 if (!p || p != q)
95 return (p > q) - (p < q);
96 }
97}
98
99unsigned
100dict_str_hash(const void* k)
101{
102 /* FNV-1a string hash. */
103 unsigned hash = 2166136261U;
104 for (const uint8_t* ptr = k; *ptr;) {
105 hash = (hash ^ *ptr++) * 16777619U;
106 }
107 return hash;
108}
109
110size_t
112{
113 ASSERT(dct != NULL);
114
115 size_t count = dct->_vtable->dfree(dct->_object, delete_func);
116 FREE(dct);
117 return count;
118}
119
120void
122{
123 ASSERT(itor != NULL);
124
125 itor->_vtable->ifree(itor->_itor);
126 FREE(itor);
127}
int dict_ptr_cmp(const void *k1, const void *k2)
Definition dict.c:73
int dict_ulong_cmp(const void *k1, const void *k2)
Definition dict.c:65
size_t dict_free(dict *dct, dict_delete_func delete_func)
Definition dict.c:111
int dict_uint_cmp(const void *k1, const void *k2)
Definition dict.c:49
int dict_str_cmp(const void *k1, const void *k2)
Definition dict.c:83
unsigned dict_str_hash(const void *k)
FNV-1a hash of a NUL-terminated string, over its bytes in order, so a key hashes to the same value on...
Definition dict.c:100
#define XSTRINGIFY(x)
Definition dict.c:30
void dict_itor_free(dict_itor *itor)
Definition dict.c:121
int dict_long_cmp(const void *k1, const void *k2)
Definition dict.c:57
const char *const kDictVersionString
Definition dict.c:33
void(* dict_free_func)(void *)
A pointer to a function that libdict will use to deallocate memory.
Definition dict.c:38
int dict_int_cmp(const void *k1, const void *k2)
Comparison functions for common key types, for use as dict_compare_func.
Definition dict.c:41
#define DICT_VERSION_MINOR
Definition dict.h:49
void(* dict_delete_func)(void *, void *)
A pointer to a function that is called when a key-value pair gets removed from a dictionary.
Definition dict.h:62
#define DICT_VERSION_PATCH
Definition dict.h:50
#define DICT_VERSION_MAJOR
Definition dict.h:48
#define FREE(p)
#define ASSERT(expr)
void * _itor
Definition dict.h:235
const itor_vtable * _vtable
Definition dict.h:236
dict_dfree_func dfree
Definition dict.h:113
Definition dict.h:164
void * _object
Definition dict.h:165
const dict_vtable * _vtable
Definition dict.h:166
dict_ifree_func ifree
Definition dict.h:144