Fix interface of Intrusive List

(Reported by Brian Sipos):
* incorrect clear operator usage
* useless prototype of _insert, inconsistent with the policy of other functions
* syntax error in _insert
This commit is contained in:
Patrick Pelissier committed 2024-07-11 21:41:14 +02:00
1 parent 0f7d5bf366
commit 02828a0109
3 files changed
+69 -15

No files matched your search

+6 -3
View File
@@ -4777,6 +4777,10 @@ It shall be put within the structure of the object to link, at the top
level of the structure.
See example of `ILIST_DEF`.
#### `ILIST_INIT_FIELD(name, object)`
Initialize the fields added by `ILIST_INTERFACE` of the object.
#### `ILIST_DEF(name, type[, oplist])`
#### `ILIST_DEF_AS(name, name_t, name_it_t, type[, oplist])`
@@ -4931,10 +4935,9 @@ or NULL if there is no more object.
Return the object that is before the object `*obj` in the list
or NULL if there is no more object.
##### `void name_insert(name_t list, name_it_t it, type x)`
##### `void name_insert(name_t list, name_it_t it, type *x)`
This method is the same as the generic one,
except it is only created if the `NEW` and `INIT_SET` methods are provided.
This method is the same as the generic one, except it is really `x` that is added in the list, not a copy.
##### `void name_splice_back(name_t list1, name_t list2, name_it_t it)`
+56
View File
@@ -0,0 +1,56 @@
#include "m-i-list.h"
typedef struct data_s {
M_ILIST_INTERFACE(list1, struct data_s);
char *ptr;
int n;
} data_t;
static void
data_init(data_t *p)
{
M_ILIST_INIT_FIELD(list1, *p);
p->ptr = malloc(100);
p->n = 100;
}
static void
data_clear(data_t *p)
{
free(p->ptr);
p->n = 0;
}
static void
data_init_set(data_t *p, data_t s)
{
p->ptr = malloc(s.n);
p->n = s.n;
memcpy(p->ptr, s.ptr, s.n);
}
#define DATA_OP (INIT(API_2(data_init)), INIT_SET(API_2(data_init_set)), CLEAR(API_2(data_clear)) )
M_ILIST_DEF(list1, data_t, DATA_OP)
data_t pool[100];
int main(void)
{
list1_t l;
list1_init(l);
data_init(&pool[0]);
list1_push_back(l, &pool[0]);
data_init(&pool[1]);
list1_push_back(l, &pool[1]);
list1_it_t it;
list1_it(it, l);
data_init(&pool[2]);
list1_insert(l, it, &pool[2]);
list1_clear(l);
exit(0);
}
+7 -12
View File
@@ -71,6 +71,10 @@
((__VA_ARGS__, M_BASIC_OPLIST), \
(__VA_ARGS__ )))
#define M_ILIST_INIT_FIELD(name, obj) do { \
(obj).name.next = NULL; \
(obj).name.prev = NULL; \
} while(0)
/*****************************************************************************/
/******************************** INTERNAL ***********************************/
@@ -117,7 +121,6 @@ typedef struct m_il1st_head_s {
IT_REF(M_F(name,_ref)), \
IT_CREF(M_F(name,_cref)), \
IT_REMOVE(M_F(name,_remove)), \
M_IF_METHOD(NEW, oplist)(IT_INSERT(M_F(name,_insert)),), \
OPLIST(oplist), \
SPLICE_BACK(M_F(name,_splice_back)) \
)
@@ -517,30 +520,22 @@ typedef struct m_il1st_head_s {
type *obj = M_TYPE_FROM_FIELD(type, it->current, \
struct m_il1st_head_s, name); \
M_F(name, _unlink)(obj); \
M_CALL_CLEAR(oplist, obj); \
M_CALL_CLEAR(oplist, *obj); \
M_IF_METHOD(DEL, oplist)(M_CALL_DEL(oplist, obj), (void) 0); \
M_F(name, _next)(it); \
} \
\
M_IF_METHOD2(NEW, INIT_SET, oplist)( \
M_INLINE void \
M_F(name, _insert)(list_t list, it_t it, type x) \
M_F(name, _insert)(list_t list, it_t it, type *p) \
{ \
M_IL1ST_CONTRACT(name, list); \
M_IL1ST_NODE_CONTRACT(it->current); \
type *p = M_CALL_NEW(oplist, type); \
if (M_UNLIKELY_NOMEM (p == NULL)) { \
M_MEMORY_FULL (sizeof (type)); \
return ; \
} \
M_CALL_INIT_SET(oplist, *p, x); \
type *obj = M_F(name, _ref)(it); \
M_F(name, _push_after)(obj, p); \
it->current = p; \
it->current = &p->name; \
(void) list; \
M_IL1ST_CONTRACT(name, list); \
} \
, /* NEW & INIT_SET not defined */) \
\
M_INLINE type * \
M_F(name, _pop_back)(list_t list) \