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.
##### 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)
Increment the number given as argument and return
+56 -56
View File
@@ -129,16 +129,16 @@
, /* NO EQUAL */) \
\
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, \
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_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, \
_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 */ \
M_IF_METHOD(IT_REF, cont_oplist)( \
@@ -167,22 +167,22 @@
* Types remain internal */
#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_C(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 void (*M_C(name, _transform_cb_ct))(type_t *, type_t const); \
typedef void (*M_C(name, _apply_cb_ct))(type_t); \
typedef bool (*M_F(name, _test_cb_ct))(type_t const); \
typedef bool (*M_F(name, _eq_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_F(name, _transform_cb_ct))(type_t *, type_t const); \
typedef void (*M_F(name, _apply_cb_ct))(type_t); \
/* Define the function objects associated to the algorithms.
* 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) \
\
FUNC_OBJ_ITF_DEF(M_C(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_C(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_C(name, _apply_obj), void, type_t * ) \
FUNC_OBJ_ITF_DEF(M_F(name, _test_obj), bool, type_t const) \
FUNC_OBJ_ITF_DEF(M_F(name, _eq_obj), bool, 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_F(name, _transform_obj), void, type_t *, type_t const ) \
FUNC_OBJ_ITF_DEF(M_F(name, _apply_obj), void, type_t * ) \
/* Define the sort functions with the CMP operator using the order selected */
@@ -203,9 +203,9 @@
// Call the created function object
#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
#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
@@ -253,7 +253,7 @@
/* - a selection sort */ \
M_IF(M_AND(M_TEST_METHOD_P(SORT, cont_oplist), M_EMPTY_P(cmp_arg)))( \
/******** 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)); \
} \
@@ -321,7 +321,7 @@
\
/* Sort the container 'l' */ \
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 l2; \
@@ -353,8 +353,8 @@
M_CALL_INIT(cont_oplist, l1); \
M_CALL_INIT(cont_oplist, l2); \
M_C3(name,sort_name,_split)(l1, l2, l); \
M_C(name,sort_name)(l1 cmp_arg); \
M_C(name,sort_name)(l2 cmp_arg); \
M_F(name,sort_name)(l1 cmp_arg); \
M_F(name,sort_name)(l2 cmp_arg); \
M_C3(name,sort_name,_merge)(l, l1, l2 cmp_arg); \
/* l1 & l2 shall be empty now */ \
M_CALL_CLEAR(cont_oplist, l2); \
@@ -363,7 +363,7 @@
, \
M_IF_METHOD(IT_PREVIOUS, cont_oplist)( \
/******** 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 it2; \
@@ -400,7 +400,7 @@
\
, \
/********** 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 it2; \
@@ -518,7 +518,7 @@
/* It supposes that the container is not sorted */ \
/* Find the next occurrence from it (included) of data */ \
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) ; \
M_CALL_IT_NEXT(cont_oplist, it)) { \
@@ -529,18 +529,18 @@
\
/* Find the first occurrence of data */ \
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_C(name, _find_again)(it, data); \
M_F(name, _find_again)(it, data); \
} \
\
/* Test if data is within the container */ \
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; \
M_C(name,_find)(it, l, data); \
M_F(name,_find)(it, l, data); \
return !M_CALL_IT_END_P(cont_oplist, it); \
} \
\
@@ -550,7 +550,7 @@
M_IF_METHOD2(PREVIOUS, IT_LAST, cont_oplist) \
( \
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); \
!M_CALL_IT_END_P(cont_oplist, it) ; \
@@ -563,7 +563,7 @@
, \
/* Otherwise search forward, but don't stop on the first occurrence */ \
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); \
it_t it2; \
@@ -579,7 +579,7 @@
\
/* Count the number of occurrence of data in the container */ \
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; \
size_t count = 0; \
@@ -595,7 +595,7 @@
\
/* Find the next mismatch between the containers */ \
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) && \
!M_CALL_IT_END_P(cont_oplist, it2); \
@@ -609,11 +609,11 @@
\
/* Find the first mismatch between the containers */ \
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, 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) */ \
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) { \
M_CALL_SET(type_oplist, *item, value); \
@@ -699,7 +699,7 @@
/* Fill the container with exactly 'n' occurrence of 'value' */ \
M_IF_METHOD(PUSH, cont_oplist)( \
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); \
for(size_t i = 0; i < n; i++) { \
@@ -711,7 +711,7 @@
/* Fill the container with FOR('value'; 'value'+'inc') */ \
M_IF_METHOD(ADD, type_oplist)( \
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; \
M_CALL_INIT_SET(type_oplist, tmp, value); \
@@ -725,7 +725,7 @@
/* Fill the container with n occurences of FOR('value'; 'value'+'inc') */ \
M_IF_METHOD(PUSH, cont_oplist)( \
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; \
M_CALL_INIT_SET(type_oplist, tmp, value); \
@@ -745,7 +745,7 @@
\
/* Apply func for all elements of the container */ \
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) { \
func(*item); \
@@ -757,9 +757,9 @@
\
/* Apply func for all elements of the container src and push the result in dst */ \
static inline void \
M_C(name, _transform) (container_t dst, \
M_F(name, _transform) (container_t dst, \
container_t src, \
M_C(name, _transform_cb_ct) func) \
M_F(name, _transform_cb_ct) func) \
{ \
M_ASSERT(dst != src); \
M_CALL_RESET(cont_oplist, dst); \
@@ -776,8 +776,8 @@
/* Reduce all elements of the container in dst in function of func */ \
M_IF_METHOD(SET, type_oplist)( \
static inline void \
M_C(name, _reduce) (type_t *dest, container_t const l, \
M_C(name, _transform_cb_ct) func) \
M_F(name, _reduce) (type_t *dest, container_t const l, \
M_F(name, _transform_cb_ct) func) \
{ \
bool initDone = false; \
for M_EACH(item, l, cont_oplist) { \
@@ -794,10 +794,10 @@
/* Reduce all transformed elements of the container in dst in function of func */ \
M_IF_METHOD(INIT, type_oplist)( \
static inline \
void M_C(name, _map_reduce) (type_t *dest, \
void M_F(name, _map_reduce) (type_t *dest, \
const container_t l, \
M_C(name, _transform_cb_ct) redFunc, \
M_C(name, _transform_cb_ct) mapFunc) \
M_F(name, _transform_cb_ct) redFunc, \
M_F(name, _transform_cb_ct) mapFunc) \
{ \
bool initDone = false; \
type_t tmp; \
@@ -857,7 +857,7 @@
#define M_ALG0_DEF_MINMAX(name, container_t, cont_oplist, type_t, type_oplist, it_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; \
for M_EACH(cref, l, cont_oplist) { \
@@ -870,7 +870,7 @@
} \
\
static inline type_t * \
M_C(name, _max) (const container_t l) \
M_F(name, _max) (const container_t l) \
{ \
type_t *max = NULL; \
for M_EACH(cref, l, cont_oplist) { \
@@ -883,7 +883,7 @@
} \
\
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) \
{ \
type_t *min = NULL; \
@@ -906,11 +906,11 @@
#define M_ALG0_DEF_REMOVE(name, container_t, cont_oplist, type_t, type_oplist, it_t) \
\
static inline void \
M_C(name, _uniq)(container_t l) \
M_F(name, _uniq)(container_t l) \
{ \
it_t it1; \
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_SET(cont_oplist, it2, it1); \
M_CALL_IT_NEXT(cont_oplist, it2); \
@@ -928,7 +928,7 @@
} \
\
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; \
M_CALL_IT_FIRST(cont_oplist, it1, l); \
@@ -943,7 +943,7 @@
} \
\
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; \
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) \
\
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 itDst; \
@@ -979,7 +979,7 @@
, /* NO_ADD METHOD */ ) \
\
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 itDst; \
@@ -997,7 +997,7 @@
, /* NO_SUB METHOD */ ) \
\
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 itDst; \
@@ -1015,7 +1015,7 @@
, /* NO_MUL METHOD */ ) \
\
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 itDst; \
+143 -143
View File
@@ -30,7 +30,7 @@
/* Define a dynamic array of the given type and its associated functions.
USAGE: ARRAY_DEF(name, type [, oplist_of_the_type]) */
#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
@@ -81,56 +81,56 @@
/* 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)? */
#define M_ARRA4_OPLIST_P3(name, oplist) \
(INIT(M_C(name, _init)) \
,M_IF_METHOD2(INIT_SET,SET, oplist)(INIT_SET(M_C(name, _init_set)),) \
(INIT(M_F(name, _init)) \
,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_METHOD2(INIT_SET,SET, oplist)(SET(M_C(name, _set)), ) \
,CLEAR(M_C(name, _clear)) \
,INIT_MOVE(M_C(name, _init_move)) \
,MOVE(M_C(name, _move)) \
,SWAP(M_C(name, _swap)) \
,TYPE(M_C(name,_ct)) \
,M_IF_METHOD2(INIT_SET,SET, oplist)(SET(M_F(name, _set)), ) \
,CLEAR(M_F(name, _clear)) \
,INIT_MOVE(M_F(name, _init_move)) \
,MOVE(M_F(name, _move)) \
,SWAP(M_F(name, _swap)) \
,TYPE(M_F(name,_ct)) \
,NAME(name) \
,SUBTYPE(M_C(name, _subtype_ct)) \
,EMPTY_P(M_C(name,_empty_p)) \
,IT_TYPE(M_C(name,_it_ct)), \
,IT_FIRST(M_C(name,_it)) \
,IT_LAST(M_C(name,_it_last)) \
,IT_END(M_C(name,_it_end)) \
,IT_SET(M_C(name,_it_set)) \
,IT_END_P(M_C(name,_end_p)) \
,IT_LAST_P(M_C(name,_last_p)) \
,IT_EQUAL_P(M_C(name,_it_equal_p)) \
,IT_NEXT(M_C(name,_next)) \
,IT_PREVIOUS(M_C(name,_previous)) \
,IT_REF(M_C(name,_ref)) \
,IT_CREF(M_C(name,_cref)) \
,M_IF_METHOD(INIT_SET, oplist)(IT_INSERT(M_C(name,_insert)) ,) \
,M_IF_AT_LEAST_METHOD(SET,INIT_MOVE,oplist)(IT_REMOVE(M_C(name,_remove)),) \
,RESET(M_C(name,_reset)) \
,SUBTYPE(M_F(name, _subtype_ct)) \
,EMPTY_P(M_F(name,_empty_p)) \
,IT_TYPE(M_F(name,_it_ct)), \
,IT_FIRST(M_F(name,_it)) \
,IT_LAST(M_F(name,_it_last)) \
,IT_END(M_F(name,_it_end)) \
,IT_SET(M_F(name,_it_set)) \
,IT_END_P(M_F(name,_end_p)) \
,IT_LAST_P(M_F(name,_last_p)) \
,IT_EQUAL_P(M_F(name,_it_equal_p)) \
,IT_NEXT(M_F(name,_next)) \
,IT_PREVIOUS(M_F(name,_previous)) \
,IT_REF(M_F(name,_ref)) \
,IT_CREF(M_F(name,_cref)) \
,M_IF_METHOD(INIT_SET, oplist)(IT_INSERT(M_F(name,_insert)) ,) \
,M_IF_AT_LEAST_METHOD(SET,INIT_MOVE,oplist)(IT_REMOVE(M_F(name,_remove)),) \
,RESET(M_F(name,_reset)) \
,KEY_TYPE(size_t) \
,VALUE_TYPE(M_C(name, _subtype_ct)) \
,VALUE_TYPE(M_F(name, _subtype_ct)) \
,KEY_OPLIST(M_BASIC_OPLIST) \
,VALUE_OPLIST(oplist) \
,M_IF_METHOD(SET, oplist)(SET_KEY(M_C(name, _set_at)) ,) \
,GET_KEY(M_C(name, _get)) \
,M_IF_METHOD(INIT, oplist)(SAFE_GET_KEY(M_C(name, _safe_get)) ,) \
,M_IF_AT_LEAST_METHOD(SET,INIT_MOVE,oplist)(ERASE_KEY(M_C(name, _erase)),) \
,GET_SIZE(M_C(name, _size)) \
,M_IF_METHOD(INIT_SET, oplist)(PUSH(M_C(name,_push_back)) ,) \
,M_IF_AT_LEAST_METHOD(SET,INIT_MOVE,oplist)(POP(M_C(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)(POP_MOVE(M_C(name,_pop_move)) ,) \
,M_IF_METHOD(SET, oplist)(SET_KEY(M_F(name, _set_at)) ,) \
,GET_KEY(M_F(name, _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_F(name, _erase)),) \
,GET_SIZE(M_F(name, _size)) \
,M_IF_METHOD(INIT_SET, oplist)(PUSH(M_F(name,_push_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_F(name,_push_move)) ,) \
,M_IF_AT_LEAST_METHOD(INIT_SET,INIT_MOVE,oplist)(POP_MOVE(M_F(name,_pop_move)) ,) \
,OPLIST(oplist) \
,M_IF_METHOD(CMP, oplist)(SORT(M_C(name, _special_sort)),) \
,M_IF_METHOD(GET_STR, oplist)(GET_STR(M_C(name, _get_str)),) \
,M_IF_METHOD(PARSE_STR, oplist)(PARSE_STR(M_C(name, _parse_str)),) \
,M_IF_METHOD(OUT_STR, oplist)(OUT_STR(M_C(name, _out_str)),) \
,M_IF_METHOD(IN_STR, oplist)(IN_STR(M_C(name, _in_str)),) \
,M_IF_METHOD(OUT_SERIAL, oplist)(OUT_SERIAL(M_C(name, _out_serial)),) \
,M_IF_METHOD(IN_SERIAL, oplist)(IN_SERIAL(M_C(name, _in_serial)),) \
,M_IF_METHOD(EQUAL, oplist)(EQUAL(M_C(name, _equal_p)),) \
,M_IF_METHOD(HASH, oplist)(HASH(M_C(name, _hash)),) \
,M_IF_METHOD(CMP, oplist)(SORT(M_F(name, _special_sort)),) \
,M_IF_METHOD(GET_STR, oplist)(GET_STR(M_F(name, _get_str)),) \
,M_IF_METHOD(PARSE_STR, oplist)(PARSE_STR(M_F(name, _parse_str)),) \
,M_IF_METHOD(OUT_STR, oplist)(OUT_STR(M_F(name, _out_str)),) \
,M_IF_METHOD(IN_STR, oplist)(IN_STR(M_F(name, _in_str)),) \
,M_IF_METHOD(OUT_SERIAL, oplist)(OUT_SERIAL(M_F(name, _out_serial)),) \
,M_IF_METHOD(IN_SERIAL, oplist)(IN_SERIAL(M_F(name, _in_serial)),) \
,M_IF_METHOD(EQUAL, oplist)(EQUAL(M_F(name, _equal_p)),) \
,M_IF_METHOD(HASH, oplist)(HASH(M_F(name, _hash)),) \
,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW oplist),) \
,M_IF_METHOD(REALLOC, oplist)(REALLOC(M_GET_REALLOC oplist),) \
,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL oplist),) \
@@ -176,36 +176,36 @@
M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \
M_ARRA4_DEF_CORE(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 M_ARRA4_DEF_TYPE(name, type, oplist, array_t, it_t) \
\
/* 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 alloc; /* Allocated size for the array base */ \
type *ptr; /* Pointer to the array base */ \
} array_t[1]; \
\
/* 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 */ \
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]; \
\
/* Definition of the synonyms of the type */ \
typedef struct M_C(name, _s) *M_C(name, _ptr); \
typedef const struct M_C(name, _s) *M_C(name, _srcptr); \
typedef array_t M_C(name, _ct); \
typedef it_t M_C(name, _it_ct); \
typedef type M_C(name, _subtype_ct); \
typedef struct M_F(name, _s) *M_F(name, _ptr); \
typedef const struct M_F(name, _s) *M_F(name, _srcptr); \
typedef array_t M_F(name, _ct); \
typedef it_t M_F(name, _it_ct); \
typedef type M_F(name, _subtype_ct); \
/* Define the core functions */
#define M_ARRA4_DEF_CORE(name, type, oplist, array_t, it_t) \
\
static inline void \
M_C(name, _init)(array_t v) \
M_F(name, _init)(array_t v) \
{ \
M_ASSERT (v != NULL); \
/* Initially, the array is empty with nothing allocated */ \
@@ -216,7 +216,7 @@
} \
\
static inline void \
M_C(name, _reset)(array_t v) \
M_F(name, _reset)(array_t v) \
{ \
M_ARRA4_CONTRACT(v); \
for(size_t i = 0; i < v->size; i++) \
@@ -226,10 +226,10 @@
} \
\
static inline void \
M_C(name, _clear)(array_t v) \
M_F(name, _clear)(array_t v) \
{ \
M_ARRA4_CONTRACT(v); \
M_C(name, _reset)(v); \
M_F(name, _reset)(v); \
M_CALL_FREE(oplist, v->ptr); \
/* This is so reusing the object implies an assertion failure */ \
v->alloc = 1; \
@@ -238,7 +238,7 @@
\
M_IF_METHOD2(INIT_SET, SET, oplist)( \
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(s); \
@@ -266,16 +266,16 @@
} \
\
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_C(name, _init)(d); \
M_C(name, _set)(d, s); \
M_F(name, _init)(d); \
M_F(name, _set)(d, s); \
} \
, /* No SET & INIT_SET */) \
\
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_ARRA4_CONTRACT(s); \
@@ -289,16 +289,16 @@
} \
\
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_C(name, _clear)(d); \
M_C(name, _init_move)(d, s); \
M_F(name, _clear)(d); \
M_F(name, _init_move)(d, s); \
} \
\
M_IF_METHOD(SET, oplist)( \
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_ASSERT(v->size > 0 && v->ptr != NULL); \
@@ -308,7 +308,7 @@
, /* No SET */) \
\
static inline type * \
M_C(name, _back)(array_t v) \
M_F(name, _back)(array_t v) \
{ \
M_ARRA4_CONTRACT(v); \
M_ASSERT(v->ptr != NULL); \
@@ -317,7 +317,7 @@
} \
\
static inline type * \
M_C(name, _push_raw)(array_t v) \
M_F(name, _push_raw)(array_t v) \
{ \
M_ARRA4_CONTRACT(v); \
if (M_UNLIKELY (v->size >= v->alloc)) { \
@@ -346,9 +346,9 @@
\
M_IF_METHOD(INIT_SET, oplist)( \
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) ) \
return; \
M_CALL_INIT_SET(oplist, *data, x); \
@@ -357,9 +357,9 @@
\
M_IF_METHOD(INIT, oplist)( \
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) ) \
return NULL; \
M_CALL_INIT(oplist, *data); \
@@ -369,10 +369,10 @@
\
M_IF_AT_LEAST_METHOD(INIT_SET, INIT_MOVE, oplist)( \
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); \
type *data = M_C(name, _push_raw)(v); \
type *data = M_F(name, _push_raw)(v); \
if (M_UNLIKELY (data == NULL) ) \
return; \
M_DO_INIT_MOVE (oplist, *data, *x); \
@@ -381,7 +381,7 @@
\
M_IF_METHOD(INIT_SET, oplist)( \
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_ASSERT_INDEX(key, v->size+1); \
@@ -411,7 +411,7 @@
\
M_IF_METHOD(INIT, oplist)( \
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); \
if (v->size > size) { \
@@ -440,7 +440,7 @@
, /* No INIT */ ) \
\
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); \
/* NOTE: Reserve below needed size to perform a shrink to fit */ \
@@ -465,7 +465,7 @@
\
M_IF_METHOD(INIT, oplist)( \
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); \
const size_t size = idx + 1; \
@@ -499,7 +499,7 @@
\
M_IF_AT_LEAST_METHOD(SET, INIT_MOVE, oplist)( \
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_ASSERT (v->ptr != NULL); \
@@ -516,7 +516,7 @@
\
M_IF_AT_LEAST_METHOD(INIT_SET, INIT_MOVE, oplist)( \
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_ASSERT (v->ptr != NULL); \
@@ -530,31 +530,31 @@
\
M_IF_METHOD(INIT, oplist)( \
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_ASSERT (v == pos->array); \
M_ASSERT_INDEX(pos->index, v->size+1); \
M_C(name, _resize)(v, pos->index); \
M_F(name, _resize)(v, pos->index); \
} \
, /* No INIT */ ) \
\
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); \
return v->size == 0; \
} \
\
static inline size_t \
M_C(name, _size)(const array_t v) \
M_F(name, _size)(const array_t v) \
{ \
M_ARRA4_CONTRACT(v); \
return v->size; \
} \
\
static inline size_t \
M_C(name, _capacity)(const array_t v) \
M_F(name, _capacity)(const array_t v) \
{ \
M_ARRA4_CONTRACT(v); \
return v->alloc; \
@@ -562,7 +562,7 @@
\
M_IF_AT_LEAST_METHOD(SET, INIT_MOVE, oplist)( \
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_ASSERT (v->size > 0 && v->ptr != NULL); \
@@ -577,18 +577,18 @@
} \
\
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); \
if (i >= a->size) return false; \
M_C(name, _pop_at)(NULL, a, i); \
M_F(name, _pop_at)(NULL, a, i); \
return true; \
} \
, /* SET | INIT_MOVE */ ) \
\
M_IF_METHOD(INIT, oplist)( \
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_ASSERT_INDEX(i, v->size+1); \
@@ -624,7 +624,7 @@
, /* No INIT */) \
\
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_ASSERT(i < j && v->ptr != NULL); \
@@ -638,7 +638,7 @@
} \
\
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(v2); \
@@ -651,7 +651,7 @@
\
M_IF_AT_LEAST_METHOD(INIT_SET,INIT_MOVE,oplist) ( \
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_ASSERT(v->ptr != NULL); \
@@ -666,7 +666,7 @@
, /* INIT_SET | INIT_MOVE */ ) \
\
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_ASSERT (v->ptr != NULL); \
@@ -675,7 +675,7 @@
} \
\
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_ASSERT (v->ptr != NULL); \
@@ -684,15 +684,15 @@
} \
\
static inline type * \
M_C(name, _front)(const array_t v) \
M_F(name, _front)(const array_t v) \
{ \
M_ARRA4_CONTRACT(v); \
M_ASSERT_INDEX(0, v->size); \
return M_C(name, _get)(v, 0); \
return M_F(name, _get)(v, 0); \
} \
\
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_ASSERT (it != NULL); \
@@ -701,7 +701,7 @@
} \
\
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_ASSERT (it != NULL); \
@@ -711,7 +711,7 @@
} \
\
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_ASSERT (it != NULL); \
@@ -720,7 +720,7 @@
} \
\
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); \
it->index = org->index; \
@@ -729,14 +729,14 @@
} \
\
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); \
return it->index >= it->array->size; \
} \
\
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); \
/* NOTE: Can not compute 'size-1' due to potential overflow \
@@ -745,7 +745,7 @@
} \
\
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) \
{ \
M_ASSERT(it1 != NULL && it2 != NULL); \
@@ -753,14 +753,14 @@
} \
\
static inline void \
M_C(name, _next)(it_t it) \
M_F(name, _next)(it_t it) \
{ \
M_ASSERT(it != NULL && it->array != NULL); \
it->index ++; \
} \
\
static inline void \
M_C(name, _previous)(it_t it) \
M_F(name, _previous)(it_t it) \
{ \
M_ASSERT(it != NULL && it->array != NULL); \
/* NOTE: In the case index=0, it will be set to (unsigned) -1 \
@@ -769,43 +769,43 @@
} \
\
static inline type * \
M_C(name, _ref)(const it_t it) \
M_F(name, _ref)(const it_t it) \
{ \
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 * \
M_C(name, _cref)(const it_t it) \
M_F(name, _cref)(const it_t it) \
{ \
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)( \
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); \
size_t index = M_C(name, _end_p)(it) ? 0 : it->index+1; \
M_C(name, _push_at)(a, index, x); \
size_t index = M_F(name, _end_p)(it) ? 0 : it->index+1; \
M_F(name, _push_at)(a, index, x); \
it->index = index; \
} \
, /* End of INIT_SET */ ) \
\
M_IF_AT_LEAST_METHOD(SET, INIT_MOVE, oplist)( \
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_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 */ \
} \
, /* End of SET | INIT_SET */ ) \
\
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)) \
{ \
/* Using qsort is more compact but slower than a full templated \
@@ -889,7 +889,7 @@
} \
\
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)) \
return; \
@@ -908,7 +908,7 @@
\
M_IF_METHOD(EQUAL, oplist)( \
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) \
{ \
M_ARRA4_CONTRACT(array1); \
@@ -916,8 +916,8 @@
if (array1->size != array2->size) return false; \
size_t i; \
for(i = 0; i < array1->size; i++) { \
type const *item1 = M_C(name, _cget)(array1, i); \
type const *item2 = M_C(name, _cget)(array2, i); \
type const *item1 = M_F(name, _cget)(array1, i); \
type const *item2 = M_F(name, _cget)(array2, i); \
bool b = M_CALL_EQUAL(oplist, *item1, *item2); \
if (!b) return false; \
} \
@@ -927,7 +927,7 @@
\
M_IF_METHOD(HASH, oplist)( \
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_HASH_DECL(hash); \
@@ -940,7 +940,7 @@
, /* no HASH */ ) \
\
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(a2); \
@@ -973,18 +973,18 @@
\
M_IF_METHOD(GET_STR, oplist)( \
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) \
{ \
M_ARRA4_CONTRACT(array); \
(append ? m_string_cat_cstr : m_string_set_cstr) (str, "["); \
it_t it; \
for (M_C(name, _it)(it, array) ; \
!M_C(name, _end_p)(it); \
M_C(name, _next)(it)){ \
type const *item = M_C(name, _cref)(it); \
for (M_F(name, _it)(it, array) ; \
!M_F(name, _end_p)(it); \
M_F(name, _next)(it)){ \
type const *item = M_F(name, _cref)(it); \
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, ']'); \
@@ -993,13 +993,13 @@
\
M_IF_METHOD(OUT_STR, oplist)( \
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_ASSERT (file != NULL); \
fputc ('[', file); \
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); \
if (i != array->size-1) \
fputc (M_GET_SEPARATOR oplist, file); \
@@ -1010,11 +1010,11 @@
\
M_IF_METHOD2(PARSE_STR, INIT, oplist)( \
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_ASSERT (str != NULL); \
M_C(name,_reset)(array); \
M_F(name,_reset)(array); \
bool success = false; \
int c = *str++; \
if (M_UNLIKELY (c != '[')) goto exit; \
@@ -1028,7 +1028,7 @@
bool b = M_CALL_PARSE_STR(oplist, item, str, &str); \
do { c = *str++; } while (isspace(c)); \
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); \
M_ARRA4_CONTRACT(array); \
success = (c == ']'); \
@@ -1042,11 +1042,11 @@
\
M_IF_METHOD2(IN_STR, INIT, oplist)( \
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_ASSERT (file != NULL); \
M_C(name,_reset)(array); \
M_F(name,_reset)(array); \
int c = fgetc(file); \
if (M_UNLIKELY (c != '[')) return false; \
c = fgetc(file); \
@@ -1059,7 +1059,7 @@
bool b = M_CALL_IN_STR(oplist, item, file); \
do { c = fgetc(file); } while (isspace(c)); \
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); \
M_CALL_CLEAR(oplist, item); \
M_ARRA4_CONTRACT(array); \
@@ -1069,7 +1069,7 @@
\
M_IF_METHOD(OUT_SERIAL, oplist)( \
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_ASSERT (f != NULL && f->m_interface != NULL); \
@@ -1077,7 +1077,7 @@
m_serial_local_t local; \
ret = f->m_interface->write_array_start(local, f, array->size); \
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) { \
ret |= f->m_interface->write_array_next(local, f); \
} \
@@ -1090,28 +1090,28 @@
\
M_IF_METHOD2(IN_SERIAL, INIT, oplist)( \
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_ASSERT (f != NULL && f->m_interface != NULL); \
m_serial_return_code_t ret; \
m_serial_local_t local; \
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); \
if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) { \
return ret; \
} \
if (estimated_size != 0) { \
/* 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; \
M_CALL_INIT(oplist, item); \
do { \
ret = M_CALL_IN_SERIAL(oplist, item, f); \
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); \
} while (ret == M_SERIAL_OK_CONTINUE); \
M_CALL_CLEAR(oplist, item); \
@@ -1126,7 +1126,7 @@
function_name(name_t v \
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) ) \
return; \
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.
USAGE: BUFFER_DEF(name, type, size_of_buffer_or_0, policy[, oplist]) */
#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
@@ -85,7 +85,7 @@ typedef enum {
USAGE: QUEUE_MPMC_DEF(name, type, policy, [oplist of 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
@@ -110,7 +110,7 @@ typedef enum {
USAGE: QUEUE_SPSC_DEF(name, type, policy, [oplist of 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
@@ -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_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \
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 M_BUFF3R_DEF_TYPE(name, type, m_size, policy, oplist, buffer_t) \
\
/* 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 */ \
typedef union M_C(name, _el_s) { \
typedef union M_F(name, _el_s) { \
type x; \
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 */ \
m_mutex_t mutexPush; /* MUTEX used for pushing elements */ \
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 */ \
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 */ \
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]; \
\
typedef struct M_C(name, _s) *M_C(name, _ptr); \
typedef const struct M_C(name, _s) *M_C(name, _srcptr); \
typedef struct M_F(name, _s) *M_F(name, _ptr); \
typedef const struct M_F(name, _s) *M_F(name, _srcptr); \
/* 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 */ \
typedef type M_C(name, _subtype_ct); \
typedef buffer_t M_C(name, _ct); \
typedef type M_F(name, _subtype_ct); \
typedef buffer_t M_F(name, _ct); \
/* Define the core functionnalities of a buffer */
#define M_BUFF3R_DEF_CORE(name, type, m_size, policy, oplist, buffer_t) \
\
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_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 */ , \
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)) { \
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; \
} \
) \
@@ -337,7 +337,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
static inline void \
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 \
M_C(name, _clear)(buffer_t v) \
M_F(name, _clear)(buffer_t v) \
{ \
M_BUFF3R_CONTRACT(v,m_size); \
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 \
M_C(name, _reset)(buffer_t v) \
M_F(name, _reset)(buffer_t v) \
{ \
M_BUFF3R_CONTRACT(v,m_size); \
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 \
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 \
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) */ \
M_C(name, _uptr_ct) vu; \
M_F(name, _uptr_ct) vu; \
vu.cptr = src; \
M_C(name, _ptr) v = vu.ptr; \
M_F(name, _ptr) v = vu.ptr; \
M_ASSERT (dest != v); \
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)) { \
m_mutex_lock(v->mutexPush); \
m_mutex_lock(v->mutexPop); \
@@ -457,12 +457,12 @@ M_C(name, _init)(buffer_t v, size_t size) \
} \
\
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) */ \
M_C(name, _uptr_ct) vu; \
M_F(name, _uptr_ct) vu; \
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(v,m_size); \
\
@@ -527,7 +527,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
} \
\
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); \
/* 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 \
M_C(name, _full_p)(buffer_t v) \
M_F(name, _full_p)(buffer_t v) \
{ \
M_BUFF3R_CONTRACT(v,m_size); \
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 \
M_C(name, _size)(buffer_t v) \
M_F(name, _size)(buffer_t v) \
{ \
M_BUFF3R_CONTRACT(v,m_size); \
return m_buff3r_number_load (v->number[0], policy); \
} \
\
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); \
\
@@ -564,7 +564,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
if (!M_BUFF3R_POLICY_P((policy), M_BUFFER_THREAD_UNSAFE)) { \
m_mutex_lock(v->mutexPush); \
while (!M_BUFF3R_POLICY_P((policy), M_BUFFER_PUSH_OVERWRITE) \
&& M_C(name, _full_p)(v)) { \
&& M_F(name, _full_p)(v)) { \
if (!blocking) { \
m_mutex_unlock(v->mutexPush); \
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); \
} \
} 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; \
M_BUFF3R_PROTECTED_CONTRACT(policy, v, m_size); \
\
size_t previousSize, idx = v->idx_prod; \
/* INDEX computation if we have to overwrite the last element */ \
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++; \
/* Let's overwrite the last 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 \
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_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) */ \
if (!M_BUFF3R_POLICY_P((policy), M_BUFFER_THREAD_UNSAFE)) { \
m_mutex_lock(v->mutexPop); \
while (M_C(name, _empty_p)(v)) { \
while (M_F(name, _empty_p)(v)) { \
if (!blocking) { \
m_mutex_unlock(v->mutexPop); \
return false; \
} \
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; \
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 \
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)); \
} \
\
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)); \
} \
\
static inline size_t \
M_C(name, _overwrite)(const buffer_t v) \
M_F(name, _overwrite)(const buffer_t v) \
{ \
return v->overwrite; \
} \
\
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 */ \
return M_BUFF3R_SIZE(m_size); \
} \
\
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 */ \
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_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \
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 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 \
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 */ \
type x; \
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 \
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 */ \
M_CACHELINE_ALIGN(align1, atomic_uint); \
atomic_uint ConsoIdx; /* Can only increase until wrapping */ \
M_CACHELINE_ALIGN(align2, atomic_uint); \
M_C(name, _el_ct) *Tab; \
M_F(name, _el_ct) *Tab; \
unsigned int size; \
} buffer_t[1]; \
\
typedef type M_C(name, _subtype_ct); \
typedef buffer_t M_C(name, _ct); \
typedef type M_F(name, _subtype_ct); \
typedef buffer_t M_F(name, _ct); \
/* Define the core functionnalities of a MPMC queue */
#define M_QU3UE_MPMC_DEF_CORE(name, type, policy, oplist, buffer_t) \
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); \
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 \
M_C(name, _pop)(type *ptr, buffer_t table) \
M_F(name, _pop)(type *ptr, buffer_t table) \
{ \
M_QU3UE_MPMC_CONTRACT(table); \
M_ASSERT (ptr != NULL); \
@@ -897,7 +897,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
} \
\
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( 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->ConsoIdx, (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)) { \
M_MEMORY_FULL (size*sizeof(M_C(name, _el_ct) )); \
M_MEMORY_FULL (size*sizeof(M_F(name, _el_ct) )); \
return; \
} \
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 \
M_C(name, _clear)(buffer_t buffer) \
M_F(name, _clear)(buffer_t buffer) \
{ \
M_QU3UE_MPMC_CONTRACT(buffer); \
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 \
M_C(name, _size)(buffer_t table) \
M_F(name, _size)(buffer_t table) \
{ \
M_QU3UE_MPMC_CONTRACT(table); \
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 \
M_C(name, _capacity)(buffer_t v) \
M_F(name, _capacity)(buffer_t v) \
{ \
M_QU3UE_MPMC_CONTRACT(v); \
return v->size; \
} \
\
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 \
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_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \
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 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 \
will only read. As such, there is no concurrent write, and no \
need to align the structure for best performance. */ \
typedef struct M_C(name, _el_s) { \
typedef struct M_F(name, _el_s) { \
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 */ \
unsigned int size; \
M_C(name, _el_ct) *Tab; \
M_CACHELINE_ALIGN(align, atomic_uint, size_t, M_C(name, _el_ct) *); \
M_F(name, _el_ct) *Tab; \
M_CACHELINE_ALIGN(align, atomic_uint, size_t, M_F(name, _el_ct) *); \
atomic_uint prodIdx; /* Can only increase until overflow */ \
} buffer_t[1]; \
\
typedef type M_C(name, _subtype_ct); \
typedef buffer_t M_C(name, _ct); \
typedef type M_F(name, _subtype_ct); \
typedef buffer_t M_F(name, _ct); \
/* Define the core functionnalities of a SPSC queue */
#define M_QU3UE_SPSC_DEF_CORE(name, type, policy, oplist, buffer_t) \
\
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); \
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 \
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); \
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 \
M_C(name, _pop)(type *ptr, buffer_t table) \
M_F(name, _pop)(type *ptr, buffer_t table) \
{ \
M_QU3UE_SPSC_CONTRACT(table); \
M_ASSERT (ptr != NULL); \
@@ -1125,7 +1125,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
} \
\
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_ASSERT (x != NULL); \
@@ -1151,7 +1151,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
} \
\
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_ASSERT (ptr != NULL); \
@@ -1177,7 +1177,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
} \
\
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); \
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 \
M_C(name, _size)(buffer_t table) \
M_F(name, _size)(buffer_t table) \
{ \
M_QU3UE_SPSC_CONTRACT(table); \
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 \
M_C(name, _capacity)(buffer_t v) \
M_F(name, _capacity)(buffer_t v) \
{ \
return v->size; \
} \
\
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 \
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 \
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( 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->consoIdx, (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)) { \
M_MEMORY_FULL (size*sizeof(M_C(name, _el_ct) )); \
M_MEMORY_FULL (size*sizeof(M_F(name, _el_ct) )); \
return; \
} \
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 \
M_C(name, _clear)(buffer_t buffer) \
M_F(name, _clear)(buffer_t buffer) \
{ \
M_QU3UE_SPSC_CONTRACT(buffer); \
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 */
#define M_BUFF3R_OPLIST_P3(name, oplist) \
(INIT(M_C3(m_buff3r_,name, _init)) \
,INIT_SET(M_C(name, _init_set)) \
,SET(M_C(name, _set)) \
,CLEAR(M_C(name, _clear)) \
,INIT_SET(M_F(name, _init_set)) \
,SET(M_F(name, _set)) \
,CLEAR(M_F(name, _clear)) \
,NAME(name) \
,TYPE(M_C(name,_ct)) \
,SUBTYPE(M_C(name, _subtype_ct)) \
,RESET(M_C(name,_reset)) \
,PUSH(M_C(name,_push)) \
,POP(M_C(name,_pop)) \
,TYPE(M_F(name,_ct)) \
,SUBTYPE(M_F(name, _subtype_ct)) \
,RESET(M_F(name,_reset)) \
,PUSH(M_F(name,_push)) \
,POP(M_F(name,_pop)) \
,OPLIST(oplist) \
,EMPTY_P(M_C(name, _empty_p)), \
,GET_SIZE(M_C(name, _size)) \
,EMPTY_P(M_F(name, _empty_p)), \
,GET_SIZE(M_F(name, _size)) \
)
+120 -120
View File
@@ -46,55 +46,55 @@ M_BEGIN_PROTECTED_CODE
/* Classic internal Singly List without allocation */
#define M_CMEMP00L_DEF_SINGLY_LIST(name, type_t) \
\
typedef struct M_C(name, _slist_node_s) { \
struct M_C(name, _slist_node_s) *next; \
typedef struct M_F(name, _slist_node_s) { \
struct M_F(name, _slist_node_s) *next; \
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 \
M_C(name, _slist_init)(M_C(name, _slist_ct) list) \
M_F(name, _slist_init)(M_F(name, _slist_ct) list) \
{ \
*list = NULL; \
} \
\
static inline void \
M_C(name, _slist_push)(M_C(name, _slist_ct) list, \
M_C(name, _slist_node_ct) *node) \
M_F(name, _slist_push)(M_F(name, _slist_ct) list, \
M_F(name, _slist_node_ct) *node) \
{ \
node->next = *list; \
*list = node; \
} \
\
static inline M_C(name, _slist_node_ct) * \
M_C(name, _slist_pop)(M_C(name, _slist_ct) list) \
static inline M_F(name, _slist_node_ct) * \
M_F(name, _slist_pop)(M_F(name, _slist_ct) list) \
{ \
M_ASSERT (*list != NULL); \
M_C(name, _slist_node_ct) *node = *list; \
M_F(name, _slist_node_ct) *node = *list; \
*list = node->next; \
M_IF_DEBUG(node->next = NULL;) \
return node; \
} \
\
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; \
} \
\
static inline void \
M_C(name, _slist_move)(M_C(name, _slist_ct) list, \
M_C(name, _slist_ct) src) \
M_F(name, _slist_move)(M_F(name, _slist_ct) list, \
M_F(name, _slist_ct) src) \
{ \
*list = *src; \
*src = NULL; \
} \
\
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) { \
next = it->next; \
M_MEMORY_DEL(it); \
@@ -125,23 +125,23 @@ M_BEGIN_PROTECTED_CODE
to reduce memory consumption too (non compatible with C++ ...) */
#define M_CMEMP00L_DEF_LF_QUEUE(name, type_t) \
\
typedef struct M_C(name, _lf_node_s) { \
M_ATTR_EXTENSION _Atomic(struct M_C(name, _lf_node_s) *) next; \
typedef struct M_F(name, _lf_node_s) { \
M_ATTR_EXTENSION _Atomic(struct M_F(name, _lf_node_s) *) next; \
m_gc_atomic_ticket_ct cpt; \
M_C(name, _slist_ct) list; \
} M_C(name, _lf_node_t); \
M_F(name, _slist_ct) list; \
} M_F(name, _lf_node_t); \
\
typedef struct M_C(name, _lflist_s) { \
M_ATTR_EXTENSION _Atomic(M_C(name, _lf_node_t) *) head; \
typedef struct M_F(name, _lflist_s) { \
M_ATTR_EXTENSION _Atomic(M_F(name, _lf_node_t) *) head; \
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]; \
M_C(name, _lf_node_t) nil; \
} M_C(name, _lflist_ct)[1]; \
M_F(name, _lf_node_t) nil; \
} M_F(name, _lflist_ct)[1]; \
\
static inline void \
M_C(name, _lflist_init)(M_C(name, _lflist_ct) list, \
M_C(name, _lf_node_t) *node) \
M_F(name, _lflist_init)(M_F(name, _lflist_ct) list, \
M_F(name, _lf_node_t) *node) \
{ \
atomic_init(&list->head, node); \
atomic_init(&list->tail, node); \
@@ -149,17 +149,17 @@ M_BEGIN_PROTECTED_CODE
} \
\
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); \
} \
\
static inline void \
M_C(name, _lflist_push)(M_C(name, _lflist_ct) list, \
M_C(name, _lf_node_t) *node, m_core_backoff_ct bkoff) \
M_F(name, _lflist_push)(M_F(name, _lflist_ct) list, \
M_F(name, _lf_node_t) *node, m_core_backoff_ct bkoff) \
{ \
M_C(name, _lf_node_t) *tail; \
M_C(name, _lf_node_t) *next; \
M_F(name, _lf_node_t) *tail; \
M_F(name, _lf_node_t) *next; \
\
atomic_store_explicit(&node->next, &list->nil, memory_order_relaxed); \
m_core_backoff_reset(bkoff); \
@@ -190,12 +190,12 @@ M_BEGIN_PROTECTED_CODE
memory_order_relaxed); \
} \
\
static inline M_C(name, _lf_node_t) * \
M_C(name, _lflist_pop)(M_C(name, _lflist_ct) list, m_core_backoff_ct bkoff) \
static inline M_F(name, _lf_node_t) * \
M_F(name, _lflist_pop)(M_F(name, _lflist_ct) list, m_core_backoff_ct bkoff) \
{ \
M_C(name, _lf_node_t) *head; \
M_C(name, _lf_node_t) *tail; \
M_C(name, _lf_node_t) *next; \
M_F(name, _lf_node_t) *head; \
M_F(name, _lf_node_t) *tail; \
M_F(name, _lf_node_t) *next; \
\
/* Reinitialize backoff */ \
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, \
Therefore, we return the previous dummy head. \
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; \
} \
\
/* Dequeue a node if the node is old enough */ \
static inline M_C(name, _lf_node_t) * \
M_C(name, _lflist_pop_if)(M_C(name, _lflist_ct) list, \
static inline M_F(name, _lf_node_t) * \
M_F(name, _lflist_pop_if)(M_F(name, _lflist_ct) list, \
m_gc_ticket_ct age, m_core_backoff_ct bkoff) \
{ \
M_C(name, _lf_node_t) *head; \
M_C(name, _lf_node_t) *tail; \
M_C(name, _lf_node_t) *next; \
M_F(name, _lf_node_t) *head; \
M_F(name, _lf_node_t) *tail; \
M_F(name, _lf_node_t) *next; \
\
m_core_backoff_reset(bkoff); \
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; \
} \
\
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_init(bkoff); \
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; \
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); \
M_C(name, _slist_clear)(node->list); \
M_F(name, _slist_clear)(node->list); \
M_MEMORY_DEL(node); \
node = next; \
} \
/* 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); \
M_C(name, _slist_clear)(dummy->list); \
M_F(name, _slist_clear)(dummy->list); \
M_MEMORY_DEL(dummy); \
} \
@@ -306,26 +306,26 @@ M_BEGIN_PROTECTED_CODE
As such it is a non Lock-Free path. */
#define M_CMEMP00L_DEF_SYSTEM_ALLOC(name, type_t) \
\
static inline M_C(name, _lf_node_t) * \
M_C(name, _alloc_node)(unsigned int initial) \
static inline M_F(name, _lf_node_t) * \
M_F(name, _alloc_node)(unsigned int initial) \
{ \
M_C(name, _lf_node_t) * node; \
node = M_MEMORY_ALLOC(M_C(name, _lf_node_t)); \
M_F(name, _lf_node_t) * node; \
node = M_MEMORY_ALLOC(M_F(name, _lf_node_t)); \
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; \
} \
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); \
M_C(name, _slist_init)(node->list); \
M_F(name, _slist_init)(node->list); \
for(unsigned i = 0; i < initial; i++) { \
M_C(name, _slist_node_ct) *n; \
n = M_MEMORY_ALLOC(M_C(name, _slist_node_ct)); \
M_F(name, _slist_node_ct) *n; \
n = M_MEMORY_ALLOC(M_F(name, _slist_node_ct)); \
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; \
} \
M_C(name, _slist_push)(node->list, n); \
M_F(name, _slist_push)(node->list, n); \
} \
return node; \
} \
@@ -388,39 +388,39 @@ M_BEGIN_PROTECTED_CODE
*/
#define M_CMEMP00L_DEF_LFMP_THREAD_MEMPOOL(name, type_t) \
\
typedef struct M_C(name, _lfmp_thread_s) { \
M_C(name, _slist_ct) free; \
M_C(name, _slist_ct) to_be_reclaimed; \
M_CACHELINE_ALIGN(align1, M_C(name, _slist_ct), M_C(name, _slist_ct)); \
} M_C(name, _lfmp_thread_ct); \
typedef struct M_F(name, _lfmp_thread_s) { \
M_F(name, _slist_ct) free; \
M_F(name, _slist_ct) to_be_reclaimed; \
M_CACHELINE_ALIGN(align1, M_F(name, _slist_ct), M_F(name, _slist_ct)); \
} M_F(name, _lfmp_thread_ct); \
\
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_C(name, _slist_init)(t->to_be_reclaimed); \
M_F(name, _slist_init)(t->free); \
M_F(name, _slist_init)(t->to_be_reclaimed); \
} \
\
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_C(name, _slist_clear)(t->free); \
M_C(name, _slist_clear)(t->to_be_reclaimed); \
M_ASSERT(M_F(name, _slist_empty_p)(t->to_be_reclaimed)); \
M_F(name, _slist_clear)(t->free); \
M_F(name, _slist_clear)(t->to_be_reclaimed); \
} \
/* NOTE: once a node is deleted, its data are kept readable until the future GC */
#define M_CMEMP00L_DEF_LF_MEMPOOL(name, type_t) \
\
typedef struct M_C(name, _s) { \
typedef struct M_F(name, _s) { \
unsigned initial; \
M_C(name, _lfmp_thread_ct) *thread_data; \
M_C(name, _lflist_ct) free; \
M_C(name, _lflist_ct) to_be_reclaimed; \
M_C(name, _lflist_ct) empty; \
M_F(name, _lfmp_thread_ct) *thread_data; \
M_F(name, _lflist_ct) free; \
M_F(name, _lflist_ct) to_be_reclaimed; \
M_F(name, _lflist_ct) empty; \
m_cmemp00l_list_ct mempool_node; \
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 */ \
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) \
{ \
/* Get back the mempool from the node */ \
struct M_C(name, _s) *mempool = \
M_TYPE_FROM_FIELD(struct M_C(name, _s), data, m_cmemp00l_list_ct, mempool_node); \
struct M_F(name, _s) *mempool = \
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 */ \
if (!M_C(name, _slist_empty_p)(mempool->thread_data[id].to_be_reclaimed)) { \
M_C(name, _lf_node_t) *node; \
if (!M_F(name, _slist_empty_p)(mempool->thread_data[id].to_be_reclaimed)) { \
M_F(name, _lf_node_t) *node; \
/* 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)) { \
/* Fail to get an empty group of node. \
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(M_C(name, _slist_empty_p)(node->list)); \
M_C(name, _slist_move)(node->list, mempool->thread_data[id].to_be_reclaimed); \
M_ASSERT(M_F(name, _slist_empty_p)(node->list)); \
M_F(name, _slist_move)(node->list, mempool->thread_data[id].to_be_reclaimed); \
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 */ \
while (true) { \
M_C(name, _lf_node_t) *node; \
node = M_C(name, _lflist_pop_if)(mempool->to_be_reclaimed, \
M_F(name, _lf_node_t) *node; \
node = M_F(name, _lflist_pop_if)(mempool->to_be_reclaimed, \
min_ticket, gc_mem->thread_data[id].bkoff); \
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 \
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) \
{ \
const size_t max_thread = gc_mem->max_thread; \
/* 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)) { \
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; \
} \
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 */ \
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_C(name, _lflist_init)(mem->to_be_reclaimed, M_C(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->free, M_F(name, _alloc_node)(init_node_count)); \
M_F(name, _lflist_init)(mem->to_be_reclaimed, M_F(name, _alloc_node)(init_node_count)); \
M_F(name, _lflist_init)(mem->empty, M_F(name, _alloc_node)(0)); \
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); \
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); \
} \
/* Register the mempool in the GC */ \
@@ -491,55 +491,55 @@ M_BEGIN_PROTECTED_CODE
} \
\
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; \
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); \
mem->thread_data = NULL; \
M_C(name, _lflist_clear)(mem->empty); \
M_C(name, _lflist_clear)(mem->free); \
M_ASSERT(M_C(name, _lflist_empty_p)(mem->to_be_reclaimed)); \
M_C(name, _lflist_clear)(mem->to_be_reclaimed); \
M_F(name, _lflist_clear)(mem->empty); \
M_F(name, _lflist_clear)(mem->free); \
M_ASSERT(M_F(name, _lflist_empty_p)(mem->to_be_reclaimed)); \
M_F(name, _lflist_clear)(mem->to_be_reclaimed); \
/* TODO: Unregister from the GC? */ \
} \
\
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_C(name, _lf_node_t) *node; \
M_F(name, _slist_node_ct) *snode; \
M_F(name, _lf_node_t) *node; \
while (true) { \
/* 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))) { \
snode = M_C(name, _slist_pop)(mem->thread_data[id].free); \
if (M_LIKELY(!M_F(name, _slist_empty_p)(mem->thread_data[id].free))) { \
snode = M_F(name, _slist_pop)(mem->thread_data[id].free); \
return &snode->data; \
} \
/* 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)) { \
/* Request a new group to the system. Non Lock Free path */ \
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(!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 */ \
M_ASSERT (M_C(name, _slist_empty_p)(node->list)); \
M_C(name, _lflist_push)(mem->empty, node, mem->gc_mem->thread_data[id].bkoff); \
M_ASSERT (M_F(name, _slist_empty_p)(node->list)); \
M_F(name, _lflist_push)(mem->empty, node, mem->gc_mem->thread_data[id].bkoff); \
} \
} \
\
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); \
snode = M_TYPE_FROM_FIELD(M_C(name, _slist_node_ct), d, type_t, data); \
M_C(name, _slist_push)(mem->thread_data[id].to_be_reclaimed, snode); \
snode = M_TYPE_FROM_FIELD(M_F(name, _slist_node_ct), d, type_t, data); \
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.
USAGE: CONCURRENT_DEF(name, type [, oplist_of_the_type]) */
#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
@@ -52,7 +52,7 @@
can be done in parallel.
USAGE: CONCURRENT_RP_DEF(name, type [, oplist_of_the_type]) */
#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
@@ -98,38 +98,38 @@
destroyed by another thread).
*/
#define M_C0NCURRENT_OPLIST_P3(name, oplist) \
(M_IF_METHOD(INIT, oplist)(INIT(M_C(name, _init)),) \
,M_IF_METHOD(INIT_SET, oplist)(INIT_SET(M_C(name, _init_set)),) \
,M_IF_METHOD(SET, oplist)(SET(M_C(name, _set)),) \
,M_IF_METHOD(CLEAR, oplist)(CLEAR(M_C(name, _clear)),) \
,M_IF_METHOD(INIT_MOVE, oplist)(INIT_MOVE(M_C(name, _init_move)),) \
,M_IF_METHOD(MOVE, oplist)(MOVE(M_C(name, _move)),) \
,M_IF_METHOD(SWAP,oplist)(SWAP(M_C(name, _swap)),) \
(M_IF_METHOD(INIT, oplist)(INIT(M_F(name, _init)),) \
,M_IF_METHOD(INIT_SET, oplist)(INIT_SET(M_F(name, _init_set)),) \
,M_IF_METHOD(SET, oplist)(SET(M_F(name, _set)),) \
,M_IF_METHOD(CLEAR, oplist)(CLEAR(M_F(name, _clear)),) \
,M_IF_METHOD(INIT_MOVE, oplist)(INIT_MOVE(M_F(name, _init_move)),) \
,M_IF_METHOD(MOVE, oplist)(MOVE(M_F(name, _move)),) \
,M_IF_METHOD(SWAP,oplist)(SWAP(M_F(name, _swap)),) \
,NAME(name) \
,TYPE(M_C(name,_ct)) \
,SUBTYPE(M_C(name, _subtype_ct)) \
,TYPE(M_F(name,_ct)) \
,SUBTYPE(M_F(name, _subtype_ct)) \
,OPLIST(oplist) \
,M_IF_METHOD(EMPTY_P, oplist)(EMPTY_P(M_C(name,_empty_p)),) \
,M_IF_METHOD(GET_SIZE, oplist)(GET_SIZE(M_C(name,_size)),) \
,M_IF_METHOD(RESET, oplist)(RESET(M_C(name,_reset)),) \
,M_IF_METHOD(EMPTY_P, oplist)(EMPTY_P(M_F(name,_empty_p)),) \
,M_IF_METHOD(GET_SIZE, oplist)(GET_SIZE(M_F(name,_size)),) \
,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(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(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(ERASE_KEY, oplist)(ERASE_KEY(M_C(name, _erase)),) \
,M_IF_METHOD(PUSH, oplist)(PUSH(M_C(name,_push)),) \
,M_IF_METHOD(POP, oplist)(POP(M_C(name,_pop)),) \
,M_IF_METHOD(PUSH_MOVE, oplist)(PUSH_MOVE(M_C(name,_push_move)),) \
,M_IF_METHOD(POP_MOVE, oplist)(POP_MOVE(M_C(name,_pop_move)),) \
,M_IF_METHOD(GET_STR, oplist)(GET_STR(M_C(name, _get_str)),) \
,M_IF_METHOD(PARSE_STR, oplist)(PARSE_STR(M_C(name, _parse_str)),) \
,M_IF_METHOD(OUT_STR, oplist)(OUT_STR(M_C(name, _out_str)),) \
,M_IF_METHOD(IN_STR, oplist)(IN_STR(M_C(name, _in_str)),) \
,M_IF_METHOD(OUT_SERIAL, oplist)(OUT_SERIAL(M_C(name, _out_serial)),) \
,M_IF_METHOD(IN_SERIAL, oplist)(IN_SERIAL(M_C(name, _in_serial)),) \
,M_IF_METHOD(EQUAL, oplist)(EQUAL(M_C(name, _equal_p)),) \
,M_IF_METHOD(HASH, oplist)(HASH(M_C(name, _hash)),) \
,M_IF_METHOD(SET_KEY, oplist)(SET_KEY(M_F(name, _set_at)),) \
,M_IF_METHOD(ERASE_KEY, oplist)(ERASE_KEY(M_F(name, _erase)),) \
,M_IF_METHOD(PUSH, oplist)(PUSH(M_F(name,_push)),) \
,M_IF_METHOD(POP, oplist)(POP(M_F(name,_pop)),) \
,M_IF_METHOD(PUSH_MOVE, oplist)(PUSH_MOVE(M_F(name,_push_move)),) \
,M_IF_METHOD(POP_MOVE, oplist)(POP_MOVE(M_F(name,_pop_move)),) \
,M_IF_METHOD(GET_STR, oplist)(GET_STR(M_F(name, _get_str)),) \
,M_IF_METHOD(PARSE_STR, oplist)(PARSE_STR(M_F(name, _parse_str)),) \
,M_IF_METHOD(OUT_STR, oplist)(OUT_STR(M_F(name, _out_str)),) \
,M_IF_METHOD(IN_STR, oplist)(IN_STR(M_F(name, _in_str)),) \
,M_IF_METHOD(OUT_SERIAL, oplist)(OUT_SERIAL(M_F(name, _out_serial)),) \
,M_IF_METHOD(IN_SERIAL, oplist)(IN_SERIAL(M_F(name, _in_serial)),) \
,M_IF_METHOD(EQUAL, oplist)(EQUAL(M_F(name, _equal_p)),) \
,M_IF_METHOD(HASH, oplist)(HASH(M_F(name, _hash)),) \
,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW oplist),) \
,M_IF_METHOD(REALLOC, oplist)(REALLOC(M_GET_REALLOC oplist),) \
,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL oplist),) \
@@ -162,7 +162,7 @@
- name: prefix to be used
- type: 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) \
M_C0NCURRENT_DEF_TYPE(name, type, oplist, concurrent_t) \
@@ -174,20 +174,20 @@
#define M_C0NCURRENT_DEF_TYPE(name, type, oplist, concurrent_t) \
\
/* Define a concurrent container using a lock */ \
typedef struct M_C(name, _s) { \
struct M_C(name, _s) *self; \
typedef struct M_F(name, _s) { \
struct M_F(name, _s) *self; \
m_mutex_t lock; \
m_cond_t there_is_data; /* condition raised when there is data */ \
type data; \
} concurrent_t[1]; \
\
/* Define alias for pointer types */ \
typedef struct M_C(name, _s) *M_C(name, _ptr); \
typedef const struct M_C(name, _s) *M_C(name, _srcptr); \
typedef struct M_F(name, _s) *M_F(name, _ptr); \
typedef const struct M_F(name, _s) *M_F(name, _srcptr); \
\
/* Internal types for oplist */ \
typedef concurrent_t M_C(name, _ct); \
typedef type M_C(name, _subtype_ct); \
typedef concurrent_t M_F(name, _ct); \
typedef type M_F(name, _subtype_ct); \
\
/* 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 \
sub-container. */ \
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_cond_init(out->there_is_data); \
@@ -208,7 +208,7 @@
/* Clear the fields of the concurrent object not associated to the \
sub-container. */ \
static inline void \
M_C(name, _internal_clear)(concurrent_t out) \
M_F(name, _internal_clear)(concurrent_t out) \
{ \
M_C0NCURRENT_CONTRACT(out); \
m_mutex_clear(out->lock); \
@@ -221,7 +221,7 @@
NOTE: This instance doesn't implement the read/write strategy, \
and only get the lock */ \
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_mutex_lock (out->self->lock); \
@@ -231,7 +231,7 @@
NOTE: This instance doesn't implement the read/write strategy, \
and only get the lock */ \
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_mutex_unlock (out->self->lock); \
@@ -240,7 +240,7 @@
/* Wait for a thread pushing some data in the container. \
CONSTRAINT: the read lock shall be get before calling this service */ \
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_cond_wait(out->self->there_is_data, out->self->lock); \
@@ -251,7 +251,7 @@
NOTE: This instance doesn't implement the read/write strategy, \
and only get the lock */ \
static inline void \
M_C(name, _write_lock)(concurrent_t out) \
M_F(name, _write_lock)(concurrent_t out) \
{ \
M_C0NCURRENT_CONTRACT(out); \
m_mutex_lock (out->lock); \
@@ -261,7 +261,7 @@
NOTE: This instance doesn't implement the read/write strategy, \
and only get the lock */ \
static inline void \
M_C(name, _write_unlock)(concurrent_t out) \
M_F(name, _write_unlock)(concurrent_t out) \
{ \
M_C0NCURRENT_CONTRACT(out); \
m_mutex_unlock (out->lock); \
@@ -270,7 +270,7 @@
/* Wait for a thread pushing some data in the container. \
CONSTRAINT: the write lock shall be get before calling this service */ \
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_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. \
CONSTRAINT: the write lock shall be get before calling this service */ \
static inline void \
M_C(name, _write_signal)(concurrent_t out) \
M_F(name, _write_signal)(concurrent_t out) \
{ \
M_C0NCURRENT_CONTRACT(out); \
/* We need to signal this to ALL waiting threads as multiple threads \
@@ -291,7 +291,7 @@
- name: prefix to be used
- type: 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
services. It is usually one service declared per service exported.
*/
@@ -299,9 +299,9 @@
\
M_IF_METHOD(INIT, oplist)( \
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_C0NCURRENT_CONTRACT(out); \
} \
@@ -309,21 +309,21 @@
\
M_IF_METHOD(INIT_SET, oplist)( \
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_ASSERT (out != src); \
M_C(name, _internal_init)(out); \
M_C(name, _read_lock)(src); \
M_F(name, _internal_init)(out); \
M_F(name, _read_lock)(src); \
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_IF_METHOD(SET, oplist)( \
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); \
if (M_UNLIKELY (out == src)) return; \
@@ -338,19 +338,19 @@
To avoid this problem, we **always** lock the mutex which address is \
the lowest. */ \
if (out < src) { \
M_C(name, _write_lock)(out); \
M_C(name, _read_lock)(src); \
M_F(name, _write_lock)(out); \
M_F(name, _read_lock)(src); \
} else { \
M_C(name, _read_lock)(src); \
M_C(name, _write_lock)(out); \
M_F(name, _read_lock)(src); \
M_F(name, _write_lock)(out); \
} \
M_CALL_SET(oplist, out->data, src->data); \
if (out < src) { \
M_C(name, _read_lock)(src); \
M_C(name, _write_unlock)(out); \
M_F(name, _read_lock)(src); \
M_F(name, _write_unlock)(out); \
} else { \
M_C(name, _write_unlock)(out); \
M_C(name, _read_unlock)(src); \
M_F(name, _write_unlock)(out); \
M_F(name, _read_unlock)(src); \
} \
M_C0NCURRENT_CONTRACT(out); \
} \
@@ -358,307 +358,307 @@
\
M_IF_METHOD(CLEAR, oplist)( \
static inline void \
M_C(name, _clear)(concurrent_t out) \
M_F(name, _clear)(concurrent_t out) \
{ \
M_C0NCURRENT_CONTRACT(out); \
/* No need to lock. A clear is supposed to be called when all operations \
of the container in other threads are terminated */ \
M_CALL_CLEAR(oplist, out->data); \
M_C(name, _internal_clear)(out); \
M_F(name, _internal_clear)(out); \
} \
,) \
\
M_IF_METHOD(INIT_MOVE, oplist)( \
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_ASSERT (out != 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_C(name, _internal_clear)(src); \
M_F(name, _internal_clear)(src); \
M_C0NCURRENT_CONTRACT(out); \
} \
,) \
\
M_IF_METHOD(MOVE, oplist)( \
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(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_C(name, _write_unlock)(out); \
M_C(name, _internal_clear)(src); \
M_F(name, _write_unlock)(out); \
M_F(name, _internal_clear)(src); \
M_C0NCURRENT_CONTRACT(out); \
} \
,) \
\
M_IF_METHOD(SWAP, oplist)( \
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(src); \
if (M_UNLIKELY (out == src)) return; \
/* See comment above */ \
if (out < src) { \
M_C(name, _write_lock)(out); \
M_C(name, _write_lock)(src); \
M_F(name, _write_lock)(out); \
M_F(name, _write_lock)(src); \
} else { \
M_C(name, _write_lock)(src); \
M_C(name, _write_lock)(out); \
M_F(name, _write_lock)(src); \
M_F(name, _write_lock)(out); \
} \
M_CALL_SWAP(oplist, out->data, src->data); \
if (out < src) { \
M_C(name, _write_unlock)(src); \
M_C(name, _write_unlock)(out); \
M_F(name, _write_unlock)(src); \
M_F(name, _write_unlock)(out); \
} else { \
M_C(name, _write_unlock)(out); \
M_C(name, _write_unlock)(src); \
M_F(name, _write_unlock)(out); \
M_F(name, _write_unlock)(src); \
} \
} \
,) \
\
M_IF_METHOD(RESET, oplist)( \
static inline void \
M_C(name, _reset)(concurrent_t out) \
M_F(name, _reset)(concurrent_t out) \
{ \
M_C0NCURRENT_CONTRACT(out); \
M_C(name, _write_lock)(out); \
M_F(name, _write_lock)(out); \
M_CALL_RESET(oplist, out->data); \
M_C(name, _write_unlock)(out); \
M_F(name, _write_unlock)(out); \
} \
,) \
\
M_IF_METHOD(EMPTY_P, oplist)( \
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_C(name, _read_lock)(out); \
M_F(name, _read_lock)(out); \
bool b = M_CALL_EMPTY_P(oplist, out->data); \
M_C(name, _read_unlock)(out); \
M_F(name, _read_unlock)(out); \
return b; \
} \
,) \
\
M_IF_METHOD(GET_SIZE, oplist)( \
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_C(name, _read_lock)(out); \
M_F(name, _read_lock)(out); \
size_t r = M_CALL_GET_SIZE(oplist, out->data); \
M_C(name, _read_unlock)(out); \
M_F(name, _read_unlock)(out); \
return r; \
} \
,) \
\
M_IF_METHOD(SET_KEY, oplist)( \
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_C(name, _write_lock)(out); \
M_F(name, _write_lock)(out); \
M_CALL_SET_KEY(oplist, out->data, key, data); \
M_C(name, _write_signal)(out); \
M_C(name, _write_unlock)(out); \
M_F(name, _write_signal)(out); \
M_F(name, _write_unlock)(out); \
} \
,) \
\
M_IF_METHOD(GET_KEY, oplist)( \
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_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); \
if (p != NULL) { \
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; \
} \
,) \
\
M_IF_METHOD(SAFE_GET_KEY, oplist)( \
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_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_ASSERT (p != NULL); \
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)( \
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_C(name, _write_lock)(out); \
M_F(name, _write_lock)(out); \
bool b = M_CALL_ERASE_KEY(oplist, out->data, key); \
/* We suppose that the container has 'infinite' capacity, so \
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; \
} \
,) \
\
M_IF_METHOD(PUSH, oplist)( \
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_C(name, _write_lock)(out); \
M_F(name, _write_lock)(out); \
M_CALL_PUSH(oplist, out->data, data); \
M_C(name, _write_signal)(out); \
M_C(name, _write_unlock)(out); \
M_F(name, _write_signal)(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)( \
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_C(name, _write_lock)(out); \
M_F(name, _write_lock)(out); \
M_CALL_POP(oplist, p, out->data); \
/* See comment above */ \
M_C(name, _write_unlock)(out); \
M_F(name, _write_unlock)(out); \
} \
,) \
\
M_IF_METHOD(PUSH_MOVE, oplist)( \
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_C(name, _write_lock)(out); \
M_F(name, _write_lock)(out); \
M_CALL_PUSH_MOVE(oplist, out->data, data); \
M_C(name, _write_signal)(out); \
M_C(name, _write_unlock)(out); \
M_F(name, _write_signal)(out); \
M_F(name, _write_unlock)(out); \
} \
,) \
\
M_IF_METHOD(POP_MOVE, oplist)( \
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_C(name, _write_lock)(out); \
M_F(name, _write_lock)(out); \
M_CALL_POP_MOVE(oplist, p, out->data); \
/* See comment above */ \
M_C(name, _write_unlock)(out); \
M_F(name, _write_unlock)(out); \
} \
,) \
\
M_IF_METHOD(GET_STR, oplist)( \
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_C(name, _read_lock)(out); \
M_F(name, _read_lock)(out); \
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)( \
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_C(name, _read_lock)(out); \
M_F(name, _read_lock)(out); \
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)( \
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_C(name, _write_lock)(out); \
M_F(name, _write_lock)(out); \
bool b = M_CALL_PARSE_STR(oplist, out->data, str, e); \
M_C(name, _write_signal)(out); \
M_C(name, _write_unlock)(out); \
M_F(name, _write_signal)(out); \
M_F(name, _write_unlock)(out); \
return b; \
} \
,) \
\
M_IF_METHOD(IN_STR, oplist)( \
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_C(name, _write_lock)(out); \
M_F(name, _write_lock)(out); \
bool b = M_CALL_IN_STR(oplist, out->data, f); \
M_C(name, _write_signal)(out); \
M_C(name, _write_unlock)(out); \
M_F(name, _write_signal)(out); \
M_F(name, _write_unlock)(out); \
return b; \
} \
,) \
\
M_IF_METHOD(OUT_SERIAL, oplist)( \
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_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_C(name, _read_unlock)(out); \
M_F(name, _read_unlock)(out); \
return r; \
} \
,) \
\
M_IF_METHOD(IN_SERIAL, oplist)( \
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_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_C(name, _write_signal)(out); \
M_C(name, _write_unlock)(out); \
M_F(name, _write_signal)(out); \
M_F(name, _write_unlock)(out); \
return r; \
} \
,) \
\
M_IF_METHOD(EQUAL, oplist)( \
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(out2); \
if (M_UNLIKELY (out1 == out2)) return true; \
/* See comment above on mutal mutexs */ \
if (out1 < out2) { \
M_C(name, _read_lock)(out1); \
M_C(name, _read_lock)(out2); \
M_F(name, _read_lock)(out1); \
M_F(name, _read_lock)(out2); \
} else { \
M_C(name, _read_lock)(out2); \
M_C(name, _read_lock)(out1); \
M_F(name, _read_lock)(out2); \
M_F(name, _read_lock)(out1); \
} \
bool b = M_CALL_EQUAL(oplist, out1->data, out2->data); \
if (out1 < out2) { \
M_C(name, _read_unlock)(out2); \
M_C(name, _read_unlock)(out1); \
M_F(name, _read_unlock)(out2); \
M_F(name, _read_unlock)(out1); \
} else { \
M_C(name, _read_unlock)(out1); \
M_C(name, _read_unlock)(out2); \
M_F(name, _read_unlock)(out1); \
M_F(name, _read_unlock)(out2); \
} \
return b; \
} \
@@ -666,12 +666,12 @@
\
M_IF_METHOD(GET_KEY, oplist)( \
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_ASSERT (out_data != NULL); \
bool ret = false; \
M_C(name, _read_lock)(out); \
M_F(name, _read_lock)(out); \
while (true) { \
M_GET_VALUE_TYPE oplist *p = M_CALL_GET_KEY(oplist, out->data, key); \
if (p != NULL) { \
@@ -681,21 +681,21 @@
} \
if (blocking == false) break; \
/* 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; \
} \
,) \
\
M_IF_METHOD2(POP, EMPTY_P, oplist)( \
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_ASSERT (p != NULL); \
bool ret = false; \
M_C(name, _write_lock)(out); \
M_F(name, _write_lock)(out); \
while (true) { \
if (!M_CALL_EMPTY_P(oplist, out->data)) { \
M_CALL_POP(oplist, p, out->data); \
@@ -704,21 +704,21 @@
} \
if (blocking == false) break; \
/* 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; \
} \
,) \
\
M_IF_METHOD2(POP_MOVE, EMPTY_P, oplist)( \
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_ASSERT (p != NULL); \
bool ret = false; \
M_C(name, _write_lock)(out); \
M_F(name, _write_lock)(out); \
while (true) { \
if (!M_CALL_EMPTY_P(oplist, out->data)) { \
M_CALL_POP_MOVE(oplist, p, out->data); \
@@ -727,21 +727,21 @@
} \
if (blocking == false) break; \
/* 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; \
} \
,) \
\
M_IF_METHOD(HASH, oplist)( \
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_C(name, _read_lock)(out); \
M_F(name, _read_lock)(out); \
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 */ \
return h; \
} \
@@ -766,7 +766,7 @@
- name: prefix to be used
- type: 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) \
M_C0NCURRENT_RP_DEF_TYPE(name, type, oplist, concurrent_t) \
@@ -777,8 +777,8 @@
/* Define the type of a RP concurrent container */
#define M_C0NCURRENT_RP_DEF_TYPE(name, type, oplist, concurrent_t) \
\
typedef struct M_C(name, _s) { \
struct M_C(name, _s) *self; \
typedef struct M_F(name, _s) { \
struct M_F(name, _s) *self; \
m_mutex_t lock; \
m_cond_t rw_done; \
size_t read_count; \
@@ -787,16 +787,16 @@
type data; \
} concurrent_t[1]; \
\
typedef struct M_C(name, _s) *M_C(name, _ptr); \
typedef const struct M_C(name, _s) *M_C(name, _srcptr); \
typedef struct M_F(name, _s) *M_F(name, _ptr); \
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 M_C0NCURRENT_RP_DEF_CORE(name, type, oplist, concurrent_t) \
\
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_cond_init(out->rw_done); \
@@ -808,7 +808,7 @@
} \
\
static inline void \
M_C(name, _internal_clear)(concurrent_t out) \
M_F(name, _internal_clear)(concurrent_t out) \
{ \
M_C0NCURRENT_CONTRACT(out); \
m_mutex_clear(out->lock); \
@@ -818,10 +818,10 @@
} \
\
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); \
struct M_C(name, _s) *self = out->self; \
struct M_F(name, _s) *self = out->self; \
m_mutex_lock (self->lock); \
while (self->writer_waiting == true) { \
m_cond_wait(self->rw_done, self->lock); \
@@ -831,10 +831,10 @@
} \
\
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); \
struct M_C(name, _s) *self = out->self; \
struct M_F(name, _s) *self = out->self; \
m_mutex_lock (self->lock); \
self->read_count --; \
if (self->read_count == 0) { \
@@ -844,7 +844,7 @@
} \
\
static inline void \
M_C(name, _write_lock)(concurrent_t out) \
M_F(name, _write_lock)(concurrent_t out) \
{ \
M_C0NCURRENT_CONTRACT(out); \
m_mutex_lock (out->lock); \
@@ -859,7 +859,7 @@
} \
\
static inline void \
M_C(name, _write_unlock)(concurrent_t out) \
M_F(name, _write_unlock)(concurrent_t out) \
{ \
M_C0NCURRENT_CONTRACT(out); \
m_mutex_lock (out->lock); \
@@ -869,10 +869,10 @@
} \
\
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); \
struct M_C(name, _s) *self = out->self; \
struct M_F(name, _s) *self = out->self; \
M_ASSERT (self == out); \
m_mutex_lock (out->self->lock); \
self->read_count --; \
@@ -888,7 +888,7 @@
} \
\
static inline void \
M_C(name, _write_wait)(concurrent_t out) \
M_F(name, _write_wait)(concurrent_t out) \
{ \
M_C0NCURRENT_CONTRACT(out); \
m_mutex_lock (out->lock); \
@@ -906,7 +906,7 @@
} \
\
static inline void \
M_C(name, _write_signal)(concurrent_t out) \
M_F(name, _write_signal)(concurrent_t out) \
{ \
M_C0NCURRENT_CONTRACT(out); \
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__)
/* 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 */
#define M_INVI_0 1
#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.
*/
#define M_CLASSIC_OPLIST(name) ( \
INIT(M_C(name, _init)), \
INIT_SET(M_C(name, _init_set)), \
SET(M_C(name, _set)), \
CLEAR(M_C(name, _clear)), \
TYPE(M_C(name, _t)) )
INIT(M_F(name, _init)), \
INIT_SET(M_F(name, _init_set)), \
SET(M_F(name, _set)), \
CLEAR(M_F(name, _clear)), \
TYPE(M_F(name, _t)) )
/* 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) \
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) \
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_QUEUE_DEF(name, name_t, M_C(name, _get_emplace), key_oplist, M_EMPLACE_GET_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_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) \
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_C(name, _get_emplace), key_oplist, M_EMPLACE_GET_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_F(name, _get_emplace), key_oplist, M_EMPLACE_GET_GENE)
/* 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(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_C(name, _value_ct) *val; \
val = M_C(name, _safe_get)(v, key); \
M_F(name, _value_ct) *val; \
val = M_F(name, _safe_get)(v, key); \
M_CALL_CLEAR(val_oplist, *val); \
M_EMPLACE_CALL_FUNC(aval, val_init_func, val_oplist, *val, val_emplace_type); \
M_CALL_CLEAR(key_oplist, key); \
@@ -4731,21 +4748,21 @@ m_core_parse2_enum (const char str[], const char **endptr)
static inline void \
function_name(name_t v \
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_C(name, _set_at)(v, key, val); \
M_F(name, _set_at)(v, key, val); \
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) \
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_C(name, _value_ct) *val; \
val = M_C(name, _safe_get)(v, key); \
M_F(name, _value_ct) *val; \
val = M_F(name, _safe_get)(v, key); \
M_CALL_CLEAR(val_oplist, *val); \
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_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); \
}
@@ -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.
*/
#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 \
M_EMPLACE_LIST_TYPE_VAR(a, exp_emplace_type) ) \
{ \
M_GET_TYPE oplist data; \
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); \
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, ...)
*/
#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'
@@ -66,7 +66,7 @@
* 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, ...) \
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'
@@ -111,9 +111,9 @@
/* Specialization of the OPLIST in function if there is at least one member or not */
#define M_FUNC0BJ_INS_NO_ATTR_OPLIST(name) ( \
NAME(name), \
TYPE(M_C(name, _ct)), \
CLEAR(M_C(name, _clear)), \
INIT(M_C(name,_init)) \
TYPE(M_F(name, _ct)), \
CLEAR(M_F(name, _clear)), \
INIT(M_F(name,_init)) \
)
/* Validate the oplist before going further */
@@ -127,10 +127,10 @@
/* Define the oplist of the instance */
#define M_FUNC0BJ_INS_ATTR_OPLIST_P3(name, ...) ( \
NAME(name), \
TYPE(M_C(name, _ct)), \
INIT_WITH(M_C(name, _init_with)), \
CLEAR(M_C(name, _clear)), \
M_IF_METHOD_ALL(INIT, __VA_ARGS__)(INIT(M_C(name,_init)),), \
TYPE(M_F(name, _ct)), \
INIT_WITH(M_F(name, _init_with)), \
CLEAR(M_F(name, _clear)), \
M_IF_METHOD_ALL(INIT, __VA_ARGS__)(INIT(M_F(name,_init)),), \
PROPERTIES(( LET_AS_INIT_WITH(1) )) \
)
@@ -140,29 +140,29 @@
/* Specialization of the definition a function object interface of name 'name'
* with a function like "retcode (void)" that doesn't have any input parameters.
* Define the following types to be used by instance:
* - M_C(name, _retcode_ct): internal type of the return code
* - M_C(name, _callback_ct): internal type of the callback.
* - M_C(name, _ct): synonym of main type used by oplist.
* - M_F(name, _retcode_ct): internal type of the return code
* - M_F(name, _callback_ct): internal type of the callback.
* - M_F(name, _ct): synonym of main type used by oplist.
*/
#define M_FUNC0BJ_ITF_NO_PARAM_DEF(name, interface_t, retcode) \
\
/* Forward declaration */ \
struct M_C(name, _s); \
struct M_F(name, _s); \
\
/* Internal type for instance */ \
typedef retcode M_C(name, _retcode_ct); \
typedef retcode M_F(name, _retcode_ct); \
/* 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) { \
M_C(name, _callback_ct) callback; \
typedef struct M_F(name, _s) { \
M_F(name, _callback_ct) callback; \
} interface_t[1]; \
\
/* Internal type for oplist & instance */ \
typedef interface_t M_C(name, _ct); \
typedef interface_t M_F(name, _ct); \
\
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) \
funcobj->callback(funcobj); \
@@ -173,32 +173,32 @@
* with a function like retcode, type of param1, type of param 2, ...
* with mandatory input parameters.
* Define the following types to be used by instance:
* - M_C(name, _retcode_ct): internal type of the return code
* - M_C(name, _callback_ct): internal type of the callback.
* - M_F(name, _retcode_ct): internal type of the return code
* - M_F(name, _callback_ct): internal type of the callback.
* - 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, ...) \
\
/* Forward declaration */ \
struct M_C(name, _s); \
struct M_F(name, _s); \
\
/* Internal types for instance */ \
typedef retcode M_C(name, _retcode_ct); \
typedef retcode M_F(name, _retcode_ct); \
/* Define types for all parameters */ \
M_MAP3(M_FUNC0BJ_BASE_TYPE, name, __VA_ARGS__) \
/* 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) { \
M_C(name, _callback_ct) callback; \
typedef struct M_F(name, _s) { \
M_F(name, _callback_ct) callback; \
} interface_t[1]; \
\
/* Internal type for oplist & instance */ \
typedef interface_t M_C(name, _ct); \
typedef interface_t M_F(name, _ct); \
\
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__) ) \
{ \
/* If the retcode is 'void', don't return the value of the callback */ \
@@ -213,48 +213,48 @@
* with no member attribute.
*/
#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; \
} instance_t[1]; \
\
/* 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) \
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)( \
/* No param */, \
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 */ \
callback_core; \
} \
\
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 \
M_C(name, _clear)(instance_t obj) \
M_F(name, _clear)(instance_t obj) \
{ \
(void) obj; /* nothing to do */ \
} \
\
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; \
} \
\
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 */
#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 */ \
M_C(base_name, _callback_ct) callback; \
/* All the member attribute of the Function Object */ \
@@ -302,12 +302,12 @@
} instance_t[1]; \
\
/* 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__) \
\
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)( \
/* No param */, \
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 */ \
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 */ \
callback_core; \
} \
\
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__); \
} \
\
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__); \
} \
\
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; \
} \
@@ -343,9 +343,9 @@
M_IF(M_FUNC0BJ_TEST_METHOD_P(INIT, __VA_ARGS)) \
( \
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__); \
} \
, /* END OF INIT METHOD */ ) \
+92 -92
View File
@@ -47,7 +47,7 @@
USAGE:
ILIST_DEF(name, type [, oplist_of_the_type]) */
#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
@@ -95,31 +95,31 @@ typedef struct m_il1st_head_s {
/* Define the oplist of an ilist of type */
#define M_IL1ST_OPLIST_P3(name, oplist) \
(INIT(M_C(name, _init)), \
CLEAR(M_C(name, _clear)), \
INIT_MOVE(M_C(name, _init_move)), \
MOVE(M_C(name, _move)), \
(INIT(M_F(name, _init)), \
CLEAR(M_F(name, _clear)), \
INIT_MOVE(M_F(name, _init_move)), \
MOVE(M_F(name, _move)), \
NAME(name), \
TYPE(M_C(name,_ct)), \
RESET(M_C(name,_reset)), \
SUBTYPE(M_C(name,_subtype_ct)), \
EMPTY_P(M_C(name,_empty_p)), \
IT_TYPE(M_C(name,_it_ct)), \
IT_FIRST(M_C(name,_it)), \
IT_SET(M_C(name,_it_set)), \
IT_LAST(M_C(name,_it_last)), \
IT_END(M_C(name,_it_end)), \
IT_END_P(M_C(name,_end_p)), \
IT_LAST_P(M_C(name,_last_p)), \
IT_EQUAL_P(M_C(name,_it_equal_p)), \
IT_NEXT(M_C(name,_next)), \
IT_PREVIOUS(M_C(name,_previous)), \
IT_REF(M_C(name,_ref)), \
IT_CREF(M_C(name,_cref)), \
IT_REMOVE(M_C(name,_remove)), \
M_IF_METHOD(NEW, oplist)(IT_INSERT(M_C(name,_insert)),), \
TYPE(M_F(name,_ct)), \
RESET(M_F(name,_reset)), \
SUBTYPE(M_F(name,_subtype_ct)), \
EMPTY_P(M_F(name,_empty_p)), \
IT_TYPE(M_F(name,_it_ct)), \
IT_FIRST(M_F(name,_it)), \
IT_SET(M_F(name,_it_set)), \
IT_LAST(M_F(name,_it_last)), \
IT_END(M_F(name,_it_end)), \
IT_END_P(M_F(name,_end_p)), \
IT_LAST_P(M_F(name,_last_p)), \
IT_EQUAL_P(M_F(name,_it_equal_p)), \
IT_NEXT(M_F(name,_next)), \
IT_PREVIOUS(M_F(name,_previous)), \
IT_REF(M_F(name,_ref)), \
IT_CREF(M_F(name,_cref)), \
IT_REMOVE(M_F(name,_remove)), \
M_IF_METHOD(NEW, oplist)(IT_INSERT(M_F(name,_insert)),), \
OPLIST(oplist), \
SPLICE_BACK(M_C(name,_splice_back)) \
SPLICE_BACK(M_F(name,_splice_back)) \
,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW 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 \
* to the front & back nodes */ \
typedef struct M_C(name, _s) { \
typedef struct M_F(name, _s) { \
struct m_il1st_head_s name; \
} list_t[1]; \
\
/* Define internal types pointers to such a list */ \
typedef struct M_C(name, _s) *M_C(name, _ptr); \
typedef const struct M_C(name, _s) *M_C(name, _srcptr); \
typedef struct M_F(name, _s) *M_F(name, _ptr); \
typedef const struct M_F(name, _s) *M_F(name, _srcptr); \
\
/* 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 *previous; \
struct m_il1st_head_s *current; \
@@ -193,15 +193,15 @@ typedef struct m_il1st_head_s {
} it_t[1]; \
\
/* Define types used by oplist */ \
typedef type M_C(name, _subtype_ct); \
typedef list_t M_C(name, _ct); \
typedef it_t M_C(name, _it_ct); \
typedef type M_F(name, _subtype_ct); \
typedef list_t M_F(name, _ct); \
typedef it_t M_F(name, _it_ct); \
/* Define core functions for intrusive lists */
#define M_IL1ST_DEF_CORE(name, type, oplist, list_t, it_t) \
\
static inline void \
M_C(name, _init)(list_t list) \
M_F(name, _init)(list_t list) \
{ \
M_ASSERT (list != NULL); \
list->name.next = &list->name; \
@@ -210,7 +210,7 @@ typedef struct m_il1st_head_s {
} \
\
static inline void \
M_C(name, _reset)(list_t list) \
M_F(name, _reset)(list_t list) \
{ \
M_IL1ST_CONTRACT(name, list); \
for(struct m_il1st_head_s *it = list->name.next, *next ; \
@@ -232,17 +232,17 @@ typedef struct m_il1st_head_s {
} \
\
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 */ \
M_C(name, _reset)(list); \
M_F(name, _reset)(list); \
/* For safety purpose (create invalid represenation of object) */ \
list->name.next = NULL; \
list->name.prev = NULL; \
} \
\
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); \
return list->name.next == &list->name; \
@@ -250,12 +250,12 @@ typedef struct m_il1st_head_s {
\
\
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_ASSERT (list != ref); \
M_C(name,_init)(list); \
if (!M_C(name,_empty_p)(ref)) { \
M_F(name,_init)(list); \
if (!M_F(name,_empty_p)(ref)) { \
list->name.next = ref->name.next; \
list->name.prev = ref->name.prev; \
list->name.next->prev = &list->name; \
@@ -267,14 +267,14 @@ typedef struct m_il1st_head_s {
} \
\
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_C(name, _init_move)(list, ref); \
M_F(name, _clear)(list); \
M_F(name, _init_move)(list, ref); \
} \
\
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); \
size_t s = 0; \
@@ -288,7 +288,7 @@ typedef struct m_il1st_head_s {
} \
\
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_ASSERT (obj != NULL); \
@@ -301,7 +301,7 @@ typedef struct m_il1st_head_s {
} \
\
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_ASSERT (obj != NULL); \
@@ -314,7 +314,7 @@ typedef struct m_il1st_head_s {
} \
\
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); \
/* 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 \
M_C(name, _init_field)(type *obj) \
M_F(name, _init_field)(type *obj) \
{ \
M_ASSERT (obj != NULL); \
/* 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 \
M_C(name, _unlink)(type *obj) \
M_F(name, _unlink)(type *obj) \
{ \
M_ASSERT (obj != NULL); \
/* 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 * \
M_C(name, _back)(const list_t list) \
M_F(name, _back)(const list_t 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, \
struct m_il1st_head_s, name); \
} \
\
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_ASSERT(!M_C(name, _empty_p)(list)); \
M_ASSERT(!M_F(name, _empty_p)(list)); \
return M_TYPE_FROM_FIELD(type, list->name.next, \
struct m_il1st_head_s, name); \
} \
\
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_ASSERT (obj != NULL); \
@@ -380,7 +380,7 @@ typedef struct m_il1st_head_s {
} \
\
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_ASSERT (obj != NULL); \
@@ -391,7 +391,7 @@ typedef struct m_il1st_head_s {
} \
\
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_ASSERT (it != NULL); \
@@ -403,7 +403,7 @@ typedef struct m_il1st_head_s {
} \
\
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); \
it->head = cit->head; \
@@ -414,7 +414,7 @@ typedef struct m_il1st_head_s {
} \
\
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_ASSERT (it != NULL); \
@@ -426,7 +426,7 @@ typedef struct m_il1st_head_s {
} \
\
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); \
it->head = list->name.next->prev; \
@@ -437,7 +437,7 @@ typedef struct m_il1st_head_s {
} \
\
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_IL1ST_NODE_CONTRACT(it->current); \
@@ -445,7 +445,7 @@ typedef struct m_il1st_head_s {
} \
\
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_IL1ST_NODE_CONTRACT(it->current); \
@@ -453,7 +453,7 @@ typedef struct m_il1st_head_s {
} \
\
static inline void \
M_C(name, _next)(it_t it) \
M_F(name, _next)(it_t it) \
{ \
M_ASSERT (it != NULL); \
/* Cannot check node for it->current: it may have been deleted! */ \
@@ -468,7 +468,7 @@ typedef struct m_il1st_head_s {
} \
\
static inline void \
M_C(name, _previous)(it_t it) \
M_F(name, _previous)(it_t it) \
{ \
M_ASSERT (it != NULL); \
/* Cannot check node for it->current: it may have been deleted! */ \
@@ -483,7 +483,7 @@ typedef struct m_il1st_head_s {
} \
\
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); \
/* No need to check for next & previous */ \
@@ -491,42 +491,42 @@ typedef struct m_il1st_head_s {
} \
\
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_IL1ST_NODE_CONTRACT(it->current); \
/* check if 'it' was not deleted */ \
M_ASSERT (it->current->next == it->next); \
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, \
struct m_il1st_head_s, name); \
} \
\
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); \
} \
\
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_NODE_CONTRACT(it->current); \
(void)list; /* list param is not used */ \
type *obj = M_TYPE_FROM_FIELD(type, it->current, \
struct m_il1st_head_s, name); \
M_C(name, _unlink)(obj); \
M_F(name, _unlink)(obj); \
M_CALL_CLEAR(oplist, obj); \
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)( \
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_NODE_CONTRACT(it->current); \
@@ -536,8 +536,8 @@ typedef struct m_il1st_head_s {
return ; \
} \
M_CALL_INIT_SET(oplist, *p, x); \
type *obj = M_C(name, _ref)(it); \
M_C(name, _push_after)(obj, p); \
type *obj = M_F(name, _ref)(it); \
M_F(name, _push_after)(obj, p); \
it->current = p; \
(void) list; \
M_IL1ST_CONTRACT(name, list); \
@@ -545,29 +545,29 @@ typedef struct m_il1st_head_s {
, /* NEW & INIT_SET not defined */) \
\
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_ASSERT (!M_C(name, _empty_p)(list)); \
type *obj = M_C(name, _back)(list); \
M_ASSERT (!M_F(name, _empty_p)(list)); \
type *obj = M_F(name, _back)(list); \
list->name.prev = list->name.prev->prev; \
list->name.prev->next = &list->name; \
return obj; \
} \
\
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_ASSERT (!M_C(name, _empty_p)(list)); \
type *obj = M_C(name, _front)(list); \
M_ASSERT (!M_F(name, _empty_p)(list)); \
type *obj = M_F(name, _front)(list); \
list->name.next = list->name.next->next; \
list->name.next->prev = &list->name; \
return obj; \
} \
\
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, list2); \
@@ -584,35 +584,35 @@ typedef struct m_il1st_head_s {
} \
\
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, ov); \
M_IL1ST_NODE_CONTRACT(it->current); \
M_ASSERT (it != NULL); \
(void) ov; \
type *obj = M_C(name, _ref)(it); \
M_C(name, _unlink)(obj); \
M_C(name, _push_back)(nv, obj); \
M_C(name, _next)(it); \
type *obj = M_F(name, _ref)(it); \
M_F(name, _unlink)(obj); \
M_F(name, _push_back)(nv, obj); \
M_F(name, _next)(it); \
M_IL1ST_CONTRACT(name, nv); \
M_IL1ST_CONTRACT(name, ov); \
} \
\
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) \
{ \
M_IL1ST_CONTRACT(name, nlist); \
M_IL1ST_CONTRACT(name, olist); \
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 */ \
(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; \
/* Remove object */ \
M_C(name, _unlink)(obj); \
M_F(name, _unlink)(obj); \
/* Push 'obj' after 'ref' */ \
struct m_il1st_head_s *next = ref->next; \
ref->next = &obj->name; \
@@ -620,7 +620,7 @@ typedef struct m_il1st_head_s {
obj->name.prev = ref; \
next->prev = &obj->name; \
/* Move iterator in old list */ \
M_C(name, _next)(opos); \
M_F(name, _next)(opos); \
/* Set npos iterator to new position of object */ \
npos->previous = ref; \
npos->current = &obj->name; \
@@ -630,7 +630,7 @@ typedef struct m_il1st_head_s {
} \
\
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, e); \
@@ -653,7 +653,7 @@ typedef struct m_il1st_head_s {
} \
\
static inline void \
M_C(name, _reverse)(list_t list) \
M_F(name, _reverse)(list_t list) \
{ \
M_IL1ST_CONTRACT(name, list); \
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.
NOTE: There can be only one interface of this kind in a 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). */
#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). */
#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.
USAGE: ISHARED_PTR_DEF(name, type, [, oplist]) */
#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
@@ -90,14 +90,14 @@ M_BEGIN_PROTECTED_CODE
// Define the oplist
#define M_ISHAR3D_PTR_OPLIST_P3(name, oplist) ( \
INIT(M_INIT_DEFAULT), \
INIT_SET(API_4(M_C(name, _init_set))), \
SET(M_C(name, _set) M_IPTR), \
CLEAR(M_C(name, _clear)), \
RESET(M_C(name, _reset) M_IPTR), \
INIT_SET(API_4(M_F(name, _init_set))), \
SET(M_F(name, _set) M_IPTR), \
CLEAR(M_F(name, _clear)), \
RESET(M_F(name, _reset) M_IPTR), \
NAME(name), \
TYPE(M_C(name, _ct)), \
TYPE(M_F(name, _ct)), \
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(REALLOC, oplist)(REALLOC(M_GET_REALLOC oplist),) \
,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL oplist),) \
@@ -129,27 +129,27 @@ M_BEGIN_PROTECTED_CODE
typedef type *shared_t; \
\
/* Define internal types for oplist */ \
typedef shared_t M_C(name, _ct); \
typedef type M_C(name, _subtype_ct); \
typedef shared_t M_F(name, _ct); \
typedef type M_F(name, _subtype_ct); \
/* Define the core functions */
#define M_ISHAR3D_PTR_DEF_CORE(name, type, oplist, 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 */ \
if (M_LIKELY (ptr != NULL)) { \
atomic_init(&ptr->M_C(name, _cpt), 2); \
atomic_init(&ptr->M_F(name, _cpt), 2); \
} \
return ptr; \
} \
\
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)) { \
int n = atomic_fetch_add(&(shared->M_C(name, _cpt)), 2); \
int n = atomic_fetch_add(&(shared->M_F(name, _cpt)), 2); \
(void) n; \
} \
return shared; \
@@ -160,38 +160,38 @@ M_BEGIN_PROTECTED_CODE
( \
/* This function is only for static object */ \
static inline shared_t \
M_C(name, _init_once)(type *shared) \
M_F(name, _init_once)(type *shared) \
{ \
if (M_LIKELY (shared != NULL)) { \
/* 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; \
do { \
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) { \
/* Partial initialization: _cpt is odd */ \
/* Call the INIT function once */ \
M_CALL_INIT(oplist, *shared); \
/* 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) { \
/* Not fully initialized yet: wait for initialization */ \
m_core_backoff_ct bkoff; \
m_core_backoff_init(bkoff); \
/* 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_ASSERT( (atomic_load(&(shared->M_C(name, _cpt)))&1) == 0); \
M_ASSERT( (atomic_load(&(shared->M_F(name, _cpt)))&1) == 0); \
} \
return shared; \
} \
, \
/* This function is only for dynamic object */ \
static inline shared_t \
M_C(name, _init_new)(void) \
M_F(name, _init_new)(void) \
{ \
type *ptr = M_CALL_NEW(oplist, type); \
if (M_UNLIKELY_NOMEM (ptr == NULL)) { \
@@ -199,17 +199,17 @@ M_BEGIN_PROTECTED_CODE
return NULL; \
} \
M_CALL_INIT(oplist, *ptr); \
atomic_init (&ptr->M_C(name, _cpt), 2); \
atomic_init (&ptr->M_F(name, _cpt), 2); \
return ptr; \
} \
/* End of NEW */) \
, /* End of INIT */) \
\
static inline void \
M_C(name, _clear)(shared_t shared) \
M_F(name, _clear)(shared_t shared) \
{ \
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_IF_DISABLED_METHOD(DEL, oplist)(, M_CALL_DEL(oplist, shared);) \
} \
@@ -217,27 +217,27 @@ M_BEGIN_PROTECTED_CODE
} \
\
static inline void \
M_C(name, _clear_ptr)(shared_t *shared) \
M_F(name, _clear_ptr)(shared_t *shared) \
{ \
M_ASSERT(shared != NULL); \
M_C(name, _clear)(*shared); \
M_F(name, _clear)(*shared); \
*shared = NULL; \
} \
\
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; \
} \
\
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); \
if (M_LIKELY (*ptr != shared)) { \
M_C(name, _clear)(*ptr); \
*ptr = M_C(name, _init_set)(shared); \
M_F(name, _clear)(*ptr); \
*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
*/
#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.
@@ -84,25 +84,25 @@
\
/* Define the type of element in a segment of the mempool. \
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; \
union M_C(name,_union_s) *next; \
} M_C(name,_union_ct); \
union M_F(name,_union_s) *next; \
} M_F(name,_union_ct); \
\
/* Define a segment of a mempool. \
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; \
struct M_C(name,_segment_s) *next; \
M_C(name,_union_ct) tab[M_USE_MEMPOOL_MAX_PER_SEGMENT(type)]; \
} M_C(name,_segment_ct); \
struct M_F(name,_segment_s) *next; \
M_F(name,_union_ct) tab[M_USE_MEMPOOL_MAX_PER_SEGMENT(type)]; \
} M_F(name,_segment_ct); \
\
/* Define a mempool. \
It is a pointer to the first free object within the segments \
and the segments themselves */ \
typedef struct M_C(name, _s) { \
M_C(name,_union_ct) *free_list; \
M_C(name,_segment_ct) *current_segment; \
typedef struct M_F(name, _s) { \
M_F(name,_union_ct) *free_list; \
M_F(name,_segment_ct) *current_segment; \
} name_t[1]; \
@@ -110,12 +110,12 @@
#define M_M3MPOOL_DEF_CORE(name, type, name_t) \
\
static inline void \
M_C(name,_init)(name_t mem) \
M_F(name,_init)(name_t mem) \
{ \
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)) { \
M_MEMORY_FULL(sizeof (M_C(name,_segment_ct))); \
M_MEMORY_FULL(sizeof (M_F(name,_segment_ct))); \
return; \
} \
mem->current_segment->next = NULL; \
@@ -124,12 +124,12 @@
} \
\
static inline void \
M_C(name,_clear)(name_t mem) \
M_F(name,_clear)(name_t mem) \
{ \
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) { \
M_C(name,_segment_ct) *next = segment->next; \
M_F(name,_segment_ct) *next = segment->next; \
M_MEMORY_DEL (segment); \
segment = next; \
} \
@@ -139,25 +139,25 @@
} \
\
static inline type * \
M_C(name,_alloc)(name_t mem) \
M_F(name,_alloc)(name_t mem) \
{ \
M_M3MPOOL_CONTRACT(mem, type); \
/* 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) { \
/* Yes, so return it, and pop it from the free list */ \
mem->free_list = ret->next; \
return &ret->t; \
} \
/* 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); \
unsigned int count = segment->count; \
/* If segment is full, allocate a new one from the system */ \
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)) { \
M_MEMORY_FULL(sizeof (M_C(name,_segment_ct))); \
M_MEMORY_FULL(sizeof (M_F(name,_segment_ct))); \
return NULL; \
} \
new_segment->next = segment; \
@@ -174,12 +174,12 @@
} \
\
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); \
/* NOTE: Unsafe cast: suppose that the given pointer \
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 */ \
ret->next = mem->free_list; \
mem->free_list = ret; \
+143 -143
View File
@@ -33,7 +33,7 @@
/* Define a prioqueue of a given type and its associated functions.
USAGE: PRIOQUEUE_DEF(name, type [, oplist_of_the_type]) */
#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.
@@ -73,38 +73,38 @@
/* Define oplist of a priority queue */
#define M_PR1OQUEUE_OPLIST_P3(name, oplist) \
(INIT(M_C(name, _init)) \
,INIT_SET(M_C(name, _init_set)) \
(INIT(M_F(name, _init)) \
,INIT_SET(M_F(name, _init_set)) \
,INIT_WITH(API_1(M_INIT_VAI)) \
,SET(M_C(name, _set)) \
,CLEAR(M_C(name, _clear)) \
,INIT_MOVE(M_C(name, _init_move)) \
,MOVE(M_C(name, _move)) \
,SWAP(M_C(name, _swap)) \
,SET(M_F(name, _set)) \
,CLEAR(M_F(name, _clear)) \
,INIT_MOVE(M_F(name, _init_move)) \
,MOVE(M_F(name, _move)) \
,SWAP(M_F(name, _swap)) \
,NAME(name) \
,TYPE(M_C(name,_ct)) \
,SUBTYPE(M_C(name, _subtype_ct)) \
,RESET(M_C(name,_reset)) \
,PUSH(M_C(name,_push)) \
,POP(M_C(name,_pop)) \
,TYPE(M_F(name,_ct)) \
,SUBTYPE(M_F(name, _subtype_ct)) \
,RESET(M_F(name,_reset)) \
,PUSH(M_F(name,_push)) \
,POP(M_F(name,_pop)) \
,OPLIST(oplist) \
,EMPTY_P(M_C(name, _empty_p)) \
,GET_SIZE(M_C(name, _size)) \
,IT_TYPE(M_C(name, _it_ct)) \
,IT_FIRST(M_C(name,_it)) \
,IT_END(M_C(name,_it_end)) \
,IT_SET(M_C(name,_it_set)) \
,IT_END_P(M_C(name,_end_p)) \
,IT_EQUAL_P(M_C(name,_it_equal_p)) \
,IT_LAST_P(M_C(name,_last_p)) \
,IT_NEXT(M_C(name,_next)) \
,IT_CREF(M_C(name,_cref)) \
,M_IF_METHOD(GET_STR, oplist)(GET_STR(M_C(name, _get_str)),) \
,M_IF_METHOD(PARSE_STR, oplist)(PARSE_STR(M_C(name, _parse_str)),) \
,M_IF_METHOD(OUT_STR, oplist)(OUT_STR(M_C(name, _out_str)),) \
,M_IF_METHOD(IN_STR, oplist)(IN_STR(M_C(name, _in_str)),) \
,M_IF_METHOD(OUT_SERIAL, oplist)(OUT_SERIAL(M_C(name, _out_serial)),) \
,M_IF_METHOD(IN_SERIAL, oplist)(IN_SERIAL(M_C(name, _in_serial)),) \
,EMPTY_P(M_F(name, _empty_p)) \
,GET_SIZE(M_F(name, _size)) \
,IT_TYPE(M_F(name, _it_ct)) \
,IT_FIRST(M_F(name,_it)) \
,IT_END(M_F(name,_it_end)) \
,IT_SET(M_F(name,_it_set)) \
,IT_END_P(M_F(name,_end_p)) \
,IT_EQUAL_P(M_F(name,_it_equal_p)) \
,IT_LAST_P(M_F(name,_last_p)) \
,IT_NEXT(M_F(name,_next)) \
,IT_CREF(M_F(name,_cref)) \
,M_IF_METHOD(GET_STR, oplist)(GET_STR(M_F(name, _get_str)),) \
,M_IF_METHOD(PARSE_STR, oplist)(PARSE_STR(M_F(name, _parse_str)),) \
,M_IF_METHOD(OUT_STR, oplist)(OUT_STR(M_F(name, _out_str)),) \
,M_IF_METHOD(IN_STR, oplist)(IN_STR(M_F(name, _in_str)),) \
,M_IF_METHOD(OUT_SERIAL, oplist)(OUT_SERIAL(M_F(name, _out_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) \
/* 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_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \
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_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 M_PR1OQUEUE_DEF_TYPE(name, type, oplist, prioqueue_t, it_t) \
\
/* Define the priority queue over the defined array */ \
typedef struct M_C(name, _s) { \
M_C(name, _array_t) array; \
typedef struct M_F(name, _s) { \
M_F(name, _array_t) array; \
} prioqueue_t[1]; \
/* Define the pointer references to the priority queue */ \
typedef struct M_C(name, _s) *M_C(name, _ptr); \
typedef const struct M_C(name, _s) *M_C(name, _srcptr); \
typedef struct M_F(name, _s) *M_F(name, _ptr); \
typedef const struct M_F(name, _s) *M_F(name, _srcptr); \
\
/* 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 */ \
typedef prioqueue_t M_C(name, _ct); \
typedef type M_C(name, _subtype_ct); \
typedef it_t M_C(name, _it_ct); \
typedef prioqueue_t M_F(name, _ct); \
typedef type M_F(name, _subtype_ct); \
typedef it_t M_F(name, _it_ct); \
/* Define the core functions */
#define M_PR1OQUEUE_DEF_CORE(name, type, oplist, prioqueue_t, it_t) \
\
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 \
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 \
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 \
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 \
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 \
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 \
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 \
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 \
M_C(name, _i_parent)(size_t i) \
M_F(name, _i_parent)(size_t i) \
{ \
M_ASSERT (i > 0); \
return (i - 1) / 2; \
} \
\
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); \
return 2*i + 1; \
} \
\
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); \
return 2*i + 2; \
} \
\
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), \
*M_C(name, _array_cget)(p->array, j)); \
return M_CALL_CMP(oplist, *M_F(name, _array_cget)(p->array, i), \
*M_F(name, _array_cget)(p->array, j)); \
} \
\
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 \
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 \
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 */ \
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 \
* 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) { \
size_t j = M_C(name, _i_parent)(i); \
if (M_C(name, _i_cmp)(p, j, i) <= 0) \
size_t j = M_F(name, _i_parent)(i); \
if (M_F(name, _i_cmp)(p, j, i) <= 0) \
break; \
M_C(name, _array_swap_at) (p->array, i, j); \
M_F(name, _array_swap_at) (p->array, i, j); \
i = j; \
} \
} \
\
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 \
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 */ \
size_t size = M_C(name, _array_size)(p->array)-1; \
M_C(name, _array_swap_at) (p->array, 0, size); \
size_t size = M_F(name, _array_size)(p->array)-1; \
M_F(name, _array_swap_at) (p->array, 0, size); \
/* 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 */ \
size_t i = 0; \
while (true) { \
size_t child = M_C(name, _i_lchild)(i); \
size_t child = M_F(name, _i_lchild)(i); \
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 \
&& M_C(name, _i_cmp)(p, otherChild, child) < 0 ) { \
&& M_F(name, _i_cmp)(p, otherChild, child) < 0 ) { \
child = otherChild; \
} \
if (M_C(name, _i_cmp)(p, i, child) <= 0) \
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; \
} \
} \
@@ -304,86 +304,86 @@
( \
/* EQUAL & CMP may be uncorrelated */ \
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 \
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; \
for(i = 0; i < size; i++) { \
/* 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; \
} \
return i; \
} \
\
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 */ \
size_t size = M_C(name, _array_size)(p->array); \
size_t i = M_C(name, _i_find)(p, x); \
size_t size = M_F(name, _array_size)(p->array); \
size_t i = M_F(name, _i_find)(p, x); \
/* If x is not found, then stop */ \
if (i >= size) \
return false; \
/* Swap the found item and the last element */ \
size--; \
M_C(name, _array_swap_at) (p->array, i, size); \
M_C(name, _array_pop_back)(NULL, p->array); \
M_F(name, _array_swap_at) (p->array, i, size); \
M_F(name, _array_pop_back)(NULL, p->array); \
/* Move back the last swapped element to its right position in the heap */ \
while (true) { \
size_t child = M_C(name, _i_lchild)(i); \
size_t child = M_F(name, _i_lchild)(i); \
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 \
&& M_C(name, _i_cmp)(p, otherChild, child) < 0 ) { \
&& M_F(name, _i_cmp)(p, otherChild, child) < 0 ) { \
child = otherChild; \
} \
if (M_C(name, _i_cmp)(p, i, child) <= 0) break; \
M_C(name, _array_swap_at) (p->array, i, child); \
if (M_F(name, _i_cmp)(p, i, child) <= 0) break; \
M_F(name, _array_swap_at) (p->array, i, child); \
i = child; \
} \
return true; \
} \
\
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 */ \
/* First pass: search for an item EQUAL to x */ \
size_t size = M_C(name, _array_size)(p->array); \
size_t i = M_C(name, _i_find)(p, xold); \
size_t size = M_F(name, _array_size)(p->array); \
size_t i = M_F(name, _i_find)(p, xold); \
/* We shall have found the item */ \
M_ASSERT (i < size); \
/* 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 */ \
M_C(name, _array_set_at) (p->array, i, xnew); \
M_F(name, _array_set_at) (p->array, i, xnew); \
if (cmp < 0) { \
/* Move back the updated element to its new position, further in the heap */ \
while (true) { \
size_t child = M_C(name, _i_lchild)(i); \
size_t child = M_F(name, _i_lchild)(i); \
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 \
&& M_C(name, _i_cmp)(p, otherChild, child) < 0 ) { \
&& M_F(name, _i_cmp)(p, otherChild, child) < 0 ) { \
child = otherChild; \
} \
if (M_C(name, _i_cmp)(p, i, child) <= 0) break; \
M_C(name, _array_swap_at) (p->array, i, child); \
if (M_F(name, _i_cmp)(p, i, child) <= 0) break; \
M_F(name, _array_swap_at) (p->array, i, child); \
i = child; \
} \
} else { \
/* Move back the updated element to its new position, nearest in the heap */ \
while (i > 0) { \
size_t parent = M_C(name, _i_parent)(i); \
if (M_C(name, _i_cmp)(p, parent, i) <= 0) break; \
M_C(name, _array_swap_at) (p->array, i, parent); \
size_t parent = M_F(name, _i_parent)(i); \
if (M_F(name, _i_cmp)(p, parent, i) <= 0) break; \
M_F(name, _array_swap_at) (p->array, i, parent); \
i = parent; \
} \
} \
@@ -395,113 +395,113 @@
\
/* Define iterators over the array iterator */ \
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 \
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 \
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 \
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 \
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 \
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 \
M_C(name, _it_equal_p)(const it_t it1, \
M_F(name, _it_equal_p)(const it_t it1, \
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 \
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 \
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 * \
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 M_PR1OQUEUE_DEF_IO(name, type, oplist, prioqueue_t, it_t) \
M_IF_METHOD(OUT_STR, oplist)( \
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 */) \
\
M_IF_METHOD(IN_STR, oplist)( \
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 */) \
\
M_IF_METHOD(GET_STR, oplist)( \
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 */) \
\
M_IF_METHOD(PARSE_STR, oplist)( \
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 */) \
\
M_IF_METHOD(OUT_SERIAL, oplist)( \
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 */) \
\
M_IF_METHOD2(IN_SERIAL, INIT, oplist)( \
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 */) \
+140 -140
View File
@@ -30,7 +30,7 @@
/* Define a Red/Black binary tree of a given type.
USAGE: RBTREE_DEF(name, type [, oplist_of_the_type]) */
#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
@@ -39,8 +39,8 @@
#define M_RBTREE_DEF_AS(name, name_t, it_t, ...) \
M_BEGIN_PROTECTED_CODE \
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__, 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_F(name, _node_ct), it_t ))) \
M_END_PROTECTED_CODE
@@ -72,43 +72,43 @@
NOTE: IT_REF is not exported so that the container appears as not modifiable
by algorithm.*/
#define M_RBTR33_OPLIST_P3(name, oplist) \
(INIT(M_C(name, _init)), \
INIT_SET(M_C(name, _init_set)), \
(INIT(M_F(name, _init)), \
INIT_SET(M_F(name, _init_set)), \
INIT_WITH(API_1(M_INIT_EMPLACE_VAI)), \
SET(M_C(name, _set)), \
CLEAR(M_C(name, _clear)), \
INIT_MOVE(M_C(name, _init_move)), \
MOVE(M_C(name, _move)), \
SWAP(M_C(name, _swap)), \
SET(M_F(name, _set)), \
CLEAR(M_F(name, _clear)), \
INIT_MOVE(M_F(name, _init_move)), \
MOVE(M_F(name, _move)), \
SWAP(M_F(name, _swap)), \
NAME(name), \
TYPE(M_C(name,_ct)), \
SUBTYPE(M_C(name, _subtype_ct)), \
EMPTY_P(M_C(name,_empty_p)), \
GET_SIZE(M_C(name, _size)), \
IT_TYPE(M_C(name, _it_ct)), \
IT_FIRST(M_C(name,_it)), \
IT_SET(M_C(name,_it_set)), \
IT_LAST(M_C(name,_it_last)), \
IT_END(M_C(name,_it_end)), \
IT_END_P(M_C(name,_end_p)), \
IT_LAST_P(M_C(name,_last_p)), \
IT_EQUAL_P(M_C(name,_it_equal_p)), \
IT_NEXT(M_C(name,_next)), \
IT_PREVIOUS(M_C(name,_previous)), \
IT_CREF(M_C(name,_cref)), \
IT_REMOVE(M_C(name,_remove)), \
RESET(M_C(name,_reset)), \
PUSH(M_C(name,_push)), \
GET_MIN(M_C(name,_min)), \
GET_MAX(M_C(name,_max)), \
M_IF_METHOD(GET_STR, oplist)(GET_STR(M_C(name, _get_str)),), \
M_IF_METHOD(PARSE_STR, oplist)(PARSE_STR(M_C(name, _parse_str)),), \
M_IF_METHOD(OUT_STR, oplist)(OUT_STR(M_C(name, _out_str)),), \
M_IF_METHOD(IN_STR, oplist)(IN_STR(M_C(name, _in_str)),), \
M_IF_METHOD(OUT_SERIAL, oplist)(OUT_SERIAL(M_C(name, _out_serial)),), \
M_IF_METHOD(IN_SERIAL, oplist)(IN_SERIAL(M_C(name, _in_serial)),), \
M_IF_METHOD(EQUAL, oplist)(EQUAL(M_C(name, _equal_p)),), \
M_IF_METHOD(HASH, oplist)(HASH(M_C(name, _hash)),) \
TYPE(M_F(name,_ct)), \
SUBTYPE(M_F(name, _subtype_ct)), \
EMPTY_P(M_F(name,_empty_p)), \
GET_SIZE(M_F(name, _size)), \
IT_TYPE(M_F(name, _it_ct)), \
IT_FIRST(M_F(name,_it)), \
IT_SET(M_F(name,_it_set)), \
IT_LAST(M_F(name,_it_last)), \
IT_END(M_F(name,_it_end)), \
IT_END_P(M_F(name,_end_p)), \
IT_LAST_P(M_F(name,_last_p)), \
IT_EQUAL_P(M_F(name,_it_equal_p)), \
IT_NEXT(M_F(name,_next)), \
IT_PREVIOUS(M_F(name,_previous)), \
IT_CREF(M_F(name,_cref)), \
IT_REMOVE(M_F(name,_remove)), \
RESET(M_F(name,_reset)), \
PUSH(M_F(name,_push)), \
GET_MIN(M_F(name,_min)), \
GET_MAX(M_F(name,_max)), \
M_IF_METHOD(GET_STR, oplist)(GET_STR(M_F(name, _get_str)),), \
M_IF_METHOD(PARSE_STR, oplist)(PARSE_STR(M_F(name, _parse_str)),), \
M_IF_METHOD(OUT_STR, oplist)(OUT_STR(M_F(name, _out_str)),), \
M_IF_METHOD(IN_STR, oplist)(IN_STR(M_F(name, _in_str)),), \
M_IF_METHOD(OUT_SERIAL, oplist)(OUT_SERIAL(M_F(name, _out_serial)),), \
M_IF_METHOD(IN_SERIAL, oplist)(IN_SERIAL(M_F(name, _in_serial)),), \
M_IF_METHOD(EQUAL, oplist)(EQUAL(M_F(name, _equal_p)),), \
M_IF_METHOD(HASH, oplist)(HASH(M_F(name, _hash)),) \
,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW oplist),) \
,M_IF_METHOD(REALLOC, oplist)(REALLOC(M_GET_REALLOC oplist),) \
,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL oplist),) \
@@ -183,7 +183,7 @@ typedef enum {
M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \
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_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 M_RBTR33_DEF_TYPE(name, type, oplist, tree_t, node_t, it_t) \
@@ -191,48 +191,48 @@ typedef enum {
/* Node of Red/Black tree. \
Each node has up to two child, a color (Red or black) \
and the data stored in it */ \
typedef struct M_C(name, _node_s) { \
struct M_C(name, _node_s) *child[2]; \
typedef struct M_F(name, _node_s) { \
struct M_F(name, _node_s) *child[2]; \
type data; \
m_rbtr33_color_e color; \
} node_t; \
\
/* 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 */ \
node_t *node; /* Root node of the tree */ \
} tree_t[1]; \
typedef struct M_C(name, _s) *M_C(name, _ptr); \
typedef const struct M_C(name, _s) *M_C(name, _srcptr); \
typedef struct M_F(name, _s) *M_F(name, _ptr); \
typedef const struct M_F(name, _s) *M_F(name, _srcptr); \
\
/* Iterator on a tree. The iterator stores the full path to the \
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]; \
int8_t which[M_RBTR33_MAX_STACK]; \
unsigned int cpt; \
} it_t[1]; \
\
/* Definition of the alias used by the oplists */ \
typedef type M_C(name, _subtype_ct); \
typedef tree_t M_C(name, _ct); \
typedef it_t M_C(name, _it_ct); \
typedef type M_F(name, _subtype_ct); \
typedef tree_t M_F(name, _ct); \
typedef it_t M_F(name, _it_ct); \
/* Define the mempool encapsulation */
#define M_RBTR33_DEF_MEMPOOL(name, type, oplist, tree_t, node_t, it_t) \
/* Link with fast memory allocator if requested */ \
M_IF_METHOD(MEMPOOL, oplist)( \
/* 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 */ \
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 */ \
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 */ \
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 */ \
@@ -249,7 +249,7 @@ typedef enum {
#define M_RBTR33_DEF_CORE(name, type, oplist, tree_t, node_t, it_t) \
\
static inline void \
M_C(name, _init)(tree_t tree) \
M_F(name, _init)(tree_t tree) \
{ \
M_ASSERT (tree != NULL); \
tree->size = 0; \
@@ -258,7 +258,7 @@ typedef enum {
} \
\
static inline void \
M_C(name, _reset)(tree_t tree) \
M_F(name, _reset)(tree_t tree) \
{ \
M_RBTR33_CONTRACT(tree); \
node_t *stack[M_RBTR33_MAX_STACK]; \
@@ -303,14 +303,14 @@ typedef enum {
} \
\
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 */ \
M_C(name, _reset)(tree); \
M_F(name, _reset)(tree); \
} \
\
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); \
node_t *tab[M_RBTR33_MAX_STACK]; \
@@ -436,7 +436,7 @@ typedef enum {
} \
\
static inline size_t \
M_C(name, _size)(const tree_t tree) \
M_F(name, _size)(const tree_t tree) \
{ \
M_RBTR33_CONTRACT (tree); \
return tree->size; \
@@ -466,19 +466,19 @@ typedef enum {
} \
\
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); \
} \
\
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); \
} \
\
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_ASSERT (it != NULL); \
@@ -487,14 +487,14 @@ typedef enum {
} \
\
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); \
*it = *ref; \
} \
\
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); \
return it->cpt == 0; \
@@ -534,19 +534,19 @@ typedef enum {
} \
\
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); \
} \
\
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); \
} \
\
static inline type * \
M_C(name, _ref)(const it_t it) \
M_F(name, _ref)(const it_t it) \
{ \
M_ASSERT(it != NULL); \
/* There shall be at least one element */ \
@@ -556,13 +556,13 @@ typedef enum {
} \
\
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 \
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); \
/* There can be no element */ \
@@ -573,7 +573,7 @@ typedef enum {
} \
\
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_ASSERT (it != NULL); \
@@ -597,12 +597,12 @@ typedef enum {
/* The iterator found may be strictly lower than data. \
In this case, go to the next element */ \
if (cmp < 0) { \
M_C(name, _next)(it); \
M_F(name, _next)(it); \
} \
} \
\
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); \
if (M_UNLIKELY(it->cpt == 0)) return true; \
@@ -613,7 +613,7 @@ typedef enum {
} \
\
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); \
if (M_UNLIKELY(it->cpt == 0)) return false; \
@@ -624,7 +624,7 @@ typedef enum {
} \
\
static inline type * \
M_C(name, _min)(const tree_t tree) \
M_F(name, _min)(const tree_t tree) \
{ \
M_RBTR33_CONTRACT (tree); \
node_t *n = tree->node; \
@@ -637,7 +637,7 @@ typedef enum {
} \
\
static inline type * \
M_C(name, _max)(const tree_t tree) \
M_F(name, _max)(const tree_t tree) \
{ \
M_RBTR33_CONTRACT (tree); \
node_t *n = tree->node; \
@@ -650,19 +650,19 @@ typedef enum {
} \
\
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 * \
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 * \
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); \
node_t *n = tree->node; \
@@ -681,9 +681,9 @@ typedef enum {
} \
\
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) */ \
@@ -704,7 +704,7 @@ typedef enum {
} \
\
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_ASSERT (tree != NULL && tree != ref); \
@@ -715,17 +715,17 @@ typedef enum {
} \
\
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 (ref); \
if (tree == ref) return; \
M_C(name,_clear)(tree); \
M_C(name,_init_set)(tree, ref); \
M_F(name,_clear)(tree); \
M_F(name,_init_set)(tree, ref); \
} \
\
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_ASSERT (tree != NULL && tree != ref); \
@@ -737,18 +737,18 @@ typedef enum {
} \
\
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 (ref); \
M_ASSERT (tree != ref); \
M_C(name,_clear)(tree); \
M_C(name,_init_move)(tree, ref); \
M_F(name,_clear)(tree); \
M_F(name,_init_move)(tree, ref); \
M_RBTR33_CONTRACT (tree); \
} \
\
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 (tree2); \
@@ -759,7 +759,7 @@ typedef enum {
} \
\
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); \
return tree->size == 0; \
@@ -805,7 +805,7 @@ typedef enum {
) \
\
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); \
node_t *tab[M_RBTR33_MAX_STACK]; \
@@ -964,22 +964,22 @@ typedef enum {
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 */ \
type data; \
M_CALL_INIT_SET(oplist, data, *M_C(name,_cref)(it)); \
M_C(name,_next)(it); \
M_C(name, _pop_at)(NULL, t, data); \
M_CALL_INIT_SET(oplist, data, *M_F(name,_cref)(it)); \
M_F(name,_next)(it); \
M_F(name, _pop_at)(NULL, t, data); \
/* We have changed the tree: the iterator is partialy invalid */ \
if (!M_C(name, _end_p)(it)) { \
M_C(name, _it_from)(it, t, *M_C(name,_cref)(it)); \
if (!M_F(name, _end_p)(it)) { \
M_F(name, _it_from)(it, t, *M_F(name,_cref)(it)); \
} \
M_CALL_CLEAR(oplist, data); \
} \
\
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(t2); \
if (t1->size != t2->size) return false; \
@@ -989,34 +989,34 @@ typedef enum {
structuraly different but functionnaly equal (you get this by \
constructing the tree in a different way). We have to \
compare the ordered value within the tree. */ \
M_C(name, _it)(it1, t1); \
M_C(name, _it)(it2, t2); \
while (!M_C(name, _end_p)(it1) \
&& !M_C(name, _end_p)(it2)) { \
type const *ref1 = M_C(name, _cref)(it1); \
type const *ref2 = M_C(name, _cref)(it2); \
M_F(name, _it)(it1, t1); \
M_F(name, _it)(it2, t2); \
while (!M_F(name, _end_p)(it1) \
&& !M_F(name, _end_p)(it2)) { \
type const *ref1 = M_F(name, _cref)(it1); \
type const *ref2 = M_F(name, _cref)(it2); \
if (M_CALL_EQUAL(oplist, *ref1, *ref2) == false) \
return false; \
M_C(name, _next)(it1); \
M_C(name, _next)(it2); \
M_F(name, _next)(it1); \
M_F(name, _next)(it2); \
} \
return M_C(name, _end_p)(it1) \
&& M_C(name, _end_p)(it2); \
return M_F(name, _end_p)(it1) \
&& M_F(name, _end_p)(it2); \
} \
, /* NO EQUAL METHOD */ ) \
\
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_HASH_DECL(hash); \
/* NOTE: We can't compute the hash directly for the same reason \
than for EQUAL operator. */ \
it_t it1; \
M_C(name, _it)(it1, t1); \
while (!M_C(name, _end_p)(it1)) { \
type const *ref1 = M_C(name, _cref)(it1); \
M_F(name, _it)(it1, t1); \
while (!M_F(name, _end_p)(it1)) { \
type const *ref1 = M_F(name, _cref)(it1); \
M_HASH_UP(hash, M_CALL_HASH(oplist, *ref1)); \
M_C(name, _next)(it1); \
M_F(name, _next)(it1); \
} \
return M_HASH_FINAL (hash); \
} \
@@ -1025,7 +1025,7 @@ typedef enum {
/* Define the I/O functions */
#define M_RBTR33_DEF_IO(name, type, oplist, tree_t, node_t, it_t) \
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) { \
M_RBTR33_CONTRACT(t1); \
M_ASSERT(str != NULL); \
@@ -1033,14 +1033,14 @@ typedef enum {
/* NOTE: The print is really naive, and not really efficient */ \
bool commaToPrint = false; \
it_t it1; \
M_C(name, _it)(it1, t1); \
while (!M_C(name, _end_p)(it1)) { \
M_F(name, _it)(it1, t1); \
while (!M_F(name, _end_p)(it1)) { \
if (commaToPrint) \
m_string_push_back (str, M_GET_SEPARATOR oplist); \
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_C(name, _next)(it1); \
M_F(name, _next)(it1); \
} \
m_string_push_back (str, ']'); \
} \
@@ -1048,20 +1048,20 @@ typedef enum {
\
M_IF_METHOD(OUT_STR, oplist)( \
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_ASSERT (file != NULL); \
fputc ('[', file); \
it_t it; \
bool commaToPrint = false; \
for (M_C(name, _it)(it, rbtree) ; \
!M_C(name, _end_p)(it); \
M_C(name, _next)(it)){ \
for (M_F(name, _it)(it, rbtree) ; \
!M_F(name, _end_p)(it); \
M_F(name, _next)(it)){ \
if (commaToPrint) \
fputc (M_GET_SEPARATOR oplist, file); \
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); \
} \
fputc (']', file); \
@@ -1070,11 +1070,11 @@ typedef enum {
\
M_IF_METHOD(PARSE_STR, oplist)( \
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_ASSERT (str != NULL); \
M_C(name,_reset)(rbtree); \
M_F(name,_reset)(rbtree); \
bool success = false; \
int c = *str++; \
if (M_UNLIKELY (c != '[')) goto exit; \
@@ -1088,7 +1088,7 @@ typedef enum {
bool b = M_CALL_PARSE_STR(oplist, item, str, &str); \
do { c = *str++; } while (isspace(c)); \
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); \
success = (c == ']'); \
exit_clear: \
@@ -1101,11 +1101,11 @@ typedef enum {
\
M_IF_METHOD(IN_STR, oplist)( \
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_ASSERT (file != NULL); \
M_C(name,_reset)(rbtree); \
M_F(name,_reset)(rbtree); \
int c = fgetc(file); \
if (M_UNLIKELY (c != '[')) return false; \
c = fgetc(file); \
@@ -1118,7 +1118,7 @@ typedef enum {
bool b = M_CALL_IN_STR(oplist, item, file); \
do { c = fgetc(file); } while (isspace(c)); \
if (b == false || c == EOF) break; \
M_C(name, _push)(rbtree, item); \
M_F(name, _push)(rbtree, item); \
} while (c == M_GET_SEPARATOR oplist); \
M_CALL_CLEAR(oplist, item); \
return c == ']'; \
@@ -1127,20 +1127,20 @@ typedef enum {
\
M_IF_METHOD(OUT_SERIAL, oplist)( \
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_ASSERT (f != NULL && f->m_interface != NULL); \
m_serial_local_t local; \
m_serial_return_code_t ret; \
M_C(name, _subtype_ct) const *item; \
M_F(name, _subtype_ct) const *item; \
bool first_done = false; \
it_t it; \
ret = f->m_interface->write_array_start(local, f, t1->size); \
for (M_C(name, _it)(it, t1) ; \
!M_C(name, _end_p)(it); \
M_C(name, _next)(it)){ \
item = M_C(name, _cref)(it); \
for (M_F(name, _it)(it, t1) ; \
!M_F(name, _end_p)(it); \
M_F(name, _next)(it)){ \
item = M_F(name, _cref)(it); \
if (first_done) \
ret |= f->m_interface->write_array_next(local, f); \
ret |= M_CALL_OUT_SERIAL(oplist, f, *item); \
@@ -1153,7 +1153,7 @@ typedef enum {
\
M_IF_METHOD(IN_SERIAL, oplist)( \
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_ASSERT (f != NULL && f->m_interface != NULL); \
@@ -1161,14 +1161,14 @@ typedef enum {
m_serial_return_code_t ret; \
size_t estimated_size = 0; \
type key; \
M_C(name,_reset)(t1); \
M_F(name,_reset)(t1); \
ret = f->m_interface->read_array_start(local, f, &estimated_size); \
if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) return ret; \
M_CALL_INIT(oplist, key); \
do { \
ret = M_CALL_IN_SERIAL(oplist, key, f); \
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); \
M_CALL_CLEAR(oplist, key); \
return ret; \
+63 -63
View File
@@ -34,7 +34,7 @@ M_BEGIN_PROTECTED_CODE
/* Define shared pointer and its function.
USAGE: SHARED_PTR_DEF(name, type, [, oplist]) */
#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
@@ -59,7 +59,7 @@ M_BEGIN_PROTECTED_CODE
/* Define relaxed shared pointer and its function (thread unsafe).
USAGE: SHARED_PTR_RELAXED_DEF(name, type, [, oplist]) */
#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)
@@ -77,7 +77,7 @@ M_BEGIN_PROTECTED_CODE
This is a bounded pool of resource shared by multiple owners.
USAGE: SHARED_RESOURCE_DEF(name, type, [, oplist]) */
#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
@@ -109,16 +109,16 @@ M_BEGIN_PROTECTED_CODE
((M_LIB_ERROR(ARGUMENT_OF_SHARED_PTR_OPLIST_IS_NOT_AN_OPLIST, name, oplist)))
#define M_SHAR3D_PTR_OPLIST_P3(name, oplist) ( \
INIT(M_C(name, _init)), \
CLEAR(M_C(name, _clear)), \
INIT_SET(M_C(name, _init_set)), \
SET(M_C(name, _set)) \
INIT_MOVE(M_C(name, _init_move)), \
RESET(M_C(name, _reset)), \
MOVE(M_C(name, _move)), \
SWAP(M_C(name, _swap)) \
INIT(M_F(name, _init)), \
CLEAR(M_F(name, _clear)), \
INIT_SET(M_F(name, _init_set)), \
SET(M_F(name, _set)) \
INIT_MOVE(M_F(name, _init_move)), \
RESET(M_F(name, _reset)), \
MOVE(M_F(name, _move)), \
SWAP(M_F(name, _swap)) \
,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(REALLOC, oplist)(REALLOC(M_GET_REALLOC 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 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 */ \
M_GET_TYPE cpt_oplist cpt; /* Counter of how many refs the data */ \
bool combineAlloc; /* Does the data and the ptr share the slot? */ \
} *shared_t[1]; \
typedef struct M_C(name, _s) *M_C(name, _ptr); \
typedef const struct M_C(name, _s) *M_C(name, _srcptr); \
typedef struct M_F(name, _s) *M_F(name, _ptr); \
typedef const struct M_F(name, _s) *M_F(name, _srcptr); \
\
/* 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; \
struct M_C(name, _s) ptr; \
} M_C(name, combine_ct)[1]; \
struct M_F(name, _s) ptr; \
} M_F(name, combine_ct)[1]; \
/* Define the core functions */
#define M_SHAR3D_PTR_DEF_CORE(name, type, oplist, cpt_oplist, shared_t) \
\
static inline void \
M_C(name, _init)(shared_t shared) \
M_F(name, _init)(shared_t shared) \
{ \
*shared = NULL; \
} \
\
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); \
/* 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)) { \
*shared = NULL; \
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)) { \
M_MEMORY_FULL(sizeof(struct M_C(name, _s))); \
M_MEMORY_FULL(sizeof(struct M_F(name, _s))); \
return; \
} \
ptr->data = data; \
@@ -222,16 +222,16 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
\
M_IF_METHOD(INIT, oplist)( \
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. */ \
struct M_C(name, combine_s) *p = \
M_CALL_NEW(oplist, struct M_C(name, combine_s)); \
struct M_F(name, combine_s) *p = \
M_CALL_NEW(oplist, struct M_F(name, combine_s)); \
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; \
} \
struct M_C(name, _s) *ptr = &p->ptr; \
struct M_F(name, _s) *ptr = &p->ptr; \
type *data = &p->data; \
M_CALL_INIT( oplist, *data); \
ptr->data = data; \
@@ -243,14 +243,14 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
, /* No INIT */ ) \
\
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); \
return *shared == NULL; \
} \
\
static inline void \
M_C(name, _init_set)(shared_t dest, \
M_F(name, _init_set)(shared_t dest, \
const shared_t shared) \
{ \
M_SHAR3D_CONTRACT(shared, cpt_oplist); \
@@ -264,7 +264,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
} \
\
static inline void \
M_C(name, _clear)(shared_t dest) \
M_F(name, _clear)(shared_t dest) \
{ \
M_SHAR3D_CONTRACT(dest, cpt_oplist); \
if (*dest != NULL) { \
@@ -285,24 +285,24 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
} \
\
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 */ \
M_C(name, _clear)(dest); \
M_F(name, _clear)(dest); \
} \
\
static inline void \
M_C(name, _set)(shared_t dest, \
M_F(name, _set)(shared_t dest, \
const shared_t shared) \
{ \
M_SHAR3D_CONTRACT(dest, cpt_oplist); \
M_SHAR3D_CONTRACT(shared, cpt_oplist); \
M_C(name, _clear)(dest); \
M_C(name, _init_set)(dest, shared); \
M_F(name, _clear)(dest); \
M_F(name, _init_set)(dest, shared); \
} \
\
static inline void \
M_C(name, _init_move)(shared_t dest, \
M_F(name, _init_move)(shared_t dest, \
shared_t shared) \
{ \
M_SHAR3D_CONTRACT(shared, cpt_oplist); \
@@ -313,30 +313,30 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
} \
\
static inline void \
M_C(name, _move)(shared_t dest, \
M_F(name, _move)(shared_t dest, \
shared_t shared) \
{ \
M_SHAR3D_CONTRACT(dest, cpt_oplist); \
M_SHAR3D_CONTRACT(shared, cpt_oplist); \
M_ASSERT (dest != shared); \
M_C(name, _clear)(dest); \
M_C(name, _init_move)(dest, shared); \
M_F(name, _clear)(dest); \
M_F(name, _init_move)(dest, shared); \
} \
\
static inline void \
M_C(name, _swap)(shared_t p1, \
M_F(name, _swap)(shared_t p1, \
shared_t p2) \
{ \
M_SHAR3D_CONTRACT(p1, cpt_oplist); \
M_SHAR3D_CONTRACT(p2, cpt_oplist); \
/* 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(p2, cpt_oplist); \
} \
\
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) \
{ \
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 * \
M_C(name, _cref)(const shared_t shared) \
M_F(name, _cref)(const shared_t shared) \
{ \
M_SHAR3D_CONTRACT(shared, cpt_oplist); \
M_ASSERT(*shared != NULL); \
@@ -355,7 +355,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
} \
\
static inline type * \
M_C(name, _ref)(shared_t shared) \
M_F(name, _ref)(shared_t shared) \
{ \
M_SHAR3D_CONTRACT(shared, cpt_oplist); \
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) \
\
/* 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; \
type x; \
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_C(name, _atype_ct) *buffer; \
M_F(name, _atype_ct) *buffer; \
} shared_t[1]; \
\
typedef struct M_C(name, _it_s) { \
typedef struct M_F(name, _it_s) { \
unsigned int idx; \
struct M_C(name, _s) *ref; \
struct M_F(name, _s) *ref; \
} it_t[1]; \
\
/* Internal Types for oplist */ \
typedef shared_t M_C(name, _ct); \
typedef shared_t M_F(name, _ct); \
/* Define the core functions */
#define M_SHAR3D_RESOURCE_DEF_CORE(name, type, oplist, shared_t, it_t) \
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 (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)) { \
M_MEMORY_FULL(sizeof(M_C(name, _atype_ct)) * n); \
M_MEMORY_FULL(sizeof(M_F(name, _atype_ct)) * n); \
return; \
} \
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 \
M_C(name, _clear)(shared_t s) \
M_F(name, _clear)(shared_t s) \
{ \
M_SHAR3D_RESOURCE_CONTRACT(s); \
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 \
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_ASSERT (it != NULL); \
@@ -459,14 +459,14 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
} \
\
static inline bool \
M_C(name, _end_p)(it_t it) \
M_F(name, _end_p)(it_t it) \
{ \
M_ASSERT (it != NULL); \
return it->idx == M_GENINT_ERROR; \
} \
\
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_SHAR3D_RESOURCE_CONTRACT(it->ref); \
@@ -474,7 +474,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
} \
\
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_SHAR3D_RESOURCE_CONTRACT(it->ref); \
@@ -482,7 +482,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
} \
\
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_ASSERT (it != NULL); \
@@ -498,7 +498,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
} \
\
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_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
USAGE: SNAPSHOT_SPSC_DEF(name, type[, oplist]) */
#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
@@ -51,7 +51,7 @@ M_BEGIN_PROTECTED_CODE
/* Define a Single Producer Multiple Consummer snapshot and its functions
USAGE: SNAPSHOT_SPMC_DEF(name, type[, oplist]) */
#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
@@ -68,7 +68,7 @@ M_BEGIN_PROTECTED_CODE
/* Define a Multiple Producer Multiple Consummer snapshot and its functions
USAGE: SNAPSHOT_MPMC_DEF(name, type[, oplist]) */
#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
@@ -107,16 +107,16 @@ M_BEGIN_PROTECTED_CODE
/* Define the oplist of a snapshot */
#define M_SNAPSH0T_OPLIST_P3(name, oplist) \
(INIT(M_C(name, _init)) \
,INIT_SET(M_C(name, _init_set)) \
,SET(M_C(name, _set)) \
,CLEAR(M_C(name, _clear)) \
(INIT(M_F(name, _init)) \
,INIT_SET(M_F(name, _init_set)) \
,SET(M_F(name, _set)) \
,CLEAR(M_F(name, _clear)) \
,NAME(name) \
,TYPE(M_C(name, _ct)) \
,SUBTYPE(M_C(name, _subtype_ct)) \
,TYPE(M_F(name, _ct)) \
,SUBTYPE(M_F(name, _subtype_ct)) \
,OPLIST(oplist) \
,M_IF_METHOD(INIT_MOVE, oplist)(INIT_MOVE(M_C(name, _init_move)),) \
,M_IF_METHOD(MOVE, oplist)(MOVE(M_C(name, _move)),) \
,M_IF_METHOD(INIT_MOVE, oplist)(INIT_MOVE(M_F(name, _init_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) \
\
/* 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; \
M_CACHELINE_ALIGN(align, type); \
} M_C(name, _aligned_type_ct); \
} M_F(name, _aligned_type_ct); \
\
typedef struct M_C(name, _s) { \
M_C(name, _aligned_type_ct) data[M_SNAPSH0T_SPSC_MAX_BUFFER]; \
typedef struct M_F(name, _s) { \
M_F(name, _aligned_type_ct) data[M_SNAPSH0T_SPSC_MAX_BUFFER]; \
atomic_uchar flags; \
} snapshot_t[1]; \
typedef struct M_C(name, _s) *M_C(name, _ptr); \
typedef const struct M_C(name, _s) *M_C(name, _srcptr); \
typedef struct M_F(name, _s) *M_F(name, _ptr); \
typedef const struct M_F(name, _s) *M_F(name, _srcptr); \
\
/* Define internal types for oplist */ \
typedef snapshot_t M_C(name, _ct); \
typedef type M_C(name, _subtype_ct); \
typedef snapshot_t M_F(name, _ct); \
typedef type M_F(name, _subtype_ct); \
/* Define the core functions */
#define M_SNAPSH0T_SPSC_DEF_CORE(name, type, oplist, snapshot_t) \
\
static inline void \
M_C(name, _init)(snapshot_t snap) \
M_F(name, _init)(snapshot_t snap) \
{ \
M_ASSERT(snap != NULL); \
for(int i = 0; i < M_SNAPSH0T_SPSC_MAX_BUFFER; i++) { \
@@ -209,7 +209,7 @@ M_BEGIN_PROTECTED_CODE
} \
\
static inline void \
M_C(name, _clear)(snapshot_t snap) \
M_F(name, _clear)(snapshot_t snap) \
{ \
M_SNAPSH0T_SPSC_CONTRACT(snap); \
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 */ \
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_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 */ \
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(org); \
@@ -245,7 +245,7 @@ M_BEGIN_PROTECTED_CODE
\
M_IF_METHOD(INIT_MOVE, oplist)( \
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_ASSERT(snap != NULL && snap != org); \
@@ -260,7 +260,7 @@ M_BEGIN_PROTECTED_CODE
\
M_IF_METHOD(MOVE, oplist)( \
static inline void \
M_C(name, _move)(snapshot_t snap, \
M_F(name, _move)(snapshot_t snap, \
snapshot_t org) \
{ \
M_SNAPSH0T_SPSC_CONTRACT(snap); \
@@ -276,7 +276,7 @@ M_BEGIN_PROTECTED_CODE
,) /* IF_METHOD (MOVE) */ \
\
static inline type * \
M_C(name, _write)(snapshot_t snap) \
M_F(name, _write)(snapshot_t snap) \
{ \
M_SNAPSH0T_SPSC_CONTRACT(snap); \
unsigned char nextFlags, origFlags = atomic_load (&snap->flags); \
@@ -295,7 +295,7 @@ M_BEGIN_PROTECTED_CODE
} \
\
static inline type const * \
M_C(name, _read)(snapshot_t snap) \
M_F(name, _read)(snapshot_t snap) \
{ \
M_SNAPSH0T_SPSC_CONTRACT(snap); \
unsigned char nextFlags, origFlags = atomic_load (&snap->flags); \
@@ -320,7 +320,7 @@ M_BEGIN_PROTECTED_CODE
\
/* Non const due to use of atomic_load */ \
static inline bool \
M_C(name, _updated_p)(snapshot_t snap) \
M_F(name, _updated_p)(snapshot_t snap) \
{ \
M_SNAPSH0T_SPSC_CONTRACT(snap); \
unsigned char flags = atomic_load (&snap->flags); \
@@ -329,7 +329,7 @@ M_BEGIN_PROTECTED_CODE
\
/* Non const due to use of atomic_load */ \
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); \
unsigned char flags = atomic_load(&snap->flags); \
@@ -338,7 +338,7 @@ M_BEGIN_PROTECTED_CODE
\
/* Non const due to use of atomic_load */ \
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); \
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) \
\
/* 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; \
M_CACHELINE_ALIGN(align, type); \
} M_C(name, _aligned_type_ct); \
} M_F(name, _aligned_type_ct); \
\
typedef struct M_C(name, _s) { \
M_C(name, _aligned_type_ct) *data; \
typedef struct M_F(name, _s) { \
M_F(name, _aligned_type_ct) *data; \
m_snapsh0t_mrsw_ct core; \
} snapshot_t[1]; \
\
/* Define internal types for oplist */ \
typedef snapshot_t M_C(name, _ct); \
typedef type M_C(name, _subtype_ct); \
typedef snapshot_t M_F(name, _ct); \
typedef type M_F(name, _subtype_ct); \
/* Define the core functions */
#define M_SNAPSH0T_SPMC_DEF_CORE(name, type, oplist, snapshot_t) \
\
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 (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); \
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)); \
return; \
} \
@@ -659,7 +659,7 @@ m_snapsh0t_mrsw_read_end(m_snapsh0t_mrsw_ct s, unsigned int idx)
} \
\
static inline void \
M_C(name, _clear)(snapshot_t snap) \
M_F(name, _clear)(snapshot_t snap) \
{ \
M_SNAPSH0T_SPMC_CONTRACT(snap); \
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 * \
M_C(name, _write)(snapshot_t snap) \
M_F(name, _write)(snapshot_t snap) \
{ \
M_SNAPSH0T_SPMC_CONTRACT(snap); \
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 * \
M_C(name, _read_start)(snapshot_t snap) \
M_F(name, _read_start)(snapshot_t snap) \
{ \
M_SNAPSH0T_SPMC_CONTRACT(snap); \
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 \
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_ASSERT (old != NULL); \
const M_C(name, _aligned_type_ct) *oldx; \
oldx = M_CTYPE_FROM_FIELD(M_C(name, _aligned_type_ct), old, type, x); \
const M_F(name, _aligned_type_ct) *oldx; \
oldx = M_CTYPE_FROM_FIELD(M_F(name, _aligned_type_ct), old, type, x); \
M_ASSERT (oldx >= snap->data); \
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); \
@@ -701,7 +701,7 @@ m_snapsh0t_mrsw_read_end(m_snapsh0t_mrsw_ct s, unsigned int idx)
} \
\
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); \
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 */
#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_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \
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 M_SNAPSH0T_MPMC_DEF_TYPE(name, type, oplist, snapshot_t) \
\
typedef struct M_C(name, _s) { \
M_C(name, _mrsw_pct) core; \
typedef struct M_F(name, _s) { \
M_F(name, _mrsw_pct) core; \
} snapshot_t[1]; \
\
/* Define internal types for oplist */ \
typedef snapshot_t M_C(name, _ct); \
typedef type M_C(name, _subtype_ct); \
typedef snapshot_t M_F(name, _ct); \
typedef type M_F(name, _subtype_ct); \
/* Define the core functions */
#define M_SNAPSH0T_MPMC_DEF_CORE(name, type, oplist, snapshot_t) \
\
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; \
snap->core->core->currentWrite = M_GENINT_ERROR; \
m_snapsh0t_mrsw_write_end(snap->core->core, idx); \
} \
\
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 * \
M_C(name, _write_start)(snapshot_t snap) \
M_F(name, _write_start)(snapshot_t snap) \
{ \
M_SNAPSH0T_SPMC_CONTRACT(snap->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 \
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); \
const M_C(name, _mrsw_aligned_type_ct) *oldx; \
oldx = M_CTYPE_FROM_FIELD(M_C(name, _mrsw_aligned_type_ct), old, type, x); \
const M_F(name, _mrsw_aligned_type_ct) *oldx; \
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 + snap->core->core->n_reader + M_SNAPSH0T_SPMC_EXTRA_BUFFER); \
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 * \
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 \
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
in case of usage with the algorithm module */
#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) \
{ \
size_t begin = 0; \
@@ -1912,7 +1912,7 @@ m_string_utf8_p(m_string_t str)
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) \
{ \
bool init_done = false; \
@@ -2163,29 +2163,29 @@ namespace m_lib {
*/
#define M_BOUNDED_STRING_DEF(name, max_size) \
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
/* Define the OPLIST of a BOUNDED_STRING */
#define M_BOUNDED_STRING_OPLIST(name) \
(INIT(M_C(name,_init)), \
INIT_SET(M_C(name,_init_set)), \
SET(M_C(name,_set)), \
CLEAR(M_C(name,_clear)), \
(INIT(M_F(name,_init)), \
INIT_SET(M_F(name,_init_set)), \
SET(M_F(name,_set)), \
CLEAR(M_F(name,_clear)), \
NAME(name), \
INIT_WITH( API_1(M_BOUNDED_STR1NG_INIT_WITH)), \
HASH(M_C(name,_hash)), \
EQUAL(M_C(name,_equal_p)), \
CMP(M_C(name,_cmp)), \
TYPE(M_C(name,_ct)), \
OOR_EQUAL(M_C(name,_oor_equal_p)), \
OOR_SET(M_C(name, _oor_set)), \
PARSE_STR(M_C(name,_parse_str)), \
GET_STR(M_C(name,_get_str)), \
OUT_STR(M_C(name,_out_str)), \
IN_STR(M_C(name,_in_str)), \
OUT_SERIAL(M_C(name,_out_serial)), \
IN_SERIAL(M_C(name,_in_serial)), \
HASH(M_F(name,_hash)), \
EQUAL(M_F(name,_equal_p)), \
CMP(M_F(name,_cmp)), \
TYPE(M_F(name,_ct)), \
OOR_EQUAL(M_F(name,_oor_equal_p)), \
OOR_SET(M_F(name, _oor_set)), \
PARSE_STR(M_F(name,_parse_str)), \
GET_STR(M_F(name,_get_str)), \
OUT_STR(M_F(name,_out_str)), \
IN_STR(M_F(name,_in_str)), \
OUT_SERIAL(M_F(name,_out_serial)), \
IN_SERIAL(M_F(name,_in_serial)), \
)
/************************** INTERNAL ***********************************/
@@ -2201,17 +2201,17 @@ namespace m_lib {
#define M_BOUNDED_STR1NG_DEF_P2(name, max_size, bounded_t) \
\
/* 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]; \
} bounded_t[1]; \
\
/* Internal types for oplist */ \
typedef bounded_t M_C(name, _ct); \
typedef bounded_t M_F(name, _ct); \
\
static inline void \
M_C(name, _init)(bounded_t s) \
M_F(name, _init)(bounded_t s) \
{ \
M_ASSERT(s != NULL); \
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 \
M_C(name, _clear)(bounded_t s) \
M_F(name, _clear)(bounded_t s) \
{ \
M_BOUNDED_STR1NG_CONTRACT(s, max_size); \
/* Make the object illegal to be able to detect use after free */ \
@@ -2229,7 +2229,7 @@ namespace m_lib {
} \
\
static inline void \
M_C(name, _reset)(bounded_t s) \
M_F(name, _reset)(bounded_t s) \
{ \
M_BOUNDED_STR1NG_CONTRACT(s, max_size); \
s->s[0] = 0; \
@@ -2237,14 +2237,14 @@ namespace m_lib {
} \
\
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); \
return strlen(s->s); \
} \
\
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); \
(void)s; /* unused */ \
@@ -2252,7 +2252,7 @@ namespace m_lib {
} \
\
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_ASSERT_INDEX(index, max_size); \
@@ -2260,14 +2260,14 @@ namespace m_lib {
} \
\
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); \
return s->s[0] == 0; \
} \
\
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_core_strncpy(s->s, max_size+1, str, max_size); \
@@ -2276,7 +2276,7 @@ namespace m_lib {
} \
\
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_ASSERT(str != NULL); \
@@ -2287,46 +2287,46 @@ namespace m_lib {
} \
\
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); \
return s->s; \
} \
\
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(str, max_size); \
M_C(name, _set_cstr)(s, str->s); \
M_F(name, _set_cstr)(s, str->s); \
} \
\
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) \
{ \
M_BOUNDED_STR1NG_CONTRACT(s, max_size); \
M_BOUNDED_STR1NG_CONTRACT(str, max_size); \
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 \
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_C(name,_set)(s, str); \
M_F(name,_init)(s); \
M_F(name,_set)(s, str); \
} \
\
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_C(name,_set_cstr)(s, str); \
M_F(name,_init)(s); \
M_F(name,_set_cstr)(s, str); \
} \
\
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_ASSERT (str != NULL); \
@@ -2335,14 +2335,14 @@ namespace m_lib {
} \
\
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_C(name, _cat_cstr)(s, str->s); \
M_F(name, _cat_cstr)(s, str->s); \
} \
\
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_ASSERT(str != NULL); \
@@ -2350,7 +2350,7 @@ namespace m_lib {
} \
\
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(str, max_size); \
@@ -2358,7 +2358,7 @@ namespace m_lib {
} \
\
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_ASSERT(str != NULL); \
@@ -2366,14 +2366,14 @@ namespace m_lib {
} \
\
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 */ \
return (s->s[max_size] == str->s[max_size]) & (strcmp(s->s, str->s) == 0); \
} \
\
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_ASSERT(format != NULL); \
@@ -2386,7 +2386,7 @@ namespace m_lib {
} \
\
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_ASSERT(format != NULL); \
@@ -2401,7 +2401,7 @@ namespace m_lib {
} \
\
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_ASSERT(f != NULL); \
@@ -2417,7 +2417,7 @@ namespace m_lib {
} \
\
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_ASSERT(f != NULL); \
@@ -2425,7 +2425,7 @@ namespace m_lib {
} \
\
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); \
/* Cannot use m_core_hash: alignment not sufficent */ \
@@ -2433,7 +2433,7 @@ namespace m_lib {
} \
\
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 */ \
M_ASSERT (s != NULL); \
@@ -2442,7 +2442,7 @@ namespace m_lib {
} \
\
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 */ \
M_ASSERT (s != NULL); \
@@ -2451,7 +2451,7 @@ namespace m_lib {
} \
\
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_BOUNDED_STR1NG_CONTRACT(s, max_size); \
@@ -2465,7 +2465,7 @@ namespace m_lib {
} \
\
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_ASSERT(f != NULL); \
@@ -2479,7 +2479,7 @@ namespace m_lib {
} \
\
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_ASSERT(f != NULL); \
@@ -2492,7 +2492,7 @@ namespace m_lib {
} \
\
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_ASSERT(str != NULL); \
@@ -2505,7 +2505,7 @@ namespace m_lib {
} \
\
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_ASSERT (serial != NULL && serial->m_interface != NULL); \
@@ -2513,7 +2513,7 @@ namespace m_lib {
} \
\
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_ASSERT (serial != NULL && serial->m_interface != NULL); \
@@ -2535,7 +2535,7 @@ namespace m_lib {
See above */
#ifndef __cplusplus
#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
namespace m_lib {
template <unsigned int N>
@@ -2549,7 +2549,7 @@ namespace m_lib {
};
}
#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
+201 -201
View File
File diff suppressed because it is too large. Load diff
+60 -60
View File
@@ -31,7 +31,7 @@
USAGE:
TUPLE_DEF2(name, [(field1, type1[, oplist1]), (field2, type2[, oplist2]), ...] ) */
#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
@@ -151,7 +151,7 @@ namespace m_lib {
M_TUPL3_IF_ALL(RESET, __VA_ARGS__)(M_TUPL3_DEFINE_RESET(name, __VA_ARGS__),)
/* 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_DSC(x) M_C3(_,x,_value)*-1
@@ -201,14 +201,14 @@ namespace m_lib {
/* Define the type of a tuple */
#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__) \
} name_t[1]; \
\
typedef struct M_C(name, _s) *M_C(name, _ptr); \
typedef const struct M_C(name, _s) *M_C(name, _srcptr); \
typedef struct M_F(name, _s) *M_F(name, _ptr); \
typedef const struct M_F(name, _s) *M_F(name, _srcptr); \
/* 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) */ \
typedef enum { \
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 M_TUPL3_DEFINE_ENUM(name, ...) \
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_C(name,_field_e);
} M_F(name,_field_e);
#define M_TUPL3_DEFINE_ENUM_ELE(name, a) \
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 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__) \
}
@@ -251,7 +251,7 @@ namespace m_lib {
/* Define the INIT_SET method calling the INIT_SET method for all params */
#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_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 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_FUNC , __VA_ARGS__) \
@@ -275,8 +275,8 @@ namespace m_lib {
/* Define the SET method calling the SET method for all params. */
#define M_TUPL3_DEFINE_SET(name, ...) \
static inline void M_C(name, _set)(M_C(name,_ct) my , \
M_C(name,_ct) const org) { \
static inline void M_F(name, _set)(M_F(name,_ct) my , \
M_F(name,_ct) const org) { \
M_TUPL3_CONTRACT(my); \
M_TUPL3_CONTRACT(org); \
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 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_TUPL3_CONTRACT(my); \
@@ -303,7 +303,7 @@ namespace m_lib {
/* Define the CLEAR method calling the CLEAR method for all params. */
#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_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) \
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); \
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) \
(M_C(name,_ct) const my) { \
(M_F(name,_ct) const my) { \
M_TUPL3_CONTRACT(my); \
return &(my->M_TUPL3_GET_FIELD a); \
} \
/* 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) \
(M_C(name,_ct) my) { \
(M_F(name,_ct) my) { \
return &(my->M_TUPL3_GET_FIELD a); \
} \
@@ -340,7 +340,7 @@ namespace m_lib {
#define M_TUPL3_DEFINE_SETTER_FIELD_PROTO(name, 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_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 M_TUPL3_DEFINE_CMP(name, ...) \
static inline int M_C(name, _cmp)(M_C(name,_ct) const e1 , \
M_C(name,_ct) const e2) { \
static inline int M_F(name, _cmp)(M_F(name,_ct) const e1 , \
M_F(name,_ct) const e2) { \
int i; \
M_TUPL3_CONTRACT(e1); \
M_TUPL3_CONTRACT(e2); \
@@ -369,8 +369,8 @@ namespace m_lib {
FIXME: All oplists shall define the CMP operator or at least one?
*/
#define M_TUPL3_DEFINE_CMP_ORDER(name, ...) \
static inline int M_C(name, _cmp_order)(M_C(name,_ct) const e1 , \
M_C(name,_ct) const e2, \
static inline int M_F(name, _cmp_order)(M_F(name,_ct) const e1 , \
M_F(name,_ct) const e2, \
const int order[]) { \
int i, r; \
M_TUPL3_CONTRACT(e1); \
@@ -403,8 +403,8 @@ namespace m_lib {
)
#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 , \
M_C(name,_ct) const e2) { \
static inline int M_C3(name, _cmp_, field)(M_F(name,_ct) const e1 , \
M_F(name,_ct) const e2) { \
M_TUPL3_CONTRACT(e1); \
M_TUPL3_CONTRACT(e2); \
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 M_TUPL3_DEFINE_EQUAL(name, ...) \
static inline bool M_C(name, _equal_p)(M_C(name,_ct) const e1 , \
M_C(name,_ct) const e2) { \
static inline bool M_F(name, _equal_p)(M_F(name,_ct) const e1 , \
M_F(name,_ct) const e2) { \
bool b; \
M_TUPL3_CONTRACT(e1); \
M_TUPL3_CONTRACT(e2); \
@@ -431,7 +431,7 @@ namespace m_lib {
/* Define a HASH method by calling the HASH methods for all params */
#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_HASH_DECL(hash); \
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 M_TUPL3_DEFINE_GET_STR(name, ...) \
static inline void M_C(name, _get_str)(m_string_t str, \
M_C(name,_ct) const el, \
static inline void M_F(name, _get_str)(m_string_t str, \
M_F(name,_ct) const el, \
bool append) { \
bool comma = false; \
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 M_TUPL3_DEFINE_OUT_STR(name, ...) \
static inline void M_C(name, _out_str)(FILE *f, \
M_C(name,_ct) const el) { \
static inline void M_F(name, _out_str)(FILE *f, \
M_F(name,_ct) const el) { \
bool comma = false; \
M_TUPL3_CONTRACT(el); \
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 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; \
M_TUPL3_CONTRACT(el); \
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 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 **endptr) { \
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 M_TUPL3_DEFINE_OUT_SERIAL(name, ...) \
static inline m_serial_return_code_t \
M_C(name, _out_serial)(m_serial_write_t f, \
M_C(name,_ct) const el) { \
M_F(name, _out_serial)(m_serial_write_t f, \
M_F(name,_ct) const el) { \
M_TUPL3_CONTRACT(el); \
M_ASSERT (f != NULL && f->m_interface != NULL); \
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 M_TUPL3_DEFINE_IN_SERIAL(name, ...) \
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_ASSERT (f != NULL && f->m_interface != NULL); \
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 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_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 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_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 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(el2); \
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 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_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_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, ...) \
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, ...) \
( 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"), \
@@ -721,27 +721,27 @@ namespace m_lib {
/* Define the TUPLE oplist */
#define M_TUPL3_OPLIST_P3(name, ...) \
(M_IF_METHOD_ALL(INIT, __VA_ARGS__)(INIT(M_C(name,_init)),), \
INIT_SET(M_C(name, _init_set)), \
(M_IF_METHOD_ALL(INIT, __VA_ARGS__)(INIT(M_F(name,_init)),), \
INIT_SET(M_F(name, _init_set)), \
INIT_WITH(API_1(M_TUPL3_INIT_WITH)), \
SET(M_C(name,_set)), \
CLEAR(M_C(name, _clear)), \
SET(M_F(name,_set)), \
CLEAR(M_F(name, _clear)), \
NAME(name), \
TYPE(M_C(name,_ct)), \
TYPE(M_F(name,_ct)), \
OPLIST( (__VA_ARGS__) ), \
M_IF_METHOD_ALL(CMP, __VA_ARGS__)(CMP(M_C(name, _cmp)),), \
M_IF_METHOD_ALL(HASH, __VA_ARGS__)(HASH(M_C(name, _hash)),), \
M_IF_METHOD_ALL(EQUAL, __VA_ARGS__)(EQUAL(M_C(name, _equal_p)),), \
M_IF_METHOD_ALL(GET_STR, __VA_ARGS__)(GET_STR(M_C(name, _get_str)),), \
M_IF_METHOD_ALL(PARSE_STR, __VA_ARGS__)(PARSE_STR(M_C(name, _parse_str)),), \
M_IF_METHOD_ALL(IN_STR, __VA_ARGS__)(IN_STR(M_C(name, _in_str)),), \
M_IF_METHOD_ALL(OUT_STR, __VA_ARGS__)(OUT_STR(M_C(name, _out_str)),), \
M_IF_METHOD_ALL(IN_SERIAL, __VA_ARGS__)(IN_SERIAL(M_C(name, _in_serial)),), \
M_IF_METHOD_ALL(OUT_SERIAL, __VA_ARGS__)(OUT_SERIAL(M_C(name, _out_serial)),), \
M_IF_METHOD_ALL(INIT_MOVE, __VA_ARGS__)(INIT_MOVE(M_C(name, _init_move)),), \
M_IF_METHOD_ALL(MOVE, __VA_ARGS__)(MOVE(M_C(name, _move)),), \
M_IF_METHOD_ALL(SWAP, __VA_ARGS__)(SWAP(M_C(name, _swap)),), \
M_IF_METHOD_ALL(RESET, __VA_ARGS__)(RESET(M_C(name, _reset)),), \
M_IF_METHOD_ALL(CMP, __VA_ARGS__)(CMP(M_F(name, _cmp)),), \
M_IF_METHOD_ALL(HASH, __VA_ARGS__)(HASH(M_F(name, _hash)),), \
M_IF_METHOD_ALL(EQUAL, __VA_ARGS__)(EQUAL(M_F(name, _equal_p)),), \
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_F(name, _parse_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_F(name, _out_str)),), \
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_F(name, _out_serial)),), \
M_IF_METHOD_ALL(INIT_MOVE, __VA_ARGS__)(INIT_MOVE(M_F(name, _init_move)),), \
M_IF_METHOD_ALL(MOVE, __VA_ARGS__)(MOVE(M_F(name, _move)),), \
M_IF_METHOD_ALL(SWAP, __VA_ARGS__)(SWAP(M_F(name, _swap)),), \
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(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__,)),), \
+102 -102
View File
@@ -31,7 +31,7 @@
USAGE:
VARIANT_DEF2(name, [(field1, type1, oplist1), (field2, type2, oplist2), ...] ) */
#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
@@ -59,8 +59,8 @@
/* Contract of a variant. */
#define M_VAR1ANT_CONTRACT(name, my) do { \
M_ASSERT(my != NULL); \
M_ASSERT(my->type >= M_C(name, _EMPTY)); \
M_ASSERT(my->type <= (enum M_C(name, _enum)) M_C(name, _MAX_TYPE)); \
M_ASSERT(my->type >= M_F(name, _EMPTY)); \
M_ASSERT(my->type <= (enum M_F(name, _enum)) M_F(name, _MAX_TYPE)); \
} while (0)
/* Inject the oplist within the list of arguments */
@@ -181,25 +181,25 @@
/* Define the type */
#define M_VAR1ANT_DEFINE_TYPE(name, name_t, ...) \
/* 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__) \
}; \
/* Define enum equal to the number of types of the variant */ \
enum M_C(name, _enum_max) { \
M_C(name, _MAX_TYPE) = M_NARGS(__VA_ARGS__) \
enum M_F(name, _enum_max) { \
M_F(name, _MAX_TYPE) = M_NARGS(__VA_ARGS__) \
}; \
/* Define the variant */ \
typedef struct M_C(name, _s) { \
enum M_C(name, _enum) type; \
typedef struct M_F(name, _s) { \
enum M_F(name, _enum) type; \
union { \
M_MAP(M_VAR1ANT_DEFINE_TYPE_ELE , __VA_ARGS__) \
} value; \
} name_t[1]; \
\
typedef struct M_C(name, _s) *M_C(name, _ptr); \
typedef const struct M_C(name, _s) *M_C(name, _srcptr); \
typedef struct M_F(name, _s) *M_F(name, _ptr); \
typedef const struct M_F(name, _s) *M_F(name, _srcptr); \
/* 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) \
, M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value)
@@ -219,21 +219,21 @@
/* Define the INIT function. Init the variant to empty */
#define M_VAR1ANT_DEFINE_INIT(name, ...) \
static inline void M_C(name, _init)(M_C(name,_ct) my) { \
my->type = M_C(name, _EMPTY); \
static inline void M_F(name, _init)(M_F(name,_ct) my) { \
my->type = M_F(name, _EMPTY); \
}
/* Define the INIT_SET function. */
#define M_VAR1ANT_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_VAR1ANT_CONTRACT(name, org); \
my->type = org->type; \
switch (org->type) { \
M_MAP2(M_VAR1ANT_DEFINE_INIT_SET_FUNC, name, __VA_ARGS__) \
case M_C(name, _EMPTY): /* fallthrough */ \
default: M_ASSUME(org->type == M_C(name, _EMPTY)); break; \
case M_F(name, _EMPTY): /* fallthrough */ \
default: M_ASSUME(org->type == M_F(name, _EMPTY)); break; \
} \
}
@@ -246,20 +246,20 @@
/* Define the SET function. */
#define M_VAR1ANT_DEFINE_SET(name, ...) \
static inline void M_C(name, _set)(M_C(name,_ct) my , \
M_C(name,_ct) const org) { \
static inline void M_F(name, _set)(M_F(name,_ct) my , \
M_F(name,_ct) const org) { \
M_VAR1ANT_CONTRACT(name, my); \
M_VAR1ANT_CONTRACT(name, org); \
if (my->type != org->type) { \
/* Different types: clear previous one and create new */ \
M_C(name, _clear)(my); \
M_C(name, _init_set)(my, org); \
M_F(name, _clear)(my); \
M_F(name, _init_set)(my, org); \
} else { \
/* Same type: optimize the set */ \
switch (org->type) { \
M_MAP2(M_VAR1ANT_DEFINE_SET_FUNC, name, __VA_ARGS__) \
case M_C(name, _EMPTY): /* fallthrough */ \
default: M_ASSUME(org->type == M_C(name, _EMPTY)); break; \
case M_F(name, _EMPTY): /* fallthrough */ \
default: M_ASSUME(org->type == M_F(name, _EMPTY)); break; \
} \
} \
}
@@ -273,14 +273,14 @@
/* Define the CLEAR function. */
#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); \
switch (my->type) { \
M_MAP2(M_VAR1ANT_DEFINE_CLEAR_FUNC, name, __VA_ARGS__) \
case M_C(name, _EMPTY): /* fallthrough */ \
default: M_ASSUME(my->type == M_C(name, _EMPTY)); break; \
case M_F(name, _EMPTY): /* fallthrough */ \
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) \
@@ -291,12 +291,12 @@
/* Define the TEST_P function. */
#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); \
return my->type == M_C(name, _EMPTY); \
return my->type == M_F(name, _EMPTY); \
} \
static inline enum M_C(name, _enum) \
M_C(name, _type)(M_C(name,_ct) my) { \
static inline enum M_F(name, _enum) \
M_F(name, _type)(M_F(name,_ct) my) { \
M_VAR1ANT_CONTRACT(name, my); \
return my->type; \
} \
@@ -304,7 +304,7 @@
#define M_VAR1ANT_DEFINE_TEST_FUNC(name, a) \
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); \
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) \
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 */ \
my->type = M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value); \
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) \
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 ) { \
my->type = M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value); \
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) \
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_CONTRACT(name, my); \
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_GET_FIELD a); \
} else { \
M_C(name, _clear)(my); \
M_F(name, _clear)(my); \
/* Reinit variable with the given 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, \
@@ -365,7 +365,7 @@
#define M_VAR1ANT_DEFINE_GETTER_FIELD_FUNC(name, 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); \
if (my->type != M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value) ) { \
return NULL; \
@@ -374,7 +374,7 @@
} \
\
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); \
if (my->type != M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value) ) { \
return NULL; \
@@ -393,8 +393,8 @@
#define M_VAR1ANT_MAP3_ALT_ID(a, b) a b
#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_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, _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, _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) \
static inline void \
@@ -418,14 +418,14 @@ static inline void \
/* Define the EQUAL_P function. */
#define M_VAR1ANT_DEFINE_EQUAL(name, ...) \
static inline bool M_C(name, _equal_p)(M_C(name,_ct) const e1 , \
M_C(name,_ct) const e2) { \
static inline bool M_F(name, _equal_p)(M_F(name,_ct) const e1 , \
M_F(name,_ct) const e2) { \
bool b; \
M_VAR1ANT_CONTRACT(name, e1); \
M_VAR1ANT_CONTRACT(name, e2); \
if (e1->type != e2->type) return false; \
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__) \
default: M_ASSUME(false); break; \
} \
@@ -442,12 +442,12 @@ static inline void \
/* Define the HASH function. */
#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_HASH_DECL(hash); \
M_HASH_UP (hash, (unsigned int) (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__) \
default: M_ASSUME(false); break; \
} \
@@ -463,15 +463,15 @@ static inline void \
/* Define the INIT_MOVE function. */
#define M_VAR1ANT_DEFINE_INIT_MOVE(name, ...) \
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); \
el -> type = org -> 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__) \
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) \
@@ -487,11 +487,11 @@ static inline void \
*/
#define M_VAR1ANT_DEFINE_MOVE(name, ...) \
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, org); \
M_C(name, _clear)(el); \
M_C(name, _init_move)(el , org); \
M_F(name, _clear)(el); \
M_F(name, _init_move)(el , org); \
}
@@ -501,10 +501,10 @@ static inline void \
#define M_VAR1ANT_DEFINE_MOVER_FUNC(name, a) \
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_CONTRACT(name, my); \
M_C(name, _clear)(my); \
M_F(name, _clear)(my); \
/* Reinit variable with the given 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, \
@@ -515,28 +515,28 @@ static inline void \
/* Define the SWAP function */
#define M_VAR1ANT_DEFINE_SWAP(name, ...) \
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, el2); \
if (el1->type == el2->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__) \
default: M_ASSUME(false); break; \
} \
} else { \
M_C(name,_ct) tmp; \
M_F(name,_ct) tmp; \
M_VAR1ANT_IF_ALL(INIT_MOVE, __VA_ARGS__) \
( /* NOTE: Slow implementation */ \
M_C(name, _init_move)(tmp, el1); \
M_C(name, _init_move)(el1, el2); \
M_C(name, _init_move)(el2, tmp); \
M_F(name, _init_move)(tmp, el1); \
M_F(name, _init_move)(el1, el2); \
M_F(name, _init_move)(el2, tmp); \
, \
/* NOTE: Very slow implementation */ \
M_C(name, _init_set)(tmp, el1); \
M_C(name, _set)(el1, el2); \
M_C(name, _set)(el2, tmp); \
M_C(name, _clear)(tmp); \
M_F(name, _init_set)(tmp, el1); \
M_F(name, _set)(el1, el2); \
M_F(name, _set)(el2, tmp); \
M_F(name, _clear)(tmp); \
) \
} \
}
@@ -550,15 +550,15 @@ static inline void \
/* Define the GET_STR function */
#define M_VAR1ANT_DEFINE_GET_STR(name, ...) \
static inline void M_C(name, _get_str)(m_string_t str, \
M_C(name,_ct) const el, \
static inline void M_F(name, _get_str)(m_string_t str, \
M_F(name,_ct) const el, \
bool append) { \
M_VAR1ANT_CONTRACT(name, el); \
M_ASSERT (str != NULL); \
void (*func)(m_string_t, const char *); \
func = append ? m_string_cat_cstr : m_string_set_cstr; \
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__) \
default: M_ASSUME(false); break; \
} \
@@ -574,7 +574,7 @@ static inline void \
/* Define the PARSE_STR function */
#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 **endp) { \
M_VAR1ANT_CONTRACT(name, el); \
@@ -583,7 +583,7 @@ static inline void \
char variantTypeBuf[M_USE_IDENTIFIER_ALLOC+1]; \
int c = *str++; \
unsigned int i = 0; \
M_C(name, _reset)(el); \
M_F(name, _reset)(el); \
if (c != '@') goto exit; \
/* First read the name of the type */ \
c = *str++; \
@@ -596,7 +596,7 @@ static inline void \
M_ASSERT(i < sizeof(variantTypeBuf)); \
/* In function of the type */ \
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__) \
else goto exit; \
@@ -617,12 +617,12 @@ static inline void \
/* Define the OUT_STR function */
#define M_VAR1ANT_DEFINE_OUT_STR(name, ...) \
static inline void M_C(name, _out_str)(FILE *f, \
M_C(name,_ct) const el) { \
static inline void M_F(name, _out_str)(FILE *f, \
M_F(name,_ct) const el) { \
M_VAR1ANT_CONTRACT(name, el); \
M_ASSERT (f != NULL); \
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__) \
default: M_ASSUME(false); break; \
} \
@@ -638,12 +638,12 @@ static inline void \
/* Define the IN_STR function */
#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) { \
M_VAR1ANT_CONTRACT(name, el); \
M_ASSERT (f != NULL); \
char variantTypeBuf[M_USE_IDENTIFIER_ALLOC+1]; \
M_C(name, _reset)(el); \
M_F(name, _reset)(el); \
if (fgetc(f) != '@') return false; \
/* First read the name of the type */ \
bool b = true; \
@@ -658,7 +658,7 @@ static inline void \
M_ASSERT(i < sizeof(variantTypeBuf)); \
/* In function of the type */ \
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__) \
else { b = false; } \
@@ -681,8 +681,8 @@ static inline void \
/* Define the OUT_SERIAL function */
#define M_VAR1ANT_DEFINE_OUT_SERIAL(name, ...) \
static inline m_serial_return_code_t \
M_C(name, _out_serial)(m_serial_write_t f, \
M_C(name,_ct) const el) { \
M_F(name, _out_serial)(m_serial_write_t f, \
M_F(name,_ct) const el) { \
M_VAR1ANT_CONTRACT(name, el); \
const int field_max = M_NARGS(__VA_ARGS__); \
static const char *const field_name[] = \
@@ -691,7 +691,7 @@ static inline void \
m_serial_local_t local; \
m_serial_return_code_t ret; \
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); \
break; \
M_MAP2(M_VAR1ANT_DEFINE_OUT_SERIAL_FUNC , name, __VA_ARGS__) \
@@ -712,7 +712,7 @@ static inline void \
/* Define the IN_SERIAL function */
#define M_VAR1ANT_DEFINE_IN_SERIAL(name, ...) \
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_VAR1ANT_CONTRACT(name, el); \
const int field_max = M_NARGS(__VA_ARGS__); \
@@ -722,11 +722,11 @@ static inline void \
m_serial_local_t local; \
m_serial_return_code_t ret; \
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); \
if (ret != M_SERIAL_OK_CONTINUE) return ret; \
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) { \
M_MAP2(M_VAR1ANT_DEFINE_IN_SERIAL_FUNC , name, __VA_ARGS__) \
default: M_ASSUME(false); break; \
@@ -745,11 +745,11 @@ static inline void \
/* Define the RESET function */
#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_C(name, _clear)(my); \
M_C(name, _init)(my); \
M_F(name, _clear)(my); \
M_F(name, _init)(my); \
} \
@@ -768,25 +768,25 @@ static inline void \
/* Define the oplist */
#define M_VAR1ANT_OPLIST_P3(name, ...) \
(INIT(M_C(name,_init)), \
INIT_SET(M_C(name, _init_set)), \
SET(M_C(name,_set)), \
CLEAR(M_C(name, _clear)), \
RESET(M_C(name, _reset)), \
(INIT(M_F(name,_init)), \
INIT_SET(M_F(name, _init_set)), \
SET(M_F(name,_set)), \
CLEAR(M_F(name, _clear)), \
RESET(M_F(name, _reset)), \
NAME(name), \
TYPE(M_C(name,_ct)), \
EMPTY_P(M_C(name,_empty_p)), \
M_IF_METHOD_ALL(HASH, __VA_ARGS__)(HASH(M_C(name, _hash)),), \
M_IF_METHOD_ALL(EQUAL, __VA_ARGS__)(EQUAL(M_C(name, _equal_p)),), \
M_IF_METHOD_ALL(GET_STR, __VA_ARGS__)(GET_STR(M_C(name, _get_str)),), \
M_IF_METHOD2_ALL(PARSE_STR, INIT, __VA_ARGS__)(PARSE_STR(M_C(name, _parse_str)),), \
M_IF_METHOD2_ALL(IN_STR, INIT, __VA_ARGS__)(IN_STR(M_C(name, _in_str)),), \
M_IF_METHOD_ALL(OUT_STR, __VA_ARGS__)(OUT_STR(M_C(name, _out_str)),), \
M_IF_METHOD2_ALL(IN_SERIAL, INIT, __VA_ARGS__)(IN_SERIAL(M_C(name, _in_serial)),), \
M_IF_METHOD_ALL(OUT_SERIAL, __VA_ARGS__)(OUT_SERIAL(M_C(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__)(MOVE(M_C(name, _move)),), \
M_IF_METHOD_ALL(SWAP, __VA_ARGS__)(SWAP(M_C(name, _swap)),), \
TYPE(M_F(name,_ct)), \
EMPTY_P(M_F(name,_empty_p)), \
M_IF_METHOD_ALL(HASH, __VA_ARGS__)(HASH(M_F(name, _hash)),), \
M_IF_METHOD_ALL(EQUAL, __VA_ARGS__)(EQUAL(M_F(name, _equal_p)),), \
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_F(name, _parse_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_F(name, _out_str)),), \
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_F(name, _out_serial)),), \
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_F(name, _move)),), \
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(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__,)),), \
+15 -1
View File
@@ -24,9 +24,19 @@
#include <stdbool.h>
#include <assert.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 "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)
{
@@ -42,6 +52,10 @@ static void test_cat(void)
assert (M_C5_EMPTY(A,a,n,d,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)