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:
1 parent
0f7d5bf366
commit
02828a0109
3 files changed
+69
-15
No files matched your search
@@ -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)`
|
||||
|
||||
|
||||
@@ -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
@@ -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) \
|
||||
|
||||
Reference in new issue
Block a user