mirror of
https://gitee.com/apaki/unicstl.git
synced 2025-05-17 19:41:36 +08:00
Compare commits
6 Commits
ce9acda014
...
32f2605656
Author | SHA1 | Date | |
---|---|---|---|
32f2605656 | |||
ccae6a9d8f | |||
65a60df00b | |||
e5ea2efe84 | |||
46caba5943 | |||
3f8f418d4e |
269
src/list.c
269
src/list.c
@ -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
|
* @brief list slice
|
||||||
* if index < 0, from the end of list. for example:
|
* 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)
|
struct _list* list_slice(struct _list* self, int start, int end, int step)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
assert(self != NULL);
|
assert(self != NULL);
|
||||||
int i = 0;
|
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)
|
if (step == 0)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -224,61 +251,31 @@ struct _list* list_slice(struct _list* self, int start, int end, int step)
|
|||||||
|
|
||||||
if (end == LIST_UNLIMITED)
|
if (end == LIST_UNLIMITED)
|
||||||
{
|
{
|
||||||
end = self->size(self);
|
end = size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (start == LIST_UNLIMITED)
|
if (start == LIST_UNLIMITED)
|
||||||
{
|
{
|
||||||
start = self->size(self) - 1;
|
start = size - 1;
|
||||||
unlimited = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (end == LIST_UNLIMITED)
|
if (end == LIST_UNLIMITED)
|
||||||
{
|
{
|
||||||
end = 0;
|
end = 0;
|
||||||
unlimited = true;
|
contains_last_obj = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (start < 0)
|
start = list_index_exchange(self, start);
|
||||||
{
|
end = list_index_exchange(self, end);
|
||||||
if (start < -self->size(self))
|
|
||||||
{
|
|
||||||
start = -self->size(self);
|
|
||||||
}
|
|
||||||
start += self->size(self);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (start > self->size(self))
|
|
||||||
{
|
|
||||||
start = self->size(self);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end < 0)
|
if(abs(end - start) != 0)
|
||||||
{
|
{
|
||||||
if (end < -self->size(self))
|
capicity = abs(end - start);
|
||||||
{
|
|
||||||
end = -self->size(self);
|
|
||||||
}
|
|
||||||
end += self->size(self);
|
|
||||||
}
|
}
|
||||||
else
|
list = list_new2(self->_obj_size, capicity);
|
||||||
{
|
|
||||||
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);
|
|
||||||
if (list == NULL)
|
if (list == NULL)
|
||||||
{
|
{
|
||||||
return 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->compare = self->compare;
|
||||||
list->print_obj = self->print_obj;
|
list->print_obj = self->print_obj;
|
||||||
|
|
||||||
if (capicity == 0 || start > self->size(self) || end > self->size(self))
|
|
||||||
{
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (step > 0)
|
if (step > 0)
|
||||||
{
|
{
|
||||||
if (start > end)
|
if (start >= end)
|
||||||
{
|
{
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlimited != true)
|
if (contains_last_obj != true)
|
||||||
{
|
{
|
||||||
for (i = start; i < end; i += step)
|
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)*/
|
else /*if(step < 0)*/
|
||||||
{
|
{
|
||||||
if (start < end)
|
if (start <= end)
|
||||||
{
|
{
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlimited != true)
|
if (contains_last_obj != true)
|
||||||
{
|
{
|
||||||
for (i = start; i > end; i += step)
|
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:
|
done:
|
||||||
return list;
|
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)
|
static bool list_iter_hasnext(struct _iterator* iter)
|
||||||
|
@ -451,6 +451,11 @@ static void test_list_slice_empty(void)
|
|||||||
TEST_ASSERT_TRUE(list2->empty(list2));
|
TEST_ASSERT_TRUE(list2->empty(list2));
|
||||||
list_free(&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
|
list2 = list->slice(list, 1, 5, -1); // if start < end && step < 0
|
||||||
TEST_ASSERT_NOT_NULL(list2);
|
TEST_ASSERT_NOT_NULL(list2);
|
||||||
TEST_ASSERT_TRUE(list2->empty(list2));
|
TEST_ASSERT_TRUE(list2->empty(list2));
|
||||||
@ -472,12 +477,12 @@ static void test_list_slice_empty(void)
|
|||||||
list_free(&list2);
|
list_free(&list2);
|
||||||
|
|
||||||
// -------------------- empty --------------------
|
// -------------------- 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_NOT_NULL(list2);
|
||||||
TEST_ASSERT_TRUE(list2->empty(list2));
|
TEST_ASSERT_TRUE(list2->empty(list2));
|
||||||
list_free(&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_NOT_NULL(list2);
|
||||||
TEST_ASSERT_TRUE(list2->empty(list2));
|
TEST_ASSERT_TRUE(list2->empty(list2));
|
||||||
list_free(&list2);
|
list_free(&list2);
|
||||||
@ -545,7 +550,7 @@ static void test_list_slice_positive(void)
|
|||||||
// python: list[4:0:-1]
|
// python: list[4:0:-1]
|
||||||
list2 = list->slice(list, 4, 0, -1);
|
list2 = list->slice(list, 4, 0, -1);
|
||||||
TEST_ASSERT_NOT_NULL(list2);
|
TEST_ASSERT_NOT_NULL(list2);
|
||||||
//list2->print(list2); printf("\n");
|
// list2->print(list2); printf("\n");
|
||||||
TEST_ASSERT_EQUAL_INT(4, list2->size(list2));
|
TEST_ASSERT_EQUAL_INT(4, list2->size(list2));
|
||||||
for(i = 0; i < list2->size(list2); i++)
|
for(i = 0; i < list2->size(list2); i++)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user