diff --git a/src/list.c b/src/list.c index 4c3929c..9e4d348 100644 --- a/src/list.c +++ b/src/list.c @@ -216,18 +216,12 @@ struct _list* list_slice(struct _list *self, int start, int end, int step) { start += self->size(self); } - if(end < 0) { end += self->size(self); } - - if(start > self->size(self) || end > self->size(self)) - { - return NULL; - } - - list_t list = list_new2(self->_obj_size, end - start); + uint32_t capicity = (end - start == 0) ? 1 : end - start; + list_t list = list_new2(self->_obj_size, capicity); if(list == NULL) { return NULL; @@ -235,47 +229,42 @@ 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) + { + goto done; + } + + if(start > self->size(self) || end > self->size(self)) + { + return list; + } + if(step > 0) { if(start >= end) { - return NULL; + goto done; } for(int i = start; i < end; i += step) { - if(i >= self->size(self)) - { - break; - } list->append(list, (char*)self->obj + i * self->_obj_size); } } else { - uint32_t temp = 0; if(start <= end) { - return NULL; + goto done; } - // start ^= end; - // end ^= start; - // start ^= end; - temp = start; - start = end; - end = temp; - step = -step; - for(int i = start; i < end; i += step) + for(int i = start; i > end; i += step) { - if(i >= self->size(self)) - { - break; - } - list->insert(list, 0, (char*)self->obj + i * self->_obj_size); + list->append(list, (char*)self->obj + i * self->_obj_size); } } +done: return list; } diff --git a/test/test_list.c b/test/test_list.c index 6be19b1..f338ecc 100644 --- a/test/test_list.c +++ b/test/test_list.c @@ -448,11 +448,11 @@ static void test_list_slice(void) TEST_ASSERT_TRUE(list2->empty(list2)); list2 = list->slice(list, 1, 5, -1); // if start < end && step < 0 - TEST_ASSERT_NULL(list2); + TEST_ASSERT_NOT_NULL(list2); TEST_ASSERT_TRUE(list2->empty(list2)); list2 = list->slice(list, 5, 1, 1); // if start > end && step > 0 - TEST_ASSERT_NULL(list2); + TEST_ASSERT_NOT_NULL(list2); TEST_ASSERT_TRUE(list2->empty(list2)); // python: list[0:] @@ -488,7 +488,7 @@ static void test_list_slice(void) TEST_ASSERT_EQUAL_INT(data[len - 1], temp); list_free(&list2); - // python: list[-5:8:1] + // python: list[-6:8] or list[-6:-2] // list2 = list->slice(list, -6, 8, 1); // It can be executed, but it's not intuitive list2 = list->slice(list, -6, -2, 1); TEST_ASSERT_NOT_NULL(list2); @@ -501,20 +501,18 @@ static void test_list_slice(void) } list_free(&list2); - // python: list[-6:0:-1] or list[4:0:-1] - // list2 = list->slice(list, -6, 0, -1); // It can be executed, but it's not intuitive + // python: list[4::-1] list2 = list->slice(list, 4, 0, -1); TEST_ASSERT_NOT_NULL(list2); list2->print(list2); printf("\n"); - TEST_ASSERT_EQUAL_INT(4, list2->size(list2)); + TEST_ASSERT_EQUAL_INT(5, list2->size(list2)); for(i = 0; i < list2->size(list2); i++) { TEST_ASSERT_TRUE(list2->get(list2, i, &temp)); - TEST_ASSERT_EQUAL_INT(data[list2->size(list2) - 1 - i], temp); + TEST_ASSERT_EQUAL_INT(data[list2->size(list2) - i], temp); } list_free(&list2); - list_free(&list); }