Add method _splice_at for dual_push_list
This commit is contained in:
1 parent
2a6893efb4
commit
e5f5563249
2 files changed
+67
-6
No files matched your search
@@ -1145,8 +1145,8 @@
|
|||||||
{ \
|
{ \
|
||||||
LISTI_DUAL_PUSH_CONTRACT(list1); \
|
LISTI_DUAL_PUSH_CONTRACT(list1); \
|
||||||
LISTI_DUAL_PUSH_CONTRACT(list2); \
|
LISTI_DUAL_PUSH_CONTRACT(list2); \
|
||||||
assert(it->current != NULL); \
|
assert (it->current != NULL); \
|
||||||
/* First remove 'it' from list2 */ \
|
/* First remove the item 'it' from the list 'list2' */ \
|
||||||
struct M_C(name, _s) *current = it->current; \
|
struct M_C(name, _s) *current = it->current; \
|
||||||
struct M_C(name, _s) *next = current->next; \
|
struct M_C(name, _s) *next = current->next; \
|
||||||
if (it->previous == NULL) { \
|
if (it->previous == NULL) { \
|
||||||
@@ -1154,20 +1154,63 @@
|
|||||||
} else { \
|
} else { \
|
||||||
it->previous->next = next; \
|
it->previous->next = next; \
|
||||||
} \
|
} \
|
||||||
/* Update front */ \
|
/* Update the front of 'list2' if it was the last element */ \
|
||||||
struct M_C(name, _s) *front = list2->front; \
|
struct M_C(name, _s) *front = list2->front; \
|
||||||
front = (next == NULL) ? it->previous : front; \
|
front = (next == NULL) ? it->previous : front; \
|
||||||
list2->front = front; \
|
list2->front = front; \
|
||||||
/* Update it to next element */ \
|
/* Update 'it' to point to the next element */ \
|
||||||
it->current = next; \
|
it->current = next; \
|
||||||
/* Move current in nv */ \
|
/* Move the extracted 'current' into the list 'nv' */ \
|
||||||
current->next = list1->back; \
|
current->next = list1->back; \
|
||||||
list1->back = current; \
|
list1->back = current; \
|
||||||
/* Update front too if the list was empty */ \
|
/* Update the front field if the list 'nv' was empty */ \
|
||||||
/* This C code shall generate branchless code */ \
|
/* This C code shall generate branchless code */ \
|
||||||
front = list1->front; \
|
front = list1->front; \
|
||||||
front = (front == NULL) ? current : front; \
|
front = (front == NULL) ? current : front; \
|
||||||
list1->front = front; \
|
list1->front = front; \
|
||||||
|
LISTI_DUAL_PUSH_CONTRACT(list1); \
|
||||||
|
LISTI_DUAL_PUSH_CONTRACT(list2); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
static inline void \
|
||||||
|
M_C(name, _splice_at)(list_t nlist, list_it_t npos, \
|
||||||
|
list_t olist, list_it_t opos) \
|
||||||
|
{ \
|
||||||
|
LISTI_DUAL_PUSH_CONTRACT(nlist); \
|
||||||
|
LISTI_DUAL_PUSH_CONTRACT(olist); \
|
||||||
|
assert (npos != NULL && opos != NULL); \
|
||||||
|
/* First remove the item 'opos' from the list 'olist' */ \
|
||||||
|
struct M_C(name, _s) *current = opos->current; \
|
||||||
|
struct M_C(name, _s) *next = current->next; \
|
||||||
|
if (opos->previous == NULL) { \
|
||||||
|
olist->back = next; \
|
||||||
|
} else { \
|
||||||
|
opos->previous->next = next; \
|
||||||
|
} \
|
||||||
|
/* Update the front of 'olist' if it was the last element */ \
|
||||||
|
struct M_C(name, _s) *front = olist->front; \
|
||||||
|
front = (next == NULL) ? opos->previous : front; \
|
||||||
|
olist->front = front; \
|
||||||
|
/* Update 'opos' to point to the next element */ \
|
||||||
|
opos->current = next; \
|
||||||
|
/* Insert into 'nlist' */ \
|
||||||
|
if (M_UNLIKELY (npos->current == NULL)) { \
|
||||||
|
current->next = nlist->back; \
|
||||||
|
nlist->back = current; \
|
||||||
|
/* update 'front' if the list was empty (branchless) */ \
|
||||||
|
front = nlist->front; \
|
||||||
|
front = (front == NULL) ? current : front; \
|
||||||
|
nlist->front = front; \
|
||||||
|
} else { \
|
||||||
|
current->next = npos->current->next; \
|
||||||
|
npos->current->next = current; \
|
||||||
|
/* update front if current == front (branchless) */ \
|
||||||
|
front = nlist->front; \
|
||||||
|
front = (front == npos->current) ? next : front; \
|
||||||
|
nlist->front = front; \
|
||||||
|
} \
|
||||||
|
LISTI_DUAL_PUSH_CONTRACT(nlist); \
|
||||||
|
LISTI_DUAL_PUSH_CONTRACT(olist); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static inline void \
|
static inline void \
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ LIST_DUAL_PUSH_DEF(list2_double, double)
|
|||||||
END_COVERAGE
|
END_COVERAGE
|
||||||
LIST_DUAL_PUSH_DEF(list2_mpz, testobj_t, TESTOBJ_OPLIST)
|
LIST_DUAL_PUSH_DEF(list2_mpz, testobj_t, TESTOBJ_OPLIST)
|
||||||
#define LIST_UINT_OPLIST LIST_OPLIST(list_uint)
|
#define LIST_UINT_OPLIST LIST_OPLIST(list_uint)
|
||||||
|
#define LIST2_DOUBLE_OPLIST LIST_OPLIST(list2_double)
|
||||||
|
|
||||||
static void test_uint(void)
|
static void test_uint(void)
|
||||||
{
|
{
|
||||||
@@ -567,6 +568,23 @@ static void test_dual_it1(void)
|
|||||||
list2_double_next(it2);
|
list2_double_next(it2);
|
||||||
assert(*list2_double_cref(it2) == 1.0);
|
assert(*list2_double_cref(it2) == 1.0);
|
||||||
|
|
||||||
|
list2_double_clean(list);
|
||||||
|
list2_double_clean(list2);
|
||||||
|
for(double i = 0; i < 10; i++)
|
||||||
|
list2_double_push_back (list, i);
|
||||||
|
list2_double_it (it, list);
|
||||||
|
list2_double_it_end (it2, list2);
|
||||||
|
for(double i = 0; i < 10; i++) {
|
||||||
|
list2_double_splice_at (list2, it2, list, it);
|
||||||
|
}
|
||||||
|
assert (list2_double_empty_p(list));
|
||||||
|
assert (list2_double_size (list2) == 10);
|
||||||
|
double s = 0.0;
|
||||||
|
for M_EACH(item, list2, LIST2_DOUBLE_OPLIST) {
|
||||||
|
assert (*item == s);
|
||||||
|
s += 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
list2_double_clear(list2);
|
list2_double_clear(list2);
|
||||||
list2_double_clear(list);
|
list2_double_clear(list);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user