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