Remove list_ prefix from all lists.
See commit on shared-pointers. Rename the iteration type to be prefix by name list_it_name_t ==> name_it_t
This commit is contained in:
1 parent
7a49348a4d
commit
4cb92a92b8
7 files changed
+284
-280
No files matched your search
@@ -183,7 +183,7 @@ Then you use the defined functions. Let's see an example which is rather simple:
|
||||
#include <stdio.h>
|
||||
#include "m-list.h"
|
||||
|
||||
LIST_DEF(uint, unsigned int) /* Define struct list_uint_t and its methods */
|
||||
LIST_DEF(list_uint, unsigned int) /* Define struct list_uint_t and its methods */
|
||||
|
||||
int main(void) {
|
||||
list_uint_t list ; /* list_uint_t has been define above */
|
||||
@@ -251,7 +251,7 @@ You can also condense the M\*LIB code by using the EACH & LET macros if you are
|
||||
#include <stdio.h>
|
||||
#include "m-list.h"
|
||||
|
||||
LIST_DEF(uint, unsigned int) /* Define struct list_uint_t and its methods */
|
||||
LIST_DEF(list_uint, unsigned int) /* Define struct list_uint_t and its methods */
|
||||
|
||||
int main(void) {
|
||||
M_LET(list, LIST_OPLIST(uint)) { /* Define & init list as list_uint_t */
|
||||
@@ -515,10 +515,10 @@ This header is for creating single-linked list.
|
||||
|
||||
#### LIST\_DEF(name, type, [, oplist])
|
||||
|
||||
Define the list 'list\_##name##\_t' which contains the objects of type 'type' and its associated methods as "static inline" functions.
|
||||
Define the list 'name##\_t' which contains the objects of type 'type' and its associated methods as "static inline" functions.
|
||||
'name' shall be a C identifier which will be used to identify the list. It will be used to create all the types and functions to handle the container.
|
||||
It shall be done once per type and per compilation unit.
|
||||
It also define the iterator list\_it\_##name##\_t and its associated methods as "static inline" functions.
|
||||
It also define the iterator name##\_it\_t and its associated methods as "static inline" functions.
|
||||
|
||||
A fundamental property of a list is that the objects created within the list
|
||||
will remain at their initialized address, and won't moved due to
|
||||
@@ -530,7 +530,7 @@ For this structure, the back is always the first element, and the front is the l
|
||||
|
||||
Example:
|
||||
|
||||
LIST_DEF(mpz, mpz_t, \
|
||||
LIST_DEF(list_mpz, mpz_t, \
|
||||
(INIT(mpz_init), INIT_SET(mpz_init_set), SET(mpz_set), CLEAR(mpz_clear)))
|
||||
|
||||
list_mpz_t my_list;
|
||||
@@ -553,7 +553,7 @@ and cleared by calling mempool\_list\_name\_clear(variable).
|
||||
|
||||
Example:
|
||||
|
||||
LIST_DEF(uint, unsigned int, (MEMPOOL(list_mpool), MEMPOOL_LINKAGE(static)))
|
||||
LIST_DEF(list_uint, unsigned int, (MEMPOOL(list_mpool), MEMPOOL_LINKAGE(static)))
|
||||
|
||||
static void test_list (size_t n)
|
||||
{
|
||||
@@ -575,169 +575,169 @@ Return the oplist of the list defined by calling LIST\_DEF with name & oplist.
|
||||
In the following methods, name stands for the name given to the macro which is used to identify the type.
|
||||
The following types are automatically defined by the previous macro:
|
||||
|
||||
#### list\_name\_t
|
||||
#### name\_t
|
||||
|
||||
Type of the list of 'type'.
|
||||
|
||||
#### list\_it\_name\_t
|
||||
#### name\_it\_t
|
||||
|
||||
Type of an iterator over this list.
|
||||
|
||||
The following methods are automatically and properly created by the previous macro.
|
||||
|
||||
##### void list\_name\_init(list\_name\_t list)
|
||||
##### void name\_init(name\_t list)
|
||||
|
||||
Initialize the list 'list' (aka constructor) to an empty list.
|
||||
|
||||
##### void list\_name\_init\_set(list\_name\_t list, const list\_name\_t ref)
|
||||
##### void name\_init\_set(name\_t list, const name\_t ref)
|
||||
|
||||
Initialize the list 'list' (aka constructor) and set it to the value of 'ref'.
|
||||
|
||||
##### void list\_name\_set(list\_name\_t list, const list\_name\_t ref)
|
||||
##### void name\_set(name\_t list, const name\_t ref)
|
||||
|
||||
Set the list 'list' to the value of 'ref'.
|
||||
|
||||
##### void list\_name\_init\_move(list\_name\_t list, list\_name\_t ref)
|
||||
##### void name\_init\_move(name\_t list, name\_t ref)
|
||||
|
||||
Initialize the list 'list' (aka constructor) by stealing as many resources from 'ref' as possible.
|
||||
After-wise 'ref' is cleared and can no longer be used.
|
||||
|
||||
##### void list\_name\_move(list\_name\_t list, list\_name\_t ref)
|
||||
##### void name\_move(name\_t list, name\_t ref)
|
||||
|
||||
Set the list 'list' (aka constructor) by stealing as many resources from 'ref' as possible.
|
||||
After-wise 'ref' is cleared and can no longer be used.
|
||||
|
||||
##### void list\_name\_clear(list\_name\_t list)
|
||||
##### void name\_clear(name\_t list)
|
||||
|
||||
Clear the list 'list (aka destructor). The list can't be used anymore, except with a constructor.
|
||||
|
||||
##### void list\_name\_clean(list\_name\_t list)
|
||||
##### void name\_clean(name\_t list)
|
||||
|
||||
Clean the list (the list becomes empty). The list remains initialized but is empty.
|
||||
|
||||
##### const type *list\_name\_back(const list\_name\_t list)
|
||||
##### const type *name\_back(const name\_t list)
|
||||
|
||||
Return a constant pointer to the data stored in the back of the list.
|
||||
|
||||
##### void list\_name\_push\_back(list\_name\_t list, type value)
|
||||
##### void name\_push\_back(name\_t list, type value)
|
||||
|
||||
Push a new element within the list 'list' with the value 'value' contained within.
|
||||
|
||||
##### type *list\_name\_push\_raw(list\_name\_t list)
|
||||
##### type *name\_push\_raw(name\_t list)
|
||||
|
||||
Push a new element within the list 'list' without initializing it and returns a pointer to the **non-initialized** data.
|
||||
The first thing to do after calling this function is to initialize the data using the proper constructor. This allows to use a more specialized
|
||||
constructor than the generic one.
|
||||
Return a pointer to the **non-initialized** data.
|
||||
|
||||
##### type *list\_name\_push\_new(list\_name\_t list)
|
||||
##### type *name\_push\_new(name\_t list)
|
||||
|
||||
Push a new element within the list 'list' and initialize it with the default constructor of the type.
|
||||
Return a pointer to the initialized object.
|
||||
|
||||
##### void list\_name\_pop\_back(type *data, list\_name\_t list)
|
||||
##### void name\_pop\_back(type *data, name\_t list)
|
||||
|
||||
Pop a element from the list 'list' and set *data to this value.
|
||||
|
||||
##### bool list\_name\_empty\_p(const list\_name\_t list)
|
||||
##### bool name\_empty\_p(const name\_t list)
|
||||
|
||||
Return true if the list is empty, false otherwise.
|
||||
|
||||
##### void list\_name\_swap(list\_name\_t list1, list\_name\_t list2)
|
||||
##### void name\_swap(name\_t list1, name\_t list2)
|
||||
|
||||
Swap the list 'list1' and 'list2'.
|
||||
|
||||
##### void list\_name\_it(list\_it\_name\_t it, list\_name\_t list)
|
||||
##### void name\_it(name\_it\_t it, name\_t list)
|
||||
|
||||
Set the iterator 'it' to the back(=first) element of 'list'.
|
||||
There is no destructor associated to this initialization.
|
||||
|
||||
##### void list\_name\_it\set(list\_it\_name\_t it, const list\_it\_name\_t ref)
|
||||
##### void name\_it\set(name\_it\_t it, const name\_it\_t ref)
|
||||
|
||||
Set the iterator 'it' to the iterator 'ref'.
|
||||
There is no destructor associated to this initialization.
|
||||
|
||||
##### bool list\_name\_end\_p(const list\_it\_name\_t it)
|
||||
##### bool name\_end\_p(const name\_it\_t it)
|
||||
|
||||
Return true if the iterator doesn't reference a valid element anymore.
|
||||
|
||||
##### bool list\_name\_last\_p(const list\_it\_name\_t it)
|
||||
##### bool name\_last\_p(const name\_it\_t it)
|
||||
|
||||
Return true if the iterator references the top(=last) element or if the iterator doesn't reference a valid element anymore.
|
||||
|
||||
##### bool list\_name\_it\_equal\_p(const list\_it\_name\_t it1, const list\_it\_name\_t it2)
|
||||
##### bool name\_it\_equal\_p(const name\_it\_t it1, const name\_it\_t it2)
|
||||
|
||||
Return true if the iterator it1 references the same element than it2.
|
||||
|
||||
##### void list\_name\_next(list\_it\_name\_t it)
|
||||
##### void name\_next(name\_it\_t it)
|
||||
|
||||
Move the iterator 'it' to the next element of the list, ie. from the back (=first) element to the front(=last) element.
|
||||
|
||||
##### type *list\_name\_ref(list\_it\_name\_t it)
|
||||
##### type *name\_ref(name\_it\_t it)
|
||||
|
||||
Return a pointer to the element pointed by the iterator.
|
||||
This pointer remains valid until the list is modified by another method.
|
||||
|
||||
##### const type *list\_name\_cref(const list\_it\_name\_t it)
|
||||
##### const type *name\_cref(const name\_it\_t it)
|
||||
|
||||
Return a constant pointer to the element pointed by the iterator.
|
||||
This pointer remains valid until the list is modified by another method.
|
||||
|
||||
##### type *list\_name\_get(const list\_name\_t list, size\_t i)
|
||||
##### type *name\_get(const name\_t list, size\_t i)
|
||||
|
||||
Return a pointer to the element i-th of the list (from 0).
|
||||
It is assumed than i is within the size of the list.
|
||||
|
||||
##### const type *list\_name\_cget(const list\_name\_t list, size\_t i)
|
||||
##### const type *name\_cget(const name\_t list, size\_t i)
|
||||
|
||||
Return a constant pointer to the element i-th of the list (from 0).
|
||||
It is assumed than i is within the size of the list.
|
||||
|
||||
##### size\_t list\_name\_size(const list\_name\_t list)
|
||||
##### size\_t name\_size(const name\_t list)
|
||||
|
||||
Return the number elements of the list (aka size). Return 0 if there no element.
|
||||
|
||||
##### void list\_name\_insert(list\_name\_t list, const list\_it\_name\_t it, const type x)
|
||||
##### void name\_insert(name\_t list, const name\_it\_t it, const type x)
|
||||
|
||||
Insert 'x' after the position pointed by 'it' (which is an iterator of the list 'list') or if 'it' doesn't point anymore to a valid element of the list, it is added as the back (=first) element of the 'list'
|
||||
|
||||
##### void list\_name\_remove(list\_name\_t list, list\_it\_name\_t it)
|
||||
##### void name\_remove(name\_t list, name\_it\_t it)
|
||||
|
||||
Remove the element 'it' from the list 'list'.
|
||||
After wise, 'it' points to the next element of the list.
|
||||
|
||||
##### void list\_name\_splice\_back(list\_name\_t list1, list\_name\_t list2, list\_it\_name\_t it)
|
||||
##### void name\_splice\_back(name\_t list1, name\_t list2, name\_it\_t it)
|
||||
|
||||
Move the element pointed by 'it' (which is an iterator of 'list2') from the list 'list2' to the back position of 'list1'.
|
||||
After wise, 'it' points to the next element of 'list2'.
|
||||
|
||||
##### void list\_name\_splice(list\_name\_t list1, list\_name\_t list2)
|
||||
##### void name\_splice(name\_t list1, name\_t list2)
|
||||
|
||||
Move all the element of 'list2' into 'list1", moving the last element
|
||||
of 'list2' after the first element of 'list1'.
|
||||
After-wise, 'list2' is emptied.
|
||||
|
||||
##### void list\_name\_reverse(list\_name\_t list)
|
||||
##### void name\_reverse(name\_t list)
|
||||
|
||||
Reverse the order of the list.
|
||||
|
||||
##### void list\_name\_get\_str(string\_t str, const list\_name\_t list, bool append)
|
||||
##### void name\_get\_str(string\_t str, const name\_t list, bool append)
|
||||
|
||||
Generate a string representation of the list 'list' and set 'str' to this representation
|
||||
(if 'append' is false) or append 'str' with this representation (if 'append' is true).
|
||||
This method is only defined if the type of the element defines a GET\_STR method itself.
|
||||
|
||||
##### void list\_name\_out\_str(FILE *file, const list\_name\_t list)
|
||||
##### void name\_out\_str(FILE *file, const name\_t list)
|
||||
|
||||
Generate a string representation of the list 'list' and outputs it into the FILE 'file'.
|
||||
This method is only defined if the type of the element defines a OUT\_STR method itself.
|
||||
|
||||
##### void list\_name\_in\_str(FILE *file, const list\_name\_t list)
|
||||
##### void name\_in\_str(FILE *file, const name\_t list)
|
||||
|
||||
Read from the file 'file' a string representation of a list and set 'list' to this representation.
|
||||
This method is only defined if the type of the element defines a IN\_STR method itself.
|
||||
|
||||
##### bool list\_name\_equal\_p(const list\_name\_t list1, const list\_name\_t list2)
|
||||
##### bool name\_equal\_p(const name\_t list1, const name\_t list2)
|
||||
|
||||
Return true if both lists 'list1' and 'list2' are equal.
|
||||
This method is only defined if the type of the element defines a EQUAL method itself.
|
||||
|
||||
+4
-4
@@ -39,9 +39,9 @@ static void test_array(size_t n)
|
||||
|
||||
// Two benched mode: with or without mempool
|
||||
#ifdef USE_MEMPOOL
|
||||
LIST_DEF(uint, unsigned int, (MEMPOOL( list_mpool), MEMPOOL_LINKAGE(static)))
|
||||
LIST_DEF(list_uint, unsigned int, (MEMPOOL( list_mpool), MEMPOOL_LINKAGE(static)))
|
||||
#else
|
||||
LIST_DEF(uint, unsigned int)
|
||||
LIST_DEF(list_uint, unsigned int)
|
||||
#endif
|
||||
|
||||
static void test_list (size_t n)
|
||||
@@ -49,13 +49,13 @@ static void test_list (size_t n)
|
||||
#ifdef USE_MEMPOOL
|
||||
mempool_list_uint_init(list_mpool);
|
||||
#endif
|
||||
M_LET(a1, a2, LIST_OPLIST(uint)) {
|
||||
M_LET(a1, a2, LIST_OPLIST(list_uint)) {
|
||||
for(size_t i = 0; i < n; i++) {
|
||||
list_uint_push_back(a1, rand_get() );
|
||||
list_uint_push_back(a2, rand_get() );
|
||||
}
|
||||
unsigned int s = 0;
|
||||
list_it_uint_t it1, it2;
|
||||
list_uint_it_t it1, it2;
|
||||
for(list_uint_it(it1, a1), list_uint_it(it2,a2); !list_uint_end_p(it1); list_uint_next(it1), list_uint_next(it2)) {
|
||||
s += *list_uint_cref(it1) * *list_uint_cref(it2);
|
||||
}
|
||||
|
||||
+3
-3
@@ -9,10 +9,10 @@
|
||||
#include "m-algo.h"
|
||||
|
||||
// Let's create a list of string.
|
||||
LIST_DEF(string, string_t, STRING_OPLIST)
|
||||
LIST_DEF(list_string, string_t, STRING_OPLIST)
|
||||
|
||||
// Let's define its oplist with a shorter name
|
||||
#define ASTR_OPLIST LIST_OPLIST(string, STRING_OPLIST)
|
||||
#define ASTR_OPLIST LIST_OPLIST(list_string, STRING_OPLIST)
|
||||
|
||||
// Let's define some basic algorithms over this list of string.
|
||||
ALGO_DEF(astring, ASTR_OPLIST)
|
||||
@@ -49,7 +49,7 @@ int main(void)
|
||||
}
|
||||
|
||||
// You can also use classic iterator:
|
||||
list_it_string_t it;
|
||||
list_string_it_t it;
|
||||
printf ("Using iterators :\n");
|
||||
for(list_string_it(it, grow) ; !list_string_end_p(it) ; list_string_next(it)) {
|
||||
const string_t *item = list_string_cref (it);
|
||||
|
||||
@@ -35,12 +35,12 @@
|
||||
#define DICT_DEF2(name, key_type, key_oplist, value_type, value_oplist) \
|
||||
TUPLE_DEF2(M_C(dict_pair_, name), (key, key_type, key_oplist), (value, value_type, value_oplist)) \
|
||||
M_IF_METHOD(MEMPOOL, key_oplist)( \
|
||||
LIST_DEF(M_C(dict_pair_, name), M_C3(dict_pair_,name,_t), \
|
||||
LIST_DEF(M_C(list_dict_pair_, name), M_C3(dict_pair_,name,_t), \
|
||||
M_OPEXTEND(TUPLE_OPLIST(M_C(dict_pair_, name), key_oplist, value_oplist), MEMPOOL(M_GET_MEMPOOL key_oplist), MEMPOOL_LINKAGE(M_GET_MEMPOOL_LINKAGE key_oplist))) \
|
||||
, \
|
||||
LIST_DEF(M_C(dict_pair_, name), M_C3(dict_pair_,name,_t), TUPLE_OPLIST(M_C(dict_pair_, name), key_oplist, value_oplist)) \
|
||||
LIST_DEF(M_C(list_dict_pair_, name), M_C3(dict_pair_,name,_t), TUPLE_OPLIST(M_C(dict_pair_, name), key_oplist, value_oplist)) \
|
||||
) \
|
||||
ARRAY_DEF(M_C(list_dict_pair_,name), M_C3(list_dict_pair_,name,_t), LIST_OPLIST(M_C(dict_pair_, name), TUPLE_OPLIST(M_C(dict_pair_, name), key_oplist, value_oplist))) \
|
||||
ARRAY_DEF(M_C(list_dict_pair_,name), M_C3(list_dict_pair_,name,_t), LIST_OPLIST(M_C(list_dict_pair_, name), TUPLE_OPLIST(M_C(dict_pair_, name), key_oplist, value_oplist))) \
|
||||
\
|
||||
DICTI_DEF2_FUNC(name, key_type, key_oplist, value_type, value_oplist, 0, M_C3(dict_, name, _t), M_C3(dict_it_, name, _t))
|
||||
|
||||
@@ -59,12 +59,12 @@
|
||||
#define DICT_SET_DEF2(name, key_type, key_oplist) \
|
||||
TUPLE_DEF2(M_C(dict_pair_, name), (key, key_type, key_oplist)) \
|
||||
M_IF_METHOD(MEMPOOL, key_oplist)( \
|
||||
LIST_DEF(M_C(dict_pair_, name), M_C3(dict_pair_,name,_t), \
|
||||
LIST_DEF(M_C(list_dict_pair_, name), M_C3(dict_pair_,name,_t), \
|
||||
M_OPEXTEND(TUPLE_OPLIST(M_C(dict_pair_, name), key_oplist), MEMPOOL(M_GET_MEMPOOL key_oplist), MEMPOOL_LINKAGE(M_GET_MEMPOOL_LINKAGE key_oplist))) \
|
||||
, \
|
||||
LIST_DEF(M_C(dict_pair_, name), M_C3(dict_pair_,name,_t), TUPLE_OPLIST(M_C(dict_pair_, name), key_oplist)) \
|
||||
LIST_DEF(M_C(list_dict_pair_, name), M_C3(dict_pair_,name,_t), TUPLE_OPLIST(M_C(dict_pair_, name), key_oplist)) \
|
||||
) \
|
||||
ARRAY_DEF(M_C(list_dict_pair_,name), M_C3(list_dict_pair_,name,_t), LIST_OPLIST(M_C(dict_pair_, name), TUPLE_OPLIST(M_C(dict_pair_, name), key_oplist))) \
|
||||
ARRAY_DEF(M_C(list_dict_pair_,name), M_C3(list_dict_pair_,name,_t), LIST_OPLIST(M_C(list_dict_pair_, name), TUPLE_OPLIST(M_C(dict_pair_, name), key_oplist))) \
|
||||
\
|
||||
DICTI_DEF2_FUNC(name, key_type, key_oplist, key_type, \
|
||||
(INIT(M_EMPTY_DEFAULT), INIT_SET(M_EMPTY_DEFAULT), SET(M_EMPTY_DEFAULT), CLEAR(M_EMPTY_DEFAULT), \
|
||||
@@ -100,7 +100,7 @@
|
||||
\
|
||||
typedef struct M_C3(dict_it_, name, _s) { \
|
||||
M_C3(array_it_list_dict_pair_, name, _t) array_it; \
|
||||
M_C3(list_it_dict_pair_, name, _t) list_it; \
|
||||
M_C3(list_dict_pair_, name, _it_t) list_it; \
|
||||
} dict_it_t[1]; \
|
||||
\
|
||||
static inline void \
|
||||
@@ -206,7 +206,7 @@
|
||||
hash = hash & (M_C3(array_list_dict_pair_,name,_size)(map->table) - 1); \
|
||||
const M_C3(list_dict_pair_,name,_t) *list_ptr = \
|
||||
M_C3(array_list_dict_pair_,name,_cget)(map->table, hash); \
|
||||
M_C3(list_it_dict_pair_,name,_t) it; \
|
||||
M_C3(list_dict_pair_,name,_it_t) it; \
|
||||
for(M_C3(list_dict_pair_,name,_it)(it, *list_ptr); \
|
||||
!M_C3(list_dict_pair_,name,_end_p)(it); \
|
||||
M_C3(list_dict_pair_,name,_next)(it)) { \
|
||||
@@ -231,7 +231,7 @@
|
||||
M_C3(array_list_dict_pair_,name,_get)(map->table, i); \
|
||||
if (M_C3(list_dict_pair_,name,_empty_p)(*list)) \
|
||||
continue; \
|
||||
M_C3(list_it_dict_pair_,name,_t) it; \
|
||||
M_C3(list_dict_pair_,name,_it_t) it; \
|
||||
M_C3(list_dict_pair_,name,_it)(it, *list); \
|
||||
while (!M_C3(list_dict_pair_,name,_end_p)(it)) { \
|
||||
M_C3(dict_pair_,name,_ptr) pair = *M_C3(list_dict_pair_,name,_ref)(it); \
|
||||
@@ -264,7 +264,7 @@
|
||||
M_C3(array_list_dict_pair_,name,_get)(map->table, i); \
|
||||
if (M_C3(list_dict_pair_,name,_empty_p)(*list)) \
|
||||
continue; \
|
||||
M_C3(list_it_dict_pair_,name,_t) it; \
|
||||
M_C3(list_dict_pair_,name,_it_t) it; \
|
||||
M_C3(list_dict_pair_,name,_it)(it, *list); \
|
||||
while (!M_C3(list_dict_pair_,name,_end_p)(it)) { \
|
||||
M_IF_DEBUG(M_C3(dict_pair_,name,_ptr) pair = *M_C3(list_dict_pair_,name,_ref)(it);) \
|
||||
@@ -292,7 +292,7 @@
|
||||
hash = hash & (M_C3(array_list_dict_pair_,name,_size)(map->table) - 1); \
|
||||
M_C3(list_dict_pair_,name,_t) *list_ptr = \
|
||||
M_C3(array_list_dict_pair_,name,_get)(map->table, hash); \
|
||||
M_C3(list_it_dict_pair_,name,_t) it; \
|
||||
M_C3(list_dict_pair_,name,_it_t) it; \
|
||||
for(M_C3(list_dict_pair_,name,_it)(it, *list_ptr); \
|
||||
!M_C3(list_dict_pair_,name,_end_p)(it); \
|
||||
M_C3(list_dict_pair_,name,_next)(it)) { \
|
||||
@@ -320,7 +320,7 @@
|
||||
hash = hash & (M_C3(array_list_dict_pair_,name,_size)(map->table) - 1); \
|
||||
M_C3(list_dict_pair_,name,_t) *list_ptr = \
|
||||
M_C3(array_list_dict_pair_,name,_get)(map->table, hash); \
|
||||
M_C3(list_it_dict_pair_,name,_t) it; \
|
||||
M_C3(list_dict_pair_,name,_it_t) it; \
|
||||
for(M_C3(list_dict_pair_,name,_it)(it, *list_ptr); \
|
||||
!M_C3(list_dict_pair_,name,_end_p)(it); \
|
||||
M_C3(list_dict_pair_,name,_next)(it)) { \
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
USAGE: LIST_DEF(name, type [, oplist_of_the_type]) */
|
||||
#define LIST_DEF(name, ...) \
|
||||
M_IF_NARGS_EQ1(__VA_ARGS__) \
|
||||
(LISTI_DEF2(name, __VA_ARGS__, M_DEFAULT_OPLIST, M_C3(list_, name,_t), M_C3(list_it_, name,_t) ), \
|
||||
LISTI_DEF2(name, __VA_ARGS__, M_C3(list_, name,_t), M_C3(list_it_, name,_t) ))
|
||||
(LISTI_DEF2(name, __VA_ARGS__, M_DEFAULT_OPLIST, M_C(name,_t), M_C(name, _it_t) ), \
|
||||
LISTI_DEF2(name, __VA_ARGS__, M_C(name,_t), M_C(name, _it_t) ))
|
||||
|
||||
/* Define the oplist of a list of type.
|
||||
USAGE: LIST_OPLIST(name [, oplist_of_the_type]) */
|
||||
@@ -50,119 +50,124 @@
|
||||
/********************************** INTERNAL ************************************/
|
||||
|
||||
#define LISTI_OPLIST(name, oplist) \
|
||||
(INIT(M_C3(list_, name, _init)), \
|
||||
INIT_SET(M_C3(list_, name, _init_set)), \
|
||||
SET(M_C3(list_, name, _set)), \
|
||||
CLEAR(M_C3(list_, name, _clear)), \
|
||||
MOVE(M_C3(list_, name, _move)), \
|
||||
INIT_MOVE(M_C3(list_, name, _init_move)), \
|
||||
SWAP(M_C3(list_, name, _swap)), \
|
||||
TYPE(M_C3(list_,name,_t)), \
|
||||
SUBTYPE(M_C3(list_type_,name,_t)), \
|
||||
IT_TYPE(M_C3(list_it_,name,_t)), \
|
||||
IT_FIRST(M_C3(list_,name,_it)), \
|
||||
IT_END(M_C3(list_,name,_it_end)), \
|
||||
IT_SET(M_C3(list_,name,_it_set)), \
|
||||
IT_END_P(M_C3(list_,name,_end_p)), \
|
||||
IT_EQUAL_P(M_C3(list_,name,_it_equal_p)), \
|
||||
IT_LAST_P(M_C3(list_,name,_last_p)), \
|
||||
IT_NEXT(M_C3(list_,name,_next)), \
|
||||
IT_REF(M_C3(list_,name,_ref)), \
|
||||
IT_CREF(M_C3(list_,name,_cref)), \
|
||||
IT_REMOVE(M_C3(list_,name,_remove)), \
|
||||
CLEAN(M_C3(list_,name,_clean)), \
|
||||
PUSH(M_C3(list_,name,_push_back)), \
|
||||
POP(M_C3(list_,name,_pop_back)) \
|
||||
,REVERSE(M_C3(list_,name,_reverse)) \
|
||||
(INIT(M_C(name, _init)), \
|
||||
INIT_SET(M_C(name, _init_set)), \
|
||||
SET(M_C(name, _set)), \
|
||||
CLEAR(M_C(name, _clear)), \
|
||||
MOVE(M_C(name, _move)), \
|
||||
INIT_MOVE(M_C(name, _init_move)), \
|
||||
SWAP(M_C(name, _swap)), \
|
||||
TYPE(M_C(name,_t)), \
|
||||
SUBTYPE(M_C(name, _type_t)), \
|
||||
IT_TYPE(M_C(name, _it_t)), \
|
||||
IT_FIRST(M_C(name,_it)), \
|
||||
IT_END(M_C(name,_it_end)), \
|
||||
IT_SET(M_C(name,_it_set)), \
|
||||
IT_END_P(M_C(name,_end_p)), \
|
||||
IT_EQUAL_P(M_C(name,_it_equal_p)), \
|
||||
IT_LAST_P(M_C(name,_last_p)), \
|
||||
IT_NEXT(M_C(name,_next)), \
|
||||
IT_REF(M_C(name,_ref)), \
|
||||
IT_CREF(M_C(name,_cref)), \
|
||||
IT_REMOVE(M_C(name,_remove)), \
|
||||
CLEAN(M_C(name,_clean)), \
|
||||
PUSH(M_C(name,_push_back)), \
|
||||
POP(M_C(name,_pop_back)) \
|
||||
,REVERSE(M_C(name,_reverse)) \
|
||||
,OPLIST(oplist) \
|
||||
,M_IF_METHOD(GET_STR, oplist)(GET_STR(M_C3(list_, name, _get_str)),) \
|
||||
,M_IF_METHOD(OUT_STR, oplist)(OUT_STR(M_C3(list_, name, _out_str)),) \
|
||||
,M_IF_METHOD(IN_STR, oplist)(IN_STR(M_C3(list_, name, _in_str)),) \
|
||||
,M_IF_METHOD(EQUAL, oplist)(EQUAL(M_C3(list_, name, _equal_p)),) \
|
||||
,M_IF_METHOD(HASH, oplist)(HASH(M_C3(list_, name, _hash)),) \
|
||||
,M_IF_METHOD(GET_STR, oplist)(GET_STR(M_C(name, _get_str)),) \
|
||||
,M_IF_METHOD(OUT_STR, oplist)(OUT_STR(M_C(name, _out_str)),) \
|
||||
,M_IF_METHOD(IN_STR, oplist)(IN_STR(M_C(name, _in_str)),) \
|
||||
,M_IF_METHOD(EQUAL, oplist)(EQUAL(M_C(name, _equal_p)),) \
|
||||
,M_IF_METHOD(HASH, oplist)(HASH(M_C(name, _hash)),) \
|
||||
,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW oplist),) \
|
||||
,M_IF_METHOD(REALLOC, oplist)(REALLOC(M_GET_REALLOC oplist),) \
|
||||
,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL oplist),) \
|
||||
)
|
||||
|
||||
#define LISTI_DEF2(name, type, oplist, list_t, list_it_t) \
|
||||
typedef struct M_C3(list_, name, _s) { \
|
||||
struct M_C3(list_, name, _s) *next; \
|
||||
\
|
||||
typedef struct M_C(name, _s) { \
|
||||
struct M_C(name, _s) *next; \
|
||||
type data; \
|
||||
} *list_t[1]; \
|
||||
\
|
||||
typedef type M_C(name, _type_t); \
|
||||
\
|
||||
typedef type M_C3(list_type_,name, _t); \
|
||||
\
|
||||
typedef struct M_C3(list_it_, name, _s) { \
|
||||
struct M_C3(list_, name, _s) *previous; \
|
||||
typedef struct M_C(name, _it_s) { \
|
||||
struct M_C(name, _s) *previous; \
|
||||
list_t l; \
|
||||
} list_it_t[1]; \
|
||||
\
|
||||
/* If MEMPOOL is required, we need to define it */ \
|
||||
/* Define alloc functions. If MEMPOOL, we need to define it */ \
|
||||
M_IF_METHOD(MEMPOOL, oplist)( \
|
||||
MEMPOOL_DEF(M_C(mempool_list_,name), struct M_C3(list_, name, _s)) \
|
||||
M_GET_MEMPOOL_LINKAGE oplist M_C3(mempool_list_, name, _t) M_GET_MEMPOOL oplist; \
|
||||
static inline struct M_C3(list_, name, _s) *M_C3(listi_,name,_new)(void) { \
|
||||
return M_C3(mempool_list_, name, _alloc)(M_GET_MEMPOOL oplist); \
|
||||
\
|
||||
MEMPOOL_DEF(M_C(name, mempool_list), struct M_C(name, _s)) \
|
||||
M_GET_MEMPOOL_LINKAGE oplist M_C(name, mempool_list_t) M_GET_MEMPOOL oplist; \
|
||||
static inline struct M_C(name, _s) *M_C(name, _int_new)(void) { \
|
||||
return M_C(name, mempool_list_alloc)(M_GET_MEMPOOL oplist); \
|
||||
} \
|
||||
static inline void M_C3(listi_,name,_del)(struct M_C3(list_, name, _s) *ptr) { \
|
||||
M_C3(mempool_list_, name, _free)(M_GET_MEMPOOL oplist, ptr); \
|
||||
static inline void M_C(name,_int_del)(struct M_C(name, _s) *ptr) { \
|
||||
M_C(name, mempool_list_free)(M_GET_MEMPOOL oplist, ptr); \
|
||||
} \
|
||||
LISTI_DEF3(name, type, oplist, list_t, list_it_t) \
|
||||
\
|
||||
, /* No mempool allocation */ \
|
||||
static inline struct M_C3(list_, name, _s) *M_C3(listi_,name,_new)(void) { \
|
||||
return M_GET_NEW oplist (struct M_C3(list_, name, _s)); \
|
||||
\
|
||||
static inline struct M_C(name, _s) *M_C(name, _int_new)(void) { \
|
||||
return M_GET_NEW oplist (struct M_C(name, _s)); \
|
||||
} \
|
||||
static inline void M_C3(listi_,name,_del)(struct M_C3(list_, name, _s) *ptr) { \
|
||||
static inline void M_C(name,_int_del)(struct M_C(name, _s) *ptr) { \
|
||||
M_GET_DEL oplist (ptr); \
|
||||
} \
|
||||
LISTI_DEF3(name, type, oplist, list_t, list_it_t) )
|
||||
) \
|
||||
\
|
||||
LISTI_DEF3(name, type, oplist, list_t, list_it_t) \
|
||||
|
||||
|
||||
#define LISTI_DEF3(name, type, oplist, list_t, list_it_t) \
|
||||
\
|
||||
\
|
||||
static inline void \
|
||||
M_C3(list_, name, _init)(list_t v) \
|
||||
M_C(name, _init)(list_t v) \
|
||||
{ \
|
||||
assert( v != NULL); \
|
||||
*v = NULL; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline void \
|
||||
M_C3(list_, name, _clean)(list_t v) \
|
||||
M_C(name, _clean)(list_t v) \
|
||||
{ \
|
||||
assert (v != NULL); \
|
||||
struct M_C3(list_, name, _s) *it = *v; \
|
||||
struct M_C(name, _s) *it = *v; \
|
||||
*v = NULL; \
|
||||
while (it != NULL) { \
|
||||
struct M_C3(list_, name, _s) *next = it->next; \
|
||||
struct M_C(name, _s) *next = it->next; \
|
||||
M_GET_CLEAR oplist(it->data); \
|
||||
M_C3(listi_,name,_del)(it); \
|
||||
M_C(name,_int_del)(it); \
|
||||
it = next; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline void \
|
||||
M_C3(list_, name, _clear)(list_t v) \
|
||||
M_C(name, _clear)(list_t v) \
|
||||
{ \
|
||||
M_C3(list_, name, _clean)(v); \
|
||||
M_C(name, _clean)(v); \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline const type * \
|
||||
M_C3(list_, name, _back)(const list_t v) \
|
||||
M_C(name, _back)(const list_t v) \
|
||||
{ \
|
||||
assert(v != NULL && *v != NULL); \
|
||||
return M_CONST_CAST(type, &((*v)->data)); \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline type * \
|
||||
M_C3(list_, name, _push_raw)(list_t v) \
|
||||
M_C(name, _push_raw)(list_t v) \
|
||||
{ \
|
||||
assert (v != NULL); \
|
||||
struct M_C3(list_, name, _s) *next; \
|
||||
next = M_C3(listi_,name,_new)(); \
|
||||
struct M_C(name, _s) *next; \
|
||||
next = M_C(name, _int_new)(); \
|
||||
if (M_UNLIKELY (next == NULL)) { \
|
||||
M_MEMORY_FULL(sizeof (struct M_C3(list_, name, _s))); \
|
||||
M_MEMORY_FULL(sizeof (struct M_C(name, _s))); \
|
||||
return NULL; \
|
||||
} \
|
||||
type *ret = &next->data; \
|
||||
@@ -170,157 +175,156 @@
|
||||
*v = next; \
|
||||
return ret; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline void \
|
||||
M_C3(list_, name, _push_back)(list_t v, type const x) \
|
||||
M_C(name, _push_back)(list_t v, type const x) \
|
||||
{ \
|
||||
type *data = M_C3(list_, name, _push_raw)(v); \
|
||||
type *data = M_C(name, _push_raw)(v); \
|
||||
if (M_UNLIKELY (data == NULL)) \
|
||||
return; \
|
||||
M_GET_INIT_SET oplist(*data, x); \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline type * \
|
||||
M_C3(list_, name, _push_new)(list_t v) \
|
||||
M_C(name, _push_new)(list_t v) \
|
||||
{ \
|
||||
type *data = M_C3(list_, name, _push_raw)(v); \
|
||||
type *data = M_C(name, _push_raw)(v); \
|
||||
if (M_UNLIKELY (data == NULL)) \
|
||||
return NULL; \
|
||||
M_GET_INIT oplist(*data); \
|
||||
return data; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline void \
|
||||
M_C3(list_, name, _pop_back)(type *data, list_t v) \
|
||||
M_C(name, _pop_back)(type *data, list_t v) \
|
||||
{ \
|
||||
assert(v != NULL && *v != NULL); \
|
||||
if (data != NULL) { \
|
||||
M_GET_SET oplist(*data, (*v)->data); \
|
||||
} \
|
||||
M_GET_CLEAR oplist((*v)->data); \
|
||||
struct M_C3(list_, name, _s) *tofree = *v; \
|
||||
struct M_C(name, _s) *tofree = *v; \
|
||||
*v = (*v)->next; \
|
||||
M_C3(listi_,name,_del)(tofree); \
|
||||
M_C(name,_int_del)(tofree); \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline bool \
|
||||
M_C3(list_, name, _empty_p)(const list_t v) \
|
||||
M_C(name, _empty_p)(const list_t v) \
|
||||
{ \
|
||||
assert (v!= NULL); \
|
||||
return *v == NULL; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline void \
|
||||
M_C3(list_, name, _swap)(list_t l, list_t v) \
|
||||
M_C(name, _swap)(list_t l, list_t v) \
|
||||
{ \
|
||||
assert (v != NULL && l != NULL); \
|
||||
struct M_C3(list_, name, _s) *tmp = *l; \
|
||||
struct M_C(name, _s) *tmp = *l; \
|
||||
*l = *v; \
|
||||
*v = tmp; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline void \
|
||||
M_C3(list_, name, _it)(list_it_t l, const list_t v) \
|
||||
M_C(name, _it)(list_it_t l, const list_t v) \
|
||||
{ \
|
||||
assert (v != NULL && l[0].l != NULL); \
|
||||
l[0].l[0] = *v; \
|
||||
l[0].previous = NULL; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline void \
|
||||
M_C3(list_, name, _it_set)(list_it_t it1, const list_it_t it2) \
|
||||
M_C(name, _it_set)(list_it_t it1, const list_it_t it2) \
|
||||
{ \
|
||||
assert (it1 != NULL && it2 != NULL); \
|
||||
it1[0].l[0] = it2[0].l[0]; \
|
||||
it1[0].previous = it2[0].previous; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline void \
|
||||
M_C3(list_, name, _it_end)(list_it_t it1, const list_t v) \
|
||||
M_C(name, _it_end)(list_it_t it1, const list_t v) \
|
||||
{ \
|
||||
assert (it1 != NULL && v != NULL); \
|
||||
(void)v; /* unused */ \
|
||||
it1[0].l[0] = NULL; \
|
||||
it1[0].previous = NULL; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline bool \
|
||||
M_C3(list_, name, _end_p)(const list_it_t v) \
|
||||
M_C(name, _end_p)(const list_it_t v) \
|
||||
{ \
|
||||
assert (v!= NULL); \
|
||||
return v[0].l[0] == NULL; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline bool \
|
||||
M_C3(list_, name, _last_p)(const list_it_t v) \
|
||||
M_C(name, _last_p)(const list_it_t v) \
|
||||
{ \
|
||||
assert (v!= NULL); \
|
||||
return v[0].l[0] == NULL || v[0].l[0]->next == NULL; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline void \
|
||||
M_C3(list_, name, _next)(list_it_t tail) \
|
||||
M_C(name, _next)(list_it_t tail) \
|
||||
{ \
|
||||
assert(tail != NULL && tail[0].l[0] != NULL); \
|
||||
tail[0].previous = tail[0].l[0]; \
|
||||
tail[0].l[0] = tail[0].l[0]->next; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline bool \
|
||||
M_C3(list_, name, _it_equal_p)(const list_it_t it1, const list_it_t it2) \
|
||||
M_C(name, _it_equal_p)(const list_it_t it1, const list_it_t it2) \
|
||||
{ \
|
||||
assert(it1 != NULL && it2 != NULL); \
|
||||
return it1[0].l[0] == it2[0].l[0]; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline type * \
|
||||
M_C3(list_, name, _ref)(const list_it_t v) \
|
||||
M_C(name, _ref)(const list_it_t v) \
|
||||
{ \
|
||||
assert(v != NULL && v[0].l[0] != NULL); \
|
||||
return &(v[0].l[0]->data); \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline const type * \
|
||||
M_C3(list_, name, _cref)(const list_it_t v) \
|
||||
M_C(name, _cref)(const list_it_t v) \
|
||||
{ \
|
||||
assert(v != NULL && v[0].l[0] != NULL); \
|
||||
return M_CONST_CAST(type, &(v[0].l[0]->data)); \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline size_t \
|
||||
M_C3(list_, name, _size)(const list_t list) \
|
||||
M_C(name, _size)(const list_t list) \
|
||||
{ \
|
||||
assert (list != NULL); \
|
||||
size_t size = 0; \
|
||||
/* FIXME: Store size field within the list to be faster? */ \
|
||||
struct M_C3(list_, name, _s) *it = *list; \
|
||||
struct M_C(name, _s) *it = *list; \
|
||||
while (it != NULL) { \
|
||||
size ++; \
|
||||
it = it->next; \
|
||||
} \
|
||||
return size; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline bool \
|
||||
M_C3(list_, name, _sublist_p)(const list_t list, \
|
||||
const list_it_t sublist) \
|
||||
M_C(name, _sublist_p)(const list_t list, \
|
||||
const list_it_t sublist) \
|
||||
{ \
|
||||
assert (list != NULL && sublist != NULL); \
|
||||
struct M_C3(list_, name, _s) *it = *list; \
|
||||
struct M_C(name, _s) *it = *list; \
|
||||
while (it != NULL) { \
|
||||
if (it == sublist[0].l[0]) return true; \
|
||||
it = it->next; \
|
||||
} \
|
||||
return (sublist[0].l[0] == NULL); \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline type * \
|
||||
M_C3(list_, name, _get)(const list_t list, size_t i) \
|
||||
M_C(name, _get)(const list_t list, size_t i) \
|
||||
{ \
|
||||
assert (list != NULL); \
|
||||
struct M_C3(list_, name, _s) *it = *list; \
|
||||
struct M_C(name, _s) *it = *list; \
|
||||
/* FIXME: How to avoid the double iteration over the list? */ \
|
||||
size_t len = M_C3(list_,name,_size)(list); \
|
||||
size_t len = M_C(name,_size)(list); \
|
||||
assert (i < len); \
|
||||
size_t j = len-1; \
|
||||
while (true) { \
|
||||
@@ -330,24 +334,24 @@
|
||||
j--; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline const type * \
|
||||
M_C3(list_, name, _cget)(const list_t l, size_t i) \
|
||||
M_C(name, _cget)(const list_t l, size_t i) \
|
||||
{ \
|
||||
return M_CONST_CAST(type, M_C3(list_, name, _get)(l,i)); \
|
||||
return M_CONST_CAST(type, M_C(name, _get)(l,i)); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_C3(list_, name, _insert)(list_t list, \
|
||||
list_it_t insertion_point, \
|
||||
type const x) \
|
||||
M_C(name, _insert)(list_t list, \
|
||||
list_it_t insertion_point, \
|
||||
type const x) \
|
||||
{ \
|
||||
assert (list != NULL && insertion_point != NULL); \
|
||||
assert(M_C3(list_, name, _sublist_p)(list, insertion_point)); \
|
||||
struct M_C3(list_, name, _s) *next; \
|
||||
next = M_C3(listi_,name,_new)(); \
|
||||
assert(M_C(name, _sublist_p)(list, insertion_point)); \
|
||||
struct M_C(name, _s) *next; \
|
||||
next = M_C(name, _int_new)(); \
|
||||
if (M_UNLIKELY (next == NULL)) { \
|
||||
M_MEMORY_FULL(sizeof (struct M_C3(list_, name, _s))); \
|
||||
M_MEMORY_FULL(sizeof (struct M_C(name, _s))); \
|
||||
return; \
|
||||
} \
|
||||
M_GET_INIT_SET oplist(next->data, x); \
|
||||
@@ -359,40 +363,40 @@
|
||||
insertion_point[0].l[0]->next = next; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline void \
|
||||
M_C3(list_, name, _remove)(list_t list, \
|
||||
list_it_t removing_point) \
|
||||
M_C(name, _remove)(list_t list, \
|
||||
list_it_t removing_point) \
|
||||
{ \
|
||||
assert (list != NULL && removing_point != NULL); \
|
||||
assert(removing_point[0].l[0] != NULL); \
|
||||
assert(M_C3(list_, name, _sublist_p)(list, removing_point)); \
|
||||
struct M_C3(list_, name, _s) *next = removing_point[0].l[0]->next; \
|
||||
assert(M_C(name, _sublist_p)(list, removing_point)); \
|
||||
struct M_C(name, _s) *next = removing_point[0].l[0]->next; \
|
||||
if (M_UNLIKELY (removing_point->previous == NULL)) { \
|
||||
*list = next; \
|
||||
} else { \
|
||||
removing_point->previous->next = next; \
|
||||
} \
|
||||
M_GET_CLEAR oplist(removing_point[0].l[0]->data); \
|
||||
M_C3(listi_,name,_del) (removing_point[0].l[0]); \
|
||||
M_C(name,_int_del) (removing_point[0].l[0]); \
|
||||
removing_point[0].l[0] = next; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline void \
|
||||
M_C3(list_, name, _set)(list_t list, const list_t org) \
|
||||
M_C(name, _set)(list_t list, const list_t org) \
|
||||
{ \
|
||||
assert (list != NULL && org != NULL); \
|
||||
struct M_C3(list_, name, _s) *next, *it_org; \
|
||||
struct M_C3(list_, name, _s) **update_list; \
|
||||
struct M_C(name, _s) *next, *it_org; \
|
||||
struct M_C(name, _s) **update_list; \
|
||||
if (list == org) return; \
|
||||
M_C3(list_, name, _clean)(list); \
|
||||
M_C(name, _clean)(list); \
|
||||
update_list = list; \
|
||||
it_org = *org; \
|
||||
while (it_org != NULL) { \
|
||||
next = M_C3(listi_,name,_new)(); \
|
||||
next = M_C(name, _int_new)(); \
|
||||
*update_list = next; \
|
||||
if (M_UNLIKELY (next == NULL)) { \
|
||||
M_MEMORY_FULL(sizeof (struct M_C3(list_, name, _s))); \
|
||||
M_MEMORY_FULL(sizeof (struct M_C(name, _s))); \
|
||||
return; \
|
||||
} \
|
||||
update_list = &next->next; \
|
||||
@@ -401,41 +405,41 @@
|
||||
} \
|
||||
*update_list = NULL; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline void \
|
||||
M_C3(list_, name, _init_set)(list_t list, const list_t org) \
|
||||
M_C(name, _init_set)(list_t list, const list_t org) \
|
||||
{ \
|
||||
assert (list != NULL && org != NULL && list != org); \
|
||||
M_C3(list_, name, _init)(list); \
|
||||
M_C3(list_, name, _set)(list, org); \
|
||||
M_C(name, _init)(list); \
|
||||
M_C(name, _set)(list, org); \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline void \
|
||||
M_C3(list_, name, _init_move)(list_t list, list_t org) \
|
||||
M_C(name, _init_move)(list_t list, list_t org) \
|
||||
{ \
|
||||
assert (list != NULL && org != NULL && list != org); \
|
||||
*list = *org; \
|
||||
*org = NULL; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline void \
|
||||
M_C3(list_, name, _move)(list_t list, list_t org) \
|
||||
M_C(name, _move)(list_t list, list_t org) \
|
||||
{ \
|
||||
assert (list != NULL && org != NULL && list != org); \
|
||||
M_C3(list_, name, _clear)(list); \
|
||||
M_C3(list_, name, _init_move)(list, org); \
|
||||
M_C(name, _clear)(list); \
|
||||
M_C(name, _init_move)(list, org); \
|
||||
} \
|
||||
\
|
||||
\
|
||||
\
|
||||
\
|
||||
static inline void \
|
||||
M_C3(list_, name, _splice_back)(list_t nv, list_t ov, list_it_t it) \
|
||||
M_C(name, _splice_back)(list_t nv, list_t ov, list_it_t it) \
|
||||
{ \
|
||||
assert (nv != NULL && ov != NULL && it != NULL && nv != ov); \
|
||||
assert(it[0].l[0] != NULL); \
|
||||
assert(M_C3(list_, name, _sublist_p)(ov, it)); \
|
||||
assert(M_C(name, _sublist_p)(ov, it)); \
|
||||
/* Remove it from ov */ \
|
||||
struct M_C3(list_, name, _s) *next = it[0].l[0]->next; \
|
||||
struct M_C3(list_, name, _s) *current = it[0].l[0]; \
|
||||
struct M_C(name, _s) *next = it[0].l[0]->next; \
|
||||
struct M_C(name, _s) *current = it[0].l[0]; \
|
||||
if (it->previous == NULL) { \
|
||||
*ov = next; \
|
||||
} else { \
|
||||
@@ -447,26 +451,26 @@
|
||||
current->next = *nv; \
|
||||
*nv = current; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline void \
|
||||
M_C3(list_, name, _splice)(list_t list1, list_t list2) \
|
||||
M_C(name, _splice)(list_t list1, list_t list2) \
|
||||
{ \
|
||||
assert (list1 != NULL && list2 != NULL && list1 != list2); \
|
||||
struct M_C3(list_, name, _s) **update_list = list1; \
|
||||
struct M_C3(list_, name, _s) *it = *list1; \
|
||||
struct M_C(name, _s) **update_list = list1; \
|
||||
struct M_C(name, _s) *it = *list1; \
|
||||
while (it != NULL) { \
|
||||
update_list = &it->next; \
|
||||
it = it->next; \
|
||||
it = it->next; \
|
||||
} \
|
||||
*update_list = *list2; \
|
||||
*list2 = NULL; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline void \
|
||||
M_C3(list_, name, _reverse)(list_t list) \
|
||||
M_C(name, _reverse)(list_t list) \
|
||||
{ \
|
||||
assert (list != NULL); \
|
||||
struct M_C3(list_, name, _s) *previous = NULL, *it = *list, *next; \
|
||||
struct M_C(name, _s) *previous = NULL, *it = *list, *next; \
|
||||
while (it != NULL) { \
|
||||
next = it->next; \
|
||||
it->next = previous; \
|
||||
@@ -475,40 +479,40 @@
|
||||
} \
|
||||
*list = previous; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
M_IF_METHOD(GET_STR, oplist)( \
|
||||
static inline void \
|
||||
M_C3(list_, name, _get_str)(string_t str, const list_t list, \
|
||||
bool append) \
|
||||
M_C(name, _get_str)(string_t str, const list_t list, \
|
||||
bool append) \
|
||||
{ \
|
||||
assert (str != NULL && list != NULL); \
|
||||
(append ? string_cat_str : string_set_str) (str, "["); \
|
||||
M_C3(list_it_, name, _t) it; \
|
||||
for (M_C3(list_, name, _it)(it, list) ; \
|
||||
!M_C3(list_, name, _end_p)(it); \
|
||||
M_C3(list_, name, _next)(it)){ \
|
||||
const type *item = M_C3(list_, name, _cref)(it); \
|
||||
M_C(name, _it_t) it; \
|
||||
for (M_C(name, _it)(it, list) ; \
|
||||
!M_C(name, _end_p)(it); \
|
||||
M_C(name, _next)(it)){ \
|
||||
const type *item = M_C(name, _cref)(it); \
|
||||
M_GET_GET_STR oplist (str, *item, true); \
|
||||
if (!M_C3(list_, name, _last_p)(it)) \
|
||||
if (!M_C(name, _last_p)(it)) \
|
||||
string_push_back (str, M_GET_SEPARATOR oplist); \
|
||||
} \
|
||||
string_push_back (str, ']'); \
|
||||
} \
|
||||
, /* no str */ ) \
|
||||
\
|
||||
\
|
||||
M_IF_METHOD(OUT_STR, oplist)( \
|
||||
static inline void \
|
||||
M_C3(list_, name, _out_str)(FILE *file, const list_t list) \
|
||||
M_C(name, _out_str)(FILE *file, const list_t list) \
|
||||
{ \
|
||||
assert (file != NULL && list != NULL); \
|
||||
fputc ('[', file); \
|
||||
M_C3(list_it_, name, _t) it; \
|
||||
for (M_C3(list_, name, _it)(it, list) ; \
|
||||
!M_C3(list_, name, _end_p)(it); \
|
||||
M_C3(list_, name, _next)(it)){ \
|
||||
const type *item = M_C3(list_, name, _cref)(it); \
|
||||
M_C(name, _it_t) it; \
|
||||
for (M_C(name, _it)(it, list) ; \
|
||||
!M_C(name, _end_p)(it); \
|
||||
M_C(name, _next)(it)){ \
|
||||
const type *item = M_C(name, _cref)(it); \
|
||||
M_GET_OUT_STR oplist (file, *item); \
|
||||
if (!M_C3(list_, name, _last_p)(it)) \
|
||||
if (!M_C(name, _last_p)(it)) \
|
||||
fputc (M_GET_SEPARATOR oplist, file); \
|
||||
} \
|
||||
fputc (']', file); \
|
||||
@@ -517,10 +521,10 @@
|
||||
\
|
||||
M_IF_METHOD(IN_STR, oplist)( \
|
||||
static inline bool \
|
||||
M_C3(list_, name, _in_str)(list_t list, FILE *file) \
|
||||
M_C(name, _in_str)(list_t list, FILE *file) \
|
||||
{ \
|
||||
assert (file != NULL && list != NULL); \
|
||||
M_C3(list_, name,_clean)(list); \
|
||||
M_C(name,_clean)(list); \
|
||||
char c = fgetc(file); \
|
||||
if (c != '[') return false; \
|
||||
c = fgetc(file); \
|
||||
@@ -532,55 +536,55 @@
|
||||
bool b = M_GET_IN_STR oplist (item, file); \
|
||||
c = fgetc(file); \
|
||||
if (!b) { break; } \
|
||||
M_C3(list_, name, _push_back)(list, item); \
|
||||
M_C(name, _push_back)(list, item); \
|
||||
} while (c == M_GET_SEPARATOR oplist && !feof(file) && !ferror(file)); \
|
||||
M_GET_CLEAR oplist (item); \
|
||||
M_C3(list_, name, _reverse)(list); \
|
||||
M_C(name, _reverse)(list); \
|
||||
return c == ']'; \
|
||||
} \
|
||||
, /* no in_str */ ) \
|
||||
\
|
||||
M_IF_METHOD(EQUAL, oplist)( \
|
||||
static inline bool \
|
||||
M_C3(list_, name, _equal_p)(const list_t list1, const list_t list2) \
|
||||
M_C(name, _equal_p)(const list_t list1, const list_t list2) \
|
||||
{ \
|
||||
assert (list1 != NULL && list2 != NULL); \
|
||||
M_C3(list_it_, name, _t) it1; \
|
||||
M_C3(list_it_, name, _t) it2; \
|
||||
M_C(name, _it_t) it1; \
|
||||
M_C(name, _it_t) it2; \
|
||||
if (list1 == list2) return true; \
|
||||
M_C3(list_, name, _it)(it1, list1); \
|
||||
M_C3(list_, name, _it)(it2, list2); \
|
||||
while (!M_C3(list_, name, _end_p)(it1) \
|
||||
&&!M_C3(list_, name, _end_p)(it2)) { \
|
||||
const type *item1 = M_C3(list_, name, _cref)(it1); \
|
||||
const type *item2 = M_C3(list_, name, _cref)(it2); \
|
||||
M_C(name, _it)(it1, list1); \
|
||||
M_C(name, _it)(it2, list2); \
|
||||
while (!M_C(name, _end_p)(it1) \
|
||||
&&!M_C(name, _end_p)(it2)) { \
|
||||
const type *item1 = M_C(name, _cref)(it1); \
|
||||
const type *item2 = M_C(name, _cref)(it2); \
|
||||
bool b = M_GET_EQUAL oplist (*item1, *item2); \
|
||||
if (!b) return false; \
|
||||
M_C3(list_, name, _next)(it1); \
|
||||
M_C3(list_, name, _next)(it2); \
|
||||
M_C(name, _next)(it1); \
|
||||
M_C(name, _next)(it2); \
|
||||
} \
|
||||
return M_C3(list_, name, _end_p)(it1) \
|
||||
&& M_C3(list_, name, _end_p)(it2); \
|
||||
return M_C(name, _end_p)(it1) \
|
||||
&& M_C(name, _end_p)(it2); \
|
||||
} \
|
||||
, /* no equal */ ) \
|
||||
\
|
||||
\
|
||||
M_IF_METHOD(HASH, oplist)( \
|
||||
static inline size_t \
|
||||
M_C3(list_, name, _hash)(const list_t list) \
|
||||
M_C(name, _hash)(const list_t list) \
|
||||
{ \
|
||||
assert (list != NULL); \
|
||||
M_HASH_DECL(hash); \
|
||||
M_C3(list_it_, name, _t) it; \
|
||||
for(M_C3(list_, name, _it)(it, list) ; \
|
||||
!M_C3(list_, name, _end_p)(it); \
|
||||
M_C3(list_, name, _next)(it)) { \
|
||||
const type *item = M_C3(list_, name, _cref)(it); \
|
||||
M_C(name, _it_t) it; \
|
||||
for(M_C(name, _it)(it, list) ; \
|
||||
!M_C(name, _end_p)(it); \
|
||||
M_C(name, _next)(it)) { \
|
||||
const type *item = M_C(name, _cref)(it); \
|
||||
size_t hi = M_GET_HASH oplist (*item); \
|
||||
M_HASH_UP(hash, hi); \
|
||||
} \
|
||||
return hash; \
|
||||
} \
|
||||
, /* no hash */ ) \
|
||||
\
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
+10
-10
@@ -4,16 +4,16 @@
|
||||
#include "m-algo.h"
|
||||
|
||||
ARRAY_DEF(int, int)
|
||||
LIST_DEF(int, int)
|
||||
LIST_DEF(string, string_t, STRING_OPLIST)
|
||||
LIST_DEF(list_int, int)
|
||||
LIST_DEF(list_string, string_t, STRING_OPLIST)
|
||||
|
||||
#include "coverage.h"
|
||||
START_COVERAGE
|
||||
ALGO_DEF(algo_array, ARRAY_OPLIST(int))
|
||||
|
||||
ALGO_DEF(algo_list, LIST_OPLIST(int))
|
||||
ALGO_DEF(algo_list, LIST_OPLIST(list_int))
|
||||
|
||||
ALGO_DEF(algo_string, LIST_OPLIST(string, STRING_OPLIST))
|
||||
ALGO_DEF(algo_string, LIST_OPLIST(list_string, STRING_OPLIST))
|
||||
END_COVERAGE
|
||||
|
||||
int g_min, g_max, g_count;
|
||||
@@ -50,9 +50,9 @@ static void test_list(void)
|
||||
assert( algo_list_count(l, -1) == 0);
|
||||
|
||||
#define f(x) assert((x) >= 0 && (x) < 100);
|
||||
ALGO_MAP(l, LIST_OPLIST(int), f);
|
||||
ALGO_MAP(l, LIST_OPLIST(list_int), f);
|
||||
#define g(y, x) assert((x) >= 0 && (x) < y);
|
||||
ALGO_MAP(l, LIST_OPLIST(int), g, 100);
|
||||
ALGO_MAP(l, LIST_OPLIST(list_int), g, 100);
|
||||
|
||||
int *p = algo_list_min(l);
|
||||
assert(p != NULL && *p == 0);
|
||||
@@ -64,7 +64,7 @@ static void test_list(void)
|
||||
assert(p2 != NULL && *p2 == 99);
|
||||
|
||||
list_int_push_back (l, 3);
|
||||
list_it_int_t it1, it2;
|
||||
list_int_it_t it1, it2;
|
||||
algo_list_find (it1, l, 3);
|
||||
assert (!list_int_end_p (it1));
|
||||
algo_list_find_last (it2, l, 3);
|
||||
@@ -80,7 +80,7 @@ static void test_list(void)
|
||||
|
||||
list_int_clear(l);
|
||||
|
||||
ALGO_INIT_VA(l, LIST_OPLIST(int), 1, 2, 3, 4, 5);
|
||||
ALGO_INIT_VA(l, LIST_OPLIST(list_int), 1, 2, 3, 4, 5);
|
||||
assert (list_int_size(l) == 5);
|
||||
list_int_clear(l);
|
||||
}
|
||||
@@ -206,10 +206,10 @@ static void test_extract(void)
|
||||
array_int_t a;
|
||||
array_int_init(a);
|
||||
#define cond(d) ((d) > 0)
|
||||
ALGO_EXTRACT(a, ARRAY_OPLIST(int), l, LIST_OPLIST(int), cond);
|
||||
ALGO_EXTRACT(a, ARRAY_OPLIST(int), l, LIST_OPLIST(list_int), cond);
|
||||
assert(array_int_size(a) == 99);
|
||||
#define cond2(c, d) ((d) > (c))
|
||||
ALGO_EXTRACT(a, ARRAY_OPLIST(int), l, LIST_OPLIST(int), cond2, 10);
|
||||
ALGO_EXTRACT(a, ARRAY_OPLIST(int), l, LIST_OPLIST(list_int), cond2, 10);
|
||||
assert(array_int_size(a) == 89);
|
||||
|
||||
int dst = 0;
|
||||
|
||||
+8
-8
@@ -50,12 +50,12 @@ static void my_mpz_str(string_t str, const mpz_t z, bool append)
|
||||
|
||||
#include "coverage.h"
|
||||
START_COVERAGE
|
||||
LIST_DEF(uint, unsigned int)
|
||||
LIST_DEF(mpz, mpz_t, (INIT(mpz_init), INIT_SET(mpz_init_set), SET(mpz_set), CLEAR(mpz_clear), \
|
||||
OUT_STR(my_mpz_out_str), IN_STR(my_mpz_in_str), EQUAL(my_mpz_equal_p), \
|
||||
GET_STR(my_mpz_str)))
|
||||
LIST_DEF(list_uint, unsigned int)
|
||||
LIST_DEF(list_mpz, mpz_t, (INIT(mpz_init), INIT_SET(mpz_init_set), SET(mpz_set), CLEAR(mpz_clear), \
|
||||
OUT_STR(my_mpz_out_str), IN_STR(my_mpz_in_str), EQUAL(my_mpz_equal_p), \
|
||||
GET_STR(my_mpz_str)))
|
||||
END_COVERAGE
|
||||
#define LIST_UINT_OPLIST LIST_OPLIST(uint)
|
||||
#define LIST_UINT_OPLIST LIST_OPLIST(list_uint)
|
||||
|
||||
static void test_uint(void)
|
||||
{
|
||||
@@ -79,7 +79,7 @@ static void test_uint(void)
|
||||
assert (*list_uint_cget(v, 500) == 500);
|
||||
assert (*list_uint_cget(v, 999) == 999);
|
||||
|
||||
list_it_uint_t u;
|
||||
list_uint_it_t u;
|
||||
unsigned int s = 0;
|
||||
for(list_uint_it(u, v); !list_uint_end_p(u); list_uint_next(u)) {
|
||||
s += *list_uint_cref(u);
|
||||
@@ -106,7 +106,7 @@ static void test_uint(void)
|
||||
list_uint_pop_back (NULL, v);
|
||||
|
||||
list_uint_t v2;
|
||||
list_it_uint_t u2;
|
||||
list_uint_it_t u2;
|
||||
list_uint_init(v2);
|
||||
list_uint_set(v, v);
|
||||
list_uint_set(v2,v);
|
||||
@@ -235,7 +235,7 @@ static void test_mpz(void)
|
||||
}
|
||||
assert (list_mpz_size(v) == 1000);
|
||||
|
||||
list_it_mpz_t u;
|
||||
list_mpz_it_t u;
|
||||
mpz_set_ui (s, 0);
|
||||
for(list_mpz_it(u, v); !list_mpz_end_p(u); list_mpz_next(u)) {
|
||||
mpz_add (s, s, *list_mpz_cref(u));
|
||||
|
||||
Reference in new issue
Block a user