Compare commits

..

6 Commits

2 changed files with 49 additions and 231 deletions

View File

@ -189,6 +189,30 @@ static void list_print(struct _list* self)
}
}
static int list_index_exchange(struct _list* self, int index)
{
assert(self != NULL);
int size = (int)self->size(self);
if (index < 0)
{
index += size;
if (index < 0)
{
index = 0;
}
}
else
{
if (index > size)
{
index = size;
}
}
return index;
}
/**
* @brief list slice
* if index < 0, from the end of list. for example:
@ -206,10 +230,13 @@ static void list_print(struct _list* self)
*/
struct _list* list_slice(struct _list* self, int start, int end, int step)
{
#if 0
assert(self != NULL);
int i = 0;
bool unlimited = false;
bool contains_last_obj = false;
int size = (int)self->size(self);
int capicity = 1;
list_t list = NULL;
if (step == 0)
{
return NULL;
@ -224,61 +251,31 @@ struct _list* list_slice(struct _list* self, int start, int end, int step)
if (end == LIST_UNLIMITED)
{
end = self->size(self);
end = size;
}
}
else
{
if (start == LIST_UNLIMITED)
{
start = self->size(self) - 1;
unlimited = true;
start = size - 1;
}
if (end == LIST_UNLIMITED)
{
end = 0;
unlimited = true;
contains_last_obj = true;
}
}
if (start < 0)
{
if (start < -self->size(self))
{
start = -self->size(self);
}
start += self->size(self);
}
else
{
if (start > self->size(self))
{
start = self->size(self);
}
}
start = list_index_exchange(self, start);
end = list_index_exchange(self, end);
if (end < 0)
if(abs(end - start) != 0)
{
if (end < -self->size(self))
{
end = -self->size(self);
capicity = abs(end - start);
}
end += self->size(self);
}
else
{
if (end > self->size(self))
{
end = self->size(self);
}
}
// printf("start = %d\n", start);
// printf("end = %d\n", end);
uint32_t capicity = (end - start == 0) ? 1 : abs(end - start);
list_t list = list_new2(self->_obj_size, capicity);
list = list_new2(self->_obj_size, capicity);
if (list == NULL)
{
return NULL;
@ -286,19 +283,14 @@ struct _list* list_slice(struct _list* self, int start, int end, int step)
list->compare = self->compare;
list->print_obj = self->print_obj;
if (capicity == 0 || start > self->size(self) || end > self->size(self))
{
goto done;
}
if (step > 0)
{
if (start > end)
if (start >= end)
{
goto done;
}
if (unlimited != true)
if (contains_last_obj != true)
{
for (i = start; i < end; i += step)
{
@ -315,12 +307,12 @@ struct _list* list_slice(struct _list* self, int start, int end, int step)
}
else /*if(step < 0)*/
{
if (start < end)
if (start <= end)
{
goto done;
}
if (unlimited != true)
if (contains_last_obj != true)
{
for (i = start; i > end; i += step)
{
@ -338,185 +330,6 @@ struct _list* list_slice(struct _list* self, int start, int end, int step)
done:
return list;
#else
assert(self != NULL);
list_t list = NULL;
bool empty = false;
uint32_t capacity = 1;
int i = 0;
bool contain_last_obj = false;
if (step == 0)
{
return NULL;
}
if (step > 0)
{
// special case
if (start == LIST_UNLIMITED)
{
start = 0;
}
if (end == LIST_UNLIMITED)
{
end = self->size(self);
contain_last_obj = true;
}
// [start_max, end_min] start < end and limit start_max and end_min
if (start >= end || start >= self->size(self) || end < -self->size(self))
{
empty = true;
}
if (empty != true)
{
if (start < 0)
{
if (start < -self->size(self))
{
start = -self->size(self);
}
start += self->size(self);
}
if (end < 0)
{
end += self->size(self);
}
else
{
if (end > self->size(self))
{
end = self->size(self);
contain_last_obj = true;
}
}
if (empty != true)
{
// calc capacity
capacity = end - start;
}
list = list_new2(self->_obj_size, capacity);
if (list == NULL)
{
return NULL;
}
list->compare = self->compare;
list->print_obj = self->print_obj;
if (contain_last_obj != true)
{
for (i = start; i < end; i += step)
{
list->append(list, (char*)self->obj + i * self->_obj_size);
}
}
else
{
for (i = start; i <= end; i += step)
{
list->append(list, (char*)self->obj + i * self->_obj_size);
}
}
}
else
{
list = list_new2(self->_obj_size, capacity);
if (list == NULL)
{
return NULL;
}
list->compare = self->compare;
list->print_obj = self->print_obj;
}
}
else
{
// special case
if (start == LIST_UNLIMITED)
{
start = self->size(self) - 1;
}
if (end == LIST_UNLIMITED)
{
end = 0;
contain_last_obj = true;
}
// [start_min, end_max] start > end and limit start_min and end_max
if (start <= end || end >= self->size(self) || start < -self->size(self))
{
empty = true;
}
if (empty != true)
{
if (start < 0)
{
if (start < -self->size(self))
{
start = -self->size(self);
}
start += self->size(self);
}
else
{
if (start > self->size(self))
{
start = self->size(self) - 1;
contain_last_obj = true;
}
}
if (end < 0)
{
end += self->size(self);
}
if (empty != true)
{
// calc capacity
capacity = end - start;
}
list = list_new2(self->_obj_size, capacity);
if (list == NULL)
{
return NULL;
}
list->compare = self->compare;
list->print_obj = self->print_obj;
if (contain_last_obj != true)
{
for (i = start; i > end; i += step)
{
list->append(list, (char*)self->obj + i * self->_obj_size);
}
}
else
{
for (i = start; i >= end; i += step)
{
list->append(list, (char*)self->obj + i * self->_obj_size);
}
}
}
else
{
list = list_new2(self->_obj_size, capacity);
if (list == NULL)
{
return NULL;
}
list->compare = self->compare;
list->print_obj = self->print_obj;
}
}
return list;
#endif
}
static bool list_iter_hasnext(struct _iterator* iter)

View File

@ -451,6 +451,11 @@ static void test_list_slice_empty(void)
TEST_ASSERT_TRUE(list2->empty(list2));
list_free(&list2);
list2 = list->slice(list, len, LIST_UNLIMITED, 1); // if start == end
TEST_ASSERT_NOT_NULL(list2);
TEST_ASSERT_TRUE(list2->empty(list2));
list_free(&list2);
list2 = list->slice(list, 1, 5, -1); // if start < end && step < 0
TEST_ASSERT_NOT_NULL(list2);
TEST_ASSERT_TRUE(list2->empty(list2));
@ -472,12 +477,12 @@ static void test_list_slice_empty(void)
list_free(&list2);
// -------------------- empty --------------------
list2 = list->slice(list, len, len + 10, 1); // if start > start_max
list2 = list->slice(list, len, len + 1, 1); // if start > start_max
TEST_ASSERT_NOT_NULL(list2);
TEST_ASSERT_TRUE(list2->empty(list2));
list_free(&list2);
list2 = list->slice(list, -len - 10, -len, 1); // if end < end_min
list2 = list->slice(list, -len - 1, -len, 1); // if end < end_min
TEST_ASSERT_NOT_NULL(list2);
TEST_ASSERT_TRUE(list2->empty(list2));
list_free(&list2);