BRL-CAD
|
Support for generalized "pointer tables", kept compactly in a dynamic array. More...
Files | |
file | ptbl.h |
Data Structures | |
struct | bu_ptbl |
Typedefs | |
typedef struct bu_ptbl | bu_ptbl_t |
Functions | |
void | bu_ptbl_init (struct bu_ptbl *b, size_t len, const char *str) |
void | bu_ptbl_reset (struct bu_ptbl *b) |
size_t | bu_ptbl_ins (struct bu_ptbl *b, long *p) |
intmax_t | bu_ptbl_locate (const struct bu_ptbl *b, const long *p) |
void | bu_ptbl_zero (struct bu_ptbl *b, const long *p) |
intmax_t | bu_ptbl_ins_unique (struct bu_ptbl *b, long *p) |
size_t | bu_ptbl_rm (struct bu_ptbl *b, const long *p) |
void | bu_ptbl_cat (struct bu_ptbl *dest, const struct bu_ptbl *src) |
void | bu_ptbl_cat_uniq (struct bu_ptbl *dest, const struct bu_ptbl *src) |
void | bu_ptbl_free (struct bu_ptbl *b) |
void | bu_pr_ptbl (const char *title, const struct bu_ptbl *tbl, int verbose) |
void | bu_ptbl_trunc (struct bu_ptbl *tbl, size_t end) |
Support for generalized "pointer tables", kept compactly in a dynamic array.
The table is currently un-ordered, and is merely an array of pointers. The support routines BU_*PTBL* and bu_ptbl* manipulate the array for you. Pointers to be operated on (inserted, deleted, searched for) are passed as a "pointer to long".
#define BU_CK_PTBL | ( | _p | ) | BU_CKMAG(_p, BU_PTBL_MAGIC, "bu_ptbl") |
#define BU_PTBL_INIT_ZERO { {BU_PTBL_MAGIC, BU_LIST_NULL, BU_LIST_NULL}, 0, 0, NULL } |
#define BU_PTBL_IS_INITIALIZED | ( | _p | ) | (((struct bu_ptbl *)(_p) != BU_PTBL_NULL) && LIKELY((_p)->l.magic == BU_PTBL_MAGIC)) |
returns truthfully whether a bu_ptbl has been initialized via BU_PTBL_INIT() or BU_PTBL_INIT_ZERO.
#define BU_PTBL_FOR | ( | ip, | |
cast, | |||
ptbl | |||
) | ip = cast BU_PTBL_LASTADDR(ptbl); ip >= cast BU_PTBL_BASEADDR(ptbl); ip-- |
A handy way to visit all the elements of the table is:
struct edgeuse **eup; for (eup = (struct edgeuse **)BU_PTBL_LASTADDR(&eutab); eup >= (struct edgeuse **)BU_PTBL_BASEADDR(&eutab); eup–) { NMG_CK_EDGEUSE(*eup); } — OR — for (BU_PTBL_FOR(eup, (struct edgeuse **), &eutab)) { NMG_CK_EDGEUSE(*eup); }
This collection of routines implements a "pointer table" data structure providing a convenient mechanism for managing a collection of pointers to objects. This is useful where the size of the array is not known in advance and may change with time. It's convenient to be able to write code that can say "remember this object", and then later on iterate through the collection of remembered objects.
When combined with the concept of placing "magic numbers" as the first field of each data structure, the pointers to the objects become automatically typed. Initialize struct & get storage for table. Recommend 8 or 64 for initial len.
Reset the table to have no elements, but retain any existing storage.
Append/Insert a (long *) item to/into the table.
locate a (long *) in an existing table
We do this a great deal, so make it go as fast as possible. this is the biggest argument I can make for changing to an ordered list. Someday....
Set all occurrences of "p" in the table to zero. This is different than deleting them.
Append item to table, if not already present. Unique insert.
We do this a great deal, so make it go as fast as possible. this is the biggest argument I can make for changing to an ordered list. Someday....
Remove all occurrences of an item from a table
we go backwards down the table looking for occurrences of p to delete. We do it backwards to reduce the amount of data moved when there is more than one occurrence of p in the table. A pittance savings, unless you're doing a lot of it.
Catenate one table onto end of another. There is no checking for duplication.
Catenate one table onto end of another, ensuring that no entry is duplicated. Duplications between multiple items in 'src' are not caught. The search is a nasty n**2 one. The tables are expected to be short.
Deallocate dynamic buffer associated with a table, and render this table unusable without a subsequent bu_ptbl_init().
Print a bu_ptbl array for inspection.