Provide a way to alter the standard naming convention for the functions
Close #72
This commit is contained in:
1 parent
272a326375
commit
219c62ff5d
24 files changed
+2801
-2758
No files matched your search
@@ -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
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -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
File diff suppressed because it is too large.
Load diff
+98
-98
@@ -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
@@ -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
@@ -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); \
|
||||
|
||||
@@ -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; \
|
||||
}
|
||||
|
||||
+49
-49
@@ -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
@@ -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
@@ -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); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
|
||||
+24
-24
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user