Added stack, queue ADTs and related tests.
[platform/upstream/glib.git] / gqueue.c
1 /*
2 * GQueue, opaque ADT with interface:
3
4         q = g_queue_new ();
5         count = g_queue_size (q);
6
7         q_queue_push_front (q, data);
8         q_queue_push_back (q, data);
9         data = q_queue_pop_front (q);
10         data = q_queue_pop_back (q);
11         #define q_queue_push q_queue_push_back
12         #define q_queue_pop q_queue_pop_front
13
14         list = g_queue_get_list (q);
15         #define g_queue_get_front g_queue_get_list
16         list_end = g_queue_get_back (q);
17 */
18
19
20 #ifdef HAVE_CONFIG_H
21 #  include <config.h>
22 #endif
23
24 #include <glib.h>
25
26
27
28
29 GQueue *
30 g_queue_new (void)
31 {
32   GQueue *q = g_new (GQueue, 1);
33
34   q->list = q->list_end = NULL;
35   q->list_size = 0;
36
37   return q;
38 }
39
40
41 void
42 g_queue_free (GQueue *q)
43 {
44   if (q) {
45     if (q->list)
46       g_list_free (q->list);
47     g_free (q);
48   }
49 }
50
51
52 guint
53 g_queue_get_size (GQueue *q)
54 {
55   return (q == NULL) ? 0 : q->list_size;
56 }
57
58
59 void
60 g_queue_push_front (GQueue *q, gpointer data)
61 {
62   if (q) {
63     q->list = g_list_prepend (q->list, data);
64
65     if (q->list_end == NULL)
66       q->list_end = q->list;
67
68     q->list_size++;
69   }
70 }
71
72
73 void
74 g_queue_push_back (GQueue *q, gpointer data)
75 {
76   if (q) {
77     q->list_end = g_list_append (q->list_end, data);
78
79     if (! q->list)
80       q->list = q->list_end;
81     else
82       q->list_end = q->list_end->next;
83
84     q->list_size++;
85   }
86 }
87
88
89 gpointer
90 g_queue_pop_front (GQueue *q)
91 {
92   gpointer data = NULL;
93
94   if ((q) && (q->list)) {
95     GList *node;
96
97     node = q->list;
98     data = node->data;
99
100     if (! node->next) {
101       q->list = q->list_end = NULL;
102       q->list_size = 0;
103     }
104     else {
105       q->list = node->next;
106       q->list->prev = NULL;
107       q->list_size--;
108     }
109
110     g_list_free_1 (node);
111   }
112
113   return data;
114 }
115
116
117 gpointer
118 g_queue_pop_back (GQueue *q)
119 {
120   gpointer data = NULL;
121
122   if ((q) && (q->list)) {
123     GList *node;
124
125     node = q->list_end;
126     data = node->data;
127
128     if (! node->prev) {
129       q->list = q->list_end = NULL;
130       q->list_size = 0;
131     }
132     else {
133       q->list_end = node->prev;
134       q->list_end->next = NULL;
135       q->list_size--;
136     }
137
138     g_list_free_1 (node);
139   }
140
141   return data;
142 }
143
144