Provide a way to alter the standard naming convention for the functions

Close #72
This commit is contained in:
Patrick Pelissier committed 2023-04-22 09:33:08 +02:00
1 parent 272a326375
commit 219c62ff5d
24 files changed
+2801 -2758

No files matched your search

+12
View File
@@ -5785,6 +5785,18 @@ It is currently 52 (even if some local macros may have increased this limit).
Return a symbol corresponding to the concatenation of the input arguments. Return a symbol corresponding to the concatenation of the input arguments.
##### M\_F(base, suffix)
Return a function name corresponding to the concatenation of the input arguments.
In developer mode, it can be overrided before inclusion of any header to support user customization of suffix.
To do this you need to define M\_F as M\_OVERRIDE\_F, then define as many suffix macros as needed. As suffix macro shall be named M_OVERRIDE_ ## suffix () and each generated suffix shall start with a comma (preliminary interface).
Example:
#define M_F(a,b) M_OVERRIDE_F(a,b)
#define M_OVERRIDE__clear() , _cleanup ,
#include "m-core.h"
##### M\_INC(number) ##### M\_INC(number)
Increment the number given as argument and return Increment the number given as argument and return
+56 -56
View File
@@ -129,16 +129,16 @@
, /* NO EQUAL */) \ , /* NO EQUAL */) \
\ \
M_ALG0_DEF_FIND_IF(name, container_t, cont_oplist, type_t, type_oplist, it_t, \ M_ALG0_DEF_FIND_IF(name, container_t, cont_oplist, type_t, type_oplist, it_t, \
if, M_C(name,_test_cb_ct), M_C(name,_eq_cb_ct), M_APPLY, M_APPLY) \ if, M_F(name,_test_cb_ct), M_F(name,_eq_cb_ct), M_APPLY, M_APPLY) \
M_IF_FUNCOBJ(M_ALG0_DEF_FIND_IF(name, container_t, cont_oplist, type_t, type_oplist, it_t, \ M_IF_FUNCOBJ(M_ALG0_DEF_FIND_IF(name, container_t, cont_oplist, type_t, type_oplist, it_t, \
fo, M_C(name,_test_obj_t), M_C(name,_eq_obj_t), M_C(name, _test_obj_call), M_C(name, _eq_obj_call))) \ fo, M_F(name,_test_obj_t), M_F(name,_eq_obj_t), M_F(name, _test_obj_call), M_F(name, _eq_obj_call))) \
\ \
M_ALG0_DEF_MAP(name, container_t, cont_oplist, type_t, type_oplist, it_t) \ M_ALG0_DEF_MAP(name, container_t, cont_oplist, type_t, type_oplist, it_t) \
\ \
M_ALG0_DEF_ALL_OF(name, container_t, cont_oplist, type_t, type_oplist, it_t, \ M_ALG0_DEF_ALL_OF(name, container_t, cont_oplist, type_t, type_oplist, it_t, \
_, M_C(name,_test_cb_ct), M_APPLY) \ _, M_F(name,_test_cb_ct), M_APPLY) \
M_IF_FUNCOBJ(M_ALG0_DEF_ALL_OF(name, container_t, cont_oplist, type_t, type_oplist, it_t, \ M_IF_FUNCOBJ(M_ALG0_DEF_ALL_OF(name, container_t, cont_oplist, type_t, type_oplist, it_t, \
_fo_, M_C(name,_test_obj_t), M_C(name,_test_obj_call)) ) \ _fo_, M_F(name,_test_obj_t), M_F(name,_test_obj_call)) ) \
\ \
/* If there is a IT_REF method, we consider the container as modifiable through iterator */ \ /* If there is a IT_REF method, we consider the container as modifiable through iterator */ \
M_IF_METHOD(IT_REF, cont_oplist)( \ M_IF_METHOD(IT_REF, cont_oplist)( \
@@ -167,22 +167,22 @@
* Types remain internal */ * Types remain internal */
#define M_ALG0_DEF_CALLBACK(name, container_t, cont_oplist, type_t, type_oplist, it_t) \ #define M_ALG0_DEF_CALLBACK(name, container_t, cont_oplist, type_t, type_oplist, it_t) \
\ \
typedef bool (*M_C(name, _test_cb_ct))(type_t const); \ typedef bool (*M_F(name, _test_cb_ct))(type_t const); \
typedef bool (*M_C(name, _eq_cb_ct))(type_t const, type_t const); \ typedef bool (*M_F(name, _eq_cb_ct))(type_t const, type_t const); \
typedef int (*M_C(name, _cmp_cb_ct))(type_t const, type_t const); \ typedef int (*M_F(name, _cmp_cb_ct))(type_t const, type_t const); \
typedef void (*M_C(name, _transform_cb_ct))(type_t *, type_t const); \ typedef void (*M_F(name, _transform_cb_ct))(type_t *, type_t const); \
typedef void (*M_C(name, _apply_cb_ct))(type_t); \ typedef void (*M_F(name, _apply_cb_ct))(type_t); \
/* Define the function objects associated to the algorithms. /* Define the function objects associated to the algorithms.
* Created Function objects are part of the public interface */ * Created Function objects are part of the public interface */
#define M_ALG0_DEF_FUNCOBJ(name, container_t, cont_oplist, type_t, type_oplist, it_t) \ #define M_ALG0_DEF_FUNCOBJ(name, container_t, cont_oplist, type_t, type_oplist, it_t) \
\ \
FUNC_OBJ_ITF_DEF(M_C(name, _test_obj), bool, type_t const) \ FUNC_OBJ_ITF_DEF(M_F(name, _test_obj), bool, type_t const) \
FUNC_OBJ_ITF_DEF(M_C(name, _eq_obj), bool, type_t const, type_t const ) \ FUNC_OBJ_ITF_DEF(M_F(name, _eq_obj), bool, type_t const, type_t const ) \
FUNC_OBJ_ITF_DEF(M_C(name, _cmp_obj), int, type_t const, type_t const ) \ FUNC_OBJ_ITF_DEF(M_F(name, _cmp_obj), int, type_t const, type_t const ) \
FUNC_OBJ_ITF_DEF(M_C(name, _transform_obj), void, type_t *, type_t const ) \ FUNC_OBJ_ITF_DEF(M_F(name, _transform_obj), void, type_t *, type_t const ) \
FUNC_OBJ_ITF_DEF(M_C(name, _apply_obj), void, type_t * ) \ FUNC_OBJ_ITF_DEF(M_F(name, _apply_obj), void, type_t * ) \
/* Define the sort functions with the CMP operator using the order selected */ /* Define the sort functions with the CMP operator using the order selected */
@@ -203,9 +203,9 @@
// Call the created function object // Call the created function object
#define M_ALG0_SORT_CALL_OBJ_P4(name, sort_name, ref1, ref2) \ #define M_ALG0_SORT_CALL_OBJ_P4(name, sort_name, ref1, ref2) \
M_C(name, _cmp_obj_call)(funcobj, *ref1, *ref2) M_F(name, _cmp_obj_call)(funcobj, *ref1, *ref2)
// Adding a parameter named 'funcobj' to the algorithm functions // Adding a parameter named 'funcobj' to the algorithm functions
#define M_ALG0_SORT_PARAM_OBJ_P4(name) M_DEFERRED_COMMA M_C(name, _cmp_obj_t) funcobj #define M_ALG0_SORT_PARAM_OBJ_P4(name) M_DEFERRED_COMMA M_F(name, _cmp_obj_t) funcobj
#define M_ALG0_SORT_ARG_OBJ_P4 M_DEFERRED_COMMA funcobj #define M_ALG0_SORT_ARG_OBJ_P4 M_DEFERRED_COMMA funcobj
@@ -253,7 +253,7 @@
/* - a selection sort */ \ /* - a selection sort */ \
M_IF(M_AND(M_TEST_METHOD_P(SORT, cont_oplist), M_EMPTY_P(cmp_arg)))( \ M_IF(M_AND(M_TEST_METHOD_P(SORT, cont_oplist), M_EMPTY_P(cmp_arg)))( \
/******** OPTIMIZED SORT FOR CONTAINER *********/ \ /******** OPTIMIZED SORT FOR CONTAINER *********/ \
static inline void M_C(name,sort_name)(container_t l) \ static inline void M_F(name,sort_name)(container_t l) \
{ \ { \
M_CALL_SORT(cont_oplist, l, M_C3(name, sort_name,_cmp)); \ M_CALL_SORT(cont_oplist, l, M_C3(name, sort_name,_cmp)); \
} \ } \
@@ -321,7 +321,7 @@
\ \
/* Sort the container 'l' */ \ /* Sort the container 'l' */ \
static inline void \ static inline void \
M_C(name,sort_name)(container_t l cmp_param(name)) \ M_F(name,sort_name)(container_t l cmp_param(name)) \
{ \ { \
container_t l1; \ container_t l1; \
container_t l2; \ container_t l2; \
@@ -353,8 +353,8 @@
M_CALL_INIT(cont_oplist, l1); \ M_CALL_INIT(cont_oplist, l1); \
M_CALL_INIT(cont_oplist, l2); \ M_CALL_INIT(cont_oplist, l2); \
M_C3(name,sort_name,_split)(l1, l2, l); \ M_C3(name,sort_name,_split)(l1, l2, l); \
M_C(name,sort_name)(l1 cmp_arg); \ M_F(name,sort_name)(l1 cmp_arg); \
M_C(name,sort_name)(l2 cmp_arg); \ M_F(name,sort_name)(l2 cmp_arg); \
M_C3(name,sort_name,_merge)(l, l1, l2 cmp_arg); \ M_C3(name,sort_name,_merge)(l, l1, l2 cmp_arg); \
/* l1 & l2 shall be empty now */ \ /* l1 & l2 shall be empty now */ \
M_CALL_CLEAR(cont_oplist, l2); \ M_CALL_CLEAR(cont_oplist, l2); \
@@ -363,7 +363,7 @@
, \ , \
M_IF_METHOD(IT_PREVIOUS, cont_oplist)( \ M_IF_METHOD(IT_PREVIOUS, cont_oplist)( \
/******** GENERIC INSERTION SORT *********/ \ /******** GENERIC INSERTION SORT *********/ \
static inline void M_C(name,sort_name)(container_t l cmp_param(name)) \ static inline void M_F(name,sort_name)(container_t l cmp_param(name)) \
{ \ { \
it_t it1; \ it_t it1; \
it_t it2; \ it_t it2; \
@@ -400,7 +400,7 @@
\ \
, \ , \
/********** GENERIC SELECTION SORT ************/ \ /********** GENERIC SELECTION SORT ************/ \
static inline void M_C(name,sort_name)(container_t l cmp_param(name)) \ static inline void M_F(name,sort_name)(container_t l cmp_param(name)) \
{ \ { \
it_t it1; \ it_t it1; \
it_t it2; \ it_t it2; \
@@ -518,7 +518,7 @@
/* It supposes that the container is not sorted */ \ /* It supposes that the container is not sorted */ \
/* Find the next occurrence from it (included) of data */ \ /* Find the next occurrence from it (included) of data */ \
static inline void \ static inline void \
M_C(name, _find_again) (it_t it, type_t const data) \ M_F(name, _find_again) (it_t it, type_t const data) \
{ \ { \
for ( /*nothing*/ ; !M_CALL_IT_END_P(cont_oplist, it) ; \ for ( /*nothing*/ ; !M_CALL_IT_END_P(cont_oplist, it) ; \
M_CALL_IT_NEXT(cont_oplist, it)) { \ M_CALL_IT_NEXT(cont_oplist, it)) { \
@@ -529,18 +529,18 @@
\ \
/* Find the first occurrence of data */ \ /* Find the first occurrence of data */ \
static inline void \ static inline void \
M_C(name, _find) (it_t it, container_t const l, type_t const data) \ M_F(name, _find) (it_t it, container_t const l, type_t const data) \
{ \ { \
M_CALL_IT_FIRST(cont_oplist, it, l); \ M_CALL_IT_FIRST(cont_oplist, it, l); \
M_C(name, _find_again)(it, data); \ M_F(name, _find_again)(it, data); \
} \ } \
\ \
/* Test if data is within the container */ \ /* Test if data is within the container */ \
static inline bool \ static inline bool \
M_C(name, _contain_p) (container_t const l, type_t const data) \ M_F(name, _contain_p) (container_t const l, type_t const data) \
{ \ { \
it_t it; \ it_t it; \
M_C(name,_find)(it, l, data); \ M_F(name,_find)(it, l, data); \
return !M_CALL_IT_END_P(cont_oplist, it); \ return !M_CALL_IT_END_P(cont_oplist, it); \
} \ } \
\ \
@@ -550,7 +550,7 @@
M_IF_METHOD2(PREVIOUS, IT_LAST, cont_oplist) \ M_IF_METHOD2(PREVIOUS, IT_LAST, cont_oplist) \
( \ ( \
static inline void \ static inline void \
M_C(name, _find_last) (it_t it, container_t const l, type_t const data) \ M_F(name, _find_last) (it_t it, container_t const l, type_t const data) \
{ \ { \
for (M_CALL_IT_LAST(cont_oplist, it, l); \ for (M_CALL_IT_LAST(cont_oplist, it, l); \
!M_CALL_IT_END_P(cont_oplist, it) ; \ !M_CALL_IT_END_P(cont_oplist, it) ; \
@@ -563,7 +563,7 @@
, \ , \
/* Otherwise search forward, but don't stop on the first occurrence */ \ /* Otherwise search forward, but don't stop on the first occurrence */ \
static inline void \ static inline void \
M_C(name, _find_last) (it_t it, container_t const l, type_t const data) \ M_F(name, _find_last) (it_t it, container_t const l, type_t const data) \
{ \ { \
M_CALL_IT_END(cont_oplist, it, l); \ M_CALL_IT_END(cont_oplist, it, l); \
it_t it2; \ it_t it2; \
@@ -579,7 +579,7 @@
\ \
/* Count the number of occurrence of data in the container */ \ /* Count the number of occurrence of data in the container */ \
static inline size_t \ static inline size_t \
M_C(name, _count) (container_t const l, type_t const data) \ M_F(name, _count) (container_t const l, type_t const data) \
{ \ { \
it_t it; \ it_t it; \
size_t count = 0; \ size_t count = 0; \
@@ -595,7 +595,7 @@
\ \
/* Find the next mismatch between the containers */ \ /* Find the next mismatch between the containers */ \
static inline void \ static inline void \
M_C(name, _mismatch_again) (it_t it1, it_t it2) \ M_F(name, _mismatch_again) (it_t it1, it_t it2) \
{ \ { \
for (/* nothing */ ; !M_CALL_IT_END_P(cont_oplist, it1) && \ for (/* nothing */ ; !M_CALL_IT_END_P(cont_oplist, it1) && \
!M_CALL_IT_END_P(cont_oplist, it2); \ !M_CALL_IT_END_P(cont_oplist, it2); \
@@ -609,11 +609,11 @@
\ \
/* Find the first mismatch between the containers */ \ /* Find the first mismatch between the containers */ \
static inline void \ static inline void \
M_C(name, _mismatch) (it_t it1, it_t it2, container_t const l1, container_t const l2 ) \ M_F(name, _mismatch) (it_t it1, it_t it2, container_t const l1, container_t const l2 ) \
{ \ { \
M_CALL_IT_FIRST(cont_oplist, it1, l1); \ M_CALL_IT_FIRST(cont_oplist, it1, l1); \
M_CALL_IT_FIRST(cont_oplist, it2, l2); \ M_CALL_IT_FIRST(cont_oplist, it2, l2); \
M_C(name, _mismatch_again)(it1, it2); \ M_F(name, _mismatch_again)(it1, it2); \
} \ } \
@@ -689,7 +689,7 @@
\ \
/* Fill all the container with value (overwritten) */ \ /* Fill all the container with value (overwritten) */ \
static inline void \ static inline void \
M_C(name, _fill) (container_t l, type_t const value) \ M_F(name, _fill) (container_t l, type_t const value) \
{ \ { \
for M_EACH(item, l, cont_oplist) { \ for M_EACH(item, l, cont_oplist) { \
M_CALL_SET(type_oplist, *item, value); \ M_CALL_SET(type_oplist, *item, value); \
@@ -699,7 +699,7 @@
/* Fill the container with exactly 'n' occurrence of 'value' */ \ /* Fill the container with exactly 'n' occurrence of 'value' */ \
M_IF_METHOD(PUSH, cont_oplist)( \ M_IF_METHOD(PUSH, cont_oplist)( \
static inline void \ static inline void \
M_C(name, _fill_n) (container_t l, size_t n, type_t const value) \ M_F(name, _fill_n) (container_t l, size_t n, type_t const value) \
{ \ { \
M_CALL_RESET(cont_oplist, l); \ M_CALL_RESET(cont_oplist, l); \
for(size_t i = 0; i < n; i++) { \ for(size_t i = 0; i < n; i++) { \
@@ -711,7 +711,7 @@
/* Fill the container with FOR('value'; 'value'+'inc') */ \ /* Fill the container with FOR('value'; 'value'+'inc') */ \
M_IF_METHOD(ADD, type_oplist)( \ M_IF_METHOD(ADD, type_oplist)( \
static inline void \ static inline void \
M_C(name, _fill_a) (container_t l, type_t const value, type_t const inc) \ M_F(name, _fill_a) (container_t l, type_t const value, type_t const inc) \
{ \ { \
type_t tmp; \ type_t tmp; \
M_CALL_INIT_SET(type_oplist, tmp, value); \ M_CALL_INIT_SET(type_oplist, tmp, value); \
@@ -725,7 +725,7 @@
/* Fill the container with n occurences of FOR('value'; 'value'+'inc') */ \ /* Fill the container with n occurences of FOR('value'; 'value'+'inc') */ \
M_IF_METHOD(PUSH, cont_oplist)( \ M_IF_METHOD(PUSH, cont_oplist)( \
static inline void \ static inline void \
M_C(name, _fill_an) (container_t l, size_t n, type_t const value, type_t const inc) \ M_F(name, _fill_an) (container_t l, size_t n, type_t const value, type_t const inc) \
{ \ { \
type_t tmp; \ type_t tmp; \
M_CALL_INIT_SET(type_oplist, tmp, value); \ M_CALL_INIT_SET(type_oplist, tmp, value); \
@@ -745,7 +745,7 @@
\ \
/* Apply func for all elements of the container */ \ /* Apply func for all elements of the container */ \
static inline void \ static inline void \
M_C(name, _for_each) (container_t l, M_C(name, _apply_cb_ct) func) \ M_F(name, _for_each) (container_t l, M_F(name, _apply_cb_ct) func) \
{ \ { \
for M_EACH(item, l, cont_oplist) { \ for M_EACH(item, l, cont_oplist) { \
func(*item); \ func(*item); \
@@ -757,9 +757,9 @@
\ \
/* Apply func for all elements of the container src and push the result in dst */ \ /* Apply func for all elements of the container src and push the result in dst */ \
static inline void \ static inline void \
M_C(name, _transform) (container_t dst, \ M_F(name, _transform) (container_t dst, \
container_t src, \ container_t src, \
M_C(name, _transform_cb_ct) func) \ M_F(name, _transform_cb_ct) func) \
{ \ { \
M_ASSERT(dst != src); \ M_ASSERT(dst != src); \
M_CALL_RESET(cont_oplist, dst); \ M_CALL_RESET(cont_oplist, dst); \
@@ -776,8 +776,8 @@
/* Reduce all elements of the container in dst in function of func */ \ /* Reduce all elements of the container in dst in function of func */ \
M_IF_METHOD(SET, type_oplist)( \ M_IF_METHOD(SET, type_oplist)( \
static inline void \ static inline void \
M_C(name, _reduce) (type_t *dest, container_t const l, \ M_F(name, _reduce) (type_t *dest, container_t const l, \
M_C(name, _transform_cb_ct) func) \ M_F(name, _transform_cb_ct) func) \
{ \ { \
bool initDone = false; \ bool initDone = false; \
for M_EACH(item, l, cont_oplist) { \ for M_EACH(item, l, cont_oplist) { \
@@ -794,10 +794,10 @@
/* Reduce all transformed elements of the container in dst in function of func */ \ /* Reduce all transformed elements of the container in dst in function of func */ \
M_IF_METHOD(INIT, type_oplist)( \ M_IF_METHOD(INIT, type_oplist)( \
static inline \ static inline \
void M_C(name, _map_reduce) (type_t *dest, \ void M_F(name, _map_reduce) (type_t *dest, \
const container_t l, \ const container_t l, \
M_C(name, _transform_cb_ct) redFunc, \ M_F(name, _transform_cb_ct) redFunc, \
M_C(name, _transform_cb_ct) mapFunc) \ M_F(name, _transform_cb_ct) mapFunc) \
{ \ { \
bool initDone = false; \ bool initDone = false; \
type_t tmp; \ type_t tmp; \
@@ -857,7 +857,7 @@
#define M_ALG0_DEF_MINMAX(name, container_t, cont_oplist, type_t, type_oplist, it_t) \ #define M_ALG0_DEF_MINMAX(name, container_t, cont_oplist, type_t, type_oplist, it_t) \
\ \
static inline type_t * \ static inline type_t * \
M_C(name, _min) (const container_t l) \ M_F(name, _min) (const container_t l) \
{ \ { \
type_t *min = NULL; \ type_t *min = NULL; \
for M_EACH(cref, l, cont_oplist) { \ for M_EACH(cref, l, cont_oplist) { \
@@ -870,7 +870,7 @@
} \ } \
\ \
static inline type_t * \ static inline type_t * \
M_C(name, _max) (const container_t l) \ M_F(name, _max) (const container_t l) \
{ \ { \
type_t *max = NULL; \ type_t *max = NULL; \
for M_EACH(cref, l, cont_oplist) { \ for M_EACH(cref, l, cont_oplist) { \
@@ -883,7 +883,7 @@
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _minmax) (type_t **min_p, type_t **max_p, \ M_F(name, _minmax) (type_t **min_p, type_t **max_p, \
const container_t l) \ const container_t l) \
{ \ { \
type_t *min = NULL; \ type_t *min = NULL; \
@@ -906,11 +906,11 @@
#define M_ALG0_DEF_REMOVE(name, container_t, cont_oplist, type_t, type_oplist, it_t) \ #define M_ALG0_DEF_REMOVE(name, container_t, cont_oplist, type_t, type_oplist, it_t) \
\ \
static inline void \ static inline void \
M_C(name, _uniq)(container_t l) \ M_F(name, _uniq)(container_t l) \
{ \ { \
it_t it1; \ it_t it1; \
it_t it2; \ it_t it2; \
M_ASSERT(M_C(name, _sort_p)(l)); \ M_ASSERT(M_F(name, _sort_p)(l)); \
M_CALL_IT_FIRST(cont_oplist, it1, l); \ M_CALL_IT_FIRST(cont_oplist, it1, l); \
M_CALL_IT_SET(cont_oplist, it2, it1); \ M_CALL_IT_SET(cont_oplist, it2, it1); \
M_CALL_IT_NEXT(cont_oplist, it2); \ M_CALL_IT_NEXT(cont_oplist, it2); \
@@ -928,7 +928,7 @@
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _remove_val)(container_t l, type_t const val) \ M_F(name, _remove_val)(container_t l, type_t const val) \
{ \ { \
it_t it1; \ it_t it1; \
M_CALL_IT_FIRST(cont_oplist, it1, l); \ M_CALL_IT_FIRST(cont_oplist, it1, l); \
@@ -943,7 +943,7 @@
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _remove_if)(container_t l, M_C(name, _test_cb_ct) func) \ M_F(name, _remove_if)(container_t l, M_F(name, _test_cb_ct) func) \
{ \ { \
it_t it1; \ it_t it1; \
M_CALL_IT_FIRST(cont_oplist, it1, l); \ M_CALL_IT_FIRST(cont_oplist, it1, l); \
@@ -961,7 +961,7 @@
#define M_ALG0_DEF_VECTOR(name, container_t, cont_oplist, type_t, type_oplist, it_t) \ #define M_ALG0_DEF_VECTOR(name, container_t, cont_oplist, type_t, type_oplist, it_t) \
\ \
M_IF_METHOD(ADD, type_oplist)( \ M_IF_METHOD(ADD, type_oplist)( \
static inline void M_C(name, _add) (container_t dst, const container_t src) \ static inline void M_F(name, _add) (container_t dst, const container_t src) \
{ \ { \
it_t itSrc; \ it_t itSrc; \
it_t itDst; \ it_t itDst; \
@@ -979,7 +979,7 @@
, /* NO_ADD METHOD */ ) \ , /* NO_ADD METHOD */ ) \
\ \
M_IF_METHOD(SUB, type_oplist)( \ M_IF_METHOD(SUB, type_oplist)( \
static inline void M_C(name, _sub) (container_t dst, const container_t src) \ static inline void M_F(name, _sub) (container_t dst, const container_t src) \
{ \ { \
it_t itSrc; \ it_t itSrc; \
it_t itDst; \ it_t itDst; \
@@ -997,7 +997,7 @@
, /* NO_SUB METHOD */ ) \ , /* NO_SUB METHOD */ ) \
\ \
M_IF_METHOD(MUL, type_oplist)( \ M_IF_METHOD(MUL, type_oplist)( \
static inline void M_C(name, _mul) (container_t dst, const container_t src) \ static inline void M_F(name, _mul) (container_t dst, const container_t src) \
{ \ { \
it_t itSrc; \ it_t itSrc; \
it_t itDst; \ it_t itDst; \
@@ -1015,7 +1015,7 @@
, /* NO_MUL METHOD */ ) \ , /* NO_MUL METHOD */ ) \
\ \
M_IF_METHOD(DIV, type_oplist)( \ M_IF_METHOD(DIV, type_oplist)( \
static inline void M_C(name, _div) (container_t dst, const container_t src) \ static inline void M_F(name, _div) (container_t dst, const container_t src) \
{ \ { \
it_t itSrc; \ it_t itSrc; \
it_t itDst; \ it_t itDst; \
+143 -143
View File
@@ -30,7 +30,7 @@
/* Define a dynamic array of the given type and its associated functions. /* Define a dynamic array of the given type and its associated functions.
USAGE: ARRAY_DEF(name, type [, oplist_of_the_type]) */ USAGE: ARRAY_DEF(name, type [, oplist_of_the_type]) */
#define M_ARRAY_DEF(name, ...) \ #define M_ARRAY_DEF(name, ...) \
M_ARRAY_DEF_AS(name, M_C(name,_t), M_C(name,_it_t), __VA_ARGS__) M_ARRAY_DEF_AS(name, M_F(name,_t), M_F(name,_it_t), __VA_ARGS__)
/* Define a dynamic array of the given type and its associated functions /* Define a dynamic array of the given type and its associated functions
@@ -81,56 +81,56 @@
/* FIXME: Do we want to export some methods as they are slow and /* FIXME: Do we want to export some methods as they are slow and
are not fit to be used for building other methods (like _it_remove)? */ are not fit to be used for building other methods (like _it_remove)? */
#define M_ARRA4_OPLIST_P3(name, oplist) \ #define M_ARRA4_OPLIST_P3(name, oplist) \
(INIT(M_C(name, _init)) \ (INIT(M_F(name, _init)) \
,M_IF_METHOD2(INIT_SET,SET, oplist)(INIT_SET(M_C(name, _init_set)),) \ ,M_IF_METHOD2(INIT_SET,SET, oplist)(INIT_SET(M_F(name, _init_set)),) \
,M_IF_METHOD(INIT_SET, oplist)(INIT_WITH(API_1(M_INIT_WITH_VAI)),) \ ,M_IF_METHOD(INIT_SET, oplist)(INIT_WITH(API_1(M_INIT_WITH_VAI)),) \
,M_IF_METHOD2(INIT_SET,SET, oplist)(SET(M_C(name, _set)), ) \ ,M_IF_METHOD2(INIT_SET,SET, oplist)(SET(M_F(name, _set)), ) \
,CLEAR(M_C(name, _clear)) \ ,CLEAR(M_F(name, _clear)) \
,INIT_MOVE(M_C(name, _init_move)) \ ,INIT_MOVE(M_F(name, _init_move)) \
,MOVE(M_C(name, _move)) \ ,MOVE(M_F(name, _move)) \
,SWAP(M_C(name, _swap)) \ ,SWAP(M_F(name, _swap)) \
,TYPE(M_C(name,_ct)) \ ,TYPE(M_F(name,_ct)) \
,NAME(name) \ ,NAME(name) \
,SUBTYPE(M_C(name, _subtype_ct)) \ ,SUBTYPE(M_F(name, _subtype_ct)) \
,EMPTY_P(M_C(name,_empty_p)) \ ,EMPTY_P(M_F(name,_empty_p)) \
,IT_TYPE(M_C(name,_it_ct)), \ ,IT_TYPE(M_F(name,_it_ct)), \
,IT_FIRST(M_C(name,_it)) \ ,IT_FIRST(M_F(name,_it)) \
,IT_LAST(M_C(name,_it_last)) \ ,IT_LAST(M_F(name,_it_last)) \
,IT_END(M_C(name,_it_end)) \ ,IT_END(M_F(name,_it_end)) \
,IT_SET(M_C(name,_it_set)) \ ,IT_SET(M_F(name,_it_set)) \
,IT_END_P(M_C(name,_end_p)) \ ,IT_END_P(M_F(name,_end_p)) \
,IT_LAST_P(M_C(name,_last_p)) \ ,IT_LAST_P(M_F(name,_last_p)) \
,IT_EQUAL_P(M_C(name,_it_equal_p)) \ ,IT_EQUAL_P(M_F(name,_it_equal_p)) \
,IT_NEXT(M_C(name,_next)) \ ,IT_NEXT(M_F(name,_next)) \
,IT_PREVIOUS(M_C(name,_previous)) \ ,IT_PREVIOUS(M_F(name,_previous)) \
,IT_REF(M_C(name,_ref)) \ ,IT_REF(M_F(name,_ref)) \
,IT_CREF(M_C(name,_cref)) \ ,IT_CREF(M_F(name,_cref)) \
,M_IF_METHOD(INIT_SET, oplist)(IT_INSERT(M_C(name,_insert)) ,) \ ,M_IF_METHOD(INIT_SET, oplist)(IT_INSERT(M_F(name,_insert)) ,) \
,M_IF_AT_LEAST_METHOD(SET,INIT_MOVE,oplist)(IT_REMOVE(M_C(name,_remove)),) \ ,M_IF_AT_LEAST_METHOD(SET,INIT_MOVE,oplist)(IT_REMOVE(M_F(name,_remove)),) \
,RESET(M_C(name,_reset)) \ ,RESET(M_F(name,_reset)) \
,KEY_TYPE(size_t) \ ,KEY_TYPE(size_t) \
,VALUE_TYPE(M_C(name, _subtype_ct)) \ ,VALUE_TYPE(M_F(name, _subtype_ct)) \
,KEY_OPLIST(M_BASIC_OPLIST) \ ,KEY_OPLIST(M_BASIC_OPLIST) \
,VALUE_OPLIST(oplist) \ ,VALUE_OPLIST(oplist) \
,M_IF_METHOD(SET, oplist)(SET_KEY(M_C(name, _set_at)) ,) \ ,M_IF_METHOD(SET, oplist)(SET_KEY(M_F(name, _set_at)) ,) \
,GET_KEY(M_C(name, _get)) \ ,GET_KEY(M_F(name, _get)) \
,M_IF_METHOD(INIT, oplist)(SAFE_GET_KEY(M_C(name, _safe_get)) ,) \ ,M_IF_METHOD(INIT, oplist)(SAFE_GET_KEY(M_F(name, _safe_get)) ,) \
,M_IF_AT_LEAST_METHOD(SET,INIT_MOVE,oplist)(ERASE_KEY(M_C(name, _erase)),) \ ,M_IF_AT_LEAST_METHOD(SET,INIT_MOVE,oplist)(ERASE_KEY(M_F(name, _erase)),) \
,GET_SIZE(M_C(name, _size)) \ ,GET_SIZE(M_F(name, _size)) \
,M_IF_METHOD(INIT_SET, oplist)(PUSH(M_C(name,_push_back)) ,) \ ,M_IF_METHOD(INIT_SET, oplist)(PUSH(M_F(name,_push_back)) ,) \
,M_IF_AT_LEAST_METHOD(SET,INIT_MOVE,oplist)(POP(M_C(name,_pop_back)) ,) \ ,M_IF_AT_LEAST_METHOD(SET,INIT_MOVE,oplist)(POP(M_F(name,_pop_back)) ,) \
,M_IF_AT_LEAST_METHOD(INIT_SET,INIT_MOVE,oplist)(PUSH_MOVE(M_C(name,_push_move)) ,) \ ,M_IF_AT_LEAST_METHOD(INIT_SET,INIT_MOVE,oplist)(PUSH_MOVE(M_F(name,_push_move)) ,) \
,M_IF_AT_LEAST_METHOD(INIT_SET,INIT_MOVE,oplist)(POP_MOVE(M_C(name,_pop_move)) ,) \ ,M_IF_AT_LEAST_METHOD(INIT_SET,INIT_MOVE,oplist)(POP_MOVE(M_F(name,_pop_move)) ,) \
,OPLIST(oplist) \ ,OPLIST(oplist) \
,M_IF_METHOD(CMP, oplist)(SORT(M_C(name, _special_sort)),) \ ,M_IF_METHOD(CMP, oplist)(SORT(M_F(name, _special_sort)),) \
,M_IF_METHOD(GET_STR, oplist)(GET_STR(M_C(name, _get_str)),) \ ,M_IF_METHOD(GET_STR, oplist)(GET_STR(M_F(name, _get_str)),) \
,M_IF_METHOD(PARSE_STR, oplist)(PARSE_STR(M_C(name, _parse_str)),) \ ,M_IF_METHOD(PARSE_STR, oplist)(PARSE_STR(M_F(name, _parse_str)),) \
,M_IF_METHOD(OUT_STR, oplist)(OUT_STR(M_C(name, _out_str)),) \ ,M_IF_METHOD(OUT_STR, oplist)(OUT_STR(M_F(name, _out_str)),) \
,M_IF_METHOD(IN_STR, oplist)(IN_STR(M_C(name, _in_str)),) \ ,M_IF_METHOD(IN_STR, oplist)(IN_STR(M_F(name, _in_str)),) \
,M_IF_METHOD(OUT_SERIAL, oplist)(OUT_SERIAL(M_C(name, _out_serial)),) \ ,M_IF_METHOD(OUT_SERIAL, oplist)(OUT_SERIAL(M_F(name, _out_serial)),) \
,M_IF_METHOD(IN_SERIAL, oplist)(IN_SERIAL(M_C(name, _in_serial)),) \ ,M_IF_METHOD(IN_SERIAL, oplist)(IN_SERIAL(M_F(name, _in_serial)),) \
,M_IF_METHOD(EQUAL, oplist)(EQUAL(M_C(name, _equal_p)),) \ ,M_IF_METHOD(EQUAL, oplist)(EQUAL(M_F(name, _equal_p)),) \
,M_IF_METHOD(HASH, oplist)(HASH(M_C(name, _hash)),) \ ,M_IF_METHOD(HASH, oplist)(HASH(M_F(name, _hash)),) \
,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW oplist),) \ ,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW oplist),) \
,M_IF_METHOD(REALLOC, oplist)(REALLOC(M_GET_REALLOC oplist),) \ ,M_IF_METHOD(REALLOC, oplist)(REALLOC(M_GET_REALLOC oplist),) \
,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL oplist),) \ ,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL oplist),) \
@@ -176,36 +176,36 @@
M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \ M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \
M_ARRA4_DEF_CORE(name, type, oplist, array_t, it_t) \ M_ARRA4_DEF_CORE(name, type, oplist, array_t, it_t) \
M_ARRA4_DEF_IO(name, type, oplist, array_t, it_t) \ M_ARRA4_DEF_IO(name, type, oplist, array_t, it_t) \
M_EMPLACE_QUEUE_DEF(name, array_t, M_C(name, _emplace_back), oplist, M_ARRA4_EMPLACE_DEF) M_EMPLACE_QUEUE_DEF(name, array_t, M_F(name, _emplace_back), oplist, M_ARRA4_EMPLACE_DEF)
/* Define the types */ /* Define the types */
#define M_ARRA4_DEF_TYPE(name, type, oplist, array_t, it_t) \ #define M_ARRA4_DEF_TYPE(name, type, oplist, array_t, it_t) \
\ \
/* Define a dynamic array */ \ /* Define a dynamic array */ \
typedef struct M_C(name, _s) { \ typedef struct M_F(name, _s) { \
size_t size; /* Number of elements in the array */ \ size_t size; /* Number of elements in the array */ \
size_t alloc; /* Allocated size for the array base */ \ size_t alloc; /* Allocated size for the array base */ \
type *ptr; /* Pointer to the array base */ \ type *ptr; /* Pointer to the array base */ \
} array_t[1]; \ } array_t[1]; \
\ \
/* Define an iterator over an array */ \ /* Define an iterator over an array */ \
typedef struct M_C(name, _it_s) { \ typedef struct M_F(name, _it_s) { \
size_t index; /* Index of the element */ \ size_t index; /* Index of the element */ \
const struct M_C(name, _s) *array; /* Reference of the array */ \ const struct M_F(name, _s) *array; /* Reference of the array */ \
} it_t[1]; \ } it_t[1]; \
\ \
/* Definition of the synonyms of the type */ \ /* Definition of the synonyms of the type */ \
typedef struct M_C(name, _s) *M_C(name, _ptr); \ typedef struct M_F(name, _s) *M_F(name, _ptr); \
typedef const struct M_C(name, _s) *M_C(name, _srcptr); \ typedef const struct M_F(name, _s) *M_F(name, _srcptr); \
typedef array_t M_C(name, _ct); \ typedef array_t M_F(name, _ct); \
typedef it_t M_C(name, _it_ct); \ typedef it_t M_F(name, _it_ct); \
typedef type M_C(name, _subtype_ct); \ typedef type M_F(name, _subtype_ct); \
/* Define the core functions */ /* Define the core functions */
#define M_ARRA4_DEF_CORE(name, type, oplist, array_t, it_t) \ #define M_ARRA4_DEF_CORE(name, type, oplist, array_t, it_t) \
\ \
static inline void \ static inline void \
M_C(name, _init)(array_t v) \ M_F(name, _init)(array_t v) \
{ \ { \
M_ASSERT (v != NULL); \ M_ASSERT (v != NULL); \
/* Initially, the array is empty with nothing allocated */ \ /* Initially, the array is empty with nothing allocated */ \
@@ -216,7 +216,7 @@
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _reset)(array_t v) \ M_F(name, _reset)(array_t v) \
{ \ { \
M_ARRA4_CONTRACT(v); \ M_ARRA4_CONTRACT(v); \
for(size_t i = 0; i < v->size; i++) \ for(size_t i = 0; i < v->size; i++) \
@@ -226,10 +226,10 @@
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _clear)(array_t v) \ M_F(name, _clear)(array_t v) \
{ \ { \
M_ARRA4_CONTRACT(v); \ M_ARRA4_CONTRACT(v); \
M_C(name, _reset)(v); \ M_F(name, _reset)(v); \
M_CALL_FREE(oplist, v->ptr); \ M_CALL_FREE(oplist, v->ptr); \
/* This is so reusing the object implies an assertion failure */ \ /* This is so reusing the object implies an assertion failure */ \
v->alloc = 1; \ v->alloc = 1; \
@@ -238,7 +238,7 @@
\ \
M_IF_METHOD2(INIT_SET, SET, oplist)( \ M_IF_METHOD2(INIT_SET, SET, oplist)( \
static inline void \ static inline void \
M_C(name, _set)(array_t d, const array_t s) \ M_F(name, _set)(array_t d, const array_t s) \
{ \ { \
M_ARRA4_CONTRACT(d); \ M_ARRA4_CONTRACT(d); \
M_ARRA4_CONTRACT(s); \ M_ARRA4_CONTRACT(s); \
@@ -266,16 +266,16 @@
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _init_set)(array_t d, const array_t s) \ M_F(name, _init_set)(array_t d, const array_t s) \
{ \ { \
M_ASSERT (d != s); \ M_ASSERT (d != s); \
M_C(name, _init)(d); \ M_F(name, _init)(d); \
M_C(name, _set)(d, s); \ M_F(name, _set)(d, s); \
} \ } \
, /* No SET & INIT_SET */) \ , /* No SET & INIT_SET */) \
\ \
static inline void \ static inline void \
M_C(name, _init_move)(array_t d, array_t s) \ M_F(name, _init_move)(array_t d, array_t s) \
{ \ { \
M_ASSERT (d != s); \ M_ASSERT (d != s); \
M_ARRA4_CONTRACT(s); \ M_ARRA4_CONTRACT(s); \
@@ -289,16 +289,16 @@
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _move)(array_t d, array_t s) \ M_F(name, _move)(array_t d, array_t s) \
{ \ { \
M_ASSERT (d != s); \ M_ASSERT (d != s); \
M_C(name, _clear)(d); \ M_F(name, _clear)(d); \
M_C(name, _init_move)(d, s); \ M_F(name, _init_move)(d, s); \
} \ } \
\ \
M_IF_METHOD(SET, oplist)( \ M_IF_METHOD(SET, oplist)( \
static inline void \ static inline void \
M_C(name, _set_at)(array_t v, size_t i, type const x) \ M_F(name, _set_at)(array_t v, size_t i, type const x) \
{ \ { \
M_ARRA4_CONTRACT(v); \ M_ARRA4_CONTRACT(v); \
M_ASSERT(v->size > 0 && v->ptr != NULL); \ M_ASSERT(v->size > 0 && v->ptr != NULL); \
@@ -308,7 +308,7 @@
, /* No SET */) \ , /* No SET */) \
\ \
static inline type * \ static inline type * \
M_C(name, _back)(array_t v) \ M_F(name, _back)(array_t v) \
{ \ { \
M_ARRA4_CONTRACT(v); \ M_ARRA4_CONTRACT(v); \
M_ASSERT(v->ptr != NULL); \ M_ASSERT(v->ptr != NULL); \
@@ -317,7 +317,7 @@
} \ } \
\ \
static inline type * \ static inline type * \
M_C(name, _push_raw)(array_t v) \ M_F(name, _push_raw)(array_t v) \
{ \ { \
M_ARRA4_CONTRACT(v); \ M_ARRA4_CONTRACT(v); \
if (M_UNLIKELY (v->size >= v->alloc)) { \ if (M_UNLIKELY (v->size >= v->alloc)) { \
@@ -346,9 +346,9 @@
\ \
M_IF_METHOD(INIT_SET, oplist)( \ M_IF_METHOD(INIT_SET, oplist)( \
static inline void \ static inline void \
M_C(name, _push_back)(array_t v, type const x) \ M_F(name, _push_back)(array_t v, type const x) \
{ \ { \
type *data = M_C(name, _push_raw)(v); \ type *data = M_F(name, _push_raw)(v); \
if (M_UNLIKELY (data == NULL) ) \ if (M_UNLIKELY (data == NULL) ) \
return; \ return; \
M_CALL_INIT_SET(oplist, *data, x); \ M_CALL_INIT_SET(oplist, *data, x); \
@@ -357,9 +357,9 @@
\ \
M_IF_METHOD(INIT, oplist)( \ M_IF_METHOD(INIT, oplist)( \
static inline type * \ static inline type * \
M_C(name, _push_new)(array_t v) \ M_F(name, _push_new)(array_t v) \
{ \ { \
type *data = M_C(name, _push_raw)(v); \ type *data = M_F(name, _push_raw)(v); \
if (M_UNLIKELY (data == NULL) ) \ if (M_UNLIKELY (data == NULL) ) \
return NULL; \ return NULL; \
M_CALL_INIT(oplist, *data); \ M_CALL_INIT(oplist, *data); \
@@ -369,10 +369,10 @@
\ \
M_IF_AT_LEAST_METHOD(INIT_SET, INIT_MOVE, oplist)( \ M_IF_AT_LEAST_METHOD(INIT_SET, INIT_MOVE, oplist)( \
static inline void \ static inline void \
M_C(name, _push_move)(array_t v, type *x) \ M_F(name, _push_move)(array_t v, type *x) \
{ \ { \
M_ASSERT (x != NULL); \ M_ASSERT (x != NULL); \
type *data = M_C(name, _push_raw)(v); \ type *data = M_F(name, _push_raw)(v); \
if (M_UNLIKELY (data == NULL) ) \ if (M_UNLIKELY (data == NULL) ) \
return; \ return; \
M_DO_INIT_MOVE (oplist, *data, *x); \ M_DO_INIT_MOVE (oplist, *data, *x); \
@@ -381,7 +381,7 @@
\ \
M_IF_METHOD(INIT_SET, oplist)( \ M_IF_METHOD(INIT_SET, oplist)( \
static inline void \ static inline void \
M_C(name, _push_at)(array_t v, size_t key, type const x) \ M_F(name, _push_at)(array_t v, size_t key, type const x) \
{ \ { \
M_ARRA4_CONTRACT(v); \ M_ARRA4_CONTRACT(v); \
M_ASSERT_INDEX(key, v->size+1); \ M_ASSERT_INDEX(key, v->size+1); \
@@ -411,7 +411,7 @@
\ \
M_IF_METHOD(INIT, oplist)( \ M_IF_METHOD(INIT, oplist)( \
static inline void \ static inline void \
M_C(name, _resize)(array_t v, size_t size) \ M_F(name, _resize)(array_t v, size_t size) \
{ \ { \
M_ARRA4_CONTRACT(v); \ M_ARRA4_CONTRACT(v); \
if (v->size > size) { \ if (v->size > size) { \
@@ -440,7 +440,7 @@
, /* No INIT */ ) \ , /* No INIT */ ) \
\ \
static inline void \ static inline void \
M_C(name, _reserve)(array_t v, size_t alloc) \ M_F(name, _reserve)(array_t v, size_t alloc) \
{ \ { \
M_ARRA4_CONTRACT(v); \ M_ARRA4_CONTRACT(v); \
/* NOTE: Reserve below needed size to perform a shrink to fit */ \ /* NOTE: Reserve below needed size to perform a shrink to fit */ \
@@ -465,7 +465,7 @@
\ \
M_IF_METHOD(INIT, oplist)( \ M_IF_METHOD(INIT, oplist)( \
static inline type * \ static inline type * \
M_C(name, _safe_get)(array_t v, size_t idx) \ M_F(name, _safe_get)(array_t v, size_t idx) \
{ \ { \
M_ARRA4_CONTRACT(v); \ M_ARRA4_CONTRACT(v); \
const size_t size = idx + 1; \ const size_t size = idx + 1; \
@@ -499,7 +499,7 @@
\ \
M_IF_AT_LEAST_METHOD(SET, INIT_MOVE, oplist)( \ M_IF_AT_LEAST_METHOD(SET, INIT_MOVE, oplist)( \
static inline void \ static inline void \
M_C(name, _pop_back)(type *dest, array_t v) \ M_F(name, _pop_back)(type *dest, array_t v) \
{ \ { \
M_ARRA4_CONTRACT(v); \ M_ARRA4_CONTRACT(v); \
M_ASSERT (v->ptr != NULL); \ M_ASSERT (v->ptr != NULL); \
@@ -516,7 +516,7 @@
\ \
M_IF_AT_LEAST_METHOD(INIT_SET, INIT_MOVE, oplist)( \ M_IF_AT_LEAST_METHOD(INIT_SET, INIT_MOVE, oplist)( \
static inline void \ static inline void \
M_C(name, _pop_move)(type *dest, array_t v) \ M_F(name, _pop_move)(type *dest, array_t v) \
{ \ { \
M_ARRA4_CONTRACT(v); \ M_ARRA4_CONTRACT(v); \
M_ASSERT (v->ptr != NULL); \ M_ASSERT (v->ptr != NULL); \
@@ -530,31 +530,31 @@
\ \
M_IF_METHOD(INIT, oplist)( \ M_IF_METHOD(INIT, oplist)( \
static inline void \ static inline void \
M_C(name, _pop_until)(array_t v, it_t pos) \ M_F(name, _pop_until)(array_t v, it_t pos) \
{ \ { \
M_ARRA4_CONTRACT(v); \ M_ARRA4_CONTRACT(v); \
M_ASSERT (v == pos->array); \ M_ASSERT (v == pos->array); \
M_ASSERT_INDEX(pos->index, v->size+1); \ M_ASSERT_INDEX(pos->index, v->size+1); \
M_C(name, _resize)(v, pos->index); \ M_F(name, _resize)(v, pos->index); \
} \ } \
, /* No INIT */ ) \ , /* No INIT */ ) \
\ \
static inline bool \ static inline bool \
M_C(name, _empty_p)(const array_t v) \ M_F(name, _empty_p)(const array_t v) \
{ \ { \
M_ARRA4_CONTRACT(v); \ M_ARRA4_CONTRACT(v); \
return v->size == 0; \ return v->size == 0; \
} \ } \
\ \
static inline size_t \ static inline size_t \
M_C(name, _size)(const array_t v) \ M_F(name, _size)(const array_t v) \
{ \ { \
M_ARRA4_CONTRACT(v); \ M_ARRA4_CONTRACT(v); \
return v->size; \ return v->size; \
} \ } \
\ \
static inline size_t \ static inline size_t \
M_C(name, _capacity)(const array_t v) \ M_F(name, _capacity)(const array_t v) \
{ \ { \
M_ARRA4_CONTRACT(v); \ M_ARRA4_CONTRACT(v); \
return v->alloc; \ return v->alloc; \
@@ -562,7 +562,7 @@
\ \
M_IF_AT_LEAST_METHOD(SET, INIT_MOVE, oplist)( \ M_IF_AT_LEAST_METHOD(SET, INIT_MOVE, oplist)( \
static inline void \ static inline void \
M_C(name, _pop_at)(type *dest, array_t v, size_t i) \ M_F(name, _pop_at)(type *dest, array_t v, size_t i) \
{ \ { \
M_ARRA4_CONTRACT(v); \ M_ARRA4_CONTRACT(v); \
M_ASSERT (v->size > 0 && v->ptr != NULL); \ M_ASSERT (v->size > 0 && v->ptr != NULL); \
@@ -577,18 +577,18 @@
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _erase)(array_t a, size_t i) \ M_F(name, _erase)(array_t a, size_t i) \
{ \ { \
M_ARRA4_CONTRACT(a); \ M_ARRA4_CONTRACT(a); \
if (i >= a->size) return false; \ if (i >= a->size) return false; \
M_C(name, _pop_at)(NULL, a, i); \ M_F(name, _pop_at)(NULL, a, i); \
return true; \ return true; \
} \ } \
, /* SET | INIT_MOVE */ ) \ , /* SET | INIT_MOVE */ ) \
\ \
M_IF_METHOD(INIT, oplist)( \ M_IF_METHOD(INIT, oplist)( \
static inline void \ static inline void \
M_C(name, _insert_v)(array_t v, size_t i, size_t num) \ M_F(name, _insert_v)(array_t v, size_t i, size_t num) \
{ \ { \
M_ARRA4_CONTRACT(v); \ M_ARRA4_CONTRACT(v); \
M_ASSERT_INDEX(i, v->size+1); \ M_ASSERT_INDEX(i, v->size+1); \
@@ -624,7 +624,7 @@
, /* No INIT */) \ , /* No INIT */) \
\ \
static inline void \ static inline void \
M_C(name, _remove_v)(array_t v, size_t i, size_t j) \ M_F(name, _remove_v)(array_t v, size_t i, size_t j) \
{ \ { \
M_ARRA4_CONTRACT(v); \ M_ARRA4_CONTRACT(v); \
M_ASSERT(i < j && v->ptr != NULL); \ M_ASSERT(i < j && v->ptr != NULL); \
@@ -638,7 +638,7 @@
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _swap)(array_t v1, array_t v2) \ M_F(name, _swap)(array_t v1, array_t v2) \
{ \ { \
M_ARRA4_CONTRACT(v1); \ M_ARRA4_CONTRACT(v1); \
M_ARRA4_CONTRACT(v2); \ M_ARRA4_CONTRACT(v2); \
@@ -651,7 +651,7 @@
\ \
M_IF_AT_LEAST_METHOD(INIT_SET,INIT_MOVE,oplist) ( \ M_IF_AT_LEAST_METHOD(INIT_SET,INIT_MOVE,oplist) ( \
static inline void \ static inline void \
M_C(name, _swap_at)(array_t v, size_t i, size_t j) \ M_F(name, _swap_at)(array_t v, size_t i, size_t j) \
{ \ { \
M_ARRA4_CONTRACT(v); \ M_ARRA4_CONTRACT(v); \
M_ASSERT(v->ptr != NULL); \ M_ASSERT(v->ptr != NULL); \
@@ -666,7 +666,7 @@
, /* INIT_SET | INIT_MOVE */ ) \ , /* INIT_SET | INIT_MOVE */ ) \
\ \
static inline type * \ static inline type * \
M_C(name, _get)(const array_t v, size_t i) \ M_F(name, _get)(const array_t v, size_t i) \
{ \ { \
M_ARRA4_CONTRACT(v); \ M_ARRA4_CONTRACT(v); \
M_ASSERT (v->ptr != NULL); \ M_ASSERT (v->ptr != NULL); \
@@ -675,7 +675,7 @@
} \ } \
\ \
static inline type const * \ static inline type const * \
M_C(name, _cget)(const array_t v, size_t i) \ M_F(name, _cget)(const array_t v, size_t i) \
{ \ { \
M_ARRA4_CONTRACT(v); \ M_ARRA4_CONTRACT(v); \
M_ASSERT (v->ptr != NULL); \ M_ASSERT (v->ptr != NULL); \
@@ -684,15 +684,15 @@
} \ } \
\ \
static inline type * \ static inline type * \
M_C(name, _front)(const array_t v) \ M_F(name, _front)(const array_t v) \
{ \ { \
M_ARRA4_CONTRACT(v); \ M_ARRA4_CONTRACT(v); \
M_ASSERT_INDEX(0, v->size); \ M_ASSERT_INDEX(0, v->size); \
return M_C(name, _get)(v, 0); \ return M_F(name, _get)(v, 0); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _it)(it_t it, const array_t v) \ M_F(name, _it)(it_t it, const array_t v) \
{ \ { \
M_ARRA4_CONTRACT(v); \ M_ARRA4_CONTRACT(v); \
M_ASSERT (it != NULL); \ M_ASSERT (it != NULL); \
@@ -701,7 +701,7 @@
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _it_last)(it_t it, const array_t v) \ M_F(name, _it_last)(it_t it, const array_t v) \
{ \ { \
M_ARRA4_CONTRACT(v); \ M_ARRA4_CONTRACT(v); \
M_ASSERT (it != NULL); \ M_ASSERT (it != NULL); \
@@ -711,7 +711,7 @@
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _it_end)(it_t it, const array_t v) \ M_F(name, _it_end)(it_t it, const array_t v) \
{ \ { \
M_ARRA4_CONTRACT(v); \ M_ARRA4_CONTRACT(v); \
M_ASSERT (it != NULL); \ M_ASSERT (it != NULL); \
@@ -720,7 +720,7 @@
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _it_set)(it_t it, const it_t org) \ M_F(name, _it_set)(it_t it, const it_t org) \
{ \ { \
M_ASSERT (it != NULL && org != NULL); \ M_ASSERT (it != NULL && org != NULL); \
it->index = org->index; \ it->index = org->index; \
@@ -729,14 +729,14 @@
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _end_p)(const it_t it) \ M_F(name, _end_p)(const it_t it) \
{ \ { \
M_ASSERT(it != NULL && it->array != NULL); \ M_ASSERT(it != NULL && it->array != NULL); \
return it->index >= it->array->size; \ return it->index >= it->array->size; \
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _last_p)(const it_t it) \ M_F(name, _last_p)(const it_t it) \
{ \ { \
M_ASSERT(it != NULL && it->array != NULL); \ M_ASSERT(it != NULL && it->array != NULL); \
/* NOTE: Can not compute 'size-1' due to potential overflow \ /* NOTE: Can not compute 'size-1' due to potential overflow \
@@ -745,7 +745,7 @@
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _it_equal_p)(const it_t it1, \ M_F(name, _it_equal_p)(const it_t it1, \
const it_t it2) \ const it_t it2) \
{ \ { \
M_ASSERT(it1 != NULL && it2 != NULL); \ M_ASSERT(it1 != NULL && it2 != NULL); \
@@ -753,14 +753,14 @@
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _next)(it_t it) \ M_F(name, _next)(it_t it) \
{ \ { \
M_ASSERT(it != NULL && it->array != NULL); \ M_ASSERT(it != NULL && it->array != NULL); \
it->index ++; \ it->index ++; \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _previous)(it_t it) \ M_F(name, _previous)(it_t it) \
{ \ { \
M_ASSERT(it != NULL && it->array != NULL); \ M_ASSERT(it != NULL && it->array != NULL); \
/* NOTE: In the case index=0, it will be set to (unsigned) -1 \ /* NOTE: In the case index=0, it will be set to (unsigned) -1 \
@@ -769,43 +769,43 @@
} \ } \
\ \
static inline type * \ static inline type * \
M_C(name, _ref)(const it_t it) \ M_F(name, _ref)(const it_t it) \
{ \ { \
M_ASSERT(it != NULL); \ M_ASSERT(it != NULL); \
return M_C(name, _get)(it->array, it->index); \ return M_F(name, _get)(it->array, it->index); \
} \ } \
\ \
static inline type const * \ static inline type const * \
M_C(name, _cref)(const it_t it) \ M_F(name, _cref)(const it_t it) \
{ \ { \
M_ASSERT(it != NULL); \ M_ASSERT(it != NULL); \
return M_C(name, _cget)(it->array, it->index); \ return M_F(name, _cget)(it->array, it->index); \
} \ } \
\ \
M_IF_METHOD(INIT_SET, oplist)( \ M_IF_METHOD(INIT_SET, oplist)( \
static inline void \ static inline void \
M_C(name, _insert)(array_t a, it_t it, type const x) \ M_F(name, _insert)(array_t a, it_t it, type const x) \
{ \ { \
M_ASSERT (it != NULL && a == it->array); \ M_ASSERT (it != NULL && a == it->array); \
size_t index = M_C(name, _end_p)(it) ? 0 : it->index+1; \ size_t index = M_F(name, _end_p)(it) ? 0 : it->index+1; \
M_C(name, _push_at)(a, index, x); \ M_F(name, _push_at)(a, index, x); \
it->index = index; \ it->index = index; \
} \ } \
, /* End of INIT_SET */ ) \ , /* End of INIT_SET */ ) \
\ \
M_IF_AT_LEAST_METHOD(SET, INIT_MOVE, oplist)( \ M_IF_AT_LEAST_METHOD(SET, INIT_MOVE, oplist)( \
static inline void \ static inline void \
M_C(name, _remove)(array_t a, it_t it) \ M_F(name, _remove)(array_t a, it_t it) \
{ \ { \
M_ASSERT (it != NULL && a == it->array); \ M_ASSERT (it != NULL && a == it->array); \
M_C(name, _pop_at)(NULL, a, it->index); \ M_F(name, _pop_at)(NULL, a, it->index); \
/* NOTE: it->index will naturaly point to the next element */ \ /* NOTE: it->index will naturaly point to the next element */ \
} \ } \
, /* End of SET | INIT_SET */ ) \ , /* End of SET | INIT_SET */ ) \
\ \
M_IF_METHOD(CMP, oplist) \ M_IF_METHOD(CMP, oplist) \
( \ ( \
static inline void M_C(name, _special_sort)(array_t l, \ static inline void M_F(name, _special_sort)(array_t l, \
int (*func_type) (type const *a, type const *b)) \ int (*func_type) (type const *a, type const *b)) \
{ \ { \
/* Using qsort is more compact but slower than a full templated \ /* Using qsort is more compact but slower than a full templated \
@@ -889,7 +889,7 @@
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _special_stable_sort)(array_t l) \ M_F(name, _special_stable_sort)(array_t l) \
{ \ { \
if (M_UNLIKELY (l->size < 2)) \ if (M_UNLIKELY (l->size < 2)) \
return; \ return; \
@@ -908,7 +908,7 @@
\ \
M_IF_METHOD(EQUAL, oplist)( \ M_IF_METHOD(EQUAL, oplist)( \
static inline bool \ static inline bool \
M_C(name, _equal_p)(const array_t array1, \ M_F(name, _equal_p)(const array_t array1, \
const array_t array2) \ const array_t array2) \
{ \ { \
M_ARRA4_CONTRACT(array1); \ M_ARRA4_CONTRACT(array1); \
@@ -916,8 +916,8 @@
if (array1->size != array2->size) return false; \ if (array1->size != array2->size) return false; \
size_t i; \ size_t i; \
for(i = 0; i < array1->size; i++) { \ for(i = 0; i < array1->size; i++) { \
type const *item1 = M_C(name, _cget)(array1, i); \ type const *item1 = M_F(name, _cget)(array1, i); \
type const *item2 = M_C(name, _cget)(array2, i); \ type const *item2 = M_F(name, _cget)(array2, i); \
bool b = M_CALL_EQUAL(oplist, *item1, *item2); \ bool b = M_CALL_EQUAL(oplist, *item1, *item2); \
if (!b) return false; \ if (!b) return false; \
} \ } \
@@ -927,7 +927,7 @@
\ \
M_IF_METHOD(HASH, oplist)( \ M_IF_METHOD(HASH, oplist)( \
static inline size_t \ static inline size_t \
M_C(name, _hash)(const array_t array) \ M_F(name, _hash)(const array_t array) \
{ \ { \
M_ARRA4_CONTRACT(array); \ M_ARRA4_CONTRACT(array); \
M_HASH_DECL(hash); \ M_HASH_DECL(hash); \
@@ -940,7 +940,7 @@
, /* no HASH */ ) \ , /* no HASH */ ) \
\ \
static inline void \ static inline void \
M_C(name, _splice)(array_t a1, array_t a2) \ M_F(name, _splice)(array_t a1, array_t a2) \
{ \ { \
M_ARRA4_CONTRACT(a1); \ M_ARRA4_CONTRACT(a1); \
M_ARRA4_CONTRACT(a2); \ M_ARRA4_CONTRACT(a2); \
@@ -973,18 +973,18 @@
\ \
M_IF_METHOD(GET_STR, oplist)( \ M_IF_METHOD(GET_STR, oplist)( \
static inline void \ static inline void \
M_C(name, _get_str)(m_string_t str, array_t const array, \ M_F(name, _get_str)(m_string_t str, array_t const array, \
bool append) \ bool append) \
{ \ { \
M_ARRA4_CONTRACT(array); \ M_ARRA4_CONTRACT(array); \
(append ? m_string_cat_cstr : m_string_set_cstr) (str, "["); \ (append ? m_string_cat_cstr : m_string_set_cstr) (str, "["); \
it_t it; \ it_t it; \
for (M_C(name, _it)(it, array) ; \ for (M_F(name, _it)(it, array) ; \
!M_C(name, _end_p)(it); \ !M_F(name, _end_p)(it); \
M_C(name, _next)(it)){ \ M_F(name, _next)(it)){ \
type const *item = M_C(name, _cref)(it); \ type const *item = M_F(name, _cref)(it); \
M_CALL_GET_STR(oplist, str, *item, true); \ M_CALL_GET_STR(oplist, str, *item, true); \
if (!M_C(name, _last_p)(it)) \ if (!M_F(name, _last_p)(it)) \
m_string_push_back (str, M_GET_SEPARATOR oplist); \ m_string_push_back (str, M_GET_SEPARATOR oplist); \
} \ } \
m_string_push_back (str, ']'); \ m_string_push_back (str, ']'); \
@@ -993,13 +993,13 @@
\ \
M_IF_METHOD(OUT_STR, oplist)( \ M_IF_METHOD(OUT_STR, oplist)( \
static inline void \ static inline void \
M_C(name, _out_str)(FILE *file, const array_t array) \ M_F(name, _out_str)(FILE *file, const array_t array) \
{ \ { \
M_ARRA4_CONTRACT(array); \ M_ARRA4_CONTRACT(array); \
M_ASSERT (file != NULL); \ M_ASSERT (file != NULL); \
fputc ('[', file); \ fputc ('[', file); \
for (size_t i = 0; i < array->size; i++) { \ for (size_t i = 0; i < array->size; i++) { \
type const *item = M_C(name, _cget)(array, i); \ type const *item = M_F(name, _cget)(array, i); \
M_CALL_OUT_STR(oplist, file, *item); \ M_CALL_OUT_STR(oplist, file, *item); \
if (i != array->size-1) \ if (i != array->size-1) \
fputc (M_GET_SEPARATOR oplist, file); \ fputc (M_GET_SEPARATOR oplist, file); \
@@ -1010,11 +1010,11 @@
\ \
M_IF_METHOD2(PARSE_STR, INIT, oplist)( \ M_IF_METHOD2(PARSE_STR, INIT, oplist)( \
static inline bool \ static inline bool \
M_C(name, _parse_str)(array_t array, const char str[], const char**endp) \ M_F(name, _parse_str)(array_t array, const char str[], const char**endp) \
{ \ { \
M_ARRA4_CONTRACT(array); \ M_ARRA4_CONTRACT(array); \
M_ASSERT (str != NULL); \ M_ASSERT (str != NULL); \
M_C(name,_reset)(array); \ M_F(name,_reset)(array); \
bool success = false; \ bool success = false; \
int c = *str++; \ int c = *str++; \
if (M_UNLIKELY (c != '[')) goto exit; \ if (M_UNLIKELY (c != '[')) goto exit; \
@@ -1028,7 +1028,7 @@
bool b = M_CALL_PARSE_STR(oplist, item, str, &str); \ bool b = M_CALL_PARSE_STR(oplist, item, str, &str); \
do { c = *str++; } while (isspace(c)); \ do { c = *str++; } while (isspace(c)); \
if (b == false || c == 0) { goto exit_clear; } \ if (b == false || c == 0) { goto exit_clear; } \
M_C(name, _push_back)(array, item); \ M_F(name, _push_back)(array, item); \
} while (c == M_GET_SEPARATOR oplist); \ } while (c == M_GET_SEPARATOR oplist); \
M_ARRA4_CONTRACT(array); \ M_ARRA4_CONTRACT(array); \
success = (c == ']'); \ success = (c == ']'); \
@@ -1042,11 +1042,11 @@
\ \
M_IF_METHOD2(IN_STR, INIT, oplist)( \ M_IF_METHOD2(IN_STR, INIT, oplist)( \
static inline bool \ static inline bool \
M_C(name, _in_str)(array_t array, FILE *file) \ M_F(name, _in_str)(array_t array, FILE *file) \
{ \ { \
M_ARRA4_CONTRACT(array); \ M_ARRA4_CONTRACT(array); \
M_ASSERT (file != NULL); \ M_ASSERT (file != NULL); \
M_C(name,_reset)(array); \ M_F(name,_reset)(array); \
int c = fgetc(file); \ int c = fgetc(file); \
if (M_UNLIKELY (c != '[')) return false; \ if (M_UNLIKELY (c != '[')) return false; \
c = fgetc(file); \ c = fgetc(file); \
@@ -1059,7 +1059,7 @@
bool b = M_CALL_IN_STR(oplist, item, file); \ bool b = M_CALL_IN_STR(oplist, item, file); \
do { c = fgetc(file); } while (isspace(c)); \ do { c = fgetc(file); } while (isspace(c)); \
if (b == false || c == EOF) { break; } \ if (b == false || c == EOF) { break; } \
M_C(name, _push_back)(array, item); \ M_F(name, _push_back)(array, item); \
} while (c == M_GET_SEPARATOR oplist); \ } while (c == M_GET_SEPARATOR oplist); \
M_CALL_CLEAR(oplist, item); \ M_CALL_CLEAR(oplist, item); \
M_ARRA4_CONTRACT(array); \ M_ARRA4_CONTRACT(array); \
@@ -1069,7 +1069,7 @@
\ \
M_IF_METHOD(OUT_SERIAL, oplist)( \ M_IF_METHOD(OUT_SERIAL, oplist)( \
static inline m_serial_return_code_t \ static inline m_serial_return_code_t \
M_C(name, _out_serial)(m_serial_write_t f, const array_t array) \ M_F(name, _out_serial)(m_serial_write_t f, const array_t array) \
{ \ { \
M_ARRA4_CONTRACT(array); \ M_ARRA4_CONTRACT(array); \
M_ASSERT (f != NULL && f->m_interface != NULL); \ M_ASSERT (f != NULL && f->m_interface != NULL); \
@@ -1077,7 +1077,7 @@
m_serial_local_t local; \ m_serial_local_t local; \
ret = f->m_interface->write_array_start(local, f, array->size); \ ret = f->m_interface->write_array_start(local, f, array->size); \
for (size_t i = 0; i < array->size; i++) { \ for (size_t i = 0; i < array->size; i++) { \
type const *item = M_C(name, _cget)(array, i); \ type const *item = M_F(name, _cget)(array, i); \
if (i != 0) { \ if (i != 0) { \
ret |= f->m_interface->write_array_next(local, f); \ ret |= f->m_interface->write_array_next(local, f); \
} \ } \
@@ -1090,28 +1090,28 @@
\ \
M_IF_METHOD2(IN_SERIAL, INIT, oplist)( \ M_IF_METHOD2(IN_SERIAL, INIT, oplist)( \
static inline m_serial_return_code_t \ static inline m_serial_return_code_t \
M_C(name, _in_serial)(array_t array, m_serial_read_t f) \ M_F(name, _in_serial)(array_t array, m_serial_read_t f) \
{ \ { \
M_ARRA4_CONTRACT(array); \ M_ARRA4_CONTRACT(array); \
M_ASSERT (f != NULL && f->m_interface != NULL); \ M_ASSERT (f != NULL && f->m_interface != NULL); \
m_serial_return_code_t ret; \ m_serial_return_code_t ret; \
m_serial_local_t local; \ m_serial_local_t local; \
size_t estimated_size = 0; \ size_t estimated_size = 0; \
M_C(name,_reset)(array); \ M_F(name,_reset)(array); \
ret = f->m_interface->read_array_start(local, f, &estimated_size); \ ret = f->m_interface->read_array_start(local, f, &estimated_size); \
if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) { \ if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) { \
return ret; \ return ret; \
} \ } \
if (estimated_size != 0) { \ if (estimated_size != 0) { \
/* The format has given an estimation of the array size */ \ /* The format has given an estimation of the array size */ \
M_C(name, _reserve)(array, estimated_size); \ M_F(name, _reserve)(array, estimated_size); \
} \ } \
type item; \ type item; \
M_CALL_INIT(oplist, item); \ M_CALL_INIT(oplist, item); \
do { \ do { \
ret = M_CALL_IN_SERIAL(oplist, item, f); \ ret = M_CALL_IN_SERIAL(oplist, item, f); \
if (ret != M_SERIAL_OK_DONE) { break; } \ if (ret != M_SERIAL_OK_DONE) { break; } \
M_C(name, _push_back)(array, item); \ M_F(name, _push_back)(array, item); \
ret = f->m_interface->read_array_next(local, f); \ ret = f->m_interface->read_array_next(local, f); \
} while (ret == M_SERIAL_OK_CONTINUE); \ } while (ret == M_SERIAL_OK_CONTINUE); \
M_CALL_CLEAR(oplist, item); \ M_CALL_CLEAR(oplist, item); \
@@ -1126,7 +1126,7 @@
function_name(name_t v \ function_name(name_t v \
M_EMPLACE_LIST_TYPE_VAR(a, exp_emplace_type) ) \ M_EMPLACE_LIST_TYPE_VAR(a, exp_emplace_type) ) \
{ \ { \
M_C(name, _subtype_ct) *data = M_C(name, _push_raw)(v); \ M_F(name, _subtype_ct) *data = M_F(name, _push_raw)(v); \
if (M_UNLIKELY (data == NULL) ) \ if (M_UNLIKELY (data == NULL) ) \
return; \ return; \
M_EMPLACE_CALL_FUNC(a, init_func, oplist, *data, exp_emplace_type); \ M_EMPLACE_CALL_FUNC(a, init_func, oplist, *data, exp_emplace_type); \
+262 -262
View File
File diff suppressed because it is too large. Load diff
+98 -98
View File
@@ -56,7 +56,7 @@ typedef enum {
otherwise the size will be a compile time constant. otherwise the size will be a compile time constant.
USAGE: BUFFER_DEF(name, type, size_of_buffer_or_0, policy[, oplist]) */ USAGE: BUFFER_DEF(name, type, size_of_buffer_or_0, policy[, oplist]) */
#define M_BUFFER_DEF(name, type, m_size, ... ) \ #define M_BUFFER_DEF(name, type, m_size, ... ) \
M_BUFFER_DEF_AS(name, M_C(name, _t), type, m_size, __VA_ARGS__) M_BUFFER_DEF_AS(name, M_F(name, _t), type, m_size, __VA_ARGS__)
/* Define a lock based buffer /* Define a lock based buffer
@@ -85,7 +85,7 @@ typedef enum {
USAGE: QUEUE_MPMC_DEF(name, type, policy, [oplist of type]) USAGE: QUEUE_MPMC_DEF(name, type, policy, [oplist of type])
*/ */
#define M_QUEUE_MPMC_DEF(name, type, ...) \ #define M_QUEUE_MPMC_DEF(name, type, ...) \
M_QUEUE_MPMC_DEF_AS(name, M_C(name,_t), type, __VA_ARGS__) M_QUEUE_MPMC_DEF_AS(name, M_F(name,_t), type, __VA_ARGS__)
/* Define a nearly lock-free queue for Many Producer Many Consummer /* Define a nearly lock-free queue for Many Producer Many Consummer
@@ -110,7 +110,7 @@ typedef enum {
USAGE: QUEUE_SPSC_DEF(name, type, policy, [oplist of type]) USAGE: QUEUE_SPSC_DEF(name, type, policy, [oplist of type])
*/ */
#define M_QUEUE_SPSC_DEF(name, type, ...) \ #define M_QUEUE_SPSC_DEF(name, type, ...) \
M_QUEUE_SPSC_DEF_AS(name, M_C(name, _t), type, __VA_ARGS__) M_QUEUE_SPSC_DEF_AS(name, M_F(name, _t), type, __VA_ARGS__)
/* Define a wait-free queue for Single Producer Single Consummer /* Define a wait-free queue for Single Producer Single Consummer
@@ -258,19 +258,19 @@ m_buff3r_number_dec(m_buff3r_number_ct n, unsigned int policy)
M_BUFF3R_DEF_TYPE(name, type, m_size, policy, oplist, buffer_t) \ M_BUFF3R_DEF_TYPE(name, type, m_size, policy, oplist, buffer_t) \
M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \ M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \
M_BUFF3R_DEF_CORE(name, type, m_size, policy, oplist, buffer_t) \ M_BUFF3R_DEF_CORE(name, type, m_size, policy, oplist, buffer_t) \
M_EMPLACE_QUEUE_DEF(name, buffer_t, M_C(name, _emplace), oplist, M_EMPLACE_QUEUE_GENE) M_EMPLACE_QUEUE_DEF(name, buffer_t, M_F(name, _emplace), oplist, M_EMPLACE_QUEUE_GENE)
/* Define the type of a buffer */ /* Define the type of a buffer */
#define M_BUFF3R_DEF_TYPE(name, type, m_size, policy, oplist, buffer_t) \ #define M_BUFF3R_DEF_TYPE(name, type, m_size, policy, oplist, buffer_t) \
\ \
/* Put each data in a separate cache line to avoid false sharing \ /* Put each data in a separate cache line to avoid false sharing \
by multiple writing threads. No need to align if there is no thread */ \ by multiple writing threads. No need to align if there is no thread */ \
typedef union M_C(name, _el_s) { \ typedef union M_F(name, _el_s) { \
type x; \ type x; \
char align[M_BUFF3R_POLICY_P(policy, M_BUFFER_THREAD_UNSAFE) ? 1 : M_ALIGN_FOR_CACHELINE_EXCLUSION]; \ char align[M_BUFF3R_POLICY_P(policy, M_BUFFER_THREAD_UNSAFE) ? 1 : M_ALIGN_FOR_CACHELINE_EXCLUSION]; \
} M_C(name, _el_ct); \ } M_F(name, _el_ct); \
\ \
typedef struct M_C(name, _s) { \ typedef struct M_F(name, _s) { \
/* Data for a producer */ \ /* Data for a producer */ \
m_mutex_t mutexPush; /* MUTEX used for pushing elements */ \ m_mutex_t mutexPush; /* MUTEX used for pushing elements */ \
size_t idx_prod; /* Index of the production threads */ \ size_t idx_prod; /* Index of the production threads */ \
@@ -286,22 +286,22 @@ m_buff3r_number_dec(m_buff3r_number_ct n, unsigned int policy)
/* number[1] := [OPTION] Number of elements being deferred in the buffer */ \ /* number[1] := [OPTION] Number of elements being deferred in the buffer */ \
m_buff3r_number_ct number[1 + M_BUFF3R_POLICY_P(policy, M_BUFFER_DEFERRED_POP)]; \ m_buff3r_number_ct number[1 + M_BUFF3R_POLICY_P(policy, M_BUFFER_DEFERRED_POP)]; \
/* If fixed size, array of elements, otherwise pointer to element */ \ /* If fixed size, array of elements, otherwise pointer to element */ \
M_C(name, _el_ct) M_BUFF3R_IF_CTE_SIZE(m_size)(data[m_size], *data); \ M_F(name, _el_ct) M_BUFF3R_IF_CTE_SIZE(m_size)(data[m_size], *data); \
} buffer_t[1]; \ } buffer_t[1]; \
\ \
typedef struct M_C(name, _s) *M_C(name, _ptr); \ typedef struct M_F(name, _s) *M_F(name, _ptr); \
typedef const struct M_C(name, _s) *M_C(name, _srcptr); \ typedef const struct M_F(name, _s) *M_F(name, _srcptr); \
/* Internal type used to unconst the buffer */ \ /* Internal type used to unconst the buffer */ \
typedef union { M_C(name, _srcptr) cptr; M_C(name, _ptr) ptr; } M_C(name, _uptr_ct); \ typedef union { M_F(name, _srcptr) cptr; M_F(name, _ptr) ptr; } M_F(name, _uptr_ct); \
/* Internal types used by the oplist */ \ /* Internal types used by the oplist */ \
typedef type M_C(name, _subtype_ct); \ typedef type M_F(name, _subtype_ct); \
typedef buffer_t M_C(name, _ct); \ typedef buffer_t M_F(name, _ct); \
/* Define the core functionnalities of a buffer */ /* Define the core functionnalities of a buffer */
#define M_BUFF3R_DEF_CORE(name, type, m_size, policy, oplist, buffer_t) \ #define M_BUFF3R_DEF_CORE(name, type, m_size, policy, oplist, buffer_t) \
\ \
static inline void \ static inline void \
M_C(name, _init)(buffer_t v, size_t size) \ M_F(name, _init)(buffer_t v, size_t size) \
{ \ { \
M_BUFF3R_IF_CTE_SIZE(m_size)(M_ASSERT(size == m_size), v->size = size); \ M_BUFF3R_IF_CTE_SIZE(m_size)(M_ASSERT(size == m_size), v->size = size); \
M_ASSERT(size <= UINT_MAX); \ M_ASSERT(size <= UINT_MAX); \
@@ -319,9 +319,9 @@ M_C(name, _init)(buffer_t v, size_t size) \
} \ } \
\ \
M_BUFF3R_IF_CTE_SIZE(m_size)( /* Statically allocated */ , \ M_BUFF3R_IF_CTE_SIZE(m_size)( /* Statically allocated */ , \
v->data = M_CALL_REALLOC(oplist, M_C(name, _el_ct), NULL, M_BUFF3R_SIZE(m_size)); \ v->data = M_CALL_REALLOC(oplist, M_F(name, _el_ct), NULL, M_BUFF3R_SIZE(m_size)); \
if (M_UNLIKELY_NOMEM (v->data == NULL)) { \ if (M_UNLIKELY_NOMEM (v->data == NULL)) { \
M_MEMORY_FULL (M_BUFF3R_SIZE(m_size)*sizeof(M_C(name, _el_ct))); \ M_MEMORY_FULL (M_BUFF3R_SIZE(m_size)*sizeof(M_F(name, _el_ct))); \
return; \ return; \
} \ } \
) \ ) \
@@ -337,7 +337,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
static inline void \ static inline void \
M_C3(m_buff3r_,name,_init)(buffer_t v) \ M_C3(m_buff3r_,name,_init)(buffer_t v) \
{ \ { \
M_C(name, _init)(v, m_size); \ M_F(name, _init)(v, m_size); \
} \ } \
, ) \ , ) \
\ \
@@ -366,7 +366,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _clear)(buffer_t v) \ M_F(name, _clear)(buffer_t v) \
{ \ { \
M_BUFF3R_CONTRACT(v,m_size); \ M_BUFF3R_CONTRACT(v,m_size); \
M_C3(m_buff3r_,name,_clear_obj)(v); \ M_C3(m_buff3r_,name,_clear_obj)(v); \
@@ -384,7 +384,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _reset)(buffer_t v) \ M_F(name, _reset)(buffer_t v) \
{ \ { \
M_BUFF3R_CONTRACT(v,m_size); \ M_BUFF3R_CONTRACT(v,m_size); \
if (!M_BUFF3R_POLICY_P((policy), M_BUFFER_THREAD_UNSAFE)) { \ if (!M_BUFF3R_POLICY_P((policy), M_BUFFER_THREAD_UNSAFE)) { \
@@ -407,21 +407,21 @@ M_C(name, _init)(buffer_t v, size_t size) \
} \ } \
\ \
static inline void M_ATTR_DEPRECATED \ static inline void M_ATTR_DEPRECATED \
M_C(name, _clean)(buffer_t v) \ M_F(name, _clean)(buffer_t v) \
{ \ { \
M_C(name,_reset)(v); \ M_F(name,_reset)(v); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _init_set)(buffer_t dest, const buffer_t src) \ M_F(name, _init_set)(buffer_t dest, const buffer_t src) \
{ \ { \
/* unconst 'src', so that we can lock it (semantically it is const) */ \ /* unconst 'src', so that we can lock it (semantically it is const) */ \
M_C(name, _uptr_ct) vu; \ M_F(name, _uptr_ct) vu; \
vu.cptr = src; \ vu.cptr = src; \
M_C(name, _ptr) v = vu.ptr; \ M_F(name, _ptr) v = vu.ptr; \
M_ASSERT (dest != v); \ M_ASSERT (dest != v); \
M_BUFF3R_CONTRACT(v,m_size); \ M_BUFF3R_CONTRACT(v,m_size); \
M_C(name, _init)(dest, M_BUFF3R_SIZE(m_size)); \ M_F(name, _init)(dest, M_BUFF3R_SIZE(m_size)); \
if (!M_BUFF3R_POLICY_P((policy), M_BUFFER_THREAD_UNSAFE)) { \ if (!M_BUFF3R_POLICY_P((policy), M_BUFFER_THREAD_UNSAFE)) { \
m_mutex_lock(v->mutexPush); \ m_mutex_lock(v->mutexPush); \
m_mutex_lock(v->mutexPop); \ m_mutex_lock(v->mutexPop); \
@@ -457,12 +457,12 @@ M_C(name, _init)(buffer_t v, size_t size) \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _set)(buffer_t dest, const buffer_t src) \ M_F(name, _set)(buffer_t dest, const buffer_t src) \
{ \ { \
/* unconst 'src', so that we can lock it (semantically it is const) */ \ /* unconst 'src', so that we can lock it (semantically it is const) */ \
M_C(name, _uptr_ct) vu; \ M_F(name, _uptr_ct) vu; \
vu.cptr = src; \ vu.cptr = src; \
M_C(name, _ptr) v = vu.ptr; \ M_F(name, _ptr) v = vu.ptr; \
M_BUFF3R_CONTRACT(dest,m_size); \ M_BUFF3R_CONTRACT(dest,m_size); \
M_BUFF3R_CONTRACT(v,m_size); \ M_BUFF3R_CONTRACT(v,m_size); \
\ \
@@ -527,7 +527,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _empty_p)(buffer_t v) \ M_F(name, _empty_p)(buffer_t v) \
{ \ { \
M_BUFF3R_CONTRACT(v,m_size); \ M_BUFF3R_CONTRACT(v,m_size); \
/* If the buffer has been configured with deferred pop \ /* If the buffer has been configured with deferred pop \
@@ -541,7 +541,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _full_p)(buffer_t v) \ M_F(name, _full_p)(buffer_t v) \
{ \ { \
M_BUFF3R_CONTRACT(v,m_size); \ M_BUFF3R_CONTRACT(v,m_size); \
return m_buff3r_number_load (v->number[0], policy) \ return m_buff3r_number_load (v->number[0], policy) \
@@ -549,14 +549,14 @@ M_C(name, _init)(buffer_t v, size_t size) \
} \ } \
\ \
static inline size_t \ static inline size_t \
M_C(name, _size)(buffer_t v) \ M_F(name, _size)(buffer_t v) \
{ \ { \
M_BUFF3R_CONTRACT(v,m_size); \ M_BUFF3R_CONTRACT(v,m_size); \
return m_buff3r_number_load (v->number[0], policy); \ return m_buff3r_number_load (v->number[0], policy); \
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _push_blocking)(buffer_t v, type const data, bool blocking) \ M_F(name, _push_blocking)(buffer_t v, type const data, bool blocking) \
{ \ { \
M_BUFF3R_CONTRACT(v,m_size); \ M_BUFF3R_CONTRACT(v,m_size); \
\ \
@@ -564,7 +564,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
if (!M_BUFF3R_POLICY_P((policy), M_BUFFER_THREAD_UNSAFE)) { \ if (!M_BUFF3R_POLICY_P((policy), M_BUFFER_THREAD_UNSAFE)) { \
m_mutex_lock(v->mutexPush); \ m_mutex_lock(v->mutexPush); \
while (!M_BUFF3R_POLICY_P((policy), M_BUFFER_PUSH_OVERWRITE) \ while (!M_BUFF3R_POLICY_P((policy), M_BUFFER_PUSH_OVERWRITE) \
&& M_C(name, _full_p)(v)) { \ && M_F(name, _full_p)(v)) { \
if (!blocking) { \ if (!blocking) { \
m_mutex_unlock(v->mutexPush); \ m_mutex_unlock(v->mutexPush); \
return false; \ return false; \
@@ -572,14 +572,14 @@ M_C(name, _init)(buffer_t v, size_t size) \
m_cond_wait(v->there_is_room_for_data, v->mutexPush); \ m_cond_wait(v->there_is_room_for_data, v->mutexPush); \
} \ } \
} else if (!M_BUFF3R_POLICY_P((policy), M_BUFFER_PUSH_OVERWRITE) \ } else if (!M_BUFF3R_POLICY_P((policy), M_BUFFER_PUSH_OVERWRITE) \
&& M_C(name, _full_p)(v)) \ && M_F(name, _full_p)(v)) \
return false; \ return false; \
M_BUFF3R_PROTECTED_CONTRACT(policy, v, m_size); \ M_BUFF3R_PROTECTED_CONTRACT(policy, v, m_size); \
\ \
size_t previousSize, idx = v->idx_prod; \ size_t previousSize, idx = v->idx_prod; \
/* INDEX computation if we have to overwrite the last element */ \ /* INDEX computation if we have to overwrite the last element */ \
if (M_UNLIKELY (M_BUFF3R_POLICY_P((policy), M_BUFFER_PUSH_OVERWRITE) \ if (M_UNLIKELY (M_BUFF3R_POLICY_P((policy), M_BUFFER_PUSH_OVERWRITE) \
&& M_C(name, _full_p)(v))) { \ && M_F(name, _full_p)(v))) { \
v->overwrite++; \ v->overwrite++; \
/* Let's overwrite the last element */ \ /* Let's overwrite the last element */ \
/* Compute the index of the last push element */ \ /* Compute the index of the last push element */ \
@@ -636,7 +636,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _pop_blocking)(type *data, buffer_t v, bool blocking) \ M_F(name, _pop_blocking)(type *data, buffer_t v, bool blocking) \
{ \ { \
M_BUFF3R_CONTRACT(v,m_size); \ M_BUFF3R_CONTRACT(v,m_size); \
M_ASSERT (data != NULL); \ M_ASSERT (data != NULL); \
@@ -644,14 +644,14 @@ M_C(name, _init)(buffer_t v, size_t size) \
/* Consummer lock (mutex lock performs an acquire memory barrier) */ \ /* Consummer lock (mutex lock performs an acquire memory barrier) */ \
if (!M_BUFF3R_POLICY_P((policy), M_BUFFER_THREAD_UNSAFE)) { \ if (!M_BUFF3R_POLICY_P((policy), M_BUFFER_THREAD_UNSAFE)) { \
m_mutex_lock(v->mutexPop); \ m_mutex_lock(v->mutexPop); \
while (M_C(name, _empty_p)(v)) { \ while (M_F(name, _empty_p)(v)) { \
if (!blocking) { \ if (!blocking) { \
m_mutex_unlock(v->mutexPop); \ m_mutex_unlock(v->mutexPop); \
return false; \ return false; \
} \ } \
m_cond_wait(v->there_is_data, v->mutexPop); \ m_cond_wait(v->there_is_data, v->mutexPop); \
} \ } \
} else if (M_C(name, _empty_p)(v)) \ } else if (M_F(name, _empty_p)(v)) \
return false; \ return false; \
M_BUFF3R_PROTECTED_CONTRACT(policy, v, m_size); \ M_BUFF3R_PROTECTED_CONTRACT(policy, v, m_size); \
\ \
@@ -707,34 +707,34 @@ M_C(name, _init)(buffer_t v, size_t size) \
\ \
\ \
static inline bool \ static inline bool \
M_C(name, _push)(buffer_t v, type const data) \ M_F(name, _push)(buffer_t v, type const data) \
{ \ { \
return M_C(name, _push_blocking)(v, data, \ return M_F(name, _push_blocking)(v, data, \
!M_BUFF3R_POLICY_P((policy), M_BUFFER_UNBLOCKING_PUSH)); \ !M_BUFF3R_POLICY_P((policy), M_BUFFER_UNBLOCKING_PUSH)); \
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _pop)(type *data, buffer_t v) \ M_F(name, _pop)(type *data, buffer_t v) \
{ \ { \
return M_C(name, _pop_blocking)(data, v, \ return M_F(name, _pop_blocking)(data, v, \
!M_BUFF3R_POLICY_P((policy), M_BUFFER_UNBLOCKING_POP)); \ !M_BUFF3R_POLICY_P((policy), M_BUFFER_UNBLOCKING_POP)); \
} \ } \
\ \
static inline size_t \ static inline size_t \
M_C(name, _overwrite)(const buffer_t v) \ M_F(name, _overwrite)(const buffer_t v) \
{ \ { \
return v->overwrite; \ return v->overwrite; \
} \ } \
\ \
static inline size_t \ static inline size_t \
M_C(name, _capacity)(const buffer_t v) \ M_F(name, _capacity)(const buffer_t v) \
{ \ { \
(void) v; /* may be unused */ \ (void) v; /* may be unused */ \
return M_BUFF3R_SIZE(m_size); \ return M_BUFF3R_SIZE(m_size); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _pop_release)(buffer_t v) \ M_F(name, _pop_release)(buffer_t v) \
{ \ { \
/* Decrement the effective number of elements in the buffer */ \ /* Decrement the effective number of elements in the buffer */ \
if (M_BUFF3R_POLICY_P((policy), M_BUFFER_DEFERRED_POP)) { \ if (M_BUFF3R_POLICY_P((policy), M_BUFFER_DEFERRED_POP)) { \
@@ -798,7 +798,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
M_QU3UE_MPMC_DEF_TYPE(name, type, policy, oplist, buffer_t) \ M_QU3UE_MPMC_DEF_TYPE(name, type, policy, oplist, buffer_t) \
M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \ M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \
M_QU3UE_MPMC_DEF_CORE(name, type, policy, oplist, buffer_t) \ M_QU3UE_MPMC_DEF_CORE(name, type, policy, oplist, buffer_t) \
M_EMPLACE_QUEUE_DEF(name, buffer_t, M_C(name, _emplace), oplist, M_EMPLACE_QUEUE_GENE) M_EMPLACE_QUEUE_DEF(name, buffer_t, M_F(name, _emplace), oplist, M_EMPLACE_QUEUE_GENE)
/* Define the type of a MPMC queue */ /* Define the type of a MPMC queue */
#define M_QU3UE_MPMC_DEF_TYPE(name, type, policy, oplist, buffer_t) \ #define M_QU3UE_MPMC_DEF_TYPE(name, type, policy, oplist, buffer_t) \
@@ -811,30 +811,30 @@ M_C(name, _init)(buffer_t v, size_t size) \
Each element is put in a separate cache line to avoid false \ Each element is put in a separate cache line to avoid false \
sharing by multiple writing threads. \ sharing by multiple writing threads. \
*/ \ */ \
typedef struct M_C(name, _el_s) { \ typedef struct M_F(name, _el_s) { \
atomic_uint seq; /* Can only increase until wrapping */ \ atomic_uint seq; /* Can only increase until wrapping */ \
type x; \ type x; \
M_CACHELINE_ALIGN(align, atomic_uint, type); \ M_CACHELINE_ALIGN(align, atomic_uint, type); \
} M_C(name, _el_ct); \ } M_F(name, _el_ct); \
\ \
/* If there is only one producer and one consummer, then they won't \ /* If there is only one producer and one consummer, then they won't \
typically use the same cache line, increasing performance. */ \ typically use the same cache line, increasing performance. */ \
typedef struct M_C(name, _s) { \ typedef struct M_F(name, _s) { \
atomic_uint ProdIdx; /* Can only increase until wrapping */ \ atomic_uint ProdIdx; /* Can only increase until wrapping */ \
M_CACHELINE_ALIGN(align1, atomic_uint); \ M_CACHELINE_ALIGN(align1, atomic_uint); \
atomic_uint ConsoIdx; /* Can only increase until wrapping */ \ atomic_uint ConsoIdx; /* Can only increase until wrapping */ \
M_CACHELINE_ALIGN(align2, atomic_uint); \ M_CACHELINE_ALIGN(align2, atomic_uint); \
M_C(name, _el_ct) *Tab; \ M_F(name, _el_ct) *Tab; \
unsigned int size; \ unsigned int size; \
} buffer_t[1]; \ } buffer_t[1]; \
\ \
typedef type M_C(name, _subtype_ct); \ typedef type M_F(name, _subtype_ct); \
typedef buffer_t M_C(name, _ct); \ typedef buffer_t M_F(name, _ct); \
/* Define the core functionnalities of a MPMC queue */ /* Define the core functionnalities of a MPMC queue */
#define M_QU3UE_MPMC_DEF_CORE(name, type, policy, oplist, buffer_t) \ #define M_QU3UE_MPMC_DEF_CORE(name, type, policy, oplist, buffer_t) \
static inline bool \ static inline bool \
M_C(name, _push)(buffer_t table, type const x) \ M_F(name, _push)(buffer_t table, type const x) \
{ \ { \
M_QU3UE_MPMC_CONTRACT(table); \ M_QU3UE_MPMC_CONTRACT(table); \
unsigned int idx = atomic_load_explicit(&table->ProdIdx, \ unsigned int idx = atomic_load_explicit(&table->ProdIdx, \
@@ -868,7 +868,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _pop)(type *ptr, buffer_t table) \ M_F(name, _pop)(type *ptr, buffer_t table) \
{ \ { \
M_QU3UE_MPMC_CONTRACT(table); \ M_QU3UE_MPMC_CONTRACT(table); \
M_ASSERT (ptr != NULL); \ M_ASSERT (ptr != NULL); \
@@ -897,7 +897,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _init)(buffer_t buffer, size_t size) \ M_F(name, _init)(buffer_t buffer, size_t size) \
{ \ { \
M_ASSERT (buffer != NULL); \ M_ASSERT (buffer != NULL); \
M_ASSERT( M_POWEROF2_P(size)); \ M_ASSERT( M_POWEROF2_P(size)); \
@@ -906,9 +906,9 @@ M_C(name, _init)(buffer_t v, size_t size) \
atomic_init(&buffer->ProdIdx, (unsigned int) size); \ atomic_init(&buffer->ProdIdx, (unsigned int) size); \
atomic_init(&buffer->ConsoIdx, (unsigned int) size); \ atomic_init(&buffer->ConsoIdx, (unsigned int) size); \
buffer->size = (unsigned int) size; \ buffer->size = (unsigned int) size; \
buffer->Tab = M_CALL_REALLOC(oplist, M_C(name, _el_ct), NULL, size); \ buffer->Tab = M_CALL_REALLOC(oplist, M_F(name, _el_ct), NULL, size); \
if (M_UNLIKELY_NOMEM (buffer->Tab == NULL)) { \ if (M_UNLIKELY_NOMEM (buffer->Tab == NULL)) { \
M_MEMORY_FULL (size*sizeof(M_C(name, _el_ct) )); \ M_MEMORY_FULL (size*sizeof(M_F(name, _el_ct) )); \
return; \ return; \
} \ } \
for(unsigned int j = 0; j < (unsigned int) size; j++) { \ for(unsigned int j = 0; j < (unsigned int) size; j++) { \
@@ -921,7 +921,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _clear)(buffer_t buffer) \ M_F(name, _clear)(buffer_t buffer) \
{ \ { \
M_QU3UE_MPMC_CONTRACT(buffer); \ M_QU3UE_MPMC_CONTRACT(buffer); \
if (!M_BUFF3R_POLICY_P((policy), M_BUFFER_PUSH_INIT_POP_MOVE)) { \ if (!M_BUFF3R_POLICY_P((policy), M_BUFFER_PUSH_INIT_POP_MOVE)) { \
@@ -946,7 +946,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
} \ } \
\ \
static inline size_t \ static inline size_t \
M_C(name, _size)(buffer_t table) \ M_F(name, _size)(buffer_t table) \
{ \ { \
M_QU3UE_MPMC_CONTRACT(table); \ M_QU3UE_MPMC_CONTRACT(table); \
const unsigned int iC = atomic_load_explicit(&table->ConsoIdx, memory_order_relaxed); \ const unsigned int iC = atomic_load_explicit(&table->ConsoIdx, memory_order_relaxed); \
@@ -965,22 +965,22 @@ M_C(name, _init)(buffer_t v, size_t size) \
} \ } \
\ \
static inline size_t \ static inline size_t \
M_C(name, _capacity)(buffer_t v) \ M_F(name, _capacity)(buffer_t v) \
{ \ { \
M_QU3UE_MPMC_CONTRACT(v); \ M_QU3UE_MPMC_CONTRACT(v); \
return v->size; \ return v->size; \
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _empty_p)(buffer_t v) \ M_F(name, _empty_p)(buffer_t v) \
{ \ { \
return M_C(name, _size) (v) == 0; \ return M_F(name, _size) (v) == 0; \
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _full_p)(buffer_t v) \ M_F(name, _full_p)(buffer_t v) \
{ \ { \
return M_C(name, _size)(v) >= v->size; \ return M_F(name, _size)(v) >= v->size; \
} \ } \
@@ -1033,7 +1033,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
M_QU3UE_SPSC_DEF_TYPE(name, type, policy, oplist, buffer_t) \ M_QU3UE_SPSC_DEF_TYPE(name, type, policy, oplist, buffer_t) \
M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \ M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \
M_QU3UE_SPSC_DEF_CORE(name, type, policy, oplist, buffer_t) \ M_QU3UE_SPSC_DEF_CORE(name, type, policy, oplist, buffer_t) \
M_EMPLACE_QUEUE_DEF(name, buffer_t, M_C(name, _emplace), oplist, M_EMPLACE_QUEUE_GENE) M_EMPLACE_QUEUE_DEF(name, buffer_t, M_F(name, _emplace), oplist, M_EMPLACE_QUEUE_GENE)
/* Define the type of a SPSC queue */ /* Define the type of a SPSC queue */
#define M_QU3UE_SPSC_DEF_TYPE(name, type, policy, oplist, buffer_t) \ #define M_QU3UE_SPSC_DEF_TYPE(name, type, policy, oplist, buffer_t) \
@@ -1042,26 +1042,26 @@ M_C(name, _init)(buffer_t v, size_t size) \
So, only one thread will write in this table. The other thread \ So, only one thread will write in this table. The other thread \
will only read. As such, there is no concurrent write, and no \ will only read. As such, there is no concurrent write, and no \
need to align the structure for best performance. */ \ need to align the structure for best performance. */ \
typedef struct M_C(name, _el_s) { \ typedef struct M_F(name, _el_s) { \
type x; \ type x; \
} M_C(name, _el_ct); \ } M_F(name, _el_ct); \
\ \
typedef struct M_C(name, _s) { \ typedef struct M_F(name, _s) { \
atomic_uint consoIdx; /* Can only increase until overflow */ \ atomic_uint consoIdx; /* Can only increase until overflow */ \
unsigned int size; \ unsigned int size; \
M_C(name, _el_ct) *Tab; \ M_F(name, _el_ct) *Tab; \
M_CACHELINE_ALIGN(align, atomic_uint, size_t, M_C(name, _el_ct) *); \ M_CACHELINE_ALIGN(align, atomic_uint, size_t, M_F(name, _el_ct) *); \
atomic_uint prodIdx; /* Can only increase until overflow */ \ atomic_uint prodIdx; /* Can only increase until overflow */ \
} buffer_t[1]; \ } buffer_t[1]; \
\ \
typedef type M_C(name, _subtype_ct); \ typedef type M_F(name, _subtype_ct); \
typedef buffer_t M_C(name, _ct); \ typedef buffer_t M_F(name, _ct); \
/* Define the core functionnalities of a SPSC queue */ /* Define the core functionnalities of a SPSC queue */
#define M_QU3UE_SPSC_DEF_CORE(name, type, policy, oplist, buffer_t) \ #define M_QU3UE_SPSC_DEF_CORE(name, type, policy, oplist, buffer_t) \
\ \
static inline bool \ static inline bool \
M_C(name, _push)(buffer_t table, type const x) \ M_F(name, _push)(buffer_t table, type const x) \
{ \ { \
M_QU3UE_SPSC_CONTRACT(table); \ M_QU3UE_SPSC_CONTRACT(table); \
unsigned int r = atomic_load_explicit(&table->consoIdx, \ unsigned int r = atomic_load_explicit(&table->consoIdx, \
@@ -1082,7 +1082,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _push_move)(buffer_t table, type *x) \ M_F(name, _push_move)(buffer_t table, type *x) \
{ \ { \
M_QU3UE_SPSC_CONTRACT(table); \ M_QU3UE_SPSC_CONTRACT(table); \
unsigned int r = atomic_load_explicit(&table->consoIdx, \ unsigned int r = atomic_load_explicit(&table->consoIdx, \
@@ -1103,7 +1103,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _pop)(type *ptr, buffer_t table) \ M_F(name, _pop)(type *ptr, buffer_t table) \
{ \ { \
M_QU3UE_SPSC_CONTRACT(table); \ M_QU3UE_SPSC_CONTRACT(table); \
M_ASSERT (ptr != NULL); \ M_ASSERT (ptr != NULL); \
@@ -1125,7 +1125,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
} \ } \
\ \
static inline unsigned \ static inline unsigned \
M_C(name, _push_bulk)(buffer_t table, unsigned n, type const x[]) \ M_F(name, _push_bulk)(buffer_t table, unsigned n, type const x[]) \
{ \ { \
M_QU3UE_SPSC_CONTRACT(table); \ M_QU3UE_SPSC_CONTRACT(table); \
M_ASSERT (x != NULL); \ M_ASSERT (x != NULL); \
@@ -1151,7 +1151,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
} \ } \
\ \
static inline unsigned \ static inline unsigned \
M_C(name, _pop_bulk)(unsigned int n, type ptr[], buffer_t table) \ M_F(name, _pop_bulk)(unsigned int n, type ptr[], buffer_t table) \
{ \ { \
M_QU3UE_SPSC_CONTRACT(table); \ M_QU3UE_SPSC_CONTRACT(table); \
M_ASSERT (ptr != NULL); \ M_ASSERT (ptr != NULL); \
@@ -1177,7 +1177,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _push_force)(buffer_t table, type const x) \ M_F(name, _push_force)(buffer_t table, type const x) \
{ \ { \
M_QU3UE_SPSC_CONTRACT(table); \ M_QU3UE_SPSC_CONTRACT(table); \
unsigned int r = atomic_load_explicit(&table->consoIdx, \ unsigned int r = atomic_load_explicit(&table->consoIdx, \
@@ -1200,7 +1200,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
} \ } \
\ \
static inline size_t \ static inline size_t \
M_C(name, _size)(buffer_t table) \ M_F(name, _size)(buffer_t table) \
{ \ { \
M_QU3UE_SPSC_CONTRACT(table); \ M_QU3UE_SPSC_CONTRACT(table); \
unsigned int r = atomic_load_explicit(&table->consoIdx, \ unsigned int r = atomic_load_explicit(&table->consoIdx, \
@@ -1221,25 +1221,25 @@ M_C(name, _init)(buffer_t v, size_t size) \
} \ } \
\ \
static inline size_t \ static inline size_t \
M_C(name, _capacity)(buffer_t v) \ M_F(name, _capacity)(buffer_t v) \
{ \ { \
return v->size; \ return v->size; \
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _empty_p)(buffer_t v) \ M_F(name, _empty_p)(buffer_t v) \
{ \ { \
return M_C(name, _size) (v) == 0; \ return M_F(name, _size) (v) == 0; \
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _full_p)(buffer_t v) \ M_F(name, _full_p)(buffer_t v) \
{ \ { \
return M_C(name, _size)(v) >= v->size; \ return M_F(name, _size)(v) >= v->size; \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _init)(buffer_t buffer, size_t size) \ M_F(name, _init)(buffer_t buffer, size_t size) \
{ \ { \
M_ASSERT (buffer != NULL); \ M_ASSERT (buffer != NULL); \
M_ASSERT( M_POWEROF2_P(size)); \ M_ASSERT( M_POWEROF2_P(size)); \
@@ -1248,9 +1248,9 @@ M_C(name, _init)(buffer_t v, size_t size) \
atomic_init(&buffer->prodIdx, (unsigned int) size); \ atomic_init(&buffer->prodIdx, (unsigned int) size); \
atomic_init(&buffer->consoIdx, (unsigned int) size); \ atomic_init(&buffer->consoIdx, (unsigned int) size); \
buffer->size = (unsigned int) size; \ buffer->size = (unsigned int) size; \
buffer->Tab = M_CALL_REALLOC(oplist, M_C(name, _el_ct), NULL, size); \ buffer->Tab = M_CALL_REALLOC(oplist, M_F(name, _el_ct), NULL, size); \
if (M_UNLIKELY_NOMEM (buffer->Tab == NULL)) { \ if (M_UNLIKELY_NOMEM (buffer->Tab == NULL)) { \
M_MEMORY_FULL (size*sizeof(M_C(name, _el_ct) )); \ M_MEMORY_FULL (size*sizeof(M_F(name, _el_ct) )); \
return; \ return; \
} \ } \
if (!M_BUFF3R_POLICY_P((policy), M_BUFFER_PUSH_INIT_POP_MOVE)) { \ if (!M_BUFF3R_POLICY_P((policy), M_BUFFER_PUSH_INIT_POP_MOVE)) { \
@@ -1262,7 +1262,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _clear)(buffer_t buffer) \ M_F(name, _clear)(buffer_t buffer) \
{ \ { \
M_QU3UE_SPSC_CONTRACT(buffer); \ M_QU3UE_SPSC_CONTRACT(buffer); \
if (!M_BUFF3R_POLICY_P((policy), M_BUFFER_PUSH_INIT_POP_MOVE)) { \ if (!M_BUFF3R_POLICY_P((policy), M_BUFFER_PUSH_INIT_POP_MOVE)) { \
@@ -1304,18 +1304,18 @@ M_C(name, _init)(buffer_t v, size_t size) \
/* OPLIST definition of a buffer */ /* OPLIST definition of a buffer */
#define M_BUFF3R_OPLIST_P3(name, oplist) \ #define M_BUFF3R_OPLIST_P3(name, oplist) \
(INIT(M_C3(m_buff3r_,name, _init)) \ (INIT(M_C3(m_buff3r_,name, _init)) \
,INIT_SET(M_C(name, _init_set)) \ ,INIT_SET(M_F(name, _init_set)) \
,SET(M_C(name, _set)) \ ,SET(M_F(name, _set)) \
,CLEAR(M_C(name, _clear)) \ ,CLEAR(M_F(name, _clear)) \
,NAME(name) \ ,NAME(name) \
,TYPE(M_C(name,_ct)) \ ,TYPE(M_F(name,_ct)) \
,SUBTYPE(M_C(name, _subtype_ct)) \ ,SUBTYPE(M_F(name, _subtype_ct)) \
,RESET(M_C(name,_reset)) \ ,RESET(M_F(name,_reset)) \
,PUSH(M_C(name,_push)) \ ,PUSH(M_F(name,_push)) \
,POP(M_C(name,_pop)) \ ,POP(M_F(name,_pop)) \
,OPLIST(oplist) \ ,OPLIST(oplist) \
,EMPTY_P(M_C(name, _empty_p)), \ ,EMPTY_P(M_F(name, _empty_p)), \
,GET_SIZE(M_C(name, _size)) \ ,GET_SIZE(M_F(name, _size)) \
) )
+120 -120
View File
@@ -46,55 +46,55 @@ M_BEGIN_PROTECTED_CODE
/* Classic internal Singly List without allocation */ /* Classic internal Singly List without allocation */
#define M_CMEMP00L_DEF_SINGLY_LIST(name, type_t) \ #define M_CMEMP00L_DEF_SINGLY_LIST(name, type_t) \
\ \
typedef struct M_C(name, _slist_node_s) { \ typedef struct M_F(name, _slist_node_s) { \
struct M_C(name, _slist_node_s) *next; \ struct M_F(name, _slist_node_s) *next; \
type_t data; \ type_t data; \
} M_C(name, _slist_node_ct); \ } M_F(name, _slist_node_ct); \
\ \
typedef struct M_C(name, _slist_node_s) *M_C(name, _slist_ct)[1]; \ typedef struct M_F(name, _slist_node_s) *M_F(name, _slist_ct)[1]; \
\ \
static inline void \ static inline void \
M_C(name, _slist_init)(M_C(name, _slist_ct) list) \ M_F(name, _slist_init)(M_F(name, _slist_ct) list) \
{ \ { \
*list = NULL; \ *list = NULL; \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _slist_push)(M_C(name, _slist_ct) list, \ M_F(name, _slist_push)(M_F(name, _slist_ct) list, \
M_C(name, _slist_node_ct) *node) \ M_F(name, _slist_node_ct) *node) \
{ \ { \
node->next = *list; \ node->next = *list; \
*list = node; \ *list = node; \
} \ } \
\ \
static inline M_C(name, _slist_node_ct) * \ static inline M_F(name, _slist_node_ct) * \
M_C(name, _slist_pop)(M_C(name, _slist_ct) list) \ M_F(name, _slist_pop)(M_F(name, _slist_ct) list) \
{ \ { \
M_ASSERT (*list != NULL); \ M_ASSERT (*list != NULL); \
M_C(name, _slist_node_ct) *node = *list; \ M_F(name, _slist_node_ct) *node = *list; \
*list = node->next; \ *list = node->next; \
M_IF_DEBUG(node->next = NULL;) \ M_IF_DEBUG(node->next = NULL;) \
return node; \ return node; \
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _slist_empty_p)(M_C(name, _slist_ct) list) \ M_F(name, _slist_empty_p)(M_F(name, _slist_ct) list) \
{ \ { \
return *list == NULL; \ return *list == NULL; \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _slist_move)(M_C(name, _slist_ct) list, \ M_F(name, _slist_move)(M_F(name, _slist_ct) list, \
M_C(name, _slist_ct) src) \ M_F(name, _slist_ct) src) \
{ \ { \
*list = *src; \ *list = *src; \
*src = NULL; \ *src = NULL; \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _slist_clear)(M_C(name, _slist_ct) list) \ M_F(name, _slist_clear)(M_F(name, _slist_ct) list) \
{ \ { \
M_C(name, _slist_node_ct) *it = *list, *next; \ M_F(name, _slist_node_ct) *it = *list, *next; \
while (it) { \ while (it) { \
next = it->next; \ next = it->next; \
M_MEMORY_DEL(it); \ M_MEMORY_DEL(it); \
@@ -125,23 +125,23 @@ M_BEGIN_PROTECTED_CODE
to reduce memory consumption too (non compatible with C++ ...) */ to reduce memory consumption too (non compatible with C++ ...) */
#define M_CMEMP00L_DEF_LF_QUEUE(name, type_t) \ #define M_CMEMP00L_DEF_LF_QUEUE(name, type_t) \
\ \
typedef struct M_C(name, _lf_node_s) { \ typedef struct M_F(name, _lf_node_s) { \
M_ATTR_EXTENSION _Atomic(struct M_C(name, _lf_node_s) *) next; \ M_ATTR_EXTENSION _Atomic(struct M_F(name, _lf_node_s) *) next; \
m_gc_atomic_ticket_ct cpt; \ m_gc_atomic_ticket_ct cpt; \
M_C(name, _slist_ct) list; \ M_F(name, _slist_ct) list; \
} M_C(name, _lf_node_t); \ } M_F(name, _lf_node_t); \
\ \
typedef struct M_C(name, _lflist_s) { \ typedef struct M_F(name, _lflist_s) { \
M_ATTR_EXTENSION _Atomic(M_C(name, _lf_node_t) *) head; \ M_ATTR_EXTENSION _Atomic(M_F(name, _lf_node_t) *) head; \
char align1[M_ALIGN_FOR_CACHELINE_EXCLUSION]; \ char align1[M_ALIGN_FOR_CACHELINE_EXCLUSION]; \
M_ATTR_EXTENSION _Atomic(M_C(name, _lf_node_t) *) tail; \ M_ATTR_EXTENSION _Atomic(M_F(name, _lf_node_t) *) tail; \
char align2[M_ALIGN_FOR_CACHELINE_EXCLUSION]; \ char align2[M_ALIGN_FOR_CACHELINE_EXCLUSION]; \
M_C(name, _lf_node_t) nil; \ M_F(name, _lf_node_t) nil; \
} M_C(name, _lflist_ct)[1]; \ } M_F(name, _lflist_ct)[1]; \
\ \
static inline void \ static inline void \
M_C(name, _lflist_init)(M_C(name, _lflist_ct) list, \ M_F(name, _lflist_init)(M_F(name, _lflist_ct) list, \
M_C(name, _lf_node_t) *node) \ M_F(name, _lf_node_t) *node) \
{ \ { \
atomic_init(&list->head, node); \ atomic_init(&list->head, node); \
atomic_init(&list->tail, node); \ atomic_init(&list->tail, node); \
@@ -149,17 +149,17 @@ M_BEGIN_PROTECTED_CODE
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _lflist_empty_p)(M_C(name, _lflist_ct) list) \ M_F(name, _lflist_empty_p)(M_F(name, _lflist_ct) list) \
{ \ { \
return atomic_load(&list->tail) == atomic_load(&list->head); \ return atomic_load(&list->tail) == atomic_load(&list->head); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _lflist_push)(M_C(name, _lflist_ct) list, \ M_F(name, _lflist_push)(M_F(name, _lflist_ct) list, \
M_C(name, _lf_node_t) *node, m_core_backoff_ct bkoff) \ M_F(name, _lf_node_t) *node, m_core_backoff_ct bkoff) \
{ \ { \
M_C(name, _lf_node_t) *tail; \ M_F(name, _lf_node_t) *tail; \
M_C(name, _lf_node_t) *next; \ M_F(name, _lf_node_t) *next; \
\ \
atomic_store_explicit(&node->next, &list->nil, memory_order_relaxed); \ atomic_store_explicit(&node->next, &list->nil, memory_order_relaxed); \
m_core_backoff_reset(bkoff); \ m_core_backoff_reset(bkoff); \
@@ -190,12 +190,12 @@ M_BEGIN_PROTECTED_CODE
memory_order_relaxed); \ memory_order_relaxed); \
} \ } \
\ \
static inline M_C(name, _lf_node_t) * \ static inline M_F(name, _lf_node_t) * \
M_C(name, _lflist_pop)(M_C(name, _lflist_ct) list, m_core_backoff_ct bkoff) \ M_F(name, _lflist_pop)(M_F(name, _lflist_ct) list, m_core_backoff_ct bkoff) \
{ \ { \
M_C(name, _lf_node_t) *head; \ M_F(name, _lf_node_t) *head; \
M_C(name, _lf_node_t) *tail; \ M_F(name, _lf_node_t) *tail; \
M_C(name, _lf_node_t) *next; \ M_F(name, _lf_node_t) *next; \
\ \
/* Reinitialize backoff */ \ /* Reinitialize backoff */ \
m_core_backoff_reset(bkoff); \ m_core_backoff_reset(bkoff); \
@@ -236,18 +236,18 @@ M_BEGIN_PROTECTED_CODE
provided that the node we return is older than the one we should return, \ provided that the node we return is older than the one we should return, \
Therefore, we return the previous dummy head. \ Therefore, we return the previous dummy head. \
As such, it is not the original MSqueue algorithm. */ \ As such, it is not the original MSqueue algorithm. */ \
M_IF_DEBUG(atomic_store(&head->next, (M_C(name, _lf_node_t) *) 0);) \ M_IF_DEBUG(atomic_store(&head->next, (M_F(name, _lf_node_t) *) 0);) \
return head; \ return head; \
} \ } \
\ \
/* Dequeue a node if the node is old enough */ \ /* Dequeue a node if the node is old enough */ \
static inline M_C(name, _lf_node_t) * \ static inline M_F(name, _lf_node_t) * \
M_C(name, _lflist_pop_if)(M_C(name, _lflist_ct) list, \ M_F(name, _lflist_pop_if)(M_F(name, _lflist_ct) list, \
m_gc_ticket_ct age, m_core_backoff_ct bkoff) \ m_gc_ticket_ct age, m_core_backoff_ct bkoff) \
{ \ { \
M_C(name, _lf_node_t) *head; \ M_F(name, _lf_node_t) *head; \
M_C(name, _lf_node_t) *tail; \ M_F(name, _lf_node_t) *tail; \
M_C(name, _lf_node_t) *next; \ M_F(name, _lf_node_t) *next; \
\ \
m_core_backoff_reset(bkoff); \ m_core_backoff_reset(bkoff); \
while (true) { \ while (true) { \
@@ -277,28 +277,28 @@ M_BEGIN_PROTECTED_CODE
} \ } \
} \ } \
} \ } \
M_IF_DEBUG(atomic_store(&head->next, (M_C(name, _lf_node_t) *) 0);) \ M_IF_DEBUG(atomic_store(&head->next, (M_F(name, _lf_node_t) *) 0);) \
return head; \ return head; \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _lflist_clear)(M_C(name, _lflist_ct) list) \ M_F(name, _lflist_clear)(M_F(name, _lflist_ct) list) \
{ \ { \
m_core_backoff_ct bkoff; \ m_core_backoff_ct bkoff; \
m_core_backoff_init(bkoff); \ m_core_backoff_init(bkoff); \
while (true) { \ while (true) { \
M_C(name, _lf_node_t) *node = M_C(name, _lflist_pop)(list, bkoff); \ M_F(name, _lf_node_t) *node = M_F(name, _lflist_pop)(list, bkoff); \
if (node == NULL) break; \ if (node == NULL) break; \
M_C(name, _lf_node_t) *next = atomic_load_explicit(&node->next, \ M_F(name, _lf_node_t) *next = atomic_load_explicit(&node->next, \
memory_order_relaxed); \ memory_order_relaxed); \
M_C(name, _slist_clear)(node->list); \ M_F(name, _slist_clear)(node->list); \
M_MEMORY_DEL(node); \ M_MEMORY_DEL(node); \
node = next; \ node = next; \
} \ } \
/* Dummy node to free too */ \ /* Dummy node to free too */ \
M_C(name, _lf_node_t) *dummy; \ M_F(name, _lf_node_t) *dummy; \
dummy = atomic_load_explicit(&list->head, memory_order_relaxed); \ dummy = atomic_load_explicit(&list->head, memory_order_relaxed); \
M_C(name, _slist_clear)(dummy->list); \ M_F(name, _slist_clear)(dummy->list); \
M_MEMORY_DEL(dummy); \ M_MEMORY_DEL(dummy); \
} \ } \
@@ -306,26 +306,26 @@ M_BEGIN_PROTECTED_CODE
As such it is a non Lock-Free path. */ As such it is a non Lock-Free path. */
#define M_CMEMP00L_DEF_SYSTEM_ALLOC(name, type_t) \ #define M_CMEMP00L_DEF_SYSTEM_ALLOC(name, type_t) \
\ \
static inline M_C(name, _lf_node_t) * \ static inline M_F(name, _lf_node_t) * \
M_C(name, _alloc_node)(unsigned int initial) \ M_F(name, _alloc_node)(unsigned int initial) \
{ \ { \
M_C(name, _lf_node_t) * node; \ M_F(name, _lf_node_t) * node; \
node = M_MEMORY_ALLOC(M_C(name, _lf_node_t)); \ node = M_MEMORY_ALLOC(M_F(name, _lf_node_t)); \
if (M_UNLIKELY_NOMEM (node == NULL)) { \ if (M_UNLIKELY_NOMEM (node == NULL)) { \
M_MEMORY_FULL(sizeof(M_C(name, _lf_node_t))); \ M_MEMORY_FULL(sizeof(M_F(name, _lf_node_t))); \
return NULL; \ return NULL; \
} \ } \
atomic_init(&node->next, (M_C(name, _lf_node_t) *) 0); \ atomic_init(&node->next, (M_F(name, _lf_node_t) *) 0); \
atomic_init(&node->cpt, 0UL); \ atomic_init(&node->cpt, 0UL); \
M_C(name, _slist_init)(node->list); \ M_F(name, _slist_init)(node->list); \
for(unsigned i = 0; i < initial; i++) { \ for(unsigned i = 0; i < initial; i++) { \
M_C(name, _slist_node_ct) *n; \ M_F(name, _slist_node_ct) *n; \
n = M_MEMORY_ALLOC(M_C(name, _slist_node_ct)); \ n = M_MEMORY_ALLOC(M_F(name, _slist_node_ct)); \
if (M_UNLIKELY_NOMEM (n == NULL)) { \ if (M_UNLIKELY_NOMEM (n == NULL)) { \
M_MEMORY_FULL(sizeof(M_C(name, _lf_node_t))); \ M_MEMORY_FULL(sizeof(M_F(name, _lf_node_t))); \
return NULL; \ return NULL; \
} \ } \
M_C(name, _slist_push)(node->list, n); \ M_F(name, _slist_push)(node->list, n); \
} \ } \
return node; \ return node; \
} \ } \
@@ -388,39 +388,39 @@ M_BEGIN_PROTECTED_CODE
*/ */
#define M_CMEMP00L_DEF_LFMP_THREAD_MEMPOOL(name, type_t) \ #define M_CMEMP00L_DEF_LFMP_THREAD_MEMPOOL(name, type_t) \
\ \
typedef struct M_C(name, _lfmp_thread_s) { \ typedef struct M_F(name, _lfmp_thread_s) { \
M_C(name, _slist_ct) free; \ M_F(name, _slist_ct) free; \
M_C(name, _slist_ct) to_be_reclaimed; \ M_F(name, _slist_ct) to_be_reclaimed; \
M_CACHELINE_ALIGN(align1, M_C(name, _slist_ct), M_C(name, _slist_ct)); \ M_CACHELINE_ALIGN(align1, M_F(name, _slist_ct), M_F(name, _slist_ct)); \
} M_C(name, _lfmp_thread_ct); \ } M_F(name, _lfmp_thread_ct); \
\ \
static inline void \ static inline void \
M_C(name, _lfmp_thread_init)(M_C(name, _lfmp_thread_ct) *t) \ M_F(name, _lfmp_thread_init)(M_F(name, _lfmp_thread_ct) *t) \
{ \ { \
M_C(name, _slist_init)(t->free); \ M_F(name, _slist_init)(t->free); \
M_C(name, _slist_init)(t->to_be_reclaimed); \ M_F(name, _slist_init)(t->to_be_reclaimed); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _lfmp_thread_clear)(M_C(name, _lfmp_thread_ct) *t) \ M_F(name, _lfmp_thread_clear)(M_F(name, _lfmp_thread_ct) *t) \
{ \ { \
M_ASSERT(M_C(name, _slist_empty_p)(t->to_be_reclaimed)); \ M_ASSERT(M_F(name, _slist_empty_p)(t->to_be_reclaimed)); \
M_C(name, _slist_clear)(t->free); \ M_F(name, _slist_clear)(t->free); \
M_C(name, _slist_clear)(t->to_be_reclaimed); \ M_F(name, _slist_clear)(t->to_be_reclaimed); \
} \ } \
/* NOTE: once a node is deleted, its data are kept readable until the future GC */ /* NOTE: once a node is deleted, its data are kept readable until the future GC */
#define M_CMEMP00L_DEF_LF_MEMPOOL(name, type_t) \ #define M_CMEMP00L_DEF_LF_MEMPOOL(name, type_t) \
\ \
typedef struct M_C(name, _s) { \ typedef struct M_F(name, _s) { \
unsigned initial; \ unsigned initial; \
M_C(name, _lfmp_thread_ct) *thread_data; \ M_F(name, _lfmp_thread_ct) *thread_data; \
M_C(name, _lflist_ct) free; \ M_F(name, _lflist_ct) free; \
M_C(name, _lflist_ct) to_be_reclaimed; \ M_F(name, _lflist_ct) to_be_reclaimed; \
M_C(name, _lflist_ct) empty; \ M_F(name, _lflist_ct) empty; \
m_cmemp00l_list_ct mempool_node; \ m_cmemp00l_list_ct mempool_node; \
struct m_gc_s *gc_mem; \ struct m_gc_s *gc_mem; \
} M_C(name, _t)[1]; \ } M_F(name, _t)[1]; \
\ \
/* Garbage collect of the nodes of the mempool on sleep */ \ /* Garbage collect of the nodes of the mempool on sleep */ \
static inline void \ static inline void \
@@ -428,59 +428,59 @@ M_BEGIN_PROTECTED_CODE
m_gc_tid_t id, m_gc_ticket_ct ticket, m_gc_ticket_ct min_ticket) \ m_gc_tid_t id, m_gc_ticket_ct ticket, m_gc_ticket_ct min_ticket) \
{ \ { \
/* Get back the mempool from the node */ \ /* Get back the mempool from the node */ \
struct M_C(name, _s) *mempool = \ struct M_F(name, _s) *mempool = \
M_TYPE_FROM_FIELD(struct M_C(name, _s), data, m_cmemp00l_list_ct, mempool_node); \ M_TYPE_FROM_FIELD(struct M_F(name, _s), data, m_cmemp00l_list_ct, mempool_node); \
\ \
/* Move the local nodes of the mempool to be reclaimed to the thread into the global pool */ \ /* Move the local nodes of the mempool to be reclaimed to the thread into the global pool */ \
if (!M_C(name, _slist_empty_p)(mempool->thread_data[id].to_be_reclaimed)) { \ if (!M_F(name, _slist_empty_p)(mempool->thread_data[id].to_be_reclaimed)) { \
M_C(name, _lf_node_t) *node; \ M_F(name, _lf_node_t) *node; \
/* Get a new empty group of nodes */ \ /* Get a new empty group of nodes */ \
node = M_C(name, _lflist_pop)(mempool->empty, gc_mem->thread_data[id].bkoff); \ node = M_F(name, _lflist_pop)(mempool->empty, gc_mem->thread_data[id].bkoff); \
if (M_UNLIKELY (node == NULL)) { \ if (M_UNLIKELY (node == NULL)) { \
/* Fail to get an empty group of node. \ /* Fail to get an empty group of node. \
Alloc a new one from the system */ \ Alloc a new one from the system */ \
node = M_C(name, _alloc_node)(0); \ node = M_F(name, _alloc_node)(0); \
M_ASSERT(node != NULL); \ M_ASSERT(node != NULL); \
} \ } \
M_ASSERT(M_C(name, _slist_empty_p)(node->list)); \ M_ASSERT(M_F(name, _slist_empty_p)(node->list)); \
M_C(name, _slist_move)(node->list, mempool->thread_data[id].to_be_reclaimed); \ M_F(name, _slist_move)(node->list, mempool->thread_data[id].to_be_reclaimed); \
atomic_store_explicit(&node->cpt, ticket, memory_order_relaxed); \ atomic_store_explicit(&node->cpt, ticket, memory_order_relaxed); \
M_C(name, _lflist_push)(mempool->to_be_reclaimed, node, gc_mem->thread_data[id].bkoff); \ M_F(name, _lflist_push)(mempool->to_be_reclaimed, node, gc_mem->thread_data[id].bkoff); \
} \ } \
\ \
/* Perform a GC of the freelist of nodes */ \ /* Perform a GC of the freelist of nodes */ \
while (true) { \ while (true) { \
M_C(name, _lf_node_t) *node; \ M_F(name, _lf_node_t) *node; \
node = M_C(name, _lflist_pop_if)(mempool->to_be_reclaimed, \ node = M_F(name, _lflist_pop_if)(mempool->to_be_reclaimed, \
min_ticket, gc_mem->thread_data[id].bkoff); \ min_ticket, gc_mem->thread_data[id].bkoff); \
if (node == NULL) break; \ if (node == NULL) break; \
M_C(name, _lflist_push)(mempool->free, node, gc_mem->thread_data[id].bkoff); \ M_F(name, _lflist_push)(mempool->free, node, gc_mem->thread_data[id].bkoff); \
} \ } \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _init)(M_C(name, _t) mem, m_gc_t gc_mem, \ M_F(name, _init)(M_F(name, _t) mem, m_gc_t gc_mem, \
unsigned init_node_count, unsigned init_group_count) \ unsigned init_node_count, unsigned init_group_count) \
{ \ { \
const size_t max_thread = gc_mem->max_thread; \ const size_t max_thread = gc_mem->max_thread; \
/* Initialize the thread data of the mempool */ \ /* Initialize the thread data of the mempool */ \
mem->thread_data = M_MEMORY_REALLOC(M_C(name, _lfmp_thread_ct), NULL, max_thread); \ mem->thread_data = M_MEMORY_REALLOC(M_F(name, _lfmp_thread_ct), NULL, max_thread); \
if (M_UNLIKELY_NOMEM (mem->thread_data == NULL)) { \ if (M_UNLIKELY_NOMEM (mem->thread_data == NULL)) { \
M_MEMORY_FULL(max_thread * sizeof(M_C(name, _lfmp_thread_ct))); \ M_MEMORY_FULL(max_thread * sizeof(M_F(name, _lfmp_thread_ct))); \
return; \ return; \
} \ } \
for(unsigned i = 0; i < max_thread;i++) { \ for(unsigned i = 0; i < max_thread;i++) { \
M_C(name, _lfmp_thread_init)(&mem->thread_data[i]); \ M_F(name, _lfmp_thread_init)(&mem->thread_data[i]); \
} \ } \
/* Preallocate some group of nodes for the mempool */ \ /* Preallocate some group of nodes for the mempool */ \
mem->initial = M_MAX(M_CMEMP00L_MIN_NODE_PER_GROUP, init_node_count); \ mem->initial = M_MAX(M_CMEMP00L_MIN_NODE_PER_GROUP, init_node_count); \
M_C(name, _lflist_init)(mem->free, M_C(name, _alloc_node)(init_node_count)); \ M_F(name, _lflist_init)(mem->free, M_F(name, _alloc_node)(init_node_count)); \
M_C(name, _lflist_init)(mem->to_be_reclaimed, M_C(name, _alloc_node)(init_node_count)); \ M_F(name, _lflist_init)(mem->to_be_reclaimed, M_F(name, _alloc_node)(init_node_count)); \
M_C(name, _lflist_init)(mem->empty, M_C(name, _alloc_node)(0)); \ M_F(name, _lflist_init)(mem->empty, M_F(name, _alloc_node)(0)); \
for(unsigned i = 1; i < init_group_count; i++) { \ for(unsigned i = 1; i < init_group_count; i++) { \
M_C(name, _lflist_push)(mem->free, M_C(name, _alloc_node)(init_node_count), \ M_F(name, _lflist_push)(mem->free, M_F(name, _alloc_node)(init_node_count), \
gc_mem->thread_data[0].bkoff); \ gc_mem->thread_data[0].bkoff); \
M_C(name, _lflist_push)(mem->empty, M_C(name, _alloc_node)(0), \ M_F(name, _lflist_push)(mem->empty, M_F(name, _alloc_node)(0), \
gc_mem->thread_data[0].bkoff); \ gc_mem->thread_data[0].bkoff); \
} \ } \
/* Register the mempool in the GC */ \ /* Register the mempool in the GC */ \
@@ -491,55 +491,55 @@ M_BEGIN_PROTECTED_CODE
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _clear)(M_C(name, _t) mem) \ M_F(name, _clear)(M_F(name, _t) mem) \
{ \ { \
const unsigned max_thread = mem->gc_mem->max_thread; \ const unsigned max_thread = mem->gc_mem->max_thread; \
for(unsigned i = 0; i < max_thread;i++) { \ for(unsigned i = 0; i < max_thread;i++) { \
M_C(name, _lfmp_thread_clear)(&mem->thread_data[i]); \ M_F(name, _lfmp_thread_clear)(&mem->thread_data[i]); \
} \ } \
M_MEMORY_FREE(mem->thread_data); \ M_MEMORY_FREE(mem->thread_data); \
mem->thread_data = NULL; \ mem->thread_data = NULL; \
M_C(name, _lflist_clear)(mem->empty); \ M_F(name, _lflist_clear)(mem->empty); \
M_C(name, _lflist_clear)(mem->free); \ M_F(name, _lflist_clear)(mem->free); \
M_ASSERT(M_C(name, _lflist_empty_p)(mem->to_be_reclaimed)); \ M_ASSERT(M_F(name, _lflist_empty_p)(mem->to_be_reclaimed)); \
M_C(name, _lflist_clear)(mem->to_be_reclaimed); \ M_F(name, _lflist_clear)(mem->to_be_reclaimed); \
/* TODO: Unregister from the GC? */ \ /* TODO: Unregister from the GC? */ \
} \ } \
\ \
static inline type_t * \ static inline type_t * \
M_C(name, _new)(M_C(name, _t) mem, m_gc_tid_t id) \ M_F(name, _new)(M_F(name, _t) mem, m_gc_tid_t id) \
{ \ { \
M_C(name, _slist_node_ct) *snode; \ M_F(name, _slist_node_ct) *snode; \
M_C(name, _lf_node_t) *node; \ M_F(name, _lf_node_t) *node; \
while (true) { \ while (true) { \
/* Fast & likely path where we access the thread pool of nodes */ \ /* Fast & likely path where we access the thread pool of nodes */ \
if (M_LIKELY(!M_C(name, _slist_empty_p)(mem->thread_data[id].free))) { \ if (M_LIKELY(!M_F(name, _slist_empty_p)(mem->thread_data[id].free))) { \
snode = M_C(name, _slist_pop)(mem->thread_data[id].free); \ snode = M_F(name, _slist_pop)(mem->thread_data[id].free); \
return &snode->data; \ return &snode->data; \
} \ } \
/* Request a group node to the freelist of groups */ \ /* Request a group node to the freelist of groups */ \
node = M_C(name, _lflist_pop)(mem->free, mem->gc_mem->thread_data[id].bkoff); \ node = M_F(name, _lflist_pop)(mem->free, mem->gc_mem->thread_data[id].bkoff); \
if (M_UNLIKELY (node == NULL)) { \ if (M_UNLIKELY (node == NULL)) { \
/* Request a new group to the system. Non Lock Free path */ \ /* Request a new group to the system. Non Lock Free path */ \
M_ASSERT(mem->initial > 0); \ M_ASSERT(mem->initial > 0); \
node = M_C(name, _alloc_node)(mem->initial); \ node = M_F(name, _alloc_node)(mem->initial); \
M_ASSERT(node != NULL); \ M_ASSERT(node != NULL); \
M_ASSERT(!M_C(name, _slist_empty_p)(node->list)); \ M_ASSERT(!M_F(name, _slist_empty_p)(node->list)); \
} \ } \
M_C(name, _slist_move)(mem->thread_data[id].free, node->list); \ M_F(name, _slist_move)(mem->thread_data[id].free, node->list); \
/* Push back the empty group */ \ /* Push back the empty group */ \
M_ASSERT (M_C(name, _slist_empty_p)(node->list)); \ M_ASSERT (M_F(name, _slist_empty_p)(node->list)); \
M_C(name, _lflist_push)(mem->empty, node, mem->gc_mem->thread_data[id].bkoff); \ M_F(name, _lflist_push)(mem->empty, node, mem->gc_mem->thread_data[id].bkoff); \
} \ } \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _del)(M_C(name, _t) mem, type_t *d, m_gc_tid_t id) \ M_F(name, _del)(M_F(name, _t) mem, type_t *d, m_gc_tid_t id) \
{ \ { \
M_C(name, _slist_node_ct) *snode; \ M_F(name, _slist_node_ct) *snode; \
M_ASSERT( d != NULL); \ M_ASSERT( d != NULL); \
snode = M_TYPE_FROM_FIELD(M_C(name, _slist_node_ct), d, type_t, data); \ snode = M_TYPE_FROM_FIELD(M_F(name, _slist_node_ct), d, type_t, data); \
M_C(name, _slist_push)(mem->thread_data[id].to_be_reclaimed, snode); \ M_F(name, _slist_push)(mem->thread_data[id].to_be_reclaimed, snode); \
} \ } \
+178 -178
View File
@@ -33,7 +33,7 @@
based on the given container. based on the given container.
USAGE: CONCURRENT_DEF(name, type [, oplist_of_the_type]) */ USAGE: CONCURRENT_DEF(name, type [, oplist_of_the_type]) */
#define M_CONCURRENT_DEF(name, ...) \ #define M_CONCURRENT_DEF(name, ...) \
M_CONCURRENT_DEF_AS(name, M_C(name,_t), __VA_ARGS__) M_CONCURRENT_DEF_AS(name, M_F(name,_t), __VA_ARGS__)
/* Define a protected concurrent container and its associated functions /* Define a protected concurrent container and its associated functions
@@ -52,7 +52,7 @@
can be done in parallel. can be done in parallel.
USAGE: CONCURRENT_RP_DEF(name, type [, oplist_of_the_type]) */ USAGE: CONCURRENT_RP_DEF(name, type [, oplist_of_the_type]) */
#define M_CONCURRENT_RP_DEF(name, ...) \ #define M_CONCURRENT_RP_DEF(name, ...) \
M_CONCURRENT_RP_DEF_AS(name, M_C(name,_t), __VA_ARGS__) M_CONCURRENT_RP_DEF_AS(name, M_F(name,_t), __VA_ARGS__)
/* Define a protected concurrent container and its associated functions /* Define a protected concurrent container and its associated functions
@@ -98,38 +98,38 @@
destroyed by another thread). destroyed by another thread).
*/ */
#define M_C0NCURRENT_OPLIST_P3(name, oplist) \ #define M_C0NCURRENT_OPLIST_P3(name, oplist) \
(M_IF_METHOD(INIT, oplist)(INIT(M_C(name, _init)),) \ (M_IF_METHOD(INIT, oplist)(INIT(M_F(name, _init)),) \
,M_IF_METHOD(INIT_SET, oplist)(INIT_SET(M_C(name, _init_set)),) \ ,M_IF_METHOD(INIT_SET, oplist)(INIT_SET(M_F(name, _init_set)),) \
,M_IF_METHOD(SET, oplist)(SET(M_C(name, _set)),) \ ,M_IF_METHOD(SET, oplist)(SET(M_F(name, _set)),) \
,M_IF_METHOD(CLEAR, oplist)(CLEAR(M_C(name, _clear)),) \ ,M_IF_METHOD(CLEAR, oplist)(CLEAR(M_F(name, _clear)),) \
,M_IF_METHOD(INIT_MOVE, oplist)(INIT_MOVE(M_C(name, _init_move)),) \ ,M_IF_METHOD(INIT_MOVE, oplist)(INIT_MOVE(M_F(name, _init_move)),) \
,M_IF_METHOD(MOVE, oplist)(MOVE(M_C(name, _move)),) \ ,M_IF_METHOD(MOVE, oplist)(MOVE(M_F(name, _move)),) \
,M_IF_METHOD(SWAP,oplist)(SWAP(M_C(name, _swap)),) \ ,M_IF_METHOD(SWAP,oplist)(SWAP(M_F(name, _swap)),) \
,NAME(name) \ ,NAME(name) \
,TYPE(M_C(name,_ct)) \ ,TYPE(M_F(name,_ct)) \
,SUBTYPE(M_C(name, _subtype_ct)) \ ,SUBTYPE(M_F(name, _subtype_ct)) \
,OPLIST(oplist) \ ,OPLIST(oplist) \
,M_IF_METHOD(EMPTY_P, oplist)(EMPTY_P(M_C(name,_empty_p)),) \ ,M_IF_METHOD(EMPTY_P, oplist)(EMPTY_P(M_F(name,_empty_p)),) \
,M_IF_METHOD(GET_SIZE, oplist)(GET_SIZE(M_C(name,_size)),) \ ,M_IF_METHOD(GET_SIZE, oplist)(GET_SIZE(M_F(name,_size)),) \
,M_IF_METHOD(RESET, oplist)(RESET(M_C(name,_reset)),) \ ,M_IF_METHOD(RESET, oplist)(RESET(M_F(name,_reset)),) \
,M_IF_METHOD(KEY_TYPE, oplist)(KEY_TYPE(M_GET_KEY_TYPE oplist),) \ ,M_IF_METHOD(KEY_TYPE, oplist)(KEY_TYPE(M_GET_KEY_TYPE oplist),) \
,M_IF_METHOD(VALUE_TYPE, oplist)(VALUE_TYPE(M_GET_VALUE_TYPE oplist),) \ ,M_IF_METHOD(VALUE_TYPE, oplist)(VALUE_TYPE(M_GET_VALUE_TYPE oplist),) \
,M_IF_METHOD(KEY_TYPE, oplist)(KEY_OPLIST(M_GET_KEY_OPLIST oplist),) \ ,M_IF_METHOD(KEY_TYPE, oplist)(KEY_OPLIST(M_GET_KEY_OPLIST oplist),) \
,M_IF_METHOD(VALUE_TYPE, oplist)(VALUE_OPLIST(M_GET_VALUE_OPLIST oplist), ) \ ,M_IF_METHOD(VALUE_TYPE, oplist)(VALUE_OPLIST(M_GET_VALUE_OPLIST oplist), ) \
,M_IF_METHOD(SET_KEY, oplist)(SET_KEY(M_C(name, _set_at)),) \ ,M_IF_METHOD(SET_KEY, oplist)(SET_KEY(M_F(name, _set_at)),) \
,M_IF_METHOD(ERASE_KEY, oplist)(ERASE_KEY(M_C(name, _erase)),) \ ,M_IF_METHOD(ERASE_KEY, oplist)(ERASE_KEY(M_F(name, _erase)),) \
,M_IF_METHOD(PUSH, oplist)(PUSH(M_C(name,_push)),) \ ,M_IF_METHOD(PUSH, oplist)(PUSH(M_F(name,_push)),) \
,M_IF_METHOD(POP, oplist)(POP(M_C(name,_pop)),) \ ,M_IF_METHOD(POP, oplist)(POP(M_F(name,_pop)),) \
,M_IF_METHOD(PUSH_MOVE, oplist)(PUSH_MOVE(M_C(name,_push_move)),) \ ,M_IF_METHOD(PUSH_MOVE, oplist)(PUSH_MOVE(M_F(name,_push_move)),) \
,M_IF_METHOD(POP_MOVE, oplist)(POP_MOVE(M_C(name,_pop_move)),) \ ,M_IF_METHOD(POP_MOVE, oplist)(POP_MOVE(M_F(name,_pop_move)),) \
,M_IF_METHOD(GET_STR, oplist)(GET_STR(M_C(name, _get_str)),) \ ,M_IF_METHOD(GET_STR, oplist)(GET_STR(M_F(name, _get_str)),) \
,M_IF_METHOD(PARSE_STR, oplist)(PARSE_STR(M_C(name, _parse_str)),) \ ,M_IF_METHOD(PARSE_STR, oplist)(PARSE_STR(M_F(name, _parse_str)),) \
,M_IF_METHOD(OUT_STR, oplist)(OUT_STR(M_C(name, _out_str)),) \ ,M_IF_METHOD(OUT_STR, oplist)(OUT_STR(M_F(name, _out_str)),) \
,M_IF_METHOD(IN_STR, oplist)(IN_STR(M_C(name, _in_str)),) \ ,M_IF_METHOD(IN_STR, oplist)(IN_STR(M_F(name, _in_str)),) \
,M_IF_METHOD(OUT_SERIAL, oplist)(OUT_SERIAL(M_C(name, _out_serial)),) \ ,M_IF_METHOD(OUT_SERIAL, oplist)(OUT_SERIAL(M_F(name, _out_serial)),) \
,M_IF_METHOD(IN_SERIAL, oplist)(IN_SERIAL(M_C(name, _in_serial)),) \ ,M_IF_METHOD(IN_SERIAL, oplist)(IN_SERIAL(M_F(name, _in_serial)),) \
,M_IF_METHOD(EQUAL, oplist)(EQUAL(M_C(name, _equal_p)),) \ ,M_IF_METHOD(EQUAL, oplist)(EQUAL(M_F(name, _equal_p)),) \
,M_IF_METHOD(HASH, oplist)(HASH(M_C(name, _hash)),) \ ,M_IF_METHOD(HASH, oplist)(HASH(M_F(name, _hash)),) \
,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW oplist),) \ ,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW oplist),) \
,M_IF_METHOD(REALLOC, oplist)(REALLOC(M_GET_REALLOC oplist),) \ ,M_IF_METHOD(REALLOC, oplist)(REALLOC(M_GET_REALLOC oplist),) \
,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL oplist),) \ ,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL oplist),) \
@@ -162,7 +162,7 @@
- name: prefix to be used - name: prefix to be used
- type: type of the sub container - type: type of the sub container
- oplist: oplist of the type of the sub container - oplist: oplist of the type of the sub container
- concurrent_t: alias for M_C(name, _t) [ type of the container ] - concurrent_t: alias for M_F(name, _t) [ type of the container ]
*/ */
#define M_C0NCURRENT_DEF_P3(name, type, oplist, concurrent_t) \ #define M_C0NCURRENT_DEF_P3(name, type, oplist, concurrent_t) \
M_C0NCURRENT_DEF_TYPE(name, type, oplist, concurrent_t) \ M_C0NCURRENT_DEF_TYPE(name, type, oplist, concurrent_t) \
@@ -174,20 +174,20 @@
#define M_C0NCURRENT_DEF_TYPE(name, type, oplist, concurrent_t) \ #define M_C0NCURRENT_DEF_TYPE(name, type, oplist, concurrent_t) \
\ \
/* Define a concurrent container using a lock */ \ /* Define a concurrent container using a lock */ \
typedef struct M_C(name, _s) { \ typedef struct M_F(name, _s) { \
struct M_C(name, _s) *self; \ struct M_F(name, _s) *self; \
m_mutex_t lock; \ m_mutex_t lock; \
m_cond_t there_is_data; /* condition raised when there is data */ \ m_cond_t there_is_data; /* condition raised when there is data */ \
type data; \ type data; \
} concurrent_t[1]; \ } concurrent_t[1]; \
\ \
/* Define alias for pointer types */ \ /* Define alias for pointer types */ \
typedef struct M_C(name, _s) *M_C(name, _ptr); \ typedef struct M_F(name, _s) *M_F(name, _ptr); \
typedef const struct M_C(name, _s) *M_C(name, _srcptr); \ typedef const struct M_F(name, _s) *M_F(name, _srcptr); \
\ \
/* Internal types for oplist */ \ /* Internal types for oplist */ \
typedef concurrent_t M_C(name, _ct); \ typedef concurrent_t M_F(name, _ct); \
typedef type M_C(name, _subtype_ct); \ typedef type M_F(name, _subtype_ct); \
\ \
/* Cannot define iterator as it cannot be reliable in a concurrent type */ \ /* Cannot define iterator as it cannot be reliable in a concurrent type */ \
@@ -197,7 +197,7 @@
/* Initial the fields of the concurrent object not associated to the \ /* Initial the fields of the concurrent object not associated to the \
sub-container. */ \ sub-container. */ \
static inline void \ static inline void \
M_C(name, _internal_init)(concurrent_t out) \ M_F(name, _internal_init)(concurrent_t out) \
{ \ { \
m_mutex_init(out->lock); \ m_mutex_init(out->lock); \
m_cond_init(out->there_is_data); \ m_cond_init(out->there_is_data); \
@@ -208,7 +208,7 @@
/* Clear the fields of the concurrent object not associated to the \ /* Clear the fields of the concurrent object not associated to the \
sub-container. */ \ sub-container. */ \
static inline void \ static inline void \
M_C(name, _internal_clear)(concurrent_t out) \ M_F(name, _internal_clear)(concurrent_t out) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
m_mutex_clear(out->lock); \ m_mutex_clear(out->lock); \
@@ -221,7 +221,7 @@
NOTE: This instance doesn't implement the read/write strategy, \ NOTE: This instance doesn't implement the read/write strategy, \
and only get the lock */ \ and only get the lock */ \
static inline void \ static inline void \
M_C(name, _read_lock)(const concurrent_t out) \ M_F(name, _read_lock)(const concurrent_t out) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
m_mutex_lock (out->self->lock); \ m_mutex_lock (out->self->lock); \
@@ -231,7 +231,7 @@
NOTE: This instance doesn't implement the read/write strategy, \ NOTE: This instance doesn't implement the read/write strategy, \
and only get the lock */ \ and only get the lock */ \
static inline void \ static inline void \
M_C(name, _read_unlock)(const concurrent_t out) \ M_F(name, _read_unlock)(const concurrent_t out) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
m_mutex_unlock (out->self->lock); \ m_mutex_unlock (out->self->lock); \
@@ -240,7 +240,7 @@
/* Wait for a thread pushing some data in the container. \ /* Wait for a thread pushing some data in the container. \
CONSTRAINT: the read lock shall be get before calling this service */ \ CONSTRAINT: the read lock shall be get before calling this service */ \
static inline void \ static inline void \
M_C(name, _read_wait)(const concurrent_t out) \ M_F(name, _read_wait)(const concurrent_t out) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
m_cond_wait(out->self->there_is_data, out->self->lock); \ m_cond_wait(out->self->there_is_data, out->self->lock); \
@@ -251,7 +251,7 @@
NOTE: This instance doesn't implement the read/write strategy, \ NOTE: This instance doesn't implement the read/write strategy, \
and only get the lock */ \ and only get the lock */ \
static inline void \ static inline void \
M_C(name, _write_lock)(concurrent_t out) \ M_F(name, _write_lock)(concurrent_t out) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
m_mutex_lock (out->lock); \ m_mutex_lock (out->lock); \
@@ -261,7 +261,7 @@
NOTE: This instance doesn't implement the read/write strategy, \ NOTE: This instance doesn't implement the read/write strategy, \
and only get the lock */ \ and only get the lock */ \
static inline void \ static inline void \
M_C(name, _write_unlock)(concurrent_t out) \ M_F(name, _write_unlock)(concurrent_t out) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
m_mutex_unlock (out->lock); \ m_mutex_unlock (out->lock); \
@@ -270,7 +270,7 @@
/* Wait for a thread pushing some data in the container. \ /* Wait for a thread pushing some data in the container. \
CONSTRAINT: the write lock shall be get before calling this service */ \ CONSTRAINT: the write lock shall be get before calling this service */ \
static inline void \ static inline void \
M_C(name, _write_wait)(const concurrent_t out) \ M_F(name, _write_wait)(const concurrent_t out) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
m_cond_wait(out->self->there_is_data, out->self->lock); \ m_cond_wait(out->self->there_is_data, out->self->lock); \
@@ -279,7 +279,7 @@
/* Wait to all threads that some data are available in the container. \ /* Wait to all threads that some data are available in the container. \
CONSTRAINT: the write lock shall be get before calling this service */ \ CONSTRAINT: the write lock shall be get before calling this service */ \
static inline void \ static inline void \
M_C(name, _write_signal)(concurrent_t out) \ M_F(name, _write_signal)(concurrent_t out) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
/* We need to signal this to ALL waiting threads as multiple threads \ /* We need to signal this to ALL waiting threads as multiple threads \
@@ -291,7 +291,7 @@
- name: prefix to be used - name: prefix to be used
- type: type of the sub container - type: type of the sub container
- oplist: oplist of the type of the sub container - oplist: oplist of the type of the sub container
- concurrent_t: alias for M_C(name, _t) [ type of the container ] - concurrent_t: alias for M_F(name, _t) [ type of the container ]
A function is defined only if the underlying container exports the needed A function is defined only if the underlying container exports the needed
services. It is usually one service declared per service exported. services. It is usually one service declared per service exported.
*/ */
@@ -299,9 +299,9 @@
\ \
M_IF_METHOD(INIT, oplist)( \ M_IF_METHOD(INIT, oplist)( \
static inline void \ static inline void \
M_C(name, _init)(concurrent_t out) \ M_F(name, _init)(concurrent_t out) \
{ \ { \
M_C(name, _internal_init)(out); \ M_F(name, _internal_init)(out); \
M_CALL_INIT(oplist, out->data); \ M_CALL_INIT(oplist, out->data); \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
} \ } \
@@ -309,21 +309,21 @@
\ \
M_IF_METHOD(INIT_SET, oplist)( \ M_IF_METHOD(INIT_SET, oplist)( \
static inline void \ static inline void \
M_C(name, _init_set)(concurrent_t out, concurrent_t const src) \ M_F(name, _init_set)(concurrent_t out, concurrent_t const src) \
{ \ { \
M_C0NCURRENT_CONTRACT(src); \ M_C0NCURRENT_CONTRACT(src); \
M_ASSERT (out != src); \ M_ASSERT (out != src); \
M_C(name, _internal_init)(out); \ M_F(name, _internal_init)(out); \
M_C(name, _read_lock)(src); \ M_F(name, _read_lock)(src); \
M_CALL_INIT_SET(oplist, out->data, src->data); \ M_CALL_INIT_SET(oplist, out->data, src->data); \
M_C(name, _read_unlock)(src); \ M_F(name, _read_unlock)(src); \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
} \ } \
,) \ ,) \
\ \
M_IF_METHOD(SET, oplist)( \ M_IF_METHOD(SET, oplist)( \
static inline void \ static inline void \
M_C(name, _set)(concurrent_t out, concurrent_t const src) \ M_F(name, _set)(concurrent_t out, concurrent_t const src) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
if (M_UNLIKELY (out == src)) return; \ if (M_UNLIKELY (out == src)) return; \
@@ -338,19 +338,19 @@
To avoid this problem, we **always** lock the mutex which address is \ To avoid this problem, we **always** lock the mutex which address is \
the lowest. */ \ the lowest. */ \
if (out < src) { \ if (out < src) { \
M_C(name, _write_lock)(out); \ M_F(name, _write_lock)(out); \
M_C(name, _read_lock)(src); \ M_F(name, _read_lock)(src); \
} else { \ } else { \
M_C(name, _read_lock)(src); \ M_F(name, _read_lock)(src); \
M_C(name, _write_lock)(out); \ M_F(name, _write_lock)(out); \
} \ } \
M_CALL_SET(oplist, out->data, src->data); \ M_CALL_SET(oplist, out->data, src->data); \
if (out < src) { \ if (out < src) { \
M_C(name, _read_lock)(src); \ M_F(name, _read_lock)(src); \
M_C(name, _write_unlock)(out); \ M_F(name, _write_unlock)(out); \
} else { \ } else { \
M_C(name, _write_unlock)(out); \ M_F(name, _write_unlock)(out); \
M_C(name, _read_unlock)(src); \ M_F(name, _read_unlock)(src); \
} \ } \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
} \ } \
@@ -358,307 +358,307 @@
\ \
M_IF_METHOD(CLEAR, oplist)( \ M_IF_METHOD(CLEAR, oplist)( \
static inline void \ static inline void \
M_C(name, _clear)(concurrent_t out) \ M_F(name, _clear)(concurrent_t out) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
/* No need to lock. A clear is supposed to be called when all operations \ /* No need to lock. A clear is supposed to be called when all operations \
of the container in other threads are terminated */ \ of the container in other threads are terminated */ \
M_CALL_CLEAR(oplist, out->data); \ M_CALL_CLEAR(oplist, out->data); \
M_C(name, _internal_clear)(out); \ M_F(name, _internal_clear)(out); \
} \ } \
,) \ ,) \
\ \
M_IF_METHOD(INIT_MOVE, oplist)( \ M_IF_METHOD(INIT_MOVE, oplist)( \
static inline void \ static inline void \
M_C(name, _init_move)(concurrent_t out, concurrent_t src) \ M_F(name, _init_move)(concurrent_t out, concurrent_t src) \
{ \ { \
M_C0NCURRENT_CONTRACT(src); \ M_C0NCURRENT_CONTRACT(src); \
M_ASSERT (out != src); \ M_ASSERT (out != src); \
/* No need to lock 'src' ? */ \ /* No need to lock 'src' ? */ \
M_C(name, _internal_init)(out); \ M_F(name, _internal_init)(out); \
M_CALL_INIT_MOVE(oplist, out->data, src->data); \ M_CALL_INIT_MOVE(oplist, out->data, src->data); \
M_C(name, _internal_clear)(src); \ M_F(name, _internal_clear)(src); \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
} \ } \
,) \ ,) \
\ \
M_IF_METHOD(MOVE, oplist)( \ M_IF_METHOD(MOVE, oplist)( \
static inline void \ static inline void \
M_C(name, _move)(concurrent_t out, concurrent_t src) \ M_F(name, _move)(concurrent_t out, concurrent_t src) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
M_C0NCURRENT_CONTRACT(src); \ M_C0NCURRENT_CONTRACT(src); \
/* No need to lock 'src' ? */ \ /* No need to lock 'src' ? */ \
M_C(name, _write_lock)(out); \ M_F(name, _write_lock)(out); \
M_CALL_MOVE(oplist, out->data, src->data); \ M_CALL_MOVE(oplist, out->data, src->data); \
M_C(name, _write_unlock)(out); \ M_F(name, _write_unlock)(out); \
M_C(name, _internal_clear)(src); \ M_F(name, _internal_clear)(src); \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
} \ } \
,) \ ,) \
\ \
M_IF_METHOD(SWAP, oplist)( \ M_IF_METHOD(SWAP, oplist)( \
static inline void \ static inline void \
M_C(name, _swap)(concurrent_t out, concurrent_t src) \ M_F(name, _swap)(concurrent_t out, concurrent_t src) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
M_C0NCURRENT_CONTRACT(src); \ M_C0NCURRENT_CONTRACT(src); \
if (M_UNLIKELY (out == src)) return; \ if (M_UNLIKELY (out == src)) return; \
/* See comment above */ \ /* See comment above */ \
if (out < src) { \ if (out < src) { \
M_C(name, _write_lock)(out); \ M_F(name, _write_lock)(out); \
M_C(name, _write_lock)(src); \ M_F(name, _write_lock)(src); \
} else { \ } else { \
M_C(name, _write_lock)(src); \ M_F(name, _write_lock)(src); \
M_C(name, _write_lock)(out); \ M_F(name, _write_lock)(out); \
} \ } \
M_CALL_SWAP(oplist, out->data, src->data); \ M_CALL_SWAP(oplist, out->data, src->data); \
if (out < src) { \ if (out < src) { \
M_C(name, _write_unlock)(src); \ M_F(name, _write_unlock)(src); \
M_C(name, _write_unlock)(out); \ M_F(name, _write_unlock)(out); \
} else { \ } else { \
M_C(name, _write_unlock)(out); \ M_F(name, _write_unlock)(out); \
M_C(name, _write_unlock)(src); \ M_F(name, _write_unlock)(src); \
} \ } \
} \ } \
,) \ ,) \
\ \
M_IF_METHOD(RESET, oplist)( \ M_IF_METHOD(RESET, oplist)( \
static inline void \ static inline void \
M_C(name, _reset)(concurrent_t out) \ M_F(name, _reset)(concurrent_t out) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
M_C(name, _write_lock)(out); \ M_F(name, _write_lock)(out); \
M_CALL_RESET(oplist, out->data); \ M_CALL_RESET(oplist, out->data); \
M_C(name, _write_unlock)(out); \ M_F(name, _write_unlock)(out); \
} \ } \
,) \ ,) \
\ \
M_IF_METHOD(EMPTY_P, oplist)( \ M_IF_METHOD(EMPTY_P, oplist)( \
static inline bool \ static inline bool \
M_C(name, _empty_p)(concurrent_t const out) \ M_F(name, _empty_p)(concurrent_t const out) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
M_C(name, _read_lock)(out); \ M_F(name, _read_lock)(out); \
bool b = M_CALL_EMPTY_P(oplist, out->data); \ bool b = M_CALL_EMPTY_P(oplist, out->data); \
M_C(name, _read_unlock)(out); \ M_F(name, _read_unlock)(out); \
return b; \ return b; \
} \ } \
,) \ ,) \
\ \
M_IF_METHOD(GET_SIZE, oplist)( \ M_IF_METHOD(GET_SIZE, oplist)( \
static inline size_t \ static inline size_t \
M_C(name, _size)(concurrent_t const out) \ M_F(name, _size)(concurrent_t const out) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
M_C(name, _read_lock)(out); \ M_F(name, _read_lock)(out); \
size_t r = M_CALL_GET_SIZE(oplist, out->data); \ size_t r = M_CALL_GET_SIZE(oplist, out->data); \
M_C(name, _read_unlock)(out); \ M_F(name, _read_unlock)(out); \
return r; \ return r; \
} \ } \
,) \ ,) \
\ \
M_IF_METHOD(SET_KEY, oplist)( \ M_IF_METHOD(SET_KEY, oplist)( \
static inline void \ static inline void \
M_C(name, _set_at)(concurrent_t out, M_GET_KEY_TYPE oplist const key, M_GET_VALUE_TYPE oplist const data) \ M_F(name, _set_at)(concurrent_t out, M_GET_KEY_TYPE oplist const key, M_GET_VALUE_TYPE oplist const data) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
M_C(name, _write_lock)(out); \ M_F(name, _write_lock)(out); \
M_CALL_SET_KEY(oplist, out->data, key, data); \ M_CALL_SET_KEY(oplist, out->data, key, data); \
M_C(name, _write_signal)(out); \ M_F(name, _write_signal)(out); \
M_C(name, _write_unlock)(out); \ M_F(name, _write_unlock)(out); \
} \ } \
,) \ ,) \
\ \
M_IF_METHOD(GET_KEY, oplist)( \ M_IF_METHOD(GET_KEY, oplist)( \
static inline bool \ static inline bool \
M_C(name, _get_copy)(M_GET_VALUE_TYPE oplist *out_data, const concurrent_t out, M_GET_KEY_TYPE oplist const key) \ M_F(name, _get_copy)(M_GET_VALUE_TYPE oplist *out_data, const concurrent_t out, M_GET_KEY_TYPE oplist const key) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
M_ASSERT (out_data != NULL); \ M_ASSERT (out_data != NULL); \
M_C(name, _read_lock)(out); \ M_F(name, _read_lock)(out); \
M_GET_VALUE_TYPE oplist *p = M_CALL_GET_KEY(oplist, out->data, key); \ M_GET_VALUE_TYPE oplist *p = M_CALL_GET_KEY(oplist, out->data, key); \
if (p != NULL) { \ if (p != NULL) { \
M_CALL_SET(M_GET_VALUE_OPLIST oplist, *out_data, *p); \ M_CALL_SET(M_GET_VALUE_OPLIST oplist, *out_data, *p); \
} \ } \
M_C(name, _read_unlock)(out); \ M_F(name, _read_unlock)(out); \
return p != NULL; \ return p != NULL; \
} \ } \
,) \ ,) \
\ \
M_IF_METHOD(SAFE_GET_KEY, oplist)( \ M_IF_METHOD(SAFE_GET_KEY, oplist)( \
static inline void \ static inline void \
M_C(name, _safe_get_copy)(M_GET_VALUE_TYPE oplist *out_data, concurrent_t out, M_GET_KEY_TYPE oplist const key) \ M_F(name, _safe_get_copy)(M_GET_VALUE_TYPE oplist *out_data, concurrent_t out, M_GET_KEY_TYPE oplist const key) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
M_ASSERT (out_data != NULL); \ M_ASSERT (out_data != NULL); \
M_C(name, _write_lock)(out); \ M_F(name, _write_lock)(out); \
M_GET_VALUE_TYPE oplist *p = M_CALL_SAFE_GET_KEY(oplist, out->data, key); \ M_GET_VALUE_TYPE oplist *p = M_CALL_SAFE_GET_KEY(oplist, out->data, key); \
M_ASSERT (p != NULL); \ M_ASSERT (p != NULL); \
M_CALL_SET(M_GET_VALUE_OPLIST oplist, *out_data, *p); \ M_CALL_SET(M_GET_VALUE_OPLIST oplist, *out_data, *p); \
M_C(name, _write_unlock)(out); \ M_F(name, _write_unlock)(out); \
} \ } \
,) \ ,) \
\ \
M_IF_METHOD(ERASE_KEY, oplist)( \ M_IF_METHOD(ERASE_KEY, oplist)( \
static inline bool \ static inline bool \
M_C(name, _erase)(concurrent_t out, M_GET_KEY_TYPE oplist const key) \ M_F(name, _erase)(concurrent_t out, M_GET_KEY_TYPE oplist const key) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
M_C(name, _write_lock)(out); \ M_F(name, _write_lock)(out); \
bool b = M_CALL_ERASE_KEY(oplist, out->data, key); \ bool b = M_CALL_ERASE_KEY(oplist, out->data, key); \
/* We suppose that the container has 'infinite' capacity, so \ /* We suppose that the container has 'infinite' capacity, so \
we won't signal that a free space has been created */ \ we won't signal that a free space has been created */ \
M_C(name, _write_unlock)(out); \ M_F(name, _write_unlock)(out); \
return b; \ return b; \
} \ } \
,) \ ,) \
\ \
M_IF_METHOD(PUSH, oplist)( \ M_IF_METHOD(PUSH, oplist)( \
static inline void \ static inline void \
M_C(name, _push)(concurrent_t out, M_GET_SUBTYPE oplist const data) \ M_F(name, _push)(concurrent_t out, M_GET_SUBTYPE oplist const data) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
M_C(name, _write_lock)(out); \ M_F(name, _write_lock)(out); \
M_CALL_PUSH(oplist, out->data, data); \ M_CALL_PUSH(oplist, out->data, data); \
M_C(name, _write_signal)(out); \ M_F(name, _write_signal)(out); \
M_C(name, _write_unlock)(out); \ M_F(name, _write_unlock)(out); \
} \ } \
\ \
M_EMPLACE_QUEUE_DEF(name, concurrent_t, M_C(name, _emplace), M_GET_OPLIST oplist, M_EMPLACE_QUEUE_GENE) \ M_EMPLACE_QUEUE_DEF(name, concurrent_t, M_F(name, _emplace), M_GET_OPLIST oplist, M_EMPLACE_QUEUE_GENE) \
,) \ ,) \
\ \
M_IF_METHOD(POP, oplist)( \ M_IF_METHOD(POP, oplist)( \
static inline void \ static inline void \
M_C(name, _pop)(M_GET_SUBTYPE oplist *p, concurrent_t out) \ M_F(name, _pop)(M_GET_SUBTYPE oplist *p, concurrent_t out) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
M_C(name, _write_lock)(out); \ M_F(name, _write_lock)(out); \
M_CALL_POP(oplist, p, out->data); \ M_CALL_POP(oplist, p, out->data); \
/* See comment above */ \ /* See comment above */ \
M_C(name, _write_unlock)(out); \ M_F(name, _write_unlock)(out); \
} \ } \
,) \ ,) \
\ \
M_IF_METHOD(PUSH_MOVE, oplist)( \ M_IF_METHOD(PUSH_MOVE, oplist)( \
static inline void \ static inline void \
M_C(name, _push_move)(concurrent_t out, M_GET_SUBTYPE oplist *data) \ M_F(name, _push_move)(concurrent_t out, M_GET_SUBTYPE oplist *data) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
M_C(name, _write_lock)(out); \ M_F(name, _write_lock)(out); \
M_CALL_PUSH_MOVE(oplist, out->data, data); \ M_CALL_PUSH_MOVE(oplist, out->data, data); \
M_C(name, _write_signal)(out); \ M_F(name, _write_signal)(out); \
M_C(name, _write_unlock)(out); \ M_F(name, _write_unlock)(out); \
} \ } \
,) \ ,) \
\ \
M_IF_METHOD(POP_MOVE, oplist)( \ M_IF_METHOD(POP_MOVE, oplist)( \
static inline void \ static inline void \
M_C(name, _pop_move)(M_GET_SUBTYPE oplist *p, concurrent_t out) \ M_F(name, _pop_move)(M_GET_SUBTYPE oplist *p, concurrent_t out) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
M_C(name, _write_lock)(out); \ M_F(name, _write_lock)(out); \
M_CALL_POP_MOVE(oplist, p, out->data); \ M_CALL_POP_MOVE(oplist, p, out->data); \
/* See comment above */ \ /* See comment above */ \
M_C(name, _write_unlock)(out); \ M_F(name, _write_unlock)(out); \
} \ } \
,) \ ,) \
\ \
M_IF_METHOD(GET_STR, oplist)( \ M_IF_METHOD(GET_STR, oplist)( \
static inline void \ static inline void \
M_C(name, _get_str)(m_string_t str, concurrent_t const out, bool a) \ M_F(name, _get_str)(m_string_t str, concurrent_t const out, bool a) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
M_C(name, _read_lock)(out); \ M_F(name, _read_lock)(out); \
M_CALL_GET_STR(oplist, str, out->data, a); \ M_CALL_GET_STR(oplist, str, out->data, a); \
M_C(name, _read_unlock)(out); \ M_F(name, _read_unlock)(out); \
} \ } \
,) \ ,) \
\ \
M_IF_METHOD(OUT_STR, oplist)( \ M_IF_METHOD(OUT_STR, oplist)( \
static inline void \ static inline void \
M_C(name, _out_str)(FILE *f, concurrent_t const out) \ M_F(name, _out_str)(FILE *f, concurrent_t const out) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
M_C(name, _read_lock)(out); \ M_F(name, _read_lock)(out); \
M_CALL_OUT_STR(oplist, f, out->data); \ M_CALL_OUT_STR(oplist, f, out->data); \
M_C(name, _read_unlock)(out); \ M_F(name, _read_unlock)(out); \
} \ } \
,) \ ,) \
\ \
M_IF_METHOD(PARSE_STR, oplist)( \ M_IF_METHOD(PARSE_STR, oplist)( \
static inline bool \ static inline bool \
M_C(name, _parse_str)(concurrent_t out, const char str[], const char **e) \ M_F(name, _parse_str)(concurrent_t out, const char str[], const char **e) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
M_C(name, _write_lock)(out); \ M_F(name, _write_lock)(out); \
bool b = M_CALL_PARSE_STR(oplist, out->data, str, e); \ bool b = M_CALL_PARSE_STR(oplist, out->data, str, e); \
M_C(name, _write_signal)(out); \ M_F(name, _write_signal)(out); \
M_C(name, _write_unlock)(out); \ M_F(name, _write_unlock)(out); \
return b; \ return b; \
} \ } \
,) \ ,) \
\ \
M_IF_METHOD(IN_STR, oplist)( \ M_IF_METHOD(IN_STR, oplist)( \
static inline bool \ static inline bool \
M_C(name, _in_str)(concurrent_t out, FILE *f) \ M_F(name, _in_str)(concurrent_t out, FILE *f) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
M_C(name, _write_lock)(out); \ M_F(name, _write_lock)(out); \
bool b = M_CALL_IN_STR(oplist, out->data, f); \ bool b = M_CALL_IN_STR(oplist, out->data, f); \
M_C(name, _write_signal)(out); \ M_F(name, _write_signal)(out); \
M_C(name, _write_unlock)(out); \ M_F(name, _write_unlock)(out); \
return b; \ return b; \
} \ } \
,) \ ,) \
\ \
M_IF_METHOD(OUT_SERIAL, oplist)( \ M_IF_METHOD(OUT_SERIAL, oplist)( \
static inline m_serial_return_code_t \ static inline m_serial_return_code_t \
M_C(name, _out_serial)(m_serial_write_t f, concurrent_t const out) \ M_F(name, _out_serial)(m_serial_write_t f, concurrent_t const out) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
M_C(name, _read_lock)(out); \ M_F(name, _read_lock)(out); \
m_serial_return_code_t r = M_CALL_OUT_SERIAL(oplist, f, out->data); \ m_serial_return_code_t r = M_CALL_OUT_SERIAL(oplist, f, out->data); \
M_C(name, _read_unlock)(out); \ M_F(name, _read_unlock)(out); \
return r; \ return r; \
} \ } \
,) \ ,) \
\ \
M_IF_METHOD(IN_SERIAL, oplist)( \ M_IF_METHOD(IN_SERIAL, oplist)( \
static inline m_serial_return_code_t \ static inline m_serial_return_code_t \
M_C(name, _in_serial)(concurrent_t out, m_serial_read_t f) \ M_F(name, _in_serial)(concurrent_t out, m_serial_read_t f) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
M_C(name, _write_lock)(out); \ M_F(name, _write_lock)(out); \
m_serial_return_code_t r = M_CALL_IN_SERIAL(oplist, out->data, f); \ m_serial_return_code_t r = M_CALL_IN_SERIAL(oplist, out->data, f); \
M_C(name, _write_signal)(out); \ M_F(name, _write_signal)(out); \
M_C(name, _write_unlock)(out); \ M_F(name, _write_unlock)(out); \
return r; \ return r; \
} \ } \
,) \ ,) \
\ \
M_IF_METHOD(EQUAL, oplist)( \ M_IF_METHOD(EQUAL, oplist)( \
static inline bool \ static inline bool \
M_C(name, _equal_p)(concurrent_t const out1, concurrent_t const out2) \ M_F(name, _equal_p)(concurrent_t const out1, concurrent_t const out2) \
{ \ { \
M_C0NCURRENT_CONTRACT(out1); \ M_C0NCURRENT_CONTRACT(out1); \
M_C0NCURRENT_CONTRACT(out2); \ M_C0NCURRENT_CONTRACT(out2); \
if (M_UNLIKELY (out1 == out2)) return true; \ if (M_UNLIKELY (out1 == out2)) return true; \
/* See comment above on mutal mutexs */ \ /* See comment above on mutal mutexs */ \
if (out1 < out2) { \ if (out1 < out2) { \
M_C(name, _read_lock)(out1); \ M_F(name, _read_lock)(out1); \
M_C(name, _read_lock)(out2); \ M_F(name, _read_lock)(out2); \
} else { \ } else { \
M_C(name, _read_lock)(out2); \ M_F(name, _read_lock)(out2); \
M_C(name, _read_lock)(out1); \ M_F(name, _read_lock)(out1); \
} \ } \
bool b = M_CALL_EQUAL(oplist, out1->data, out2->data); \ bool b = M_CALL_EQUAL(oplist, out1->data, out2->data); \
if (out1 < out2) { \ if (out1 < out2) { \
M_C(name, _read_unlock)(out2); \ M_F(name, _read_unlock)(out2); \
M_C(name, _read_unlock)(out1); \ M_F(name, _read_unlock)(out1); \
} else { \ } else { \
M_C(name, _read_unlock)(out1); \ M_F(name, _read_unlock)(out1); \
M_C(name, _read_unlock)(out2); \ M_F(name, _read_unlock)(out2); \
} \ } \
return b; \ return b; \
} \ } \
@@ -666,12 +666,12 @@
\ \
M_IF_METHOD(GET_KEY, oplist)( \ M_IF_METHOD(GET_KEY, oplist)( \
static inline bool \ static inline bool \
M_C(name, _get_blocking)(M_GET_VALUE_TYPE oplist *out_data, const concurrent_t out, M_GET_KEY_TYPE oplist const key, bool blocking) \ M_F(name, _get_blocking)(M_GET_VALUE_TYPE oplist *out_data, const concurrent_t out, M_GET_KEY_TYPE oplist const key, bool blocking) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
M_ASSERT (out_data != NULL); \ M_ASSERT (out_data != NULL); \
bool ret = false; \ bool ret = false; \
M_C(name, _read_lock)(out); \ M_F(name, _read_lock)(out); \
while (true) { \ while (true) { \
M_GET_VALUE_TYPE oplist *p = M_CALL_GET_KEY(oplist, out->data, key); \ M_GET_VALUE_TYPE oplist *p = M_CALL_GET_KEY(oplist, out->data, key); \
if (p != NULL) { \ if (p != NULL) { \
@@ -681,21 +681,21 @@
} \ } \
if (blocking == false) break; \ if (blocking == false) break; \
/* No data: wait for a write to signal some data */ \ /* No data: wait for a write to signal some data */ \
M_C(name, _read_wait)(out); \ M_F(name, _read_wait)(out); \
} \ } \
M_C(name, _read_unlock)(out); \ M_F(name, _read_unlock)(out); \
return ret; \ return ret; \
} \ } \
,) \ ,) \
\ \
M_IF_METHOD2(POP, EMPTY_P, oplist)( \ M_IF_METHOD2(POP, EMPTY_P, oplist)( \
static inline bool \ static inline bool \
M_C(name, _pop_blocking)(M_GET_SUBTYPE oplist *p, concurrent_t out, bool blocking) \ M_F(name, _pop_blocking)(M_GET_SUBTYPE oplist *p, concurrent_t out, bool blocking) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
M_ASSERT (p != NULL); \ M_ASSERT (p != NULL); \
bool ret = false; \ bool ret = false; \
M_C(name, _write_lock)(out); \ M_F(name, _write_lock)(out); \
while (true) { \ while (true) { \
if (!M_CALL_EMPTY_P(oplist, out->data)) { \ if (!M_CALL_EMPTY_P(oplist, out->data)) { \
M_CALL_POP(oplist, p, out->data); \ M_CALL_POP(oplist, p, out->data); \
@@ -704,21 +704,21 @@
} \ } \
if (blocking == false) break; \ if (blocking == false) break; \
/* No data: wait for a write to signal some data */ \ /* No data: wait for a write to signal some data */ \
M_C(name, _write_wait)(out); \ M_F(name, _write_wait)(out); \
} \ } \
M_C(name, _write_unlock)(out); \ M_F(name, _write_unlock)(out); \
return ret; \ return ret; \
} \ } \
,) \ ,) \
\ \
M_IF_METHOD2(POP_MOVE, EMPTY_P, oplist)( \ M_IF_METHOD2(POP_MOVE, EMPTY_P, oplist)( \
static inline bool \ static inline bool \
M_C(name, _pop_move_blocking)(M_GET_SUBTYPE oplist *p, concurrent_t out, bool blocking) \ M_F(name, _pop_move_blocking)(M_GET_SUBTYPE oplist *p, concurrent_t out, bool blocking) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
M_ASSERT (p != NULL); \ M_ASSERT (p != NULL); \
bool ret = false; \ bool ret = false; \
M_C(name, _write_lock)(out); \ M_F(name, _write_lock)(out); \
while (true) { \ while (true) { \
if (!M_CALL_EMPTY_P(oplist, out->data)) { \ if (!M_CALL_EMPTY_P(oplist, out->data)) { \
M_CALL_POP_MOVE(oplist, p, out->data); \ M_CALL_POP_MOVE(oplist, p, out->data); \
@@ -727,21 +727,21 @@
} \ } \
if (blocking == false) break; \ if (blocking == false) break; \
/* No data: wait for a write to signal some data */ \ /* No data: wait for a write to signal some data */ \
M_C(name, _write_wait)(out); \ M_F(name, _write_wait)(out); \
} \ } \
M_C(name, _write_unlock)(out); \ M_F(name, _write_unlock)(out); \
return ret; \ return ret; \
} \ } \
,) \ ,) \
\ \
M_IF_METHOD(HASH, oplist)( \ M_IF_METHOD(HASH, oplist)( \
static inline size_t \ static inline size_t \
M_C(name, _hash)(concurrent_t const out) \ M_F(name, _hash)(concurrent_t const out) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
M_C(name, _read_lock)(out); \ M_F(name, _read_lock)(out); \
size_t h = M_CALL_HASH(oplist, out->data); \ size_t h = M_CALL_HASH(oplist, out->data); \
M_C(name, _read_unlock)(out); \ M_F(name, _read_unlock)(out); \
/* The hash is unchanged by the concurrent container */ \ /* The hash is unchanged by the concurrent container */ \
return h; \ return h; \
} \ } \
@@ -766,7 +766,7 @@
- name: prefix to be used - name: prefix to be used
- type: type of the sub container - type: type of the sub container
- oplist: oplist of the type of the sub container - oplist: oplist of the type of the sub container
- concurrent_t: alias for M_C(name, _t) [ type of the container ] - concurrent_t: alias for M_F(name, _t) [ type of the container ]
*/ */
#define M_C0NCURRENT_RP_DEF_P3(name, type, oplist, concurrent_t) \ #define M_C0NCURRENT_RP_DEF_P3(name, type, oplist, concurrent_t) \
M_C0NCURRENT_RP_DEF_TYPE(name, type, oplist, concurrent_t) \ M_C0NCURRENT_RP_DEF_TYPE(name, type, oplist, concurrent_t) \
@@ -777,8 +777,8 @@
/* Define the type of a RP concurrent container */ /* Define the type of a RP concurrent container */
#define M_C0NCURRENT_RP_DEF_TYPE(name, type, oplist, concurrent_t) \ #define M_C0NCURRENT_RP_DEF_TYPE(name, type, oplist, concurrent_t) \
\ \
typedef struct M_C(name, _s) { \ typedef struct M_F(name, _s) { \
struct M_C(name, _s) *self; \ struct M_F(name, _s) *self; \
m_mutex_t lock; \ m_mutex_t lock; \
m_cond_t rw_done; \ m_cond_t rw_done; \
size_t read_count; \ size_t read_count; \
@@ -787,16 +787,16 @@
type data; \ type data; \
} concurrent_t[1]; \ } concurrent_t[1]; \
\ \
typedef struct M_C(name, _s) *M_C(name, _ptr); \ typedef struct M_F(name, _s) *M_F(name, _ptr); \
typedef const struct M_C(name, _s) *M_C(name, _srcptr); \ typedef const struct M_F(name, _s) *M_F(name, _srcptr); \
\ \
typedef type M_C(name, _subtype_ct); \ typedef type M_F(name, _subtype_ct); \
/* Define the internal services for the lock strategy of a RP container */ /* Define the internal services for the lock strategy of a RP container */
#define M_C0NCURRENT_RP_DEF_CORE(name, type, oplist, concurrent_t) \ #define M_C0NCURRENT_RP_DEF_CORE(name, type, oplist, concurrent_t) \
\ \
static inline void \ static inline void \
M_C(name, _internal_init)(concurrent_t out) \ M_F(name, _internal_init)(concurrent_t out) \
{ \ { \
m_mutex_init(out->lock); \ m_mutex_init(out->lock); \
m_cond_init(out->rw_done); \ m_cond_init(out->rw_done); \
@@ -808,7 +808,7 @@
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _internal_clear)(concurrent_t out) \ M_F(name, _internal_clear)(concurrent_t out) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
m_mutex_clear(out->lock); \ m_mutex_clear(out->lock); \
@@ -818,10 +818,10 @@
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _read_lock)(const concurrent_t out) \ M_F(name, _read_lock)(const concurrent_t out) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
struct M_C(name, _s) *self = out->self; \ struct M_F(name, _s) *self = out->self; \
m_mutex_lock (self->lock); \ m_mutex_lock (self->lock); \
while (self->writer_waiting == true) { \ while (self->writer_waiting == true) { \
m_cond_wait(self->rw_done, self->lock); \ m_cond_wait(self->rw_done, self->lock); \
@@ -831,10 +831,10 @@
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _read_unlock)(const concurrent_t out) \ M_F(name, _read_unlock)(const concurrent_t out) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
struct M_C(name, _s) *self = out->self; \ struct M_F(name, _s) *self = out->self; \
m_mutex_lock (self->lock); \ m_mutex_lock (self->lock); \
self->read_count --; \ self->read_count --; \
if (self->read_count == 0) { \ if (self->read_count == 0) { \
@@ -844,7 +844,7 @@
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _write_lock)(concurrent_t out) \ M_F(name, _write_lock)(concurrent_t out) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
m_mutex_lock (out->lock); \ m_mutex_lock (out->lock); \
@@ -859,7 +859,7 @@
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _write_unlock)(concurrent_t out) \ M_F(name, _write_unlock)(concurrent_t out) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
m_mutex_lock (out->lock); \ m_mutex_lock (out->lock); \
@@ -869,10 +869,10 @@
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _read_wait)(const concurrent_t out) \ M_F(name, _read_wait)(const concurrent_t out) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
struct M_C(name, _s) *self = out->self; \ struct M_F(name, _s) *self = out->self; \
M_ASSERT (self == out); \ M_ASSERT (self == out); \
m_mutex_lock (out->self->lock); \ m_mutex_lock (out->self->lock); \
self->read_count --; \ self->read_count --; \
@@ -888,7 +888,7 @@
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _write_wait)(concurrent_t out) \ M_F(name, _write_wait)(concurrent_t out) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
m_mutex_lock (out->lock); \ m_mutex_lock (out->lock); \
@@ -906,7 +906,7 @@
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _write_signal)(concurrent_t out) \ M_F(name, _write_signal)(concurrent_t out) \
{ \ { \
M_C0NCURRENT_CONTRACT(out); \ M_C0NCURRENT_CONTRACT(out); \
m_mutex_lock (out->lock); \ m_mutex_lock (out->lock); \
+38 -21
View File
@@ -471,6 +471,23 @@ M_BEGIN_PROTECTED_CODE
#define M_C4(a, b, c, ...) M_C4I(a ,b, c, __VA_ARGS__) #define M_C4(a, b, c, ...) M_C4I(a ,b, c, __VA_ARGS__)
/* Generation of function name by concatenation
Can be ovverrided by user
*/
#ifndef M_F
#define M_F(a, b) M_C2I(a, b)
#endif
/* Concatenation of function name that enable developer to use customizaton
developer shall provide its own name customization by forcing M_F to it
then provide its own suffix in the namespace M_OVERRIDE_ ## suffix ():
Each generated suffix shall start with a comma.
#define M_F(a,b) M_OVERRIDE_F(a,b)
#define M_OVERRIDE__clear() , _cleanup ,
#include "m-core.h"
*/
#define M_OVERRIDE_F(a, b) M_C(a, M_RET_ARG2( M_C(M_OVERRIDE_, b)() , b))
/* Inverse 0 into 1 and 1 into 0 */ /* Inverse 0 into 1 and 1 into 0 */
#define M_INVI_0 1 #define M_INVI_0 1
#define M_INVI_1 0 #define M_INVI_1 0
@@ -3980,11 +3997,11 @@ m_core_parse2_enum (const char str[], const char **endptr)
/* Default oplist for complex objects with "classic" names for methods. /* Default oplist for complex objects with "classic" names for methods.
*/ */
#define M_CLASSIC_OPLIST(name) ( \ #define M_CLASSIC_OPLIST(name) ( \
INIT(M_C(name, _init)), \ INIT(M_F(name, _init)), \
INIT_SET(M_C(name, _init_set)), \ INIT_SET(M_F(name, _init_set)), \
SET(M_C(name, _set)), \ SET(M_F(name, _set)), \
CLEAR(M_C(name, _clear)), \ CLEAR(M_F(name, _clear)), \
TYPE(M_C(name, _t)) ) TYPE(M_F(name, _t)) )
/* OPLIST for 'const char *' string (with NO memory allocation). /* OPLIST for 'const char *' string (with NO memory allocation).
@@ -4698,11 +4715,11 @@ m_core_parse2_enum (const char str[], const char **endptr)
#define M_EMPLACE_ASS_ARRAY_OR_QUEUE_DEF(isSet, name, name_t, key_oplist, val_oplist) \ #define M_EMPLACE_ASS_ARRAY_OR_QUEUE_DEF(isSet, name, name_t, key_oplist, val_oplist) \
M_ID( M_C(M_EMPLACE_ASS_ARRAY_OR_QUEUE_DEF, isSet)(name, name_t, key_oplist, val_oplist) ) M_ID( M_C(M_EMPLACE_ASS_ARRAY_OR_QUEUE_DEF, isSet)(name, name_t, key_oplist, val_oplist) )
#define M_EMPLACE_ASS_ARRAY_OR_QUEUE_DEF0(name, name_t, key_oplist, val_oplist) \ #define M_EMPLACE_ASS_ARRAY_OR_QUEUE_DEF0(name, name_t, key_oplist, val_oplist) \
M_EMPLACE_ASS_ARRAY_DEF(name, name_t, M_C(name, _emplace), key_oplist, val_oplist, M_EMPLACE_ASS_ARRA1_BOTH_GENE, M_EMPLACE_ASS_ARRA1_KEY_GENE, M_EMPLACE_ASS_ARRA1_VAL_GENE) \ M_EMPLACE_ASS_ARRAY_DEF(name, name_t, M_F(name, _emplace), key_oplist, val_oplist, M_EMPLACE_ASS_ARRA1_BOTH_GENE, M_EMPLACE_ASS_ARRA1_KEY_GENE, M_EMPLACE_ASS_ARRA1_VAL_GENE) \
M_EMPLACE_QUEUE_DEF(name, name_t, M_C(name, _get_emplace), key_oplist, M_EMPLACE_GET_GENE) M_EMPLACE_QUEUE_DEF(name, name_t, M_F(name, _get_emplace), key_oplist, M_EMPLACE_GET_GENE)
#define M_EMPLACE_ASS_ARRAY_OR_QUEUE_DEF1(name, name_t, key_oplist, val_oplist) \ #define M_EMPLACE_ASS_ARRAY_OR_QUEUE_DEF1(name, name_t, key_oplist, val_oplist) \
M_EMPLACE_QUEUE_DEF(name, name_t, M_C(name, _emplace), key_oplist, M_EMPLACE_QUEUE_GENE) \ M_EMPLACE_QUEUE_DEF(name, name_t, M_F(name, _emplace), key_oplist, M_EMPLACE_QUEUE_GENE) \
M_EMPLACE_QUEUE_DEF(name, name_t, M_C(name, _get_emplace), key_oplist, M_EMPLACE_GET_GENE) M_EMPLACE_QUEUE_DEF(name, name_t, M_F(name, _get_emplace), key_oplist, M_EMPLACE_GET_GENE)
/* Definition of the emplace_back function for associative arrays. /* Definition of the emplace_back function for associative arrays.
@@ -4718,10 +4735,10 @@ m_core_parse2_enum (const char str[], const char **endptr)
M_EMPLACE_LIST_TYPE_VAR(akey, key_emplace_type) \ M_EMPLACE_LIST_TYPE_VAR(akey, key_emplace_type) \
M_EMPLACE_LIST_TYPE_VAR(aval, val_emplace_type) \ M_EMPLACE_LIST_TYPE_VAR(aval, val_emplace_type) \
){ \ ){ \
M_C(name, _key_ct) key; \ M_F(name, _key_ct) key; \
M_EMPLACE_CALL_FUNC(akey, key_init_func, key_oplist, key, key_emplace_type); \ M_EMPLACE_CALL_FUNC(akey, key_init_func, key_oplist, key, key_emplace_type); \
M_C(name, _value_ct) *val; \ M_F(name, _value_ct) *val; \
val = M_C(name, _safe_get)(v, key); \ val = M_F(name, _safe_get)(v, key); \
M_CALL_CLEAR(val_oplist, *val); \ M_CALL_CLEAR(val_oplist, *val); \
M_EMPLACE_CALL_FUNC(aval, val_init_func, val_oplist, *val, val_emplace_type); \ M_EMPLACE_CALL_FUNC(aval, val_init_func, val_oplist, *val, val_emplace_type); \
M_CALL_CLEAR(key_oplist, key); \ M_CALL_CLEAR(key_oplist, key); \
@@ -4731,21 +4748,21 @@ m_core_parse2_enum (const char str[], const char **endptr)
static inline void \ static inline void \
function_name(name_t v \ function_name(name_t v \
M_EMPLACE_LIST_TYPE_VAR(akey, key_emplace_type) \ M_EMPLACE_LIST_TYPE_VAR(akey, key_emplace_type) \
, M_C(name, _value_ct) const val \ , M_F(name, _value_ct) const val \
){ \ ){ \
M_C(name, _key_ct) key; \ M_F(name, _key_ct) key; \
M_EMPLACE_CALL_FUNC(akey, key_init_func, key_oplist, key, key_emplace_type); \ M_EMPLACE_CALL_FUNC(akey, key_init_func, key_oplist, key, key_emplace_type); \
M_C(name, _set_at)(v, key, val); \ M_F(name, _set_at)(v, key, val); \
M_CALL_CLEAR(key_oplist, key); \ M_CALL_CLEAR(key_oplist, key); \
} \ } \
#define M_EMPLACE_ASS_ARRA1_VAL_GENE(name, name_t, function_name, key_oplist, val_oplist, key_init_func, val_init_func, key_emplace_type, val_emplace_type) \ #define M_EMPLACE_ASS_ARRA1_VAL_GENE(name, name_t, function_name, key_oplist, val_oplist, key_init_func, val_init_func, key_emplace_type, val_emplace_type) \
static inline void \ static inline void \
function_name(name_t v, M_C(name, _key_ct) const key \ function_name(name_t v, M_F(name, _key_ct) const key \
M_EMPLACE_LIST_TYPE_VAR(aval, val_emplace_type) \ M_EMPLACE_LIST_TYPE_VAR(aval, val_emplace_type) \
){ \ ){ \
M_C(name, _value_ct) *val; \ M_F(name, _value_ct) *val; \
val = M_C(name, _safe_get)(v, key); \ val = M_F(name, _safe_get)(v, key); \
M_CALL_CLEAR(val_oplist, *val); \ M_CALL_CLEAR(val_oplist, *val); \
M_EMPLACE_CALL_FUNC(aval, val_init_func, val_oplist, *val, val_emplace_type); \ M_EMPLACE_CALL_FUNC(aval, val_init_func, val_oplist, *val, val_emplace_type); \
} \ } \
@@ -4762,7 +4779,7 @@ m_core_parse2_enum (const char str[], const char **endptr)
{ \ { \
M_GET_TYPE oplist data; \ M_GET_TYPE oplist data; \
M_EMPLACE_CALL_FUNC(a, init_func, oplist, data, exp_emplace_type); \ M_EMPLACE_CALL_FUNC(a, init_func, oplist, data, exp_emplace_type); \
M_C(name, _push)(v, data); \ M_F(name, _push)(v, data); \
M_CALL_CLEAR(oplist, data); \ M_CALL_CLEAR(oplist, data); \
} }
@@ -4772,13 +4789,13 @@ m_core_parse2_enum (const char str[], const char **endptr)
This definition is far from being efficient but works for the current interface. This definition is far from being efficient but works for the current interface.
*/ */
#define M_EMPLACE_GET_GENE(name, name_t, function_name, oplist, init_func, exp_emplace_type) \ #define M_EMPLACE_GET_GENE(name, name_t, function_name, oplist, init_func, exp_emplace_type) \
static inline M_C(name, _value_ct) * \ static inline M_F(name, _value_ct) * \
function_name(name_t const v \ function_name(name_t const v \
M_EMPLACE_LIST_TYPE_VAR(a, exp_emplace_type) ) \ M_EMPLACE_LIST_TYPE_VAR(a, exp_emplace_type) ) \
{ \ { \
M_GET_TYPE oplist data; \ M_GET_TYPE oplist data; \
M_EMPLACE_CALL_FUNC(a, init_func, oplist, data, exp_emplace_type); \ M_EMPLACE_CALL_FUNC(a, init_func, oplist, data, exp_emplace_type); \
M_C(name, _value_ct) *ret = M_C(name, _get)(v, data); \ M_F(name, _value_ct) *ret = M_F(name, _get)(v, data); \
M_CALL_CLEAR(oplist, data); \ M_CALL_CLEAR(oplist, data); \
return ret; \ return ret; \
} }
+200 -200
View File
File diff suppressed because it is too large. Load diff
+355 -355
View File
File diff suppressed because it is too large. Load diff
+49 -49
View File
@@ -33,7 +33,7 @@
* FUNC_OBJ_ITF_DEF(name, retcode type, type of param1, type of param 2, ...) * FUNC_OBJ_ITF_DEF(name, retcode type, type of param1, type of param 2, ...)
*/ */
#define M_FUNC_OBJ_ITF_DEF(name, ...) \ #define M_FUNC_OBJ_ITF_DEF(name, ...) \
M_FUNC_OBJ_ITF_DEF_AS(name, M_C(name,_t), __VA_ARGS__) M_FUNC_OBJ_ITF_DEF_AS(name, M_F(name,_t), __VA_ARGS__)
/* Define a function object interface of name 'name' /* Define a function object interface of name 'name'
@@ -66,7 +66,7 @@
* FUNC_OBJ_INS_DEF(name, base_name, (param1, ...), { return param1 * self->member1 }, (member1, int), ...) * FUNC_OBJ_INS_DEF(name, base_name, (param1, ...), { return param1 * self->member1 }, (member1, int), ...)
*/ */
#define M_FUNC_OBJ_INS_DEF(name, base_name, param_list, ...) \ #define M_FUNC_OBJ_INS_DEF(name, base_name, param_list, ...) \
M_FUNC_OBJ_INS_DEF_AS(name, M_C(name,_t), base_name, param_list, __VA_ARGS__) M_FUNC_OBJ_INS_DEF_AS(name, M_F(name,_t), base_name, param_list, __VA_ARGS__)
/* Define a function object instance of name 'name' based on the interface 'base_name' /* Define a function object instance of name 'name' based on the interface 'base_name'
@@ -111,9 +111,9 @@
/* Specialization of the OPLIST in function if there is at least one member or not */ /* Specialization of the OPLIST in function if there is at least one member or not */
#define M_FUNC0BJ_INS_NO_ATTR_OPLIST(name) ( \ #define M_FUNC0BJ_INS_NO_ATTR_OPLIST(name) ( \
NAME(name), \ NAME(name), \
TYPE(M_C(name, _ct)), \ TYPE(M_F(name, _ct)), \
CLEAR(M_C(name, _clear)), \ CLEAR(M_F(name, _clear)), \
INIT(M_C(name,_init)) \ INIT(M_F(name,_init)) \
) )
/* Validate the oplist before going further */ /* Validate the oplist before going further */
@@ -127,10 +127,10 @@
/* Define the oplist of the instance */ /* Define the oplist of the instance */
#define M_FUNC0BJ_INS_ATTR_OPLIST_P3(name, ...) ( \ #define M_FUNC0BJ_INS_ATTR_OPLIST_P3(name, ...) ( \
NAME(name), \ NAME(name), \
TYPE(M_C(name, _ct)), \ TYPE(M_F(name, _ct)), \
INIT_WITH(M_C(name, _init_with)), \ INIT_WITH(M_F(name, _init_with)), \
CLEAR(M_C(name, _clear)), \ CLEAR(M_F(name, _clear)), \
M_IF_METHOD_ALL(INIT, __VA_ARGS__)(INIT(M_C(name,_init)),), \ M_IF_METHOD_ALL(INIT, __VA_ARGS__)(INIT(M_F(name,_init)),), \
PROPERTIES(( LET_AS_INIT_WITH(1) )) \ PROPERTIES(( LET_AS_INIT_WITH(1) )) \
) )
@@ -140,29 +140,29 @@
/* Specialization of the definition a function object interface of name 'name' /* Specialization of the definition a function object interface of name 'name'
* with a function like "retcode (void)" that doesn't have any input parameters. * with a function like "retcode (void)" that doesn't have any input parameters.
* Define the following types to be used by instance: * Define the following types to be used by instance:
* - M_C(name, _retcode_ct): internal type of the return code * - M_F(name, _retcode_ct): internal type of the return code
* - M_C(name, _callback_ct): internal type of the callback. * - M_F(name, _callback_ct): internal type of the callback.
* - M_C(name, _ct): synonym of main type used by oplist. * - M_F(name, _ct): synonym of main type used by oplist.
*/ */
#define M_FUNC0BJ_ITF_NO_PARAM_DEF(name, interface_t, retcode) \ #define M_FUNC0BJ_ITF_NO_PARAM_DEF(name, interface_t, retcode) \
\ \
/* Forward declaration */ \ /* Forward declaration */ \
struct M_C(name, _s); \ struct M_F(name, _s); \
\ \
/* Internal type for instance */ \ /* Internal type for instance */ \
typedef retcode M_C(name, _retcode_ct); \ typedef retcode M_F(name, _retcode_ct); \
/* No parameters to the callback */ \ /* No parameters to the callback */ \
typedef retcode(*M_C(name, _callback_ct))(struct M_C(name, _s) *); \ typedef retcode(*M_F(name, _callback_ct))(struct M_F(name, _s) *); \
\ \
typedef struct M_C(name, _s) { \ typedef struct M_F(name, _s) { \
M_C(name, _callback_ct) callback; \ M_F(name, _callback_ct) callback; \
} interface_t[1]; \ } interface_t[1]; \
\ \
/* Internal type for oplist & instance */ \ /* Internal type for oplist & instance */ \
typedef interface_t M_C(name, _ct); \ typedef interface_t M_F(name, _ct); \
\ \
static inline retcode \ static inline retcode \
M_C(name, _call)(interface_t funcobj) \ M_F(name, _call)(interface_t funcobj) \
{ \ { \
M_IF(M_KEYWORD_P(void, retcode)) ( /* nothing */,return) \ M_IF(M_KEYWORD_P(void, retcode)) ( /* nothing */,return) \
funcobj->callback(funcobj); \ funcobj->callback(funcobj); \
@@ -173,32 +173,32 @@
* with a function like retcode, type of param1, type of param 2, ... * with a function like retcode, type of param1, type of param 2, ...
* with mandatory input parameters. * with mandatory input parameters.
* Define the following types to be used by instance: * Define the following types to be used by instance:
* - M_C(name, _retcode_ct): internal type of the return code * - M_F(name, _retcode_ct): internal type of the return code
* - M_C(name, _callback_ct): internal type of the callback. * - M_F(name, _callback_ct): internal type of the callback.
* - M_C4(name, _param_, num, _ct) for each parameter defined * - M_C4(name, _param_, num, _ct) for each parameter defined
* - M_C(name, _ct): synonym of main type used by oplist. * - M_F(name, _ct): synonym of main type used by oplist.
*/ */
#define M_FUNC0BJ_ITF_PARAM_DEF(name, interface_t, retcode, ...) \ #define M_FUNC0BJ_ITF_PARAM_DEF(name, interface_t, retcode, ...) \
\ \
/* Forward declaration */ \ /* Forward declaration */ \
struct M_C(name, _s); \ struct M_F(name, _s); \
\ \
/* Internal types for instance */ \ /* Internal types for instance */ \
typedef retcode M_C(name, _retcode_ct); \ typedef retcode M_F(name, _retcode_ct); \
/* Define types for all parameters */ \ /* Define types for all parameters */ \
M_MAP3(M_FUNC0BJ_BASE_TYPE, name, __VA_ARGS__) \ M_MAP3(M_FUNC0BJ_BASE_TYPE, name, __VA_ARGS__) \
/* Define callback type with all parameters */ \ /* Define callback type with all parameters */ \
typedef retcode(*M_C(name, _callback_ct))(struct M_C(name, _s) *, __VA_ARGS__); \ typedef retcode(*M_F(name, _callback_ct))(struct M_F(name, _s) *, __VA_ARGS__); \
\ \
typedef struct M_C(name, _s) { \ typedef struct M_F(name, _s) { \
M_C(name, _callback_ct) callback; \ M_F(name, _callback_ct) callback; \
} interface_t[1]; \ } interface_t[1]; \
\ \
/* Internal type for oplist & instance */ \ /* Internal type for oplist & instance */ \
typedef interface_t M_C(name, _ct); \ typedef interface_t M_F(name, _ct); \
\ \
static inline retcode \ static inline retcode \
M_C(name, _call)(interface_t funcobj \ M_F(name, _call)(interface_t funcobj \
M_MAP3(M_FUNC0BJ_BASE_ARGLIST, name, __VA_ARGS__) ) \ M_MAP3(M_FUNC0BJ_BASE_ARGLIST, name, __VA_ARGS__) ) \
{ \ { \
/* If the retcode is 'void', don't return the value of the callback */ \ /* If the retcode is 'void', don't return the value of the callback */ \
@@ -213,48 +213,48 @@
* with no member attribute. * with no member attribute.
*/ */
#define M_FUNC0BJ_INS_NO_ATTR_DEF(name, instance_t, base_name, param_list, callback_core) \ #define M_FUNC0BJ_INS_NO_ATTR_DEF(name, instance_t, base_name, param_list, callback_core) \
typedef struct M_C(name, _s) { \ typedef struct M_F(name, _s) { \
M_C(base_name, _callback_ct) callback; \ M_C(base_name, _callback_ct) callback; \
} instance_t[1]; \ } instance_t[1]; \
\ \
/* Internal type for oplist */ \ /* Internal type for oplist */ \
typedef instance_t M_C(name, _ct); \ typedef instance_t M_F(name, _ct); \
\ \
static inline M_C(base_name, _retcode_ct) \ static inline M_C(base_name, _retcode_ct) \
M_C(name, _callback)(M_C(base_name, _ct) _self \ M_F(name, _callback)(M_C(base_name, _ct) _self \
M_IF_EMPTY(M_OPFLAT param_list)( \ M_IF_EMPTY(M_OPFLAT param_list)( \
/* No param */, \ /* No param */, \
M_MAP3(M_FUNC0BJ_INS_ARGLIST, base_name, M_OPFLAT param_list) \ M_MAP3(M_FUNC0BJ_INS_ARGLIST, base_name, M_OPFLAT param_list) \
) \ ) \
) \ ) \
{ \ { \
struct M_C(name, _s) *self = (struct M_C(name, _s) *)_self; \ struct M_F(name, _s) *self = (struct M_F(name, _s) *)_self; \
(void) self; /* maybe unused */ \ (void) self; /* maybe unused */ \
callback_core; \ callback_core; \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _init_with)(instance_t obj) \ M_F(name, _init_with)(instance_t obj) \
{ \ { \
obj->callback = M_C(name, _callback); \ obj->callback = M_F(name, _callback); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _clear)(instance_t obj) \ M_F(name, _clear)(instance_t obj) \
{ \ { \
(void) obj; /* nothing to do */ \ (void) obj; /* nothing to do */ \
} \ } \
\ \
static inline struct M_C(base_name, _s) * \ static inline struct M_C(base_name, _s) * \
M_C(name, _as_interface)(instance_t obj) \ M_F(name, _as_interface)(instance_t obj) \
{ \ { \
return (struct M_C(base_name, _s) *) obj; \ return (struct M_C(base_name, _s) *) obj; \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _init)(instance_t obj) \ M_F(name, _init)(instance_t obj) \
{ \ { \
obj->callback = M_C(name, _callback); \ obj->callback = M_F(name, _callback); \
} \ } \
@@ -294,7 +294,7 @@
/* Expand the Function Object with members */ /* Expand the Function Object with members */
#define M_FUNC0BJ_INS_ATTR_DEF_P3(name, instance_t, base_name, param_list, callback_core, ...) \ #define M_FUNC0BJ_INS_ATTR_DEF_P3(name, instance_t, base_name, param_list, callback_core, ...) \
typedef struct M_C(name, _s) { \ typedef struct M_F(name, _s) { \
/* Callback is the mandatory first argument */ \ /* Callback is the mandatory first argument */ \
M_C(base_name, _callback_ct) callback; \ M_C(base_name, _callback_ct) callback; \
/* All the member attribute of the Function Object */ \ /* All the member attribute of the Function Object */ \
@@ -302,12 +302,12 @@
} instance_t[1]; \ } instance_t[1]; \
\ \
/* Internal type for oplist */ \ /* Internal type for oplist */ \
typedef instance_t M_C(name, _ct); \ typedef instance_t M_F(name, _ct); \
\ \
M_FUNC0BJ_CONTROL_ALL_OPLIST(name, __VA_ARGS__) \ M_FUNC0BJ_CONTROL_ALL_OPLIST(name, __VA_ARGS__) \
\ \
static inline M_C(base_name, _retcode_ct) \ static inline M_C(base_name, _retcode_ct) \
M_C(name, _callback)(M_C(base_name, _ct) _self \ M_F(name, _callback)(M_C(base_name, _ct) _self \
M_IF_EMPTY(M_OPFLAT param_list)( \ M_IF_EMPTY(M_OPFLAT param_list)( \
/* No param */, \ /* No param */, \
M_MAP3(M_FUNC0BJ_INS_ARGLIST, base_name, M_OPFLAT param_list) \ M_MAP3(M_FUNC0BJ_INS_ARGLIST, base_name, M_OPFLAT param_list) \
@@ -316,26 +316,26 @@
{ \ { \
/* Let's go through an uintptr_t to avoid [broken] aliasing detection by compiler */ \ /* Let's go through an uintptr_t to avoid [broken] aliasing detection by compiler */ \
uintptr_t __self = (uintptr_t) _self; \ uintptr_t __self = (uintptr_t) _self; \
struct M_C(name, _s) *self = (struct M_C(name, _s) *)(void*)__self; \ struct M_F(name, _s) *self = (struct M_F(name, _s) *)(void*)__self; \
(void) self; /* maybe unused */ \ (void) self; /* maybe unused */ \
callback_core; \ callback_core; \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _init_with)(instance_t obj M_MAP(M_FUNC0BJ_INS_ATTR_LIST, __VA_ARGS__)) \ M_F(name, _init_with)(instance_t obj M_MAP(M_FUNC0BJ_INS_ATTR_LIST, __VA_ARGS__)) \
{ \ { \
obj->callback = M_C(name, _callback); \ obj->callback = M_F(name, _callback); \
M_MAP(M_FUNC0BJ_INS_ATTR_INIT_SET, __VA_ARGS__); \ M_MAP(M_FUNC0BJ_INS_ATTR_INIT_SET, __VA_ARGS__); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _clear)(instance_t obj) \ M_F(name, _clear)(instance_t obj) \
{ \ { \
M_MAP(M_FUNC0BJ_INS_ATTR_CLEAR, __VA_ARGS__); \ M_MAP(M_FUNC0BJ_INS_ATTR_CLEAR, __VA_ARGS__); \
} \ } \
\ \
static inline struct M_C(base_name, _s) * \ static inline struct M_C(base_name, _s) * \
M_C(name, _as_interface)(instance_t obj) \ M_F(name, _as_interface)(instance_t obj) \
{ \ { \
return (struct M_C(base_name, _s) *) obj; \ return (struct M_C(base_name, _s) *) obj; \
} \ } \
@@ -343,9 +343,9 @@
M_IF(M_FUNC0BJ_TEST_METHOD_P(INIT, __VA_ARGS)) \ M_IF(M_FUNC0BJ_TEST_METHOD_P(INIT, __VA_ARGS)) \
( \ ( \
static inline void \ static inline void \
M_C(name, _init)(instance_t obj) \ M_F(name, _init)(instance_t obj) \
{ \ { \
obj->callback = M_C(name, _callback); \ obj->callback = M_F(name, _callback); \
M_MAP(M_FUNC0BJ_INS_ATTR_INIT, __VA_ARGS__); \ M_MAP(M_FUNC0BJ_INS_ATTR_INIT, __VA_ARGS__); \
} \ } \
, /* END OF INIT METHOD */ ) \ , /* END OF INIT METHOD */ ) \
+92 -92
View File
@@ -47,7 +47,7 @@
USAGE: USAGE:
ILIST_DEF(name, type [, oplist_of_the_type]) */ ILIST_DEF(name, type [, oplist_of_the_type]) */
#define M_ILIST_DEF(name, ...) \ #define M_ILIST_DEF(name, ...) \
M_ILIST_DEF_AS(name, M_C(name,_t), M_C(name,_it_t), __VA_ARGS__) M_ILIST_DEF_AS(name, M_F(name,_t), M_F(name,_it_t), __VA_ARGS__)
/* Define a doubly-linked intrusive list of a given type /* Define a doubly-linked intrusive list of a given type
@@ -95,31 +95,31 @@ typedef struct m_il1st_head_s {
/* Define the oplist of an ilist of type */ /* Define the oplist of an ilist of type */
#define M_IL1ST_OPLIST_P3(name, oplist) \ #define M_IL1ST_OPLIST_P3(name, oplist) \
(INIT(M_C(name, _init)), \ (INIT(M_F(name, _init)), \
CLEAR(M_C(name, _clear)), \ CLEAR(M_F(name, _clear)), \
INIT_MOVE(M_C(name, _init_move)), \ INIT_MOVE(M_F(name, _init_move)), \
MOVE(M_C(name, _move)), \ MOVE(M_F(name, _move)), \
NAME(name), \ NAME(name), \
TYPE(M_C(name,_ct)), \ TYPE(M_F(name,_ct)), \
RESET(M_C(name,_reset)), \ RESET(M_F(name,_reset)), \
SUBTYPE(M_C(name,_subtype_ct)), \ SUBTYPE(M_F(name,_subtype_ct)), \
EMPTY_P(M_C(name,_empty_p)), \ EMPTY_P(M_F(name,_empty_p)), \
IT_TYPE(M_C(name,_it_ct)), \ IT_TYPE(M_F(name,_it_ct)), \
IT_FIRST(M_C(name,_it)), \ IT_FIRST(M_F(name,_it)), \
IT_SET(M_C(name,_it_set)), \ IT_SET(M_F(name,_it_set)), \
IT_LAST(M_C(name,_it_last)), \ IT_LAST(M_F(name,_it_last)), \
IT_END(M_C(name,_it_end)), \ IT_END(M_F(name,_it_end)), \
IT_END_P(M_C(name,_end_p)), \ IT_END_P(M_F(name,_end_p)), \
IT_LAST_P(M_C(name,_last_p)), \ IT_LAST_P(M_F(name,_last_p)), \
IT_EQUAL_P(M_C(name,_it_equal_p)), \ IT_EQUAL_P(M_F(name,_it_equal_p)), \
IT_NEXT(M_C(name,_next)), \ IT_NEXT(M_F(name,_next)), \
IT_PREVIOUS(M_C(name,_previous)), \ IT_PREVIOUS(M_F(name,_previous)), \
IT_REF(M_C(name,_ref)), \ IT_REF(M_F(name,_ref)), \
IT_CREF(M_C(name,_cref)), \ IT_CREF(M_F(name,_cref)), \
IT_REMOVE(M_C(name,_remove)), \ IT_REMOVE(M_F(name,_remove)), \
M_IF_METHOD(NEW, oplist)(IT_INSERT(M_C(name,_insert)),), \ M_IF_METHOD(NEW, oplist)(IT_INSERT(M_F(name,_insert)),), \
OPLIST(oplist), \ OPLIST(oplist), \
SPLICE_BACK(M_C(name,_splice_back)) \ SPLICE_BACK(M_F(name,_splice_back)) \
,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW oplist),) \ ,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW oplist),) \
,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL oplist),) \ ,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL oplist),) \
) )
@@ -176,16 +176,16 @@ typedef struct m_il1st_head_s {
\ \
/* Define the list as a structure containing pointers \ /* Define the list as a structure containing pointers \
* to the front & back nodes */ \ * to the front & back nodes */ \
typedef struct M_C(name, _s) { \ typedef struct M_F(name, _s) { \
struct m_il1st_head_s name; \ struct m_il1st_head_s name; \
} list_t[1]; \ } list_t[1]; \
\ \
/* Define internal types pointers to such a list */ \ /* Define internal types pointers to such a list */ \
typedef struct M_C(name, _s) *M_C(name, _ptr); \ typedef struct M_F(name, _s) *M_F(name, _ptr); \
typedef const struct M_C(name, _s) *M_C(name, _srcptr); \ typedef const struct M_F(name, _s) *M_F(name, _srcptr); \
\ \
/* Define iterator of such a list */ \ /* Define iterator of such a list */ \
typedef struct M_C(name, _it_s) { \ typedef struct M_F(name, _it_s) { \
struct m_il1st_head_s *head; \ struct m_il1st_head_s *head; \
struct m_il1st_head_s *previous; \ struct m_il1st_head_s *previous; \
struct m_il1st_head_s *current; \ struct m_il1st_head_s *current; \
@@ -193,15 +193,15 @@ typedef struct m_il1st_head_s {
} it_t[1]; \ } it_t[1]; \
\ \
/* Define types used by oplist */ \ /* Define types used by oplist */ \
typedef type M_C(name, _subtype_ct); \ typedef type M_F(name, _subtype_ct); \
typedef list_t M_C(name, _ct); \ typedef list_t M_F(name, _ct); \
typedef it_t M_C(name, _it_ct); \ typedef it_t M_F(name, _it_ct); \
/* Define core functions for intrusive lists */ /* Define core functions for intrusive lists */
#define M_IL1ST_DEF_CORE(name, type, oplist, list_t, it_t) \ #define M_IL1ST_DEF_CORE(name, type, oplist, list_t, it_t) \
\ \
static inline void \ static inline void \
M_C(name, _init)(list_t list) \ M_F(name, _init)(list_t list) \
{ \ { \
M_ASSERT (list != NULL); \ M_ASSERT (list != NULL); \
list->name.next = &list->name; \ list->name.next = &list->name; \
@@ -210,7 +210,7 @@ typedef struct m_il1st_head_s {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _reset)(list_t list) \ M_F(name, _reset)(list_t list) \
{ \ { \
M_IL1ST_CONTRACT(name, list); \ M_IL1ST_CONTRACT(name, list); \
for(struct m_il1st_head_s *it = list->name.next, *next ; \ for(struct m_il1st_head_s *it = list->name.next, *next ; \
@@ -232,17 +232,17 @@ typedef struct m_il1st_head_s {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _clear)(list_t list) \ M_F(name, _clear)(list_t list) \
{ \ { \
/* Nothing to do more than clean the list itself */ \ /* Nothing to do more than clean the list itself */ \
M_C(name, _reset)(list); \ M_F(name, _reset)(list); \
/* For safety purpose (create invalid represenation of object) */ \ /* For safety purpose (create invalid represenation of object) */ \
list->name.next = NULL; \ list->name.next = NULL; \
list->name.prev = NULL; \ list->name.prev = NULL; \
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _empty_p)(const list_t list) \ M_F(name, _empty_p)(const list_t list) \
{ \ { \
M_IL1ST_CONTRACT(name, list); \ M_IL1ST_CONTRACT(name, list); \
return list->name.next == &list->name; \ return list->name.next == &list->name; \
@@ -250,12 +250,12 @@ typedef struct m_il1st_head_s {
\ \
\ \
static inline void \ static inline void \
M_C(name, _init_move)(list_t list, list_t ref) \ M_F(name, _init_move)(list_t list, list_t ref) \
{ \ { \
M_IL1ST_CONTRACT(name, ref); \ M_IL1ST_CONTRACT(name, ref); \
M_ASSERT (list != ref); \ M_ASSERT (list != ref); \
M_C(name,_init)(list); \ M_F(name,_init)(list); \
if (!M_C(name,_empty_p)(ref)) { \ if (!M_F(name,_empty_p)(ref)) { \
list->name.next = ref->name.next; \ list->name.next = ref->name.next; \
list->name.prev = ref->name.prev; \ list->name.prev = ref->name.prev; \
list->name.next->prev = &list->name; \ list->name.next->prev = &list->name; \
@@ -267,14 +267,14 @@ typedef struct m_il1st_head_s {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _move)(list_t list, list_t ref) \ M_F(name, _move)(list_t list, list_t ref) \
{ \ { \
M_C(name, _clear)(list); \ M_F(name, _clear)(list); \
M_C(name, _init_move)(list, ref); \ M_F(name, _init_move)(list, ref); \
} \ } \
\ \
static inline size_t \ static inline size_t \
M_C(name, _size)(const list_t list) \ M_F(name, _size)(const list_t list) \
{ \ { \
M_IL1ST_CONTRACT(name, list); \ M_IL1ST_CONTRACT(name, list); \
size_t s = 0; \ size_t s = 0; \
@@ -288,7 +288,7 @@ typedef struct m_il1st_head_s {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _push_back)(list_t list, type *obj) \ M_F(name, _push_back)(list_t list, type *obj) \
{ \ { \
M_IL1ST_CONTRACT(name, list); \ M_IL1ST_CONTRACT(name, list); \
M_ASSERT (obj != NULL); \ M_ASSERT (obj != NULL); \
@@ -301,7 +301,7 @@ typedef struct m_il1st_head_s {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _push_front)(list_t list, type *obj) \ M_F(name, _push_front)(list_t list, type *obj) \
{ \ { \
M_IL1ST_CONTRACT(name, list); \ M_IL1ST_CONTRACT(name, list); \
M_ASSERT (obj != NULL); \ M_ASSERT (obj != NULL); \
@@ -314,7 +314,7 @@ typedef struct m_il1st_head_s {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _push_after)(type *obj_pos, type *obj) \ M_F(name, _push_after)(type *obj_pos, type *obj) \
{ \ { \
M_ASSERT (obj_pos != NULL && obj != NULL); \ M_ASSERT (obj_pos != NULL && obj != NULL); \
/* We don't have the list, so we have no contract at list level */ \ /* We don't have the list, so we have no contract at list level */ \
@@ -327,7 +327,7 @@ typedef struct m_il1st_head_s {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _init_field)(type *obj) \ M_F(name, _init_field)(type *obj) \
{ \ { \
M_ASSERT (obj != NULL); \ M_ASSERT (obj != NULL); \
/* Init the fields of the node. To be used in object constructor */ \ /* Init the fields of the node. To be used in object constructor */ \
@@ -336,7 +336,7 @@ typedef struct m_il1st_head_s {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _unlink)(type *obj) \ M_F(name, _unlink)(type *obj) \
{ \ { \
M_ASSERT (obj != NULL); \ M_ASSERT (obj != NULL); \
/* We don't have the list, so we have no contract at list level */ \ /* We don't have the list, so we have no contract at list level */ \
@@ -351,25 +351,25 @@ typedef struct m_il1st_head_s {
} \ } \
\ \
static inline type * \ static inline type * \
M_C(name, _back)(const list_t list) \ M_F(name, _back)(const list_t list) \
{ \ { \
M_IL1ST_CONTRACT(name, list); \ M_IL1ST_CONTRACT(name, list); \
M_ASSERT(!M_C(name, _empty_p)(list)); \ M_ASSERT(!M_F(name, _empty_p)(list)); \
return M_TYPE_FROM_FIELD(type, list->name.prev, \ return M_TYPE_FROM_FIELD(type, list->name.prev, \
struct m_il1st_head_s, name); \ struct m_il1st_head_s, name); \
} \ } \
\ \
static inline type * \ static inline type * \
M_C(name, _front)(const list_t list) \ M_F(name, _front)(const list_t list) \
{ \ { \
M_IL1ST_CONTRACT(name, list); \ M_IL1ST_CONTRACT(name, list); \
M_ASSERT(!M_C(name, _empty_p)(list)); \ M_ASSERT(!M_F(name, _empty_p)(list)); \
return M_TYPE_FROM_FIELD(type, list->name.next, \ return M_TYPE_FROM_FIELD(type, list->name.next, \
struct m_il1st_head_s, name); \ struct m_il1st_head_s, name); \
} \ } \
\ \
static inline type * \ static inline type * \
M_C(name, _next_obj)(const list_t list, type const *obj) \ M_F(name, _next_obj)(const list_t list, type const *obj) \
{ \ { \
M_IL1ST_CONTRACT(name, list); \ M_IL1ST_CONTRACT(name, list); \
M_ASSERT (obj != NULL); \ M_ASSERT (obj != NULL); \
@@ -380,7 +380,7 @@ typedef struct m_il1st_head_s {
} \ } \
\ \
static inline type * \ static inline type * \
M_C(name, _previous_obj)(const list_t list, type const *obj) \ M_F(name, _previous_obj)(const list_t list, type const *obj) \
{ \ { \
M_IL1ST_CONTRACT(name, list); \ M_IL1ST_CONTRACT(name, list); \
M_ASSERT (obj != NULL); \ M_ASSERT (obj != NULL); \
@@ -391,7 +391,7 @@ typedef struct m_il1st_head_s {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _it)(it_t it, const list_t list) \ M_F(name, _it)(it_t it, const list_t list) \
{ \ { \
M_IL1ST_CONTRACT(name, list); \ M_IL1ST_CONTRACT(name, list); \
M_ASSERT (it != NULL); \ M_ASSERT (it != NULL); \
@@ -403,7 +403,7 @@ typedef struct m_il1st_head_s {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _it_set)(it_t it, const it_t cit) \ M_F(name, _it_set)(it_t it, const it_t cit) \
{ \ { \
M_ASSERT (it != NULL && cit != NULL); \ M_ASSERT (it != NULL && cit != NULL); \
it->head = cit->head; \ it->head = cit->head; \
@@ -414,7 +414,7 @@ typedef struct m_il1st_head_s {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _it_last)(it_t it, list_t const list) \ M_F(name, _it_last)(it_t it, list_t const list) \
{ \ { \
M_IL1ST_CONTRACT(name, list); \ M_IL1ST_CONTRACT(name, list); \
M_ASSERT (it != NULL); \ M_ASSERT (it != NULL); \
@@ -426,7 +426,7 @@ typedef struct m_il1st_head_s {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _it_end)(it_t it, list_t const list) \ M_F(name, _it_end)(it_t it, list_t const list) \
{ \ { \
M_ASSERT (it != NULL && list != NULL); \ M_ASSERT (it != NULL && list != NULL); \
it->head = list->name.next->prev; \ it->head = list->name.next->prev; \
@@ -437,7 +437,7 @@ typedef struct m_il1st_head_s {
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _end_p)(const it_t it) \ M_F(name, _end_p)(const it_t it) \
{ \ { \
M_ASSERT (it != NULL); \ M_ASSERT (it != NULL); \
M_IL1ST_NODE_CONTRACT(it->current); \ M_IL1ST_NODE_CONTRACT(it->current); \
@@ -445,7 +445,7 @@ typedef struct m_il1st_head_s {
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _last_p)(const it_t it) \ M_F(name, _last_p)(const it_t it) \
{ \ { \
M_ASSERT (it != NULL); \ M_ASSERT (it != NULL); \
M_IL1ST_NODE_CONTRACT(it->current); \ M_IL1ST_NODE_CONTRACT(it->current); \
@@ -453,7 +453,7 @@ typedef struct m_il1st_head_s {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _next)(it_t it) \ M_F(name, _next)(it_t it) \
{ \ { \
M_ASSERT (it != NULL); \ M_ASSERT (it != NULL); \
/* Cannot check node for it->current: it may have been deleted! */ \ /* Cannot check node for it->current: it may have been deleted! */ \
@@ -468,7 +468,7 @@ typedef struct m_il1st_head_s {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _previous)(it_t it) \ M_F(name, _previous)(it_t it) \
{ \ { \
M_ASSERT (it != NULL); \ M_ASSERT (it != NULL); \
/* Cannot check node for it->current: it may have been deleted! */ \ /* Cannot check node for it->current: it may have been deleted! */ \
@@ -483,7 +483,7 @@ typedef struct m_il1st_head_s {
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _it_equal_p)(const it_t it1, const it_t it2 ) \ M_F(name, _it_equal_p)(const it_t it1, const it_t it2 ) \
{ \ { \
M_ASSERT (it1 != NULL && it2 != NULL); \ M_ASSERT (it1 != NULL && it2 != NULL); \
/* No need to check for next & previous */ \ /* No need to check for next & previous */ \
@@ -491,42 +491,42 @@ typedef struct m_il1st_head_s {
} \ } \
\ \
static inline type * \ static inline type * \
M_C(name, _ref)(const it_t it) \ M_F(name, _ref)(const it_t it) \
{ \ { \
M_ASSERT (it != NULL && it->current != NULL); \ M_ASSERT (it != NULL && it->current != NULL); \
M_IL1ST_NODE_CONTRACT(it->current); \ M_IL1ST_NODE_CONTRACT(it->current); \
/* check if 'it' was not deleted */ \ /* check if 'it' was not deleted */ \
M_ASSERT (it->current->next == it->next); \ M_ASSERT (it->current->next == it->next); \
M_ASSERT (it->current->prev == it->previous); \ M_ASSERT (it->current->prev == it->previous); \
M_ASSERT (!M_C(name, _end_p)(it)); \ M_ASSERT (!M_F(name, _end_p)(it)); \
return M_TYPE_FROM_FIELD(type, it->current, \ return M_TYPE_FROM_FIELD(type, it->current, \
struct m_il1st_head_s, name); \ struct m_il1st_head_s, name); \
} \ } \
\ \
static inline type const * \ static inline type const * \
M_C(name, _cref)(const it_t it) \ M_F(name, _cref)(const it_t it) \
{ \ { \
type *ptr = M_C(name, _ref)(it); \ type *ptr = M_F(name, _ref)(it); \
return M_CONST_CAST(type, ptr); \ return M_CONST_CAST(type, ptr); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _remove)(list_t list, it_t it) \ M_F(name, _remove)(list_t list, it_t it) \
{ \ { \
M_IL1ST_CONTRACT(name, list); \ M_IL1ST_CONTRACT(name, list); \
M_IL1ST_NODE_CONTRACT(it->current); \ M_IL1ST_NODE_CONTRACT(it->current); \
(void)list; /* list param is not used */ \ (void)list; /* list param is not used */ \
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_C(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_C(name, _next)(it); \ M_F(name, _next)(it); \
} \ } \
\ \
M_IF_METHOD2(NEW, INIT_SET, oplist)( \ M_IF_METHOD2(NEW, INIT_SET, oplist)( \
static inline void \ static inline void \
M_C(name, _insert)(list_t list, it_t it, type x) \ M_F(name, _insert)(list_t list, it_t it, type x) \
{ \ { \
M_IL1ST_CONTRACT(name, list); \ M_IL1ST_CONTRACT(name, list); \
M_IL1ST_NODE_CONTRACT(it->current); \ M_IL1ST_NODE_CONTRACT(it->current); \
@@ -536,8 +536,8 @@ typedef struct m_il1st_head_s {
return ; \ return ; \
} \ } \
M_CALL_INIT_SET(oplist, *p, x); \ M_CALL_INIT_SET(oplist, *p, x); \
type *obj = M_C(name, _ref)(it); \ type *obj = M_F(name, _ref)(it); \
M_C(name, _push_after)(obj, p); \ M_F(name, _push_after)(obj, p); \
it->current = p; \ it->current = p; \
(void) list; \ (void) list; \
M_IL1ST_CONTRACT(name, list); \ M_IL1ST_CONTRACT(name, list); \
@@ -545,29 +545,29 @@ typedef struct m_il1st_head_s {
, /* NEW & INIT_SET not defined */) \ , /* NEW & INIT_SET not defined */) \
\ \
static inline type * \ static inline type * \
M_C(name, _pop_back)(list_t list) \ M_F(name, _pop_back)(list_t list) \
{ \ { \
M_IL1ST_CONTRACT(name, list); \ M_IL1ST_CONTRACT(name, list); \
M_ASSERT (!M_C(name, _empty_p)(list)); \ M_ASSERT (!M_F(name, _empty_p)(list)); \
type *obj = M_C(name, _back)(list); \ type *obj = M_F(name, _back)(list); \
list->name.prev = list->name.prev->prev; \ list->name.prev = list->name.prev->prev; \
list->name.prev->next = &list->name; \ list->name.prev->next = &list->name; \
return obj; \ return obj; \
} \ } \
\ \
static inline type * \ static inline type * \
M_C(name, _pop_front)(list_t list) \ M_F(name, _pop_front)(list_t list) \
{ \ { \
M_IL1ST_CONTRACT(name, list); \ M_IL1ST_CONTRACT(name, list); \
M_ASSERT (!M_C(name, _empty_p)(list)); \ M_ASSERT (!M_F(name, _empty_p)(list)); \
type *obj = M_C(name, _front)(list); \ type *obj = M_F(name, _front)(list); \
list->name.next = list->name.next->next; \ list->name.next = list->name.next->next; \
list->name.next->prev = &list->name; \ list->name.next->prev = &list->name; \
return obj; \ return obj; \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _splice)(list_t list1, list_t list2) \ M_F(name, _splice)(list_t list1, list_t list2) \
{ \ { \
M_IL1ST_CONTRACT(name, list1); \ M_IL1ST_CONTRACT(name, list1); \
M_IL1ST_CONTRACT(name, list2); \ M_IL1ST_CONTRACT(name, list2); \
@@ -584,35 +584,35 @@ typedef struct m_il1st_head_s {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _splice_back)(list_t nv, list_t ov, it_t it) \ M_F(name, _splice_back)(list_t nv, list_t ov, it_t it) \
{ \ { \
M_IL1ST_CONTRACT(name, nv); \ M_IL1ST_CONTRACT(name, nv); \
M_IL1ST_CONTRACT(name, ov); \ M_IL1ST_CONTRACT(name, ov); \
M_IL1ST_NODE_CONTRACT(it->current); \ M_IL1ST_NODE_CONTRACT(it->current); \
M_ASSERT (it != NULL); \ M_ASSERT (it != NULL); \
(void) ov; \ (void) ov; \
type *obj = M_C(name, _ref)(it); \ type *obj = M_F(name, _ref)(it); \
M_C(name, _unlink)(obj); \ M_F(name, _unlink)(obj); \
M_C(name, _push_back)(nv, obj); \ M_F(name, _push_back)(nv, obj); \
M_C(name, _next)(it); \ M_F(name, _next)(it); \
M_IL1ST_CONTRACT(name, nv); \ M_IL1ST_CONTRACT(name, nv); \
M_IL1ST_CONTRACT(name, ov); \ M_IL1ST_CONTRACT(name, ov); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _splice_at)(list_t nlist, it_t npos, \ M_F(name, _splice_at)(list_t nlist, it_t npos, \
list_t olist, it_t opos) \ list_t olist, it_t opos) \
{ \ { \
M_IL1ST_CONTRACT(name, nlist); \ M_IL1ST_CONTRACT(name, nlist); \
M_IL1ST_CONTRACT(name, olist); \ M_IL1ST_CONTRACT(name, olist); \
M_ASSERT (npos != NULL && opos != NULL); \ M_ASSERT (npos != NULL && opos != NULL); \
M_ASSERT (!M_C(name, _end_p)(opos)); \ M_ASSERT (!M_F(name, _end_p)(opos)); \
/* npos may be end */ \ /* npos may be end */ \
(void) olist, (void) nlist; \ (void) olist, (void) nlist; \
type *obj = M_C(name, _ref)(opos); \ type *obj = M_F(name, _ref)(opos); \
struct m_il1st_head_s *ref = npos->current; \ struct m_il1st_head_s *ref = npos->current; \
/* Remove object */ \ /* Remove object */ \
M_C(name, _unlink)(obj); \ M_F(name, _unlink)(obj); \
/* Push 'obj' after 'ref' */ \ /* Push 'obj' after 'ref' */ \
struct m_il1st_head_s *next = ref->next; \ struct m_il1st_head_s *next = ref->next; \
ref->next = &obj->name; \ ref->next = &obj->name; \
@@ -620,7 +620,7 @@ typedef struct m_il1st_head_s {
obj->name.prev = ref; \ obj->name.prev = ref; \
next->prev = &obj->name; \ next->prev = &obj->name; \
/* Move iterator in old list */ \ /* Move iterator in old list */ \
M_C(name, _next)(opos); \ M_F(name, _next)(opos); \
/* Set npos iterator to new position of object */ \ /* Set npos iterator to new position of object */ \
npos->previous = ref; \ npos->previous = ref; \
npos->current = &obj->name; \ npos->current = &obj->name; \
@@ -630,7 +630,7 @@ typedef struct m_il1st_head_s {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _swap)(list_t d, list_t e) \ M_F(name, _swap)(list_t d, list_t e) \
{ \ { \
M_IL1ST_CONTRACT(name, d); \ M_IL1ST_CONTRACT(name, d); \
M_IL1ST_CONTRACT(name, e); \ M_IL1ST_CONTRACT(name, e); \
@@ -653,7 +653,7 @@ typedef struct m_il1st_head_s {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _reverse)(list_t list) \ M_F(name, _reverse)(list_t list) \
{ \ { \
M_IL1ST_CONTRACT(name, list); \ M_IL1ST_CONTRACT(name, list); \
struct m_il1st_head_s *next, *it; \ struct m_il1st_head_s *next, *it; \
+32 -32
View File
@@ -43,12 +43,12 @@ M_BEGIN_PROTECTED_CODE
type: name of the type of the structure (aka. struct test_s) - not used currently. type: name of the type of the structure (aka. struct test_s) - not used currently.
NOTE: There can be only one interface of this kind in a type! */ NOTE: There can be only one interface of this kind in a type! */
#define M_ISHARED_PTR_INTERFACE(name, type) \ #define M_ISHARED_PTR_INTERFACE(name, type) \
atomic_int M_C(name, _cpt) atomic_int M_F(name, _cpt)
/* Value of the interface field for static intialization (Uses C99 designated element). */ /* Value of the interface field for static intialization (Uses C99 designated element). */
#define M_ISHARED_PTR_STATIC_DESIGNATED_INIT(name, type) \ #define M_ISHARED_PTR_STATIC_DESIGNATED_INIT(name, type) \
.M_C(name, _cpt) = ATOMIC_VAR_INIT(0) .M_F(name, _cpt) = ATOMIC_VAR_INIT(0)
/* Value of the interface field for static intialization (Uses C89 designated element). */ /* Value of the interface field for static intialization (Uses C89 designated element). */
#define M_ISHARED_PTR_STATIC_INIT(name, type) \ #define M_ISHARED_PTR_STATIC_INIT(name, type) \
@@ -58,7 +58,7 @@ M_BEGIN_PROTECTED_CODE
/* Define the intrusive shared pointer type and its static inline functions. /* Define the intrusive shared pointer type and its static inline functions.
USAGE: ISHARED_PTR_DEF(name, type, [, oplist]) */ USAGE: ISHARED_PTR_DEF(name, type, [, oplist]) */
#define M_ISHARED_PTR_DEF(name, ...) \ #define M_ISHARED_PTR_DEF(name, ...) \
M_ISHARED_PTR_DEF_AS(name, M_C(name,_t), __VA_ARGS__) M_ISHARED_PTR_DEF_AS(name, M_F(name,_t), __VA_ARGS__)
/* Define the intrusive shared pointer type and its static inline functions /* Define the intrusive shared pointer type and its static inline functions
@@ -90,14 +90,14 @@ M_BEGIN_PROTECTED_CODE
// Define the oplist // Define the oplist
#define M_ISHAR3D_PTR_OPLIST_P3(name, oplist) ( \ #define M_ISHAR3D_PTR_OPLIST_P3(name, oplist) ( \
INIT(M_INIT_DEFAULT), \ INIT(M_INIT_DEFAULT), \
INIT_SET(API_4(M_C(name, _init_set))), \ INIT_SET(API_4(M_F(name, _init_set))), \
SET(M_C(name, _set) M_IPTR), \ SET(M_F(name, _set) M_IPTR), \
CLEAR(M_C(name, _clear)), \ CLEAR(M_F(name, _clear)), \
RESET(M_C(name, _reset) M_IPTR), \ RESET(M_F(name, _reset) M_IPTR), \
NAME(name), \ NAME(name), \
TYPE(M_C(name, _ct)), \ TYPE(M_F(name, _ct)), \
OPLIST(oplist), \ OPLIST(oplist), \
SUBTYPE(M_C(name, _subtype_ct)) \ SUBTYPE(M_F(name, _subtype_ct)) \
,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW oplist),) \ ,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW oplist),) \
,M_IF_METHOD(REALLOC, oplist)(REALLOC(M_GET_REALLOC oplist),) \ ,M_IF_METHOD(REALLOC, oplist)(REALLOC(M_GET_REALLOC oplist),) \
,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL oplist),) \ ,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL oplist),) \
@@ -129,27 +129,27 @@ M_BEGIN_PROTECTED_CODE
typedef type *shared_t; \ typedef type *shared_t; \
\ \
/* Define internal types for oplist */ \ /* Define internal types for oplist */ \
typedef shared_t M_C(name, _ct); \ typedef shared_t M_F(name, _ct); \
typedef type M_C(name, _subtype_ct); \ typedef type M_F(name, _subtype_ct); \
/* Define the core functions */ /* Define the core functions */
#define M_ISHAR3D_PTR_DEF_CORE(name, type, oplist, shared_t) \ #define M_ISHAR3D_PTR_DEF_CORE(name, type, oplist, shared_t) \
\ \
static inline shared_t \ static inline shared_t \
M_C(name, _init)(type *ptr) \ M_F(name, _init)(type *ptr) \
{ \ { \
/* Initialize the type referenced by the pointer */ \ /* Initialize the type referenced by the pointer */ \
if (M_LIKELY (ptr != NULL)) { \ if (M_LIKELY (ptr != NULL)) { \
atomic_init(&ptr->M_C(name, _cpt), 2); \ atomic_init(&ptr->M_F(name, _cpt), 2); \
} \ } \
return ptr; \ return ptr; \
} \ } \
\ \
static inline shared_t \ static inline shared_t \
M_C(name, _init_set)(shared_t shared) \ M_F(name, _init_set)(shared_t shared) \
{ \ { \
if (M_LIKELY (shared != NULL)) { \ if (M_LIKELY (shared != NULL)) { \
int n = atomic_fetch_add(&(shared->M_C(name, _cpt)), 2); \ int n = atomic_fetch_add(&(shared->M_F(name, _cpt)), 2); \
(void) n; \ (void) n; \
} \ } \
return shared; \ return shared; \
@@ -160,38 +160,38 @@ M_BEGIN_PROTECTED_CODE
( \ ( \
/* This function is only for static object */ \ /* This function is only for static object */ \
static inline shared_t \ static inline shared_t \
M_C(name, _init_once)(type *shared) \ M_F(name, _init_once)(type *shared) \
{ \ { \
if (M_LIKELY (shared != NULL)) { \ if (M_LIKELY (shared != NULL)) { \
/* Pretty much like atomic_add, except the first one increment by 1, others by 2 */ \ /* Pretty much like atomic_add, except the first one increment by 1, others by 2 */ \
int o = atomic_load(&(shared->M_C(name, _cpt))); \ int o = atomic_load(&(shared->M_F(name, _cpt))); \
int n; \ int n; \
do { \ do { \
n = o + 1 + (o != 0); \ n = o + 1 + (o != 0); \
} while (!atomic_compare_exchange_strong(&(shared->M_C(name, _cpt)), &o, n)); \ } while (!atomic_compare_exchange_strong(&(shared->M_F(name, _cpt)), &o, n)); \
if (o == 0) { \ if (o == 0) { \
/* Partial initialization: _cpt is odd */ \ /* Partial initialization: _cpt is odd */ \
/* Call the INIT function once */ \ /* Call the INIT function once */ \
M_CALL_INIT(oplist, *shared); \ M_CALL_INIT(oplist, *shared); \
/* Finish initialization: _cpt is even */ \ /* Finish initialization: _cpt is even */ \
atomic_fetch_add(&(shared->M_C(name, _cpt)), 1); \ atomic_fetch_add(&(shared->M_F(name, _cpt)), 1); \
} else if ( (o&1) != 0) { \ } else if ( (o&1) != 0) { \
/* Not fully initialized yet: wait for initialization */ \ /* Not fully initialized yet: wait for initialization */ \
m_core_backoff_ct bkoff; \ m_core_backoff_ct bkoff; \
m_core_backoff_init(bkoff); \ m_core_backoff_init(bkoff); \
/* Wait for _cpt to be _even */ \ /* Wait for _cpt to be _even */ \
while ((atomic_load(&(shared->M_C(name, _cpt)))&1) != 0 ) { \ while ((atomic_load(&(shared->M_F(name, _cpt)))&1) != 0 ) { \
m_core_backoff_wait(bkoff); \ m_core_backoff_wait(bkoff); \
} \ } \
} \ } \
M_ASSERT( (atomic_load(&(shared->M_C(name, _cpt)))&1) == 0); \ M_ASSERT( (atomic_load(&(shared->M_F(name, _cpt)))&1) == 0); \
} \ } \
return shared; \ return shared; \
} \ } \
, \ , \
/* This function is only for dynamic object */ \ /* This function is only for dynamic object */ \
static inline shared_t \ static inline shared_t \
M_C(name, _init_new)(void) \ M_F(name, _init_new)(void) \
{ \ { \
type *ptr = M_CALL_NEW(oplist, type); \ type *ptr = M_CALL_NEW(oplist, type); \
if (M_UNLIKELY_NOMEM (ptr == NULL)) { \ if (M_UNLIKELY_NOMEM (ptr == NULL)) { \
@@ -199,17 +199,17 @@ M_BEGIN_PROTECTED_CODE
return NULL; \ return NULL; \
} \ } \
M_CALL_INIT(oplist, *ptr); \ M_CALL_INIT(oplist, *ptr); \
atomic_init (&ptr->M_C(name, _cpt), 2); \ atomic_init (&ptr->M_F(name, _cpt), 2); \
return ptr; \ return ptr; \
} \ } \
/* End of NEW */) \ /* End of NEW */) \
, /* End of INIT */) \ , /* End of INIT */) \
\ \
static inline void \ static inline void \
M_C(name, _clear)(shared_t shared) \ M_F(name, _clear)(shared_t shared) \
{ \ { \
if (shared != NULL) { \ if (shared != NULL) { \
if (atomic_fetch_sub(&(shared->M_C(name, _cpt)), 2) == 2) { \ if (atomic_fetch_sub(&(shared->M_F(name, _cpt)), 2) == 2) { \
M_CALL_CLEAR(oplist, *shared); \ M_CALL_CLEAR(oplist, *shared); \
M_IF_DISABLED_METHOD(DEL, oplist)(, M_CALL_DEL(oplist, shared);) \ M_IF_DISABLED_METHOD(DEL, oplist)(, M_CALL_DEL(oplist, shared);) \
} \ } \
@@ -217,27 +217,27 @@ M_BEGIN_PROTECTED_CODE
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _clear_ptr)(shared_t *shared) \ M_F(name, _clear_ptr)(shared_t *shared) \
{ \ { \
M_ASSERT(shared != NULL); \ M_ASSERT(shared != NULL); \
M_C(name, _clear)(*shared); \ M_F(name, _clear)(*shared); \
*shared = NULL; \ *shared = NULL; \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _reset)(shared_t *shared) \ M_F(name, _reset)(shared_t *shared) \
{ \ { \
M_C(name, _clear)(*shared); \ M_F(name, _clear)(*shared); \
*shared = NULL; \ *shared = NULL; \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _set)(shared_t *ptr, shared_t shared) \ M_F(name, _set)(shared_t *ptr, shared_t shared) \
{ \ { \
M_ASSERT (ptr != NULL); \ M_ASSERT (ptr != NULL); \
if (M_LIKELY (*ptr != shared)) { \ if (M_LIKELY (*ptr != shared)) { \
M_C(name, _clear)(*ptr); \ M_F(name, _clear)(*ptr); \
*ptr = M_C(name, _init_set)(shared); \ *ptr = M_F(name, _init_set)(shared); \
} \ } \
} \ } \
\ \
+291 -291
View File
File diff suppressed because it is too large. Load diff
+24 -24
View File
@@ -42,7 +42,7 @@
mempool_uint_clear(m); // Give back memory to system mempool_uint_clear(m); // Give back memory to system
*/ */
#define M_MEMPOOL_DEF(name, type) \ #define M_MEMPOOL_DEF(name, type) \
M_MEMPOOL_DEF_AS(name, M_C(name,_t), type) M_MEMPOOL_DEF_AS(name, M_F(name,_t), type)
/* Fast, fixed Size, thread unsafe allocator based on memory region. /* Fast, fixed Size, thread unsafe allocator based on memory region.
@@ -84,25 +84,25 @@
\ \
/* Define the type of element in a segment of the mempool. \ /* Define the type of element in a segment of the mempool. \
Either it is the basic type or a pointer to another one. */ \ Either it is the basic type or a pointer to another one. */ \
typedef union M_C(name,_union_s) { \ typedef union M_F(name,_union_s) { \
type t; \ type t; \
union M_C(name,_union_s) *next; \ union M_F(name,_union_s) *next; \
} M_C(name,_union_ct); \ } M_F(name,_union_ct); \
\ \
/* Define a segment of a mempool. \ /* Define a segment of a mempool. \
It is an array of basic type, each segment is in a linked list */ \ It is an array of basic type, each segment is in a linked list */ \
typedef struct M_C(name,_segment_s) { \ typedef struct M_F(name,_segment_s) { \
unsigned int count; \ unsigned int count; \
struct M_C(name,_segment_s) *next; \ struct M_F(name,_segment_s) *next; \
M_C(name,_union_ct) tab[M_USE_MEMPOOL_MAX_PER_SEGMENT(type)]; \ M_F(name,_union_ct) tab[M_USE_MEMPOOL_MAX_PER_SEGMENT(type)]; \
} M_C(name,_segment_ct); \ } M_F(name,_segment_ct); \
\ \
/* Define a mempool. \ /* Define a mempool. \
It is a pointer to the first free object within the segments \ It is a pointer to the first free object within the segments \
and the segments themselves */ \ and the segments themselves */ \
typedef struct M_C(name, _s) { \ typedef struct M_F(name, _s) { \
M_C(name,_union_ct) *free_list; \ M_F(name,_union_ct) *free_list; \
M_C(name,_segment_ct) *current_segment; \ M_F(name,_segment_ct) *current_segment; \
} name_t[1]; \ } name_t[1]; \
@@ -110,12 +110,12 @@
#define M_M3MPOOL_DEF_CORE(name, type, name_t) \ #define M_M3MPOOL_DEF_CORE(name, type, name_t) \
\ \
static inline void \ static inline void \
M_C(name,_init)(name_t mem) \ M_F(name,_init)(name_t mem) \
{ \ { \
mem->free_list = NULL; \ mem->free_list = NULL; \
mem->current_segment = M_MEMORY_ALLOC(M_C(name,_segment_ct)); \ mem->current_segment = M_MEMORY_ALLOC(M_F(name,_segment_ct)); \
if (M_UNLIKELY_NOMEM(mem->current_segment == NULL)) { \ if (M_UNLIKELY_NOMEM(mem->current_segment == NULL)) { \
M_MEMORY_FULL(sizeof (M_C(name,_segment_ct))); \ M_MEMORY_FULL(sizeof (M_F(name,_segment_ct))); \
return; \ return; \
} \ } \
mem->current_segment->next = NULL; \ mem->current_segment->next = NULL; \
@@ -124,12 +124,12 @@
} \ } \
\ \
static inline void \ static inline void \
M_C(name,_clear)(name_t mem) \ M_F(name,_clear)(name_t mem) \
{ \ { \
M_M3MPOOL_CONTRACT(mem, type); \ M_M3MPOOL_CONTRACT(mem, type); \
M_C(name,_segment_ct) *segment = mem->current_segment; \ M_F(name,_segment_ct) *segment = mem->current_segment; \
while (segment != NULL) { \ while (segment != NULL) { \
M_C(name,_segment_ct) *next = segment->next; \ M_F(name,_segment_ct) *next = segment->next; \
M_MEMORY_DEL (segment); \ M_MEMORY_DEL (segment); \
segment = next; \ segment = next; \
} \ } \
@@ -139,25 +139,25 @@
} \ } \
\ \
static inline type * \ static inline type * \
M_C(name,_alloc)(name_t mem) \ M_F(name,_alloc)(name_t mem) \
{ \ { \
M_M3MPOOL_CONTRACT(mem, type); \ M_M3MPOOL_CONTRACT(mem, type); \
/* Test if one object is in the free list */ \ /* Test if one object is in the free list */ \
M_C(name,_union_ct) *ret = mem->free_list; \ M_F(name,_union_ct) *ret = mem->free_list; \
if (ret != NULL) { \ if (ret != NULL) { \
/* Yes, so return it, and pop it from the free list */ \ /* Yes, so return it, and pop it from the free list */ \
mem->free_list = ret->next; \ mem->free_list = ret->next; \
return &ret->t; \ return &ret->t; \
} \ } \
/* No cheap free object exist. Test within a segment */ \ /* No cheap free object exist. Test within a segment */ \
M_C(name,_segment_ct) *segment = mem->current_segment; \ M_F(name,_segment_ct) *segment = mem->current_segment; \
M_ASSERT(segment != NULL); \ M_ASSERT(segment != NULL); \
unsigned int count = segment->count; \ unsigned int count = segment->count; \
/* If segment is full, allocate a new one from the system */ \ /* If segment is full, allocate a new one from the system */ \
if (M_UNLIKELY (count >= M_USE_MEMPOOL_MAX_PER_SEGMENT(type))) { \ if (M_UNLIKELY (count >= M_USE_MEMPOOL_MAX_PER_SEGMENT(type))) { \
M_C(name,_segment_ct) *new_segment = M_MEMORY_ALLOC (M_C(name,_segment_ct)); \ M_F(name,_segment_ct) *new_segment = M_MEMORY_ALLOC (M_F(name,_segment_ct)); \
if (M_UNLIKELY_NOMEM (new_segment == NULL)) { \ if (M_UNLIKELY_NOMEM (new_segment == NULL)) { \
M_MEMORY_FULL(sizeof (M_C(name,_segment_ct))); \ M_MEMORY_FULL(sizeof (M_F(name,_segment_ct))); \
return NULL; \ return NULL; \
} \ } \
new_segment->next = segment; \ new_segment->next = segment; \
@@ -174,12 +174,12 @@
} \ } \
\ \
static inline void \ static inline void \
M_C(name,_free)(name_t mem, type *ptr) \ M_F(name,_free)(name_t mem, type *ptr) \
{ \ { \
M_M3MPOOL_CONTRACT(mem, type); \ M_M3MPOOL_CONTRACT(mem, type); \
/* NOTE: Unsafe cast: suppose that the given pointer \ /* NOTE: Unsafe cast: suppose that the given pointer \
was allocated by the previous alloc function. */ \ was allocated by the previous alloc function. */ \
M_C(name,_union_ct) *ret = (M_C(name,_union_ct) *)(uintptr_t)ptr; \ M_F(name,_union_ct) *ret = (M_F(name,_union_ct) *)(uintptr_t)ptr; \
/* Add the object back in the free list */ \ /* Add the object back in the free list */ \
ret->next = mem->free_list; \ ret->next = mem->free_list; \
mem->free_list = ret; \ mem->free_list = ret; \
+143 -143
View File
@@ -33,7 +33,7 @@
/* Define a prioqueue of a given type and its associated functions. /* Define a prioqueue of a given type and its associated functions.
USAGE: PRIOQUEUE_DEF(name, type [, oplist_of_the_type]) */ USAGE: PRIOQUEUE_DEF(name, type [, oplist_of_the_type]) */
#define M_PRIOQUEUE_DEF(name, ...) \ #define M_PRIOQUEUE_DEF(name, ...) \
M_PRIOQUEUE_DEF_AS(name, M_C(name,_t), M_C(name,_it_t), __VA_ARGS__) M_PRIOQUEUE_DEF_AS(name, M_F(name,_t), M_F(name,_it_t), __VA_ARGS__)
/* Define a prioqueue of a given type and its associated functions. /* Define a prioqueue of a given type and its associated functions.
@@ -73,38 +73,38 @@
/* Define oplist of a priority queue */ /* Define oplist of a priority queue */
#define M_PR1OQUEUE_OPLIST_P3(name, oplist) \ #define M_PR1OQUEUE_OPLIST_P3(name, oplist) \
(INIT(M_C(name, _init)) \ (INIT(M_F(name, _init)) \
,INIT_SET(M_C(name, _init_set)) \ ,INIT_SET(M_F(name, _init_set)) \
,INIT_WITH(API_1(M_INIT_VAI)) \ ,INIT_WITH(API_1(M_INIT_VAI)) \
,SET(M_C(name, _set)) \ ,SET(M_F(name, _set)) \
,CLEAR(M_C(name, _clear)) \ ,CLEAR(M_F(name, _clear)) \
,INIT_MOVE(M_C(name, _init_move)) \ ,INIT_MOVE(M_F(name, _init_move)) \
,MOVE(M_C(name, _move)) \ ,MOVE(M_F(name, _move)) \
,SWAP(M_C(name, _swap)) \ ,SWAP(M_F(name, _swap)) \
,NAME(name) \ ,NAME(name) \
,TYPE(M_C(name,_ct)) \ ,TYPE(M_F(name,_ct)) \
,SUBTYPE(M_C(name, _subtype_ct)) \ ,SUBTYPE(M_F(name, _subtype_ct)) \
,RESET(M_C(name,_reset)) \ ,RESET(M_F(name,_reset)) \
,PUSH(M_C(name,_push)) \ ,PUSH(M_F(name,_push)) \
,POP(M_C(name,_pop)) \ ,POP(M_F(name,_pop)) \
,OPLIST(oplist) \ ,OPLIST(oplist) \
,EMPTY_P(M_C(name, _empty_p)) \ ,EMPTY_P(M_F(name, _empty_p)) \
,GET_SIZE(M_C(name, _size)) \ ,GET_SIZE(M_F(name, _size)) \
,IT_TYPE(M_C(name, _it_ct)) \ ,IT_TYPE(M_F(name, _it_ct)) \
,IT_FIRST(M_C(name,_it)) \ ,IT_FIRST(M_F(name,_it)) \
,IT_END(M_C(name,_it_end)) \ ,IT_END(M_F(name,_it_end)) \
,IT_SET(M_C(name,_it_set)) \ ,IT_SET(M_F(name,_it_set)) \
,IT_END_P(M_C(name,_end_p)) \ ,IT_END_P(M_F(name,_end_p)) \
,IT_EQUAL_P(M_C(name,_it_equal_p)) \ ,IT_EQUAL_P(M_F(name,_it_equal_p)) \
,IT_LAST_P(M_C(name,_last_p)) \ ,IT_LAST_P(M_F(name,_last_p)) \
,IT_NEXT(M_C(name,_next)) \ ,IT_NEXT(M_F(name,_next)) \
,IT_CREF(M_C(name,_cref)) \ ,IT_CREF(M_F(name,_cref)) \
,M_IF_METHOD(GET_STR, oplist)(GET_STR(M_C(name, _get_str)),) \ ,M_IF_METHOD(GET_STR, oplist)(GET_STR(M_F(name, _get_str)),) \
,M_IF_METHOD(PARSE_STR, oplist)(PARSE_STR(M_C(name, _parse_str)),) \ ,M_IF_METHOD(PARSE_STR, oplist)(PARSE_STR(M_F(name, _parse_str)),) \
,M_IF_METHOD(OUT_STR, oplist)(OUT_STR(M_C(name, _out_str)),) \ ,M_IF_METHOD(OUT_STR, oplist)(OUT_STR(M_F(name, _out_str)),) \
,M_IF_METHOD(IN_STR, oplist)(IN_STR(M_C(name, _in_str)),) \ ,M_IF_METHOD(IN_STR, oplist)(IN_STR(M_F(name, _in_str)),) \
,M_IF_METHOD(OUT_SERIAL, oplist)(OUT_SERIAL(M_C(name, _out_serial)),) \ ,M_IF_METHOD(OUT_SERIAL, oplist)(OUT_SERIAL(M_F(name, _out_serial)),) \
,M_IF_METHOD(IN_SERIAL, oplist)(IN_SERIAL(M_C(name, _in_serial)),) \ ,M_IF_METHOD(IN_SERIAL, oplist)(IN_SERIAL(M_F(name, _in_serial)),) \
) )
@@ -131,171 +131,171 @@
*/ */
#define M_PR1OQUEUE_DEF_P3(name, type, oplist, prioqueue_t, it_t) \ #define M_PR1OQUEUE_DEF_P3(name, type, oplist, prioqueue_t, it_t) \
/* Definition of the internal array used to construct the priority queue */ \ /* Definition of the internal array used to construct the priority queue */ \
ARRAY_DEF(M_C(name, _array), type, oplist) \ ARRAY_DEF(M_F(name, _array), type, oplist) \
M_PR1OQUEUE_DEF_TYPE(name, type, oplist, prioqueue_t, it_t) \ M_PR1OQUEUE_DEF_TYPE(name, type, oplist, prioqueue_t, it_t) \
M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \ M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \
M_PR1OQUEUE_DEF_CORE(name, type, oplist, prioqueue_t, it_t) \ M_PR1OQUEUE_DEF_CORE(name, type, oplist, prioqueue_t, it_t) \
M_PR1OQUEUE_DEF_IT(name, type, oplist, prioqueue_t, it_t) \ M_PR1OQUEUE_DEF_IT(name, type, oplist, prioqueue_t, it_t) \
M_PR1OQUEUE_DEF_IO(name, type, oplist, prioqueue_t, it_t) \ M_PR1OQUEUE_DEF_IO(name, type, oplist, prioqueue_t, it_t) \
M_EMPLACE_QUEUE_DEF(name, prioqueue_t, M_C(name, _emplace), oplist, M_EMPLACE_QUEUE_GENE) M_EMPLACE_QUEUE_DEF(name, prioqueue_t, M_F(name, _emplace), oplist, M_EMPLACE_QUEUE_GENE)
/* Define the types */ /* Define the types */
#define M_PR1OQUEUE_DEF_TYPE(name, type, oplist, prioqueue_t, it_t) \ #define M_PR1OQUEUE_DEF_TYPE(name, type, oplist, prioqueue_t, it_t) \
\ \
/* Define the priority queue over the defined array */ \ /* Define the priority queue over the defined array */ \
typedef struct M_C(name, _s) { \ typedef struct M_F(name, _s) { \
M_C(name, _array_t) array; \ M_F(name, _array_t) array; \
} prioqueue_t[1]; \ } prioqueue_t[1]; \
/* Define the pointer references to the priority queue */ \ /* Define the pointer references to the priority queue */ \
typedef struct M_C(name, _s) *M_C(name, _ptr); \ typedef struct M_F(name, _s) *M_F(name, _ptr); \
typedef const struct M_C(name, _s) *M_C(name, _srcptr); \ typedef const struct M_F(name, _s) *M_F(name, _srcptr); \
\ \
/* The iterator is the same one as the one of the internal array */ \ /* The iterator is the same one as the one of the internal array */ \
typedef M_C(name, _array_it_t) it_t; \ typedef M_F(name, _array_it_t) it_t; \
\ \
/* Definition of the internal types used by the oplist */ \ /* Definition of the internal types used by the oplist */ \
typedef prioqueue_t M_C(name, _ct); \ typedef prioqueue_t M_F(name, _ct); \
typedef type M_C(name, _subtype_ct); \ typedef type M_F(name, _subtype_ct); \
typedef it_t M_C(name, _it_ct); \ typedef it_t M_F(name, _it_ct); \
/* Define the core functions */ /* Define the core functions */
#define M_PR1OQUEUE_DEF_CORE(name, type, oplist, prioqueue_t, it_t) \ #define M_PR1OQUEUE_DEF_CORE(name, type, oplist, prioqueue_t, it_t) \
\ \
static inline void \ static inline void \
M_C(name, _init)(prioqueue_t p) \ M_F(name, _init)(prioqueue_t p) \
{ \ { \
M_C(name, _array_init)(p->array); \ M_F(name, _array_init)(p->array); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _init_set)(prioqueue_t p, prioqueue_t const o) \ M_F(name, _init_set)(prioqueue_t p, prioqueue_t const o) \
{ \ { \
M_C(name, _array_init_set)(p->array, o->array); \ M_F(name, _array_init_set)(p->array, o->array); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _set)(prioqueue_t p, prioqueue_t const o) \ M_F(name, _set)(prioqueue_t p, prioqueue_t const o) \
{ \ { \
M_C(name, _array_set)(p->array, o->array); \ M_F(name, _array_set)(p->array, o->array); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _clear)(prioqueue_t p) \ M_F(name, _clear)(prioqueue_t p) \
{ \ { \
M_C(name, _array_clear)(p->array); \ M_F(name, _array_clear)(p->array); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _init_move)(prioqueue_t p, prioqueue_t o) \ M_F(name, _init_move)(prioqueue_t p, prioqueue_t o) \
{ \ { \
M_C(name, _array_init_move)(p->array, o->array); \ M_F(name, _array_init_move)(p->array, o->array); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _move)(prioqueue_t p, prioqueue_t o) \ M_F(name, _move)(prioqueue_t p, prioqueue_t o) \
{ \ { \
M_C(name, _array_move)(p->array, o->array); \ M_F(name, _array_move)(p->array, o->array); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _swap)(prioqueue_t p, prioqueue_t o) \ M_F(name, _swap)(prioqueue_t p, prioqueue_t o) \
{ \ { \
M_C(name, _array_swap)(p->array, o->array); \ M_F(name, _array_swap)(p->array, o->array); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _reset)(prioqueue_t p) \ M_F(name, _reset)(prioqueue_t p) \
{ \ { \
M_C(name, _array_reset)(p->array); \ M_F(name, _array_reset)(p->array); \
} \ } \
\ \
static inline size_t \ static inline size_t \
M_C(name, _i_parent)(size_t i) \ M_F(name, _i_parent)(size_t i) \
{ \ { \
M_ASSERT (i > 0); \ M_ASSERT (i > 0); \
return (i - 1) / 2; \ return (i - 1) / 2; \
} \ } \
\ \
static inline size_t \ static inline size_t \
M_C(name, _i_lchild)(size_t i) \ M_F(name, _i_lchild)(size_t i) \
{ \ { \
M_ASSERT(i <= ((SIZE_MAX)-2)/2); \ M_ASSERT(i <= ((SIZE_MAX)-2)/2); \
return 2*i + 1; \ return 2*i + 1; \
} \ } \
\ \
static inline size_t \ static inline size_t \
M_C(name, _i_rchild)(size_t i) \ M_F(name, _i_rchild)(size_t i) \
{ \ { \
M_ASSERT(i <= ((SIZE_MAX)-2)/2); \ M_ASSERT(i <= ((SIZE_MAX)-2)/2); \
return 2*i + 2; \ return 2*i + 2; \
} \ } \
\ \
static inline int \ static inline int \
M_C(name, _i_cmp)(const prioqueue_t p, size_t i, size_t j) \ M_F(name, _i_cmp)(const prioqueue_t p, size_t i, size_t j) \
{ \ { \
return M_CALL_CMP(oplist, *M_C(name, _array_cget)(p->array, i), \ return M_CALL_CMP(oplist, *M_F(name, _array_cget)(p->array, i), \
*M_C(name, _array_cget)(p->array, j)); \ *M_F(name, _array_cget)(p->array, j)); \
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _empty_p)(prioqueue_t const p) \ M_F(name, _empty_p)(prioqueue_t const p) \
{ \ { \
return M_C(name, _array_empty_p)(p->array); \ return M_F(name, _array_empty_p)(p->array); \
} \ } \
\ \
static inline size_t \ static inline size_t \
M_C(name, _size)(prioqueue_t const p) \ M_F(name, _size)(prioqueue_t const p) \
{ \ { \
return M_C(name, _array_size)(p->array); \ return M_F(name, _array_size)(p->array); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _push)(prioqueue_t p, type const x) \ M_F(name, _push)(prioqueue_t p, type const x) \
{ \ { \
/* Push back the new element at the end of the array */ \ /* Push back the new element at the end of the array */ \
M_C(name, _array_push_back)(p->array, x); \ M_F(name, _array_push_back)(p->array, x); \
\ \
/* Reorder the array by swapping with its parent \ /* Reorder the array by swapping with its parent \
* until it reaches the right position */ \ * until it reaches the right position */ \
size_t i = M_C(name, _array_size)(p->array)-1; \ size_t i = M_F(name, _array_size)(p->array)-1; \
while (i > 0) { \ while (i > 0) { \
size_t j = M_C(name, _i_parent)(i); \ size_t j = M_F(name, _i_parent)(i); \
if (M_C(name, _i_cmp)(p, j, i) <= 0) \ if (M_F(name, _i_cmp)(p, j, i) <= 0) \
break; \ break; \
M_C(name, _array_swap_at) (p->array, i, j); \ M_F(name, _array_swap_at) (p->array, i, j); \
i = j; \ i = j; \
} \ } \
} \ } \
\ \
static inline type const * \ static inline type const * \
M_C(name, _front)(prioqueue_t const p) \ M_F(name, _front)(prioqueue_t const p) \
{ \ { \
return M_C(name, _array_cget)(p->array, 0); \ return M_F(name, _array_cget)(p->array, 0); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _pop)(type *x, prioqueue_t p) \ M_F(name, _pop)(type *x, prioqueue_t p) \
{ \ { \
/* Swap the front element with the last element */ \ /* Swap the front element with the last element */ \
size_t size = M_C(name, _array_size)(p->array)-1; \ size_t size = M_F(name, _array_size)(p->array)-1; \
M_C(name, _array_swap_at) (p->array, 0, size); \ M_F(name, _array_swap_at) (p->array, 0, size); \
/* Swap the new last element */ \ /* Swap the new last element */ \
M_C(name, _array_pop_back)(x, p->array); \ M_F(name, _array_pop_back)(x, p->array); \
\ \
/* Reorder the heap */ \ /* Reorder the heap */ \
size_t i = 0; \ size_t i = 0; \
while (true) { \ while (true) { \
size_t child = M_C(name, _i_lchild)(i); \ size_t child = M_F(name, _i_lchild)(i); \
if (child >= size) \ if (child >= size) \
break; \ break; \
size_t otherChild = M_C(name, _i_rchild)(i); \ size_t otherChild = M_F(name, _i_rchild)(i); \
if (otherChild < size \ if (otherChild < size \
&& M_C(name, _i_cmp)(p, otherChild, child) < 0 ) { \ && M_F(name, _i_cmp)(p, otherChild, child) < 0 ) { \
child = otherChild; \ child = otherChild; \
} \ } \
if (M_C(name, _i_cmp)(p, i, child) <= 0) \ if (M_F(name, _i_cmp)(p, i, child) <= 0) \
break; \ break; \
M_C(name, _array_swap_at) (p->array, i, child); \ M_F(name, _array_swap_at) (p->array, i, child); \
i = child; \ i = child; \
} \ } \
} \ } \
@@ -304,86 +304,86 @@
( \ ( \
/* EQUAL & CMP may be uncorrelated */ \ /* EQUAL & CMP may be uncorrelated */ \
static inline bool \ static inline bool \
M_C(name, _equal_p)(prioqueue_t const p, prioqueue_t const q) \ M_F(name, _equal_p)(prioqueue_t const p, prioqueue_t const q) \
{ \ { \
return M_C(name, _array_equal_p)(p->array, q->array); \ return M_F(name, _array_equal_p)(p->array, q->array); \
} \ } \
\ \
static inline size_t \ static inline size_t \
M_C(name, _i_find)(prioqueue_t p, type const x) \ M_F(name, _i_find)(prioqueue_t p, type const x) \
{ \ { \
size_t size = M_C(name, _array_size)(p->array); \ size_t size = M_F(name, _array_size)(p->array); \
size_t i = 0; \ size_t i = 0; \
for(i = 0; i < size; i++) { \ for(i = 0; i < size; i++) { \
/* FIXME: Can we use CMP and the partial order to go faster? */ \ /* FIXME: Can we use CMP and the partial order to go faster? */ \
if (M_CALL_EQUAL(oplist, *M_C(name, _array_cget)(p->array, i), x)) \ if (M_CALL_EQUAL(oplist, *M_F(name, _array_cget)(p->array, i), x)) \
break; \ break; \
} \ } \
return i; \ return i; \
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _erase)(prioqueue_t p, type const x) \ M_F(name, _erase)(prioqueue_t p, type const x) \
{ \ { \
/* First pass: search for an item EQUAL to x */ \ /* First pass: search for an item EQUAL to x */ \
size_t size = M_C(name, _array_size)(p->array); \ size_t size = M_F(name, _array_size)(p->array); \
size_t i = M_C(name, _i_find)(p, x); \ size_t i = M_F(name, _i_find)(p, x); \
/* If x is not found, then stop */ \ /* If x is not found, then stop */ \
if (i >= size) \ if (i >= size) \
return false; \ return false; \
/* Swap the found item and the last element */ \ /* Swap the found item and the last element */ \
size--; \ size--; \
M_C(name, _array_swap_at) (p->array, i, size); \ M_F(name, _array_swap_at) (p->array, i, size); \
M_C(name, _array_pop_back)(NULL, p->array); \ M_F(name, _array_pop_back)(NULL, p->array); \
/* Move back the last swapped element to its right position in the heap */ \ /* Move back the last swapped element to its right position in the heap */ \
while (true) { \ while (true) { \
size_t child = M_C(name, _i_lchild)(i); \ size_t child = M_F(name, _i_lchild)(i); \
if (child >= size) break; \ if (child >= size) break; \
size_t otherChild = M_C(name, _i_rchild)(i); \ size_t otherChild = M_F(name, _i_rchild)(i); \
if (otherChild < size \ if (otherChild < size \
&& M_C(name, _i_cmp)(p, otherChild, child) < 0 ) { \ && M_F(name, _i_cmp)(p, otherChild, child) < 0 ) { \
child = otherChild; \ child = otherChild; \
} \ } \
if (M_C(name, _i_cmp)(p, i, child) <= 0) break; \ if (M_F(name, _i_cmp)(p, i, child) <= 0) break; \
M_C(name, _array_swap_at) (p->array, i, child); \ M_F(name, _array_swap_at) (p->array, i, child); \
i = child; \ i = child; \
} \ } \
return true; \ return true; \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _update)(prioqueue_t p, type const xold, type const xnew) \ M_F(name, _update)(prioqueue_t p, type const xold, type const xnew) \
{ \ { \
/* NOTE: xold can be the same pointer than xnew */ \ /* NOTE: xold can be the same pointer than xnew */ \
/* First pass: search for an item EQUAL to x */ \ /* First pass: search for an item EQUAL to x */ \
size_t size = M_C(name, _array_size)(p->array); \ size_t size = M_F(name, _array_size)(p->array); \
size_t i = M_C(name, _i_find)(p, xold); \ size_t i = M_F(name, _i_find)(p, xold); \
/* We shall have found the item */ \ /* We shall have found the item */ \
M_ASSERT (i < size); \ M_ASSERT (i < size); \
/* Test if the position of the old data is further or nearer than the new */ \ /* Test if the position of the old data is further or nearer than the new */ \
int cmp = M_CALL_CMP(oplist, *M_C(name, _array_cget)(p->array, i), xnew); \ int cmp = M_CALL_CMP(oplist, *M_F(name, _array_cget)(p->array, i), xnew); \
/* Set the found item to the new element */ \ /* Set the found item to the new element */ \
M_C(name, _array_set_at) (p->array, i, xnew); \ M_F(name, _array_set_at) (p->array, i, xnew); \
if (cmp < 0) { \ if (cmp < 0) { \
/* Move back the updated element to its new position, further in the heap */ \ /* Move back the updated element to its new position, further in the heap */ \
while (true) { \ while (true) { \
size_t child = M_C(name, _i_lchild)(i); \ size_t child = M_F(name, _i_lchild)(i); \
if (child >= size) break; \ if (child >= size) break; \
size_t otherChild = M_C(name, _i_rchild)(i); \ size_t otherChild = M_F(name, _i_rchild)(i); \
if (otherChild < size \ if (otherChild < size \
&& M_C(name, _i_cmp)(p, otherChild, child) < 0 ) { \ && M_F(name, _i_cmp)(p, otherChild, child) < 0 ) { \
child = otherChild; \ child = otherChild; \
} \ } \
if (M_C(name, _i_cmp)(p, i, child) <= 0) break; \ if (M_F(name, _i_cmp)(p, i, child) <= 0) break; \
M_C(name, _array_swap_at) (p->array, i, child); \ M_F(name, _array_swap_at) (p->array, i, child); \
i = child; \ i = child; \
} \ } \
} else { \ } else { \
/* Move back the updated element to its new position, nearest in the heap */ \ /* Move back the updated element to its new position, nearest in the heap */ \
while (i > 0) { \ while (i > 0) { \
size_t parent = M_C(name, _i_parent)(i); \ size_t parent = M_F(name, _i_parent)(i); \
if (M_C(name, _i_cmp)(p, parent, i) <= 0) break; \ if (M_F(name, _i_cmp)(p, parent, i) <= 0) break; \
M_C(name, _array_swap_at) (p->array, i, parent); \ M_F(name, _array_swap_at) (p->array, i, parent); \
i = parent; \ i = parent; \
} \ } \
} \ } \
@@ -395,113 +395,113 @@
\ \
/* Define iterators over the array iterator */ \ /* Define iterators over the array iterator */ \
static inline void \ static inline void \
M_C(name, _it)(it_t it, prioqueue_t const v) \ M_F(name, _it)(it_t it, prioqueue_t const v) \
{ \ { \
M_C(name, _array_it)(it, v->array); \ M_F(name, _array_it)(it, v->array); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _it_last)(it_t it, prioqueue_t const v) \ M_F(name, _it_last)(it_t it, prioqueue_t const v) \
{ \ { \
M_C(name, _array_it_last)(it, v->array); \ M_F(name, _array_it_last)(it, v->array); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _it_end)(it_t it, prioqueue_t const v) \ M_F(name, _it_end)(it_t it, prioqueue_t const v) \
{ \ { \
M_C(name, _array_it_end)(it, v->array); \ M_F(name, _array_it_end)(it, v->array); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _it_set)(it_t it, const it_t org) \ M_F(name, _it_set)(it_t it, const it_t org) \
{ \ { \
M_C(name, _array_it_set)(it, org); \ M_F(name, _array_it_set)(it, org); \
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _end_p)(const it_t it) \ M_F(name, _end_p)(const it_t it) \
{ \ { \
return M_C(name, _array_end_p)(it); \ return M_F(name, _array_end_p)(it); \
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _last_p)(const it_t it) \ M_F(name, _last_p)(const it_t it) \
{ \ { \
return M_C(name, _array_last_p)(it); \ return M_F(name, _array_last_p)(it); \
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _it_equal_p)(const it_t it1, \ M_F(name, _it_equal_p)(const it_t it1, \
const it_t it2) \ const it_t it2) \
{ \ { \
return M_C(name, _array_it_equal_p)(it1, it2); \ return M_F(name, _array_it_equal_p)(it1, it2); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _next)(it_t it) \ M_F(name, _next)(it_t it) \
{ \ { \
M_C(name, _array_next)(it); \ M_F(name, _array_next)(it); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _previous)(it_t it) \ M_F(name, _previous)(it_t it) \
{ \ { \
M_C(name, _array_previous)(it); \ M_F(name, _array_previous)(it); \
} \ } \
\ \
static inline type const * \ static inline type const * \
M_C(name, _cref)(const it_t it) \ M_F(name, _cref)(const it_t it) \
{ \ { \
return M_C(name, _array_cref)(it); \ return M_F(name, _array_cref)(it); \
} \ } \
/* Define the IO functions */ /* Define the IO functions */
#define M_PR1OQUEUE_DEF_IO(name, type, oplist, prioqueue_t, it_t) \ #define M_PR1OQUEUE_DEF_IO(name, type, oplist, prioqueue_t, it_t) \
M_IF_METHOD(OUT_STR, oplist)( \ M_IF_METHOD(OUT_STR, oplist)( \
static inline void \ static inline void \
M_C(name, _out_str)(FILE *file, const prioqueue_t p) \ M_F(name, _out_str)(FILE *file, const prioqueue_t p) \
{ \ { \
M_C(name, _array_out_str)(file, p->array); \ M_F(name, _array_out_str)(file, p->array); \
} \ } \
,/* No OUT_STR */) \ ,/* No OUT_STR */) \
\ \
M_IF_METHOD(IN_STR, oplist)( \ M_IF_METHOD(IN_STR, oplist)( \
static inline bool \ static inline bool \
M_C(name, _in_str)(prioqueue_t p, FILE *file) \ M_F(name, _in_str)(prioqueue_t p, FILE *file) \
{ \ { \
return M_C(name, _array_in_str)(p->array, file); \ return M_F(name, _array_in_str)(p->array, file); \
} \ } \
,/* No IN_STR */) \ ,/* No IN_STR */) \
\ \
M_IF_METHOD(GET_STR, oplist)( \ M_IF_METHOD(GET_STR, oplist)( \
static inline void \ static inline void \
M_C(name, _get_str)(string_t str, const prioqueue_t p, bool append) \ M_F(name, _get_str)(string_t str, const prioqueue_t p, bool append) \
{ \ { \
M_C(name, _array_get_str)(str, p->array, append); \ M_F(name, _array_get_str)(str, p->array, append); \
} \ } \
,/* No GET_STR */) \ ,/* No GET_STR */) \
\ \
M_IF_METHOD(PARSE_STR, oplist)( \ M_IF_METHOD(PARSE_STR, oplist)( \
static inline bool \ static inline bool \
M_C(name, _parse_str)(prioqueue_t p, const char str[], const char **endp) \ M_F(name, _parse_str)(prioqueue_t p, const char str[], const char **endp) \
{ \ { \
return M_C(name, _array_parse_str)(p->array, str, endp); \ return M_F(name, _array_parse_str)(p->array, str, endp); \
} \ } \
,/* No PARSE_STR */) \ ,/* No PARSE_STR */) \
\ \
M_IF_METHOD(OUT_SERIAL, oplist)( \ M_IF_METHOD(OUT_SERIAL, oplist)( \
static inline m_serial_return_code_t \ static inline m_serial_return_code_t \
M_C(name, _out_serial)(m_serial_write_t f, const prioqueue_t p) \ M_F(name, _out_serial)(m_serial_write_t f, const prioqueue_t p) \
{ \ { \
return M_C(name, _array_out_serial)(f, p->array); \ return M_F(name, _array_out_serial)(f, p->array); \
} \ } \
,/* No OUT_SERIAL */) \ ,/* No OUT_SERIAL */) \
\ \
M_IF_METHOD2(IN_SERIAL, INIT, oplist)( \ M_IF_METHOD2(IN_SERIAL, INIT, oplist)( \
static inline m_serial_return_code_t \ static inline m_serial_return_code_t \
M_C(name, _in_serial)(prioqueue_t p, m_serial_read_t f) \ M_F(name, _in_serial)(prioqueue_t p, m_serial_read_t f) \
{ \ { \
return M_C(name, _array_in_serial)(p->array, f); \ return M_F(name, _array_in_serial)(p->array, f); \
} \ } \
,/* No in_SERIAL */) \ ,/* No in_SERIAL */) \
+140 -140
View File
@@ -30,7 +30,7 @@
/* Define a Red/Black binary tree of a given type. /* Define a Red/Black binary tree of a given type.
USAGE: RBTREE_DEF(name, type [, oplist_of_the_type]) */ USAGE: RBTREE_DEF(name, type [, oplist_of_the_type]) */
#define M_RBTREE_DEF(name, ...) \ #define M_RBTREE_DEF(name, ...) \
M_RBTREE_DEF_AS(name, M_C(name,_t), M_C(name,_it_t), __VA_ARGS__) M_RBTREE_DEF_AS(name, M_F(name,_t), M_F(name,_it_t), __VA_ARGS__)
/* Define a Red/Black binary tree of a given type /* Define a Red/Black binary tree of a given type
@@ -39,8 +39,8 @@
#define M_RBTREE_DEF_AS(name, name_t, it_t, ...) \ #define M_RBTREE_DEF_AS(name, name_t, it_t, ...) \
M_BEGIN_PROTECTED_CODE \ M_BEGIN_PROTECTED_CODE \
M_RBTR33_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ M_RBTR33_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \
((name, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), name_t, M_C(name, _node_ct), it_t ), \ ((name, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), name_t, M_F(name, _node_ct), it_t ), \
(name, __VA_ARGS__, name_t, M_C(name, _node_ct), it_t ))) \ (name, __VA_ARGS__, name_t, M_F(name, _node_ct), it_t ))) \
M_END_PROTECTED_CODE M_END_PROTECTED_CODE
@@ -72,43 +72,43 @@
NOTE: IT_REF is not exported so that the container appears as not modifiable NOTE: IT_REF is not exported so that the container appears as not modifiable
by algorithm.*/ by algorithm.*/
#define M_RBTR33_OPLIST_P3(name, oplist) \ #define M_RBTR33_OPLIST_P3(name, oplist) \
(INIT(M_C(name, _init)), \ (INIT(M_F(name, _init)), \
INIT_SET(M_C(name, _init_set)), \ INIT_SET(M_F(name, _init_set)), \
INIT_WITH(API_1(M_INIT_EMPLACE_VAI)), \ INIT_WITH(API_1(M_INIT_EMPLACE_VAI)), \
SET(M_C(name, _set)), \ SET(M_F(name, _set)), \
CLEAR(M_C(name, _clear)), \ CLEAR(M_F(name, _clear)), \
INIT_MOVE(M_C(name, _init_move)), \ INIT_MOVE(M_F(name, _init_move)), \
MOVE(M_C(name, _move)), \ MOVE(M_F(name, _move)), \
SWAP(M_C(name, _swap)), \ SWAP(M_F(name, _swap)), \
NAME(name), \ NAME(name), \
TYPE(M_C(name,_ct)), \ TYPE(M_F(name,_ct)), \
SUBTYPE(M_C(name, _subtype_ct)), \ SUBTYPE(M_F(name, _subtype_ct)), \
EMPTY_P(M_C(name,_empty_p)), \ EMPTY_P(M_F(name,_empty_p)), \
GET_SIZE(M_C(name, _size)), \ GET_SIZE(M_F(name, _size)), \
IT_TYPE(M_C(name, _it_ct)), \ IT_TYPE(M_F(name, _it_ct)), \
IT_FIRST(M_C(name,_it)), \ IT_FIRST(M_F(name,_it)), \
IT_SET(M_C(name,_it_set)), \ IT_SET(M_F(name,_it_set)), \
IT_LAST(M_C(name,_it_last)), \ IT_LAST(M_F(name,_it_last)), \
IT_END(M_C(name,_it_end)), \ IT_END(M_F(name,_it_end)), \
IT_END_P(M_C(name,_end_p)), \ IT_END_P(M_F(name,_end_p)), \
IT_LAST_P(M_C(name,_last_p)), \ IT_LAST_P(M_F(name,_last_p)), \
IT_EQUAL_P(M_C(name,_it_equal_p)), \ IT_EQUAL_P(M_F(name,_it_equal_p)), \
IT_NEXT(M_C(name,_next)), \ IT_NEXT(M_F(name,_next)), \
IT_PREVIOUS(M_C(name,_previous)), \ IT_PREVIOUS(M_F(name,_previous)), \
IT_CREF(M_C(name,_cref)), \ IT_CREF(M_F(name,_cref)), \
IT_REMOVE(M_C(name,_remove)), \ IT_REMOVE(M_F(name,_remove)), \
RESET(M_C(name,_reset)), \ RESET(M_F(name,_reset)), \
PUSH(M_C(name,_push)), \ PUSH(M_F(name,_push)), \
GET_MIN(M_C(name,_min)), \ GET_MIN(M_F(name,_min)), \
GET_MAX(M_C(name,_max)), \ GET_MAX(M_F(name,_max)), \
M_IF_METHOD(GET_STR, oplist)(GET_STR(M_C(name, _get_str)),), \ M_IF_METHOD(GET_STR, oplist)(GET_STR(M_F(name, _get_str)),), \
M_IF_METHOD(PARSE_STR, oplist)(PARSE_STR(M_C(name, _parse_str)),), \ M_IF_METHOD(PARSE_STR, oplist)(PARSE_STR(M_F(name, _parse_str)),), \
M_IF_METHOD(OUT_STR, oplist)(OUT_STR(M_C(name, _out_str)),), \ M_IF_METHOD(OUT_STR, oplist)(OUT_STR(M_F(name, _out_str)),), \
M_IF_METHOD(IN_STR, oplist)(IN_STR(M_C(name, _in_str)),), \ M_IF_METHOD(IN_STR, oplist)(IN_STR(M_F(name, _in_str)),), \
M_IF_METHOD(OUT_SERIAL, oplist)(OUT_SERIAL(M_C(name, _out_serial)),), \ M_IF_METHOD(OUT_SERIAL, oplist)(OUT_SERIAL(M_F(name, _out_serial)),), \
M_IF_METHOD(IN_SERIAL, oplist)(IN_SERIAL(M_C(name, _in_serial)),), \ M_IF_METHOD(IN_SERIAL, oplist)(IN_SERIAL(M_F(name, _in_serial)),), \
M_IF_METHOD(EQUAL, oplist)(EQUAL(M_C(name, _equal_p)),), \ M_IF_METHOD(EQUAL, oplist)(EQUAL(M_F(name, _equal_p)),), \
M_IF_METHOD(HASH, oplist)(HASH(M_C(name, _hash)),) \ M_IF_METHOD(HASH, oplist)(HASH(M_F(name, _hash)),) \
,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW oplist),) \ ,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW oplist),) \
,M_IF_METHOD(REALLOC, oplist)(REALLOC(M_GET_REALLOC oplist),) \ ,M_IF_METHOD(REALLOC, oplist)(REALLOC(M_GET_REALLOC oplist),) \
,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL oplist),) \ ,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL oplist),) \
@@ -183,7 +183,7 @@ typedef enum {
M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \ M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \
M_RBTR33_DEF_CORE(name, type, oplist, tree_t, node_t, it_t) \ M_RBTR33_DEF_CORE(name, type, oplist, tree_t, node_t, it_t) \
M_RBTR33_DEF_IO(name, type, oplist, tree_t, node_t, it_t) \ M_RBTR33_DEF_IO(name, type, oplist, tree_t, node_t, it_t) \
M_EMPLACE_QUEUE_DEF(name, tree_t, M_C(name, _emplace), oplist, M_EMPLACE_QUEUE_GENE) M_EMPLACE_QUEUE_DEF(name, tree_t, M_F(name, _emplace), oplist, M_EMPLACE_QUEUE_GENE)
/* Define the types associated to a R/B Tree */ /* Define the types associated to a R/B Tree */
#define M_RBTR33_DEF_TYPE(name, type, oplist, tree_t, node_t, it_t) \ #define M_RBTR33_DEF_TYPE(name, type, oplist, tree_t, node_t, it_t) \
@@ -191,48 +191,48 @@ typedef enum {
/* Node of Red/Black tree. \ /* Node of Red/Black tree. \
Each node has up to two child, a color (Red or black) \ Each node has up to two child, a color (Red or black) \
and the data stored in it */ \ and the data stored in it */ \
typedef struct M_C(name, _node_s) { \ typedef struct M_F(name, _node_s) { \
struct M_C(name, _node_s) *child[2]; \ struct M_F(name, _node_s) *child[2]; \
type data; \ type data; \
m_rbtr33_color_e color; \ m_rbtr33_color_e color; \
} node_t; \ } node_t; \
\ \
/* Define the Red/Black tree */ \ /* Define the Red/Black tree */ \
typedef struct M_C(name, _s) { \ typedef struct M_F(name, _s) { \
size_t size; /* Number of elements in the tree */ \ size_t size; /* Number of elements in the tree */ \
node_t *node; /* Root node of the tree */ \ node_t *node; /* Root node of the tree */ \
} tree_t[1]; \ } tree_t[1]; \
typedef struct M_C(name, _s) *M_C(name, _ptr); \ typedef struct M_F(name, _s) *M_F(name, _ptr); \
typedef const struct M_C(name, _s) *M_C(name, _srcptr); \ typedef const struct M_F(name, _s) *M_F(name, _srcptr); \
\ \
/* Iterator on a tree. The iterator stores the full path to the \ /* Iterator on a tree. The iterator stores the full path to the \
current node through all its parents and its depth */ \ current node through all its parents and its depth */ \
typedef struct M_C(name, _it_s) { \ typedef struct M_F(name, _it_s) { \
node_t *stack[M_RBTR33_MAX_STACK]; \ node_t *stack[M_RBTR33_MAX_STACK]; \
int8_t which[M_RBTR33_MAX_STACK]; \ int8_t which[M_RBTR33_MAX_STACK]; \
unsigned int cpt; \ unsigned int cpt; \
} it_t[1]; \ } it_t[1]; \
\ \
/* Definition of the alias used by the oplists */ \ /* Definition of the alias used by the oplists */ \
typedef type M_C(name, _subtype_ct); \ typedef type M_F(name, _subtype_ct); \
typedef tree_t M_C(name, _ct); \ typedef tree_t M_F(name, _ct); \
typedef it_t M_C(name, _it_ct); \ typedef it_t M_F(name, _it_ct); \
/* Define the mempool encapsulation */ /* Define the mempool encapsulation */
#define M_RBTR33_DEF_MEMPOOL(name, type, oplist, tree_t, node_t, it_t) \ #define M_RBTR33_DEF_MEMPOOL(name, type, oplist, tree_t, node_t, it_t) \
/* Link with fast memory allocator if requested */ \ /* Link with fast memory allocator if requested */ \
M_IF_METHOD(MEMPOOL, oplist)( \ M_IF_METHOD(MEMPOOL, oplist)( \
/* Definition of the memory pool of this kind of node */ \ /* Definition of the memory pool of this kind of node */ \
MEMPOOL_DEF(M_C(name, _mempool), node_t) \ MEMPOOL_DEF(M_F(name, _mempool), node_t) \
/* Definition of the global variable used to reference this pool */ \ /* Definition of the global variable used to reference this pool */ \
M_GET_MEMPOOL_LINKAGE oplist M_C(name, _mempool_t) M_GET_MEMPOOL oplist; \ M_GET_MEMPOOL_LINKAGE oplist M_F(name, _mempool_t) M_GET_MEMPOOL oplist; \
/* Allocator function */ \ /* Allocator function */ \
static inline node_t *M_C3(m_rbtr33_,name,_new)(void) { \ static inline node_t *M_C3(m_rbtr33_,name,_new)(void) { \
return M_C(name, _mempool_alloc)(M_GET_MEMPOOL oplist); \ return M_F(name, _mempool_alloc)(M_GET_MEMPOOL oplist); \
} \ } \
/* Deallocator function */ \ /* Deallocator function */ \
static inline void M_C3(m_rbtr33_,name,_del)(node_t *ptr) { \ static inline void M_C3(m_rbtr33_,name,_del)(node_t *ptr) { \
M_C(name, _mempool_free)(M_GET_MEMPOOL oplist, ptr); \ M_F(name, _mempool_free)(M_GET_MEMPOOL oplist, ptr); \
} \ } \
\ \
, /* No mempool allocation */ \ , /* No mempool allocation */ \
@@ -249,7 +249,7 @@ typedef enum {
#define M_RBTR33_DEF_CORE(name, type, oplist, tree_t, node_t, it_t) \ #define M_RBTR33_DEF_CORE(name, type, oplist, tree_t, node_t, it_t) \
\ \
static inline void \ static inline void \
M_C(name, _init)(tree_t tree) \ M_F(name, _init)(tree_t tree) \
{ \ { \
M_ASSERT (tree != NULL); \ M_ASSERT (tree != NULL); \
tree->size = 0; \ tree->size = 0; \
@@ -258,7 +258,7 @@ typedef enum {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _reset)(tree_t tree) \ M_F(name, _reset)(tree_t tree) \
{ \ { \
M_RBTR33_CONTRACT(tree); \ M_RBTR33_CONTRACT(tree); \
node_t *stack[M_RBTR33_MAX_STACK]; \ node_t *stack[M_RBTR33_MAX_STACK]; \
@@ -303,14 +303,14 @@ typedef enum {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _clear)(tree_t tree) \ M_F(name, _clear)(tree_t tree) \
{ \ { \
/* Nothing more than clean the tree as everything is cleared */ \ /* Nothing more than clean the tree as everything is cleared */ \
M_C(name, _reset)(tree); \ M_F(name, _reset)(tree); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _push)(tree_t tree, type const data) \ M_F(name, _push)(tree_t tree, type const data) \
{ \ { \
M_RBTR33_CONTRACT(tree); \ M_RBTR33_CONTRACT(tree); \
node_t *tab[M_RBTR33_MAX_STACK]; \ node_t *tab[M_RBTR33_MAX_STACK]; \
@@ -436,7 +436,7 @@ typedef enum {
} \ } \
\ \
static inline size_t \ static inline size_t \
M_C(name, _size)(const tree_t tree) \ M_F(name, _size)(const tree_t tree) \
{ \ { \
M_RBTR33_CONTRACT (tree); \ M_RBTR33_CONTRACT (tree); \
return tree->size; \ return tree->size; \
@@ -466,19 +466,19 @@ typedef enum {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _it)(it_t it, const tree_t tree) \ M_F(name, _it)(it_t it, const tree_t tree) \
{ \ { \
M_C3(m_rbtr33_,name,_it)(it, tree, 0); \ M_C3(m_rbtr33_,name,_it)(it, tree, 0); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _it_last)(it_t it, const tree_t tree) \ M_F(name, _it_last)(it_t it, const tree_t tree) \
{ \ { \
M_C3(m_rbtr33_,name,_it)(it, tree, 1); \ M_C3(m_rbtr33_,name,_it)(it, tree, 1); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _it_end)(it_t it, const tree_t tree) \ M_F(name, _it_end)(it_t it, const tree_t tree) \
{ \ { \
M_RBTR33_CONTRACT (tree); \ M_RBTR33_CONTRACT (tree); \
M_ASSERT (it != NULL); \ M_ASSERT (it != NULL); \
@@ -487,14 +487,14 @@ typedef enum {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _it_set)(it_t it, const it_t ref) \ M_F(name, _it_set)(it_t it, const it_t ref) \
{ \ { \
M_ASSERT (it != NULL && ref != NULL); \ M_ASSERT (it != NULL && ref != NULL); \
*it = *ref; \ *it = *ref; \
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _end_p)(const it_t it) \ M_F(name, _end_p)(const it_t it) \
{ \ { \
M_ASSERT (it != NULL); \ M_ASSERT (it != NULL); \
return it->cpt == 0; \ return it->cpt == 0; \
@@ -534,19 +534,19 @@ typedef enum {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _next)(it_t it) \ M_F(name, _next)(it_t it) \
{ \ { \
M_C3(m_rbtr33_,name,_next)(it, 0); \ M_C3(m_rbtr33_,name,_next)(it, 0); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _previous)(it_t it) \ M_F(name, _previous)(it_t it) \
{ \ { \
M_C3(m_rbtr33_,name,_next)(it, 1); \ M_C3(m_rbtr33_,name,_next)(it, 1); \
} \ } \
\ \
static inline type * \ static inline type * \
M_C(name, _ref)(const it_t it) \ M_F(name, _ref)(const it_t it) \
{ \ { \
M_ASSERT(it != NULL); \ M_ASSERT(it != NULL); \
/* There shall be at least one element */ \ /* There shall be at least one element */ \
@@ -556,13 +556,13 @@ typedef enum {
} \ } \
\ \
static inline type const * \ static inline type const * \
M_C(name, _cref)(const it_t it) \ M_F(name, _cref)(const it_t it) \
{ \ { \
return M_CONST_CAST(type, M_C(name, _ref)(it)); \ return M_CONST_CAST(type, M_F(name, _ref)(it)); \
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _it_equal_p)(const it_t it1, const it_t it2) \ M_F(name, _it_equal_p)(const it_t it1, const it_t it2) \
{ \ { \
M_ASSERT(it1 != NULL && it2 != NULL); \ M_ASSERT(it1 != NULL && it2 != NULL); \
/* There can be no element */ \ /* There can be no element */ \
@@ -573,7 +573,7 @@ typedef enum {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _it_from)(it_t it, const tree_t tree, type const data) \ M_F(name, _it_from)(it_t it, const tree_t tree, type const data) \
{ \ { \
M_RBTR33_CONTRACT (tree); \ M_RBTR33_CONTRACT (tree); \
M_ASSERT (it != NULL); \ M_ASSERT (it != NULL); \
@@ -597,12 +597,12 @@ typedef enum {
/* The iterator found may be strictly lower than data. \ /* The iterator found may be strictly lower than data. \
In this case, go to the next element */ \ In this case, go to the next element */ \
if (cmp < 0) { \ if (cmp < 0) { \
M_C(name, _next)(it); \ M_F(name, _next)(it); \
} \ } \
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _it_until_p)(it_t it, type const data) \ M_F(name, _it_until_p)(it_t it, type const data) \
{ \ { \
M_ASSERT (it != NULL); \ M_ASSERT (it != NULL); \
if (M_UNLIKELY(it->cpt == 0)) return true; \ if (M_UNLIKELY(it->cpt == 0)) return true; \
@@ -613,7 +613,7 @@ typedef enum {
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _it_while_p)(it_t it, type const data) \ M_F(name, _it_while_p)(it_t it, type const data) \
{ \ { \
M_ASSERT (it != NULL); \ M_ASSERT (it != NULL); \
if (M_UNLIKELY(it->cpt == 0)) return false; \ if (M_UNLIKELY(it->cpt == 0)) return false; \
@@ -624,7 +624,7 @@ typedef enum {
} \ } \
\ \
static inline type * \ static inline type * \
M_C(name, _min)(const tree_t tree) \ M_F(name, _min)(const tree_t tree) \
{ \ { \
M_RBTR33_CONTRACT (tree); \ M_RBTR33_CONTRACT (tree); \
node_t *n = tree->node; \ node_t *n = tree->node; \
@@ -637,7 +637,7 @@ typedef enum {
} \ } \
\ \
static inline type * \ static inline type * \
M_C(name, _max)(const tree_t tree) \ M_F(name, _max)(const tree_t tree) \
{ \ { \
M_RBTR33_CONTRACT (tree); \ M_RBTR33_CONTRACT (tree); \
node_t *n = tree->node; \ node_t *n = tree->node; \
@@ -650,19 +650,19 @@ typedef enum {
} \ } \
\ \
static inline type const * \ static inline type const * \
M_C(name, _cmin)(const tree_t tree) \ M_F(name, _cmin)(const tree_t tree) \
{ \ { \
return M_CONST_CAST(type, M_C(name, _min)(tree)); \ return M_CONST_CAST(type, M_F(name, _min)(tree)); \
} \ } \
\ \
static inline type const * \ static inline type const * \
M_C(name, _cmax)(const tree_t tree) \ M_F(name, _cmax)(const tree_t tree) \
{ \ { \
return M_CONST_CAST(type, M_C(name, _max)(tree)); \ return M_CONST_CAST(type, M_F(name, _max)(tree)); \
} \ } \
\ \
static inline type * \ static inline type * \
M_C(name, _get)(const tree_t tree, type const data) \ M_F(name, _get)(const tree_t tree, type const data) \
{ \ { \
M_RBTR33_CONTRACT (tree); \ M_RBTR33_CONTRACT (tree); \
node_t *n = tree->node; \ node_t *n = tree->node; \
@@ -681,9 +681,9 @@ typedef enum {
} \ } \
\ \
static inline type const * \ static inline type const * \
M_C(name, _cget)(const tree_t tree, type const data) \ M_F(name, _cget)(const tree_t tree, type const data) \
{ \ { \
return M_CONST_CAST(type, M_C(name, _get)(tree, data)); \ return M_CONST_CAST(type, M_F(name, _get)(tree, data)); \
} \ } \
\ \
/* Create a copy of the given node (recursively) */ \ /* Create a copy of the given node (recursively) */ \
@@ -704,7 +704,7 @@ typedef enum {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _init_set)(tree_t tree, const tree_t ref) \ M_F(name, _init_set)(tree_t tree, const tree_t ref) \
{ \ { \
M_RBTR33_CONTRACT (ref); \ M_RBTR33_CONTRACT (ref); \
M_ASSERT (tree != NULL && tree != ref); \ M_ASSERT (tree != NULL && tree != ref); \
@@ -715,17 +715,17 @@ typedef enum {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _set)(tree_t tree, const tree_t ref) \ M_F(name, _set)(tree_t tree, const tree_t ref) \
{ \ { \
M_RBTR33_CONTRACT (tree); \ M_RBTR33_CONTRACT (tree); \
M_RBTR33_CONTRACT (ref); \ M_RBTR33_CONTRACT (ref); \
if (tree == ref) return; \ if (tree == ref) return; \
M_C(name,_clear)(tree); \ M_F(name,_clear)(tree); \
M_C(name,_init_set)(tree, ref); \ M_F(name,_init_set)(tree, ref); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _init_move)(tree_t tree, tree_t ref) \ M_F(name, _init_move)(tree_t tree, tree_t ref) \
{ \ { \
M_RBTR33_CONTRACT (ref); \ M_RBTR33_CONTRACT (ref); \
M_ASSERT (tree != NULL && tree != ref); \ M_ASSERT (tree != NULL && tree != ref); \
@@ -737,18 +737,18 @@ typedef enum {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _move)(tree_t tree, tree_t ref) \ M_F(name, _move)(tree_t tree, tree_t ref) \
{ \ { \
M_RBTR33_CONTRACT (tree); \ M_RBTR33_CONTRACT (tree); \
M_RBTR33_CONTRACT (ref); \ M_RBTR33_CONTRACT (ref); \
M_ASSERT (tree != ref); \ M_ASSERT (tree != ref); \
M_C(name,_clear)(tree); \ M_F(name,_clear)(tree); \
M_C(name,_init_move)(tree, ref); \ M_F(name,_init_move)(tree, ref); \
M_RBTR33_CONTRACT (tree); \ M_RBTR33_CONTRACT (tree); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _swap)(tree_t tree1, tree_t tree2) \ M_F(name, _swap)(tree_t tree1, tree_t tree2) \
{ \ { \
M_RBTR33_CONTRACT (tree1); \ M_RBTR33_CONTRACT (tree1); \
M_RBTR33_CONTRACT (tree2); \ M_RBTR33_CONTRACT (tree2); \
@@ -759,7 +759,7 @@ typedef enum {
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _empty_p)(const tree_t tree) \ M_F(name, _empty_p)(const tree_t tree) \
{ \ { \
M_RBTR33_CONTRACT (tree); \ M_RBTR33_CONTRACT (tree); \
return tree->size == 0; \ return tree->size == 0; \
@@ -805,7 +805,7 @@ typedef enum {
) \ ) \
\ \
static inline bool \ static inline bool \
M_C(name, _pop_at)(type *data_ptr, tree_t tree, type const key) \ M_F(name, _pop_at)(type *data_ptr, tree_t tree, type const key) \
{ \ { \
M_RBTR33_CONTRACT (tree); \ M_RBTR33_CONTRACT (tree); \
node_t *tab[M_RBTR33_MAX_STACK]; \ node_t *tab[M_RBTR33_MAX_STACK]; \
@@ -964,22 +964,22 @@ typedef enum {
return true; \ return true; \
} \ } \
\ \
static inline void M_C(name,_remove)(tree_t t, it_t it) \ static inline void M_F(name,_remove)(tree_t t, it_t it) \
{ \ { \
/* Not optimum: another search in the tree is performed */ \ /* Not optimum: another search in the tree is performed */ \
type data; \ type data; \
M_CALL_INIT_SET(oplist, data, *M_C(name,_cref)(it)); \ M_CALL_INIT_SET(oplist, data, *M_F(name,_cref)(it)); \
M_C(name,_next)(it); \ M_F(name,_next)(it); \
M_C(name, _pop_at)(NULL, t, data); \ M_F(name, _pop_at)(NULL, t, data); \
/* We have changed the tree: the iterator is partialy invalid */ \ /* We have changed the tree: the iterator is partialy invalid */ \
if (!M_C(name, _end_p)(it)) { \ if (!M_F(name, _end_p)(it)) { \
M_C(name, _it_from)(it, t, *M_C(name,_cref)(it)); \ M_F(name, _it_from)(it, t, *M_F(name,_cref)(it)); \
} \ } \
M_CALL_CLEAR(oplist, data); \ M_CALL_CLEAR(oplist, data); \
} \ } \
\ \
M_IF_METHOD(EQUAL, oplist)( \ M_IF_METHOD(EQUAL, oplist)( \
static inline bool M_C(name,_equal_p)(const tree_t t1, const tree_t t2) { \ static inline bool M_F(name,_equal_p)(const tree_t t1, const tree_t t2) { \
M_RBTR33_CONTRACT(t1); \ M_RBTR33_CONTRACT(t1); \
M_RBTR33_CONTRACT(t2); \ M_RBTR33_CONTRACT(t2); \
if (t1->size != t2->size) return false; \ if (t1->size != t2->size) return false; \
@@ -989,34 +989,34 @@ typedef enum {
structuraly different but functionnaly equal (you get this by \ structuraly different but functionnaly equal (you get this by \
constructing the tree in a different way). We have to \ constructing the tree in a different way). We have to \
compare the ordered value within the tree. */ \ compare the ordered value within the tree. */ \
M_C(name, _it)(it1, t1); \ M_F(name, _it)(it1, t1); \
M_C(name, _it)(it2, t2); \ M_F(name, _it)(it2, t2); \
while (!M_C(name, _end_p)(it1) \ while (!M_F(name, _end_p)(it1) \
&& !M_C(name, _end_p)(it2)) { \ && !M_F(name, _end_p)(it2)) { \
type const *ref1 = M_C(name, _cref)(it1); \ type const *ref1 = M_F(name, _cref)(it1); \
type const *ref2 = M_C(name, _cref)(it2); \ type const *ref2 = M_F(name, _cref)(it2); \
if (M_CALL_EQUAL(oplist, *ref1, *ref2) == false) \ if (M_CALL_EQUAL(oplist, *ref1, *ref2) == false) \
return false; \ return false; \
M_C(name, _next)(it1); \ M_F(name, _next)(it1); \
M_C(name, _next)(it2); \ M_F(name, _next)(it2); \
} \ } \
return M_C(name, _end_p)(it1) \ return M_F(name, _end_p)(it1) \
&& M_C(name, _end_p)(it2); \ && M_F(name, _end_p)(it2); \
} \ } \
, /* NO EQUAL METHOD */ ) \ , /* NO EQUAL METHOD */ ) \
\ \
M_IF_METHOD(HASH, oplist)( \ M_IF_METHOD(HASH, oplist)( \
static inline size_t M_C(name,_hash)(const tree_t t1) { \ static inline size_t M_F(name,_hash)(const tree_t t1) { \
M_RBTR33_CONTRACT(t1); \ M_RBTR33_CONTRACT(t1); \
M_HASH_DECL(hash); \ M_HASH_DECL(hash); \
/* NOTE: We can't compute the hash directly for the same reason \ /* NOTE: We can't compute the hash directly for the same reason \
than for EQUAL operator. */ \ than for EQUAL operator. */ \
it_t it1; \ it_t it1; \
M_C(name, _it)(it1, t1); \ M_F(name, _it)(it1, t1); \
while (!M_C(name, _end_p)(it1)) { \ while (!M_F(name, _end_p)(it1)) { \
type const *ref1 = M_C(name, _cref)(it1); \ type const *ref1 = M_F(name, _cref)(it1); \
M_HASH_UP(hash, M_CALL_HASH(oplist, *ref1)); \ M_HASH_UP(hash, M_CALL_HASH(oplist, *ref1)); \
M_C(name, _next)(it1); \ M_F(name, _next)(it1); \
} \ } \
return M_HASH_FINAL (hash); \ return M_HASH_FINAL (hash); \
} \ } \
@@ -1025,7 +1025,7 @@ typedef enum {
/* Define the I/O functions */ /* Define the I/O functions */
#define M_RBTR33_DEF_IO(name, type, oplist, tree_t, node_t, it_t) \ #define M_RBTR33_DEF_IO(name, type, oplist, tree_t, node_t, it_t) \
M_IF_METHOD(GET_STR, oplist)( \ M_IF_METHOD(GET_STR, oplist)( \
static inline void M_C(name, _get_str)(m_string_t str, \ static inline void M_F(name, _get_str)(m_string_t str, \
tree_t const t1, bool append) { \ tree_t const t1, bool append) { \
M_RBTR33_CONTRACT(t1); \ M_RBTR33_CONTRACT(t1); \
M_ASSERT(str != NULL); \ M_ASSERT(str != NULL); \
@@ -1033,14 +1033,14 @@ typedef enum {
/* NOTE: The print is really naive, and not really efficient */ \ /* NOTE: The print is really naive, and not really efficient */ \
bool commaToPrint = false; \ bool commaToPrint = false; \
it_t it1; \ it_t it1; \
M_C(name, _it)(it1, t1); \ M_F(name, _it)(it1, t1); \
while (!M_C(name, _end_p)(it1)) { \ while (!M_F(name, _end_p)(it1)) { \
if (commaToPrint) \ if (commaToPrint) \
m_string_push_back (str, M_GET_SEPARATOR oplist); \ m_string_push_back (str, M_GET_SEPARATOR oplist); \
commaToPrint = true; \ commaToPrint = true; \
type const *ref1 = M_C(name, _cref)(it1); \ type const *ref1 = M_F(name, _cref)(it1); \
M_CALL_GET_STR(oplist, str, *ref1, true); \ M_CALL_GET_STR(oplist, str, *ref1, true); \
M_C(name, _next)(it1); \ M_F(name, _next)(it1); \
} \ } \
m_string_push_back (str, ']'); \ m_string_push_back (str, ']'); \
} \ } \
@@ -1048,20 +1048,20 @@ typedef enum {
\ \
M_IF_METHOD(OUT_STR, oplist)( \ M_IF_METHOD(OUT_STR, oplist)( \
static inline void \ static inline void \
M_C(name, _out_str)(FILE *file, tree_t const rbtree) \ M_F(name, _out_str)(FILE *file, tree_t const rbtree) \
{ \ { \
M_RBTR33_CONTRACT(rbtree); \ M_RBTR33_CONTRACT(rbtree); \
M_ASSERT (file != NULL); \ M_ASSERT (file != NULL); \
fputc ('[', file); \ fputc ('[', file); \
it_t it; \ it_t it; \
bool commaToPrint = false; \ bool commaToPrint = false; \
for (M_C(name, _it)(it, rbtree) ; \ for (M_F(name, _it)(it, rbtree) ; \
!M_C(name, _end_p)(it); \ !M_F(name, _end_p)(it); \
M_C(name, _next)(it)){ \ M_F(name, _next)(it)){ \
if (commaToPrint) \ if (commaToPrint) \
fputc (M_GET_SEPARATOR oplist, file); \ fputc (M_GET_SEPARATOR oplist, file); \
commaToPrint = true; \ commaToPrint = true; \
type const *item = M_C(name, _cref)(it); \ type const *item = M_F(name, _cref)(it); \
M_CALL_OUT_STR(oplist, file, *item); \ M_CALL_OUT_STR(oplist, file, *item); \
} \ } \
fputc (']', file); \ fputc (']', file); \
@@ -1070,11 +1070,11 @@ typedef enum {
\ \
M_IF_METHOD(PARSE_STR, oplist)( \ M_IF_METHOD(PARSE_STR, oplist)( \
static inline bool \ static inline bool \
M_C(name, _parse_str)(tree_t rbtree, const char str[], const char **endp) \ M_F(name, _parse_str)(tree_t rbtree, const char str[], const char **endp) \
{ \ { \
M_RBTR33_CONTRACT(rbtree); \ M_RBTR33_CONTRACT(rbtree); \
M_ASSERT (str != NULL); \ M_ASSERT (str != NULL); \
M_C(name,_reset)(rbtree); \ M_F(name,_reset)(rbtree); \
bool success = false; \ bool success = false; \
int c = *str++; \ int c = *str++; \
if (M_UNLIKELY (c != '[')) goto exit; \ if (M_UNLIKELY (c != '[')) goto exit; \
@@ -1088,7 +1088,7 @@ typedef enum {
bool b = M_CALL_PARSE_STR(oplist, item, str, &str); \ bool b = M_CALL_PARSE_STR(oplist, item, str, &str); \
do { c = *str++; } while (isspace(c)); \ do { c = *str++; } while (isspace(c)); \
if (b == false || c == 0) goto exit_clear; \ if (b == false || c == 0) goto exit_clear; \
M_C(name, _push)(rbtree, item); \ M_F(name, _push)(rbtree, item); \
} while (c == M_GET_SEPARATOR oplist); \ } while (c == M_GET_SEPARATOR oplist); \
success = (c == ']'); \ success = (c == ']'); \
exit_clear: \ exit_clear: \
@@ -1101,11 +1101,11 @@ typedef enum {
\ \
M_IF_METHOD(IN_STR, oplist)( \ M_IF_METHOD(IN_STR, oplist)( \
static inline bool \ static inline bool \
M_C(name, _in_str)(tree_t rbtree, FILE *file) \ M_F(name, _in_str)(tree_t rbtree, FILE *file) \
{ \ { \
M_RBTR33_CONTRACT(rbtree); \ M_RBTR33_CONTRACT(rbtree); \
M_ASSERT (file != NULL); \ M_ASSERT (file != NULL); \
M_C(name,_reset)(rbtree); \ M_F(name,_reset)(rbtree); \
int c = fgetc(file); \ int c = fgetc(file); \
if (M_UNLIKELY (c != '[')) return false; \ if (M_UNLIKELY (c != '[')) return false; \
c = fgetc(file); \ c = fgetc(file); \
@@ -1118,7 +1118,7 @@ typedef enum {
bool b = M_CALL_IN_STR(oplist, item, file); \ bool b = M_CALL_IN_STR(oplist, item, file); \
do { c = fgetc(file); } while (isspace(c)); \ do { c = fgetc(file); } while (isspace(c)); \
if (b == false || c == EOF) break; \ if (b == false || c == EOF) break; \
M_C(name, _push)(rbtree, item); \ M_F(name, _push)(rbtree, item); \
} while (c == M_GET_SEPARATOR oplist); \ } while (c == M_GET_SEPARATOR oplist); \
M_CALL_CLEAR(oplist, item); \ M_CALL_CLEAR(oplist, item); \
return c == ']'; \ return c == ']'; \
@@ -1127,20 +1127,20 @@ typedef enum {
\ \
M_IF_METHOD(OUT_SERIAL, oplist)( \ M_IF_METHOD(OUT_SERIAL, oplist)( \
static inline m_serial_return_code_t \ static inline m_serial_return_code_t \
M_C(name, _out_serial)(m_serial_write_t f, tree_t const t1) \ M_F(name, _out_serial)(m_serial_write_t f, tree_t const t1) \
{ \ { \
M_RBTR33_CONTRACT(t1); \ M_RBTR33_CONTRACT(t1); \
M_ASSERT (f != NULL && f->m_interface != NULL); \ M_ASSERT (f != NULL && f->m_interface != NULL); \
m_serial_local_t local; \ m_serial_local_t local; \
m_serial_return_code_t ret; \ m_serial_return_code_t ret; \
M_C(name, _subtype_ct) const *item; \ M_F(name, _subtype_ct) const *item; \
bool first_done = false; \ bool first_done = false; \
it_t it; \ it_t it; \
ret = f->m_interface->write_array_start(local, f, t1->size); \ ret = f->m_interface->write_array_start(local, f, t1->size); \
for (M_C(name, _it)(it, t1) ; \ for (M_F(name, _it)(it, t1) ; \
!M_C(name, _end_p)(it); \ !M_F(name, _end_p)(it); \
M_C(name, _next)(it)){ \ M_F(name, _next)(it)){ \
item = M_C(name, _cref)(it); \ item = M_F(name, _cref)(it); \
if (first_done) \ if (first_done) \
ret |= f->m_interface->write_array_next(local, f); \ ret |= f->m_interface->write_array_next(local, f); \
ret |= M_CALL_OUT_SERIAL(oplist, f, *item); \ ret |= M_CALL_OUT_SERIAL(oplist, f, *item); \
@@ -1153,7 +1153,7 @@ typedef enum {
\ \
M_IF_METHOD(IN_SERIAL, oplist)( \ M_IF_METHOD(IN_SERIAL, oplist)( \
static inline m_serial_return_code_t \ static inline m_serial_return_code_t \
M_C(name, _in_serial)(tree_t t1, m_serial_read_t f) \ M_F(name, _in_serial)(tree_t t1, m_serial_read_t f) \
{ \ { \
M_RBTR33_CONTRACT(t1); \ M_RBTR33_CONTRACT(t1); \
M_ASSERT (f != NULL && f->m_interface != NULL); \ M_ASSERT (f != NULL && f->m_interface != NULL); \
@@ -1161,14 +1161,14 @@ typedef enum {
m_serial_return_code_t ret; \ m_serial_return_code_t ret; \
size_t estimated_size = 0; \ size_t estimated_size = 0; \
type key; \ type key; \
M_C(name,_reset)(t1); \ M_F(name,_reset)(t1); \
ret = f->m_interface->read_array_start(local, f, &estimated_size); \ ret = f->m_interface->read_array_start(local, f, &estimated_size); \
if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) return ret; \ if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) return ret; \
M_CALL_INIT(oplist, key); \ M_CALL_INIT(oplist, key); \
do { \ do { \
ret = M_CALL_IN_SERIAL(oplist, key, f); \ ret = M_CALL_IN_SERIAL(oplist, key, f); \
if (ret != M_SERIAL_OK_DONE) { break; } \ if (ret != M_SERIAL_OK_DONE) { break; } \
M_C(name, _push)(t1, key); \ M_F(name, _push)(t1, key); \
} while ((ret = f->m_interface->read_array_next(local, f)) == M_SERIAL_OK_CONTINUE); \ } while ((ret = f->m_interface->read_array_next(local, f)) == M_SERIAL_OK_CONTINUE); \
M_CALL_CLEAR(oplist, key); \ M_CALL_CLEAR(oplist, key); \
return ret; \ return ret; \
+63 -63
View File
@@ -34,7 +34,7 @@ M_BEGIN_PROTECTED_CODE
/* Define shared pointer and its function. /* Define shared pointer and its function.
USAGE: SHARED_PTR_DEF(name, type, [, oplist]) */ USAGE: SHARED_PTR_DEF(name, type, [, oplist]) */
#define M_SHARED_PTR_DEF(name, ...) \ #define M_SHARED_PTR_DEF(name, ...) \
M_SHARED_PTR_DEF_AS(name, M_C(name,_t), __VA_ARGS__) M_SHARED_PTR_DEF_AS(name, M_F(name,_t), __VA_ARGS__)
/* Define shared pointer and its function /* Define shared pointer and its function
@@ -59,7 +59,7 @@ M_BEGIN_PROTECTED_CODE
/* Define relaxed shared pointer and its function (thread unsafe). /* Define relaxed shared pointer and its function (thread unsafe).
USAGE: SHARED_PTR_RELAXED_DEF(name, type, [, oplist]) */ USAGE: SHARED_PTR_RELAXED_DEF(name, type, [, oplist]) */
#define M_SHARED_PTR_RELAXED_DEF(name, ...) \ #define M_SHARED_PTR_RELAXED_DEF(name, ...) \
M_SHARED_PTR_RELAXED_DEF_AS(name, M_C(name,_t), __VA_ARGS__) M_SHARED_PTR_RELAXED_DEF_AS(name, M_F(name,_t), __VA_ARGS__)
/* Define relaxed shared pointer and its function (thread unsafe) /* Define relaxed shared pointer and its function (thread unsafe)
@@ -77,7 +77,7 @@ M_BEGIN_PROTECTED_CODE
This is a bounded pool of resource shared by multiple owners. This is a bounded pool of resource shared by multiple owners.
USAGE: SHARED_RESOURCE_DEF(name, type, [, oplist]) */ USAGE: SHARED_RESOURCE_DEF(name, type, [, oplist]) */
#define M_SHARED_RESOURCE_DEF(name, ...) \ #define M_SHARED_RESOURCE_DEF(name, ...) \
M_SHARED_RESOURCE_DEF_AS(name, M_C(name,_t), M_C(name,_it_t), __VA_ARGS__) M_SHARED_RESOURCE_DEF_AS(name, M_F(name,_t), M_F(name,_it_t), __VA_ARGS__)
/* Define shared resource and its function /* Define shared resource and its function
@@ -109,16 +109,16 @@ M_BEGIN_PROTECTED_CODE
((M_LIB_ERROR(ARGUMENT_OF_SHARED_PTR_OPLIST_IS_NOT_AN_OPLIST, name, oplist))) ((M_LIB_ERROR(ARGUMENT_OF_SHARED_PTR_OPLIST_IS_NOT_AN_OPLIST, name, oplist)))
#define M_SHAR3D_PTR_OPLIST_P3(name, oplist) ( \ #define M_SHAR3D_PTR_OPLIST_P3(name, oplist) ( \
INIT(M_C(name, _init)), \ INIT(M_F(name, _init)), \
CLEAR(M_C(name, _clear)), \ CLEAR(M_F(name, _clear)), \
INIT_SET(M_C(name, _init_set)), \ INIT_SET(M_F(name, _init_set)), \
SET(M_C(name, _set)) \ SET(M_F(name, _set)) \
INIT_MOVE(M_C(name, _init_move)), \ INIT_MOVE(M_F(name, _init_move)), \
RESET(M_C(name, _reset)), \ RESET(M_F(name, _reset)), \
MOVE(M_C(name, _move)), \ MOVE(M_F(name, _move)), \
SWAP(M_C(name, _swap)) \ SWAP(M_F(name, _swap)) \
,NAME(name) \ ,NAME(name) \
,TYPE(M_C(name, _ct)) \ ,TYPE(M_F(name, _ct)) \
,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW oplist),) \ ,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW oplist),) \
,M_IF_METHOD(REALLOC, oplist)(REALLOC(M_GET_REALLOC oplist),) \ ,M_IF_METHOD(REALLOC, oplist)(REALLOC(M_GET_REALLOC oplist),) \
,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL oplist),) \ ,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL oplist),) \
@@ -173,44 +173,44 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
/* Define the types */ /* Define the types */
#define M_SHAR3D_PTR_DEF_TYPE(name, type, oplist, cpt_oplist, shared_t) \ #define M_SHAR3D_PTR_DEF_TYPE(name, type, oplist, cpt_oplist, shared_t) \
\ \
typedef struct M_C(name, _s){ \ typedef struct M_F(name, _s){ \
type *data; /* Pointer to the data */ \ type *data; /* Pointer to the data */ \
M_GET_TYPE cpt_oplist cpt; /* Counter of how many refs the data */ \ M_GET_TYPE cpt_oplist cpt; /* Counter of how many refs the data */ \
bool combineAlloc; /* Does the data and the ptr share the slot? */ \ bool combineAlloc; /* Does the data and the ptr share the slot? */ \
} *shared_t[1]; \ } *shared_t[1]; \
typedef struct M_C(name, _s) *M_C(name, _ptr); \ typedef struct M_F(name, _s) *M_F(name, _ptr); \
typedef const struct M_C(name, _s) *M_C(name, _srcptr); \ typedef const struct M_F(name, _s) *M_F(name, _srcptr); \
\ \
/* Internal type for oplist */ \ /* Internal type for oplist */ \
typedef shared_t M_C(name, _ct); \ typedef shared_t M_F(name, _ct); \
\ \
typedef struct M_C(name, combine_s) { \ typedef struct M_F(name, combine_s) { \
type data; \ type data; \
struct M_C(name, _s) ptr; \ struct M_F(name, _s) ptr; \
} M_C(name, combine_ct)[1]; \ } M_F(name, combine_ct)[1]; \
/* Define the core functions */ /* Define the core functions */
#define M_SHAR3D_PTR_DEF_CORE(name, type, oplist, cpt_oplist, shared_t) \ #define M_SHAR3D_PTR_DEF_CORE(name, type, oplist, cpt_oplist, shared_t) \
\ \
static inline void \ static inline void \
M_C(name, _init)(shared_t shared) \ M_F(name, _init)(shared_t shared) \
{ \ { \
*shared = NULL; \ *shared = NULL; \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _init2)(shared_t shared, type *data) \ M_F(name, _init2)(shared_t shared, type *data) \
{ \ { \
M_ASSERT (shared != NULL); \ M_ASSERT (shared != NULL); \
/* The shared ptr get exclusive access to data */ \ /* The shared ptr get exclusive access to data */ \
struct M_C(name, _s) *ptr; \ struct M_F(name, _s) *ptr; \
if (M_UNLIKELY (data == NULL)) { \ if (M_UNLIKELY (data == NULL)) { \
*shared = NULL; \ *shared = NULL; \
return; \ return; \
} \ } \
ptr = M_CALL_NEW(oplist, struct M_C(name, _s)); \ ptr = M_CALL_NEW(oplist, struct M_F(name, _s)); \
if (M_UNLIKELY_NOMEM (ptr == NULL)) { \ if (M_UNLIKELY_NOMEM (ptr == NULL)) { \
M_MEMORY_FULL(sizeof(struct M_C(name, _s))); \ M_MEMORY_FULL(sizeof(struct M_F(name, _s))); \
return; \ return; \
} \ } \
ptr->data = data; \ ptr->data = data; \
@@ -222,16 +222,16 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
\ \
M_IF_METHOD(INIT, oplist)( \ M_IF_METHOD(INIT, oplist)( \
static inline void \ static inline void \
M_C(name, _init_new)(shared_t shared) \ M_F(name, _init_new)(shared_t shared) \
{ \ { \
/* NOTE: Alloc 1 struct with both structures. */ \ /* NOTE: Alloc 1 struct with both structures. */ \
struct M_C(name, combine_s) *p = \ struct M_F(name, combine_s) *p = \
M_CALL_NEW(oplist, struct M_C(name, combine_s)); \ M_CALL_NEW(oplist, struct M_F(name, combine_s)); \
if (M_UNLIKELY_NOMEM (p == NULL)) { \ if (M_UNLIKELY_NOMEM (p == NULL)) { \
M_MEMORY_FULL(sizeof(struct M_C(name, combine_s))); \ M_MEMORY_FULL(sizeof(struct M_F(name, combine_s))); \
return; \ return; \
} \ } \
struct M_C(name, _s) *ptr = &p->ptr; \ struct M_F(name, _s) *ptr = &p->ptr; \
type *data = &p->data; \ type *data = &p->data; \
M_CALL_INIT( oplist, *data); \ M_CALL_INIT( oplist, *data); \
ptr->data = data; \ ptr->data = data; \
@@ -243,14 +243,14 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
, /* No INIT */ ) \ , /* No INIT */ ) \
\ \
static inline bool \ static inline bool \
M_C(name, _NULL_p)(const shared_t shared) \ M_F(name, _NULL_p)(const shared_t shared) \
{ \ { \
M_SHAR3D_CONTRACT(shared, cpt_oplist); \ M_SHAR3D_CONTRACT(shared, cpt_oplist); \
return *shared == NULL; \ return *shared == NULL; \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _init_set)(shared_t dest, \ M_F(name, _init_set)(shared_t dest, \
const shared_t shared) \ const shared_t shared) \
{ \ { \
M_SHAR3D_CONTRACT(shared, cpt_oplist); \ M_SHAR3D_CONTRACT(shared, cpt_oplist); \
@@ -264,7 +264,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _clear)(shared_t dest) \ M_F(name, _clear)(shared_t dest) \
{ \ { \
M_SHAR3D_CONTRACT(dest, cpt_oplist); \ M_SHAR3D_CONTRACT(dest, cpt_oplist); \
if (*dest != NULL) { \ if (*dest != NULL) { \
@@ -285,24 +285,24 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _reset)(shared_t dest) \ M_F(name, _reset)(shared_t dest) \
{ \ { \
/* NOTE: Clear will also set dest to NULL */ \ /* NOTE: Clear will also set dest to NULL */ \
M_C(name, _clear)(dest); \ M_F(name, _clear)(dest); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _set)(shared_t dest, \ M_F(name, _set)(shared_t dest, \
const shared_t shared) \ const shared_t shared) \
{ \ { \
M_SHAR3D_CONTRACT(dest, cpt_oplist); \ M_SHAR3D_CONTRACT(dest, cpt_oplist); \
M_SHAR3D_CONTRACT(shared, cpt_oplist); \ M_SHAR3D_CONTRACT(shared, cpt_oplist); \
M_C(name, _clear)(dest); \ M_F(name, _clear)(dest); \
M_C(name, _init_set)(dest, shared); \ M_F(name, _init_set)(dest, shared); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _init_move)(shared_t dest, \ M_F(name, _init_move)(shared_t dest, \
shared_t shared) \ shared_t shared) \
{ \ { \
M_SHAR3D_CONTRACT(shared, cpt_oplist); \ M_SHAR3D_CONTRACT(shared, cpt_oplist); \
@@ -313,30 +313,30 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _move)(shared_t dest, \ M_F(name, _move)(shared_t dest, \
shared_t shared) \ shared_t shared) \
{ \ { \
M_SHAR3D_CONTRACT(dest, cpt_oplist); \ M_SHAR3D_CONTRACT(dest, cpt_oplist); \
M_SHAR3D_CONTRACT(shared, cpt_oplist); \ M_SHAR3D_CONTRACT(shared, cpt_oplist); \
M_ASSERT (dest != shared); \ M_ASSERT (dest != shared); \
M_C(name, _clear)(dest); \ M_F(name, _clear)(dest); \
M_C(name, _init_move)(dest, shared); \ M_F(name, _init_move)(dest, shared); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _swap)(shared_t p1, \ M_F(name, _swap)(shared_t p1, \
shared_t p2) \ shared_t p2) \
{ \ { \
M_SHAR3D_CONTRACT(p1, cpt_oplist); \ M_SHAR3D_CONTRACT(p1, cpt_oplist); \
M_SHAR3D_CONTRACT(p2, cpt_oplist); \ M_SHAR3D_CONTRACT(p2, cpt_oplist); \
/* NOTE: SWAP is not atomic */ \ /* NOTE: SWAP is not atomic */ \
M_SWAP (struct M_C(name, _s)*, *p1, *p2); \ M_SWAP (struct M_F(name, _s)*, *p1, *p2); \
M_SHAR3D_CONTRACT(p1, cpt_oplist); \ M_SHAR3D_CONTRACT(p1, cpt_oplist); \
M_SHAR3D_CONTRACT(p2, cpt_oplist); \ M_SHAR3D_CONTRACT(p2, cpt_oplist); \
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _equal_p)(const shared_t p1, \ M_F(name, _equal_p)(const shared_t p1, \
const shared_t p2) \ const shared_t p2) \
{ \ { \
M_SHAR3D_CONTRACT(p1, cpt_oplist); \ M_SHAR3D_CONTRACT(p1, cpt_oplist); \
@@ -345,7 +345,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
} \ } \
\ \
static inline type const * \ static inline type const * \
M_C(name, _cref)(const shared_t shared) \ M_F(name, _cref)(const shared_t shared) \
{ \ { \
M_SHAR3D_CONTRACT(shared, cpt_oplist); \ M_SHAR3D_CONTRACT(shared, cpt_oplist); \
M_ASSERT(*shared != NULL); \ M_ASSERT(*shared != NULL); \
@@ -355,7 +355,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
} \ } \
\ \
static inline type * \ static inline type * \
M_C(name, _ref)(shared_t shared) \ M_F(name, _ref)(shared_t shared) \
{ \ { \
M_SHAR3D_CONTRACT(shared, cpt_oplist); \ M_SHAR3D_CONTRACT(shared, cpt_oplist); \
M_ASSERT(*shared != NULL); \ M_ASSERT(*shared != NULL); \
@@ -392,35 +392,35 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
#define M_SHAR3D_RESOURCE_DEF_TYPE(name, type, oplist, shared_t, it_t) \ #define M_SHAR3D_RESOURCE_DEF_TYPE(name, type, oplist, shared_t, it_t) \
\ \
/* Create an aligned type to avoid false sharing between threads */ \ /* Create an aligned type to avoid false sharing between threads */ \
typedef struct M_C(name, _atype_s) { \ typedef struct M_F(name, _atype_s) { \
atomic_uint cpt; \ atomic_uint cpt; \
type x; \ type x; \
M_CACHELINE_ALIGN(align, type, atomic_uint); \ M_CACHELINE_ALIGN(align, type, atomic_uint); \
} M_C(name, _atype_ct); \ } M_F(name, _atype_ct); \
\ \
typedef struct M_C(name, _s) { \ typedef struct M_F(name, _s) { \
m_genint_t core; \ m_genint_t core; \
M_C(name, _atype_ct) *buffer; \ M_F(name, _atype_ct) *buffer; \
} shared_t[1]; \ } shared_t[1]; \
\ \
typedef struct M_C(name, _it_s) { \ typedef struct M_F(name, _it_s) { \
unsigned int idx; \ unsigned int idx; \
struct M_C(name, _s) *ref; \ struct M_F(name, _s) *ref; \
} it_t[1]; \ } it_t[1]; \
\ \
/* Internal Types for oplist */ \ /* Internal Types for oplist */ \
typedef shared_t M_C(name, _ct); \ typedef shared_t M_F(name, _ct); \
/* Define the core functions */ /* Define the core functions */
#define M_SHAR3D_RESOURCE_DEF_CORE(name, type, oplist, shared_t, it_t) \ #define M_SHAR3D_RESOURCE_DEF_CORE(name, type, oplist, shared_t, it_t) \
static inline void \ static inline void \
M_C(name, _init)(shared_t s, size_t n) \ M_F(name, _init)(shared_t s, size_t n) \
{ \ { \
M_ASSERT(s != NULL); \ M_ASSERT(s != NULL); \
M_ASSERT (n > 0 && n < UINT_MAX); \ M_ASSERT (n > 0 && n < UINT_MAX); \
s->buffer = M_CALL_REALLOC(oplist, M_C(name, _atype_ct), NULL, n); \ s->buffer = M_CALL_REALLOC(oplist, M_F(name, _atype_ct), NULL, n); \
if (M_UNLIKELY_NOMEM (s->buffer == NULL)) { \ if (M_UNLIKELY_NOMEM (s->buffer == NULL)) { \
M_MEMORY_FULL(sizeof(M_C(name, _atype_ct)) * n); \ M_MEMORY_FULL(sizeof(M_F(name, _atype_ct)) * n); \
return; \ return; \
} \ } \
for(size_t i = 0; i < n; i++) { \ for(size_t i = 0; i < n; i++) { \
@@ -432,7 +432,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _clear)(shared_t s) \ M_F(name, _clear)(shared_t s) \
{ \ { \
M_SHAR3D_RESOURCE_CONTRACT(s); \ M_SHAR3D_RESOURCE_CONTRACT(s); \
size_t n = m_genint_size(s->core); \ size_t n = m_genint_size(s->core); \
@@ -445,7 +445,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _it)(it_t it, shared_t s) \ M_F(name, _it)(it_t it, shared_t s) \
{ \ { \
M_SHAR3D_RESOURCE_CONTRACT(s); \ M_SHAR3D_RESOURCE_CONTRACT(s); \
M_ASSERT (it != NULL); \ M_ASSERT (it != NULL); \
@@ -459,14 +459,14 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _end_p)(it_t it) \ M_F(name, _end_p)(it_t it) \
{ \ { \
M_ASSERT (it != NULL); \ M_ASSERT (it != NULL); \
return it->idx == M_GENINT_ERROR; \ return it->idx == M_GENINT_ERROR; \
} \ } \
\ \
static inline type * \ static inline type * \
M_C(name, _ref)(it_t it) \ M_F(name, _ref)(it_t it) \
{ \ { \
M_ASSERT (it != NULL && it->ref != NULL && it->idx != M_GENINT_ERROR); \ M_ASSERT (it != NULL && it->ref != NULL && it->idx != M_GENINT_ERROR); \
M_SHAR3D_RESOURCE_CONTRACT(it->ref); \ M_SHAR3D_RESOURCE_CONTRACT(it->ref); \
@@ -474,7 +474,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
} \ } \
\ \
static inline type const * \ static inline type const * \
M_C(name, _cref)(it_t it) \ M_F(name, _cref)(it_t it) \
{ \ { \
M_ASSERT (it != NULL && it->ref != NULL && it->idx != M_GENINT_ERROR); \ M_ASSERT (it != NULL && it->ref != NULL && it->idx != M_GENINT_ERROR); \
M_SHAR3D_RESOURCE_CONTRACT(it->ref); \ M_SHAR3D_RESOURCE_CONTRACT(it->ref); \
@@ -482,7 +482,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _end)(it_t it, shared_t s) \ M_F(name, _end)(it_t it, shared_t s) \
{ \ { \
M_SHAR3D_RESOURCE_CONTRACT(s); \ M_SHAR3D_RESOURCE_CONTRACT(s); \
M_ASSERT (it != NULL); \ M_ASSERT (it != NULL); \
@@ -498,7 +498,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _it_set)(it_t itd, it_t its) \ M_F(name, _it_set)(it_t itd, it_t its) \
{ \ { \
M_ASSERT (itd != NULL && its != NULL); \ M_ASSERT (itd != NULL && its != NULL); \
M_SHAR3D_RESOURCE_CONTRACT(its->ref); \ M_SHAR3D_RESOURCE_CONTRACT(its->ref); \
+63 -63
View File
@@ -34,7 +34,7 @@ M_BEGIN_PROTECTED_CODE
/* Define a Single Producer Single Consummer snapshot and its functions /* Define a Single Producer Single Consummer snapshot and its functions
USAGE: SNAPSHOT_SPSC_DEF(name, type[, oplist]) */ USAGE: SNAPSHOT_SPSC_DEF(name, type[, oplist]) */
#define M_SNAPSHOT_SPSC_DEF(name, ...) \ #define M_SNAPSHOT_SPSC_DEF(name, ...) \
M_SNAPSHOT_SPSC_DEF_AS(name, M_C(name,_t), __VA_ARGS__) M_SNAPSHOT_SPSC_DEF_AS(name, M_F(name,_t), __VA_ARGS__)
/* Define a Single Producer Single Consummer snapshot and its functions /* Define a Single Producer Single Consummer snapshot and its functions
@@ -51,7 +51,7 @@ M_BEGIN_PROTECTED_CODE
/* Define a Single Producer Multiple Consummer snapshot and its functions /* Define a Single Producer Multiple Consummer snapshot and its functions
USAGE: SNAPSHOT_SPMC_DEF(name, type[, oplist]) */ USAGE: SNAPSHOT_SPMC_DEF(name, type[, oplist]) */
#define M_SNAPSHOT_SPMC_DEF(name, ...) \ #define M_SNAPSHOT_SPMC_DEF(name, ...) \
M_SNAPSHOT_SPMC_DEF_AS(name, M_C(name,_t), __VA_ARGS__) M_SNAPSHOT_SPMC_DEF_AS(name, M_F(name,_t), __VA_ARGS__)
/* Define a Single Producer Multiple Consummer snapshot and its functions /* Define a Single Producer Multiple Consummer snapshot and its functions
@@ -68,7 +68,7 @@ M_BEGIN_PROTECTED_CODE
/* Define a Multiple Producer Multiple Consummer snapshot and its functions /* Define a Multiple Producer Multiple Consummer snapshot and its functions
USAGE: SNAPSHOT_MPMC_DEF(name, type[, oplist]) */ USAGE: SNAPSHOT_MPMC_DEF(name, type[, oplist]) */
#define M_SNAPSHOT_MPMC_DEF(name, ...) \ #define M_SNAPSHOT_MPMC_DEF(name, ...) \
M_SNAPSHOT_MPMC_DEF_AS(name, M_C(name,_t), __VA_ARGS__) M_SNAPSHOT_MPMC_DEF_AS(name, M_F(name,_t), __VA_ARGS__)
/* Define a Multiple Producer Multiple Consummer snapshot and its functions /* Define a Multiple Producer Multiple Consummer snapshot and its functions
@@ -107,16 +107,16 @@ M_BEGIN_PROTECTED_CODE
/* Define the oplist of a snapshot */ /* Define the oplist of a snapshot */
#define M_SNAPSH0T_OPLIST_P3(name, oplist) \ #define M_SNAPSH0T_OPLIST_P3(name, oplist) \
(INIT(M_C(name, _init)) \ (INIT(M_F(name, _init)) \
,INIT_SET(M_C(name, _init_set)) \ ,INIT_SET(M_F(name, _init_set)) \
,SET(M_C(name, _set)) \ ,SET(M_F(name, _set)) \
,CLEAR(M_C(name, _clear)) \ ,CLEAR(M_F(name, _clear)) \
,NAME(name) \ ,NAME(name) \
,TYPE(M_C(name, _ct)) \ ,TYPE(M_F(name, _ct)) \
,SUBTYPE(M_C(name, _subtype_ct)) \ ,SUBTYPE(M_F(name, _subtype_ct)) \
,OPLIST(oplist) \ ,OPLIST(oplist) \
,M_IF_METHOD(INIT_MOVE, oplist)(INIT_MOVE(M_C(name, _init_move)),) \ ,M_IF_METHOD(INIT_MOVE, oplist)(INIT_MOVE(M_F(name, _init_move)),) \
,M_IF_METHOD(MOVE, oplist)(MOVE(M_C(name, _move)),) \ ,M_IF_METHOD(MOVE, oplist)(MOVE(M_F(name, _move)),) \
) )
@@ -178,27 +178,27 @@ M_BEGIN_PROTECTED_CODE
#define M_SNAPSH0T_SPSC_DEF_TYPE(name, type, oplist, snapshot_t) \ #define M_SNAPSH0T_SPSC_DEF_TYPE(name, type, oplist, snapshot_t) \
\ \
/* Create an aligned type to avoid false sharing between threads */ \ /* Create an aligned type to avoid false sharing between threads */ \
typedef struct M_C(name, _aligned_type_s) { \ typedef struct M_F(name, _aligned_type_s) { \
type x; \ type x; \
M_CACHELINE_ALIGN(align, type); \ M_CACHELINE_ALIGN(align, type); \
} M_C(name, _aligned_type_ct); \ } M_F(name, _aligned_type_ct); \
\ \
typedef struct M_C(name, _s) { \ typedef struct M_F(name, _s) { \
M_C(name, _aligned_type_ct) data[M_SNAPSH0T_SPSC_MAX_BUFFER]; \ M_F(name, _aligned_type_ct) data[M_SNAPSH0T_SPSC_MAX_BUFFER]; \
atomic_uchar flags; \ atomic_uchar flags; \
} snapshot_t[1]; \ } snapshot_t[1]; \
typedef struct M_C(name, _s) *M_C(name, _ptr); \ typedef struct M_F(name, _s) *M_F(name, _ptr); \
typedef const struct M_C(name, _s) *M_C(name, _srcptr); \ typedef const struct M_F(name, _s) *M_F(name, _srcptr); \
\ \
/* Define internal types for oplist */ \ /* Define internal types for oplist */ \
typedef snapshot_t M_C(name, _ct); \ typedef snapshot_t M_F(name, _ct); \
typedef type M_C(name, _subtype_ct); \ typedef type M_F(name, _subtype_ct); \
/* Define the core functions */ /* Define the core functions */
#define M_SNAPSH0T_SPSC_DEF_CORE(name, type, oplist, snapshot_t) \ #define M_SNAPSH0T_SPSC_DEF_CORE(name, type, oplist, snapshot_t) \
\ \
static inline void \ static inline void \
M_C(name, _init)(snapshot_t snap) \ M_F(name, _init)(snapshot_t snap) \
{ \ { \
M_ASSERT(snap != NULL); \ M_ASSERT(snap != NULL); \
for(int i = 0; i < M_SNAPSH0T_SPSC_MAX_BUFFER; i++) { \ for(int i = 0; i < M_SNAPSH0T_SPSC_MAX_BUFFER; i++) { \
@@ -209,7 +209,7 @@ M_BEGIN_PROTECTED_CODE
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _clear)(snapshot_t snap) \ M_F(name, _clear)(snapshot_t snap) \
{ \ { \
M_SNAPSH0T_SPSC_CONTRACT(snap); \ M_SNAPSH0T_SPSC_CONTRACT(snap); \
for(int i = 0; i < M_SNAPSH0T_SPSC_MAX_BUFFER; i++) { \ for(int i = 0; i < M_SNAPSH0T_SPSC_MAX_BUFFER; i++) { \
@@ -219,7 +219,7 @@ M_BEGIN_PROTECTED_CODE
\ \
/* const is missing for org due to use of atomic_load of org */ \ /* const is missing for org due to use of atomic_load of org */ \
static inline void \ static inline void \
M_C(name, _init_set)(snapshot_t snap, snapshot_t org) \ M_F(name, _init_set)(snapshot_t snap, snapshot_t org) \
{ \ { \
M_SNAPSH0T_SPSC_CONTRACT(org); \ M_SNAPSH0T_SPSC_CONTRACT(org); \
M_ASSERT(snap != NULL && snap != org); \ M_ASSERT(snap != NULL && snap != org); \
@@ -232,7 +232,7 @@ M_BEGIN_PROTECTED_CODE
\ \
/* const is missing for org due to use of atomic_load of org */ \ /* const is missing for org due to use of atomic_load of org */ \
static inline void \ static inline void \
M_C(name, _set)(snapshot_t snap, snapshot_t org) \ M_F(name, _set)(snapshot_t snap, snapshot_t org) \
{ \ { \
M_SNAPSH0T_SPSC_CONTRACT(snap); \ M_SNAPSH0T_SPSC_CONTRACT(snap); \
M_SNAPSH0T_SPSC_CONTRACT(org); \ M_SNAPSH0T_SPSC_CONTRACT(org); \
@@ -245,7 +245,7 @@ M_BEGIN_PROTECTED_CODE
\ \
M_IF_METHOD(INIT_MOVE, oplist)( \ M_IF_METHOD(INIT_MOVE, oplist)( \
static inline void \ static inline void \
M_C(name, _init_move)(snapshot_t snap, snapshot_t org) \ M_F(name, _init_move)(snapshot_t snap, snapshot_t org) \
{ \ { \
M_SNAPSH0T_SPSC_CONTRACT(org); \ M_SNAPSH0T_SPSC_CONTRACT(org); \
M_ASSERT(snap != NULL && snap != org); \ M_ASSERT(snap != NULL && snap != org); \
@@ -260,7 +260,7 @@ M_BEGIN_PROTECTED_CODE
\ \
M_IF_METHOD(MOVE, oplist)( \ M_IF_METHOD(MOVE, oplist)( \
static inline void \ static inline void \
M_C(name, _move)(snapshot_t snap, \ M_F(name, _move)(snapshot_t snap, \
snapshot_t org) \ snapshot_t org) \
{ \ { \
M_SNAPSH0T_SPSC_CONTRACT(snap); \ M_SNAPSH0T_SPSC_CONTRACT(snap); \
@@ -276,7 +276,7 @@ M_BEGIN_PROTECTED_CODE
,) /* IF_METHOD (MOVE) */ \ ,) /* IF_METHOD (MOVE) */ \
\ \
static inline type * \ static inline type * \
M_C(name, _write)(snapshot_t snap) \ M_F(name, _write)(snapshot_t snap) \
{ \ { \
M_SNAPSH0T_SPSC_CONTRACT(snap); \ M_SNAPSH0T_SPSC_CONTRACT(snap); \
unsigned char nextFlags, origFlags = atomic_load (&snap->flags); \ unsigned char nextFlags, origFlags = atomic_load (&snap->flags); \
@@ -295,7 +295,7 @@ M_BEGIN_PROTECTED_CODE
} \ } \
\ \
static inline type const * \ static inline type const * \
M_C(name, _read)(snapshot_t snap) \ M_F(name, _read)(snapshot_t snap) \
{ \ { \
M_SNAPSH0T_SPSC_CONTRACT(snap); \ M_SNAPSH0T_SPSC_CONTRACT(snap); \
unsigned char nextFlags, origFlags = atomic_load (&snap->flags); \ unsigned char nextFlags, origFlags = atomic_load (&snap->flags); \
@@ -320,7 +320,7 @@ M_BEGIN_PROTECTED_CODE
\ \
/* Non const due to use of atomic_load */ \ /* Non const due to use of atomic_load */ \
static inline bool \ static inline bool \
M_C(name, _updated_p)(snapshot_t snap) \ M_F(name, _updated_p)(snapshot_t snap) \
{ \ { \
M_SNAPSH0T_SPSC_CONTRACT(snap); \ M_SNAPSH0T_SPSC_CONTRACT(snap); \
unsigned char flags = atomic_load (&snap->flags); \ unsigned char flags = atomic_load (&snap->flags); \
@@ -329,7 +329,7 @@ M_BEGIN_PROTECTED_CODE
\ \
/* Non const due to use of atomic_load */ \ /* Non const due to use of atomic_load */ \
static inline type * \ static inline type * \
M_C(name, _get_write_buffer)(snapshot_t snap) \ M_F(name, _get_write_buffer)(snapshot_t snap) \
{ \ { \
M_SNAPSH0T_SPSC_CONTRACT(snap); \ M_SNAPSH0T_SPSC_CONTRACT(snap); \
unsigned char flags = atomic_load(&snap->flags); \ unsigned char flags = atomic_load(&snap->flags); \
@@ -338,7 +338,7 @@ M_BEGIN_PROTECTED_CODE
\ \
/* Non const due to use of atomic_load */ \ /* Non const due to use of atomic_load */ \
static inline type const * \ static inline type const * \
M_C(name, _get_read_buffer)(snapshot_t snap) \ M_F(name, _get_read_buffer)(snapshot_t snap) \
{ \ { \
M_SNAPSH0T_SPSC_CONTRACT(snap); \ M_SNAPSH0T_SPSC_CONTRACT(snap); \
unsigned char flags = atomic_load(&snap->flags); \ unsigned char flags = atomic_load(&snap->flags); \
@@ -622,32 +622,32 @@ m_snapsh0t_mrsw_read_end(m_snapsh0t_mrsw_ct s, unsigned int idx)
#define M_SNAPSH0T_SPMC_DEF_TYPE(name, type, oplist, snapshot_t) \ #define M_SNAPSH0T_SPMC_DEF_TYPE(name, type, oplist, snapshot_t) \
\ \
/* Create an aligned type to avoid false sharing between threads */ \ /* Create an aligned type to avoid false sharing between threads */ \
typedef struct M_C(name, _aligned_type_s) { \ typedef struct M_F(name, _aligned_type_s) { \
type x; \ type x; \
M_CACHELINE_ALIGN(align, type); \ M_CACHELINE_ALIGN(align, type); \
} M_C(name, _aligned_type_ct); \ } M_F(name, _aligned_type_ct); \
\ \
typedef struct M_C(name, _s) { \ typedef struct M_F(name, _s) { \
M_C(name, _aligned_type_ct) *data; \ M_F(name, _aligned_type_ct) *data; \
m_snapsh0t_mrsw_ct core; \ m_snapsh0t_mrsw_ct core; \
} snapshot_t[1]; \ } snapshot_t[1]; \
\ \
/* Define internal types for oplist */ \ /* Define internal types for oplist */ \
typedef snapshot_t M_C(name, _ct); \ typedef snapshot_t M_F(name, _ct); \
typedef type M_C(name, _subtype_ct); \ typedef type M_F(name, _subtype_ct); \
/* Define the core functions */ /* Define the core functions */
#define M_SNAPSH0T_SPMC_DEF_CORE(name, type, oplist, snapshot_t) \ #define M_SNAPSH0T_SPMC_DEF_CORE(name, type, oplist, snapshot_t) \
\ \
static inline void \ static inline void \
M_C(name, _init)(snapshot_t snap, size_t nReader) \ M_F(name, _init)(snapshot_t snap, size_t nReader) \
{ \ { \
M_ASSERT (snap != NULL); \ M_ASSERT (snap != NULL); \
M_ASSERT (nReader > 0 && nReader <= M_SNAPSH0T_SPMC_MAX_READER); \ M_ASSERT (nReader > 0 && nReader <= M_SNAPSH0T_SPMC_MAX_READER); \
snap->data = M_CALL_REALLOC(oplist, M_C(name, _aligned_type_ct), \ snap->data = M_CALL_REALLOC(oplist, M_F(name, _aligned_type_ct), \
NULL, nReader+M_SNAPSH0T_SPMC_EXTRA_BUFFER); \ NULL, nReader+M_SNAPSH0T_SPMC_EXTRA_BUFFER); \
if (M_UNLIKELY_NOMEM (snap->data == NULL)) { \ if (M_UNLIKELY_NOMEM (snap->data == NULL)) { \
M_MEMORY_FULL(sizeof(M_C(name, _aligned_type_ct)) * \ M_MEMORY_FULL(sizeof(M_F(name, _aligned_type_ct)) * \
(nReader+M_SNAPSH0T_SPMC_EXTRA_BUFFER)); \ (nReader+M_SNAPSH0T_SPMC_EXTRA_BUFFER)); \
return; \ return; \
} \ } \
@@ -659,7 +659,7 @@ m_snapsh0t_mrsw_read_end(m_snapsh0t_mrsw_ct s, unsigned int idx)
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _clear)(snapshot_t snap) \ M_F(name, _clear)(snapshot_t snap) \
{ \ { \
M_SNAPSH0T_SPMC_CONTRACT(snap); \ M_SNAPSH0T_SPMC_CONTRACT(snap); \
size_t nReader = m_snapsh0t_mrsw_size(snap->core); \ size_t nReader = m_snapsh0t_mrsw_size(snap->core); \
@@ -671,7 +671,7 @@ m_snapsh0t_mrsw_read_end(m_snapsh0t_mrsw_ct s, unsigned int idx)
} \ } \
\ \
static inline type * \ static inline type * \
M_C(name, _write)(snapshot_t snap) \ M_F(name, _write)(snapshot_t snap) \
{ \ { \
M_SNAPSH0T_SPMC_CONTRACT(snap); \ M_SNAPSH0T_SPMC_CONTRACT(snap); \
const unsigned int idx = m_snapsh0t_mrsw_write(snap->core); \ const unsigned int idx = m_snapsh0t_mrsw_write(snap->core); \
@@ -679,7 +679,7 @@ m_snapsh0t_mrsw_read_end(m_snapsh0t_mrsw_ct s, unsigned int idx)
} \ } \
\ \
static inline type const * \ static inline type const * \
M_C(name, _read_start)(snapshot_t snap) \ M_F(name, _read_start)(snapshot_t snap) \
{ \ { \
M_SNAPSH0T_SPMC_CONTRACT(snap); \ M_SNAPSH0T_SPMC_CONTRACT(snap); \
const unsigned int idx = m_snapsh0t_mrsw_read_start(snap->core); \ const unsigned int idx = m_snapsh0t_mrsw_read_start(snap->core); \
@@ -687,12 +687,12 @@ m_snapsh0t_mrsw_read_end(m_snapsh0t_mrsw_ct s, unsigned int idx)
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _read_end)(snapshot_t snap, type const *old) \ M_F(name, _read_end)(snapshot_t snap, type const *old) \
{ \ { \
M_SNAPSH0T_SPMC_CONTRACT(snap); \ M_SNAPSH0T_SPMC_CONTRACT(snap); \
M_ASSERT (old != NULL); \ M_ASSERT (old != NULL); \
const M_C(name, _aligned_type_ct) *oldx; \ const M_F(name, _aligned_type_ct) *oldx; \
oldx = M_CTYPE_FROM_FIELD(M_C(name, _aligned_type_ct), old, type, x); \ oldx = M_CTYPE_FROM_FIELD(M_F(name, _aligned_type_ct), old, type, x); \
M_ASSERT (oldx >= snap->data); \ M_ASSERT (oldx >= snap->data); \
M_ASSERT (oldx < snap->data + snap->core->n_reader + M_SNAPSH0T_SPMC_EXTRA_BUFFER); \ M_ASSERT (oldx < snap->data + snap->core->n_reader + M_SNAPSH0T_SPMC_EXTRA_BUFFER); \
M_ASSERT(snap->core->n_reader +M_SNAPSH0T_SPMC_EXTRA_BUFFER < UINT_MAX); \ M_ASSERT(snap->core->n_reader +M_SNAPSH0T_SPMC_EXTRA_BUFFER < UINT_MAX); \
@@ -701,7 +701,7 @@ m_snapsh0t_mrsw_read_end(m_snapsh0t_mrsw_ct s, unsigned int idx)
} \ } \
\ \
static inline type * \ static inline type * \
M_C(name, _get_write_buffer)(snapshot_t snap) \ M_F(name, _get_write_buffer)(snapshot_t snap) \
{ \ { \
M_SNAPSH0T_SPMC_CONTRACT(snap); \ M_SNAPSH0T_SPMC_CONTRACT(snap); \
const unsigned int idx = m_snapsh0t_mrsw_get_write_idx(snap->core); \ const unsigned int idx = m_snapsh0t_mrsw_get_write_idx(snap->core); \
@@ -727,7 +727,7 @@ m_snapsh0t_mrsw_read_end(m_snapsh0t_mrsw_ct s, unsigned int idx)
/* Expand the type and the functions of a MPMC snapshot */ /* Expand the type and the functions of a MPMC snapshot */
#define M_SNAPSH0T_MPMC_DEF_P3(name, type, oplist, snapshot_t) \ #define M_SNAPSH0T_MPMC_DEF_P3(name, type, oplist, snapshot_t) \
M_SNAPSH0T_SPMC_DEF_P1((M_C(name, _mrsw), type, oplist, M_C(name, _mrsw_pct))) \ M_SNAPSH0T_SPMC_DEF_P1((M_F(name, _mrsw), type, oplist, M_F(name, _mrsw_pct))) \
M_SNAPSH0T_MPMC_DEF_TYPE(name, type, oplist, snapshot_t) \ M_SNAPSH0T_MPMC_DEF_TYPE(name, type, oplist, snapshot_t) \
M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \ M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \
M_SNAPSH0T_MPMC_DEF_CORE(name, type, oplist, snapshot_t) \ M_SNAPSH0T_MPMC_DEF_CORE(name, type, oplist, snapshot_t) \
@@ -735,34 +735,34 @@ m_snapsh0t_mrsw_read_end(m_snapsh0t_mrsw_ct s, unsigned int idx)
/* Define the types */ /* Define the types */
#define M_SNAPSH0T_MPMC_DEF_TYPE(name, type, oplist, snapshot_t) \ #define M_SNAPSH0T_MPMC_DEF_TYPE(name, type, oplist, snapshot_t) \
\ \
typedef struct M_C(name, _s) { \ typedef struct M_F(name, _s) { \
M_C(name, _mrsw_pct) core; \ M_F(name, _mrsw_pct) core; \
} snapshot_t[1]; \ } snapshot_t[1]; \
\ \
/* Define internal types for oplist */ \ /* Define internal types for oplist */ \
typedef snapshot_t M_C(name, _ct); \ typedef snapshot_t M_F(name, _ct); \
typedef type M_C(name, _subtype_ct); \ typedef type M_F(name, _subtype_ct); \
/* Define the core functions */ /* Define the core functions */
#define M_SNAPSH0T_MPMC_DEF_CORE(name, type, oplist, snapshot_t) \ #define M_SNAPSH0T_MPMC_DEF_CORE(name, type, oplist, snapshot_t) \
\ \
static inline void \ static inline void \
M_C(name, _init)(snapshot_t snap, size_t nReader, size_t nWriter) \ M_F(name, _init)(snapshot_t snap, size_t nReader, size_t nWriter) \
{ \ { \
M_C(name, _mrsw_init)(snap->core, nReader + nWriter -1 ); \ M_F(name, _mrsw_init)(snap->core, nReader + nWriter -1 ); \
unsigned int idx = snap->core->core->currentWrite; \ unsigned int idx = snap->core->core->currentWrite; \
snap->core->core->currentWrite = M_GENINT_ERROR; \ snap->core->core->currentWrite = M_GENINT_ERROR; \
m_snapsh0t_mrsw_write_end(snap->core->core, idx); \ m_snapsh0t_mrsw_write_end(snap->core->core, idx); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _clear)(snapshot_t snap) \ M_F(name, _clear)(snapshot_t snap) \
{ \ { \
M_C(name, _mrsw_clear)(snap->core); \ M_F(name, _mrsw_clear)(snap->core); \
} \ } \
\ \
static inline type * \ static inline type * \
M_C(name, _write_start)(snapshot_t snap) \ M_F(name, _write_start)(snapshot_t snap) \
{ \ { \
M_SNAPSH0T_SPMC_CONTRACT(snap->core); \ M_SNAPSH0T_SPMC_CONTRACT(snap->core); \
const unsigned int idx = m_snapsh0t_mrsw_write_start(snap->core->core); \ const unsigned int idx = m_snapsh0t_mrsw_write_start(snap->core->core); \
@@ -770,11 +770,11 @@ m_snapsh0t_mrsw_read_end(m_snapsh0t_mrsw_ct s, unsigned int idx)
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _write_end)(snapshot_t snap, type *old) \ M_F(name, _write_end)(snapshot_t snap, type *old) \
{ \ { \
M_SNAPSH0T_SPMC_CONTRACT(snap->core); \ M_SNAPSH0T_SPMC_CONTRACT(snap->core); \
const M_C(name, _mrsw_aligned_type_ct) *oldx; \ const M_F(name, _mrsw_aligned_type_ct) *oldx; \
oldx = M_CTYPE_FROM_FIELD(M_C(name, _mrsw_aligned_type_ct), old, type, x); \ oldx = M_CTYPE_FROM_FIELD(M_F(name, _mrsw_aligned_type_ct), old, type, x); \
M_ASSERT (oldx >= snap->core->data); \ M_ASSERT (oldx >= snap->core->data); \
M_ASSERT (oldx < snap->core->data + snap->core->core->n_reader + M_SNAPSH0T_SPMC_EXTRA_BUFFER); \ M_ASSERT (oldx < snap->core->data + snap->core->core->n_reader + M_SNAPSH0T_SPMC_EXTRA_BUFFER); \
M_ASSERT(snap->core->core->n_reader + M_SNAPSH0T_SPMC_EXTRA_BUFFER < UINT_MAX); \ M_ASSERT(snap->core->core->n_reader + M_SNAPSH0T_SPMC_EXTRA_BUFFER < UINT_MAX); \
@@ -783,15 +783,15 @@ m_snapsh0t_mrsw_read_end(m_snapsh0t_mrsw_ct s, unsigned int idx)
} \ } \
\ \
static inline type const * \ static inline type const * \
M_C(name, _read_start)(snapshot_t snap) \ M_F(name, _read_start)(snapshot_t snap) \
{ \ { \
return M_C(name, _mrsw_read_start)(snap->core); \ return M_F(name, _mrsw_read_start)(snap->core); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _read_end)(snapshot_t snap, type const *old) \ M_F(name, _read_end)(snapshot_t snap, type const *old) \
{ \ { \
M_C(name, _mrsw_read_end)(snap->core, old); \ M_F(name, _mrsw_read_end)(snap->core, old); \
} \ } \
\ \
+64 -64
View File
@@ -1882,7 +1882,7 @@ m_string_utf8_p(m_string_t str)
/* Define the split & the join functions /* Define the split & the join functions
in case of usage with the algorithm module */ in case of usage with the algorithm module */
#define M_STR1NG_SPLIT(name, oplist, type_oplist) \ #define M_STR1NG_SPLIT(name, oplist, type_oplist) \
static inline void M_C(name, _split)(M_GET_TYPE oplist cont, \ static inline void M_F(name, _split)(M_GET_TYPE oplist cont, \
const m_string_t str, const char sep) \ const m_string_t str, const char sep) \
{ \ { \
size_t begin = 0; \ size_t begin = 0; \
@@ -1912,7 +1912,7 @@ m_string_utf8_p(m_string_t str)
m_string_clear(tmp); \ m_string_clear(tmp); \
} \ } \
\ \
static inline void M_C(name, _join)(m_string_t dst, M_GET_TYPE oplist cont, \ static inline void M_F(name, _join)(m_string_t dst, M_GET_TYPE oplist cont, \
const m_string_t str) \ const m_string_t str) \
{ \ { \
bool init_done = false; \ bool init_done = false; \
@@ -2163,29 +2163,29 @@ namespace m_lib {
*/ */
#define M_BOUNDED_STRING_DEF(name, max_size) \ #define M_BOUNDED_STRING_DEF(name, max_size) \
M_BEGIN_PROTECTED_CODE \ M_BEGIN_PROTECTED_CODE \
M_BOUNDED_STR1NG_DEF_P2(name, max_size, M_C(name, _t) ) \ M_BOUNDED_STR1NG_DEF_P2(name, max_size, M_F(name, _t) ) \
M_END_PROTECTED_CODE M_END_PROTECTED_CODE
/* Define the OPLIST of a BOUNDED_STRING */ /* Define the OPLIST of a BOUNDED_STRING */
#define M_BOUNDED_STRING_OPLIST(name) \ #define M_BOUNDED_STRING_OPLIST(name) \
(INIT(M_C(name,_init)), \ (INIT(M_F(name,_init)), \
INIT_SET(M_C(name,_init_set)), \ INIT_SET(M_F(name,_init_set)), \
SET(M_C(name,_set)), \ SET(M_F(name,_set)), \
CLEAR(M_C(name,_clear)), \ CLEAR(M_F(name,_clear)), \
NAME(name), \ NAME(name), \
INIT_WITH( API_1(M_BOUNDED_STR1NG_INIT_WITH)), \ INIT_WITH( API_1(M_BOUNDED_STR1NG_INIT_WITH)), \
HASH(M_C(name,_hash)), \ HASH(M_F(name,_hash)), \
EQUAL(M_C(name,_equal_p)), \ EQUAL(M_F(name,_equal_p)), \
CMP(M_C(name,_cmp)), \ CMP(M_F(name,_cmp)), \
TYPE(M_C(name,_ct)), \ TYPE(M_F(name,_ct)), \
OOR_EQUAL(M_C(name,_oor_equal_p)), \ OOR_EQUAL(M_F(name,_oor_equal_p)), \
OOR_SET(M_C(name, _oor_set)), \ OOR_SET(M_F(name, _oor_set)), \
PARSE_STR(M_C(name,_parse_str)), \ PARSE_STR(M_F(name,_parse_str)), \
GET_STR(M_C(name,_get_str)), \ GET_STR(M_F(name,_get_str)), \
OUT_STR(M_C(name,_out_str)), \ OUT_STR(M_F(name,_out_str)), \
IN_STR(M_C(name,_in_str)), \ IN_STR(M_F(name,_in_str)), \
OUT_SERIAL(M_C(name,_out_serial)), \ OUT_SERIAL(M_F(name,_out_serial)), \
IN_SERIAL(M_C(name,_in_serial)), \ IN_SERIAL(M_F(name,_in_serial)), \
) )
/************************** INTERNAL ***********************************/ /************************** INTERNAL ***********************************/
@@ -2201,17 +2201,17 @@ namespace m_lib {
#define M_BOUNDED_STR1NG_DEF_P2(name, max_size, bounded_t) \ #define M_BOUNDED_STR1NG_DEF_P2(name, max_size, bounded_t) \
\ \
/* Define of an array with one more to store the final nul char */ \ /* Define of an array with one more to store the final nul char */ \
typedef char M_C(name, _array_t)[max_size+1]; \ typedef char M_F(name, _array_t)[max_size+1]; \
\ \
typedef struct M_C(name, _s) { \ typedef struct M_F(name, _s) { \
char s[max_size+1]; \ char s[max_size+1]; \
} bounded_t[1]; \ } bounded_t[1]; \
\ \
/* Internal types for oplist */ \ /* Internal types for oplist */ \
typedef bounded_t M_C(name, _ct); \ typedef bounded_t M_F(name, _ct); \
\ \
static inline void \ static inline void \
M_C(name, _init)(bounded_t s) \ M_F(name, _init)(bounded_t s) \
{ \ { \
M_ASSERT(s != NULL); \ M_ASSERT(s != NULL); \
M_STATIC_ASSERT(max_size >= 1, M_LIB_INTERNAL, "M*LIB: max_size parameter shall be greater than 0."); \ M_STATIC_ASSERT(max_size >= 1, M_LIB_INTERNAL, "M*LIB: max_size parameter shall be greater than 0."); \
@@ -2221,7 +2221,7 @@ namespace m_lib {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _clear)(bounded_t s) \ M_F(name, _clear)(bounded_t s) \
{ \ { \
M_BOUNDED_STR1NG_CONTRACT(s, max_size); \ M_BOUNDED_STR1NG_CONTRACT(s, max_size); \
/* Make the object illegal to be able to detect use after free */ \ /* Make the object illegal to be able to detect use after free */ \
@@ -2229,7 +2229,7 @@ namespace m_lib {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _reset)(bounded_t s) \ M_F(name, _reset)(bounded_t s) \
{ \ { \
M_BOUNDED_STR1NG_CONTRACT(s, max_size); \ M_BOUNDED_STR1NG_CONTRACT(s, max_size); \
s->s[0] = 0; \ s->s[0] = 0; \
@@ -2237,14 +2237,14 @@ namespace m_lib {
} \ } \
\ \
static inline size_t \ static inline size_t \
M_C(name, _size)(const bounded_t s) \ M_F(name, _size)(const bounded_t s) \
{ \ { \
M_BOUNDED_STR1NG_CONTRACT(s, max_size); \ M_BOUNDED_STR1NG_CONTRACT(s, max_size); \
return strlen(s->s); \ return strlen(s->s); \
} \ } \
\ \
static inline size_t \ static inline size_t \
M_C(name, _capacity)(const bounded_t s) \ M_F(name, _capacity)(const bounded_t s) \
{ \ { \
M_BOUNDED_STR1NG_CONTRACT(s, max_size); \ M_BOUNDED_STR1NG_CONTRACT(s, max_size); \
(void)s; /* unused */ \ (void)s; /* unused */ \
@@ -2252,7 +2252,7 @@ namespace m_lib {
} \ } \
\ \
static inline char \ static inline char \
M_C(name, _get_char)(const bounded_t s, size_t index) \ M_F(name, _get_char)(const bounded_t s, size_t index) \
{ \ { \
M_BOUNDED_STR1NG_CONTRACT(s, max_size); \ M_BOUNDED_STR1NG_CONTRACT(s, max_size); \
M_ASSERT_INDEX(index, max_size); \ M_ASSERT_INDEX(index, max_size); \
@@ -2260,14 +2260,14 @@ namespace m_lib {
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _empty_p)(const bounded_t s) \ M_F(name, _empty_p)(const bounded_t s) \
{ \ { \
M_BOUNDED_STR1NG_CONTRACT(s, max_size); \ M_BOUNDED_STR1NG_CONTRACT(s, max_size); \
return s->s[0] == 0; \ return s->s[0] == 0; \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _set_cstr)(bounded_t s, const char str[]) \ M_F(name, _set_cstr)(bounded_t s, const char str[]) \
{ \ { \
M_BOUNDED_STR1NG_CONTRACT(s, max_size); \ M_BOUNDED_STR1NG_CONTRACT(s, max_size); \
m_core_strncpy(s->s, max_size+1, str, max_size); \ m_core_strncpy(s->s, max_size+1, str, max_size); \
@@ -2276,7 +2276,7 @@ namespace m_lib {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _set_cstrn)(bounded_t s, const char str[], size_t n) \ M_F(name, _set_cstrn)(bounded_t s, const char str[], size_t n) \
{ \ { \
M_BOUNDED_STR1NG_CONTRACT(s, max_size); \ M_BOUNDED_STR1NG_CONTRACT(s, max_size); \
M_ASSERT(str != NULL); \ M_ASSERT(str != NULL); \
@@ -2287,46 +2287,46 @@ namespace m_lib {
} \ } \
\ \
static inline const char * \ static inline const char * \
M_C(name, _get_cstr)(const bounded_t s) \ M_F(name, _get_cstr)(const bounded_t s) \
{ \ { \
M_BOUNDED_STR1NG_CONTRACT(s, max_size); \ M_BOUNDED_STR1NG_CONTRACT(s, max_size); \
return s->s; \ return s->s; \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _set)(bounded_t s, const bounded_t str) \ M_F(name, _set)(bounded_t s, const bounded_t str) \
{ \ { \
M_BOUNDED_STR1NG_CONTRACT(s, max_size); \ M_BOUNDED_STR1NG_CONTRACT(s, max_size); \
M_BOUNDED_STR1NG_CONTRACT(str, max_size); \ M_BOUNDED_STR1NG_CONTRACT(str, max_size); \
M_C(name, _set_cstr)(s, str->s); \ M_F(name, _set_cstr)(s, str->s); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _set_n)(bounded_t s, const bounded_t str, \ M_F(name, _set_n)(bounded_t s, const bounded_t str, \
size_t offset, size_t length) \ size_t offset, size_t length) \
{ \ { \
M_BOUNDED_STR1NG_CONTRACT(s, max_size); \ M_BOUNDED_STR1NG_CONTRACT(s, max_size); \
M_BOUNDED_STR1NG_CONTRACT(str, max_size); \ M_BOUNDED_STR1NG_CONTRACT(str, max_size); \
M_ASSERT_INDEX (offset, max_size+1); \ M_ASSERT_INDEX (offset, max_size+1); \
M_C(name, _set_cstrn)(s, str->s+offset, length); \ M_F(name, _set_cstrn)(s, str->s+offset, length); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _init_set)(bounded_t s, const bounded_t str) \ M_F(name, _init_set)(bounded_t s, const bounded_t str) \
{ \ { \
M_C(name,_init)(s); \ M_F(name,_init)(s); \
M_C(name,_set)(s, str); \ M_F(name,_set)(s, str); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _init_set_cstr)(bounded_t s, const char str[]) \ M_F(name, _init_set_cstr)(bounded_t s, const char str[]) \
{ \ { \
M_C(name,_init)(s); \ M_F(name,_init)(s); \
M_C(name,_set_cstr)(s, str); \ M_F(name,_set_cstr)(s, str); \
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _cat_cstr)(bounded_t s, const char str[]) \ M_F(name, _cat_cstr)(bounded_t s, const char str[]) \
{ \ { \
M_BOUNDED_STR1NG_CONTRACT(s, max_size); \ M_BOUNDED_STR1NG_CONTRACT(s, max_size); \
M_ASSERT (str != NULL); \ M_ASSERT (str != NULL); \
@@ -2335,14 +2335,14 @@ namespace m_lib {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _cat)(bounded_t s, const bounded_t str) \ M_F(name, _cat)(bounded_t s, const bounded_t str) \
{ \ { \
M_BOUNDED_STR1NG_CONTRACT(str, max_size); \ M_BOUNDED_STR1NG_CONTRACT(str, max_size); \
M_C(name, _cat_cstr)(s, str->s); \ M_F(name, _cat_cstr)(s, str->s); \
} \ } \
\ \
static inline int \ static inline int \
M_C(name, _cmp_cstr)(const bounded_t s, const char str[]) \ M_F(name, _cmp_cstr)(const bounded_t s, const char str[]) \
{ \ { \
M_BOUNDED_STR1NG_CONTRACT(s, max_size); \ M_BOUNDED_STR1NG_CONTRACT(s, max_size); \
M_ASSERT(str != NULL); \ M_ASSERT(str != NULL); \
@@ -2350,7 +2350,7 @@ namespace m_lib {
} \ } \
\ \
static inline int \ static inline int \
M_C(name, _cmp)(const bounded_t s, const bounded_t str) \ M_F(name, _cmp)(const bounded_t s, const bounded_t str) \
{ \ { \
M_BOUNDED_STR1NG_CONTRACT(s, max_size); \ M_BOUNDED_STR1NG_CONTRACT(s, max_size); \
M_BOUNDED_STR1NG_CONTRACT(str, max_size); \ M_BOUNDED_STR1NG_CONTRACT(str, max_size); \
@@ -2358,7 +2358,7 @@ namespace m_lib {
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _equal_cstr_p)(const bounded_t s, const char str[]) \ M_F(name, _equal_cstr_p)(const bounded_t s, const char str[]) \
{ \ { \
M_BOUNDED_STR1NG_CONTRACT(s, max_size); \ M_BOUNDED_STR1NG_CONTRACT(s, max_size); \
M_ASSERT(str != NULL); \ M_ASSERT(str != NULL); \
@@ -2366,14 +2366,14 @@ namespace m_lib {
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _equal_p)(const bounded_t s, const bounded_t str) \ M_F(name, _equal_p)(const bounded_t s, const bounded_t str) \
{ \ { \
/* _equal_p may be called in context OOR. So contract cannot be verified */ \ /* _equal_p may be called in context OOR. So contract cannot be verified */ \
return (s->s[max_size] == str->s[max_size]) & (strcmp(s->s, str->s) == 0); \ return (s->s[max_size] == str->s[max_size]) & (strcmp(s->s, str->s) == 0); \
} \ } \
\ \
static inline int \ static inline int \
M_C(name, _printf)(bounded_t s, const char format[], ...) \ M_F(name, _printf)(bounded_t s, const char format[], ...) \
{ \ { \
M_BOUNDED_STR1NG_CONTRACT(s, max_size); \ M_BOUNDED_STR1NG_CONTRACT(s, max_size); \
M_ASSERT(format != NULL); \ M_ASSERT(format != NULL); \
@@ -2386,7 +2386,7 @@ namespace m_lib {
} \ } \
\ \
static inline int \ static inline int \
M_C(name, _cat_printf)(bounded_t s, const char format[], ...) \ M_F(name, _cat_printf)(bounded_t s, const char format[], ...) \
{ \ { \
M_BOUNDED_STR1NG_CONTRACT(s, max_size); \ M_BOUNDED_STR1NG_CONTRACT(s, max_size); \
M_ASSERT(format != NULL); \ M_ASSERT(format != NULL); \
@@ -2401,7 +2401,7 @@ namespace m_lib {
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _fgets)(bounded_t s, FILE *f, m_string_fgets_t arg) \ M_F(name, _fgets)(bounded_t s, FILE *f, m_string_fgets_t arg) \
{ \ { \
M_BOUNDED_STR1NG_CONTRACT(s, max_size); \ M_BOUNDED_STR1NG_CONTRACT(s, max_size); \
M_ASSERT(f != NULL); \ M_ASSERT(f != NULL); \
@@ -2417,7 +2417,7 @@ namespace m_lib {
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _fputs)(FILE *f, const bounded_t s) \ M_F(name, _fputs)(FILE *f, const bounded_t s) \
{ \ { \
M_BOUNDED_STR1NG_CONTRACT(s, max_size); \ M_BOUNDED_STR1NG_CONTRACT(s, max_size); \
M_ASSERT(f != NULL); \ M_ASSERT(f != NULL); \
@@ -2425,7 +2425,7 @@ namespace m_lib {
} \ } \
\ \
static inline size_t \ static inline size_t \
M_C(name, _hash)(const bounded_t s) \ M_F(name, _hash)(const bounded_t s) \
{ \ { \
M_BOUNDED_STR1NG_CONTRACT(s, max_size); \ M_BOUNDED_STR1NG_CONTRACT(s, max_size); \
/* Cannot use m_core_hash: alignment not sufficent */ \ /* Cannot use m_core_hash: alignment not sufficent */ \
@@ -2433,7 +2433,7 @@ namespace m_lib {
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _oor_equal_p)(const bounded_t s, unsigned char n) \ M_F(name, _oor_equal_p)(const bounded_t s, unsigned char n) \
{ \ { \
/* s may be invalid contract */ \ /* s may be invalid contract */ \
M_ASSERT (s != NULL); \ M_ASSERT (s != NULL); \
@@ -2442,7 +2442,7 @@ namespace m_lib {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _oor_set)(bounded_t s, unsigned char n) \ M_F(name, _oor_set)(bounded_t s, unsigned char n) \
{ \ { \
/* s may be invalid contract */ \ /* s may be invalid contract */ \
M_ASSERT (s != NULL); \ M_ASSERT (s != NULL); \
@@ -2451,7 +2451,7 @@ namespace m_lib {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _get_str)(m_string_t v, const bounded_t s, bool append) \ M_F(name, _get_str)(m_string_t v, const bounded_t s, bool append) \
{ \ { \
M_STR1NG_CONTRACT(v); \ M_STR1NG_CONTRACT(v); \
M_BOUNDED_STR1NG_CONTRACT(s, max_size); \ M_BOUNDED_STR1NG_CONTRACT(s, max_size); \
@@ -2465,7 +2465,7 @@ namespace m_lib {
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _out_str)(FILE *f, const bounded_t s) \ M_F(name, _out_str)(FILE *f, const bounded_t s) \
{ \ { \
M_BOUNDED_STR1NG_CONTRACT(s, max_size); \ M_BOUNDED_STR1NG_CONTRACT(s, max_size); \
M_ASSERT(f != NULL); \ M_ASSERT(f != NULL); \
@@ -2479,7 +2479,7 @@ namespace m_lib {
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _in_str)(bounded_t v, FILE *f) \ M_F(name, _in_str)(bounded_t v, FILE *f) \
{ \ { \
M_BOUNDED_STR1NG_CONTRACT(v, max_size); \ M_BOUNDED_STR1NG_CONTRACT(v, max_size); \
M_ASSERT(f != NULL); \ M_ASSERT(f != NULL); \
@@ -2492,7 +2492,7 @@ namespace m_lib {
} \ } \
\ \
static inline bool \ static inline bool \
M_C(name, _parse_str)(bounded_t v, const char str[], const char **endptr) \ M_F(name, _parse_str)(bounded_t v, const char str[], const char **endptr) \
{ \ { \
M_BOUNDED_STR1NG_CONTRACT(v, max_size); \ M_BOUNDED_STR1NG_CONTRACT(v, max_size); \
M_ASSERT(str != NULL); \ M_ASSERT(str != NULL); \
@@ -2505,7 +2505,7 @@ namespace m_lib {
} \ } \
\ \
static inline m_serial_return_code_t \ static inline m_serial_return_code_t \
M_C(name, _out_serial)(m_serial_write_t serial, const bounded_t v) \ M_F(name, _out_serial)(m_serial_write_t serial, const bounded_t v) \
{ \ { \
M_BOUNDED_STR1NG_CONTRACT(v, max_size); \ M_BOUNDED_STR1NG_CONTRACT(v, max_size); \
M_ASSERT (serial != NULL && serial->m_interface != NULL); \ M_ASSERT (serial != NULL && serial->m_interface != NULL); \
@@ -2513,7 +2513,7 @@ namespace m_lib {
} \ } \
\ \
static inline m_serial_return_code_t \ static inline m_serial_return_code_t \
M_C(name, _in_serial)(bounded_t v, m_serial_read_t serial) \ M_F(name, _in_serial)(bounded_t v, m_serial_read_t serial) \
{ \ { \
M_BOUNDED_STR1NG_CONTRACT(v, max_size); \ M_BOUNDED_STR1NG_CONTRACT(v, max_size); \
M_ASSERT (serial != NULL && serial->m_interface != NULL); \ M_ASSERT (serial != NULL && serial->m_interface != NULL); \
@@ -2535,7 +2535,7 @@ namespace m_lib {
See above */ See above */
#ifndef __cplusplus #ifndef __cplusplus
#define M_BOUNDED_STRING_CTE(name, string) \ #define M_BOUNDED_STRING_CTE(name, string) \
((const struct M_C(name, _s) *)((M_C(name, _array_t)){string})) ((const struct M_F(name, _s) *)((M_F(name, _array_t)){string}))
#else #else
namespace m_lib { namespace m_lib {
template <unsigned int N> template <unsigned int N>
@@ -2549,7 +2549,7 @@ namespace m_lib {
}; };
} }
#define M_BOUNDED_STRING_CTE(name, string) \ #define M_BOUNDED_STRING_CTE(name, string) \
((const struct M_C(name, _s) *)(m_lib::m_bounded_string<sizeof (M_C(name, _t))>(string).s)) ((const struct M_F(name, _s) *)(m_lib::m_bounded_string<sizeof (M_F(name, _t))>(string).s))
#endif #endif
+201 -201
View File
File diff suppressed because it is too large. Load diff
+60 -60
View File
@@ -31,7 +31,7 @@
USAGE: USAGE:
TUPLE_DEF2(name, [(field1, type1[, oplist1]), (field2, type2[, oplist2]), ...] ) */ TUPLE_DEF2(name, [(field1, type1[, oplist1]), (field2, type2[, oplist2]), ...] ) */
#define M_TUPLE_DEF2(name, ...) \ #define M_TUPLE_DEF2(name, ...) \
M_TUPLE_DEF2_AS(name, M_C(name,_t), __VA_ARGS__) M_TUPLE_DEF2_AS(name, M_F(name,_t), __VA_ARGS__)
/* Define the tuple type and functions /* Define the tuple type and functions
@@ -151,7 +151,7 @@ namespace m_lib {
M_TUPL3_IF_ALL(RESET, __VA_ARGS__)(M_TUPL3_DEFINE_RESET(name, __VA_ARGS__),) M_TUPL3_IF_ALL(RESET, __VA_ARGS__)(M_TUPL3_DEFINE_RESET(name, __VA_ARGS__),)
/* Provide order for _cmp_order */ /* Provide order for _cmp_order */
#define M_TUPL3_ORDER_CONVERT(name, x) M_C(name, M_C(M_TUPL3_ORDER_CONVERT_, x)) #define M_TUPL3_ORDER_CONVERT(name, x) M_F(name, M_C(M_TUPL3_ORDER_CONVERT_, x))
#define M_TUPL3_ORDER_CONVERT_ASC(x) M_C3(_,x,_value) #define M_TUPL3_ORDER_CONVERT_ASC(x) M_C3(_,x,_value)
#define M_TUPL3_ORDER_CONVERT_DSC(x) M_C3(_,x,_value)*-1 #define M_TUPL3_ORDER_CONVERT_DSC(x) M_C3(_,x,_value)*-1
@@ -201,14 +201,14 @@ namespace m_lib {
/* Define the type of a tuple */ /* Define the type of a tuple */
#define M_TUPL3_DEFINE_TYPE(name, name_t, ...) \ #define M_TUPL3_DEFINE_TYPE(name, name_t, ...) \
typedef struct M_C(name, _s) { \ typedef struct M_F(name, _s) { \
M_MAP(M_TUPL3_DEFINE_RECUR_TYPE_ELE , __VA_ARGS__) \ M_MAP(M_TUPL3_DEFINE_RECUR_TYPE_ELE , __VA_ARGS__) \
} name_t[1]; \ } name_t[1]; \
\ \
typedef struct M_C(name, _s) *M_C(name, _ptr); \ typedef struct M_F(name, _s) *M_F(name, _ptr); \
typedef const struct M_C(name, _s) *M_C(name, _srcptr); \ typedef const struct M_F(name, _s) *M_F(name, _srcptr); \
/* Define internal type for oplist */ \ /* Define internal type for oplist */ \
typedef name_t M_C(name, _ct); \ typedef name_t M_F(name, _ct); \
/* Save constant as the number of arguments (internal) */ \ /* Save constant as the number of arguments (internal) */ \
typedef enum { \ typedef enum { \
M_C3(m_tupl3_, name, _num_args) = M_NARGS(__VA_ARGS__) \ M_C3(m_tupl3_, name, _num_args) = M_NARGS(__VA_ARGS__) \
@@ -225,9 +225,9 @@ namespace m_lib {
/* Define the basic enumerate, identifying a parameter */ /* Define the basic enumerate, identifying a parameter */
#define M_TUPL3_DEFINE_ENUM(name, ...) \ #define M_TUPL3_DEFINE_ENUM(name, ...) \
typedef enum { \ typedef enum { \
M_C(name, _first_one_val), \ M_F(name, _first_one_val), \
M_MAP2_C(M_TUPL3_DEFINE_ENUM_ELE , name, __VA_ARGS__) \ M_MAP2_C(M_TUPL3_DEFINE_ENUM_ELE , name, __VA_ARGS__) \
} M_C(name,_field_e); } M_F(name,_field_e);
#define M_TUPL3_DEFINE_ENUM_ELE(name, a) \ #define M_TUPL3_DEFINE_ENUM_ELE(name, a) \
M_C4(name, _, M_TUPL3_GET_FIELD a, _value) M_C4(name, _, M_TUPL3_GET_FIELD a, _value)
@@ -242,7 +242,7 @@ namespace m_lib {
/* Define the INIT method calling the INIT method for all params */ /* Define the INIT method calling the INIT method for all params */
#define M_TUPL3_DEFINE_INIT(name, ...) \ #define M_TUPL3_DEFINE_INIT(name, ...) \
static inline void M_C(name, _init)(M_C(name,_ct) my) { \ static inline void M_F(name, _init)(M_F(name,_ct) my) { \
M_MAP(M_TUPL3_DEFINE_INIT_FUNC , __VA_ARGS__) \ M_MAP(M_TUPL3_DEFINE_INIT_FUNC , __VA_ARGS__) \
} }
@@ -251,7 +251,7 @@ namespace m_lib {
/* Define the INIT_SET method calling the INIT_SET method for all params */ /* Define the INIT_SET method calling the INIT_SET method for all params */
#define M_TUPL3_DEFINE_INIT_SET(name, ...) \ #define M_TUPL3_DEFINE_INIT_SET(name, ...) \
static inline void M_C(name, _init_set)(M_C(name,_ct) my , M_C(name,_ct) const org) { \ static inline void M_F(name, _init_set)(M_F(name,_ct) my , M_F(name,_ct) const org) { \
M_TUPL3_CONTRACT(org); \ M_TUPL3_CONTRACT(org); \
M_MAP(M_TUPL3_DEFINE_INIT_SET_FUNC , __VA_ARGS__) \ M_MAP(M_TUPL3_DEFINE_INIT_SET_FUNC , __VA_ARGS__) \
} }
@@ -260,7 +260,7 @@ namespace m_lib {
/* Define the INIT_WITH method calling the INIT_SET method for all params. */ /* Define the INIT_WITH method calling the INIT_SET method for all params. */
#define M_TUPL3_DEFINE_INIT_SET2(name, ...) \ #define M_TUPL3_DEFINE_INIT_SET2(name, ...) \
static inline void M_C(name, _init_emplace)(M_C(name,_ct) my \ static inline void M_F(name, _init_emplace)(M_F(name,_ct) my \
M_MAP(M_TUPL3_DEFINE_INIT_SET2_PROTO, __VA_ARGS__) \ M_MAP(M_TUPL3_DEFINE_INIT_SET2_PROTO, __VA_ARGS__) \
) { \ ) { \
M_MAP(M_TUPL3_DEFINE_INIT_SET2_FUNC , __VA_ARGS__) \ M_MAP(M_TUPL3_DEFINE_INIT_SET2_FUNC , __VA_ARGS__) \
@@ -275,8 +275,8 @@ namespace m_lib {
/* Define the SET method calling the SET method for all params. */ /* Define the SET method calling the SET method for all params. */
#define M_TUPL3_DEFINE_SET(name, ...) \ #define M_TUPL3_DEFINE_SET(name, ...) \
static inline void M_C(name, _set)(M_C(name,_ct) my , \ static inline void M_F(name, _set)(M_F(name,_ct) my , \
M_C(name,_ct) const org) { \ M_F(name,_ct) const org) { \
M_TUPL3_CONTRACT(my); \ M_TUPL3_CONTRACT(my); \
M_TUPL3_CONTRACT(org); \ M_TUPL3_CONTRACT(org); \
M_MAP(M_TUPL3_DEFINE_SET_FUNC , __VA_ARGS__) \ M_MAP(M_TUPL3_DEFINE_SET_FUNC , __VA_ARGS__) \
@@ -288,7 +288,7 @@ namespace m_lib {
/* Define the SET_WITH method calling the SET method for all params. */ /* Define the SET_WITH method calling the SET method for all params. */
#define M_TUPL3_DEFINE_SET2(name, ...) \ #define M_TUPL3_DEFINE_SET2(name, ...) \
static inline void M_C(name, _emplace)(M_C(name,_ct) my \ static inline void M_F(name, _emplace)(M_F(name,_ct) my \
M_MAP(M_TUPL3_DEFINE_SET2_PROTO, __VA_ARGS__) \ M_MAP(M_TUPL3_DEFINE_SET2_PROTO, __VA_ARGS__) \
) { \ ) { \
M_TUPL3_CONTRACT(my); \ M_TUPL3_CONTRACT(my); \
@@ -303,7 +303,7 @@ namespace m_lib {
/* Define the CLEAR method calling the CLEAR method for all params. */ /* Define the CLEAR method calling the CLEAR method for all params. */
#define M_TUPL3_DEFINE_CLEAR(name, ...) \ #define M_TUPL3_DEFINE_CLEAR(name, ...) \
static inline void M_C(name, _clear)(M_C(name,_ct) my) { \ static inline void M_F(name, _clear)(M_F(name,_ct) my) { \
M_TUPL3_CONTRACT(my); \ M_TUPL3_CONTRACT(my); \
M_MAP(M_TUPL3_DEFINE_CLEAR_FUNC , __VA_ARGS__) \ M_MAP(M_TUPL3_DEFINE_CLEAR_FUNC , __VA_ARGS__) \
} }
@@ -318,18 +318,18 @@ namespace m_lib {
#define M_TUPL3_DEFINE_GETTER_FIELD_PROTO(name, num, a) \ #define M_TUPL3_DEFINE_GETTER_FIELD_PROTO(name, num, a) \
static inline M_TUPL3_GET_TYPE a * M_C3(name, _get_at_, M_TUPL3_GET_FIELD a) \ static inline M_TUPL3_GET_TYPE a * M_C3(name, _get_at_, M_TUPL3_GET_FIELD a) \
(M_C(name,_ct) my) { \ (M_F(name,_ct) my) { \
M_TUPL3_CONTRACT(my); \ M_TUPL3_CONTRACT(my); \
return &(my->M_TUPL3_GET_FIELD a); \ return &(my->M_TUPL3_GET_FIELD a); \
} \ } \
static inline M_TUPL3_GET_TYPE a const * M_C3(name, _cget_at_, M_TUPL3_GET_FIELD a) \ static inline M_TUPL3_GET_TYPE a const * M_C3(name, _cget_at_, M_TUPL3_GET_FIELD a) \
(M_C(name,_ct) const my) { \ (M_F(name,_ct) const my) { \
M_TUPL3_CONTRACT(my); \ M_TUPL3_CONTRACT(my); \
return &(my->M_TUPL3_GET_FIELD a); \ return &(my->M_TUPL3_GET_FIELD a); \
} \ } \
/* Same but uses numerical index for accessing the field (internal) */ \ /* Same but uses numerical index for accessing the field (internal) */ \
static inline M_TUPL3_GET_TYPE a * M_C4(m_tupl3_, name, _get_at_, num) \ static inline M_TUPL3_GET_TYPE a * M_C4(m_tupl3_, name, _get_at_, num) \
(M_C(name,_ct) my) { \ (M_F(name,_ct) my) { \
return &(my->M_TUPL3_GET_FIELD a); \ return &(my->M_TUPL3_GET_FIELD a); \
} \ } \
@@ -340,7 +340,7 @@ namespace m_lib {
#define M_TUPL3_DEFINE_SETTER_FIELD_PROTO(name, a) \ #define M_TUPL3_DEFINE_SETTER_FIELD_PROTO(name, a) \
static inline void M_C3(name, _set_, M_TUPL3_GET_FIELD a) \ static inline void M_C3(name, _set_, M_TUPL3_GET_FIELD a) \
(M_C(name,_ct) my, M_TUPL3_GET_TYPE a const M_TUPL3_GET_FIELD a) { \ (M_F(name,_ct) my, M_TUPL3_GET_TYPE a const M_TUPL3_GET_FIELD a) { \
M_TUPL3_CONTRACT(my); \ M_TUPL3_CONTRACT(my); \
M_TUPL3_CALL_SET(a, my ->M_TUPL3_GET_FIELD a, M_TUPL3_GET_FIELD a); \ M_TUPL3_CALL_SET(a, my ->M_TUPL3_GET_FIELD a, M_TUPL3_GET_FIELD a); \
} }
@@ -348,8 +348,8 @@ namespace m_lib {
/* Define the CMP method by calling CMP methods for all params. */ /* Define the CMP method by calling CMP methods for all params. */
#define M_TUPL3_DEFINE_CMP(name, ...) \ #define M_TUPL3_DEFINE_CMP(name, ...) \
static inline int M_C(name, _cmp)(M_C(name,_ct) const e1 , \ static inline int M_F(name, _cmp)(M_F(name,_ct) const e1 , \
M_C(name,_ct) const e2) { \ M_F(name,_ct) const e2) { \
int i; \ int i; \
M_TUPL3_CONTRACT(e1); \ M_TUPL3_CONTRACT(e1); \
M_TUPL3_CONTRACT(e2); \ M_TUPL3_CONTRACT(e2); \
@@ -369,8 +369,8 @@ namespace m_lib {
FIXME: All oplists shall define the CMP operator or at least one? FIXME: All oplists shall define the CMP operator or at least one?
*/ */
#define M_TUPL3_DEFINE_CMP_ORDER(name, ...) \ #define M_TUPL3_DEFINE_CMP_ORDER(name, ...) \
static inline int M_C(name, _cmp_order)(M_C(name,_ct) const e1 , \ static inline int M_F(name, _cmp_order)(M_F(name,_ct) const e1 , \
M_C(name,_ct) const e2, \ M_F(name,_ct) const e2, \
const int order[]) { \ const int order[]) { \
int i, r; \ int i, r; \
M_TUPL3_CONTRACT(e1); \ M_TUPL3_CONTRACT(e1); \
@@ -403,8 +403,8 @@ namespace m_lib {
) )
#define M_TUPL3_DEFINE_CMP_FIELD_FUNC(name, field, func_cmp, oplist) \ #define M_TUPL3_DEFINE_CMP_FIELD_FUNC(name, field, func_cmp, oplist) \
static inline int M_C3(name, _cmp_, field)(M_C(name,_ct) const e1 , \ static inline int M_C3(name, _cmp_, field)(M_F(name,_ct) const e1 , \
M_C(name,_ct) const e2) { \ M_F(name,_ct) const e2) { \
M_TUPL3_CONTRACT(e1); \ M_TUPL3_CONTRACT(e1); \
M_TUPL3_CONTRACT(e2); \ M_TUPL3_CONTRACT(e2); \
return M_APPLY_API(func_cmp, oplist, e1 -> field , e2 -> field ); \ return M_APPLY_API(func_cmp, oplist, e1 -> field , e2 -> field ); \
@@ -413,8 +413,8 @@ namespace m_lib {
/* Define a EQUAL method by calling the EQUAL methods for all params */ /* Define a EQUAL method by calling the EQUAL methods for all params */
#define M_TUPL3_DEFINE_EQUAL(name, ...) \ #define M_TUPL3_DEFINE_EQUAL(name, ...) \
static inline bool M_C(name, _equal_p)(M_C(name,_ct) const e1 , \ static inline bool M_F(name, _equal_p)(M_F(name,_ct) const e1 , \
M_C(name,_ct) const e2) { \ M_F(name,_ct) const e2) { \
bool b; \ bool b; \
M_TUPL3_CONTRACT(e1); \ M_TUPL3_CONTRACT(e1); \
M_TUPL3_CONTRACT(e2); \ M_TUPL3_CONTRACT(e2); \
@@ -431,7 +431,7 @@ namespace m_lib {
/* Define a HASH method by calling the HASH methods for all params */ /* Define a HASH method by calling the HASH methods for all params */
#define M_TUPL3_DEFINE_HASH(name, ...) \ #define M_TUPL3_DEFINE_HASH(name, ...) \
static inline size_t M_C(name, _hash)(M_C(name,_ct) const e1) { \ static inline size_t M_F(name, _hash)(M_F(name,_ct) const e1) { \
M_TUPL3_CONTRACT(e1); \ M_TUPL3_CONTRACT(e1); \
M_HASH_DECL(hash); \ M_HASH_DECL(hash); \
M_MAP(M_TUPL3_DEFINE_HASH_FUNC_P0, __VA_ARGS__) \ M_MAP(M_TUPL3_DEFINE_HASH_FUNC_P0, __VA_ARGS__) \
@@ -446,8 +446,8 @@ namespace m_lib {
/* Define a GET_STR method by calling the GET_STR methods for all params */ /* Define a GET_STR method by calling the GET_STR methods for all params */
#define M_TUPL3_DEFINE_GET_STR(name, ...) \ #define M_TUPL3_DEFINE_GET_STR(name, ...) \
static inline void M_C(name, _get_str)(m_string_t str, \ static inline void M_F(name, _get_str)(m_string_t str, \
M_C(name,_ct) const el, \ M_F(name,_ct) const el, \
bool append) { \ bool append) { \
bool comma = false; \ bool comma = false; \
M_TUPL3_CONTRACT(el); \ M_TUPL3_CONTRACT(el); \
@@ -465,8 +465,8 @@ namespace m_lib {
/* Define a OUT_STR method by calling the OUT_STR methods for all params */ /* Define a OUT_STR method by calling the OUT_STR methods for all params */
#define M_TUPL3_DEFINE_OUT_STR(name, ...) \ #define M_TUPL3_DEFINE_OUT_STR(name, ...) \
static inline void M_C(name, _out_str)(FILE *f, \ static inline void M_F(name, _out_str)(FILE *f, \
M_C(name,_ct) const el) { \ M_F(name,_ct) const el) { \
bool comma = false; \ bool comma = false; \
M_TUPL3_CONTRACT(el); \ M_TUPL3_CONTRACT(el); \
M_ASSERT (f != NULL); \ M_ASSERT (f != NULL); \
@@ -483,7 +483,7 @@ namespace m_lib {
/* Define a IN_STR method by calling the IN_STR methods for all params */ /* Define a IN_STR method by calling the IN_STR methods for all params */
#define M_TUPL3_DEFINE_IN_STR(name, ...) \ #define M_TUPL3_DEFINE_IN_STR(name, ...) \
static inline bool M_C(name, _in_str)(M_C(name,_ct) el, FILE *f) { \ static inline bool M_F(name, _in_str)(M_F(name,_ct) el, FILE *f) { \
bool comma = false; \ bool comma = false; \
M_TUPL3_CONTRACT(el); \ M_TUPL3_CONTRACT(el); \
M_ASSERT (f != NULL); \ M_ASSERT (f != NULL); \
@@ -506,7 +506,7 @@ namespace m_lib {
/* Define a PARSE_STR method by calling the PARSE_STR methods for all params */ /* Define a PARSE_STR method by calling the PARSE_STR methods for all params */
#define M_TUPL3_DEFINE_PARSE_STR(name, ...) \ #define M_TUPL3_DEFINE_PARSE_STR(name, ...) \
static inline bool M_C(name, _parse_str)(M_C(name,_ct) el, \ static inline bool M_F(name, _parse_str)(M_F(name,_ct) el, \
const char str[], \ const char str[], \
const char **endptr) { \ const char **endptr) { \
M_TUPL3_CONTRACT(el); \ M_TUPL3_CONTRACT(el); \
@@ -541,8 +541,8 @@ namespace m_lib {
/* Define a OUT_SERIAL method by calling the OUT_SERIAL methods for all params */ /* Define a OUT_SERIAL method by calling the OUT_SERIAL methods for all params */
#define M_TUPL3_DEFINE_OUT_SERIAL(name, ...) \ #define M_TUPL3_DEFINE_OUT_SERIAL(name, ...) \
static inline m_serial_return_code_t \ static inline m_serial_return_code_t \
M_C(name, _out_serial)(m_serial_write_t f, \ M_F(name, _out_serial)(m_serial_write_t f, \
M_C(name,_ct) const el) { \ M_F(name,_ct) const el) { \
M_TUPL3_CONTRACT(el); \ M_TUPL3_CONTRACT(el); \
M_ASSERT (f != NULL && f->m_interface != NULL); \ M_ASSERT (f != NULL && f->m_interface != NULL); \
const int field_max = M_NARGS(__VA_ARGS__); \ const int field_max = M_NARGS(__VA_ARGS__); \
@@ -568,7 +568,7 @@ namespace m_lib {
/* Define a IN_SERIAL method by calling the IN_SERIAL methods for all params */ /* Define a IN_SERIAL method by calling the IN_SERIAL methods for all params */
#define M_TUPL3_DEFINE_IN_SERIAL(name, ...) \ #define M_TUPL3_DEFINE_IN_SERIAL(name, ...) \
static inline m_serial_return_code_t \ static inline m_serial_return_code_t \
M_C(name, _in_serial)(M_C(name,_ct) el, m_serial_read_t f) { \ M_F(name, _in_serial)(M_F(name,_ct) el, m_serial_read_t f) { \
M_TUPL3_CONTRACT(el); \ M_TUPL3_CONTRACT(el); \
M_ASSERT (f != NULL && f->m_interface != NULL); \ M_ASSERT (f != NULL && f->m_interface != NULL); \
int index = -1; \ int index = -1; \
@@ -600,7 +600,7 @@ namespace m_lib {
/* Define a INIT_MOVE method by calling the INIT_MOVE methods for all params */ /* Define a INIT_MOVE method by calling the INIT_MOVE methods for all params */
#define M_TUPL3_DEFINE_INIT_MOVE(name, ...) \ #define M_TUPL3_DEFINE_INIT_MOVE(name, ...) \
static inline void M_C(name, _init_move)(M_C(name,_ct) el, M_C(name,_ct) org) { \ static inline void M_F(name, _init_move)(M_F(name,_ct) el, M_F(name,_ct) org) { \
M_TUPL3_CONTRACT(el); \ M_TUPL3_CONTRACT(el); \
M_MAP(M_TUPL3_DEFINE_INIT_MOVE_FUNC , __VA_ARGS__) \ M_MAP(M_TUPL3_DEFINE_INIT_MOVE_FUNC , __VA_ARGS__) \
} }
@@ -611,7 +611,7 @@ namespace m_lib {
/* Define a MOVE method by calling the MOVE methods for all params */ /* Define a MOVE method by calling the MOVE methods for all params */
#define M_TUPL3_DEFINE_MOVE(name, ...) \ #define M_TUPL3_DEFINE_MOVE(name, ...) \
static inline void M_C(name, _move)(M_C(name,_ct) el, M_C(name,_ct) org) { \ static inline void M_F(name, _move)(M_F(name,_ct) el, M_F(name,_ct) org) { \
M_TUPL3_CONTRACT(el); \ M_TUPL3_CONTRACT(el); \
M_MAP(M_TUPL3_DEFINE_MOVE_FUNC , __VA_ARGS__) \ M_MAP(M_TUPL3_DEFINE_MOVE_FUNC , __VA_ARGS__) \
} }
@@ -622,7 +622,7 @@ namespace m_lib {
/* Define a SWAP method by calling the SWAP methods for all params */ /* Define a SWAP method by calling the SWAP methods for all params */
#define M_TUPL3_DEFINE_SWAP(name, ...) \ #define M_TUPL3_DEFINE_SWAP(name, ...) \
static inline void M_C(name, _swap)(M_C(name,_ct) el1, M_C(name,_ct) el2) { \ static inline void M_F(name, _swap)(M_F(name,_ct) el1, M_F(name,_ct) el2) { \
M_TUPL3_CONTRACT(el1); \ M_TUPL3_CONTRACT(el1); \
M_TUPL3_CONTRACT(el2); \ M_TUPL3_CONTRACT(el2); \
M_MAP(M_TUPL3_DEFINE_SWAP_FUNC , __VA_ARGS__) \ M_MAP(M_TUPL3_DEFINE_SWAP_FUNC , __VA_ARGS__) \
@@ -634,7 +634,7 @@ namespace m_lib {
/* Define a RESET method by calling the RESET methods for all params */ /* Define a RESET method by calling the RESET methods for all params */
#define M_TUPL3_DEFINE_RESET(name, ...) \ #define M_TUPL3_DEFINE_RESET(name, ...) \
static inline void M_C(name, _reset)(M_C(name,_ct) el1) { \ static inline void M_F(name, _reset)(M_F(name,_ct) el1) { \
M_TUPL3_CONTRACT(el1); \ M_TUPL3_CONTRACT(el1); \
M_MAP(M_TUPL3_DEFINE_RESET_FUNC , __VA_ARGS__) \ M_MAP(M_TUPL3_DEFINE_RESET_FUNC , __VA_ARGS__) \
} \ } \
@@ -671,7 +671,7 @@ namespace m_lib {
M_IF(M_NOTEQUAL( M_NARGS oplist_arglist, M_NARGS (__VA_ARGS__))) \ M_IF(M_NOTEQUAL( M_NARGS oplist_arglist, M_NARGS (__VA_ARGS__))) \
(M_TUPL3_INIT_WITH_P1_FUNC, M_TUPL3_INIT_WITH_P1_MACRO)(name, oplist_arglist, dest, __VA_ARGS__) (M_TUPL3_INIT_WITH_P1_FUNC, M_TUPL3_INIT_WITH_P1_MACRO)(name, oplist_arglist, dest, __VA_ARGS__)
#define M_TUPL3_INIT_WITH_P1_FUNC(name, oplist_arglist, dest, ...) \ #define M_TUPL3_INIT_WITH_P1_FUNC(name, oplist_arglist, dest, ...) \
M_C(name, _init_emplace)(dest, __VA_ARGS__) M_F(name, _init_emplace)(dest, __VA_ARGS__)
#define M_TUPL3_INIT_WITH_P1_MACRO(name, oplist_arglist, dest, ...) \ #define M_TUPL3_INIT_WITH_P1_MACRO(name, oplist_arglist, dest, ...) \
( M_STATIC_ASSERT( M_NARGS oplist_arglist == M_C3(m_tupl3_, name, _num_args), M_LIB_DIMENSION_ERROR, "The number of oplists given to TUPLE_OPLIST don't match the number of oplists used to create the tuple." ), \ ( M_STATIC_ASSERT( M_NARGS oplist_arglist == M_C3(m_tupl3_, name, _num_args), M_LIB_DIMENSION_ERROR, "The number of oplists given to TUPLE_OPLIST don't match the number of oplists used to create the tuple." ), \
M_STATIC_ASSERT( M_NARGS(__VA_ARGS__) == M_C3(m_tupl3_, name, _num_args), M_LIB_DIMENSION_ERROR, "Missing / Too many arguments for tuple"), \ M_STATIC_ASSERT( M_NARGS(__VA_ARGS__) == M_C3(m_tupl3_, name, _num_args), M_LIB_DIMENSION_ERROR, "Missing / Too many arguments for tuple"), \
@@ -721,27 +721,27 @@ namespace m_lib {
/* Define the TUPLE oplist */ /* Define the TUPLE oplist */
#define M_TUPL3_OPLIST_P3(name, ...) \ #define M_TUPL3_OPLIST_P3(name, ...) \
(M_IF_METHOD_ALL(INIT, __VA_ARGS__)(INIT(M_C(name,_init)),), \ (M_IF_METHOD_ALL(INIT, __VA_ARGS__)(INIT(M_F(name,_init)),), \
INIT_SET(M_C(name, _init_set)), \ INIT_SET(M_F(name, _init_set)), \
INIT_WITH(API_1(M_TUPL3_INIT_WITH)), \ INIT_WITH(API_1(M_TUPL3_INIT_WITH)), \
SET(M_C(name,_set)), \ SET(M_F(name,_set)), \
CLEAR(M_C(name, _clear)), \ CLEAR(M_F(name, _clear)), \
NAME(name), \ NAME(name), \
TYPE(M_C(name,_ct)), \ TYPE(M_F(name,_ct)), \
OPLIST( (__VA_ARGS__) ), \ OPLIST( (__VA_ARGS__) ), \
M_IF_METHOD_ALL(CMP, __VA_ARGS__)(CMP(M_C(name, _cmp)),), \ M_IF_METHOD_ALL(CMP, __VA_ARGS__)(CMP(M_F(name, _cmp)),), \
M_IF_METHOD_ALL(HASH, __VA_ARGS__)(HASH(M_C(name, _hash)),), \ M_IF_METHOD_ALL(HASH, __VA_ARGS__)(HASH(M_F(name, _hash)),), \
M_IF_METHOD_ALL(EQUAL, __VA_ARGS__)(EQUAL(M_C(name, _equal_p)),), \ M_IF_METHOD_ALL(EQUAL, __VA_ARGS__)(EQUAL(M_F(name, _equal_p)),), \
M_IF_METHOD_ALL(GET_STR, __VA_ARGS__)(GET_STR(M_C(name, _get_str)),), \ M_IF_METHOD_ALL(GET_STR, __VA_ARGS__)(GET_STR(M_F(name, _get_str)),), \
M_IF_METHOD_ALL(PARSE_STR, __VA_ARGS__)(PARSE_STR(M_C(name, _parse_str)),), \ M_IF_METHOD_ALL(PARSE_STR, __VA_ARGS__)(PARSE_STR(M_F(name, _parse_str)),), \
M_IF_METHOD_ALL(IN_STR, __VA_ARGS__)(IN_STR(M_C(name, _in_str)),), \ M_IF_METHOD_ALL(IN_STR, __VA_ARGS__)(IN_STR(M_F(name, _in_str)),), \
M_IF_METHOD_ALL(OUT_STR, __VA_ARGS__)(OUT_STR(M_C(name, _out_str)),), \ M_IF_METHOD_ALL(OUT_STR, __VA_ARGS__)(OUT_STR(M_F(name, _out_str)),), \
M_IF_METHOD_ALL(IN_SERIAL, __VA_ARGS__)(IN_SERIAL(M_C(name, _in_serial)),), \ M_IF_METHOD_ALL(IN_SERIAL, __VA_ARGS__)(IN_SERIAL(M_F(name, _in_serial)),), \
M_IF_METHOD_ALL(OUT_SERIAL, __VA_ARGS__)(OUT_SERIAL(M_C(name, _out_serial)),), \ M_IF_METHOD_ALL(OUT_SERIAL, __VA_ARGS__)(OUT_SERIAL(M_F(name, _out_serial)),), \
M_IF_METHOD_ALL(INIT_MOVE, __VA_ARGS__)(INIT_MOVE(M_C(name, _init_move)),), \ M_IF_METHOD_ALL(INIT_MOVE, __VA_ARGS__)(INIT_MOVE(M_F(name, _init_move)),), \
M_IF_METHOD_ALL(MOVE, __VA_ARGS__)(MOVE(M_C(name, _move)),), \ M_IF_METHOD_ALL(MOVE, __VA_ARGS__)(MOVE(M_F(name, _move)),), \
M_IF_METHOD_ALL(SWAP, __VA_ARGS__)(SWAP(M_C(name, _swap)),), \ M_IF_METHOD_ALL(SWAP, __VA_ARGS__)(SWAP(M_F(name, _swap)),), \
M_IF_METHOD_ALL(RESET, __VA_ARGS__)(RESET(M_C(name, _reset)),), \ M_IF_METHOD_ALL(RESET, __VA_ARGS__)(RESET(M_F(name, _reset)),), \
M_IF_METHOD(NEW, M_RET_ARG1(__VA_ARGS__,))(NEW(M_DELAY2(M_GET_NEW) M_RET_ARG1(__VA_ARGS__,)),), \ M_IF_METHOD(NEW, M_RET_ARG1(__VA_ARGS__,))(NEW(M_DELAY2(M_GET_NEW) M_RET_ARG1(__VA_ARGS__,)),), \
M_IF_METHOD(REALLOC, M_RET_ARG1(__VA_ARGS__,))(REALLOC(M_DELAY2(M_GET_REALLOC) M_RET_ARG1(__VA_ARGS__,)),), \ M_IF_METHOD(REALLOC, M_RET_ARG1(__VA_ARGS__,))(REALLOC(M_DELAY2(M_GET_REALLOC) M_RET_ARG1(__VA_ARGS__,)),), \
M_IF_METHOD(DEL, M_RET_ARG1(__VA_ARGS__,))(DEL(M_DELAY2(M_GET_DEL) M_RET_ARG1(__VA_ARGS__,)),), \ M_IF_METHOD(DEL, M_RET_ARG1(__VA_ARGS__,))(DEL(M_DELAY2(M_GET_DEL) M_RET_ARG1(__VA_ARGS__,)),), \
+102 -102
View File
@@ -31,7 +31,7 @@
USAGE: USAGE:
VARIANT_DEF2(name, [(field1, type1, oplist1), (field2, type2, oplist2), ...] ) */ VARIANT_DEF2(name, [(field1, type1, oplist1), (field2, type2, oplist2), ...] ) */
#define M_VARIANT_DEF2(name, ...) \ #define M_VARIANT_DEF2(name, ...) \
M_VARIANT_DEF2_AS(name, M_C(name,_t), __VA_ARGS__) M_VARIANT_DEF2_AS(name, M_F(name,_t), __VA_ARGS__)
/* Define the variant type and functions /* Define the variant type and functions
@@ -59,8 +59,8 @@
/* Contract of a variant. */ /* Contract of a variant. */
#define M_VAR1ANT_CONTRACT(name, my) do { \ #define M_VAR1ANT_CONTRACT(name, my) do { \
M_ASSERT(my != NULL); \ M_ASSERT(my != NULL); \
M_ASSERT(my->type >= M_C(name, _EMPTY)); \ M_ASSERT(my->type >= M_F(name, _EMPTY)); \
M_ASSERT(my->type <= (enum M_C(name, _enum)) M_C(name, _MAX_TYPE)); \ M_ASSERT(my->type <= (enum M_F(name, _enum)) M_F(name, _MAX_TYPE)); \
} while (0) } while (0)
/* Inject the oplist within the list of arguments */ /* Inject the oplist within the list of arguments */
@@ -181,25 +181,25 @@
/* Define the type */ /* Define the type */
#define M_VAR1ANT_DEFINE_TYPE(name, name_t, ...) \ #define M_VAR1ANT_DEFINE_TYPE(name, name_t, ...) \
/* Define enum of all types of the variant */ \ /* Define enum of all types of the variant */ \
enum M_C(name, _enum) { M_C(name, _EMPTY) \ enum M_F(name, _enum) { M_F(name, _EMPTY) \
M_MAP2(M_VAR1ANT_DEFINE_UNION_ELE, name, __VA_ARGS__) \ M_MAP2(M_VAR1ANT_DEFINE_UNION_ELE, name, __VA_ARGS__) \
}; \ }; \
/* Define enum equal to the number of types of the variant */ \ /* Define enum equal to the number of types of the variant */ \
enum M_C(name, _enum_max) { \ enum M_F(name, _enum_max) { \
M_C(name, _MAX_TYPE) = M_NARGS(__VA_ARGS__) \ M_F(name, _MAX_TYPE) = M_NARGS(__VA_ARGS__) \
}; \ }; \
/* Define the variant */ \ /* Define the variant */ \
typedef struct M_C(name, _s) { \ typedef struct M_F(name, _s) { \
enum M_C(name, _enum) type; \ enum M_F(name, _enum) type; \
union { \ union { \
M_MAP(M_VAR1ANT_DEFINE_TYPE_ELE , __VA_ARGS__) \ M_MAP(M_VAR1ANT_DEFINE_TYPE_ELE , __VA_ARGS__) \
} value; \ } value; \
} name_t[1]; \ } name_t[1]; \
\ \
typedef struct M_C(name, _s) *M_C(name, _ptr); \ typedef struct M_F(name, _s) *M_F(name, _ptr); \
typedef const struct M_C(name, _s) *M_C(name, _srcptr); \ typedef const struct M_F(name, _s) *M_F(name, _srcptr); \
/* Define internal type for oplist */ \ /* Define internal type for oplist */ \
typedef name_t M_C(name, _ct); typedef name_t M_F(name, _ct);
#define M_VAR1ANT_DEFINE_UNION_ELE(name, a) \ #define M_VAR1ANT_DEFINE_UNION_ELE(name, a) \
, M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value) , M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value)
@@ -219,21 +219,21 @@
/* Define the INIT function. Init the variant to empty */ /* Define the INIT function. Init the variant to empty */
#define M_VAR1ANT_DEFINE_INIT(name, ...) \ #define M_VAR1ANT_DEFINE_INIT(name, ...) \
static inline void M_C(name, _init)(M_C(name,_ct) my) { \ static inline void M_F(name, _init)(M_F(name,_ct) my) { \
my->type = M_C(name, _EMPTY); \ my->type = M_F(name, _EMPTY); \
} }
/* Define the INIT_SET function. */ /* Define the INIT_SET function. */
#define M_VAR1ANT_DEFINE_INIT_SET(name, ...) \ #define M_VAR1ANT_DEFINE_INIT_SET(name, ...) \
static inline void M_C(name, _init_set)(M_C(name,_ct) my , \ static inline void M_F(name, _init_set)(M_F(name,_ct) my , \
M_C(name,_ct) const org) { \ M_F(name,_ct) const org) { \
M_VAR1ANT_CONTRACT(name, org); \ M_VAR1ANT_CONTRACT(name, org); \
my->type = org->type; \ my->type = org->type; \
switch (org->type) { \ switch (org->type) { \
M_MAP2(M_VAR1ANT_DEFINE_INIT_SET_FUNC, name, __VA_ARGS__) \ M_MAP2(M_VAR1ANT_DEFINE_INIT_SET_FUNC, name, __VA_ARGS__) \
case M_C(name, _EMPTY): /* fallthrough */ \ case M_F(name, _EMPTY): /* fallthrough */ \
default: M_ASSUME(org->type == M_C(name, _EMPTY)); break; \ default: M_ASSUME(org->type == M_F(name, _EMPTY)); break; \
} \ } \
} }
@@ -246,20 +246,20 @@
/* Define the SET function. */ /* Define the SET function. */
#define M_VAR1ANT_DEFINE_SET(name, ...) \ #define M_VAR1ANT_DEFINE_SET(name, ...) \
static inline void M_C(name, _set)(M_C(name,_ct) my , \ static inline void M_F(name, _set)(M_F(name,_ct) my , \
M_C(name,_ct) const org) { \ M_F(name,_ct) const org) { \
M_VAR1ANT_CONTRACT(name, my); \ M_VAR1ANT_CONTRACT(name, my); \
M_VAR1ANT_CONTRACT(name, org); \ M_VAR1ANT_CONTRACT(name, org); \
if (my->type != org->type) { \ if (my->type != org->type) { \
/* Different types: clear previous one and create new */ \ /* Different types: clear previous one and create new */ \
M_C(name, _clear)(my); \ M_F(name, _clear)(my); \
M_C(name, _init_set)(my, org); \ M_F(name, _init_set)(my, org); \
} else { \ } else { \
/* Same type: optimize the set */ \ /* Same type: optimize the set */ \
switch (org->type) { \ switch (org->type) { \
M_MAP2(M_VAR1ANT_DEFINE_SET_FUNC, name, __VA_ARGS__) \ M_MAP2(M_VAR1ANT_DEFINE_SET_FUNC, name, __VA_ARGS__) \
case M_C(name, _EMPTY): /* fallthrough */ \ case M_F(name, _EMPTY): /* fallthrough */ \
default: M_ASSUME(org->type == M_C(name, _EMPTY)); break; \ default: M_ASSUME(org->type == M_F(name, _EMPTY)); break; \
} \ } \
} \ } \
} }
@@ -273,14 +273,14 @@
/* Define the CLEAR function. */ /* Define the CLEAR function. */
#define M_VAR1ANT_DEFINE_CLEAR(name, ...) \ #define M_VAR1ANT_DEFINE_CLEAR(name, ...) \
static inline void M_C(name, _clear)(M_C(name,_ct) my) { \ static inline void M_F(name, _clear)(M_F(name,_ct) my) { \
M_VAR1ANT_CONTRACT(name, my); \ M_VAR1ANT_CONTRACT(name, my); \
switch (my->type) { \ switch (my->type) { \
M_MAP2(M_VAR1ANT_DEFINE_CLEAR_FUNC, name, __VA_ARGS__) \ M_MAP2(M_VAR1ANT_DEFINE_CLEAR_FUNC, name, __VA_ARGS__) \
case M_C(name, _EMPTY): /* fallthrough */ \ case M_F(name, _EMPTY): /* fallthrough */ \
default: M_ASSUME(my->type == M_C(name, _EMPTY)); break; \ default: M_ASSUME(my->type == M_F(name, _EMPTY)); break; \
} \ } \
my->type = M_C(name, _EMPTY); \ my->type = M_F(name, _EMPTY); \
} }
#define M_VAR1ANT_DEFINE_CLEAR_FUNC(name, a) \ #define M_VAR1ANT_DEFINE_CLEAR_FUNC(name, a) \
@@ -291,12 +291,12 @@
/* Define the TEST_P function. */ /* Define the TEST_P function. */
#define M_VAR1ANT_DEFINE_TEST_P(name, ...) \ #define M_VAR1ANT_DEFINE_TEST_P(name, ...) \
static inline bool M_C(name, _empty_p)(M_C(name,_ct) const my) { \ static inline bool M_F(name, _empty_p)(M_F(name,_ct) const my) { \
M_VAR1ANT_CONTRACT(name, my); \ M_VAR1ANT_CONTRACT(name, my); \
return my->type == M_C(name, _EMPTY); \ return my->type == M_F(name, _EMPTY); \
} \ } \
static inline enum M_C(name, _enum) \ static inline enum M_F(name, _enum) \
M_C(name, _type)(M_C(name,_ct) my) { \ M_F(name, _type)(M_F(name,_ct) my) { \
M_VAR1ANT_CONTRACT(name, my); \ M_VAR1ANT_CONTRACT(name, my); \
return my->type; \ return my->type; \
} \ } \
@@ -304,7 +304,7 @@
#define M_VAR1ANT_DEFINE_TEST_FUNC(name, a) \ #define M_VAR1ANT_DEFINE_TEST_FUNC(name, a) \
static inline bool \ static inline bool \
M_C4(name, _, M_VAR1ANT_GET_FIELD a, _p)(M_C(name,_ct) const my) { \ M_C4(name, _, M_VAR1ANT_GET_FIELD a, _p)(M_F(name,_ct) const my) { \
M_VAR1ANT_CONTRACT(name, my); \ M_VAR1ANT_CONTRACT(name, my); \
return my->type == M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value); \ return my->type == M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value); \
} }
@@ -316,7 +316,7 @@
#define M_VAR1ANT_DEFINE_INIT_FIELD_FUNC(name, a) \ #define M_VAR1ANT_DEFINE_INIT_FIELD_FUNC(name, a) \
static inline void \ static inline void \
M_C3(name, _init_, M_VAR1ANT_GET_FIELD a)(M_C(name,_ct) my) { \ M_C3(name, _init_, M_VAR1ANT_GET_FIELD a)(M_F(name,_ct) my) { \
/* Reinit variable with the given value */ \ /* Reinit variable with the given value */ \
my->type = M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value); \ my->type = M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value); \
M_VAR1ANT_CALL_INIT(a, my -> value. M_VAR1ANT_GET_FIELD a); \ M_VAR1ANT_CALL_INIT(a, my -> value. M_VAR1ANT_GET_FIELD a); \
@@ -329,7 +329,7 @@
#define M_VAR1ANT_DEFINE_INIT_SETTER_FIELD_FUNC(name, a) \ #define M_VAR1ANT_DEFINE_INIT_SETTER_FIELD_FUNC(name, a) \
static inline void \ static inline void \
M_C3(name, _init_set_, M_VAR1ANT_GET_FIELD a)(M_C(name,_ct) my, \ M_C3(name, _init_set_, M_VAR1ANT_GET_FIELD a)(M_F(name,_ct) my, \
M_VAR1ANT_GET_TYPE a const M_VAR1ANT_GET_FIELD a ) { \ M_VAR1ANT_GET_TYPE a const M_VAR1ANT_GET_FIELD a ) { \
my->type = M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value); \ my->type = M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value); \
M_VAR1ANT_CALL_INIT_SET(a, my -> value. M_VAR1ANT_GET_FIELD a, \ M_VAR1ANT_CALL_INIT_SET(a, my -> value. M_VAR1ANT_GET_FIELD a, \
@@ -343,14 +343,14 @@
#define M_VAR1ANT_DEFINE_SETTER_FIELD_FUNC(name, a) \ #define M_VAR1ANT_DEFINE_SETTER_FIELD_FUNC(name, a) \
static inline void \ static inline void \
M_C3(name, _set_, M_VAR1ANT_GET_FIELD a)(M_C(name,_ct) my, \ M_C3(name, _set_, M_VAR1ANT_GET_FIELD a)(M_F(name,_ct) my, \
M_VAR1ANT_GET_TYPE a const M_VAR1ANT_GET_FIELD a ) { \ M_VAR1ANT_GET_TYPE a const M_VAR1ANT_GET_FIELD a ) { \
M_VAR1ANT_CONTRACT(name, my); \ M_VAR1ANT_CONTRACT(name, my); \
if (my->type == M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value) ) { \ if (my->type == M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value) ) { \
M_VAR1ANT_CALL_SET(a, my -> value. M_VAR1ANT_GET_FIELD a, \ M_VAR1ANT_CALL_SET(a, my -> value. M_VAR1ANT_GET_FIELD a, \
M_VAR1ANT_GET_FIELD a); \ M_VAR1ANT_GET_FIELD a); \
} else { \ } else { \
M_C(name, _clear)(my); \ M_F(name, _clear)(my); \
/* Reinit variable with the given value */ \ /* Reinit variable with the given value */ \
my->type = M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value); \ my->type = M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value); \
M_VAR1ANT_CALL_INIT_SET(a, my -> value. M_VAR1ANT_GET_FIELD a, \ M_VAR1ANT_CALL_INIT_SET(a, my -> value. M_VAR1ANT_GET_FIELD a, \
@@ -365,7 +365,7 @@
#define M_VAR1ANT_DEFINE_GETTER_FIELD_FUNC(name, a) \ #define M_VAR1ANT_DEFINE_GETTER_FIELD_FUNC(name, a) \
static inline M_VAR1ANT_GET_TYPE a * \ static inline M_VAR1ANT_GET_TYPE a * \
M_C3(name, _get_, M_VAR1ANT_GET_FIELD a)(M_C(name,_ct) my) { \ M_C3(name, _get_, M_VAR1ANT_GET_FIELD a)(M_F(name,_ct) my) { \
M_VAR1ANT_CONTRACT(name, my); \ M_VAR1ANT_CONTRACT(name, my); \
if (my->type != M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value) ) { \ if (my->type != M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value) ) { \
return NULL; \ return NULL; \
@@ -374,7 +374,7 @@
} \ } \
\ \
static inline M_VAR1ANT_GET_TYPE a const * \ static inline M_VAR1ANT_GET_TYPE a const * \
M_C3(name, _cget_, M_VAR1ANT_GET_FIELD a)(M_C(name,_ct) const my) { \ M_C3(name, _cget_, M_VAR1ANT_GET_FIELD a)(M_F(name,_ct) const my) { \
M_VAR1ANT_CONTRACT(name, my); \ M_VAR1ANT_CONTRACT(name, my); \
if (my->type != M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value) ) { \ if (my->type != M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value) ) { \
return NULL; \ return NULL; \
@@ -393,8 +393,8 @@
#define M_VAR1ANT_MAP3_ALT_ID(a, b) a b #define M_VAR1ANT_MAP3_ALT_ID(a, b) a b
#define M_VAR1ANT_DEFINE_EMPLACE_FUNC(name, num, a) \ #define M_VAR1ANT_DEFINE_EMPLACE_FUNC(name, num, a) \
M_EMPLACE_QUEUE_DEF( (name, M_VAR1ANT_GET_FIELD a), M_C(name,_ct), M_C3(name, _init_emplace_, M_VAR1ANT_GET_FIELD a), M_VAR1ANT_GET_OPLIST a, M_VAR1ANT_DEFINE_INIT_EMPLACE_DEF) \ M_EMPLACE_QUEUE_DEF( (name, M_VAR1ANT_GET_FIELD a), M_F(name,_ct), M_C3(name, _init_emplace_, M_VAR1ANT_GET_FIELD a), M_VAR1ANT_GET_OPLIST a, M_VAR1ANT_DEFINE_INIT_EMPLACE_DEF) \
M_EMPLACE_QUEUE_DEF( (name, M_VAR1ANT_GET_FIELD a), M_C(name,_ct), M_C3(name, _emplace_, M_VAR1ANT_GET_FIELD a), M_VAR1ANT_GET_OPLIST a, M_VAR1ANT_DEFINE_EMPLACE_DEF) M_EMPLACE_QUEUE_DEF( (name, M_VAR1ANT_GET_FIELD a), M_F(name,_ct), M_C3(name, _emplace_, M_VAR1ANT_GET_FIELD a), M_VAR1ANT_GET_OPLIST a, M_VAR1ANT_DEFINE_EMPLACE_DEF)
#define M_VAR1ANT_DEFINE_INIT_EMPLACE_DEF(name, name_t, function_name, oplist, init_func, exp_emplace_type) \ #define M_VAR1ANT_DEFINE_INIT_EMPLACE_DEF(name, name_t, function_name, oplist, init_func, exp_emplace_type) \
static inline void \ static inline void \
@@ -418,14 +418,14 @@ static inline void \
/* Define the EQUAL_P function. */ /* Define the EQUAL_P function. */
#define M_VAR1ANT_DEFINE_EQUAL(name, ...) \ #define M_VAR1ANT_DEFINE_EQUAL(name, ...) \
static inline bool M_C(name, _equal_p)(M_C(name,_ct) const e1 , \ static inline bool M_F(name, _equal_p)(M_F(name,_ct) const e1 , \
M_C(name,_ct) const e2) { \ M_F(name,_ct) const e2) { \
bool b; \ bool b; \
M_VAR1ANT_CONTRACT(name, e1); \ M_VAR1ANT_CONTRACT(name, e1); \
M_VAR1ANT_CONTRACT(name, e2); \ M_VAR1ANT_CONTRACT(name, e2); \
if (e1->type != e2->type) return false; \ if (e1->type != e2->type) return false; \
switch (e1->type) { \ switch (e1->type) { \
case M_C(name, _EMPTY): break; \ case M_F(name, _EMPTY): break; \
M_MAP2(M_VAR1ANT_DEFINE_EQUAL_FUNC , name, __VA_ARGS__) \ M_MAP2(M_VAR1ANT_DEFINE_EQUAL_FUNC , name, __VA_ARGS__) \
default: M_ASSUME(false); break; \ default: M_ASSUME(false); break; \
} \ } \
@@ -442,12 +442,12 @@ static inline void \
/* Define the HASH function. */ /* Define the HASH function. */
#define M_VAR1ANT_DEFINE_HASH(name, ...) \ #define M_VAR1ANT_DEFINE_HASH(name, ...) \
static inline size_t M_C(name, _hash)(M_C(name,_ct) const e1) { \ static inline size_t M_F(name, _hash)(M_F(name,_ct) const e1) { \
M_VAR1ANT_CONTRACT(name, e1); \ M_VAR1ANT_CONTRACT(name, e1); \
M_HASH_DECL(hash); \ M_HASH_DECL(hash); \
M_HASH_UP (hash, (unsigned int) (e1 -> type)); \ M_HASH_UP (hash, (unsigned int) (e1 -> type)); \
switch (e1->type) { \ switch (e1->type) { \
case M_C(name, _EMPTY): break; \ case M_F(name, _EMPTY): break; \
M_MAP2(M_VAR1ANT_DEFINE_HASH_FUNC , name, __VA_ARGS__) \ M_MAP2(M_VAR1ANT_DEFINE_HASH_FUNC , name, __VA_ARGS__) \
default: M_ASSUME(false); break; \ default: M_ASSUME(false); break; \
} \ } \
@@ -463,15 +463,15 @@ static inline void \
/* Define the INIT_MOVE function. */ /* Define the INIT_MOVE function. */
#define M_VAR1ANT_DEFINE_INIT_MOVE(name, ...) \ #define M_VAR1ANT_DEFINE_INIT_MOVE(name, ...) \
static inline void \ static inline void \
M_C(name, _init_move)(M_C(name,_ct) el, M_C(name,_ct) org) { \ M_F(name, _init_move)(M_F(name,_ct) el, M_F(name,_ct) org) { \
M_VAR1ANT_CONTRACT(name, org); \ M_VAR1ANT_CONTRACT(name, org); \
el -> type = org -> type; \ el -> type = org -> type; \
switch (el->type) { \ switch (el->type) { \
case M_C(name, _EMPTY): break; \ case M_F(name, _EMPTY): break; \
M_MAP2(M_VAR1ANT_DEFINE_INIT_MOVE_FUNC , name, __VA_ARGS__) \ M_MAP2(M_VAR1ANT_DEFINE_INIT_MOVE_FUNC , name, __VA_ARGS__) \
default: M_ASSUME(false); break; \ default: M_ASSUME(false); break; \
} \ } \
org -> type = M_C(name, _EMPTY); \ org -> type = M_F(name, _EMPTY); \
} }
#define M_VAR1ANT_DEFINE_INIT_MOVE_FUNC(name, a) \ #define M_VAR1ANT_DEFINE_INIT_MOVE_FUNC(name, a) \
@@ -487,11 +487,11 @@ static inline void \
*/ */
#define M_VAR1ANT_DEFINE_MOVE(name, ...) \ #define M_VAR1ANT_DEFINE_MOVE(name, ...) \
static inline void \ static inline void \
M_C(name, _move)(M_C(name,_ct) el, M_C(name,_ct) org) { \ M_F(name, _move)(M_F(name,_ct) el, M_F(name,_ct) org) { \
M_VAR1ANT_CONTRACT(name, el); \ M_VAR1ANT_CONTRACT(name, el); \
M_VAR1ANT_CONTRACT(name, org); \ M_VAR1ANT_CONTRACT(name, org); \
M_C(name, _clear)(el); \ M_F(name, _clear)(el); \
M_C(name, _init_move)(el , org); \ M_F(name, _init_move)(el , org); \
} }
@@ -501,10 +501,10 @@ static inline void \
#define M_VAR1ANT_DEFINE_MOVER_FUNC(name, a) \ #define M_VAR1ANT_DEFINE_MOVER_FUNC(name, a) \
static inline void \ static inline void \
M_C3(name, _move_, M_VAR1ANT_GET_FIELD a)(M_C(name,_ct) my, \ M_C3(name, _move_, M_VAR1ANT_GET_FIELD a)(M_F(name,_ct) my, \
M_VAR1ANT_GET_TYPE a M_VAR1ANT_GET_FIELD a ) { \ M_VAR1ANT_GET_TYPE a M_VAR1ANT_GET_FIELD a ) { \
M_VAR1ANT_CONTRACT(name, my); \ M_VAR1ANT_CONTRACT(name, my); \
M_C(name, _clear)(my); \ M_F(name, _clear)(my); \
/* Reinit variable with the given value */ \ /* Reinit variable with the given value */ \
my->type = M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value); \ my->type = M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value); \
M_VAR1ANT_CALL_INIT_MOVE(a, my -> value. M_VAR1ANT_GET_FIELD a, \ M_VAR1ANT_CALL_INIT_MOVE(a, my -> value. M_VAR1ANT_GET_FIELD a, \
@@ -515,28 +515,28 @@ static inline void \
/* Define the SWAP function */ /* Define the SWAP function */
#define M_VAR1ANT_DEFINE_SWAP(name, ...) \ #define M_VAR1ANT_DEFINE_SWAP(name, ...) \
static inline void \ static inline void \
M_C(name, _swap)(M_C(name,_ct) el1, M_C(name,_ct) el2) { \ M_F(name, _swap)(M_F(name,_ct) el1, M_F(name,_ct) el2) { \
M_VAR1ANT_CONTRACT(name, el1); \ M_VAR1ANT_CONTRACT(name, el1); \
M_VAR1ANT_CONTRACT(name, el2); \ M_VAR1ANT_CONTRACT(name, el2); \
if (el1->type == el2->type) { \ if (el1->type == el2->type) { \
switch (el1->type) { \ switch (el1->type) { \
case M_C(name, _EMPTY): break; \ case M_F(name, _EMPTY): break; \
M_MAP2(M_VAR1ANT_DEFINE_INIT_SWAP_FUNC , name, __VA_ARGS__) \ M_MAP2(M_VAR1ANT_DEFINE_INIT_SWAP_FUNC , name, __VA_ARGS__) \
default: M_ASSUME(false); break; \ default: M_ASSUME(false); break; \
} \ } \
} else { \ } else { \
M_C(name,_ct) tmp; \ M_F(name,_ct) tmp; \
M_VAR1ANT_IF_ALL(INIT_MOVE, __VA_ARGS__) \ M_VAR1ANT_IF_ALL(INIT_MOVE, __VA_ARGS__) \
( /* NOTE: Slow implementation */ \ ( /* NOTE: Slow implementation */ \
M_C(name, _init_move)(tmp, el1); \ M_F(name, _init_move)(tmp, el1); \
M_C(name, _init_move)(el1, el2); \ M_F(name, _init_move)(el1, el2); \
M_C(name, _init_move)(el2, tmp); \ M_F(name, _init_move)(el2, tmp); \
, \ , \
/* NOTE: Very slow implementation */ \ /* NOTE: Very slow implementation */ \
M_C(name, _init_set)(tmp, el1); \ M_F(name, _init_set)(tmp, el1); \
M_C(name, _set)(el1, el2); \ M_F(name, _set)(el1, el2); \
M_C(name, _set)(el2, tmp); \ M_F(name, _set)(el2, tmp); \
M_C(name, _clear)(tmp); \ M_F(name, _clear)(tmp); \
) \ ) \
} \ } \
} }
@@ -550,15 +550,15 @@ static inline void \
/* Define the GET_STR function */ /* Define the GET_STR function */
#define M_VAR1ANT_DEFINE_GET_STR(name, ...) \ #define M_VAR1ANT_DEFINE_GET_STR(name, ...) \
static inline void M_C(name, _get_str)(m_string_t str, \ static inline void M_F(name, _get_str)(m_string_t str, \
M_C(name,_ct) const el, \ M_F(name,_ct) const el, \
bool append) { \ bool append) { \
M_VAR1ANT_CONTRACT(name, el); \ M_VAR1ANT_CONTRACT(name, el); \
M_ASSERT (str != NULL); \ M_ASSERT (str != NULL); \
void (*func)(m_string_t, const char *); \ void (*func)(m_string_t, const char *); \
func = append ? m_string_cat_cstr : m_string_set_cstr; \ func = append ? m_string_cat_cstr : m_string_set_cstr; \
switch (el->type) { \ switch (el->type) { \
case M_C(name, _EMPTY): func(str, "@EMPTY@"); break; \ case M_F(name, _EMPTY): func(str, "@EMPTY@"); break; \
M_MAP2(M_VAR1ANT_DEFINE_GET_STR_FUNC , name, __VA_ARGS__) \ M_MAP2(M_VAR1ANT_DEFINE_GET_STR_FUNC , name, __VA_ARGS__) \
default: M_ASSUME(false); break; \ default: M_ASSUME(false); break; \
} \ } \
@@ -574,7 +574,7 @@ static inline void \
/* Define the PARSE_STR function */ /* Define the PARSE_STR function */
#define M_VAR1ANT_DEFINE_PARSE_STR(name, ...) \ #define M_VAR1ANT_DEFINE_PARSE_STR(name, ...) \
static inline bool M_C(name, _parse_str)(M_C(name,_ct) el, \ static inline bool M_F(name, _parse_str)(M_F(name,_ct) el, \
const char str[], \ const char str[], \
const char **endp) { \ const char **endp) { \
M_VAR1ANT_CONTRACT(name, el); \ M_VAR1ANT_CONTRACT(name, el); \
@@ -583,7 +583,7 @@ static inline void \
char variantTypeBuf[M_USE_IDENTIFIER_ALLOC+1]; \ char variantTypeBuf[M_USE_IDENTIFIER_ALLOC+1]; \
int c = *str++; \ int c = *str++; \
unsigned int i = 0; \ unsigned int i = 0; \
M_C(name, _reset)(el); \ M_F(name, _reset)(el); \
if (c != '@') goto exit; \ if (c != '@') goto exit; \
/* First read the name of the type */ \ /* First read the name of the type */ \
c = *str++; \ c = *str++; \
@@ -596,7 +596,7 @@ static inline void \
M_ASSERT(i < sizeof(variantTypeBuf)); \ M_ASSERT(i < sizeof(variantTypeBuf)); \
/* In function of the type */ \ /* In function of the type */ \
if (strcmp(variantTypeBuf, "EMPTY") == 0) { \ if (strcmp(variantTypeBuf, "EMPTY") == 0) { \
el->type = M_C(name, _EMPTY); \ el->type = M_F(name, _EMPTY); \
} \ } \
M_MAP2(M_VAR1ANT_DEFINE_PARSE_STR_FUNC , name, __VA_ARGS__) \ M_MAP2(M_VAR1ANT_DEFINE_PARSE_STR_FUNC , name, __VA_ARGS__) \
else goto exit; \ else goto exit; \
@@ -617,12 +617,12 @@ static inline void \
/* Define the OUT_STR function */ /* Define the OUT_STR function */
#define M_VAR1ANT_DEFINE_OUT_STR(name, ...) \ #define M_VAR1ANT_DEFINE_OUT_STR(name, ...) \
static inline void M_C(name, _out_str)(FILE *f, \ static inline void M_F(name, _out_str)(FILE *f, \
M_C(name,_ct) const el) { \ M_F(name,_ct) const el) { \
M_VAR1ANT_CONTRACT(name, el); \ M_VAR1ANT_CONTRACT(name, el); \
M_ASSERT (f != NULL); \ M_ASSERT (f != NULL); \
switch (el->type) { \ switch (el->type) { \
case M_C(name, _EMPTY): fprintf(f, "@EMPTY@"); break; \ case M_F(name, _EMPTY): fprintf(f, "@EMPTY@"); break; \
M_MAP2(M_VAR1ANT_DEFINE_OUT_STR_FUNC , name, __VA_ARGS__) \ M_MAP2(M_VAR1ANT_DEFINE_OUT_STR_FUNC , name, __VA_ARGS__) \
default: M_ASSUME(false); break; \ default: M_ASSUME(false); break; \
} \ } \
@@ -638,12 +638,12 @@ static inline void \
/* Define the IN_STR function */ /* Define the IN_STR function */
#define M_VAR1ANT_DEFINE_IN_STR(name, ...) \ #define M_VAR1ANT_DEFINE_IN_STR(name, ...) \
static inline bool M_C(name, _in_str)(M_C(name,_ct) el, \ static inline bool M_F(name, _in_str)(M_F(name,_ct) el, \
FILE *f) { \ FILE *f) { \
M_VAR1ANT_CONTRACT(name, el); \ M_VAR1ANT_CONTRACT(name, el); \
M_ASSERT (f != NULL); \ M_ASSERT (f != NULL); \
char variantTypeBuf[M_USE_IDENTIFIER_ALLOC+1]; \ char variantTypeBuf[M_USE_IDENTIFIER_ALLOC+1]; \
M_C(name, _reset)(el); \ M_F(name, _reset)(el); \
if (fgetc(f) != '@') return false; \ if (fgetc(f) != '@') return false; \
/* First read the name of the type */ \ /* First read the name of the type */ \
bool b = true; \ bool b = true; \
@@ -658,7 +658,7 @@ static inline void \
M_ASSERT(i < sizeof(variantTypeBuf)); \ M_ASSERT(i < sizeof(variantTypeBuf)); \
/* In function of the type */ \ /* In function of the type */ \
if (strcmp(variantTypeBuf, "EMPTY") == 0) { \ if (strcmp(variantTypeBuf, "EMPTY") == 0) { \
el->type = M_C(name, _EMPTY); \ el->type = M_F(name, _EMPTY); \
} \ } \
M_MAP2(M_VAR1ANT_DEFINE_IN_STR_FUNC , name, __VA_ARGS__) \ M_MAP2(M_VAR1ANT_DEFINE_IN_STR_FUNC , name, __VA_ARGS__) \
else { b = false; } \ else { b = false; } \
@@ -681,8 +681,8 @@ static inline void \
/* Define the OUT_SERIAL function */ /* Define the OUT_SERIAL function */
#define M_VAR1ANT_DEFINE_OUT_SERIAL(name, ...) \ #define M_VAR1ANT_DEFINE_OUT_SERIAL(name, ...) \
static inline m_serial_return_code_t \ static inline m_serial_return_code_t \
M_C(name, _out_serial)(m_serial_write_t f, \ M_F(name, _out_serial)(m_serial_write_t f, \
M_C(name,_ct) const el) { \ M_F(name,_ct) const el) { \
M_VAR1ANT_CONTRACT(name, el); \ M_VAR1ANT_CONTRACT(name, el); \
const int field_max = M_NARGS(__VA_ARGS__); \ const int field_max = M_NARGS(__VA_ARGS__); \
static const char *const field_name[] = \ static const char *const field_name[] = \
@@ -691,7 +691,7 @@ static inline void \
m_serial_local_t local; \ m_serial_local_t local; \
m_serial_return_code_t ret; \ m_serial_return_code_t ret; \
switch (el->type) { \ switch (el->type) { \
case M_C(name, _EMPTY): \ case M_F(name, _EMPTY): \
return f->m_interface->write_variant_start(local, f, field_name, field_max, -1); \ return f->m_interface->write_variant_start(local, f, field_name, field_max, -1); \
break; \ break; \
M_MAP2(M_VAR1ANT_DEFINE_OUT_SERIAL_FUNC , name, __VA_ARGS__) \ M_MAP2(M_VAR1ANT_DEFINE_OUT_SERIAL_FUNC , name, __VA_ARGS__) \
@@ -712,7 +712,7 @@ static inline void \
/* Define the IN_SERIAL function */ /* Define the IN_SERIAL function */
#define M_VAR1ANT_DEFINE_IN_SERIAL(name, ...) \ #define M_VAR1ANT_DEFINE_IN_SERIAL(name, ...) \
static inline m_serial_return_code_t \ static inline m_serial_return_code_t \
M_C(name, _in_serial)(M_C(name,_ct) el, \ M_F(name, _in_serial)(M_F(name,_ct) el, \
m_serial_read_t f) { \ m_serial_read_t f) { \
M_VAR1ANT_CONTRACT(name, el); \ M_VAR1ANT_CONTRACT(name, el); \
const int field_max = M_NARGS(__VA_ARGS__); \ const int field_max = M_NARGS(__VA_ARGS__); \
@@ -722,11 +722,11 @@ static inline void \
m_serial_local_t local; \ m_serial_local_t local; \
m_serial_return_code_t ret; \ m_serial_return_code_t ret; \
int id = -1; \ int id = -1; \
M_C(name, _reset)(el); \ M_F(name, _reset)(el); \
ret = f->m_interface->read_variant_start(local, f, field_name, field_max, &id); \ ret = f->m_interface->read_variant_start(local, f, field_name, field_max, &id); \
if (ret != M_SERIAL_OK_CONTINUE) return ret; \ if (ret != M_SERIAL_OK_CONTINUE) return ret; \
M_ASSERT (id >= 0 && id < field_max); \ M_ASSERT (id >= 0 && id < field_max); \
el->type = (enum M_C(name, _enum))(id+1); \ el->type = (enum M_F(name, _enum))(id+1); \
switch (id+1) { \ switch (id+1) { \
M_MAP2(M_VAR1ANT_DEFINE_IN_SERIAL_FUNC , name, __VA_ARGS__) \ M_MAP2(M_VAR1ANT_DEFINE_IN_SERIAL_FUNC , name, __VA_ARGS__) \
default: M_ASSUME(false); break; \ default: M_ASSUME(false); break; \
@@ -745,11 +745,11 @@ static inline void \
/* Define the RESET function */ /* Define the RESET function */
#define M_VAR1ANT_DEFINE_RESET_FUNC(name, ...) \ #define M_VAR1ANT_DEFINE_RESET_FUNC(name, ...) \
static inline void M_C(name, _reset)(M_C(name,_ct) my) \ static inline void M_F(name, _reset)(M_F(name,_ct) my) \
{ \ { \
M_VAR1ANT_CONTRACT(name, my); \ M_VAR1ANT_CONTRACT(name, my); \
M_C(name, _clear)(my); \ M_F(name, _clear)(my); \
M_C(name, _init)(my); \ M_F(name, _init)(my); \
} \ } \
@@ -768,25 +768,25 @@ static inline void \
/* Define the oplist */ /* Define the oplist */
#define M_VAR1ANT_OPLIST_P3(name, ...) \ #define M_VAR1ANT_OPLIST_P3(name, ...) \
(INIT(M_C(name,_init)), \ (INIT(M_F(name,_init)), \
INIT_SET(M_C(name, _init_set)), \ INIT_SET(M_F(name, _init_set)), \
SET(M_C(name,_set)), \ SET(M_F(name,_set)), \
CLEAR(M_C(name, _clear)), \ CLEAR(M_F(name, _clear)), \
RESET(M_C(name, _reset)), \ RESET(M_F(name, _reset)), \
NAME(name), \ NAME(name), \
TYPE(M_C(name,_ct)), \ TYPE(M_F(name,_ct)), \
EMPTY_P(M_C(name,_empty_p)), \ EMPTY_P(M_F(name,_empty_p)), \
M_IF_METHOD_ALL(HASH, __VA_ARGS__)(HASH(M_C(name, _hash)),), \ M_IF_METHOD_ALL(HASH, __VA_ARGS__)(HASH(M_F(name, _hash)),), \
M_IF_METHOD_ALL(EQUAL, __VA_ARGS__)(EQUAL(M_C(name, _equal_p)),), \ M_IF_METHOD_ALL(EQUAL, __VA_ARGS__)(EQUAL(M_F(name, _equal_p)),), \
M_IF_METHOD_ALL(GET_STR, __VA_ARGS__)(GET_STR(M_C(name, _get_str)),), \ M_IF_METHOD_ALL(GET_STR, __VA_ARGS__)(GET_STR(M_F(name, _get_str)),), \
M_IF_METHOD2_ALL(PARSE_STR, INIT, __VA_ARGS__)(PARSE_STR(M_C(name, _parse_str)),), \ M_IF_METHOD2_ALL(PARSE_STR, INIT, __VA_ARGS__)(PARSE_STR(M_F(name, _parse_str)),), \
M_IF_METHOD2_ALL(IN_STR, INIT, __VA_ARGS__)(IN_STR(M_C(name, _in_str)),), \ M_IF_METHOD2_ALL(IN_STR, INIT, __VA_ARGS__)(IN_STR(M_F(name, _in_str)),), \
M_IF_METHOD_ALL(OUT_STR, __VA_ARGS__)(OUT_STR(M_C(name, _out_str)),), \ M_IF_METHOD_ALL(OUT_STR, __VA_ARGS__)(OUT_STR(M_F(name, _out_str)),), \
M_IF_METHOD2_ALL(IN_SERIAL, INIT, __VA_ARGS__)(IN_SERIAL(M_C(name, _in_serial)),), \ M_IF_METHOD2_ALL(IN_SERIAL, INIT, __VA_ARGS__)(IN_SERIAL(M_F(name, _in_serial)),), \
M_IF_METHOD_ALL(OUT_SERIAL, __VA_ARGS__)(OUT_SERIAL(M_C(name, _out_serial)),), \ M_IF_METHOD_ALL(OUT_SERIAL, __VA_ARGS__)(OUT_SERIAL(M_F(name, _out_serial)),), \
M_IF_METHOD_ALL(INIT_MOVE, __VA_ARGS__)(INIT_MOVE(M_C(name, _init_move)),), \ M_IF_METHOD_ALL(INIT_MOVE, __VA_ARGS__)(INIT_MOVE(M_F(name, _init_move)),), \
M_IF_METHOD_ALL(INIT_MOVE, __VA_ARGS__)(MOVE(M_C(name, _move)),), \ M_IF_METHOD_ALL(INIT_MOVE, __VA_ARGS__)(MOVE(M_F(name, _move)),), \
M_IF_METHOD_ALL(SWAP, __VA_ARGS__)(SWAP(M_C(name, _swap)),), \ M_IF_METHOD_ALL(SWAP, __VA_ARGS__)(SWAP(M_F(name, _swap)),), \
M_IF_METHOD(NEW, M_RET_ARG1(__VA_ARGS__,))(NEW(M_DELAY2(M_GET_NEW) M_RET_ARG1(__VA_ARGS__,)),), \ M_IF_METHOD(NEW, M_RET_ARG1(__VA_ARGS__,))(NEW(M_DELAY2(M_GET_NEW) M_RET_ARG1(__VA_ARGS__,)),), \
M_IF_METHOD(REALLOC, M_RET_ARG1(__VA_ARGS__,))(REALLOC(M_DELAY2(M_GET_REALLOC) M_RET_ARG1(__VA_ARGS__,)),), \ M_IF_METHOD(REALLOC, M_RET_ARG1(__VA_ARGS__,))(REALLOC(M_DELAY2(M_GET_REALLOC) M_RET_ARG1(__VA_ARGS__,)),), \
M_IF_METHOD(DEL, M_RET_ARG1(__VA_ARGS__,))(DEL(M_DELAY2(M_GET_DEL) M_RET_ARG1(__VA_ARGS__,)),), \ M_IF_METHOD(DEL, M_RET_ARG1(__VA_ARGS__,))(DEL(M_DELAY2(M_GET_DEL) M_RET_ARG1(__VA_ARGS__,)),), \
+15 -1
View File
@@ -24,9 +24,19 @@
#include <stdbool.h> #include <stdbool.h>
#include <assert.h> #include <assert.h>
#include "coverage.h" #include "coverage.h"
// Override M_F for testing purpose
#define M_F(a,b) M_OVERRIDE_F(a,b)
#define M_OVERRIDE__method() , _get_method ,
#define M_OVERRIDE__method2() , _get_method2
#include "m-core.h"
#include "test-obj.h" #include "test-obj.h"
#include "m-core.h" static bool tmp_init(void) { return true; }
static bool tmp_get_method(void) { return true; }
static bool tmp_get_method2(void) { return true; }
static bool tmp_clear(void) { return true; }
static void test_cat(void) static void test_cat(void)
{ {
@@ -42,6 +52,10 @@ static void test_cat(void)
assert (M_C5_EMPTY(A,a,n,d,B)); assert (M_C5_EMPTY(A,a,n,d,B));
assert (M_C5_EMPTY(Aand,,,,B)); assert (M_C5_EMPTY(Aand,,,,B));
assert( M_F(tmp, _init)());
assert( M_F(tmp, _method)());
assert( M_F(tmp, _method2)());
assert( M_F(tmp, _clear)());
} }
static void test_power2(void) static void test_power2(void)