src/cx/tree.h

changeset 913
72db8e42b95e
parent 909
f4e00bb3f3b2
child 914
7da30512efc4
equal deleted inserted replaced
912:9533fc293aea 913:72db8e42b95e
809 /** 809 /**
810 * The class definition for arbitrary trees. 810 * The class definition for arbitrary trees.
811 */ 811 */
812 struct cx_tree_class_s { 812 struct cx_tree_class_s {
813 /** 813 /**
814 * Destructor function.
815 *
816 * Implementations SHALL invoke the node destructor functions if provided
817 * and SHALL deallocate the tree memory.
818 */
819 void (*destructor)(struct cx_tree_s *);
820
821 /**
822 * Member function for inserting a single element. 814 * Member function for inserting a single element.
823 * 815 *
824 * Implementations SHALL NOT simply invoke \p insert_many as this comes 816 * Implementations SHALL NOT simply invoke \p insert_many as this comes
825 * with too much overhead. 817 * with too much overhead.
826 */ 818 */
968 ptrdiff_t loc_prev, 960 ptrdiff_t loc_prev,
969 ptrdiff_t loc_next 961 ptrdiff_t loc_next
970 ); 962 );
971 963
972 /** 964 /**
973 * Destroys the tree structure.
974 *
975 * \attention This function will only invoke the destructor functions
976 * on the nodes, if specified.
977 * It will NOT additionally free the nodes with the tree's allocator, because
978 * that would cause a double-free in most scenarios.
979 *
980 * @param tree the tree to destroy
981 */
982 __attribute__((__nonnull__))
983 static inline void cxTreeDestroy(CxTree *tree) {
984 tree->cl->destructor(tree);
985 }
986
987 /**
988 * Inserts data into the tree. 965 * Inserts data into the tree.
989 * 966 *
990 * \remark For this function to work, the tree needs specified search and 967 * \remark For this function to work, the tree needs specified search and
991 * create functions, which might not be available for wrapped trees 968 * create functions, which might not be available for wrapped trees
992 * (see #cxTreeCreateWrapped()). 969 * (see #cxTreeCreateWrapped()).
1197 1174
1198 /** 1175 /**
1199 * A function that is invoked when a node needs to be re-linked to a new parent. 1176 * A function that is invoked when a node needs to be re-linked to a new parent.
1200 * 1177 *
1201 * When a node is re-linked, sometimes the contents need to be updated. 1178 * When a node is re-linked, sometimes the contents need to be updated.
1202 * This callback is invoked by #cxTreeRemove() so that those updates can be 1179 * This callback is invoked by #cxTreeRemoveNode() and #cxTreeDestroyNode()
1203 * applied when re-linking the children of the removed node. 1180 * so that those updates can be applied when re-linking the children of the
1181 * removed node.
1204 * 1182 *
1205 * @param node the affected node 1183 * @param node the affected node
1206 * @param old_parent the old parent of the node 1184 * @param old_parent the old parent of the node
1207 * @param new_parent the new parent of the node 1185 * @param new_parent the new parent of the node
1208 */ 1186 */
1225 * @param relink_func optional callback to update the content of each re-linked 1203 * @param relink_func optional callback to update the content of each re-linked
1226 * node 1204 * node
1227 * @return zero on success, non-zero if \p node is the root node of the tree 1205 * @return zero on success, non-zero if \p node is the root node of the tree
1228 */ 1206 */
1229 __attribute__((__nonnull__(1,2))) 1207 __attribute__((__nonnull__(1,2)))
1230 int cxTreeRemove( 1208 int cxTreeRemoveNode(
1231 CxTree *tree, 1209 CxTree *tree,
1232 void *node, 1210 void *node,
1233 cx_tree_relink_func relink_func 1211 cx_tree_relink_func relink_func
1234 ); 1212 );
1235 1213
1245 * @param node the node to remove 1223 * @param node the node to remove
1246 */ 1224 */
1247 __attribute__((__nonnull__)) 1225 __attribute__((__nonnull__))
1248 void cxTreeRemoveSubtree(CxTree *tree, void *node); 1226 void cxTreeRemoveSubtree(CxTree *tree, void *node);
1249 1227
1228 /**
1229 * Destroys a node and re-links its children to its former parent.
1230 *
1231 * If the node is not part of the tree, the behavior is undefined.
1232 *
1233 * It is guaranteed that the simple destructor is invoked before
1234 * the advanced destructor.
1235 *
1236 * \attention This function will not free the memory of the node with the
1237 * tree's allocator, because that is usually done by the advanced destructor
1238 * and would therefore result in a double-free.
1239 *
1240 * @param tree the tree
1241 * @param node the node to destroy (must not be the root node)
1242 * @param relink_func optional callback to update the content of each re-linked
1243 * node
1244 * @return zero on success, non-zero if \p node is the root node of the tree
1245 */
1246 __attribute__((__nonnull__(1,2)))
1247 int cxTreeDestroyNode(
1248 CxTree *tree,
1249 void *node,
1250 cx_tree_relink_func relink_func
1251 );
1252
1253 /**
1254 * Destroys a node and it's subtree.
1255 *
1256 * It is guaranteed that the simple destructor is invoked before
1257 * the advanced destructor, starting with the leaf nodes of the subtree.
1258 *
1259 * When this function is invoked on the root node of the tree, it destroys the
1260 * tree contents, but - in contrast to #cxTreeDestroy() - not the tree
1261 * structure, leaving an empty tree behind.
1262 *
1263 * \note The destructor function, if any, will \em not be invoked. That means
1264 * you will need to free the removed subtree by yourself, eventually.
1265 *
1266 * \attention This function will not free the memory of the nodes with the
1267 * tree's allocator, because that is usually done by the advanced destructor
1268 * and would therefore result in a double-free.
1269 *
1270 * @param tree the tree
1271 * @param node the node to remove
1272 * @see cxTreeDestroy()
1273 */
1274 __attribute__((__nonnull__))
1275 void cxTreeDestroySubtree(CxTree *tree, void *node);
1276
1277
1278 /**
1279 * Destroys the tree contents.
1280 *
1281 * It is guaranteed that the simple destructor is invoked before
1282 * the advanced destructor, starting with the leaf nodes of the subtree.
1283 *
1284 * This is a convenience macro for invoking #cxTreeDestroySubtree() on the
1285 * root node of the tree.
1286 *
1287 * \attention Be careful when calling this function when no destructor function
1288 * is registered that actually frees the memory of nodes. In that case you will
1289 * need a reference to the (former) root node of the tree somewhere or
1290 * otherwise you will be leaking memory.
1291 *
1292 * @param tree the tree
1293 * @see cxTreeDestroySubtree()
1294 */
1295 #define cxTreeClear(tree) cxTreeDestroySubtree(tree, tree->root)
1296
1297 /**
1298 * Destroys the tree structure.
1299 *
1300 * The destructor functions are invoked for each node, starting with the leaf
1301 * nodes.
1302 * It is guaranteed that for each node the simple destructor is invoked before
1303 * the advanced destructor.
1304 *
1305 * \attention This function will only invoke the destructor functions
1306 * on the nodes.
1307 * It will NOT additionally free the nodes with the tree's allocator, because
1308 * that would cause a double-free in most scenarios where the advanced
1309 * destructor is already freeing the memory.
1310 *
1311 * @param tree the tree to destroy
1312 */
1313 __attribute__((__nonnull__))
1314 static inline void cxTreeDestroy(CxTree *tree) {
1315 if (tree->root != NULL) {
1316 cxTreeDestroySubtree(tree, tree->root);
1317 }
1318 cxFree(tree->allocator, tree);
1319 }
1320
1250 #ifdef __cplusplus 1321 #ifdef __cplusplus
1251 } // extern "C" 1322 } // extern "C"
1252 #endif 1323 #endif
1253 1324
1254 #endif //UCX_TREE_H 1325 #endif //UCX_TREE_H

mercurial