diff --git a/Makefile b/Makefile index 7eb90f1..432c98e 100644 --- a/Makefile +++ b/Makefile @@ -17,13 +17,13 @@ all: example libcrap.so %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< -example: example.o memory.o try.o oop.o exceptions/stdex.o tools/strbuilder.o lists/lists.o lists/arraylist.o +example: example.o memory.o try.o oop.o exceptions/stdex.o tools/strbuilder.o lists/lists.o lists/arraylist.o lists/linkedlist.o $(CC) $(LDFLAGS) -o $@ $^ -libcrap.so: memory.o try.o oop.o exceptions/stdex.o tools/strbuilder.o lists/lists.o lists/arraylist.o +libcrap.so: memory.o try.o oop.o exceptions/stdex.o tools/strbuilder.o lists/lists.o lists/arraylist.o lists/linkedlist.o $(CC) $(LIBFLAGS) -o $@ $^ -example.o: example.c try.h +example.o: example.c try.h crap.h memory.o: memory.c memory.h oop.h exceptions/stdex.h try.o: try.c try.h oop.h exceptions/stdex.h oop.o: oop.h misc.h @@ -34,6 +34,7 @@ tools/strbuilder.o: tools/strbuilder.c tools/strbuilder.h exceptions/stdex.h lists/lists.o: lists/lists.c lists/lists.h oop.h lists/arraylist.o: lists/arraylist.c lists/arraylist.h oop.h +lists/linkedlist.o: lists/linkedlist.c lists/linkedlist.h oop.h clean: rm -f *.o exceptions/*.o tools/*.o lists/*.o example diff --git a/crap.h b/crap.h index 4b8080c..17f103b 100644 --- a/crap.h +++ b/crap.h @@ -8,3 +8,4 @@ #include "lists/lists.h" #include "lists/arraylist.h" +#include "lists/linkedlist.h" diff --git a/example.c b/example.c index f1c18c0..07a82b0 100644 --- a/example.c +++ b/example.c @@ -3,13 +3,14 @@ #include int main(void) { - ArrayList_t* list = new ArrayList(); + //ArrayList_t* list = new (ArrayList)(); + LinkedList_t* list = new (LinkedList)(); printf("adding some strings\n"); - list->add(list, "Hallo"); - list->add(list, "Welt"); list->add(list, "Hello"); list->add(list, "World"); + list->add(list, "Foo"); + list->add(list, "Bar"); for (size_t i = 0; i < list->length(list); i++) { printf("%lu: %s\n", i, (const char*) list->get(list, i)); @@ -22,11 +23,19 @@ int main(void) { printf("%lu: %s\n", i, (const char*) list->get(list, i)); } - printf("\nremoving index %lu\n", list->length(list)); - //list->remove(list, list->length(list)); - //List_t* list2 = new List(); + printf("\npush new string\n"); + list->push(list, "Test"); - Object_t* obj = new Object(); + printf("poping string\n"); + const char* string = list->pop(list); + printf(": %s\n", string); + + + printf("\nremoving index %lu\n", list->length(list)); + + list->remove(list, list->length(list)); + + list->destruct(list); return 0; } diff --git a/lists/linkedlist.c b/lists/linkedlist.c new file mode 100644 index 0000000..4a1525d --- /dev/null +++ b/lists/linkedlist.c @@ -0,0 +1,169 @@ +#include "linkedlist.h" +#include "lists.h" +#include "../oop.h" +#include "../try.h" +#include "../exceptions/stdex.h" +#include "../memory.h" + +#include + +#define DEFAULT_SIZE_STEP 64 + +#define to_list(name, obj) LinkedList_t* name = (LinkedList_t*) obj + +class_t LinkedList_class; + +LinkedList_t* method(LinkedList, construct)(void) { + throws(OutOfMemoryException_t); + + sr_(LinkedList_t* list = allocate_object(LinkedList), NULL); + populate(LinkedList)(list, LinkedList_class); + + return list; +} + +size_t method(LinkedList, length)(void* this) { + to_list(list, this); + + LinkedListElement_t* elem = list->first; + + size_t size; + for(size = 0; elem != NULL; size++) + elem = elem->next; + + return size; +} + +void method(LinkedList, add)(void* this, void* obj) { + throws(NullPointerException_t, OutOfMemoryException_t); + if (this == NULL) + throw(new (NullPointerException)()); + + to_list(list, this); + + s_(LinkedListElement_t* entry = allocate(sizeof(LinkedListElement_t))); + + entry->next = NULL; + entry->data = obj; + + if (list->first == NULL) { + list->first = entry; + return; + } + + LinkedListElement_t* last = list->first; + + for(; last->next != NULL; last = last->next); + + last->next = entry; +} + +void* method(LinkedList, get)(void* this, size_t index) { + throws(NullPointerException_t, IndexOutOfBoundsException_t, IndexOutOfBoundsException_t); + if (this == NULL) + throwr(new (NullPointerException)(), NULL); + + to_list(list, this); + + size_t size; + LinkedListElement_t* next; + + for(next = list->first, size = 0; next != NULL; size++, next = next->next) { + if (size == index) + return next->data; + } + + throwr(new (IndexOutOfBoundsException)(index, size), NULL); +} +void method(LinkedList, remove)(void* this, size_t index) { + throws(NullPointerException_t, OutOfMemoryException_t, IndexOutOfBoundsException_t); + if (this == NULL) + throw(new (NullPointerException)()); + + to_list(list, this); + + size_t size; + LinkedListElement_t** next; + + for(next = &(list->first), size = 0; (*next) != NULL; size++, next = &((*next)->next)) { + if (size == index) { + LinkedListElement_t* tmp; + tmp = *next; + *next = (*next)->next; + free(tmp); + return; + } + } + + throw(new (IndexOutOfBoundsException)(index, size)); +} + +void method(LinkedList, push)(void* this, void* obj) { + throws(NullPointerException_t); + if (this == NULL) + throw(new (NullPointerException)()); + + to_list(list, this); + + list->add(list, obj); +} + +void* method(LinkedList, pop)(void* this) { + throws(NullPointerException_t, OutOfMemoryException_t); + if (this == NULL) + throwr(new (NullPointerException)(), NULL); + + to_list(list, this); + + if (list->first == NULL) { + return NULL; // TODO NoElementException? + } + + if (list->first->next == NULL) { + void* value = list->first->data; + free(list->first); + list->first = NULL; + return value; + } + + LinkedListElement_t* current; + LinkedListElement_t* prev; + + for(prev = NULL, current = list->first; current->next != NULL; prev = current, current = current->next); + + void* data = current->data; + free(current); + prev->next = NULL; + return data; + +} + +void method(LinkedList, destruct)(LinkedList_t* this) { + throws(NullPointerException_t); + if (this == NULL) + throw(new (NullPointerException)()); + + to_list(list, this); + + for(LinkedListElement_t* next = list->first; next != NULL;) { + next = next->next; + free(next); + } + + this->super.destruct((Object_t*) list); +} + +void method(LinkedList, populate)(LinkedList_t* obj, class_t c) { + populate(Object)((Object_t*) obj, c); + + obj->first = NULL; + + add_method(obj, LinkedList, destruct); + add_method(obj, LinkedList, length); + add_method(obj, LinkedList, add); + add_method(obj, LinkedList, get); + add_method(obj, LinkedList, remove); + add_method(obj, LinkedList, push); + add_method(obj, LinkedList, pop); +} + diff --git a/lists/linkedlist.h b/lists/linkedlist.h new file mode 100644 index 0000000..35442c3 --- /dev/null +++ b/lists/linkedlist.h @@ -0,0 +1,27 @@ +#ifndef LINKEDLIST_H +#define LINKEDLIST_H + +#include "../oop.h" +#include "lists.h" + +typedef struct LinkedListElement { + void* data; + struct LinkedListElement* next; +} LinkedListElement_t; + +// #define LinkedList construct(LinkedList) +extern class(LinkedList, Object_class, (interfaces){4 namely {Cloneable_class and List_class and Countable_class and Stack_class}}, true) { + extends(Object_t); + implements(Cloneable); + implements(List); + implements(Countable); + implements(Stack); + void (*destruct)(defclass LinkedList*); + + LinkedListElement_t* first; +} LinkedList_t; + +LinkedList_t* method(LinkedList, construct)(void); +void method(LinkedList, populate)(LinkedList_t*, class_t); + +#endif