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.
|
level of the structure.
|
||||||
See example of `ILIST_DEF`.
|
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(name, type[, oplist])`
|
||||||
#### `ILIST_DEF_AS(name, name_t, name_it_t, 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
|
Return the object that is before the object `*obj` in the list
|
||||||
or NULL if there is no more object.
|
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,
|
This method is the same as the generic one, except it is really `x` that is added in the list, not a copy.
|
||||||
except it is only created if the `NEW` and `INIT_SET` methods are provided.
|
|
||||||
|
|
||||||
##### `void name_splice_back(name_t list1, name_t list2, name_it_t it)`
|
##### `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__, M_BASIC_OPLIST), \
|
||||||
(__VA_ARGS__ )))
|
(__VA_ARGS__ )))
|
||||||
|
|
||||||
|
#define M_ILIST_INIT_FIELD(name, obj) do { \
|
||||||
|
(obj).name.next = NULL; \
|
||||||
|
(obj).name.prev = NULL; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/******************************** INTERNAL ***********************************/
|
/******************************** INTERNAL ***********************************/
|
||||||
@@ -117,7 +121,6 @@ typedef struct m_il1st_head_s {
|
|||||||
IT_REF(M_F(name,_ref)), \
|
IT_REF(M_F(name,_ref)), \
|
||||||
IT_CREF(M_F(name,_cref)), \
|
IT_CREF(M_F(name,_cref)), \
|
||||||
IT_REMOVE(M_F(name,_remove)), \
|
IT_REMOVE(M_F(name,_remove)), \
|
||||||
M_IF_METHOD(NEW, oplist)(IT_INSERT(M_F(name,_insert)),), \
|
|
||||||
OPLIST(oplist), \
|
OPLIST(oplist), \
|
||||||
SPLICE_BACK(M_F(name,_splice_back)) \
|
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, \
|
type *obj = M_TYPE_FROM_FIELD(type, it->current, \
|
||||||
struct m_il1st_head_s, name); \
|
struct m_il1st_head_s, name); \
|
||||||
M_F(name, _unlink)(obj); \
|
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_IF_METHOD(DEL, oplist)(M_CALL_DEL(oplist, obj), (void) 0); \
|
||||||
M_F(name, _next)(it); \
|
M_F(name, _next)(it); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
M_IF_METHOD2(NEW, INIT_SET, oplist)( \
|
|
||||||
M_INLINE void \
|
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_CONTRACT(name, list); \
|
||||||
M_IL1ST_NODE_CONTRACT(it->current); \
|
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); \
|
type *obj = M_F(name, _ref)(it); \
|
||||||
M_F(name, _push_after)(obj, p); \
|
M_F(name, _push_after)(obj, p); \
|
||||||
it->current = p; \
|
it->current = &p->name; \
|
||||||
(void) list; \
|
(void) list; \
|
||||||
M_IL1ST_CONTRACT(name, list); \
|
M_IL1ST_CONTRACT(name, list); \
|
||||||
} \
|
} \
|
||||||
, /* NEW & INIT_SET not defined */) \
|
|
||||||
\
|
\
|
||||||
M_INLINE type * \
|
M_INLINE type * \
|
||||||
M_F(name, _pop_back)(list_t list) \
|
M_F(name, _pop_back)(list_t list) \
|
||||||
|
|||||||
Reference in new issue
Block a user