diff --git a/include/Makefile.am b/include/Makefile.am
index e4a0206..094f5ab 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -7,4 +7,5 @@ nobase_include_HEADERS = trdata.h \
tr/tree.h \
tr/dynarray.h \
tr/heap.h \
- tr/interface/hashable.h
+ tr/interface/hashable.h \
+ tr/interface/iterable.h
diff --git a/include/tr/interface/iterable.h b/include/tr/interface/iterable.h
new file mode 100644
index 0000000..e74d5ca
--- /dev/null
+++ b/include/tr/interface/iterable.h
@@ -0,0 +1,52 @@
+/**
+ * \file
+ *
+ * \author Georg Hopp
+ *
+ * \copyright
+ * Copyright © 2014 Georg Hopp
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef __TR_INTERFACE_ITERABLE_H__
+#define __TR_INTERFACE_ITERABLE_H__
+
+#include "trbase.h"
+
+typedef void * (* fptr_TR_iterableCurrent)(void *);
+typedef void (* fptr_TR_iterableNext)(void *);
+typedef void (* fptr_TR_iterableRewind)(void *);
+typedef int (* fptr_TR_iterableValid)(void *);
+
+TR_INTERFACE(TR_Iterable) {
+ TR_IFID;
+ fptr_TR_iterableCurrent current;
+ fptr_TR_iterableNext next;
+ fptr_TR_iterableRewind rewind;
+ fptr_TR_iterableValid valid;
+};
+
+#define TR_iterableForeach(this) \
+ TR_iterableRewind((this)); \
+ for (; TR_iterableValid((this)); TR_iterableNext((this)))
+
+extern void * TR_iterableCurrent(void *);
+extern void TR_iterableNext(void *);
+extern void TR_iterableRewind(void *);
+extern int TR_iterableValid(void *);
+
+#endif // __TR_INTERFACE_ITERABLE_H__
+
+// vim: set ts=4 sw=4:
diff --git a/include/tr/list.h b/include/tr/list.h
index faa1ecc..c2b6a52 100644
--- a/include/tr/list.h
+++ b/include/tr/list.h
@@ -37,6 +37,9 @@ TR_CLASS(TR_List) {
size_t end;
void ** data;
int free_msgs;
+
+ // for iterable interface
+ size_t current;
};
TR_INSTANCE_INIT(TR_List);
TR_CLASSVARS_DECL(TR_List) {};
diff --git a/include/trdata.h b/include/trdata.h
index d434332..d489a4f 100644
--- a/include/trdata.h
+++ b/include/trdata.h
@@ -10,6 +10,7 @@
#include "tr/dynarray.h"
#include "tr/heap.h"
#include "tr/interface/hashable.h"
+#include "tr/interface/iterable.h"
#endif // __TR_DATA_H__
diff --git a/src/Makefile.am b/src/Makefile.am
index 4626ec9..523f0c9 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -12,9 +12,11 @@ TRDATALIBS = cbuf/libcbuf.la \
dynarray/libdynarray.la \
heap/libheap.la
+ITERABLE = interface/iterable.c
+
lib_LTLIBRARIES = libtrdata.la
-libtrdata_la_SOURCES =
+libtrdata_la_SOURCES = $(ITERABLE)
libtrdata_la_CFLAGS = $(AM_CFLAGS)
libtrdata_la_LIBADD = $(TRDATALIBS)
libtrdata_la_LDFLAGS = -version-info 0:0:0 $(AM_LDFLAGS)
diff --git a/src/interface/iterable.c b/src/interface/iterable.c
new file mode 100644
index 0000000..1cfd086
--- /dev/null
+++ b/src/interface/iterable.c
@@ -0,0 +1,56 @@
+/**
+ * \file
+ *
+ * \author Georg Hopp
+ *
+ * \copyright
+ * Copyright © 2012 Georg Hopp
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "trbase.h"
+#include "tr/interface/iterable.h"
+
+TR_CREATE_INTERFACE(TR_Iterable, 4);
+
+void *
+TR_iterableCurrent(void * iterable)
+{
+ void * ret;
+ TR_RETCALL(iterable, TR_Iterable, current, ret);
+ return ret;
+}
+
+void
+TR_iterableNext(void * iterable)
+{
+ TR_CALL(iterable, TR_Iterable, next);
+}
+
+void
+TR_iterableRewind(void * iterable)
+{
+ TR_CALL(iterable, TR_Iterable, rewind);
+}
+
+int
+TR_iterableValid(void * iterable)
+{
+ int ret;
+ TR_RETCALL(iterable, TR_Iterable, valid, ret);
+ return ret;
+}
+
+// vim: set ts=4 sw=4:
diff --git a/src/list/list.c b/src/list/list.c
index 5a2cbcf..b801f76 100644
--- a/src/list/list.c
+++ b/src/list/list.c
@@ -24,6 +24,7 @@
#include "trbase.h"
#include "tr/list.h"
+#include "tr/interface/iterable.h"
static
int
@@ -33,7 +34,7 @@ listCtor(void * _this, va_list * params)
this->data = (void **)TR_malloc(32 * sizeof(void *));
this->size = TR_getUsableSize(this->data) / sizeof(void *);
- this->start = this->end = 0;
+ this->start = this->end = this->current = 0;
this->free_msgs = 1;
return 0;
@@ -60,7 +61,40 @@ listDtor(void * _this)
TR_MEM_FREE(this->data);
}
+static
+void *
+listCurrent(void * _this)
+{
+ TR_List this = _this;
+ return this->data[this->current];
+}
+
+static
+void
+listNext(void * _this)
+{
+ TR_List this = _this;
+ this->current = this->current + 1 == this->size ? 0 : this->current + 1;
+}
+
+static
+void
+listRewind(void * _this)
+{
+ TR_List this = _this;
+ this->current = this->start;
+}
+
+static
+int
+listValid(void * _this)
+{
+ TR_List this = _this;
+ return this->current != this->end;
+}
+
TR_INIT_IFACE(TR_Class, listCtor, listDtor, NULL);
-TR_CREATE_CLASS(TR_List, NULL, NULL, TR_IF(TR_Class));
+TR_INIT_IFACE(TR_Iterable, listCurrent, listNext, listRewind, listValid);
+TR_CREATE_CLASS(TR_List, NULL, NULL, TR_IF(TR_Class), TR_IF(TR_Iterable));
// vim: set ts=4 sw=4: