diff --git a/core/include/blue/core/iterator.h b/core/include/blue/core/iterator.h index 16ce7a8..f294465 100644 --- a/core/include/blue/core/iterator.h +++ b/core/include/blue/core/iterator.h @@ -9,9 +9,26 @@ B_DECLS_BEGIN; #define b_foreach(type, var, iterator) \ - for (type var = (type)b_iterator_value(iterator).v_int; var != NULL; \ - b_iterator_next(iterator), \ - var = (type)b_iterator_value(iterator).v_int) + for (type var = (type)b_iterator_get_value(iterator).v_int; \ + B_OK(b_iterator_get_status(iterator)); \ + b_iterator_move_next(iterator), \ + var = (type)b_iterator_get_value(iterator).v_int) +#define b_foreach_ptr(type, var, iterator) \ + for (type *var = (type *)b_iterator_get_value(iterator).v_ptr; \ + B_OK(b_iterator_get_status(iterator)); \ + b_iterator_move_next(iterator), \ + var = (type *)b_iterator_get_value(iterator).v_ptr) +#define b_foreach_c(type, var, iterator) \ + for (type var = (type)b_iterator_get_cvalue(iterator).v_int; \ + B_OK(b_iterator_get_status(iterator)); \ + b_iterator_move_next(iterator), \ + var = (type)b_iterator_get_cvalue(iterator).v_int) +#define b_foreach_cptr(type, var, iterator) \ + for (const type *var \ + = (const type *)b_iterator_get_cvalue(iterator).v_cptr; \ + B_OK(b_iterator_get_status(iterator)); \ + b_iterator_move_next(iterator), \ + var = (const type *)b_iterator_get_cvalue(iterator).v_cptr) #define B_ITERATOR_VALUE_INT(v) ((b_iterator_value) {.v_int = (v)}) #define B_ITERATOR_VALUE_PTR(v) ((b_iterator_value) {.v_ptr = (v)}) @@ -28,7 +45,8 @@ typedef union b_iterator_value { const void *v_cptr; } b_iterator_value; -B_DECLARE_TYPE(b_iterator); +__B_DECLARE_TYPE(b_iterator); + B_DECLARE_TYPE(b_iterable); B_TYPE_CLASS_DECLARATION_BEGIN(b_iterator) @@ -46,13 +64,22 @@ B_TYPE_CLASS_DECLARATION_END(b_iterable) BLUE_API b_type b_iterator_get_type(void); BLUE_API b_type b_iterable_get_type(void); +static inline const b_iterator *b_iterator_ref(const b_iterator *p) +{ + return b_object_ref((b_object *)p); +} +static inline void b_iterator_unref(const b_iterator *p) +{ + b_object_unref((b_object *)p); +} + BLUE_API b_iterator *b_iterator_begin(b_iterable *it); BLUE_API const b_iterator *b_iterator_cbegin(const b_iterable *it); BLUE_API b_status b_iterator_get_status(const b_iterator *it); BLUE_API b_status b_iterator_set_status(const b_iterator *it, b_status status); -BLUE_API b_status b_iterator_next(const b_iterator *it); +BLUE_API b_status b_iterator_move_next(const b_iterator *it); BLUE_API b_iterator_value b_iterator_get_value(b_iterator *it); BLUE_API const b_iterator_value b_iterator_get_cvalue(const b_iterator *it); BLUE_API b_status b_iterator_erase(b_iterator *it); diff --git a/core/include/blue/core/macros.h b/core/include/blue/core/macros.h index 380836c..5f426d0 100644 --- a/core/include/blue/core/macros.h +++ b/core/include/blue/core/macros.h @@ -92,9 +92,12 @@ /* Type declaration macros (for use in .h header file) */ -#define B_DECLARE_TYPE(name) \ +#define __B_DECLARE_TYPE(name) \ typedef B_TYPE_FWDREF(name) name; \ - typedef struct _##name##_class name##_class; \ + typedef struct _##name##_class name##_class; + +#define B_DECLARE_TYPE(name) \ + __B_DECLARE_TYPE(name); \ static inline name *name##_ref(name *p) \ { \ return b_object_ref(p); \ diff --git a/core/iterator.c b/core/iterator.c index a365a7c..d311fe8 100644 --- a/core/iterator.c +++ b/core/iterator.c @@ -41,10 +41,19 @@ enum b_status b_iterator_set_status(const b_iterator *it, b_status status) B_CLASS_DISPATCH_STATIC(B_TYPE_ITERATOR, iterator_set_status, it, status); } -b_status b_iterator_move_next(b_iterator *it) +enum b_status b_iterator_move_next(const b_iterator *it) { - B_CLASS_DISPATCH_VIRTUAL_0( - b_iterator, B_TYPE_ITERATOR, B_ERR_NOT_SUPPORTED, it_move_next, it); + enum b_status status = B_ERR_NOT_SUPPORTED; + + b_iterator_class *iface = b_object_get_interface(it, B_TYPE_ITERATOR); + if (iface && iface->it_move_next) { + status = iface->it_move_next(it); + } + + struct b_iterator_p *p = b_object_get_private(it, B_TYPE_ITERATOR); + p->it_status = status; + + return status; } b_iterator_value b_iterator_get_value(b_iterator *it) @@ -63,8 +72,17 @@ const b_iterator_value b_iterator_get_cvalue(const b_iterator *it) b_status b_iterator_erase(b_iterator *it) { - B_CLASS_DISPATCH_VIRTUAL_0( - b_iterator, B_TYPE_ITERATOR, B_ERR_NOT_SUPPORTED, it_erase, it); + enum b_status status = B_ERR_NOT_SUPPORTED; + + b_iterator_class *iface = b_object_get_interface(it, B_TYPE_ITERATOR); + if (iface && iface->it_erase) { + status = iface->it_erase(it); + } + + struct b_iterator_p *p = b_object_get_private(it, B_TYPE_ITERATOR); + p->it_status = status; + + return status; } /*** CLASS DEFINITION *********************************************************/