1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- /*
- * Copyright © 2023 Michael Smith <mikesmiffy128@gmail.com>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
- * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
- #ifndef INC_DICTMAPTREE_H
- #define INC_DICTMAPTREE_H
- #include "engineapi.h"
- #include "intdefs.h"
- /*
- * Valve's dict/map/tree structures come in various shapes and sizes, so here we
- * do the generic macro thing for future-proofing. For now we just define a
- * CUtlDict (map with string keys) of pointers, with ushort indices, which is
- * sufficient for server entity factory lookup, and probably some other stuff.
- * Functions for actually modifying the dicts/maps/trees aren't implemented.
- */
- #define DECL_CUTLRBTREE_NODE(name, ktype, vtype, idxtype) \
- typedef typeof(ktype) _cutlrbtree_##name##_key; \
- typedef typeof(vtype) _cutlrbtree_##name##_val; \
- typedef typeof(idxtype) _cutlrbtree_##name##_idx; \
- struct name { \
- struct { \
- _cutlrbtree_##name##_idx l, r, p, tags; \
- } links; \
- _cutlrbtree_##name##_key k; \
- _cutlrbtree_##name##_val v; \
- };
- #define DEF_CUTLRBTREE(name, nodetype) \
- struct name { \
- bool (*cmp)(const _cutlrbtree_##nodetype##_key *, \
- const _cutlrbtree_##nodetype##_key *); \
- struct CUtlMemory elems; \
- _cutlrbtree_##nodetype##_idx root, count, firstfree, lastalloc; \
- struct nodetype *nodes; \
- }; \
- \
- static _cutlrbtree_##nodetype##_idx name##_find(const struct name *rb, \
- const _cutlrbtree_##nodetype##_key k) { \
- _cutlrbtree_##nodetype##_idx idx = rb->root; \
- while (idx != (_cutlrbtree_##nodetype##_idx)-1) { \
- struct nodetype *nodes = rb->elems.mem; \
- if (rb->cmp(&k, &nodes[idx].k)) idx = nodes[idx].links.l; \
- else if (rb->cmp(&nodes[idx].k, &k)) idx = nodes[idx].links.r; \
- else break; \
- } \
- return idx; \
- } \
- \
- static inline _cutlrbtree_##nodetype##_val name##_findval(const struct name *rb, \
- const _cutlrbtree_##nodetype##_key k) { \
- const _cutlrbtree_##nodetype##_idx idx = name##_find(rb, k); \
- if (idx == (_cutlrbtree_##nodetype##_idx)-1) { \
- return (_cutlrbtree_CUtlDict_node_p_ushort_val){0}; \
- } \
- struct nodetype *nodes = rb->elems.mem; \
- return nodes[idx].v; \
- }
- DECL_CUTLRBTREE_NODE(CUtlDict_node_p_ushort, const char *, void *, ushort)
- DEF_CUTLRBTREE(CUtlDict_p_ushort, CUtlDict_node_p_ushort)
- #endif
- // vi: sw=4 ts=4 noet tw=80 cc=80
|