BRL-CAD
ptbl.h
Go to the documentation of this file.
1/* P T B L . H
2 * BRL-CAD
3 *
4 * Copyright (c) 2004-2023 United States Government as represented by
5 * the U.S. Army Research Laboratory.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * version 2.1 as published by the Free Software Foundation.
10 *
11 * This library is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this file; see the file named COPYING for more
18 * information.
19 */
20
21#ifndef BU_PTBL_H
22#define BU_PTBL_H
23
24#include "common.h"
25
26#include <stddef.h> /* for size_t */
27
28#include "bu/defines.h"
29#include "bu/magic.h"
30#include "bu/list.h"
31
32__BEGIN_DECLS
33
34/** @addtogroup bu_ptbl
35 *
36 * @brief
37 * Support for generalized "pointer tables", kept compactly in a
38 * dynamic array.
39 *
40 * The table is currently un-ordered, and is merely an array of
41 * pointers. The support routines BU_*PTBL* and bu_ptbl* manipulate the
42 * array for you. Pointers to be operated on (inserted, deleted, searched
43 * for) are passed as a "pointer to long".
44 *
45 */
46/** @{ */
47/** @file bu/ptbl.h*/
48
49
50/**
51 * Support for generalized "pointer tables".
52 */
53struct bu_ptbl {
54 struct bu_list l; /**< linked list for caller's use */
55 size_t end; /**< index into buffer of first available location */
56 size_t blen; /**< # of (long *)'s worth of storage at *buffer */
57 long **buffer; /**< data storage area */
58};
59typedef struct bu_ptbl bu_ptbl_t;
60#define BU_PTBL_NULL ((struct bu_ptbl *)0)
61
62/**
63 * assert the integrity of a bu_ptbl struct pointer.
64 */
65#define BU_CK_PTBL(_p) BU_CKMAG(_p, BU_PTBL_MAGIC, "bu_ptbl")
66
67/**
68 * initialize a bu_ptbl struct without allocating any memory. this
69 * macro is not suitable for initializing a list head node.
70 */
71#define BU_PTBL_INIT(_p) { \
72 BU_LIST_INIT_MAGIC(&(_p)->l, BU_PTBL_MAGIC); \
73 (_p)->end = 0; \
74 (_p)->blen = 0; \
75 (_p)->buffer = NULL; \
76 }
77
78/**
79 * macro suitable for declaration statement initialization of a
80 * bu_ptbl struct. does not allocate memory. not suitable for
81 * initializing a list head node.
82 */
83#define BU_PTBL_INIT_ZERO { {BU_PTBL_MAGIC, BU_LIST_NULL, BU_LIST_NULL}, 0, 0, NULL }
84
85/**
86 * returns truthfully whether a bu_ptbl has been initialized via
87 * BU_PTBL_INIT() or BU_PTBL_INIT_ZERO.
88 */
89#define BU_PTBL_IS_INITIALIZED(_p) (((struct bu_ptbl *)(_p) != BU_PTBL_NULL) && LIKELY((_p)->l.magic == BU_PTBL_MAGIC))
90
91
92/*
93 * For those routines that have to "peek" into the ptbl a little bit.
94 */
95#define BU_PTBL_LEN(ptbl) (((uintptr_t)(ptbl) != (uintptr_t)NULL)?(ptbl)->end:0)
96#define BU_PTBL_TEST(ptbl) (((uintptr_t)(ptbl) != (uintptr_t)NULL)?(ptbl)->l.magic == BU_PTBL_MAGIC:0)
97#define BU_PTBL_GET(ptbl, i) ((ptbl)->buffer[(i)])
98#define BU_PTBL_SET(ptbl, i, val) ((ptbl)->buffer[(i)] = (long*)(val))
99
100/** DEPRECATED */
101#define BU_PTBL_END(ptbl) ((ptbl)->end)
102/** DEPRECATED */
103#define BU_PTBL_BASEADDR(ptbl) (((uintptr_t)(ptbl) != (uintptr_t)NULL)?(ptbl)->buffer:NULL)
104/** DEPRECATED */
105#define BU_PTBL_LASTADDR(ptbl) (((uintptr_t)(ptbl) != (uintptr_t)NULL)?(ptbl)->buffer + (ptbl)->end - 1:NULL)
106
107/**
108 * A handy way to visit all the elements of the table is:
109 *
110 * struct edgeuse **eup;
111 * for (eup = (struct edgeuse **)BU_PTBL_LASTADDR(&eutab); eup >= (struct edgeuse **)BU_PTBL_BASEADDR(&eutab); eup--) {
112 * NMG_CK_EDGEUSE(*eup);
113 * }
114 * --- OR ---
115 * for (BU_PTBL_FOR(eup, (struct edgeuse **), &eutab)) {
116 * NMG_CK_EDGEUSE(*eup);
117 * }
118 */
119#define BU_PTBL_FOR(ip, cast, ptbl) \
120 ip = cast BU_PTBL_LASTADDR(ptbl); ip >= cast BU_PTBL_BASEADDR(ptbl); ip--
121
122/**
123 * This collection of routines implements a "pointer table" data
124 * structure providing a convenient mechanism for managing a collection
125 * of pointers to objects. This is useful where the size of the array
126 * is not known in advance and may change with time. It's convenient
127 * to be able to write code that can say "remember this object", and
128 * then later on iterate through the collection of remembered objects.
129 *
130 * When combined with the concept of placing "magic numbers" as the
131 * first field of each data structure, the pointers to the objects
132 * become automatically typed.
133 */
134
135/**
136 * Initialize struct & get storage for table.
137 * Recommend 8 or 64 for initial len.
138 */
139BU_EXPORT extern void bu_ptbl_init(struct bu_ptbl *b,
140 size_t len,
141 const char *str);
142
143/**
144 * Reset the table to have no elements, but retain any existing
145 * storage.
146 */
147BU_EXPORT extern void bu_ptbl_reset(struct bu_ptbl *b);
148
149/**
150 * Append/Insert a (long *) item to/into the table.
151 */
152BU_EXPORT extern size_t bu_ptbl_ins(struct bu_ptbl *b, long *p);
153
154/**
155 * locate a (long *) in an existing table
156 *
157 *
158 * @return index of first matching element in array, if found
159 * @return -1 if not found
160 *
161 * We do this a great deal, so make it go as fast as possible. this
162 * is the biggest argument I can make for changing to an ordered list.
163 * Someday....
164 */
165BU_EXPORT extern intmax_t bu_ptbl_locate(const struct bu_ptbl *b, const long *p);
166
167/**
168 * Set all occurrences of "p" in the table to zero. This is different
169 * than deleting them.
170 */
171BU_EXPORT extern void bu_ptbl_zero(struct bu_ptbl *b,
172 const long *p);
173
174/**
175 * Append item to table, if not already present. Unique insert.
176 *
177 * @return index of first matching element in array, if found. (table unchanged)
178 * @return -1 if table extended to hold new element
179 *
180 * We do this a great deal, so make it go as fast as possible. this
181 * is the biggest argument I can make for changing to an ordered list.
182 * Someday....
183 */
184BU_EXPORT extern intmax_t bu_ptbl_ins_unique(struct bu_ptbl *b, long *p);
185
186/**
187 * Remove all occurrences of an item from a table
188 *
189 * @return Number of copies of 'p' that were removed from the table.
190 * @return 0 if none found.
191 *
192 * we go backwards down the table looking for occurrences of p to
193 * delete. We do it backwards to reduce the amount of data moved when
194 * there is more than one occurrence of p in the table. A pittance
195 * savings, unless you're doing a lot of it.
196 */
197BU_EXPORT extern size_t bu_ptbl_rm(struct bu_ptbl *b, const long *p);
198
199/**
200 * Catenate one table onto end of another. There is no checking for
201 * duplication.
202 */
203BU_EXPORT extern void bu_ptbl_cat(struct bu_ptbl *dest,
204 const struct bu_ptbl *src);
205
206/**
207 * Catenate one table onto end of another, ensuring that no entry is
208 * duplicated. Duplications between multiple items in 'src' are not
209 * caught. The search is a nasty n**2 one. The tables are expected
210 * to be short.
211 */
212BU_EXPORT extern void bu_ptbl_cat_uniq(struct bu_ptbl *dest,
213 const struct bu_ptbl *src);
214
215/**
216 * Deallocate dynamic buffer associated with a table, and render this
217 * table unusable without a subsequent bu_ptbl_init().
218 */
219BU_EXPORT extern void bu_ptbl_free(struct bu_ptbl *b);
220
221/**
222 * Print a bu_ptbl array for inspection.
223 */
224BU_EXPORT extern void bu_pr_ptbl(const char *title,
225 const struct bu_ptbl *tbl,
226 int verbose);
227
228/**
229 * truncate a bu_ptbl to the specified size.
230 */
231BU_EXPORT extern void bu_ptbl_trunc(struct bu_ptbl *tbl, size_t end);
232
233/** @} */
234
235__END_DECLS
236
237#endif /* BU_PTBL_H */
238
239/*
240 * Local Variables:
241 * mode: C
242 * tab-width: 8
243 * indent-tabs-mode: t
244 * c-file-style: "stroustrup"
245 * End:
246 * ex: shiftwidth=4 tabstop=8
247 */
Header file for the BRL-CAD common definitions.
void bu_ptbl_cat(struct bu_ptbl *dest, const struct bu_ptbl *src)
size_t bu_ptbl_rm(struct bu_ptbl *b, const long *p)
void bu_ptbl_free(struct bu_ptbl *b)
intmax_t bu_ptbl_locate(const struct bu_ptbl *b, const long *p)
void bu_ptbl_trunc(struct bu_ptbl *tbl, size_t end)
void bu_ptbl_reset(struct bu_ptbl *b)
void bu_ptbl_cat_uniq(struct bu_ptbl *dest, const struct bu_ptbl *src)
size_t bu_ptbl_ins(struct bu_ptbl *b, long *p)
intmax_t bu_ptbl_ins_unique(struct bu_ptbl *b, long *p)
void bu_ptbl_init(struct bu_ptbl *b, size_t len, const char *str)
void bu_pr_ptbl(const char *title, const struct bu_ptbl *tbl, int verbose)
void bu_ptbl_zero(struct bu_ptbl *b, const long *p)
Global registry of recognized magic numbers.
Definition: list.h:131
Definition: ptbl.h:53
size_t blen
Definition: ptbl.h:56
long ** buffer
Definition: ptbl.h:57
struct bu_list l
Definition: ptbl.h:54
size_t end
Definition: ptbl.h:55