876 * the last child in the linked list (negative if there is no such pointer) |
874 * the last child in the linked list (negative if there is no such pointer) |
877 * @param loc_prev offset in the node struct for the prev pointer |
875 * @param loc_prev offset in the node struct for the prev pointer |
878 * @param loc_next offset in the node struct for the next pointer |
876 * @param loc_next offset in the node struct for the next pointer |
879 * @return the new tree |
877 * @return the new tree |
880 * @see cxTreeCreateSimple() |
878 * @see cxTreeCreateSimple() |
|
879 * @see cxTreeCreateWrapped() |
881 */ |
880 */ |
882 __attribute__((__nonnull__, __warn_unused_result__)) |
881 __attribute__((__nonnull__, __warn_unused_result__)) |
883 CxTree *cxTreeCreate( |
882 CxTree *cxTreeCreate( |
884 const CxAllocator *allocator, |
883 const CxAllocator *allocator, |
885 cx_tree_node_create_func create_func, |
884 cx_tree_node_create_func create_func, |
914 return cxTreeCreate(cxDefaultAllocator, |
913 return cxTreeCreate(cxDefaultAllocator, |
915 create_func, search_func, cx_tree_node_base_layout); |
914 create_func, search_func, cx_tree_node_base_layout); |
916 } |
915 } |
917 |
916 |
918 /** |
917 /** |
|
918 * Creates a new tree structure based on an existing tree. |
|
919 * |
|
920 * The specified \p allocator will be used for creating the tree struct |
|
921 * and SHALL be used by \p create_func to allocate memory for the nodes. |
|
922 * |
|
923 * \attention This function will create an incompletely defined tree structure |
|
924 * where neither the create function, the search function, nor a destructor |
|
925 * will be set. If you wish to use any of this functionality for the wrapped |
|
926 * tree, you need to specify those functions afterwards. |
|
927 * |
|
928 * @param root the root node of the tree that shall be wrapped |
|
929 * @param loc_parent offset in the node struct for the parent pointer |
|
930 * @param loc_children offset in the node struct for the children linked list |
|
931 * @param loc_last_child optional offset in the node struct for the pointer to |
|
932 * the last child in the linked list (negative if there is no such pointer) |
|
933 * @param loc_prev offset in the node struct for the prev pointer |
|
934 * @param loc_next offset in the node struct for the next pointer |
|
935 * @return the new tree |
|
936 * @see cxTreeCreate() |
|
937 */ |
|
938 __attribute__((__nonnull__, __warn_unused_result__)) |
|
939 CxTree *cxTreeCreateWrapped( |
|
940 void *root, |
|
941 ptrdiff_t loc_parent, |
|
942 ptrdiff_t loc_children, |
|
943 ptrdiff_t loc_last_child, |
|
944 ptrdiff_t loc_prev, |
|
945 ptrdiff_t loc_next |
|
946 ); |
|
947 |
|
948 /** |
919 * Destroys the tree structure. |
949 * Destroys the tree structure. |
920 * |
950 * |
921 * \attention This function will only invoke the destructor functions |
951 * \attention This function will only invoke the destructor functions |
922 * on the nodes, if specified. |
952 * on the nodes, if specified. |
923 * It will NOT automatically free the nodes with the allocator, because that |
953 * It will NOT automatically free the nodes with the allocator, because that |
925 * a tree which memory is managed by someone else. |
955 * a tree which memory is managed by someone else. |
926 * |
956 * |
927 * @param tree the tree to destroy |
957 * @param tree the tree to destroy |
928 */ |
958 */ |
929 __attribute__((__nonnull__)) |
959 __attribute__((__nonnull__)) |
930 void cxTreeDestroy(CxTree *tree); |
960 static inline void cxTreeDestroy(CxTree *tree) { |
|
961 tree->cl->destructor(tree); |
|
962 } |
|
963 |
|
964 /** |
|
965 * Inserts data into the tree. |
|
966 * |
|
967 * \remark For this function to work, the tree needs specified search and |
|
968 * create functions, which might not be available for wrapped trees |
|
969 * (see #cxTreeCreateWrapped()). |
|
970 * |
|
971 * @param tree the tree |
|
972 * @param data the data to insert |
|
973 * @return zero on success, non-zero on failure |
|
974 */ |
|
975 __attribute__((__nonnull__)) |
|
976 static inline int cxTreeInsert( |
|
977 CxTree *tree, |
|
978 const void *data |
|
979 ) { |
|
980 return tree->cl->insert_element(tree, data); |
|
981 } |
|
982 |
|
983 /** |
|
984 * Inserts elements provided by an iterator efficiently into the tree. |
|
985 * |
|
986 * \remark For this function to work, the tree needs specified search and |
|
987 * create functions, which might not be available for wrapped trees |
|
988 * (see #cxTreeCreateWrapped()). |
|
989 * |
|
990 * @param tree the tree |
|
991 * @param iter the iterator providing the elements |
|
992 * @param n the maximum number of elements to insert |
|
993 * @return the number of elements that could be successfully inserted |
|
994 */ |
|
995 __attribute__((__nonnull__)) |
|
996 static inline size_t cxTreeInsertIter( |
|
997 CxTree *tree, |
|
998 struct cx_iterator_base_s *iter, |
|
999 size_t n |
|
1000 ) { |
|
1001 return tree->cl->insert_many(tree, iter, n); |
|
1002 } |
|
1003 |
|
1004 /** |
|
1005 * Inserts an array of data efficiently into the tree. |
|
1006 * |
|
1007 * \remark For this function to work, the tree needs specified search and |
|
1008 * create functions, which might not be available for wrapped trees |
|
1009 * (see #cxTreeCreateWrapped()). |
|
1010 * |
|
1011 * @param tree the tree |
|
1012 * @param data the array of data to insert |
|
1013 * @param elem_size the size of each element in the array |
|
1014 * @param n the number of elements in the array |
|
1015 * @return the number of elements that could be successfully inserted |
|
1016 */ |
|
1017 __attribute__((__nonnull__)) |
|
1018 static inline size_t cxTreeInsertArray( |
|
1019 CxTree *tree, |
|
1020 const void *data, |
|
1021 size_t elem_size, |
|
1022 size_t n |
|
1023 ) { |
|
1024 if (n == 0) return 0; |
|
1025 if (n == 1) return 0 == cxTreeInsert(tree, data) ? 1 : 0; |
|
1026 CxIterator iter = cxIterator(data, elem_size, n); |
|
1027 return tree->cl->insert_many(tree, cxIteratorRef(iter), n); |
|
1028 } |
|
1029 |
|
1030 /** |
|
1031 * Searches the data in the specified tree. |
|
1032 * |
|
1033 * \remark For this function to work, the tree needs a specified search |
|
1034 * function, which might not be available wrapped trees |
|
1035 * (see #cxTreeCreateWrapped()). |
|
1036 * |
|
1037 * @param tree the tree |
|
1038 * @param data the data to search for |
|
1039 * @return the first matching node, or \c NULL when the data cannot be found |
|
1040 */ |
|
1041 __attribute__((__nonnull__)) |
|
1042 static inline void *cxTreeFind( |
|
1043 CxTree *tree, |
|
1044 const void *data |
|
1045 ) { |
|
1046 return tree->cl->find(tree, tree->root, data); |
|
1047 } |
|
1048 |
|
1049 /** |
|
1050 * Searches the data in the specified subtree. |
|
1051 * |
|
1052 * \note When \p subtree_root is not part of the \p tree, the behavior is |
|
1053 * undefined. |
|
1054 * |
|
1055 * \remark For this function to work, the tree needs a specified search |
|
1056 * function, which might not be the case for wrapped trees |
|
1057 * (see #cxTreeCreateWrapped()). |
|
1058 * |
|
1059 * @param tree the tree |
|
1060 * @param data the data to search for |
|
1061 * @param subtree_root the node where to start |
|
1062 * @return the first matching node, or \c NULL when the data cannot be found |
|
1063 */ |
|
1064 __attribute__((__nonnull__)) |
|
1065 static inline void *cxTreeFindInSubtree( |
|
1066 CxTree *tree, |
|
1067 const void *data, |
|
1068 void *subtree_root |
|
1069 ) { |
|
1070 return tree->cl->find(tree, subtree_root, data); |
|
1071 } |
|
1072 |
|
1073 /** |
|
1074 * Creates a depth-first iterator for the specified tree. |
|
1075 * |
|
1076 * @param tree the tree to iterate |
|
1077 * @param visit_on_exit true, if the iterator shall visit a node again when |
|
1078 * leaving the sub-tree |
|
1079 * @return a tree iterator (depth-first) |
|
1080 * @see cxTreeVisitor() |
|
1081 */ |
|
1082 __attribute__((__nonnull__, __warn_unused_result__)) |
|
1083 static inline CxTreeIterator cxTreeIterator( |
|
1084 CxTree *tree, |
|
1085 bool visit_on_exit |
|
1086 ) { |
|
1087 return tree->cl->iterator(tree, visit_on_exit); |
|
1088 } |
|
1089 |
|
1090 /** |
|
1091 * Creates a breadth-first iterator for the specified tree. |
|
1092 * |
|
1093 * @param tree the tree to iterate |
|
1094 * @return a tree visitor (a.k.a. breadth-first iterator) |
|
1095 * @see cxTreeIterator() |
|
1096 */ |
|
1097 __attribute__((__nonnull__, __warn_unused_result__)) |
|
1098 static inline CxTreeVisitor cxTreeVisitor(CxTree *tree) { |
|
1099 return tree->cl->visitor(tree); |
|
1100 } |
931 |
1101 |
932 #ifdef __cplusplus |
1102 #ifdef __cplusplus |
933 } // extern "C" |
1103 } // extern "C" |
934 #endif |
1104 #endif |
935 |
1105 |