From b7e4a1de23826462a4bd014736590f5efddd9aa6 Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Tue, 1 Dec 2015 10:59:01 -0500 Subject: [PATCH] core/containers/queue: Add _q_remove_it() function Signed-off-by: Anna Schumaker --- core/containers/queue.c | 15 +++++++++++++++ include/core/containers/queue.h | 10 ++++++++++ tests/core/containers/queue.c | 25 +++++++++++++++++++++++++ 3 files changed, 50 insertions(+) create mode 100644 core/containers/queue.c diff --git a/core/containers/queue.c b/core/containers/queue.c new file mode 100644 index 00000000..4d4c1b2f --- /dev/null +++ b/core/containers/queue.c @@ -0,0 +1,15 @@ +/* + * Copyright 2015 (c) Anna Schumaker. + */ + +#include + +gpointer _q_remove_it(struct _queue *queue, struct _q_iter *it) +{ + gpointer ret = _q_iter_val(it); + GList *link = it->it_iter; + + _q_iter_prev(it); + g_queue_delete_link(&queue->_queue, link); + return ret; +} diff --git a/include/core/containers/queue.h b/include/core/containers/queue.h index 766b4bf4..65b5a129 100644 --- a/include/core/containers/queue.h +++ b/include/core/containers/queue.h @@ -30,6 +30,13 @@ static inline void _q_iter_next(struct _q_iter *it) it->it_pos++; } +/* Called to rewind a queue iterator by one step. */ +static inline void _q_iter_prev(struct _q_iter *it) +{ + it->it_iter = g_list_previous(it->it_iter); + it->it_pos--; +} + /* Called to set a queue iterator to a specific position. */ static inline void _q_iter_set(struct _queue *queue, struct _q_iter *it, unsigned int pos) @@ -79,4 +86,7 @@ static inline guint _q_add_tail(struct _queue *queue, gpointer data) return _q_size(queue) - 1; } +/* Called to remove an item by iterator. */ +gpointer _q_remove_it(struct _queue *, struct _q_iter *); + #endif /* OCARINA_CORE_CONTAINERS_QUEUE_H */ diff --git a/tests/core/containers/queue.c b/tests/core/containers/queue.c index 72aa00b0..bf1a9ec1 100644 --- a/tests/core/containers/queue.c +++ b/tests/core/containers/queue.c @@ -4,6 +4,8 @@ #include #include +static unsigned int data_val = 0; + static inline unsigned int test_q_first(struct _queue *queue) { return GPOINTER_TO_INT(g_queue_peek_head(&queue->_queue)); @@ -19,6 +21,12 @@ static inline unsigned int test_q_iter_val(struct _q_iter *it) return GPOINTER_TO_INT(_q_iter_val(it)); } +static int test_sort_int(gconstpointer a, gconstpointer b, gpointer data) +{ + data_val = GPOINTER_TO_INT(data); + return GPOINTER_TO_INT(a) - GPOINTER_TO_INT(b); +} + static void test_stress(unsigned int N) { struct _queue queue = _Q_INIT(); @@ -70,6 +78,23 @@ static void test_stress(unsigned int N) } i++; } test_loop_passed(); + + /* _q_remove_it() (last N items) */ + _q_iter_set(&queue, &it, 2 * N - 1); + for (i = 0; i < N; i++) { + test_loop_not_equal((void *)it.it_iter, NULL, i); + test_loop_equal(it.it_pos, (2 * N) - (i + 1), i); + test_loop_equal(GPOINTER_TO_INT(_q_remove_it(&queue, &it)), N - (i + 1), i); + } test_loop_passed(); + test_equal(_q_size(&queue), N); + + /* _q_remove_it() (remaining items) */ + for (i = 0; i < N; i++) { + _q_iter_set(&queue, &it, 0); + test_loop_not_equal((void *)it.it_iter, NULL, i); + test_loop_equal(it.it_pos, 0, i); + test_loop_equal(GPOINTER_TO_INT(_q_remove_it(&queue, &it)), N - (i + 1), i); + } test_loop_passed(); } static void test_basics() { test_stress(10); }