Parcourir la source

structure: CAvl: cosmetic changes

ambrop7 il y a 13 ans
Parent
commit
e9e0285a80

+ 4 - 4
ncd/NCDVal.c

@@ -689,7 +689,7 @@ int NCDVal_MapInsert (NCDValRef map, NCDValRef key, NCDValRef val)
     me_e->key_idx = key.idx;
     me_e->val_idx = val.idx;
     
-    int res = NCDVal__MapTree_Insert(&map_e->tree, map.mem, NCDVal__MapTree_Deref(map.mem, elemidx), NULL);
+    int res = NCDVal__MapTree_Insert(&map_e->tree, map.mem, NCDVal__MapTreeDeref(map.mem, elemidx), NULL);
     if (!res) {
         return 0;
     }
@@ -766,7 +766,7 @@ NCDValMapElem NCDVal_MapOrderedFirst (NCDValRef map)
     
     struct NCDVal__map *map_e = NCDValMem__BufAt(map.mem, map.idx);
     
-    NCDVal__MapTreeNode ref = NCDVal__MapTree_GetFirst(&map_e->tree, map.mem);
+    NCDVal__MapTreeRef ref = NCDVal__MapTree_GetFirst(&map_e->tree, map.mem);
     ASSERT(ref.link == -1 || (NCDVal__MapAssertElemOnly(map, ref.link), 1))
     
     return NCDVal__MapElem(ref.link);
@@ -778,7 +778,7 @@ NCDValMapElem NCDVal_MapOrderedNext (NCDValRef map, NCDValMapElem me)
     
     struct NCDVal__map *map_e = NCDValMem__BufAt(map.mem, map.idx);
     
-    NCDVal__MapTreeNode ref = NCDVal__MapTree_GetNext(&map_e->tree, map.mem, NCDVal__MapTree_Deref(map.mem, me.elemidx));
+    NCDVal__MapTreeRef ref = NCDVal__MapTree_GetNext(&map_e->tree, map.mem, NCDVal__MapTreeDeref(map.mem, me.elemidx));
     ASSERT(ref.link == -1 || (NCDVal__MapAssertElemOnly(map, ref.link), 1))
     
     return NCDVal__MapElem(ref.link);
@@ -809,7 +809,7 @@ NCDValMapElem NCDVal_MapFindKey (NCDValRef map, NCDValRef key)
     
     struct NCDVal__map *map_e = NCDValMem__BufAt(map.mem, map.idx);
     
-    NCDVal__MapTreeNode ref = NCDVal__MapTree_LookupExact(&map_e->tree, map.mem, key);
+    NCDVal__MapTreeRef ref = NCDVal__MapTree_LookupExact(&map_e->tree, map.mem, key);
     ASSERT(ref.link == -1 || (NCDVal__MapAssertElemOnly(map, ref.link), 1))
     
     return NCDVal__MapElem(ref.link);

+ 1 - 1
ncd/NCDVal.h

@@ -77,7 +77,7 @@ struct NCDVal__list {
 struct NCDVal__mapelem {
     NCDVal__idx key_idx;
     NCDVal__idx val_idx;
-    NCDVal__idx tree_link[2];
+    NCDVal__idx tree_child[2];
     NCDVal__idx tree_parent;
     int8_t tree_balance;
 };

+ 13 - 12
ncd/NCDVal_maptree.h

@@ -1,13 +1,14 @@
-#define CAVL_PARAM_USE_COUNTS 0
 #define CAVL_PARAM_NAME NCDVal__MapTree
-#define CAVL_PARAM_ENTRY NCDVal__maptree_entry
-#define CAVL_PARAM_LINK NCDVal__idx
-#define CAVL_PARAM_KEY NCDValRef
-#define CAVL_PARAM_ARG NCDVal__maptree_arg
-#define CAVL_PARAM_NULL ((NCDVal__idx)-1)
-#define CAVL_PARAM_DEREF(arg, link) ((struct NCDVal__mapelem *)NCDValMem__BufAt((arg), (link)))
-#define CAVL_PARAM_COMPARE_NODES(arg, node1, node2) NCDVal_Compare(NCDVal__Ref((arg), (node1).ptr->key_idx), NCDVal__Ref((arg), (node2).ptr->key_idx))
-#define CAVL_PARAM_COMPARE_KEY_NODE(arg, key1, node2) NCDVal_Compare((key1), NCDVal__Ref((arg), (node2).ptr->key_idx))
-#define CAVL_PARAM_NODE_LINK tree_link
-#define CAVL_PARAM_NODE_BALANCE tree_balance
-#define CAVL_PARAM_NODE_PARENT tree_parent
+#define CAVL_PARAM_FEATURE_COUNTS 0
+#define CAVL_PARAM_FEATURE_KEYS_ARE_INDICES 0
+#define CAVL_PARAM_TYPE_ENTRY NCDVal__maptree_entry
+#define CAVL_PARAM_TYPE_LINK NCDVal__idx
+#define CAVL_PARAM_TYPE_KEY NCDValRef
+#define CAVL_PARAM_TYPE_ARG NCDVal__maptree_arg
+#define CAVL_PARAM_VALUE_NULL ((NCDVal__idx)-1)
+#define CAVL_PARAM_FUN_DEREF(arg, link) ((struct NCDVal__mapelem *)NCDValMem__BufAt((arg), (link)))
+#define CAVL_PARAM_FUN_COMPARE_ENTRIES(arg, node1, node2) NCDVal_Compare(NCDVal__Ref((arg), (node1).ptr->key_idx), NCDVal__Ref((arg), (node2).ptr->key_idx))
+#define CAVL_PARAM_FUN_COMPARE_KEY_ENTRY(arg, key1, node2) NCDVal_Compare((key1), NCDVal__Ref((arg), (node2).ptr->key_idx))
+#define CAVL_PARAM_MEMBER_CHILD tree_child
+#define CAVL_PARAM_MEMBER_BALANCE tree_balance
+#define CAVL_PARAM_MEMBER_PARENT tree_parent

+ 24 - 24
ncd/NCDValue.c

@@ -154,12 +154,12 @@ void NCDValue_Free (NCDValue *o)
         } break;
         
         case NCDVALUE_MAP: {
-            NCDValue__MapTreeNode tn;
-            while ((tn = NCDValue__MapTree_GetFirst(&o->map_tree, 0)).link != NCDValue__MapTreeNullLink) {
-                NCDValue__MapTree_Remove(&o->map_tree, 0, tn);
-                NCDValue_Free(&tn.ptr->key);
-                NCDValue_Free(&tn.ptr->val);
-                free(tn.ptr);
+            NCDValue__MapTreeRef ref;
+            while (NCDValue__MapTreeIsValidRef(ref = NCDValue__MapTree_GetFirst(&o->map_tree, 0))) {
+                NCDValue__MapTree_Remove(&o->map_tree, 0, ref);
+                NCDValue_Free(&ref.ptr->key);
+                NCDValue_Free(&ref.ptr->val);
+                free(ref.ptr);
             }
         } break;
         
@@ -508,15 +508,15 @@ NCDValue * NCDValue_MapFirstKey (NCDValue *o)
     value_assert(o);
     ASSERT(o->type == NCDVALUE_MAP)
     
-    NCDValue__MapTreeNode tn = NCDValue__MapTree_GetFirst(&o->map_tree, 0);
-    if (tn.link == NCDValue__MapTreeNullLink) {
+    NCDValue__MapTreeRef ref = NCDValue__MapTree_GetFirst(&o->map_tree, 0);
+    if (NCDValue__MapTreeIsNullRef(ref)) {
         return NULL;
     }
     
-    value_assert(&tn.ptr->key);
-    value_assert(&tn.ptr->val);
+    value_assert(&ref.ptr->key);
+    value_assert(&ref.ptr->val);
     
-    return &tn.ptr->key;
+    return &ref.ptr->key;
 }
 
 NCDValue * NCDValue_MapNextKey (NCDValue *o, NCDValue *ekey)
@@ -528,15 +528,15 @@ NCDValue * NCDValue_MapNextKey (NCDValue *o, NCDValue *ekey)
     value_assert(&e->key);
     value_assert(&e->val);
     
-    NCDValue__MapTreeNode tn = NCDValue__MapTree_GetNext(&o->map_tree, 0, NCDValue__MapTree_Deref(0, e));
-    if (tn.link == NCDValue__MapTreeNullLink) {
+    NCDValue__MapTreeRef ref = NCDValue__MapTree_GetNext(&o->map_tree, 0, NCDValue__MapTreeDeref(0, e));
+    if (NCDValue__MapTreeIsNullRef(ref)) {
         return NULL;
     }
     
-    value_assert(&tn.ptr->key);
-    value_assert(&tn.ptr->val);
+    value_assert(&ref.ptr->key);
+    value_assert(&ref.ptr->val);
     
-    return &tn.ptr->key;
+    return &ref.ptr->key;
 }
 
 NCDValue * NCDValue_MapKeyValue (NCDValue *o, NCDValue *ekey)
@@ -557,16 +557,16 @@ NCDValue * NCDValue_MapFindKey (NCDValue *o, NCDValue *key)
     ASSERT(o->type == NCDVALUE_MAP)
     value_assert(key);
     
-    NCDValue__MapTreeNode tn = NCDValue__MapTree_LookupExact(&o->map_tree, 0, key);
-    if (tn.link == NCDValue__MapTreeNullLink) {
+    NCDValue__MapTreeRef ref = NCDValue__MapTree_LookupExact(&o->map_tree, 0, key);
+    if (NCDValue__MapTreeIsNullRef(ref)) {
         return NULL;
     }
     
-    value_assert(&tn.ptr->key);
-    value_assert(&tn.ptr->val);
-    ASSERT(!NCDValue_Compare(&tn.ptr->key, key))
+    value_assert(&ref.ptr->key);
+    value_assert(&ref.ptr->val);
+    ASSERT(!NCDValue_Compare(&ref.ptr->key, key))
     
-    return &tn.ptr->key;
+    return &ref.ptr->key;
 }
 
 NCDValue * NCDValue_MapInsert (NCDValue *o, NCDValue key, NCDValue val)
@@ -588,7 +588,7 @@ NCDValue * NCDValue_MapInsert (NCDValue *o, NCDValue key, NCDValue val)
     
     e->key = key;
     e->val = val;
-    int res = NCDValue__MapTree_Insert(&o->map_tree, 0, NCDValue__MapTree_Deref(0, e), NULL);
+    int res = NCDValue__MapTree_Insert(&o->map_tree, 0, NCDValue__MapTreeDeref(0, e), NULL);
     ASSERT(res)
     
     o->map_count++;
@@ -608,7 +608,7 @@ void NCDValue_MapRemove (NCDValue *o, NCDValue *ekey, NCDValue *out_key, NCDValu
     value_assert(&e->key);
     value_assert(&e->val);
     
-    NCDValue__MapTree_Remove(&o->map_tree, 0, NCDValue__MapTree_Deref(0, e));
+    NCDValue__MapTree_Remove(&o->map_tree, 0, NCDValue__MapTreeDeref(0, e));
     
     *out_key = e->key;
     *out_val = e->val;

+ 1 - 1
ncd/NCDValue.h

@@ -93,7 +93,7 @@ typedef struct {
 } NCDListElement;
 
 struct NCDMapElement_s {
-    NCDMapElement *tree_link[2];
+    NCDMapElement *tree_child[2];
     NCDMapElement *tree_parent;
     int8_t tree_balance;
     NCDValue key;

+ 13 - 12
ncd/NCDValue_maptree.h

@@ -1,13 +1,14 @@
-#define CAVL_PARAM_USE_COUNTS 0
 #define CAVL_PARAM_NAME NCDValue__MapTree
-#define CAVL_PARAM_ENTRY NCDMapElement
-#define CAVL_PARAM_LINK NCDValue__maptree_link
-#define CAVL_PARAM_KEY NCDValue__maptree_key
-#define CAVL_PARAM_ARG int
-#define CAVL_PARAM_NULL NULL
-#define CAVL_PARAM_DEREF(arg, link) (link)
-#define CAVL_PARAM_COMPARE_NODES(arg, node1, node2) NCDValue_Compare(&(node1).ptr->key, &(node2).ptr->key)
-#define CAVL_PARAM_COMPARE_KEY_NODE(arg, key1, node2) NCDValue_Compare((key1), &(node2).ptr->key)
-#define CAVL_PARAM_NODE_LINK tree_link
-#define CAVL_PARAM_NODE_BALANCE tree_balance
-#define CAVL_PARAM_NODE_PARENT tree_parent
+#define CAVL_PARAM_FEATURE_COUNTS 0
+#define CAVL_PARAM_FEATURE_KEYS_ARE_INDICES 0
+#define CAVL_PARAM_TYPE_ENTRY NCDMapElement
+#define CAVL_PARAM_TYPE_LINK NCDValue__maptree_link
+#define CAVL_PARAM_TYPE_KEY NCDValue__maptree_key
+#define CAVL_PARAM_TYPE_ARG int
+#define CAVL_PARAM_VALUE_NULL ((NCDValue__maptree_link)NULL)
+#define CAVL_PARAM_FUN_DEREF(arg, link) (link)
+#define CAVL_PARAM_FUN_COMPARE_ENTRIES(arg, entry1, entry2) NCDValue_Compare(&(entry1).ptr->key, &(entry2).ptr->key)
+#define CAVL_PARAM_FUN_COMPARE_KEY_ENTRY(arg, key1, entry2) NCDValue_Compare((key1), &(entry2).ptr->key)
+#define CAVL_PARAM_MEMBER_CHILD tree_child
+#define CAVL_PARAM_MEMBER_BALANCE tree_balance
+#define CAVL_PARAM_MEMBER_PARENT tree_parent

+ 19 - 21
structure/CAvl_decl.h

@@ -36,35 +36,33 @@ typedef struct {
 typedef struct {
     CAvlEntry *ptr;
     CAvlLink link;
-} CAvlNode;
+} CAvlRef;
 
-static const CAvlLink CAvlNullLink = CAVL_PARAM_NULL;
+static int CAvlIsNullRef (CAvlRef node);
+static int CAvlIsValidRef (CAvlRef node);
+static CAvlRef CAvlDeref (CAvlArg arg, CAvlLink link);
 
 static void CAvl_Init (CAvl *o);
-static CAvlNode CAvl_Deref (CAvlArg arg, CAvlLink link);
-#if !CAVL_PARAM_KEYS_ARE_INDICES
-static int CAvl_Insert (CAvl *o, CAvlArg arg, CAvlNode node, CAvlNode *out_ref);
+#if !CAVL_PARAM_FEATURE_KEYS_ARE_INDICES
+static int CAvl_Insert (CAvl *o, CAvlArg arg, CAvlRef node, CAvlRef *out_ref);
+#else
+static void CAvl_InsertAt (CAvl *o, CAvlArg arg, CAvlRef node, CAvlCount index);
 #endif
-static void CAvl_Remove (CAvl *o, CAvlArg arg, CAvlNode node);
-#if !CAVL_PARAM_KEYS_ARE_INDICES
-static CAvlNode CAvl_Lookup (const CAvl *o, CAvlArg arg, CAvlKey key);
-static CAvlNode CAvl_LookupExact (const CAvl *o, CAvlArg arg, CAvlKey key);
+static void CAvl_Remove (CAvl *o, CAvlArg arg, CAvlRef node);
+#if !CAVL_PARAM_FEATURE_KEYS_ARE_INDICES
+static CAvlRef CAvl_Lookup (const CAvl *o, CAvlArg arg, CAvlKey key);
+static CAvlRef CAvl_LookupExact (const CAvl *o, CAvlArg arg, CAvlKey key);
 #endif
-static CAvlNode CAvl_GetFirst (const CAvl *o, CAvlArg arg);
-static CAvlNode CAvl_GetLast (const CAvl *o, CAvlArg arg);
-static CAvlNode CAvl_GetNext (const CAvl *o, CAvlArg arg, CAvlNode node);
-static CAvlNode CAvl_GetPrev (const CAvl *o, CAvlArg arg, CAvlNode node);
+static CAvlRef CAvl_GetFirst (const CAvl *o, CAvlArg arg);
+static CAvlRef CAvl_GetLast (const CAvl *o, CAvlArg arg);
+static CAvlRef CAvl_GetNext (const CAvl *o, CAvlArg arg, CAvlRef node);
+static CAvlRef CAvl_GetPrev (const CAvl *o, CAvlArg arg, CAvlRef node);
 static int CAvl_IsEmpty (const CAvl *o);
 static void CAvl_Verify (const CAvl *o, CAvlArg arg);
-
-#if CAVL_PARAM_USE_COUNTS
+#if CAVL_PARAM_FEATURE_COUNTS
 static CAvlCount CAvl_Count (const CAvl *o, CAvlArg arg);
-static CAvlCount CAvl_IndexOf (const CAvl *o, CAvlArg arg, CAvlNode node);
-static CAvlNode CAvl_GetAt (const CAvl *o, CAvlArg arg, CAvlCount index);
-#endif
-
-#if CAVL_PARAM_KEYS_ARE_INDICES
-static void CAvl_InsertAt (CAvl *o, CAvlArg arg, CAvlNode node, CAvlCount index);
+static CAvlCount CAvl_IndexOf (const CAvl *o, CAvlArg arg, CAvlRef node);
+static CAvlRef CAvl_GetAt (const CAvl *o, CAvlArg arg, CAvlCount index);
 #endif
 
 #include "CAvl_footer.h"

+ 26 - 24
structure/CAvl_footer.h

@@ -27,37 +27,39 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#undef CAVL_PARAM_USE_COUNTS
 #undef CAVL_PARAM_NAME
-#undef CAVL_PARAM_ENTRY
-#undef CAVL_PARAM_LINK
-#undef CAVL_PARAM_KEY
-#undef CAVL_PARAM_ARG
-#undef CAVL_PARAM_COUNT
-#undef CAVL_PARAM_COUNT_MAX
-#undef CAVL_PARAM_NULL
-#undef CAVL_PARAM_DEREF
-#undef CAVL_PARAM_COMPARE_NODES
-#undef CAVL_PARAM_COMPARE_KEY_NODE
-#undef CAVL_PARAM_NODE_LINK
-#undef CAVL_PARAM_NODE_BALANCE
-#undef CAVL_PARAM_NODE_PARENT
-#undef CAVL_PARAM_NODE_COUNT
-#undef CAVL_PARAM_KEYS_ARE_INDICES
+#undef CAVL_PARAM_FEATURE_COUNTS
+#undef CAVL_PARAM_FEATURE_KEYS_ARE_INDICES
+#undef CAVL_PARAM_TYPE_ENTRY
+#undef CAVL_PARAM_TYPE_LINK
+#undef CAVL_PARAM_TYPE_KEY
+#undef CAVL_PARAM_TYPE_ARG
+#undef CAVL_PARAM_TYPE_COUNT
+#undef CAVL_PARAM_VALUE_COUNT_MAX
+#undef CAVL_PARAM_VALUE_NULL
+#undef CAVL_PARAM_FUN_DEREF
+#undef CAVL_PARAM_FUN_COMPARE_ENTRIES
+#undef CAVL_PARAM_FUN_COMPARE_KEY_ENTRY
+#undef CAVL_PARAM_MEMBER_CHILD
+#undef CAVL_PARAM_MEMBER_BALANCE
+#undef CAVL_PARAM_MEMBER_PARENT
+#undef CAVL_PARAM_MEMBER_COUNT
 
 #undef CAvl
 #undef CAvlEntry
 #undef CAvlLink
-#undef CAvlNode
+#undef CAvlRef
 #undef CAvlArg
 #undef CAvlKey
 #undef CAvlCount
 
-#undef CAvlNullLink
+#undef CAvlIsNullRef
+#undef CAvlIsValidRef
+#undef CAvlDeref
 
 #undef CAvl_Init
-#undef CAvl_Deref
 #undef CAvl_Insert
+#undef CAvl_InsertAt
 #undef CAvl_Remove
 #undef CAvl_Lookup
 #undef CAvl_LookupExact
@@ -70,15 +72,15 @@
 #undef CAvl_Count
 #undef CAvl_IndexOf
 #undef CAvl_GetAt
-#undef CAvl_InsertAt
 
 #undef CAvl_link
 #undef CAvl_balance
 #undef CAvl_parent
 #undef CAvl_count
-#undef CAvl_nullnode
-#undef CAvl_compare_nodes
-#undef CAvl_compare_key_node
+#undef CAvl_nulllink
+#undef CAvl_nullref
+#undef CAvl_compare_entries
+#undef CAvl_compare_key_entry
 #undef CAvl_check_parent
 #undef CAvl_verify_recurser
 #undef CAvl_assert_tree
@@ -87,7 +89,7 @@
 #undef CAvl_subtree_min
 #undef CAvl_subtree_max
 #undef CAvl_replace_subtree_fix_counts
-#undef CAvl_swap_nodes
+#undef CAvl_swap_entries
 #undef CAvl_rebalance
 #undef CAvl_child_count
 #undef CAvl_MAX

+ 50 - 47
structure/CAvl_header.h

@@ -28,46 +28,49 @@
  */
 
 // Preprocessor inputs:
-// CAVL_PARAM_USE_COUNTS - whether to keep node counts (0 or 1)
 // CAVL_PARAM_NAME - name of this data structure
-// CAVL_PARAM_ENTRY - type of entry
-// CAVL_PARAM_LINK - type of node link (usually pointer)
-// CAVL_PARAM_KEY - type of key (unused if CAVL_PARAM_KEYS_ARE_INDICES=1) 
-// CAVL_PARAM_ARG - type of argument pass through to comparisons
-// CAVL_PARAM_COUNT - type of count
-// CAVL_PARAM_COUNT_MAX - maximum value of count
-// CAVL_PARAM_NULL - invalid link
-// CAVL_PARAM_DEREF(arg, link) - dereference a non-null link
-// CAVL_PARAM_COMPARE_NODES(arg, node1, node2) - compare nodes
-// CAVL_PARAM_COMPARE_KEY_NODE(arg, key1, node2) - compare key and node
-// CAVL_PARAM_NODE_LINK - link member in node
-// CAVL_PARAM_NODE_BALANCE - balance member in node
-// CAVL_PARAM_NODE_PARENT - parent member in node
-// CAVL_PARAM_NODE_COUNT - count member in node (if CAVL_PARAM_USE_COUNTS)
-// CAVL_PARAM_KEYS_ARE_INDICES - (0 or 1) whether to assume the keys are node indices
-//                               (number of nodes lesser than given node). If yes,
-//                               CAVL_PARAM_KEY is unused. Requires CAVL_PARAM_USE_COUNTS.
+// CAVL_PARAM_FEATURE_COUNTS - whether to keep count information (0 or 1)
+// CAVL_PARAM_FEATURE_KEYS_ARE_INDICES - (0 or 1) whether to assume the keys are entry indices
+//   (number of entries lesser than given entry). If yes, CAVL_PARAM_TYPE_KEY is unused.
+//   Requires CAVL_PARAM_FEATURE_COUNTS.
+// CAVL_PARAM_TYPE_ENTRY - type of entry
+// CAVL_PARAM_TYPE_LINK - type of entry link (usually pointer or index)
+// CAVL_PARAM_TYPE_KEY - type of key (only if not CAVL_PARAM_FEATURE_KEYS_ARE_INDICES)
+// CAVL_PARAM_TYPE_ARG - type of argument pass through to callbacks
+// CAVL_PARAM_TYPE_COUNT - type of count (only if CAVL_PARAM_FEATURE_COUNTS)
+// CAVL_PARAM_VALUE_COUNT_MAX - maximum value of count (type is CAVL_PARAM_TYPE_COUNT)
+// CAVL_PARAM_VALUE_NULL - value of invalid link (type is CAVL_PARAM_TYPE_LINK)
+// CAVL_PARAM_FUN_DEREF(arg, link) - dereference a non-null link; returns pointer to CAVL_PARAM_TYPE_LINK
+// CAVL_PARAM_FUN_COMPARE_ENTRIES(arg, entry1, entry2) - compare to entries; returns -1/0/1
+// CAVL_PARAM_FUN_COMPARE_KEY_ENTRY(arg, key1, entry2) - compare key and entry; returns -1/0/1
+// CAVL_PARAM_MEMBER_CHILD - name of the child member in entry (type is CAVL_PARAM_TYPE_LINK[2])
+// CAVL_PARAM_MEMBER_BALANCE - name of the balance member in entry (type is any signed integer)
+// CAVL_PARAM_MEMBER_PARENT - name of the parent member in entry (type is CAVL_PARAM_TYPE_LINK)
+// CAVL_PARAM_MEMBER_COUNT - name of the count member in entry (type is CAVL_PARAM_TYPE_COUNT)
+//   (only if CAVL_PARAM_FEATURE_COUNTS)
 
-#if CAVL_PARAM_KEYS_ARE_INDICES && !CAVL_PARAM_USE_COUNTS
-#error CAVL_PARAM_KEYS_ARE_INDICES requires CAVL_PARAM_USE_COUNTS
+#if CAVL_PARAM_FEATURE_KEYS_ARE_INDICES && !CAVL_PARAM_FEATURE_COUNTS
+#error CAVL_PARAM_FEATURE_KEYS_ARE_INDICES requires CAVL_PARAM_FEATURE_COUNTS
 #endif
 
 // types
 #define CAvl CAVL_PARAM_NAME
-#define CAvlEntry CAVL_PARAM_ENTRY
-#define CAvlLink CAVL_PARAM_LINK
-#define CAvlNode MERGE(CAvl, Node)
-#define CAvlArg CAVL_PARAM_ARG
-#define CAvlKey CAVL_PARAM_KEY
-#define CAvlCount CAVL_PARAM_COUNT
+#define CAvlEntry CAVL_PARAM_TYPE_ENTRY
+#define CAvlLink CAVL_PARAM_TYPE_LINK
+#define CAvlRef MERGE(CAVL_PARAM_NAME, Ref)
+#define CAvlArg CAVL_PARAM_TYPE_ARG
+#define CAvlKey CAVL_PARAM_TYPE_KEY
+#define CAvlCount CAVL_PARAM_TYPE_COUNT
 
-// static values
-#define CAvlNullLink MERGE(CAvl, NullLink)
+// non-object public functions
+#define CAvlIsNullRef MERGE(CAvl, IsNullRef)
+#define CAvlIsValidRef MERGE(CAvl, IsValidRef)
+#define CAvlDeref MERGE(CAvl, Deref)
 
 // public functions
 #define CAvl_Init MERGE(CAvl, _Init)
-#define CAvl_Deref MERGE(CAvl, _Deref)
 #define CAvl_Insert MERGE(CAvl, _Insert)
+#define CAvl_InsertAt MERGE(CAvl, _InsertAt)
 #define CAvl_Remove MERGE(CAvl, _Remove)
 #define CAvl_Lookup MERGE(CAvl, _Lookup)
 #define CAvl_LookupExact MERGE(CAvl, _LookupExact)
@@ -80,26 +83,26 @@
 #define CAvl_Count MERGE(CAvl, _Count)
 #define CAvl_IndexOf MERGE(CAvl, _IndexOf)
 #define CAvl_GetAt MERGE(CAvl, _GetAt)
-#define CAvl_InsertAt MERGE(CAvl, _InsertAt)
 
 // private stuff
-#define CAvl_link(node) ((node).ptr->CAVL_PARAM_NODE_LINK)
-#define CAvl_balance(node) ((node).ptr->CAVL_PARAM_NODE_BALANCE)
-#define CAvl_parent(node) ((node).ptr->CAVL_PARAM_NODE_PARENT)
-#define CAvl_count(node) ((node).ptr->CAVL_PARAM_NODE_COUNT)
-#define CAvl_nullnode MERGE(CAvl, __nullnode)
-#define CAvl_compare_nodes MERGE(CAvl, __compare_nodes)
-#define CAvl_compare_key_node MERGE(CAvl, __compare_key_node)
-#define CAvl_check_parent MERGE(CAvl, __check_parent)
-#define CAvl_verify_recurser MERGE(CAvl, __verify_recurser)
-#define CAvl_assert_tree MERGE(CAvl, __assert_tree)
-#define CAvl_update_count_from_children MERGE(CAvl, __update_count_from_children)
-#define CAvl_rotate MERGE(CAvl, __rotate)
-#define CAvl_subtree_min MERGE(CAvl, __subtree_min)
-#define CAvl_subtree_max MERGE(CAvl, __subtree_max)
-#define CAvl_replace_subtree_fix_counts MERGE(CAvl, __replace_subtree_fix_counts)
-#define CAvl_swap_nodes MERGE(CAvl, __swap_nodes)
-#define CAvl_rebalance MERGE(CAvl, __rebalance)
+#define CAvl_link(entry) ((entry).ptr->CAVL_PARAM_MEMBER_CHILD)
+#define CAvl_balance(entry) ((entry).ptr->CAVL_PARAM_MEMBER_BALANCE)
+#define CAvl_parent(entry) ((entry).ptr->CAVL_PARAM_MEMBER_PARENT)
+#define CAvl_count(entry) ((entry).ptr->CAVL_PARAM_MEMBER_COUNT)
+#define CAvl_nulllink MERGE(CAvl, __nulllink)
+#define CAvl_nullref MERGE(CAvl, __nullref)
+#define CAvl_compare_entries MERGE(CAVL_PARAM_NAME, _compare_entries)
+#define CAvl_compare_key_entry MERGE(CAVL_PARAM_NAME, _compare_key_entry)
+#define CAvl_check_parent MERGE(CAVL_PARAM_NAME, _check_parent)
+#define CAvl_verify_recurser MERGE(CAVL_PARAM_NAME, _verify_recurser)
+#define CAvl_assert_tree MERGE(CAVL_PARAM_NAME, _assert_tree)
+#define CAvl_update_count_from_children MERGE(CAVL_PARAM_NAME, _update_count_from_children)
+#define CAvl_rotate MERGE(CAVL_PARAM_NAME, _rotate)
+#define CAvl_subtree_min MERGE(CAVL_PARAM_NAME, _subtree_min)
+#define CAvl_subtree_max MERGE(CAVL_PARAM_NAME, _subtree_max)
+#define CAvl_replace_subtree_fix_counts MERGE(CAVL_PARAM_NAME, _replace_subtree_fix_counts)
+#define CAvl_swap_entries MERGE(CAVL_PARAM_NAME, _swap_entries)
+#define CAvl_rebalance MERGE(CAVL_PARAM_NAME, _rebalance)
 #define CAvl_child_count MERGE(CAvl, __child_count)
 #define CAvl_MAX(_a, _b) ((_a) > (_b) ? (_a) : (_b))
 #define CAvl_OPTNEG(_a, _neg) ((_neg) ? -(_a) : (_a))

+ 268 - 247
structure/CAvl_impl.h

@@ -29,87 +29,94 @@
 
 #include "CAvl_header.h"
 
-static CAvlNode CAvl_nullnode (void)
+static CAvlLink CAvl_nulllink (void)
 {
-    CAvlNode n;
-    n.link = CAvlNullLink;
+    return CAVL_PARAM_VALUE_NULL;
+}
+
+static CAvlRef CAvl_nullref (void)
+{
+    CAvlRef n;
+    n.link = CAVL_PARAM_VALUE_NULL;
     n.ptr = NULL;
     return n;
 }
 
-#if !CAVL_PARAM_KEYS_ARE_INDICES
-static int CAvl_compare_nodes (CAvlArg arg, CAvlNode node1, CAvlNode node2)
+#if !CAVL_PARAM_FEATURE_KEYS_ARE_INDICES
+
+static int CAvl_compare_entries (CAvlArg arg, CAvlRef node1, CAvlRef node2)
 {
-    int res = CAVL_PARAM_COMPARE_NODES(arg, node1, node2);
+    int res = CAVL_PARAM_FUN_COMPARE_ENTRIES(arg, node1, node2);
     ASSERT(res >= -1)
     ASSERT(res <= 1)
     
     return res;
 }
 
-static int CAvl_compare_key_node (CAvlArg arg, CAvlKey key1, CAvlNode node2)
+static int CAvl_compare_key_entry (CAvlArg arg, CAvlKey key1, CAvlRef node2)
 {
-    int res = CAVL_PARAM_COMPARE_KEY_NODE(arg, key1, node2);
+    int res = CAVL_PARAM_FUN_COMPARE_KEY_ENTRY(arg, key1, node2);
     ASSERT(res >= -1)
     ASSERT(res <= 1)
     
     return res;
 }
+
 #endif
 
-static int CAvl_check_parent (CAvlNode p, CAvlNode c)
+static int CAvl_check_parent (CAvlRef p, CAvlRef c)
 {
-    return (p.link == CAvl_parent(c)) && (p.link == CAvlNullLink || c.link == CAvl_link(p)[0] || c.link == CAvl_link(p)[1]);
+    return (p.link == CAvl_parent(c)) && (p.link == CAvl_nulllink() || c.link == CAvl_link(p)[0] || c.link == CAvl_link(p)[1]);
 }
 
-static int CAvl_verify_recurser (CAvlArg arg, CAvlNode n)
+static int CAvl_verify_recurser (CAvlArg arg, CAvlRef n)
 {
     ASSERT_FORCE(CAvl_balance(n) >= -1)
     ASSERT_FORCE(CAvl_balance(n) <= 1)
     
     int height_left = 0;
     int height_right = 0;
-#if CAVL_PARAM_USE_COUNTS
+#if CAVL_PARAM_FEATURE_COUNTS
     CAvlCount count_left = 0;
     CAvlCount count_right = 0;
 #endif
     
     // check left subtree
-    if (CAvl_link(n)[0] != CAvlNullLink) {
+    if (CAvl_link(n)[0] != CAvl_nulllink()) {
         // check parent link
-        ASSERT_FORCE(CAvl_parent(CAvl_Deref(arg, CAvl_link(n)[0])) == n.link)
+        ASSERT_FORCE(CAvl_parent(CAvlDeref(arg, CAvl_link(n)[0])) == n.link)
         // check binary search tree
-#if !CAVL_PARAM_KEYS_ARE_INDICES
-        ASSERT_FORCE(CAvl_compare_nodes(arg, CAvl_Deref(arg, CAvl_link(n)[0]), n) == -1)
+#if !CAVL_PARAM_FEATURE_KEYS_ARE_INDICES
+        ASSERT_FORCE(CAvl_compare_entries(arg, CAvlDeref(arg, CAvl_link(n)[0]), n) == -1)
 #endif
         // recursively calculate height
-        height_left = CAvl_verify_recurser(arg, CAvl_Deref(arg, CAvl_link(n)[0]));
-#if CAVL_PARAM_USE_COUNTS
-        count_left = CAvl_count(CAvl_Deref(arg, CAvl_link(n)[0]));
+        height_left = CAvl_verify_recurser(arg, CAvlDeref(arg, CAvl_link(n)[0]));
+#if CAVL_PARAM_FEATURE_COUNTS
+        count_left = CAvl_count(CAvlDeref(arg, CAvl_link(n)[0]));
 #endif
     }
     
     // check right subtree
-    if (CAvl_link(n)[1] != CAvlNullLink) {
+    if (CAvl_link(n)[1] != CAvl_nulllink()) {
         // check parent link
-        ASSERT_FORCE(CAvl_parent(CAvl_Deref(arg, CAvl_link(n)[1])) == n.link)
-#if !CAVL_PARAM_KEYS_ARE_INDICES
+        ASSERT_FORCE(CAvl_parent(CAvlDeref(arg, CAvl_link(n)[1])) == n.link)
         // check binary search tree
-        ASSERT_FORCE(CAvl_compare_nodes(arg, CAvl_Deref(arg, CAvl_link(n)[1]), n) == 1)
+#if !CAVL_PARAM_FEATURE_KEYS_ARE_INDICES
+        ASSERT_FORCE(CAvl_compare_entries(arg, CAvlDeref(arg, CAvl_link(n)[1]), n) == 1)
 #endif
         // recursively calculate height
-        height_right = CAvl_verify_recurser(arg, CAvl_Deref(arg, CAvl_link(n)[1]));
-#if CAVL_PARAM_USE_COUNTS
-        count_right = CAvl_count(CAvl_Deref(arg, CAvl_link(n)[1]));
+        height_right = CAvl_verify_recurser(arg, CAvlDeref(arg, CAvl_link(n)[1]));
+#if CAVL_PARAM_FEATURE_COUNTS
+        count_right = CAvl_count(CAvlDeref(arg, CAvl_link(n)[1]));
 #endif
     }
     
     // check balance factor
     ASSERT_FORCE(CAvl_balance(n) == height_right - height_left)
     
-#if CAVL_PARAM_USE_COUNTS
+#if CAVL_PARAM_FEATURE_COUNTS
     // check count
-    ASSERT(CAvl_count(n) == 1 + count_left + count_right)
+    ASSERT_FORCE(CAvl_count(n) == 1 + count_left + count_right)
 #endif
     
     return CAvl_MAX(height_left, height_right) + 1;
@@ -122,88 +129,88 @@ static void CAvl_assert_tree (CAvl *o, CAvlArg arg)
 #endif
 }
 
-#if CAVL_PARAM_USE_COUNTS
-static void CAvl_update_count_from_children (CAvlArg arg, CAvlNode n)
+#if CAVL_PARAM_FEATURE_COUNTS
+static void CAvl_update_count_from_children (CAvlArg arg, CAvlRef n)
 {
-    CAvlCount left_count = CAvl_link(n)[0] != CAvlNullLink ? CAvl_count(CAvl_Deref(arg, CAvl_link(n)[0])) : 0;
-    CAvlCount right_count = CAvl_link(n)[1] != CAvlNullLink ? CAvl_count(CAvl_Deref(arg, CAvl_link(n)[1])) : 0;
+    CAvlCount left_count = CAvl_link(n)[0] != CAvl_nulllink() ? CAvl_count(CAvlDeref(arg, CAvl_link(n)[0])) : 0;
+    CAvlCount right_count = CAvl_link(n)[1] != CAvl_nulllink() ? CAvl_count(CAvlDeref(arg, CAvl_link(n)[1])) : 0;
     CAvl_count(n) = 1 + left_count + right_count;
 }
 #endif
 
-static void CAvl_rotate (CAvl *o, CAvlArg arg, CAvlNode r, uint8_t dir, CAvlNode r_parent)
+static void CAvl_rotate (CAvl *o, CAvlArg arg, CAvlRef r, uint8_t dir, CAvlRef r_parent)
 {
     ASSERT(CAvl_check_parent(r_parent, r))
-    CAvlNode nr = CAvl_Deref(arg, CAvl_link(r)[!dir]);
+    CAvlRef nr = CAvlDeref(arg, CAvl_link(r)[!dir]);
     
     CAvl_link(r)[!dir] = CAvl_link(nr)[dir];
-    if (CAvl_link(r)[!dir] != CAvlNullLink) {
-        CAvl_parent(CAvl_Deref(arg, CAvl_link(r)[!dir])) = r.link;
+    if (CAvl_link(r)[!dir] != CAvl_nulllink()) {
+        CAvl_parent(CAvlDeref(arg, CAvl_link(r)[!dir])) = r.link;
     }
     CAvl_link(nr)[dir] = r.link;
     CAvl_parent(nr) = r_parent.link;
-    if (r_parent.link != CAvlNullLink) {
+    if (r_parent.link != CAvl_nulllink()) {
         CAvl_link(r_parent)[r.link == CAvl_link(r_parent)[1]] = nr.link;
     } else {
         o->root = nr.link;
     }
     CAvl_parent(r) = nr.link;
     
-#if CAVL_PARAM_USE_COUNTS
+#if CAVL_PARAM_FEATURE_COUNTS
     CAvl_update_count_from_children(arg, r);
     CAvl_update_count_from_children(arg, nr);
 #endif
 }
 
-static CAvlNode CAvl_subtree_min (CAvlArg arg, CAvlNode n)
+static CAvlRef CAvl_subtree_min (CAvlArg arg, CAvlRef n)
 {
-    ASSERT(n.link != CAvlNullLink)
+    ASSERT(n.link != CAvl_nulllink())
     
-    while (CAvl_link(n)[0] != CAvlNullLink) {
-        n = CAvl_Deref(arg, CAvl_link(n)[0]);
+    while (CAvl_link(n)[0] != CAvl_nulllink()) {
+        n = CAvlDeref(arg, CAvl_link(n)[0]);
     }
     
     return n;
 }
 
-static CAvlNode CAvl_subtree_max (CAvlArg arg, CAvlNode n)
+static CAvlRef CAvl_subtree_max (CAvlArg arg, CAvlRef n)
 {
-    ASSERT(n.link != CAvlNullLink)
+    ASSERT(n.link != CAvl_nulllink())
     
-    while (CAvl_link(n)[1] != CAvlNullLink) {
-        n = CAvl_Deref(arg, CAvl_link(n)[1]);
+    while (CAvl_link(n)[1] != CAvl_nulllink()) {
+        n = CAvlDeref(arg, CAvl_link(n)[1]);
     }
     
     return n;
 }
 
-static void CAvl_replace_subtree_fix_counts (CAvl *o, CAvlArg arg, CAvlNode dest, CAvlNode n, CAvlNode dest_parent)
+static void CAvl_replace_subtree_fix_counts (CAvl *o, CAvlArg arg, CAvlRef dest, CAvlRef n, CAvlRef dest_parent)
 {
-    ASSERT(dest.link != CAvlNullLink)
+    ASSERT(dest.link != CAvl_nulllink())
     ASSERT(CAvl_check_parent(dest_parent, dest))
     
-    if (dest_parent.link != CAvlNullLink) {
+    if (dest_parent.link != CAvl_nulllink()) {
         CAvl_link(dest_parent)[dest.link == CAvl_link(dest_parent)[1]] = n.link;
     } else {
         o->root = n.link;
     }
-    if (n.link != CAvlNullLink) {
+    if (n.link != CAvl_nulllink()) {
         CAvl_parent(n) = CAvl_parent(dest);
     }
     
-#if CAVL_PARAM_USE_COUNTS
-    for (CAvlNode c = dest_parent; c.link != CAvlNullLink; c = CAvl_Deref(arg, CAvl_parent(c))) {
+#if CAVL_PARAM_FEATURE_COUNTS
+    for (CAvlRef c = dest_parent; c.link != CAvl_nulllink(); c = CAvlDeref(arg, CAvl_parent(c))) {
         ASSERT(CAvl_count(c) >= CAvl_count(dest))
         CAvl_count(c) -= CAvl_count(dest);
-        if (n.link != CAvlNullLink) {
-            ASSERT(CAvl_count(n) <= CAVL_PARAM_COUNT_MAX - CAvl_count(c))
+        if (n.link != CAvl_nulllink()) {
+            ASSERT(CAvl_count(n) <= CAVL_PARAM_VALUE_COUNT_MAX - CAvl_count(c))
             CAvl_count(c) += CAvl_count(n);
         }
     }
 #endif
 }
 
-static void CAvl_swap_nodes (CAvl *o, CAvlArg arg, CAvlNode n1, CAvlNode n2, CAvlNode n1_parent, CAvlNode n2_parent)
+static void CAvl_swap_entries (CAvl *o, CAvlArg arg, CAvlRef n1, CAvlRef n2, CAvlRef n1_parent, CAvlRef n2_parent)
 {
     ASSERT(CAvl_check_parent(n1_parent, n1))
     ASSERT(CAvl_check_parent(n2_parent, n2))
@@ -212,7 +219,7 @@ static void CAvl_swap_nodes (CAvl *o, CAvlArg arg, CAvlNode n1, CAvlNode n2, CAv
         // when the nodes are directly connected we need special handling
         // make sure n1 is above n2
         if (n1_parent.link == n2.link) {
-            CAvlNode t = n1;
+            CAvlRef t = n1;
             n1 = n2;
             n2 = t;
             t = n1_parent;
@@ -221,17 +228,17 @@ static void CAvl_swap_nodes (CAvl *o, CAvlArg arg, CAvlNode n1, CAvlNode n2, CAv
         }
         
         uint8_t side = (n2.link == CAvl_link(n1)[1]);
-        CAvlNode c = CAvl_Deref(arg, CAvl_link(n1)[!side]);
+        CAvlRef c = CAvlDeref(arg, CAvl_link(n1)[!side]);
         
-        if ((CAvl_link(n1)[0] = CAvl_link(n2)[0]) != CAvlNullLink) {
-            CAvl_parent(CAvl_Deref(arg, CAvl_link(n1)[0])) = n1.link;
+        if ((CAvl_link(n1)[0] = CAvl_link(n2)[0]) != CAvl_nulllink()) {
+            CAvl_parent(CAvlDeref(arg, CAvl_link(n1)[0])) = n1.link;
         }
-        if ((CAvl_link(n1)[1] = CAvl_link(n2)[1]) != CAvlNullLink) {
-            CAvl_parent(CAvl_Deref(arg, CAvl_link(n1)[1])) = n1.link;
+        if ((CAvl_link(n1)[1] = CAvl_link(n2)[1]) != CAvl_nulllink()) {
+            CAvl_parent(CAvlDeref(arg, CAvl_link(n1)[1])) = n1.link;
         }
         
         CAvl_parent(n2) = CAvl_parent(n1);
-        if (n1_parent.link != CAvlNullLink) {
+        if (n1_parent.link != CAvl_nulllink()) {
             CAvl_link(n1_parent)[n1.link == CAvl_link(n1_parent)[1]] = n2.link;
         } else {
             o->root = n2.link;
@@ -239,43 +246,43 @@ static void CAvl_swap_nodes (CAvl *o, CAvlArg arg, CAvlNode n1, CAvlNode n2, CAv
         
         CAvl_link(n2)[side] = n1.link;
         CAvl_parent(n1) = n2.link;
-        if ((CAvl_link(n2)[!side] = c.link) != CAvlNullLink) {
+        if ((CAvl_link(n2)[!side] = c.link) != CAvl_nulllink()) {
             CAvl_parent(c) = n2.link;
         }
     } else {
-        CAvlNode temp;
+        CAvlRef temp;
         
         // swap parents
         temp = n1_parent;
         CAvl_parent(n1) = CAvl_parent(n2);
-        if (n2_parent.link != CAvlNullLink) {
+        if (n2_parent.link != CAvl_nulllink()) {
             CAvl_link(n2_parent)[n2.link == CAvl_link(n2_parent)[1]] = n1.link;
         } else {
             o->root = n1.link;
         }
         CAvl_parent(n2) = temp.link;
-        if (temp.link != CAvlNullLink) {
+        if (temp.link != CAvl_nulllink()) {
             CAvl_link(temp)[n1.link == CAvl_link(temp)[1]] = n2.link;
         } else {
             o->root = n2.link;
         }
         
         // swap left children
-        temp = CAvl_Deref(arg, CAvl_link(n1)[0]);
-        if ((CAvl_link(n1)[0] = CAvl_link(n2)[0]) != CAvlNullLink) {
-            CAvl_parent(CAvl_Deref(arg, CAvl_link(n1)[0])) = n1.link;
+        temp = CAvlDeref(arg, CAvl_link(n1)[0]);
+        if ((CAvl_link(n1)[0] = CAvl_link(n2)[0]) != CAvl_nulllink()) {
+            CAvl_parent(CAvlDeref(arg, CAvl_link(n1)[0])) = n1.link;
         }
-        if ((CAvl_link(n2)[0] = temp.link) != CAvlNullLink) {
-            CAvl_parent(CAvl_Deref(arg, CAvl_link(n2)[0])) = n2.link;
+        if ((CAvl_link(n2)[0] = temp.link) != CAvl_nulllink()) {
+            CAvl_parent(CAvlDeref(arg, CAvl_link(n2)[0])) = n2.link;
         }
         
         // swap right children
-        temp = CAvl_Deref(arg, CAvl_link(n1)[1]);
-        if ((CAvl_link(n1)[1] = CAvl_link(n2)[1]) != CAvlNullLink) {
-            CAvl_parent(CAvl_Deref(arg, CAvl_link(n1)[1])) = n1.link;
+        temp = CAvlDeref(arg, CAvl_link(n1)[1]);
+        if ((CAvl_link(n1)[1] = CAvl_link(n2)[1]) != CAvl_nulllink()) {
+            CAvl_parent(CAvlDeref(arg, CAvl_link(n1)[1])) = n1.link;
         }
-        if ((CAvl_link(n2)[1] = temp.link) != CAvlNullLink) {
-            CAvl_parent(CAvl_Deref(arg, CAvl_link(n2)[1])) = n2.link;
+        if ((CAvl_link(n2)[1] = temp.link) != CAvl_nulllink()) {
+            CAvl_parent(CAvlDeref(arg, CAvl_link(n2)[1])) = n2.link;
         }
     }
     
@@ -284,7 +291,7 @@ static void CAvl_swap_nodes (CAvl *o, CAvlArg arg, CAvlNode n1, CAvlNode n2, CAv
     CAvl_balance(n1) = CAvl_balance(n2);
     CAvl_balance(n2) = b;
     
-#if CAVL_PARAM_USE_COUNTS
+#if CAVL_PARAM_FEATURE_COUNTS
     // swap counts
     CAvlCount c = CAvl_count(n1);
     CAvl_count(n1) = CAvl_count(n2);
@@ -292,7 +299,7 @@ static void CAvl_swap_nodes (CAvl *o, CAvlArg arg, CAvlNode n1, CAvlNode n2, CAv
 #endif
 }
 
-static void CAvl_rebalance (CAvl *o, CAvlArg arg, CAvlNode node, uint8_t side, int8_t deltac)
+static void CAvl_rebalance (CAvl *o, CAvlArg arg, CAvlRef node, uint8_t side, int8_t deltac)
 {
     ASSERT(side == 0 || side == 1)
     ASSERT(deltac >= -1 && deltac <= 1)
@@ -310,8 +317,8 @@ static void CAvl_rebalance (CAvl *o, CAvlArg arg, CAvlNode node, uint8_t side, i
     // update our balance factor
     CAvl_balance(node) -= CAvl_OPTNEG(deltac, side);
     
-    CAvlNode child;
-    CAvlNode gchild;
+    CAvlRef child;
+    CAvlRef gchild;
     
     // perform transformations if the balance factor is wrong
     if (CAvl_balance(node) == 2 || CAvl_balance(node) == -2) {
@@ -325,28 +332,28 @@ static void CAvl_rebalance (CAvl *o, CAvlArg arg, CAvlNode node, uint8_t side, i
             bsidef = -1;
         }
         
-        ASSERT(CAvl_link(node)[bside] != CAvlNullLink)
-        child = CAvl_Deref(arg, CAvl_link(node)[bside]);
+        ASSERT(CAvl_link(node)[bside] != CAvl_nulllink())
+        child = CAvlDeref(arg, CAvl_link(node)[bside]);
         
         switch (CAvl_balance(child) * bsidef) {
             case 1:
-                CAvl_rotate(o, arg, node, !bside, CAvl_Deref(arg, CAvl_parent(node)));
+                CAvl_rotate(o, arg, node, !bside, CAvlDeref(arg, CAvl_parent(node)));
                 CAvl_balance(node) = 0;
                 CAvl_balance(child) = 0;
                 node = child;
                 delta -= 1;
                 break;
             case 0:
-                CAvl_rotate(o, arg, node, !bside, CAvl_Deref(arg, CAvl_parent(node)));
+                CAvl_rotate(o, arg, node, !bside, CAvlDeref(arg, CAvl_parent(node)));
                 CAvl_balance(node) = 1 * bsidef;
                 CAvl_balance(child) = -1 * bsidef;
                 node = child;
                 break;
             case -1:
-                ASSERT(CAvl_link(child)[!bside] != CAvlNullLink)
-                gchild = CAvl_Deref(arg, CAvl_link(child)[!bside]);
+                ASSERT(CAvl_link(child)[!bside] != CAvl_nulllink())
+                gchild = CAvlDeref(arg, CAvl_link(child)[!bside]);
                 CAvl_rotate(o, arg, child, bside, node);
-                CAvl_rotate(o, arg, node, !bside, CAvl_Deref(arg, CAvl_parent(node)));
+                CAvl_rotate(o, arg, node, !bside, CAvlDeref(arg, CAvl_parent(node)));
                 CAvl_balance(node) = -CAvl_MAX(0, CAvl_balance(gchild) * bsidef) * bsidef;
                 CAvl_balance(child) = CAvl_MAX(0, -CAvl_balance(gchild) * bsidef) * bsidef;
                 CAvl_balance(gchild) = 0;
@@ -369,32 +376,37 @@ static void CAvl_rebalance (CAvl *o, CAvlArg arg, CAvlNode node, uint8_t side, i
     //       the height of the heaviest subtree was unchanged. If the transformation
     //       reduces delta by one, it becomes -1.
     
-    if (CAvl_parent(node) != CAvlNullLink) {
-        CAvlNode node_parent = CAvl_Deref(arg, CAvl_parent(node));
+    if (CAvl_parent(node) != CAvl_nulllink()) {
+        CAvlRef node_parent = CAvlDeref(arg, CAvl_parent(node));
         CAvl_rebalance(o, arg, node_parent, node.link == CAvl_link(node_parent)[1], delta);
     }
 }
 
-#if CAVL_PARAM_KEYS_ARE_INDICES
-static CAvlCount CAvl_child_count (CAvlArg arg, CAvlNode n, int dir)
+#if CAVL_PARAM_FEATURE_KEYS_ARE_INDICES
+static CAvlCount CAvl_child_count (CAvlArg arg, CAvlRef n, int dir)
 {
-    return (CAvl_link(n)[dir] != CAvlNullLink ? CAvl_count(CAvl_Deref(arg, CAvl_link(n)[dir])) : 0);
+    return (CAvl_link(n)[dir] != CAvl_nulllink() ? CAvl_count(CAvlDeref(arg, CAvl_link(n)[dir])) : 0);
 }
 #endif
 
-static void CAvl_Init (CAvl *o)
+static int CAvlIsNullRef (CAvlRef node)
 {
-    o->root = CAvlNullLink;
+    return node.link == CAvl_nulllink();
 }
 
-static CAvlNode CAvl_Deref (CAvlArg arg, CAvlLink link)
+static int CAvlIsValidRef (CAvlRef node)
 {
-    if (link == CAvlNullLink) {
-        return CAvl_nullnode();
+    return node.link != CAvl_nulllink();
+}
+
+static CAvlRef CAvlDeref (CAvlArg arg, CAvlLink link)
+{
+    if (link == CAvl_nulllink()) {
+        return CAvl_nullref();
     }
     
-    CAvlNode n;
-    n.ptr = CAVL_PARAM_DEREF(arg, link);
+    CAvlRef n;
+    n.ptr = CAVL_PARAM_FUN_DEREF(arg, link);
     n.link = link;
     
     ASSERT(n.ptr)
@@ -402,34 +414,40 @@ static CAvlNode CAvl_Deref (CAvlArg arg, CAvlLink link)
     return n;
 }
 
-#if !CAVL_PARAM_KEYS_ARE_INDICES
-static int CAvl_Insert (CAvl *o, CAvlArg arg, CAvlNode node, CAvlNode *out_ref)
+static void CAvl_Init (CAvl *o)
+{
+    o->root = CAvl_nulllink();
+}
+
+#if !CAVL_PARAM_FEATURE_KEYS_ARE_INDICES
+
+static int CAvl_Insert (CAvl *o, CAvlArg arg, CAvlRef node, CAvlRef *out_ref)
 {
-    ASSERT(node.link != CAvlNullLink)
+    ASSERT(node.link != CAvl_nulllink())
     
     // insert to root?
-    if (o->root == CAvlNullLink) {
+    if (o->root == CAvl_nulllink()) {
         o->root = node.link;
-        CAvl_parent(node) = CAvlNullLink;
-        CAvl_link(node)[0] = CAvlNullLink;
-        CAvl_link(node)[1] = CAvlNullLink;
+        CAvl_parent(node) = CAvl_nulllink();
+        CAvl_link(node)[0] = CAvl_nulllink();
+        CAvl_link(node)[1] = CAvl_nulllink();
         CAvl_balance(node) = 0;
-#if CAVL_PARAM_USE_COUNTS
+#if CAVL_PARAM_FEATURE_COUNTS
         CAvl_count(node) = 1;
 #endif
         
         CAvl_assert_tree(o, arg);
         
         if (out_ref) {
-            *out_ref = CAvl_nullnode();
+            *out_ref = CAvl_nullref();
         }
         return 1;
     }
     
-    CAvlNode c = CAvl_Deref(arg, o->root);
+    CAvlRef c = CAvlDeref(arg, o->root);
     int side;
     while (1) {
-        int comp = CAvl_compare_nodes(arg, node, c);
+        int comp = CAvl_compare_entries(arg, node, c);
         
         if (comp == 0) {
             if (out_ref) {
@@ -440,24 +458,24 @@ static int CAvl_Insert (CAvl *o, CAvlArg arg, CAvlNode node, CAvlNode *out_ref)
         
         side = (comp == 1);
         
-        if (CAvl_link(c)[side] == CAvlNullLink) {
+        if (CAvl_link(c)[side] == CAvl_nulllink()) {
             break;
         }
         
-        c = CAvl_Deref(arg, CAvl_link(c)[side]);
+        c = CAvlDeref(arg, CAvl_link(c)[side]);
     }
     
     CAvl_link(c)[side] = node.link;
     CAvl_parent(node) = c.link;
-    CAvl_link(node)[0] = CAvlNullLink;
-    CAvl_link(node)[1] = CAvlNullLink;
+    CAvl_link(node)[0] = CAvl_nulllink();
+    CAvl_link(node)[1] = CAvl_nulllink();
     CAvl_balance(node) = 0;
-#if CAVL_PARAM_USE_COUNTS
+#if CAVL_PARAM_FEATURE_COUNTS
     CAvl_count(node) = 1;
 #endif
     
-#if CAVL_PARAM_USE_COUNTS
-    for (CAvlNode p = c; p.link != CAvlNullLink; p = CAvl_Deref(arg, CAvl_parent(p))) {
+#if CAVL_PARAM_FEATURE_COUNTS
+    for (CAvlRef p = c; p.link != CAvl_nulllink(); p = CAvlDeref(arg, CAvl_parent(p))) {
         CAvl_count(p)++;
     }
 #endif
@@ -471,24 +489,81 @@ static int CAvl_Insert (CAvl *o, CAvlArg arg, CAvlNode node, CAvlNode *out_ref)
     }
     return 1;
 }
+
+#else
+
+static void CAvl_InsertAt (CAvl *o, CAvlArg arg, CAvlRef node, CAvlCount index)
+{
+    ASSERT(node.link != CAvl_nulllink())
+    ASSERT(index <= CAvl_Count(o, arg))
+    
+    // insert to root?
+    if (o->root == CAvl_nulllink()) {
+        o->root = node.link;
+        CAvl_parent(node) = CAvl_nulllink();
+        CAvl_link(node)[0] = CAvl_nulllink();
+        CAvl_link(node)[1] = CAvl_nulllink();
+        CAvl_balance(node) = 0;
+        CAvl_count(node) = 1;
+        
+        CAvl_assert_tree(o, arg);
+        return;
+    }
+    
+    CAvlRef c = CAvlDeref(arg, o->root);
+    CAvlCount c_idx = CAvl_child_count(arg, c, 0);
+    int side;
+    while (1) {
+        side = (index > c_idx);
+        
+        if (CAvl_link(c)[side] == CAvl_nulllink()) {
+            break;
+        }
+        
+        c = CAvlDeref(arg, CAvl_link(c)[side]);
+        
+        if (side == 0) {
+            c_idx -= 1 + CAvl_child_count(arg, c, 1);
+        } else {
+            c_idx += 1 + CAvl_child_count(arg, c, 0);
+        }
+    }
+    
+    CAvl_link(c)[side] = node.link;
+    CAvl_parent(node) = c.link;
+    CAvl_link(node)[0] = CAvl_nulllink();
+    CAvl_link(node)[1] = CAvl_nulllink();
+    CAvl_balance(node) = 0;
+    CAvl_count(node) = 1;
+    
+    for (CAvlRef p = c; p.link != CAvl_nulllink(); p = CAvlDeref(arg, CAvl_parent(p))) {
+        CAvl_count(p)++;
+    }
+    
+    CAvl_rebalance(o, arg, c, side, 1);
+    
+    CAvl_assert_tree(o, arg);
+    return;
+}
+
 #endif
 
-static void CAvl_Remove (CAvl *o, CAvlArg arg, CAvlNode node)
+static void CAvl_Remove (CAvl *o, CAvlArg arg, CAvlRef node)
 {
-    ASSERT(node.link != CAvlNullLink)
-    ASSERT(o->root != CAvlNullLink)
+    ASSERT(node.link != CAvl_nulllink())
+    ASSERT(o->root != CAvl_nulllink())
     
-    if (CAvl_link(node)[0] != CAvlNullLink && CAvl_link(node)[1] != CAvlNullLink) {
-        CAvlNode max = CAvl_subtree_max(arg, CAvl_Deref(arg, CAvl_link(node)[0]));
-        CAvl_swap_nodes(o, arg, node, max, CAvl_Deref(arg, CAvl_parent(node)), CAvl_Deref(arg, CAvl_parent(max)));
+    if (CAvl_link(node)[0] != CAvl_nulllink() && CAvl_link(node)[1] != CAvl_nulllink()) {
+        CAvlRef max = CAvl_subtree_max(arg, CAvlDeref(arg, CAvl_link(node)[0]));
+        CAvl_swap_entries(o, arg, node, max, CAvlDeref(arg, CAvl_parent(node)), CAvlDeref(arg, CAvl_parent(max)));
     }
     
-    ASSERT(CAvl_link(node)[0] == CAvlNullLink || CAvl_link(node)[1] == CAvlNullLink)
+    ASSERT(CAvl_link(node)[0] == CAvl_nulllink() || CAvl_link(node)[1] == CAvl_nulllink())
     
-    CAvlNode paren = CAvl_Deref(arg, CAvl_parent(node));
-    CAvlNode child = (CAvl_link(node)[0] != CAvlNullLink ? CAvl_Deref(arg, CAvl_link(node)[0]) : CAvl_Deref(arg, CAvl_link(node)[1]));
+    CAvlRef paren = CAvlDeref(arg, CAvl_parent(node));
+    CAvlRef child = (CAvl_link(node)[0] != CAvl_nulllink() ? CAvlDeref(arg, CAvl_link(node)[0]) : CAvlDeref(arg, CAvl_link(node)[1]));
     
-    if (paren.link != CAvlNullLink) {
+    if (paren.link != CAvl_nulllink()) {
         int side = (node.link == CAvl_link(paren)[1]);
         CAvl_replace_subtree_fix_counts(o, arg, node, child, paren);
         CAvl_rebalance(o, arg, paren, side, -1);
@@ -499,17 +574,18 @@ static void CAvl_Remove (CAvl *o, CAvlArg arg, CAvlNode node)
     CAvl_assert_tree(o, arg);
 }
 
-#if !CAVL_PARAM_KEYS_ARE_INDICES
-static CAvlNode CAvl_Lookup (const CAvl *o, CAvlArg arg, CAvlKey key)
+#if !CAVL_PARAM_FEATURE_KEYS_ARE_INDICES
+
+static CAvlRef CAvl_Lookup (const CAvl *o, CAvlArg arg, CAvlKey key)
 {
-    if (o->root == CAvlNullLink) {
-        return CAvl_nullnode();
+    if (o->root == CAvl_nulllink()) {
+        return CAvl_nullref();
     }
     
-    CAvlNode c = CAvl_Deref(arg, o->root);
+    CAvlRef c = CAvlDeref(arg, o->root);
     while (1) {
         // compare
-        int comp = CAvl_compare_key_node(arg, key, c);
+        int comp = CAvl_compare_key_entry(arg, key, c);
         
         // have we found a node that compares equal?
         if (comp == 0) {
@@ -519,24 +595,24 @@ static CAvlNode CAvl_Lookup (const CAvl *o, CAvlArg arg, CAvlKey key)
         int side = (comp == 1);
         
         // have we reached a leaf?
-        if (CAvl_link(c)[side] == CAvlNullLink) {
+        if (CAvl_link(c)[side] == CAvl_nulllink()) {
             return c;
         }
         
-        c = CAvl_Deref(arg, CAvl_link(c)[side]);
+        c = CAvlDeref(arg, CAvl_link(c)[side]);
     }
 }
 
-static CAvlNode CAvl_LookupExact (const CAvl *o, CAvlArg arg, CAvlKey key)
+static CAvlRef CAvl_LookupExact (const CAvl *o, CAvlArg arg, CAvlKey key)
 {
-    if (o->root == CAvlNullLink) {
-        return CAvl_nullnode();
+    if (o->root == CAvl_nulllink()) {
+        return CAvl_nullref();
     }
     
-    CAvlNode c = CAvl_Deref(arg, o->root);
+    CAvlRef c = CAvlDeref(arg, o->root);
     while (1) {
         // compare
-        int comp = CAvl_compare_key_node(arg, key, c);
+        int comp = CAvl_compare_key_entry(arg, key, c);
         
         // have we found a node that compares equal?
         if (comp == 0) {
@@ -546,68 +622,69 @@ static CAvlNode CAvl_LookupExact (const CAvl *o, CAvlArg arg, CAvlKey key)
         int side = (comp == 1);
         
         // have we reached a leaf?
-        if (CAvl_link(c)[side] == CAvlNullLink) {
-            return CAvl_nullnode();
+        if (CAvl_link(c)[side] == CAvl_nulllink()) {
+            return CAvl_nullref();
         }
         
-        c = CAvl_Deref(arg, CAvl_link(c)[side]);
+        c = CAvlDeref(arg, CAvl_link(c)[side]);
     }
 }
+
 #endif
 
-static CAvlNode CAvl_GetFirst (const CAvl *o, CAvlArg arg)
+static CAvlRef CAvl_GetFirst (const CAvl *o, CAvlArg arg)
 {
-    if (o->root == CAvlNullLink) {
-        return CAvl_nullnode();
+    if (o->root == CAvl_nulllink()) {
+        return CAvl_nullref();
     }
     
-    return CAvl_subtree_min(arg, CAvl_Deref(arg, o->root));
+    return CAvl_subtree_min(arg, CAvlDeref(arg, o->root));
 }
 
-static CAvlNode CAvl_GetLast (const CAvl *o, CAvlArg arg)
+static CAvlRef CAvl_GetLast (const CAvl *o, CAvlArg arg)
 {
-    if (o->root == CAvlNullLink) {
-        return CAvl_nullnode();
+    if (o->root == CAvl_nulllink()) {
+        return CAvl_nullref();
     }
     
-    return CAvl_subtree_max(arg, CAvl_Deref(arg, o->root));
+    return CAvl_subtree_max(arg, CAvlDeref(arg, o->root));
 }
 
-static CAvlNode CAvl_GetNext (const CAvl *o, CAvlArg arg, CAvlNode node)
+static CAvlRef CAvl_GetNext (const CAvl *o, CAvlArg arg, CAvlRef node)
 {
-    ASSERT(node.link != CAvlNullLink)
-    ASSERT(o->root != CAvlNullLink)
+    ASSERT(node.link != CAvl_nulllink())
+    ASSERT(o->root != CAvl_nulllink())
     
-    if (CAvl_link(node)[1] != CAvlNullLink) {
-        node = CAvl_Deref(arg, CAvl_link(node)[1]);
-        while (CAvl_link(node)[0] != CAvlNullLink) {
-            node = CAvl_Deref(arg, CAvl_link(node)[0]);
+    if (CAvl_link(node)[1] != CAvl_nulllink()) {
+        node = CAvlDeref(arg, CAvl_link(node)[1]);
+        while (CAvl_link(node)[0] != CAvl_nulllink()) {
+            node = CAvlDeref(arg, CAvl_link(node)[0]);
         }
     } else {
-        while (CAvl_parent(node) != CAvlNullLink && node.link == CAvl_link(CAvl_Deref(arg, CAvl_parent(node)))[1]) {
-            node = CAvl_Deref(arg, CAvl_parent(node));
+        while (CAvl_parent(node) != CAvl_nulllink() && node.link == CAvl_link(CAvlDeref(arg, CAvl_parent(node)))[1]) {
+            node = CAvlDeref(arg, CAvl_parent(node));
         }
-        node = CAvl_Deref(arg, CAvl_parent(node));
+        node = CAvlDeref(arg, CAvl_parent(node));
     }
     
     return node;
 }
 
-static CAvlNode CAvl_GetPrev (const CAvl *o, CAvlArg arg, CAvlNode node)
+static CAvlRef CAvl_GetPrev (const CAvl *o, CAvlArg arg, CAvlRef node)
 {
-    ASSERT(node.link != CAvlNullLink)
-    ASSERT(o->root != CAvlNullLink)
+    ASSERT(node.link != CAvl_nulllink())
+    ASSERT(o->root != CAvl_nulllink())
     
-    if (CAvl_link(node)[0] != CAvlNullLink) {
-        node = CAvl_Deref(arg, CAvl_link(node)[0]);
-        while (CAvl_link(node)[1] != CAvlNullLink) {
-            node = CAvl_Deref(arg, CAvl_link(node)[1]);
+    if (CAvl_link(node)[0] != CAvl_nulllink()) {
+        node = CAvlDeref(arg, CAvl_link(node)[0]);
+        while (CAvl_link(node)[1] != CAvl_nulllink()) {
+            node = CAvlDeref(arg, CAvl_link(node)[1]);
         }
     } else {
-        while (CAvl_parent(node) != CAvlNullLink && node.link == CAvl_link(CAvl_Deref(arg, CAvl_parent(node)))[0]) {
-            node = CAvl_Deref(arg, CAvl_parent(node));
+        while (CAvl_parent(node) != CAvl_nulllink() && node.link == CAvl_link(CAvlDeref(arg, CAvl_parent(node)))[0]) {
+            node = CAvlDeref(arg, CAvl_parent(node));
         }
-        node = CAvl_Deref(arg, CAvl_parent(node));
+        node = CAvlDeref(arg, CAvl_parent(node));
     }
     
     return node;
@@ -615,38 +692,38 @@ static CAvlNode CAvl_GetPrev (const CAvl *o, CAvlArg arg, CAvlNode node)
 
 static int CAvl_IsEmpty (const CAvl *o)
 {
-    return o->root == CAvlNullLink;
+    return o->root == CAvl_nulllink();
 }
 
 static void CAvl_Verify (const CAvl *o, CAvlArg arg)
 {
-    if (o->root != CAvlNullLink) {
-        CAvlNode root = CAvl_Deref(arg, o->root);
-        ASSERT(CAvl_parent(root) == CAvlNullLink)
+    if (o->root != CAvl_nulllink()) {
+        CAvlRef root = CAvlDeref(arg, o->root);
+        ASSERT(CAvl_parent(root) == CAvl_nulllink())
         CAvl_verify_recurser(arg, root);
     }
 }
 
-#if CAVL_PARAM_USE_COUNTS
+#if CAVL_PARAM_FEATURE_COUNTS
 
 static CAvlCount CAvl_Count (const CAvl *o, CAvlArg arg)
 {
-    return (o->root != CAvlNullLink ? CAvl_count(CAvl_Deref(arg, o->root)) : 0);
+    return (o->root != CAvl_nulllink() ? CAvl_count(CAvlDeref(arg, o->root)) : 0);
 }
 
-static CAvlCount CAvl_IndexOf (const CAvl *o, CAvlArg arg, CAvlNode node)
+static CAvlCount CAvl_IndexOf (const CAvl *o, CAvlArg arg, CAvlRef node)
 {
-    ASSERT(node.link != CAvlNullLink)
-    ASSERT(o->root != CAvlNullLink)
+    ASSERT(node.link != CAvl_nulllink())
+    ASSERT(o->root != CAvl_nulllink())
     
-    CAvlCount index = (CAvl_link(node)[0] != CAvlNullLink ? CAvl_count(CAvl_Deref(arg, CAvl_link(node)[0])) : 0);
+    CAvlCount index = (CAvl_link(node)[0] != CAvl_nulllink() ? CAvl_count(CAvlDeref(arg, CAvl_link(node)[0])) : 0);
     
-    CAvlNode paren = CAvl_Deref(arg, CAvl_parent(node));
+    CAvlRef paren = CAvlDeref(arg, CAvl_parent(node));
     
-    for (CAvlNode c = node; paren.link != CAvlNullLink; c = paren, paren = CAvl_Deref(arg, CAvl_parent(c))) {
+    for (CAvlRef c = node; paren.link != CAvl_nulllink(); c = paren, paren = CAvlDeref(arg, CAvl_parent(c))) {
         if (c.link == CAvl_link(paren)[1]) {
             ASSERT(CAvl_count(paren) > CAvl_count(c))
-            ASSERT(CAvl_count(paren) - CAvl_count(c) <= CAVL_PARAM_COUNT_MAX - index)
+            ASSERT(CAvl_count(paren) - CAvl_count(c) <= CAVL_PARAM_VALUE_COUNT_MAX - index)
             index += CAvl_count(paren) - CAvl_count(c);
         }
     }
@@ -654,28 +731,28 @@ static CAvlCount CAvl_IndexOf (const CAvl *o, CAvlArg arg, CAvlNode node)
     return index;
 }
 
-static CAvlNode CAvl_GetAt (const CAvl *o, CAvlArg arg, CAvlCount index)
+static CAvlRef CAvl_GetAt (const CAvl *o, CAvlArg arg, CAvlCount index)
 {
     if (index >= CAvl_Count(o, arg)) {
-        return CAvl_nullnode();
+        return CAvl_nullref();
     }
     
-    CAvlNode c = CAvl_Deref(arg, o->root);
+    CAvlRef c = CAvlDeref(arg, o->root);
     
     while (1) {
-        ASSERT(c.link != CAvlNullLink)
+        ASSERT(c.link != CAvl_nulllink())
         ASSERT(index < CAvl_count(c))
         
-        CAvlCount left_count = (CAvl_link(c)[0] != CAvlNullLink ? CAvl_count(CAvl_Deref(arg, CAvl_link(c)[0])) : 0);
+        CAvlCount left_count = (CAvl_link(c)[0] != CAvl_nulllink() ? CAvl_count(CAvlDeref(arg, CAvl_link(c)[0])) : 0);
         
         if (index == left_count) {
             return c;
         }
         
         if (index < left_count) {
-            c = CAvl_Deref(arg, CAvl_link(c)[0]);
+            c = CAvlDeref(arg, CAvl_link(c)[0]);
         } else {
-            c = CAvl_Deref(arg, CAvl_link(c)[1]);
+            c = CAvlDeref(arg, CAvl_link(c)[1]);
             index -= left_count + 1;
         }
     }
@@ -683,60 +760,4 @@ static CAvlNode CAvl_GetAt (const CAvl *o, CAvlArg arg, CAvlCount index)
 
 #endif
 
-#if CAVL_PARAM_KEYS_ARE_INDICES
-static void CAvl_InsertAt (CAvl *o, CAvlArg arg, CAvlNode node, CAvlCount index)
-{
-    ASSERT(node.link != CAvlNullLink)
-    ASSERT(index <= CAvl_Count(o, arg))
-    
-    // insert to root?
-    if (o->root == CAvlNullLink) {
-        o->root = node.link;
-        CAvl_parent(node) = CAvlNullLink;
-        CAvl_link(node)[0] = CAvlNullLink;
-        CAvl_link(node)[1] = CAvlNullLink;
-        CAvl_balance(node) = 0;
-        CAvl_count(node) = 1;
-        
-        CAvl_assert_tree(o, arg);
-        return;
-    }
-    
-    CAvlNode c = CAvl_Deref(arg, o->root);
-    CAvlCount c_idx = CAvl_child_count(arg, c, 0);
-    int side;
-    while (1) {
-        side = (index > c_idx);
-        
-        if (CAvl_link(c)[side] == CAvlNullLink) {
-            break;
-        }
-        
-        c = CAvl_Deref(arg, CAvl_link(c)[side]);
-        
-        if (side == 0) {
-            c_idx -= 1 + CAvl_child_count(arg, c, 1);
-        } else {
-            c_idx += 1 + CAvl_child_count(arg, c, 0);
-        }
-    }
-    
-    CAvl_link(c)[side] = node.link;
-    CAvl_parent(node) = c.link;
-    CAvl_link(node)[0] = CAvlNullLink;
-    CAvl_link(node)[1] = CAvlNullLink;
-    CAvl_balance(node) = 0;
-    CAvl_count(node) = 1;
-    
-    for (CAvlNode p = c; p.link != CAvlNullLink; p = CAvl_Deref(arg, CAvl_parent(p))) {
-        CAvl_count(p)++;
-    }
-    
-    CAvl_rebalance(o, arg, c, side, 1);
-    
-    CAvl_assert_tree(o, arg);
-    return;
-}
-#endif
-
 #include "CAvl_footer.h"

+ 11 - 12
structure/IndexedList.h

@@ -53,7 +53,7 @@ struct IndexedList_s {
 };
 
 struct IndexedListNode_s {
-    IndexedListNode *tree_link[2];
+    IndexedListNode *tree_child[2];
     IndexedListNode *tree_parent;
     int8_t tree_balance;
     uint64_t tree_count;
@@ -148,9 +148,9 @@ static IndexedListNode * IndexedList_GetPrev (IndexedList *o, IndexedListNode *n
 #include "IndexedList_tree.h"
 #include <structure/CAvl_impl.h>
 
-static IndexedListNode * IndexedList__deref (IndexedList__TreeNode ref)
+static IndexedListNode * IndexedList__deref (IndexedList__TreeRef ref)
 {
-    return (ref.link == IndexedList__TreeNullLink ? NULL : ref.ptr);
+    return ref.link;
 }
 
 static void IndexedList_Init (IndexedList *o)
@@ -165,15 +165,15 @@ static void IndexedList_InsertAt (IndexedList *o, IndexedListNode *node, uint64_
     
     uint64_t orig_count = IndexedList__Tree_Count(&o->tree, 0);
     
-    IndexedList__Tree_InsertAt(&o->tree, 0, IndexedList__Tree_Deref(0, node), index);
+    IndexedList__Tree_InsertAt(&o->tree, 0, IndexedList__TreeDeref(0, node), index);
     
-    ASSERT(IndexedList__Tree_IndexOf(&o->tree, 0, IndexedList__Tree_Deref(0, node)) == index)
+    ASSERT(IndexedList__Tree_IndexOf(&o->tree, 0, IndexedList__TreeDeref(0, node)) == index)
     ASSERT(IndexedList__Tree_Count(&o->tree, 0) == orig_count + 1)
 }
 
 static void IndexedList_Remove (IndexedList *o, IndexedListNode *node)
 {
-    IndexedList__Tree_Remove(&o->tree, 0, IndexedList__Tree_Deref(0, node));
+    IndexedList__Tree_Remove(&o->tree, 0, IndexedList__TreeDeref(0, node));
 }
 
 static uint64_t IndexedList_Count (IndexedList *o)
@@ -183,15 +183,15 @@ static uint64_t IndexedList_Count (IndexedList *o)
 
 static uint64_t IndexedList_IndexOf (IndexedList *o, IndexedListNode *node)
 {
-    return IndexedList__Tree_IndexOf(&o->tree, 0, IndexedList__Tree_Deref(0, node));
+    return IndexedList__Tree_IndexOf(&o->tree, 0, IndexedList__TreeDeref(0, node));
 }
 
 static IndexedListNode * IndexedList_GetAt (IndexedList *o, uint64_t index)
 {
     ASSERT(index < IndexedList__Tree_Count(&o->tree, 0))
     
-    IndexedList__TreeNode ref = IndexedList__Tree_GetAt(&o->tree, 0, index);
-    ASSERT(ref.link != IndexedList__TreeNullLink)
+    IndexedList__TreeRef ref = IndexedList__Tree_GetAt(&o->tree, 0, index);
+    ASSERT(!IndexedList__TreeIsNullRef(ref))
     
     return ref.ptr;
 }
@@ -210,15 +210,14 @@ static IndexedListNode * IndexedList_GetNext (IndexedList *o, IndexedListNode *n
 {
     ASSERT(node)
     
-    return IndexedList__deref(IndexedList__Tree_GetNext(&o->tree, 0, IndexedList__Tree_Deref(0, node)));
+    return IndexedList__deref(IndexedList__Tree_GetNext(&o->tree, 0, IndexedList__TreeDeref(0, node)));
 }
 
 static IndexedListNode * IndexedList_GetPrev (IndexedList *o, IndexedListNode *node)
 {
     ASSERT(node)
     
-    return IndexedList__deref(IndexedList__Tree_GetPrev(&o->tree, 0, IndexedList__Tree_Deref(0, node)));
+    return IndexedList__deref(IndexedList__Tree_GetPrev(&o->tree, 0, IndexedList__TreeDeref(0, node)));
 }
 
-
 #endif

+ 13 - 13
structure/IndexedList_tree.h

@@ -1,14 +1,14 @@
-#define CAVL_PARAM_USE_COUNTS 1
 #define CAVL_PARAM_NAME IndexedList__Tree
-#define CAVL_PARAM_ENTRY IndexedListNode
-#define CAVL_PARAM_LINK IndexedList__tree_link
-#define CAVL_PARAM_ARG int
-#define CAVL_PARAM_COUNT uint64_t
-#define CAVL_PARAM_COUNT_MAX UINT64_MAX
-#define CAVL_PARAM_NULL NULL
-#define CAVL_PARAM_DEREF(arg, link) (link)
-#define CAVL_PARAM_NODE_LINK tree_link
-#define CAVL_PARAM_NODE_BALANCE tree_balance
-#define CAVL_PARAM_NODE_PARENT tree_parent
-#define CAVL_PARAM_NODE_COUNT tree_count
-#define CAVL_PARAM_KEYS_ARE_INDICES 1
+#define CAVL_PARAM_FEATURE_COUNTS 1
+#define CAVL_PARAM_FEATURE_KEYS_ARE_INDICES 1
+#define CAVL_PARAM_TYPE_ENTRY IndexedListNode
+#define CAVL_PARAM_TYPE_LINK IndexedList__tree_link
+#define CAVL_PARAM_TYPE_ARG int
+#define CAVL_PARAM_TYPE_COUNT uint64_t
+#define CAVL_PARAM_VALUE_COUNT_MAX UINT64_MAX
+#define CAVL_PARAM_VALUE_NULL ((IndexedList__tree_link)NULL)
+#define CAVL_PARAM_FUN_DEREF(arg, link) (link)
+#define CAVL_PARAM_MEMBER_CHILD tree_child
+#define CAVL_PARAM_MEMBER_BALANCE tree_balance
+#define CAVL_PARAM_MEMBER_PARENT tree_parent
+#define CAVL_PARAM_MEMBER_COUNT tree_count