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: