lib: add LinkedList
authorTimePath <andrew.hardaker1995@gmail.com>
Thu, 15 Oct 2015 22:10:48 +0000 (09:10 +1100)
committerTimePath <andrew.hardaker1995@gmail.com>
Thu, 15 Oct 2015 22:11:06 +0000 (09:11 +1100)
qcsrc/lib/_all.inc
qcsrc/lib/linkedlist.qh [new file with mode: 0644]

index 49b8ef7798bccac4f833edb868f31cb79c7161fd..9bc9ca2aefdc29f1cd96ffa5d8cbb0af8497659e 100644 (file)
@@ -41,6 +41,7 @@
 #include "int.qh"
 #include "iter.qh"
 #include "lazy.qh"
+#include "linkedlist.qh"
 #include "log.qh"
 #include "math.qh"
 #include "misc.qh"
diff --git a/qcsrc/lib/linkedlist.qh b/qcsrc/lib/linkedlist.qh
new file mode 100644 (file)
index 0000000..be57bb5
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef LINKEDLIST_H
+#define LINKEDLIST_H
+
+CLASS(LinkedListNode, Object)
+    ATTRIB(LinkedListNode, ll_data, entity, NULL)
+    ATTRIB(LinkedListNode, ll_prev, LinkedListNode, NULL)
+    ATTRIB(LinkedListNode, ll_next, LinkedListNode, NULL)
+ENDCLASS(LinkedListNode)
+
+CLASS(LinkedList, Object)
+    ATTRIB(LinkedList, ll_head, LinkedListNode, NULL);
+    ATTRIB(LinkedList, ll_tail, LinkedListNode, NULL);
+ENDCLASS(LinkedList)
+
+#define LL_NEW() NEW(LinkedList)
+
+/**
+ * Push to tail
+ */
+entity LL_PUSH(LinkedList this, entity e) {
+    LinkedListNode n = NEW(LinkedListNode);
+    n.ll_data = e;
+    n.ll_prev = this.ll_tail;
+    LinkedListNode tail = this.ll_tail;
+    if (tail) {
+        tail.ll_next = n;
+    } else {
+        this.ll_head = this.ll_tail = n;
+    }
+    return e;
+}
+
+/**
+ * Pop from tail
+ */
+entity LL_POP(LinkedList this) {
+    if (!this.ll_tail) return NULL;
+    LinkedListNode n = this.ll_tail;
+    entity e = n.ll_data;
+    LinkedListNode prev = n.ll_prev;
+    if (prev) {
+        prev.ll_next = NULL;
+    } else {
+        this.ll_head = this.ll_tail = NULL;
+    }
+    return e;
+}
+
+#define LL_EACH(list, cond, body) do {                                  \
+    noref int i = 0;                                                    \
+    for (entity _it = list.ll_head; _it; (_it = _it.ll_next, ++i)) {    \
+        noref entity it = _it.ll_data;                                  \
+        if (cond) { body }                                              \
+    }                                                                   \
+} while(0)
+
+#endif