diff --git a/core/include/blue/core/queue.h b/core/include/blue/core/queue.h index 1d25c99..441a27a 100644 --- a/core/include/blue/core/queue.h +++ b/core/include/blue/core/queue.h @@ -1,22 +1,24 @@ -#ifndef BLUELIB_CORE_QUEUE_H_ -#define BLUELIB_CORE_QUEUE_H_ +#ifndef BLUE_CORE_QUEUE_H_ +#define BLUE_CORE_QUEUE_H_ #include +#include #include #include #include -#ifdef __cplusplus -extern "C" { -#endif +B_DECLS_BEGIN; + +#define B_TYPE_QUEUE_ITERATOR (b_queue_iterator_get_type()) + +B_DECLARE_TYPE(b_queue_iterator); + +B_TYPE_CLASS_DECLARATION_BEGIN(b_queue_iterator) +B_TYPE_CLASS_DECLARATION_END(b_queue_iterator) #define B_QUEUE_INIT ((b_queue) {.q_first = NULL, .q_last = NULL}) #define B_QUEUE_ENTRY_INIT ((b_queue_entry) {.qe_next = NULL, .qe_prev = NULL}) -#define b_queue_foreach(it, q) \ - for (int z__b_unique_name() = b_queue_iterator_begin(q, it); \ - (it)->entry != NULL; b_queue_iterator_next(it)) - typedef struct b_queue_entry { struct b_queue_entry *qe_next; struct b_queue_entry *qe_prev; @@ -27,13 +29,6 @@ typedef struct b_queue { b_queue_entry *q_last; } b_queue; -typedef struct b_queue_iterator { - b_iterator _base; - size_t i; - b_queue_entry *entry; - b_queue *_q; -} b_queue_iterator; - static inline void b_queue_init(b_queue *q) { memset(q, 0x00, sizeof *q); @@ -60,6 +55,8 @@ static inline b_queue_entry *b_queue_prev(const b_queue_entry *entry) return entry->qe_prev; } +BLUE_API b_type b_queue_iterator_get_type(void); + BLUE_API size_t b_queue_length(const b_queue *q); BLUE_API void b_queue_insert_before( @@ -76,13 +73,9 @@ BLUE_API b_queue_entry *b_queue_pop_back(b_queue *q); BLUE_API void b_queue_delete(b_queue *q, b_queue_entry *entry); BLUE_API void b_queue_delete_all(b_queue *q); -BLUE_API int b_queue_iterator_begin(const b_queue *q, b_queue_iterator *it); -BLUE_API bool b_queue_iterator_next(b_queue_iterator *it); -BLUE_API b_status b_queue_iterator_erase(b_queue_iterator *it); -BLUE_API bool b_queue_iterator_is_valid(const b_queue_iterator *it); +BLUE_API b_iterator *b_queue_begin(b_queue *q); +BLUE_API b_iterator *b_queue_cbegin(const b_queue *q); -#ifdef __cplusplus -} -#endif +B_DECLS_END; #endif diff --git a/core/queue.c b/core/queue.c index 89d6aff..048c134 100644 --- a/core/queue.c +++ b/core/queue.c @@ -1,5 +1,11 @@ #include +struct b_queue_iterator_p { + size_t i; + b_queue_entry *entry; + b_queue *_q; +}; + size_t b_queue_length(const struct b_queue *q) { size_t i = 0; @@ -133,52 +139,43 @@ void b_queue_delete_all(struct b_queue *q) q->q_first = q->q_last = NULL; } -static bool queue_iterator_next(struct b_iterator *it) +b_iterator *b_queue_begin(struct b_queue *q) { - return b_queue_iterator_next((struct b_queue_iterator *)it); -} + b_queue_iterator *it_obj = b_object_create(B_TYPE_QUEUE_ITERATOR); + struct b_queue_iterator_p *it + = b_object_get_private(it_obj, B_TYPE_QUEUE_ITERATOR); -static b_status queue_iterator_erase(struct b_iterator *it) -{ - return b_queue_iterator_erase((struct b_queue_iterator *)it); -} - -static bool queue_iterator_is_valid(const struct b_iterator *it) -{ - return b_queue_iterator_is_valid((const struct b_queue_iterator *)it); -} - -static const b_iterator_ops queue_iterator_ops = { - .it_next = queue_iterator_next, - .it_erase = queue_iterator_erase, - .it_close = NULL, - .it_is_valid = queue_iterator_is_valid, -}; - -int b_queue_iterator_begin(const struct b_queue *q, struct b_queue_iterator *it) -{ it->_q = (struct b_queue *)q; - it->_base.it_ops = &queue_iterator_ops; it->entry = q->q_first; it->i = 0; - return 0; + if (!it->entry) { + b_iterator_set_status(it_obj, B_ERR_NO_DATA); + } + + return it_obj; } -bool b_queue_iterator_next(struct b_queue_iterator *it) +static enum b_status iterator_move_next(const b_iterator *obj) { + struct b_queue_iterator_p *it + = b_object_get_private(obj, B_TYPE_QUEUE_ITERATOR); + if (!it->entry) { - return false; + return B_ERR_NO_DATA; } it->entry = it->entry->qe_next; it->i++; - return it->entry != NULL; + return (it->entry != NULL) ? B_SUCCESS : B_ERR_NO_DATA; } -b_status b_queue_iterator_erase(struct b_queue_iterator *it) +static enum b_status iterator_erase(b_iterator *obj) { + struct b_queue_iterator_p *it + = b_object_get_private(obj, B_TYPE_QUEUE_ITERATOR); + if (!it->entry) { return B_ERR_OUT_OF_BOUNDS; } @@ -190,7 +187,38 @@ b_status b_queue_iterator_erase(struct b_queue_iterator *it) return B_SUCCESS; } -bool b_queue_iterator_is_valid(const struct b_queue_iterator *it) +static b_iterator_value iterator_get_value(b_iterator *obj) { - return it->entry != NULL; + struct b_queue_iterator_p *it + = b_object_get_private(obj, B_TYPE_QUEUE_ITERATOR); + + return B_ITERATOR_VALUE_PTR(it->entry); } + +static const b_iterator_value iterator_get_cvalue(const b_iterator *obj) +{ + struct b_queue_iterator_p *it + = b_object_get_private(obj, B_TYPE_QUEUE_ITERATOR); + + return B_ITERATOR_VALUE_CPTR(it->entry); +} + +B_TYPE_CLASS_DEFINITION_BEGIN(b_queue_iterator) + B_TYPE_CLASS_INTERFACE_BEGIN(b_object, B_TYPE_OBJECT) + B_INTERFACE_ENTRY(to_string) = NULL; + B_TYPE_CLASS_INTERFACE_END(b_object, B_TYPE_OBJECT) + + B_TYPE_CLASS_INTERFACE_BEGIN(b_iterator, B_TYPE_ITERATOR) + B_INTERFACE_ENTRY(it_move_next) = iterator_move_next; + B_INTERFACE_ENTRY(it_erase) = iterator_erase; + B_INTERFACE_ENTRY(it_get_value) = iterator_get_value; + B_INTERFACE_ENTRY(it_get_cvalue) = iterator_get_cvalue; + B_TYPE_CLASS_INTERFACE_END(b_iterator, B_TYPE_ITERATOR) +B_TYPE_CLASS_DEFINITION_END(b_queue_iterator) + +B_TYPE_DEFINITION_BEGIN(b_queue_iterator) + B_TYPE_ID(0x560dc263, 0xff98, 0x4812, 0x9b29, 0xa1218bd70881); + B_TYPE_EXTENDS(B_TYPE_ITERATOR); + B_TYPE_CLASS(b_queue_iterator_class); + B_TYPE_INSTANCE_PRIVATE(struct b_queue_iterator_p); +B_TYPE_DEFINITION_END(b_queue_iterator)