array_t *array;
/** current index +1, initialized at 0 */
int idx;
+ /** current element for element based arrays */
+ void *cur;
} array_enumerator_t;
METHOD(enumerator_t, enumerate, bool,
get_size(this->array, this->idx + this->array->head);
if (this->array->esize)
{
- /* for element based arrays we return a pointer to the element */
- *out = pos;
+ /* for element based arrays we copy the element and return a pointer to
+ * the copy. this is required in case remove_at is called, which might
+ * overwrite the current element */
+ memcpy(this->cur, pos, this->array->esize);
+ *out = this->cur;
}
else
{
return TRUE;
}
+METHOD(enumerator_t, enumerator_destroy, void,
+ array_enumerator_t *this)
+{
+ free(this->cur);
+ free(this);
+}
+
enumerator_t* array_create_enumerator(array_t *array)
{
array_enumerator_t *enumerator;
INIT(enumerator,
.public = {
.enumerate = (void*)_enumerate,
- .destroy = (void*)free,
+ .destroy = _enumerator_destroy,
},
.array = array,
);
+ if (array->esize)
+ {
+ enumerator->cur = malloc(array->esize);
+ }
return &enumerator->public;
}
}
END_TEST
+static int remove_at_data[] = {0, 1, 2, 3, 4};
+
+START_TEST(test_remove_at_obj)
+{
+ array_t *array;
+ int i, *x;
+ enumerator_t *enumerator;
+
+ array = array_create(sizeof(remove_at_data[0]), 0);
+
+ array_insert(array, ARRAY_TAIL, &remove_at_data[0]);
+ array_insert(array, ARRAY_TAIL, &remove_at_data[1]);
+ array_insert(array, ARRAY_TAIL, &remove_at_data[2]);
+ array_insert(array, ARRAY_TAIL, &remove_at_data[3]);
+ array_insert(array, ARRAY_TAIL, &remove_at_data[4]);
+
+ i = 0;
+ enumerator = array_create_enumerator(array);
+ while (enumerator->enumerate(enumerator, &x))
+ {
+ if (i >= _i)
+ {
+ ck_assert_int_eq(*x, remove_at_data[i]);
+ array_remove_at(array, enumerator);
+ ck_assert_int_eq(array_count(array),
+ countof(remove_at_data) - i - 1 + _i);
+ ck_assert_int_eq(*x, remove_at_data[i]);
+ }
+ i++;
+ }
+ enumerator->destroy(enumerator);
+ ck_assert_int_eq(array_count(array), _i);
+
+ array_destroy(array);
+}
+END_TEST
+
+START_TEST(test_remove_at_ptr)
+{
+ array_t *array;
+ int i, *x;
+ enumerator_t *enumerator;
+
+ array = array_create(0, 0);
+
+ array_insert(array, ARRAY_TAIL, &remove_at_data[0]);
+ array_insert(array, ARRAY_TAIL, &remove_at_data[1]);
+ array_insert(array, ARRAY_TAIL, &remove_at_data[2]);
+ array_insert(array, ARRAY_TAIL, &remove_at_data[3]);
+ array_insert(array, ARRAY_TAIL, &remove_at_data[4]);
+
+ i = 0;
+ enumerator = array_create_enumerator(array);
+ while (enumerator->enumerate(enumerator, &x))
+ {
+ if (i >= _i)
+ {
+ ck_assert(x == &remove_at_data[i]);
+ array_remove_at(array, enumerator);
+ ck_assert_int_eq(array_count(array),
+ countof(remove_at_data) - i - 1 + _i);
+ ck_assert(x == &remove_at_data[i]);
+ }
+ i++;
+ }
+ enumerator->destroy(enumerator);
+ ck_assert_int_eq(array_count(array), _i);
+
+ array_destroy(array);
+}
+END_TEST
+
static int comp_obj(const void *a, const void *b, void *arg)
{
ck_assert_str_eq(arg, "arg");
tcase_add_test(tc, test_enumerate);
suite_add_tcase(s, tc);
+ tc = tcase_create("remove_at");
+ tcase_add_loop_test(tc, test_remove_at_obj, 0, countof(remove_at_data));
+ tcase_add_loop_test(tc, test_remove_at_ptr, 0, countof(remove_at_data));
+ suite_add_tcase(s, tc);
+
tc = tcase_create("sort");
tcase_add_test(tc, test_sort_obj);
tcase_add_test(tc, test_sort_ptr);