Updating queue iterators API
This commit is contained in:
1 parent
66c829701d
commit
7fa41df65a
3 files changed
+519
-130
No files matched your search
+51
-58
@@ -11,8 +11,6 @@ struct queue
|
||||
struct queue_fval *f_val;
|
||||
struct cmc_alloc_node *alloc;
|
||||
struct cmc_callbacks *callbacks;
|
||||
struct queue_iter (*it_start)(struct queue *);
|
||||
struct queue_iter (*it_end)(struct queue *);
|
||||
};
|
||||
struct queue_fval
|
||||
{
|
||||
@@ -53,13 +51,12 @@ struct queue *q_copy_of(struct queue *_queue_);
|
||||
_Bool q_equals(struct queue *_queue1_, struct queue *_queue2_);
|
||||
struct cmc_string q_to_string(struct queue *_queue_);
|
||||
_Bool q_print(struct queue *_queue_, FILE *fptr);
|
||||
struct queue_iter *q_iter_new(struct queue *target);
|
||||
void q_iter_free(struct queue_iter *iter);
|
||||
void q_iter_init(struct queue_iter *iter, struct queue *target);
|
||||
_Bool q_iter_start(struct queue_iter *iter);
|
||||
_Bool q_iter_end(struct queue_iter *iter);
|
||||
void q_iter_to_start(struct queue_iter *iter);
|
||||
void q_iter_to_end(struct queue_iter *iter);
|
||||
struct queue_iter q_iter_start(struct queue *target);
|
||||
struct queue_iter q_iter_end(struct queue *target);
|
||||
_Bool q_iter_at_start(struct queue_iter *iter);
|
||||
_Bool q_iter_at_end(struct queue_iter *iter);
|
||||
_Bool q_iter_to_start(struct queue_iter *iter);
|
||||
_Bool q_iter_to_end(struct queue_iter *iter);
|
||||
_Bool q_iter_next(struct queue_iter *iter);
|
||||
_Bool q_iter_prev(struct queue_iter *iter);
|
||||
_Bool q_iter_advance(struct queue_iter *iter, size_t steps);
|
||||
@@ -68,8 +65,6 @@ _Bool q_iter_go_to(struct queue_iter *iter, size_t index);
|
||||
size_t q_iter_value(struct queue_iter *iter);
|
||||
size_t *q_iter_rvalue(struct queue_iter *iter);
|
||||
size_t q_iter_index(struct queue_iter *iter);
|
||||
static struct queue_iter q_impl_it_start(struct queue *_queue_);
|
||||
static struct queue_iter q_impl_it_end(struct queue *_queue_);
|
||||
struct queue *q_new(size_t capacity, struct queue_fval *f_val)
|
||||
{
|
||||
struct cmc_alloc_node *alloc = &cmc_alloc_node_default;
|
||||
@@ -94,8 +89,6 @@ struct queue *q_new(size_t capacity, struct queue_fval *f_val)
|
||||
_queue_->f_val = f_val;
|
||||
_queue_->alloc = alloc;
|
||||
_queue_->callbacks = ((void *)0);
|
||||
_queue_->it_start = q_impl_it_start;
|
||||
_queue_->it_end = q_impl_it_end;
|
||||
return _queue_;
|
||||
}
|
||||
struct queue *q_new_custom(size_t capacity, struct queue_fval *f_val,
|
||||
@@ -125,8 +118,6 @@ struct queue *q_new_custom(size_t capacity, struct queue_fval *f_val,
|
||||
_queue_->f_val = f_val;
|
||||
_queue_->alloc = alloc;
|
||||
_queue_->callbacks = callbacks;
|
||||
_queue_->it_start = q_impl_it_start;
|
||||
_queue_->it_end = q_impl_it_end;
|
||||
return _queue_;
|
||||
}
|
||||
void q_clear(struct queue *_queue_)
|
||||
@@ -348,55 +339,71 @@ _Bool q_print(struct queue *_queue_, FILE *fptr)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
struct queue_iter *q_iter_new(struct queue *target)
|
||||
struct queue_iter q_iter_start(struct queue *target)
|
||||
{
|
||||
struct queue_iter *iter = target->alloc->malloc(sizeof(struct queue_iter));
|
||||
if (!iter)
|
||||
return ((void *)0);
|
||||
q_iter_init(iter, target);
|
||||
struct queue_iter iter;
|
||||
iter.target = target;
|
||||
iter.cursor = target->front;
|
||||
iter.index = 0;
|
||||
iter.start = 1;
|
||||
iter.end = q_empty(target);
|
||||
return iter;
|
||||
}
|
||||
void q_iter_free(struct queue_iter *iter)
|
||||
struct queue_iter q_iter_end(struct queue *target)
|
||||
{
|
||||
iter->target->alloc->free(iter);
|
||||
struct queue_iter iter;
|
||||
iter.target = target;
|
||||
if (!q_empty(target))
|
||||
{
|
||||
if (iter.target->back == 0)
|
||||
iter.cursor = iter.target->capacity - 1;
|
||||
else
|
||||
iter.cursor = iter.target->back - 1;
|
||||
iter.index = iter.target->count - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
iter.cursor = 0;
|
||||
iter.index = 0;
|
||||
}
|
||||
iter.start = q_empty(target);
|
||||
iter.end = 1;
|
||||
return iter;
|
||||
}
|
||||
void q_iter_init(struct queue_iter *iter, struct queue *target)
|
||||
{
|
||||
iter->target = target;
|
||||
iter->cursor = target->front;
|
||||
iter->index = 0;
|
||||
iter->start = 1;
|
||||
iter->end = q_empty(target);
|
||||
}
|
||||
_Bool q_iter_start(struct queue_iter *iter)
|
||||
_Bool q_iter_at_start(struct queue_iter *iter)
|
||||
{
|
||||
return q_empty(iter->target) || iter->start;
|
||||
}
|
||||
_Bool q_iter_end(struct queue_iter *iter)
|
||||
_Bool q_iter_at_end(struct queue_iter *iter)
|
||||
{
|
||||
return q_empty(iter->target) || iter->end;
|
||||
}
|
||||
void q_iter_to_start(struct queue_iter *iter)
|
||||
_Bool q_iter_to_start(struct queue_iter *iter)
|
||||
{
|
||||
iter->cursor = iter->target->front;
|
||||
iter->index = 0;
|
||||
iter->start = 1;
|
||||
iter->end = q_empty(iter->target);
|
||||
if (!q_empty(iter->target))
|
||||
{
|
||||
iter->cursor = iter->target->front;
|
||||
iter->index = 0;
|
||||
iter->start = 1;
|
||||
iter->end = 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void q_iter_to_end(struct queue_iter *iter)
|
||||
_Bool q_iter_to_end(struct queue_iter *iter)
|
||||
{
|
||||
if (q_empty(iter->target))
|
||||
iter->cursor = 0;
|
||||
else
|
||||
if (!q_empty(iter->target))
|
||||
{
|
||||
if (iter->target->back == 0)
|
||||
iter->cursor = iter->target->capacity - 1;
|
||||
else
|
||||
iter->cursor = iter->target->back - 1;
|
||||
iter->index = iter->target->count - 1;
|
||||
iter->start = 0;
|
||||
iter->end = 1;
|
||||
return 1;
|
||||
}
|
||||
iter->index = iter->target->count - 1;
|
||||
iter->start = q_empty(iter->target);
|
||||
iter->end = 1;
|
||||
return 0;
|
||||
}
|
||||
_Bool q_iter_next(struct queue_iter *iter)
|
||||
{
|
||||
@@ -487,17 +494,3 @@ size_t q_iter_index(struct queue_iter *iter)
|
||||
{
|
||||
return iter->index;
|
||||
}
|
||||
static struct queue_iter q_impl_it_start(struct queue *_queue_)
|
||||
{
|
||||
struct queue_iter iter;
|
||||
q_iter_init(&iter, _queue_);
|
||||
q_iter_to_start(&iter);
|
||||
return iter;
|
||||
}
|
||||
static struct queue_iter q_impl_it_end(struct queue *_queue_)
|
||||
{
|
||||
struct queue_iter iter;
|
||||
q_iter_init(&iter, _queue_);
|
||||
q_iter_to_end(&iter);
|
||||
return iter;
|
||||
}
|
||||
@@ -546,7 +546,413 @@ CMC_CREATE_UNIT(Queue, true, {
|
||||
});
|
||||
|
||||
CMC_CREATE_UNIT(QueueIter, true, {
|
||||
CMC_CREATE_TEST(PFX##_iter_start(), {
|
||||
struct queue *q = q_new(100, q_fval);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, q);
|
||||
|
||||
struct queue_iter it = q_iter_start(q);
|
||||
|
||||
cmc_assert_equals(ptr, q, it.target);
|
||||
cmc_assert_equals(size_t, q->front, it.cursor);
|
||||
cmc_assert_equals(size_t, 0, it.index);
|
||||
cmc_assert_equals(bool, true, it.start);
|
||||
cmc_assert_equals(bool, true, it.end);
|
||||
|
||||
cmc_assert(q_iter_at_start(&it));
|
||||
cmc_assert(q_iter_at_end(&it));
|
||||
|
||||
cmc_assert(q_enqueue(q, 1));
|
||||
cmc_assert(q_enqueue(q, 2));
|
||||
|
||||
it = q_iter_start(q);
|
||||
|
||||
cmc_assert_equals(size_t, 0, it.index);
|
||||
cmc_assert_equals(bool, false, it.end);
|
||||
cmc_assert_equals(size_t, q->front, it.cursor);
|
||||
|
||||
q_free(q);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(PFX##_iter_end(), {
|
||||
struct queue *q = q_new(100, q_fval);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, q);
|
||||
|
||||
struct queue_iter it = q_iter_end(q);
|
||||
|
||||
cmc_assert_equals(ptr, q, it.target);
|
||||
cmc_assert_equals(size_t, q->back, it.cursor);
|
||||
cmc_assert_equals(size_t, 0, it.index);
|
||||
cmc_assert_equals(bool, true, it.start);
|
||||
cmc_assert_equals(bool, true, it.end);
|
||||
|
||||
cmc_assert(q_iter_at_start(&it));
|
||||
cmc_assert(q_iter_at_end(&it));
|
||||
|
||||
cmc_assert(q_enqueue(q, 1));
|
||||
cmc_assert(q_enqueue(q, 2));
|
||||
cmc_assert(q_enqueue(q, 3));
|
||||
|
||||
it = q_iter_end(q);
|
||||
|
||||
cmc_assert_equals(size_t, q->count - 1, it.index);
|
||||
cmc_assert_equals(size_t, q->back - 1, it.cursor);
|
||||
cmc_assert_equals(bool, false, it.start);
|
||||
|
||||
q_free(q);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(PFX##_iter_at_start(), {
|
||||
struct queue *q = q_new(100, q_fval);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, q);
|
||||
|
||||
struct queue_iter it = q_iter_start(q);
|
||||
|
||||
// Empty checks
|
||||
cmc_assert(q_iter_at_start(&it));
|
||||
it = q_iter_end(q);
|
||||
cmc_assert(q_iter_at_start(&it));
|
||||
|
||||
// Non-empty check
|
||||
cmc_assert(q_enqueue(q, 1));
|
||||
it = q_iter_end(q);
|
||||
cmc_assert(!q_iter_at_start(&it));
|
||||
it = q_iter_start(q);
|
||||
cmc_assert(q_iter_at_start(&it));
|
||||
|
||||
q_free(q);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(PFX##_iter_at_end(), {
|
||||
struct queue *q = q_new(100, q_fval);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, q);
|
||||
|
||||
struct queue_iter it = q_iter_start(q);
|
||||
|
||||
// Empty check
|
||||
cmc_assert(q_iter_at_end(&it));
|
||||
it = q_iter_end(q);
|
||||
cmc_assert(q_iter_at_end(&it));
|
||||
|
||||
// Non-empty check
|
||||
cmc_assert(q_enqueue(q, 1));
|
||||
it = q_iter_end(q);
|
||||
cmc_assert(q_iter_at_end(&it));
|
||||
it = q_iter_start(q);
|
||||
cmc_assert(!q_iter_at_end(&it));
|
||||
|
||||
q_free(q);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(PFX##_iter_to_start(), {
|
||||
struct queue *q = q_new(100, q_fval);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, q);
|
||||
|
||||
struct queue_iter it = q_iter_start(q);
|
||||
|
||||
cmc_assert(!q_iter_to_start(&it));
|
||||
|
||||
for (size_t i = 1; i <= 100; i++)
|
||||
q_enqueue(q, i);
|
||||
|
||||
cmc_assert_equals(size_t, 100, q->count);
|
||||
|
||||
it = q_iter_end(q);
|
||||
|
||||
cmc_assert(!q_iter_at_start(&it));
|
||||
cmc_assert(q_iter_at_end(&it));
|
||||
|
||||
cmc_assert_equals(size_t, 100, q_iter_value(&it));
|
||||
|
||||
cmc_assert(q_iter_to_start(&it));
|
||||
|
||||
cmc_assert(q_iter_at_start(&it));
|
||||
cmc_assert(!q_iter_at_end(&it));
|
||||
|
||||
cmc_assert_equals(size_t, 1, q_iter_value(&it));
|
||||
|
||||
q_free(q);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(PFX##_iter_to_end(), {
|
||||
struct queue *q = q_new(100, q_fval);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, q);
|
||||
|
||||
struct queue_iter it = q_iter_end(q);
|
||||
|
||||
cmc_assert(!q_iter_to_end(&it));
|
||||
|
||||
for (size_t i = 1; i <= 100; i++)
|
||||
q_enqueue(q, i);
|
||||
|
||||
it = q_iter_start(q);
|
||||
|
||||
cmc_assert(q_iter_at_start(&it));
|
||||
cmc_assert(!q_iter_at_end(&it));
|
||||
|
||||
cmc_assert_equals(size_t, 1, q_iter_value(&it));
|
||||
|
||||
cmc_assert(q_iter_to_end(&it));
|
||||
|
||||
cmc_assert(!q_iter_at_start(&it));
|
||||
cmc_assert(q_iter_at_end(&it));
|
||||
|
||||
cmc_assert_equals(size_t, 100, q_iter_value(&it));
|
||||
|
||||
q_free(q);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(PFX##_iter_next(), {
|
||||
struct queue *q = q_new(100, q_fval);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, q);
|
||||
|
||||
struct queue_iter it = q_iter_start(q);
|
||||
|
||||
cmc_assert(!q_iter_next(&it));
|
||||
|
||||
for (size_t i = 1; i <= 1000; i++)
|
||||
q_enqueue(q, i);
|
||||
|
||||
size_t sum = 0;
|
||||
for (it = q_iter_start(q); !q_iter_at_end(&it); q_iter_next(&it))
|
||||
{
|
||||
sum += q_iter_value(&it);
|
||||
}
|
||||
|
||||
cmc_assert_equals(size_t, 500500, sum);
|
||||
|
||||
sum = 0;
|
||||
|
||||
q_iter_to_start(&it);
|
||||
do
|
||||
{
|
||||
sum += q_iter_value(&it);
|
||||
} while (q_iter_next(&it));
|
||||
|
||||
cmc_assert_equals(size_t, 500500, sum);
|
||||
|
||||
q_free(q);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(PFX##_iter_prev(), {
|
||||
struct queue *q = q_new(100, q_fval);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, q);
|
||||
|
||||
struct queue_iter it = q_iter_end(q);
|
||||
|
||||
cmc_assert(!q_iter_prev(&it));
|
||||
|
||||
for (size_t i = 1; i <= 1000; i++)
|
||||
q_enqueue(q, i);
|
||||
|
||||
size_t sum = 0;
|
||||
for (it = q_iter_end(q); !q_iter_at_start(&it); q_iter_prev(&it))
|
||||
{
|
||||
sum += q_iter_value(&it);
|
||||
}
|
||||
|
||||
cmc_assert_equals(size_t, 500500, sum);
|
||||
|
||||
sum = 0;
|
||||
|
||||
q_iter_to_end(&it);
|
||||
do
|
||||
{
|
||||
sum += q_iter_value(&it);
|
||||
} while (q_iter_prev(&it));
|
||||
|
||||
cmc_assert_equals(size_t, 500500, sum);
|
||||
|
||||
q_free(q);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(PFX##_iter_advance(), {
|
||||
struct queue *q = q_new(100, q_fval);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, q);
|
||||
|
||||
struct queue_iter it = q_iter_start(q);
|
||||
|
||||
cmc_assert(!q_iter_advance(&it, 1));
|
||||
|
||||
for (size_t i = 0; i <= 1000; i++)
|
||||
q_enqueue(q, i);
|
||||
|
||||
it = q_iter_start(q);
|
||||
|
||||
cmc_assert(!q_iter_advance(&it, 0));
|
||||
cmc_assert(!q_iter_advance(&it, q->count));
|
||||
|
||||
size_t sum = 0;
|
||||
for (it = q_iter_start(q);;)
|
||||
{
|
||||
sum += q_iter_value(&it);
|
||||
|
||||
if (!q_iter_advance(&it, 2))
|
||||
break;
|
||||
}
|
||||
|
||||
cmc_assert_equals(size_t, 250500, sum);
|
||||
|
||||
q_iter_to_start(&it);
|
||||
cmc_assert(q_iter_advance(&it, q->count - 1));
|
||||
|
||||
q_free(q);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(PFX##_iter_rewind(), {
|
||||
struct queue *q = q_new(100, q_fval);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, q);
|
||||
|
||||
struct queue_iter it = q_iter_end(q);
|
||||
|
||||
cmc_assert(!q_iter_rewind(&it, 1));
|
||||
|
||||
for (size_t i = 0; i <= 1000; i++)
|
||||
q_enqueue(q, i);
|
||||
|
||||
it = q_iter_end(q);
|
||||
|
||||
cmc_assert(!q_iter_rewind(&it, 0));
|
||||
cmc_assert(!q_iter_rewind(&it, q->count));
|
||||
|
||||
size_t sum = 0;
|
||||
for (it = q_iter_end(q);;)
|
||||
{
|
||||
sum += q_iter_value(&it);
|
||||
|
||||
if (!q_iter_rewind(&it, 2))
|
||||
break;
|
||||
}
|
||||
|
||||
cmc_assert_equals(size_t, 250500, sum);
|
||||
|
||||
q_iter_to_end(&it);
|
||||
cmc_assert(q_iter_rewind(&it, q->count - 1));
|
||||
|
||||
q_free(q);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(PFX##_iter_go_to(), {
|
||||
struct queue *q = q_new(100, q_fval);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, q);
|
||||
|
||||
struct queue_iter it = q_iter_end(q);
|
||||
cmc_assert(!q_iter_go_to(&it, 0));
|
||||
|
||||
it = q_iter_start(q);
|
||||
cmc_assert(!q_iter_go_to(&it, 0));
|
||||
|
||||
for (size_t i = 0; i <= 1000; i++)
|
||||
q_enqueue(q, i);
|
||||
|
||||
it = q_iter_start(q);
|
||||
|
||||
size_t sum = 0;
|
||||
for (size_t i = 0; i < 1001; i++)
|
||||
{
|
||||
q_iter_go_to(&it, i);
|
||||
|
||||
sum += q_iter_value(&it);
|
||||
}
|
||||
|
||||
cmc_assert_equals(size_t, 500500, sum);
|
||||
|
||||
sum = 0;
|
||||
for (size_t i = 1001; i > 0; i--)
|
||||
{
|
||||
cmc_assert(q_iter_go_to(&it, i - 1));
|
||||
|
||||
sum += q_iter_value(&it);
|
||||
}
|
||||
|
||||
cmc_assert_equals(size_t, 500500, sum);
|
||||
|
||||
sum = 0;
|
||||
for (size_t i = 0; i < 1001; i += 100)
|
||||
{
|
||||
cmc_assert(q_iter_go_to(&it, i));
|
||||
cmc_assert_equals(size_t, i, q_iter_index(&it));
|
||||
|
||||
sum += q_iter_value(&it);
|
||||
}
|
||||
|
||||
cmc_assert_equals(size_t, 5500, sum);
|
||||
|
||||
q_free(q);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(PFX##_iter_value(), {
|
||||
struct queue *q = q_new(100, q_fval);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, q);
|
||||
|
||||
struct queue_iter it = q_iter_end(q);
|
||||
|
||||
cmc_assert_equals(size_t, (size_t){ 0 }, q_iter_value(&it));
|
||||
|
||||
cmc_assert(q_enqueue(q, 10));
|
||||
|
||||
it = q_iter_start(q);
|
||||
|
||||
cmc_assert_equals(size_t, 10, q_iter_value(&it));
|
||||
|
||||
q_free(q);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(PFX##_iter_rvalue(), {
|
||||
struct queue *q = q_new(100, q_fval);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, q);
|
||||
|
||||
struct queue_iter it = q_iter_end(q);
|
||||
|
||||
cmc_assert_equals(ptr, NULL, q_iter_rvalue(&it));
|
||||
|
||||
cmc_assert(q_enqueue(q, 10));
|
||||
|
||||
it = q_iter_start(q);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, q_iter_rvalue(&it));
|
||||
cmc_assert_equals(size_t, 10, *q_iter_rvalue(&it));
|
||||
|
||||
q_free(q);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(PFX##_iter_index(), {
|
||||
struct queue *q = q_new(100, q_fval);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, q);
|
||||
|
||||
for (size_t i = 0; i <= 1000; i++)
|
||||
q_enqueue(q, i);
|
||||
|
||||
struct queue_iter it = q_iter_start(q);
|
||||
|
||||
for (size_t i = 0; i < 1001; i++)
|
||||
{
|
||||
cmc_assert_equals(size_t, i, q_iter_index(&it));
|
||||
q_iter_next(&it);
|
||||
}
|
||||
|
||||
it = q_iter_end(q);
|
||||
for (size_t i = 1001; i > 0; i--)
|
||||
{
|
||||
cmc_assert_equals(size_t, i - 1, q_iter_index(&it));
|
||||
q_iter_prev(&it);
|
||||
}
|
||||
|
||||
q_free(q);
|
||||
});
|
||||
});
|
||||
|
||||
#ifdef CMC_TEST_MAIN
|
||||
|
||||
Reference in new issue
Block a user