1 /* 2 * Distributed under the Boost Software License, Version 1.0. 3 * (See accompanying file LICENSE_1_0.txt or copy at 4 * http://www.boost.org/LICENSE_1_0.txt) 5 */ 6 module glib.gnode; 7 8 import glib.gmem; 9 import glib.gtypes; 10 11 12 /* Tree traverse flags */ 13 enum GTraverseFlags 14 { 15 G_TRAVERSE_LEAVES = 1 << 0, 16 G_TRAVERSE_NON_LEAVES = 1 << 1, 17 G_TRAVERSE_ALL = G_TRAVERSE_LEAVES | G_TRAVERSE_NON_LEAVES, 18 G_TRAVERSE_MASK = 0x03, 19 G_TRAVERSE_LEAFS = G_TRAVERSE_LEAVES, 20 G_TRAVERSE_NON_LEAFS = G_TRAVERSE_NON_LEAVES 21 } 22 23 /* Tree traverse orders */ 24 enum GTraverseType 25 { 26 G_IN_ORDER, 27 G_PRE_ORDER, 28 G_POST_ORDER, 29 G_LEVEL_ORDER 30 } 31 32 33 extern (C) { 34 35 alias GNodeTraverseFunc = gboolean function (GNode *node, gpointer data); 36 37 alias GNodeForeachFunc = void function (GNode *node, gpointer data); 38 39 alias GCopyFunc = gpointer function (gconstpointer src, gpointer data); 40 41 } 42 43 struct GNode 44 { 45 gpointer data; 46 GNode *next; 47 GNode *prev; 48 GNode *parent; 49 GNode *children; 50 } 51 52 53 bool G_NODE_IS_ROOT(const(GNode) *n) { 54 return n.parent is null && n.prev is null && n.next is null; 55 } 56 57 bool G_NODE_IS_LEAF(const(GNode) *n) { 58 return n.children is null; 59 } 60 61 62 extern (C) { 63 64 GNode* g_node_new (gpointer data); 65 66 void g_node_destroy (GNode *root); 67 68 void g_node_unlink (GNode *node); 69 70 GNode* g_node_copy_deep (GNode *node, 71 GCopyFunc copy_func, 72 gpointer data); 73 74 GNode* g_node_copy (GNode *node); 75 76 GNode* g_node_insert (GNode *parent, 77 gint position, 78 GNode *node); 79 80 GNode* g_node_insert_before (GNode *parent, 81 GNode *sibling, 82 GNode *node); 83 84 GNode* g_node_insert_after (GNode *parent, 85 GNode *sibling, 86 GNode *node); 87 88 GNode* g_node_prepend (GNode *parent, 89 GNode *node); 90 91 guint g_node_n_nodes (GNode *root, 92 GTraverseFlags flags); 93 94 GNode* g_node_get_root (GNode *node); 95 96 gboolean g_node_is_ancestor (GNode *node, 97 GNode *descendant); 98 99 guint g_node_depth (GNode *node); 100 101 GNode* g_node_find (GNode *root, 102 GTraverseType order, 103 GTraverseFlags flags, 104 gpointer data); 105 106 } 107 108 109 auto g_node_append(P, N)(P parent, N node) { 110 return g_node_insert_before(parent, null, node); 111 } 112 113 auto g_node_insert_data(P, Pos, D)(P parent, Pos pos, D data) { 114 return g_node_insert(parent, pos, g_node_new(data)); 115 } 116 117 auto g_node_insert_data_after(P, S, D)(P parent, S sibling, D data) { 118 return g_node_insert_after ((parent), (sibling), g_node_new (data)); 119 } 120 121 auto g_node_insert_data_before(P, S, D)(P parent, S sibling, D data) { 122 return g_node_insert_before (parent, sibling, g_node_new (data)); 123 } 124 125 auto g_node_prepend_data(P, D)(P parent, D data) { 126 return g_node_prepend (parent, g_node_new (data)); 127 } 128 129 auto g_node_append_data(P, D)(P parent, D data) { 130 return g_node_insert_before (parent, null, g_node_new (data)); 131 } 132 133 134 extern (C) { 135 136 void g_node_traverse (GNode *root, 137 GTraverseType order, 138 GTraverseFlags flags, 139 gint max_depth, 140 GNodeTraverseFunc func, 141 gpointer data); 142 143 guint g_node_max_height (GNode *root); 144 145 146 void g_node_children_foreach (GNode *node, 147 GTraverseFlags flags, 148 GNodeForeachFunc func, 149 gpointer data); 150 151 void g_node_reverse_children (GNode *node); 152 153 guint g_node_n_children (GNode *node); 154 155 GNode* g_nodenth_child (GNode *node, 156 guint n); 157 158 GNode* g_node_last_child (GNode *node); 159 160 GNode* g_node_find_child (GNode *node, 161 GTraverseFlags flags, 162 gpointer data); 163 164 gint g_node_child_position (GNode *node, 165 GNode *child); 166 167 gint g_node_child_index (GNode *node, 168 gpointer data); 169 170 171 GNode* g_node_first_sibling (GNode *node); 172 173 GNode* g_node_last_sibling (GNode *node); 174 175 } 176 177 auto g_node_prev_sibling(N)(N node) { 178 return node ? node.prev : null; 179 } 180 181 auto g_node_next_sibling(N)(N node) { 182 return node ? node.next : null; 183 } 184 185 auto g_node_first_child(N)(N node) { 186 return node ? node.children : null; 187 } 188