Bläddra i källkod

structure: add SLinkedList

ambrop7 13 år sedan
förälder
incheckning
9323a5e812

+ 38 - 0
structure/SLinkedList.h

@@ -0,0 +1,38 @@
+/**
+ * @file SLinkedList.h
+ * @author Ambroz Bizjak <ambrop7@gmail.com>
+ * 
+ * @section LICENSE
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BADVPN_SLINKEDLIST_H
+#define BADVPN_SLINKEDLIST_H
+
+#include <stddef.h>
+
+#include <misc/merge.h>
+#include <misc/debug.h>
+
+#endif

+ 61 - 0
structure/SLinkedList_decl.h

@@ -0,0 +1,61 @@
+/**
+ * @file SLinkedList_decl.h
+ * @author Ambroz Bizjak <ambrop7@gmail.com>
+ * 
+ * @section LICENSE
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "SLinkedList_header.h"
+
+typedef struct {
+    SLinkedListEntry *first;
+#if SLINKEDLIST_PARAM_FEATURE_LAST
+    SLinkedListEntry *last;
+#endif
+} SLinkedList;
+
+typedef struct {
+    SLinkedListEntry *prev;
+    SLinkedListEntry *next;
+} SLinkedListNode;
+
+static SLinkedListEntry * SLinkedListNext (SLinkedListEntry *entry);
+static SLinkedListEntry * SLinkedListPrev (SLinkedListEntry *entry);
+
+static void SLinkedList_Init (SLinkedList *o);
+static void SLinkedList_Prepend (SLinkedList *o, SLinkedListEntry *entry);
+#if SLINKEDLIST_PARAM_FEATURE_LAST
+static void SLinkedList_Append (SLinkedList *o, SLinkedListEntry *entry);
+#endif
+static void SLinkedList_InsertBefore (SLinkedList *o, SLinkedListEntry *entry, SLinkedListEntry *before_entry);
+static void SLinkedList_InsertAfter (SLinkedList *o, SLinkedListEntry *entry, SLinkedListEntry *after_entry);
+static void SLinkedList_Remove (SLinkedList *o, SLinkedListEntry *entry);
+static SLinkedListEntry * SLinkedList_First (const SLinkedList *o);
+#if SLINKEDLIST_PARAM_FEATURE_LAST
+static SLinkedListEntry * SLinkedList_Last (const SLinkedList *o);
+#endif
+static int SLinkedList_IsEmpty (const SLinkedList *o);
+
+#include "SLinkedList_footer.h"

+ 53 - 0
structure/SLinkedList_footer.h

@@ -0,0 +1,53 @@
+/**
+ * @file SLinkedList_footer.h
+ * @author Ambroz Bizjak <ambrop7@gmail.com>
+ * 
+ * @section LICENSE
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#undef SLINKEDLIST_PARAM_NAME
+#undef SLINKEDLIST_PARAM_FEATURE_LAST
+#undef SLINKEDLIST_PARAM_TYPE_ENTRY
+#undef SLINKEDLIST_PARAM_MEMBER_NODE
+
+#undef SLinkedList
+#undef SLinkedListEntry
+#undef SLinkedListNode
+
+#undef SLinkedListNext
+#undef SLinkedListPrev
+
+#undef SLinkedList_Init
+#undef SLinkedList_Prepend
+#undef SLinkedList_Append
+#undef SLinkedList_InsertBefore
+#undef SLinkedList_InsertAfter
+#undef SLinkedList_Remove
+#undef SLinkedList_First
+#undef SLinkedList_Last
+#undef SLinkedList_IsEmpty
+
+#undef SLinkedList_prev
+#undef SLinkedList_next

+ 58 - 0
structure/SLinkedList_header.h

@@ -0,0 +1,58 @@
+/**
+ * @file SLinkedList_header.h
+ * @author Ambroz Bizjak <ambrop7@gmail.com>
+ * 
+ * @section LICENSE
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Preprocessor inputs:
+// SLINKEDLIST_PARAM_NAME - name of this data structure
+// SLINKEDLIST_PARAM_FEATURE_LAST - whether to keep track of the last entry in the list (0/1)
+// SLINKEDLIST_PARAM_TYPE_ENTRY - type of entry
+// SLINKEDLIST_PARAM_MEMBER_NODE - name of the node member in entry
+
+// types
+#define SLinkedList SLINKEDLIST_PARAM_NAME
+#define SLinkedListEntry SLINKEDLIST_PARAM_TYPE_ENTRY
+#define SLinkedListNode MERGE(SLinkedList, Node)
+
+// non-object public functions
+#define SLinkedListNext MERGE(SLinkedList, Next)
+#define SLinkedListPrev MERGE(SLinkedList, Prev)
+
+// public functions
+#define SLinkedList_Init MERGE(SLinkedList, _Init)
+#define SLinkedList_Prepend MERGE(SLinkedList, _Prepend)
+#define SLinkedList_Append MERGE(SLinkedList, _Append)
+#define SLinkedList_InsertBefore MERGE(SLinkedList, _InsertBefore)
+#define SLinkedList_InsertAfter MERGE(SLinkedList, _InsertAfter)
+#define SLinkedList_Remove MERGE(SLinkedList, _Remove)
+#define SLinkedList_First MERGE(SLinkedList, _First)
+#define SLinkedList_Last MERGE(SLinkedList, _Last)
+#define SLinkedList_IsEmpty MERGE(SLinkedList, _IsEmpty)
+
+// private things
+#define SLinkedList_prev(entry) ((entry)->SLINKEDLIST_PARAM_MEMBER_NODE . prev)
+#define SLinkedList_next(entry) ((entry)->SLINKEDLIST_PARAM_MEMBER_NODE . next)

+ 151 - 0
structure/SLinkedList_impl.h

@@ -0,0 +1,151 @@
+/**
+ * @file SLinkedList_impl.h
+ * @author Ambroz Bizjak <ambrop7@gmail.com>
+ * 
+ * @section LICENSE
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "SLinkedList_header.h"
+
+static SLinkedListEntry * SLinkedListNext (SLinkedListEntry *entry)
+{
+    ASSERT(entry)
+    
+    return SLinkedList_next(entry);
+}
+
+static SLinkedListEntry * SLinkedListPrev (SLinkedListEntry *entry)
+{
+    ASSERT(entry)
+    
+    return SLinkedList_prev(entry);
+}
+
+static void SLinkedList_Init (SLinkedList *o)
+{
+    o->first = NULL;
+#if SLINKEDLIST_PARAM_FEATURE_LAST
+    o->last = NULL;
+#endif
+}
+
+static void SLinkedList_Prepend (SLinkedList *o, SLinkedListEntry *entry)
+{
+    ASSERT(entry)
+
+    SLinkedList_prev(entry) = NULL;
+    SLinkedList_next(entry) = o->first;
+    if (o->first) {
+        SLinkedList_prev(o->first) = entry;
+    } else {
+#if SLINKEDLIST_PARAM_FEATURE_LAST
+        o->last = entry;
+#endif
+    }
+    o->first = entry;
+}
+
+#if SLINKEDLIST_PARAM_FEATURE_LAST
+static void SLinkedList_Append (SLinkedList *o, SLinkedListEntry *entry)
+{
+    ASSERT(entry)
+
+    SLinkedList_next(entry) = NULL;
+    SLinkedList_prev(entry) = o->last;
+    if (o->last) {
+        SLinkedList_next(o->last) = entry;
+    } else {
+        o->first = entry;
+    }
+    o->last = entry;
+}
+#endif
+
+static void SLinkedList_InsertBefore (SLinkedList *o, SLinkedListEntry *entry, SLinkedListEntry *before_entry)
+{
+    ASSERT(entry)
+    ASSERT(before_entry)
+    
+    SLinkedList_prev(entry) = SLinkedList_prev(before_entry);
+    SLinkedList_next(entry) = before_entry;
+    if (SLinkedList_prev(before_entry)) {
+        SLinkedList_next(SLinkedList_prev(before_entry)) = entry;
+    } else {
+        o->first = entry;
+    }
+    SLinkedList_prev(before_entry) = entry;
+}
+
+static void SLinkedList_InsertAfter (SLinkedList *o, SLinkedListEntry *entry, SLinkedListEntry *after_entry)
+{
+    ASSERT(entry)
+    ASSERT(after_entry)
+    
+    SLinkedList_next(entry) = SLinkedList_next(after_entry);
+    SLinkedList_prev(entry) = after_entry;
+    if (SLinkedList_next(after_entry)) {
+        SLinkedList_prev(SLinkedList_next(after_entry)) = entry;
+    } else {
+#if SLINKEDLIST_PARAM_FEATURE_LAST
+        o->last = entry;
+#endif
+    }
+    SLinkedList_next(after_entry) = entry;
+}
+
+static void SLinkedList_Remove (SLinkedList *o, SLinkedListEntry *entry)
+{
+    if (SLinkedList_prev(entry)) {
+        SLinkedList_next(SLinkedList_prev(entry)) = SLinkedList_next(entry);
+    } else {
+        o->first = SLinkedList_next(entry);
+    }
+    if (SLinkedList_next(entry)) {
+        SLinkedList_prev(SLinkedList_next(entry)) = SLinkedList_prev(entry);
+    } else {
+#if SLINKEDLIST_PARAM_FEATURE_LAST
+        o->last = SLinkedList_prev(entry);
+#endif
+    }
+}
+
+static SLinkedListEntry * SLinkedList_First (const SLinkedList *o)
+{
+    return o->first;
+}
+
+#if SLINKEDLIST_PARAM_FEATURE_LAST
+static SLinkedListEntry * SLinkedList_Last (const SLinkedList *o)
+{
+    return o->last;
+}
+#endif
+
+static int SLinkedList_IsEmpty (const SLinkedList *o)
+{
+    return !o->first;
+}
+
+#include "SLinkedList_footer.h"