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 */ |
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 |