From 5f9feb833cdec702f62fb469a5612d4e56f5a3fc Mon Sep 17 00:00:00 2001 From: Patrick Pelissier Date: Sat, 25 Jul 2020 19:17:25 +0200 Subject: [PATCH] Replace TAB by SPACE --- m-atomic.h | 14 +- m-buffer.h | 499 ++++++++++++------------- m-c-mempool.h | 4 +- m-core.h | 34 +- m-dict.h | 979 +++++++++++++++++++++++++------------------------- m-funcobj.h | 34 +- m-i-list.h | 400 ++++++++++----------- m-i-shared.h | 100 +++--- m-rbtree.h | 2 +- m-string.h | 62 ++-- 10 files changed, 1067 insertions(+), 1061 deletions(-) diff --git a/m-atomic.h b/m-atomic.h index 4f27a2d0..f4d9339a 100644 --- a/m-atomic.h +++ b/m-atomic.h @@ -127,7 +127,7 @@ using std::memory_order_seq_cst; */ #elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__) ) \ || (defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER) && !defined(__cplusplus) && (__GNUC__*100 + __GNUC_MINOR__) >= 409) \ - || (defined(__clang__) && __clang_major__ >= 4) \ + || (defined(__clang__) && __clang_major__ >= 4) \ || (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1800) #include @@ -166,12 +166,12 @@ M_BEGIN_PROTECTED_CODE _lock : the mutex lock. Support up to sizeof (long long) type. */ -#define _Atomic(T) \ - struct { \ - T volatile _val; \ - T _zero; \ - T _previous; \ - m_mutex_t _lock; \ +#define _Atomic(T) \ + struct { \ + T volatile _val; \ + T _zero; \ + T _previous; \ + m_mutex_t _lock; \ } /* Define the supported memory order. diff --git a/m-buffer.h b/m-buffer.h index b9bed40b..11f65693 100644 --- a/m-buffer.h +++ b/m-buffer.h @@ -63,14 +63,14 @@ typedef enum { USAGE: BUFFER_OPLIST(name[, oplist of the type]) */ #define BUFFER_OPLIST(...) \ BUFFERI_OPLIST_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ - ((__VA_ARGS__, M_DEFAULT_OPLIST), \ + ((__VA_ARGS__, M_DEFAULT_OPLIST), \ (__VA_ARGS__ ))) /* Define a nearly lock-free queue for Many Producer Many Consummer Much faster than queue of BUFFER_DEF in heavy communication scenario Size of created queue can only a power of 2. */ -#define QUEUE_MPMC_DEF(name, type, ...) \ +#define QUEUE_MPMC_DEF(name, type, ...) \ M_BEGIN_PROTECTED_CODE \ QUEUEI_MPMC_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ ((name, type, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(type)(), M_C(name,_t)), \ @@ -81,7 +81,7 @@ typedef enum { Much faster than queue of BUFFER_DEF in heavy communication scenario Size of created queue can only a power of 2. */ -#define QUEUE_SPSC_DEF(name, type, ...) \ +#define QUEUE_SPSC_DEF(name, type, ...) \ M_BEGIN_PROTECTED_CODE \ QUEUEI_SPSC_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ ((name, type, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(type)(), M_C(name,_t)), \ @@ -99,13 +99,13 @@ typedef enum { #define BUFFERI_POLICY_P(policy, val) \ (((policy) & (val)) != 0) -#define BUFFERI_CONTRACT(buffer, size) do { \ - assert (buffer != NULL); \ - assert (buffer->data != NULL); \ +#define BUFFERI_CONTRACT(buffer, size) do { \ + assert (buffer != NULL); \ + assert (buffer->data != NULL); \ }while (0) #define BUFFERI_PROTECTED_CONTRACT(buffer, size) do { \ - assert (atomic_load(&buffer->number[0]) <= BUFFERI_SIZE(size)); \ + assert (atomic_load(&buffer->number[0]) <= BUFFERI_SIZE(size)); \ } while (0) /* Deferred evaluation for the definition, @@ -122,7 +122,7 @@ typedef enum { #define BUFFERI_DEF_P3(name, type, m_size, policy, oplist, buffer_t) \ \ - typedef struct M_C(name, _s) { \ + typedef struct M_C(name, _s) { \ m_mutex_t mutexPush; /* MUTEX used for pushing elements */ \ size_t idx_prod; /* Index of the production threads */ \ size_t overwrite; /* Number of overwritten values */ \ @@ -158,9 +158,11 @@ M_C(name, _init)(buffer_t v, size_t size) \ m_mutex_init(v->mutexPop); \ m_cond_init(v->there_is_data); \ m_cond_init(v->there_is_room_for_data); \ - } else \ + } else { \ assert(BUFFERI_POLICY_P((policy), BUFFER_UNBLOCKING)); \ - BUFFERI_IF_CTE_SIZE(m_size)( , \ + } \ + \ + BUFFERI_IF_CTE_SIZE(m_size)( /* Statically allocated */ , \ v->data = M_CALL_REALLOC(oplist, type, NULL, BUFFERI_SIZE(m_size)); \ if (v->data == NULL) { \ M_MEMORY_FULL (BUFFERI_SIZE(m_size)*sizeof(type)); \ @@ -168,12 +170,12 @@ M_C(name, _init)(buffer_t v, size_t size) \ } \ ) \ if (!BUFFERI_POLICY_P((policy), BUFFER_PUSH_INIT_POP_MOVE)) { \ - for(size_t i = 0; i < size; i++) { \ + for(size_t i = 0; i < size; i++) { \ M_CALL_INIT(oplist, v->data[i]); \ - } \ + } \ } \ - BUFFERI_CONTRACT(v,m_size); \ -} \ + BUFFERI_CONTRACT(v,m_size); \ +} \ \ BUFFERI_IF_CTE_SIZE(m_size)( \ static inline void \ @@ -184,13 +186,13 @@ M_C(name, _init)(buffer_t v, size_t size) \ , ) \ \ static inline void \ - M_C(name, _int_clear_obj)(buffer_t v) \ + M_C(name, _int_clear_obj)(buffer_t v) \ { \ - BUFFERI_CONTRACT(v,m_size); \ + BUFFERI_CONTRACT(v,m_size); \ if (!BUFFERI_POLICY_P((policy), BUFFER_PUSH_INIT_POP_MOVE)) { \ - for(size_t i = 0; i < BUFFERI_SIZE(m_size); i++) { \ + for(size_t i = 0; i < BUFFERI_SIZE(m_size); i++) { \ M_CALL_CLEAR(oplist, v->data[i]); \ - } \ + } \ } else { \ size_t i = BUFFERI_POLICY_P((policy), BUFFER_STACK) ? 0 : v->idx_cons; \ while (i != v->idx_prod) { \ @@ -201,17 +203,17 @@ M_C(name, _init)(buffer_t v, size_t size) \ } \ } \ v->idx_prod = v->idx_cons = 0; \ - atomic_store_explicit (&v->number[0], 0UL, memory_order_relaxed); \ + atomic_store_explicit (&v->number[0], 0UL, memory_order_relaxed); \ if (BUFFERI_POLICY_P(policy, BUFFER_DEFERRED_POP)) \ - atomic_store_explicit(&v->number[1], 0UL, memory_order_relaxed); \ - BUFFERI_CONTRACT(v,m_size); \ + atomic_store_explicit(&v->number[1], 0UL, memory_order_relaxed); \ + BUFFERI_CONTRACT(v,m_size); \ } \ - \ + \ static inline void \ - M_C(name, _clear)(buffer_t v) \ + M_C(name, _clear)(buffer_t v) \ { \ - BUFFERI_CONTRACT(v,m_size); \ - M_C(name, _int_clear_obj)(v); \ + BUFFERI_CONTRACT(v,m_size); \ + M_C(name, _int_clear_obj)(v); \ BUFFERI_IF_CTE_SIZE(m_size)( , \ M_CALL_FREE(oplist, v->data); \ v->data = NULL; \ @@ -224,30 +226,30 @@ M_C(name, _init)(buffer_t v, size_t size) \ m_cond_clear(v->there_is_room_for_data); \ } \ } \ - \ + \ static inline void \ - M_C(name, _clean)(buffer_t v) \ + M_C(name, _clean)(buffer_t v) \ { \ - BUFFERI_CONTRACT(v,m_size); \ + BUFFERI_CONTRACT(v,m_size); \ if (!BUFFERI_POLICY_P((policy), BUFFER_THREAD_UNSAFE)) { \ m_mutex_lock(v->mutexPush); \ m_mutex_lock(v->mutexPop); \ } \ - BUFFERI_PROTECTED_CONTRACT(v, m_size); \ - if (BUFFERI_POLICY_P((policy), BUFFER_PUSH_INIT_POP_MOVE)) \ - M_C(name, _int_clear_obj)(v); \ + BUFFERI_PROTECTED_CONTRACT(v, m_size); \ + if (BUFFERI_POLICY_P((policy), BUFFER_PUSH_INIT_POP_MOVE)) \ + M_C(name, _int_clear_obj)(v); \ v->idx_prod = v->idx_cons = 0; \ - atomic_store_explicit (&v->number[0], 0UL, memory_order_relaxed); \ + atomic_store_explicit (&v->number[0], 0UL, memory_order_relaxed); \ if (BUFFERI_POLICY_P(policy, BUFFER_DEFERRED_POP)) \ - atomic_store_explicit(&v->number[1], 0UL, memory_order_relaxed); \ + atomic_store_explicit(&v->number[1], 0UL, memory_order_relaxed); \ if (!BUFFERI_POLICY_P((policy), BUFFER_THREAD_UNSAFE)) { \ m_cond_broadcast(v->there_is_room_for_data); \ m_mutex_unlock(v->mutexPop); \ m_mutex_unlock(v->mutexPush); \ } \ - BUFFERI_CONTRACT(v,m_size); \ + BUFFERI_CONTRACT(v,m_size); \ } \ - \ + \ static inline void \ M_C(name, _init_set)(buffer_t dest, const buffer_t src) \ { \ @@ -263,11 +265,11 @@ M_C(name, _init)(buffer_t v, size_t size) \ m_mutex_lock(v->mutexPop); \ } \ \ - BUFFERI_PROTECTED_CONTRACT(v, m_size); \ + BUFFERI_PROTECTED_CONTRACT(v, m_size); \ if (!BUFFERI_POLICY_P((policy), BUFFER_PUSH_INIT_POP_MOVE)) { \ - for(size_t i = 0; i < BUFFERI_SIZE(m_size); i++) { \ + for(size_t i = 0; i < BUFFERI_SIZE(m_size); i++) { \ M_CALL_INIT_SET(oplist, dest->data[i], v->data[i]); \ - } \ + } \ } else { \ size_t i = BUFFERI_POLICY_P((policy), BUFFER_STACK) ? 0 : v->idx_cons; \ while (i != v->idx_prod) { \ @@ -291,7 +293,7 @@ M_C(name, _init)(buffer_t v, size_t size) \ BUFFERI_CONTRACT(v,m_size); \ BUFFERI_CONTRACT(dest, m_size); \ } \ - \ + \ static inline void \ M_C(name, _set)(buffer_t dest, const buffer_t src) \ { \ @@ -319,13 +321,13 @@ M_C(name, _init)(buffer_t v, size_t size) \ } \ } \ \ - BUFFERI_PROTECTED_CONTRACT(v, m_size); \ - M_C(name, _int_clear_obj)(dest); \ + BUFFERI_PROTECTED_CONTRACT(v, m_size); \ + M_C(name, _int_clear_obj)(dest); \ \ if (!BUFFERI_POLICY_P((policy), BUFFER_PUSH_INIT_POP_MOVE)) { \ - for(size_t i = 0; i < BUFFERI_SIZE(m_size); i++) { \ + for(size_t i = 0; i < BUFFERI_SIZE(m_size); i++) { \ M_CALL_INIT_SET(oplist, dest->data[i], v->data[i]); \ - } \ + } \ } else { \ size_t i = BUFFERI_POLICY_P((policy), BUFFER_STACK) ? 0 : v->idx_cons; \ while (i != v->idx_prod) { \ @@ -361,11 +363,11 @@ M_C(name, _init)(buffer_t v, size_t size) \ BUFFERI_CONTRACT(v,m_size); \ BUFFERI_CONTRACT(dest, m_size); \ } \ - \ + \ static inline bool \ - M_C(name, _empty_p)(buffer_t v) \ + M_C(name, _empty_p)(buffer_t v) \ { \ - BUFFERI_CONTRACT(v,m_size); \ + BUFFERI_CONTRACT(v,m_size); \ /* If the buffer has been configured with deferred pop \ we considered the queue as empty when the number of \ deferred pop has reached 0, not the number of items in the \ @@ -375,32 +377,32 @@ M_C(name, _init)(buffer_t v, size_t size) \ else \ return atomic_load_explicit (&v->number[0], memory_order_relaxed) == 0; \ } \ - \ + \ static inline bool \ M_C(name, _full_p)(buffer_t v) \ { \ - BUFFERI_CONTRACT(v,m_size); \ - return atomic_load_explicit (&v->number[0], memory_order_relaxed) \ - == BUFFERI_SIZE(m_size); \ + BUFFERI_CONTRACT(v,m_size); \ + return atomic_load_explicit (&v->number[0], memory_order_relaxed) \ + == BUFFERI_SIZE(m_size); \ } \ - \ - static inline size_t \ + \ + static inline size_t \ M_C(name, _size)(buffer_t v) \ { \ - BUFFERI_CONTRACT(v,m_size); \ - return atomic_load_explicit (&v->number[0], memory_order_relaxed); \ + BUFFERI_CONTRACT(v,m_size); \ + return atomic_load_explicit (&v->number[0], memory_order_relaxed); \ } \ - \ + \ static inline bool \ M_C(name, _push_blocking)(buffer_t v, type const data, bool blocking) \ { \ - BUFFERI_CONTRACT(v,m_size); \ - \ - /* BUFFER lock */ \ + BUFFERI_CONTRACT(v,m_size); \ + \ + /* BUFFER lock */ \ if (!BUFFERI_POLICY_P((policy), BUFFER_THREAD_UNSAFE)) { \ m_mutex_lock(v->mutexPush); \ while (!BUFFERI_POLICY_P((policy), BUFFER_PUSH_OVERWRITE) \ - && M_C(name, _full_p)(v)) { \ + && M_C(name, _full_p)(v)) { \ if (!blocking) { \ m_mutex_unlock(v->mutexPush); \ return false; \ @@ -408,15 +410,15 @@ M_C(name, _init)(buffer_t v, size_t size) \ m_cond_wait(v->there_is_room_for_data, v->mutexPush); \ } \ } else if (!BUFFERI_POLICY_P((policy), BUFFER_PUSH_OVERWRITE) \ - && M_C(name, _full_p)(v)) \ + && M_C(name, _full_p)(v)) \ return false; \ - BUFFERI_PROTECTED_CONTRACT(v, m_size); \ - \ + BUFFERI_PROTECTED_CONTRACT(v, m_size); \ + \ size_t previousSize, idx = v->idx_prod; \ - /* INDEX computation if we have to overwrite the last element */ \ - if (M_UNLIKELY (BUFFERI_POLICY_P((policy), BUFFER_PUSH_OVERWRITE) \ - && M_C(name, _full_p)(v))) { \ - v->overwrite++; \ + /* INDEX computation if we have to overwrite the last element */ \ + if (M_UNLIKELY (BUFFERI_POLICY_P((policy), BUFFER_PUSH_OVERWRITE) \ + && M_C(name, _full_p)(v))) { \ + v->overwrite++; \ /* Let's overwrite the last element */ \ /* Compute the index of the last push element */ \ idx--; \ @@ -424,7 +426,7 @@ M_C(name, _init)(buffer_t v, size_t size) \ idx = idx >= BUFFERI_SIZE(m_size) ? BUFFERI_SIZE(m_size)-1 : idx; \ } \ /* Update data in the buffer */ \ - M_CALL_SET(oplist, v->data[idx], data); \ + M_CALL_SET(oplist, v->data[idx], data); \ previousSize = BUFFERI_SIZE(m_size); \ \ } else { \ @@ -449,13 +451,13 @@ M_C(name, _init)(buffer_t v, size_t size) \ thread which has the push lock. As such, it has to be handled \ like an atomic variable. */ \ /* Increment number of elements of the buffer */ \ - previousSize = atomic_fetch_add (&v->number[0], 1UL); \ + previousSize = atomic_fetch_add (&v->number[0], 1UL); \ if (BUFFERI_POLICY_P((policy), BUFFER_DEFERRED_POP)) { \ - previousSize = atomic_fetch_add (&v->number[1], 1UL); \ + previousSize = atomic_fetch_add (&v->number[1], 1UL); \ } \ } \ \ - /* BUFFER unlock */ \ + /* BUFFER unlock */ \ if (!BUFFERI_POLICY_P((policy), BUFFER_THREAD_UNSAFE)) { \ m_mutex_unlock(v->mutexPush); \ /* If the number of items in the buffer was 0, some consummer \ @@ -467,35 +469,35 @@ M_C(name, _init)(buffer_t v, size_t size) \ m_mutex_unlock(v->mutexPop); \ } \ } \ - \ - BUFFERI_CONTRACT(v,m_size); \ + \ + BUFFERI_CONTRACT(v,m_size); \ return true; \ } \ \ static inline bool \ M_C(name, _pop_blocking)(type *data, buffer_t v, bool blocking) \ { \ - BUFFERI_CONTRACT(v,m_size); \ - assert (data != NULL); \ - \ - /* BUFFER lock */ \ + BUFFERI_CONTRACT(v,m_size); \ + assert (data != NULL); \ + \ + /* BUFFER lock */ \ if (!BUFFERI_POLICY_P((policy), BUFFER_THREAD_UNSAFE)) { \ m_mutex_lock(v->mutexPop); \ - while (M_C(name, _empty_p)(v)) { \ + while (M_C(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_C(name, _empty_p)(v)) \ return false; \ - BUFFERI_PROTECTED_CONTRACT(v, m_size); \ - \ + BUFFERI_PROTECTED_CONTRACT(v, m_size); \ + \ /* POP data from the buffer and update INDEX */ \ if (!BUFFERI_POLICY_P((policy), BUFFER_STACK)) { \ /* FIFO queue */ \ - if (!BUFFERI_POLICY_P((policy), BUFFER_PUSH_INIT_POP_MOVE)) { \ + if (!BUFFERI_POLICY_P((policy), BUFFER_PUSH_INIT_POP_MOVE)) { \ M_CALL_SET(oplist, *data, v->data[v->idx_cons]); \ } else { \ M_DO_INIT_MOVE (oplist, *data, v->data[v->idx_cons]); \ @@ -518,12 +520,12 @@ M_C(name, _init)(buffer_t v, size_t size) \ /* Decrement number of elements in the buffer */ \ size_t previousSize; \ if (!BUFFERI_POLICY_P((policy), BUFFER_DEFERRED_POP)) { \ - previousSize = atomic_fetch_sub (&v->number[0], 1UL); \ + previousSize = atomic_fetch_sub (&v->number[0], 1UL); \ } else { \ - atomic_fetch_sub (&v->number[1], 1UL); \ + atomic_fetch_sub (&v->number[1], 1UL); \ } \ \ - /* BUFFER unlock */ \ + /* BUFFER unlock */ \ if (!BUFFERI_POLICY_P((policy), BUFFER_THREAD_UNSAFE)) { \ m_mutex_unlock(v->mutexPop); \ /* If the number of items in the buffer was the max, some producer \ @@ -536,31 +538,31 @@ M_C(name, _init)(buffer_t v, size_t size) \ m_mutex_unlock(v->mutexPush); \ } \ } \ - \ - BUFFERI_CONTRACT(v,m_size); \ + \ + BUFFERI_CONTRACT(v,m_size); \ return true; \ } \ - \ - \ + \ + \ static inline bool \ - M_C(name, _push)(buffer_t v, type const data) \ + M_C(name, _push)(buffer_t v, type const data) \ { \ return M_C(name, _push_blocking)(v, data, \ !BUFFERI_POLICY_P((policy), BUFFER_UNBLOCKING_PUSH)); \ } \ \ static inline bool \ - M_C(name, _pop)(type *data, buffer_t v) \ + M_C(name, _pop)(type *data, buffer_t v) \ { \ return M_C(name, _pop_blocking)(data, v, \ !BUFFERI_POLICY_P((policy), BUFFER_UNBLOCKING_POP)); \ } \ \ - static inline size_t \ - M_C(name, _overwrite)(const buffer_t v) \ + static inline size_t \ + M_C(name, _overwrite)(const buffer_t v) \ { \ - return v->overwrite; \ - } \ + return v->overwrite; \ + } \ \ static inline size_t \ M_C(name, _capacity)(const buffer_t v) \ @@ -574,7 +576,7 @@ M_C(name, _init)(buffer_t v, size_t size) \ { \ /* Decrement the effective number of elements in the buffer */ \ if (BUFFERI_POLICY_P((policy), BUFFER_DEFERRED_POP)) { \ - size_t previousSize = atomic_fetch_sub (&v->number[0], 1UL); \ + size_t previousSize = atomic_fetch_sub (&v->number[0], 1UL); \ if (previousSize == BUFFERI_SIZE(m_size)) { \ m_mutex_lock(v->mutexPush); \ m_cond_broadcast(v->there_is_room_for_data); \ @@ -600,11 +602,11 @@ M_C(name, _init)(buffer_t v, size_t size) \ #define QUEUEI_MPMC_DEF_P1(arg) QUEUEI_MPMC_DEF_P2 arg /* Validate the value oplist before going further */ -#define QUEUEI_MPMC_DEF_P2(name, type, policy, oplist, buffer_t) \ +#define QUEUEI_MPMC_DEF_P2(name, type, policy, oplist, buffer_t) \ M_IF_OPLIST(oplist)(QUEUEI_MPMC_DEF_P3, QUEUEI_MPMC_DEF_FAILURE)(name, type, policy, oplist, buffer_t) /* Stop processing with a compilation failure */ -#define QUEUEI_MPMC_DEF_FAILURE(name, type, policy, oplist, buffer_t) \ +#define QUEUEI_MPMC_DEF_FAILURE(name, type, policy, oplist, buffer_t) \ M_STATIC_FAILURE(M_LIB_NOT_AN_OPLIST, "(QUEUE_MPMC_DEF): the given argument is not a valid oplist: " M_AS_STR(oplist)) #ifdef NDEBUG @@ -621,54 +623,55 @@ M_C(name, _init)(buffer_t v, size_t size) \ } while (0) #endif + #define QUEUEI_MPMC_DEF_P3(name, type, policy, oplist, buffer_t) \ - \ - /* The sequence number of an element will be equal to either \ - - 2* the index of the production which creates it, \ - - 1 + 2* the index of the consumption which consummes it \ + \ + /* The sequence number of an element will be equal to either \ + - 2* the index of the production which creates it, \ + - 1 + 2* the index of the consumption which consummes it \ In case of wrapping, as there is no order comparison but only \ equal comparison, there is no special issue. \ Each element is put in a separate cache line to avoid false \ sharing. \ - */ \ - typedef struct M_C(name, _el_s) { \ - atomic_uint seq; /* Can only increase until wrapping */ \ - type x; \ + */ \ + typedef struct M_C(name, _el_s) { \ + atomic_uint seq; /* Can only increase until wrapping */ \ + type x; \ M_CACHELINE_ALIGN(align, atomic_uint, type); \ - } M_C(name, _el_t); \ - \ + } M_C(name, _el_t); \ + \ /* 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_C(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_t) *Tab; \ - unsigned int size; \ - } buffer_t[1]; \ - \ - static inline bool \ + unsigned int size; \ + } buffer_t[1]; \ + \ + static inline bool \ M_C(name, _push)(buffer_t table, type const x) \ - { \ + { \ QUEUEI_MPMC_CONTRACT(table); \ unsigned int idx = atomic_load_explicit(&table->ProdIdx, \ memory_order_relaxed); \ - const unsigned int i = idx & (table->size -1); \ + const unsigned int i = idx & (table->size -1); \ const unsigned int seq = atomic_load_explicit(&table->Tab[i].seq, \ memory_order_acquire); \ - if (M_UNLIKELY (2*(idx - table->size) + 1 != seq)) { \ + if (M_UNLIKELY (2*(idx - table->size) + 1 != seq)) { \ /* Buffer full (or unlikely preemption). Can not push */ \ - return false; \ - } \ + return false; \ + } \ if (M_UNLIKELY (!atomic_compare_exchange_strong_explicit(&table->ProdIdx, \ - &idx, idx+1, memory_order_relaxed, memory_order_relaxed))) { \ - /* Thread has been preempted by another one. */ \ - return false; \ - } \ + &idx, idx+1, memory_order_relaxed, memory_order_relaxed))) { \ + /* Thread has been preempted by another one. */ \ + return false; \ + } \ /* If it is interrupted here, it may block pop method (not push) */ \ if (!BUFFERI_POLICY_P((policy), BUFFER_PUSH_INIT_POP_MOVE)) { \ - M_CALL_SET(oplist, table->Tab[i].x, x); \ + M_CALL_SET(oplist, table->Tab[i].x, x); \ } else { \ M_CALL_INIT_SET(oplist, table->Tab[i].x, x); \ } \ @@ -676,27 +679,27 @@ M_C(name, _init)(buffer_t v, size_t size) \ atomic_store_explicit(&table->Tab[i].seq, 2*idx, memory_order_release); \ QUEUEI_MPMC_CONTRACT(table); \ return true; \ - } \ - \ - static inline bool \ - M_C(name, _pop)(type *ptr, buffer_t table) \ - { \ + } \ + \ + static inline bool \ + M_C(name, _pop)(type *ptr, buffer_t table) \ + { \ QUEUEI_MPMC_CONTRACT(table); \ assert (ptr != NULL); \ unsigned int iC = atomic_load_explicit(&table->ConsoIdx, \ - memory_order_relaxed); \ - const unsigned int i = (iC & (table->size -1)); \ + memory_order_relaxed); \ + const unsigned int i = (iC & (table->size -1)); \ const unsigned int seq = atomic_load_explicit(&table->Tab[i].seq, \ memory_order_acquire); \ - if (seq != 2 * iC) { \ + if (seq != 2 * iC) { \ /* Nothing in buffer to consumme (or unlikely preemption) */ \ - return false; \ - } \ + return false; \ + } \ if (M_UNLIKELY (!atomic_compare_exchange_strong_explicit(&table->ConsoIdx, \ - &iC, iC+1, memory_order_relaxed, memory_order_relaxed))) { \ - /* Thread has been preempted by another one */ \ - return false; \ - } \ + &iC, iC+1, memory_order_relaxed, memory_order_relaxed))) { \ + /* Thread has been preempted by another one */ \ + return false; \ + } \ if (!BUFFERI_POLICY_P((policy), BUFFER_PUSH_INIT_POP_MOVE)) { \ M_CALL_SET(oplist, *ptr, table->Tab[i].x); \ } else { \ @@ -705,40 +708,40 @@ M_C(name, _init)(buffer_t v, size_t size) \ atomic_store_explicit(&table->Tab[i].seq, 2*iC + 1, memory_order_release); \ QUEUEI_MPMC_CONTRACT(table); \ return true; \ - } \ - \ - static inline void \ - M_C(name, _init)(buffer_t buffer, size_t size) \ - { \ - assert (buffer != NULL); \ - assert( M_POWEROF2_P(size)); \ + } \ + \ + static inline void \ + M_C(name, _init)(buffer_t buffer, size_t size) \ + { \ + assert (buffer != NULL); \ + assert( M_POWEROF2_P(size)); \ assert (0 < size && size <= UINT_MAX); \ assert(((policy) & (BUFFER_STACK|BUFFER_THREAD_UNSAFE|BUFFER_PUSH_OVERWRITE)) == 0); \ 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_t), NULL, size); \ - if (buffer->Tab == NULL) { \ - M_MEMORY_FULL (size*sizeof(M_C(name, _el_t) )); \ - return; \ - } \ + if (buffer->Tab == NULL) { \ + M_MEMORY_FULL (size*sizeof(M_C(name, _el_t) )); \ + return; \ + } \ for(unsigned int j = 0; j < (unsigned int) size; j++) { \ atomic_init(&buffer->Tab[j].seq, 2*j+1U); \ if (!BUFFERI_POLICY_P((policy), BUFFER_PUSH_INIT_POP_MOVE)) { \ - M_CALL_INIT(oplist, buffer->Tab[j].x); \ + M_CALL_INIT(oplist, buffer->Tab[j].x); \ } \ - } \ + } \ QUEUEI_MPMC_CONTRACT(buffer); \ - } \ - \ - static inline void \ - M_C(name, _clear)(buffer_t buffer) \ - { \ + } \ + \ + static inline void \ + M_C(name, _clear)(buffer_t buffer) \ + { \ QUEUEI_MPMC_CONTRACT(buffer); \ if (!BUFFERI_POLICY_P((policy), BUFFER_PUSH_INIT_POP_MOVE)) { \ for(unsigned int j = 0; j < buffer->size; j++) { \ M_CALL_CLEAR(oplist, buffer->Tab[j].x); \ - } \ + } \ } else { \ unsigned int iP = atomic_load_explicit(&buffer->ProdIdx, memory_order_relaxed); \ unsigned int i = iP & (buffer->size -1); \ @@ -751,19 +754,19 @@ M_C(name, _init)(buffer_t v, size_t size) \ j = 0; \ } \ } \ - M_CALL_FREE(oplist, buffer->Tab); \ + M_CALL_FREE(oplist, buffer->Tab); \ buffer->Tab = NULL; /* safer */ \ - } \ - \ - static inline size_t \ + } \ + \ + static inline size_t \ M_C(name, _size)(buffer_t table) \ - { \ + { \ QUEUEI_MPMC_CONTRACT(table); \ const unsigned int iC = atomic_load_explicit(&table->ConsoIdx, memory_order_relaxed); \ const unsigned int iP = atomic_load_explicit(&table->ProdIdx, memory_order_acquire); \ /* We return an approximation as we can't read both iC & iP atomically \ As we read producer index after consummer index, \ - and they are atomic variables without reordering \ + and they are atomic variables without reordering \ producer index is always greater or equal than consumer index \ (or on overflow occurs, in which case as we compute with modulo \ arithmetic, the right result is computed). \ @@ -771,27 +774,27 @@ M_C(name, _init)(buffer_t v, size_t size) \ if the function is interrupted a long time between reading iC & \ iP. the function is not protected against it. \ */ \ - return iP-iC; \ - } \ + return iP-iC; \ + } \ \ static inline size_t \ - M_C(name, _capacity)(buffer_t v) \ + M_C(name, _capacity)(buffer_t v) \ { \ QUEUEI_MPMC_CONTRACT(v); \ return v->size; \ } \ \ - static inline bool \ - M_C(name, _empty_p)(buffer_t v) \ - { \ - return M_C(name, _size) (v) == 0; \ - } \ - \ - static inline bool \ - M_C(name, _full_p)(buffer_t v) \ - { \ + static inline bool \ + M_C(name, _empty_p)(buffer_t v) \ + { \ + return M_C(name, _size) (v) == 0; \ + } \ + \ + static inline bool \ + M_C(name, _full_p)(buffer_t v) \ + { \ return M_C(name, _size)(v) >= v->size; \ - } \ + } \ @@ -810,11 +813,11 @@ M_C(name, _init)(buffer_t v, size_t size) \ #define QUEUEI_SPSC_DEF_P1(arg) QUEUEI_SPSC_DEF_P2 arg /* Validate the value oplist before going further */ -#define QUEUEI_SPSC_DEF_P2(name, type, policy, oplist, buffer_t) \ +#define QUEUEI_SPSC_DEF_P2(name, type, policy, oplist, buffer_t) \ M_IF_OPLIST(oplist)(QUEUEI_SPSC_DEF_P3, QUEUEI_SPSC_DEF_FAILURE)(name, type, policy, oplist, buffer_t) /* Stop processing with a compilation failure */ -#define QUEUEI_SPSC_DEF_FAILURE(name, type, policy, oplist, buffer_t) \ +#define QUEUEI_SPSC_DEF_FAILURE(name, type, policy, oplist, buffer_t) \ M_STATIC_FAILURE(M_LIB_NOT_AN_OPLIST, "(QUEUE_SPSC_DEF): the given argument is not a valid oplist: " M_AS_STR(oplist)) #ifdef NDEBUG @@ -833,10 +836,10 @@ M_C(name, _init)(buffer_t v, size_t size) \ #define QUEUEI_SPSC_DEF_P3(name, type, policy, oplist, buffer_t) \ \ - typedef struct M_C(name, _el_s) { \ - type x; \ - } M_C(name, _el_t); \ - \ + typedef struct M_C(name, _el_s) { \ + type x; \ + } M_C(name, _el_t); \ + \ typedef struct M_C(name, _s) { \ atomic_uint consoIdx; /* Can only increase until overflow */ \ unsigned int size; \ @@ -845,9 +848,9 @@ M_C(name, _init)(buffer_t v, size_t size) \ atomic_uint prodIdx; /* Can only increase until overflow */ \ } buffer_t[1]; \ \ - static inline bool \ + static inline bool \ M_C(name, _push)(buffer_t table, type const x) \ - { \ + { \ QUEUEI_SPSC_CONTRACT(table); \ unsigned int r = atomic_load_explicit(&table->consoIdx, \ memory_order_relaxed); \ @@ -857,18 +860,18 @@ M_C(name, _init)(buffer_t v, size_t size) \ return false; \ unsigned int i = w & (table->size -1); \ if (!BUFFERI_POLICY_P((policy), BUFFER_PUSH_INIT_POP_MOVE)) { \ - M_CALL_SET(oplist, table->Tab[i].x, x); \ + M_CALL_SET(oplist, table->Tab[i].x, x); \ } else { \ M_CALL_INIT_SET(oplist, table->Tab[i].x, x); \ } \ - atomic_store_explicit(&table->prodIdx, w+1, memory_order_release); \ + atomic_store_explicit(&table->prodIdx, w+1, memory_order_release); \ QUEUEI_SPSC_CONTRACT(table); \ return true; \ } \ \ - static inline bool \ + static inline bool \ M_C(name, _push_move)(buffer_t table, type x) \ - { \ + { \ QUEUEI_SPSC_CONTRACT(table); \ unsigned int r = atomic_load_explicit(&table->consoIdx, \ memory_order_relaxed); \ @@ -878,24 +881,24 @@ M_C(name, _init)(buffer_t v, size_t size) \ return false; \ unsigned int i = w & (table->size -1); \ if (!BUFFERI_POLICY_P((policy), BUFFER_PUSH_INIT_POP_MOVE)) { \ - M_DO_MOVE(oplist, table->Tab[i].x, x); \ + M_DO_MOVE(oplist, table->Tab[i].x, x); \ } else { \ M_DO_INIT_MOVE(oplist, table->Tab[i].x, x); \ } \ - atomic_store_explicit(&table->prodIdx, w+1, memory_order_release); \ + atomic_store_explicit(&table->prodIdx, w+1, memory_order_release); \ QUEUEI_SPSC_CONTRACT(table); \ return true; \ } \ \ - static inline bool \ + static inline bool \ M_C(name, _pop)(type *ptr, buffer_t table) \ - { \ + { \ QUEUEI_SPSC_CONTRACT(table); \ assert (ptr != NULL); \ unsigned int w = atomic_load_explicit(&table->prodIdx, \ - memory_order_relaxed); \ + memory_order_relaxed); \ unsigned int r = atomic_load_explicit(&table->consoIdx, \ - memory_order_acquire); \ + memory_order_acquire); \ if (w-r == 0) \ return false; \ unsigned int i = r & (table->size -1); \ @@ -904,14 +907,14 @@ M_C(name, _init)(buffer_t v, size_t size) \ } else { \ M_DO_INIT_MOVE (oplist, *ptr, table->Tab[i].x); \ } \ - atomic_store_explicit(&table->consoIdx, r+1, memory_order_release); \ + atomic_store_explicit(&table->consoIdx, r+1, memory_order_release); \ QUEUEI_SPSC_CONTRACT(table); \ return true; \ } \ \ - static inline unsigned \ + static inline unsigned \ M_C(name, _push_bulk)(buffer_t table, unsigned n, type const x[]) \ - { \ + { \ QUEUEI_SPSC_CONTRACT(table); \ assert (x != NULL); \ assert (n <= table->size); \ @@ -935,16 +938,16 @@ M_C(name, _init)(buffer_t v, size_t size) \ return max; \ } \ \ - static inline unsigned \ + static inline unsigned \ M_C(name, _pop_bulk)(unsigned int n, type ptr[], buffer_t table) \ - { \ + { \ QUEUEI_SPSC_CONTRACT(table); \ assert (ptr != NULL); \ assert (n <= table->size); \ unsigned int w = atomic_load_explicit(&table->prodIdx, \ - memory_order_relaxed); \ + memory_order_relaxed); \ unsigned int r = atomic_load_explicit(&table->consoIdx, \ - memory_order_acquire); \ + memory_order_acquire); \ if (w-r == 0) \ return 0; \ unsigned int max = M_MIN(w-r, n); \ @@ -961,9 +964,9 @@ M_C(name, _init)(buffer_t v, size_t size) \ return max; \ } \ \ - static inline void \ + static inline void \ M_C(name, _push_force)(buffer_t table, type const x) \ - { \ + { \ QUEUEI_SPSC_CONTRACT(table); \ unsigned int r = atomic_load_explicit(&table->consoIdx, \ memory_order_relaxed); \ @@ -976,11 +979,11 @@ M_C(name, _init)(buffer_t v, size_t size) \ } \ unsigned int i = w & (table->size -1); \ if (!BUFFERI_POLICY_P((policy), BUFFER_PUSH_INIT_POP_MOVE)) { \ - M_CALL_SET(oplist, table->Tab[i].x, x); \ + M_CALL_SET(oplist, table->Tab[i].x, x); \ } else { \ M_CALL_INIT_SET(oplist, table->Tab[i].x, x); \ } \ - atomic_store_explicit(&table->prodIdx, w+1, memory_order_release); \ + atomic_store_explicit(&table->prodIdx, w+1, memory_order_release); \ QUEUEI_SPSC_CONTRACT(table); \ } \ \ @@ -989,12 +992,12 @@ M_C(name, _init)(buffer_t v, size_t size) \ { \ QUEUEI_SPSC_CONTRACT(table); \ unsigned int r = atomic_load_explicit(&table->consoIdx, \ - memory_order_relaxed); \ + memory_order_relaxed); \ unsigned int w = atomic_load_explicit(&table->prodIdx, \ - memory_order_acquire); \ + memory_order_acquire); \ /* We return an approximation as we can't read both r & w atomically \ As we read producer index after consummer index, \ - and they are atomic variables without reordering \ + and they are atomic variables without reordering \ producer index is always greater or equal than consumer index \ (or on overflow occurs, in which case as we compute with modulo \ arithmetic, the right result is computed). \ @@ -1006,54 +1009,54 @@ M_C(name, _init)(buffer_t v, size_t size) \ } \ \ static inline size_t \ - M_C(name, _capacity)(buffer_t v) \ + M_C(name, _capacity)(buffer_t v) \ { \ return v->size; \ } \ \ - static inline bool \ - M_C(name, _empty_p)(buffer_t v) \ - { \ - return M_C(name, _size) (v) == 0; \ - } \ - \ - static inline bool \ - M_C(name, _full_p)(buffer_t v) \ - { \ - return M_C(name, _size)(v) >= v->size; \ - } \ + static inline bool \ + M_C(name, _empty_p)(buffer_t v) \ + { \ + return M_C(name, _size) (v) == 0; \ + } \ \ - static inline void \ - M_C(name, _init)(buffer_t buffer, size_t size) \ - { \ - assert (buffer != NULL); \ - assert( M_POWEROF2_P(size)); \ + static inline bool \ + M_C(name, _full_p)(buffer_t v) \ + { \ + return M_C(name, _size)(v) >= v->size; \ + } \ + \ + static inline void \ + M_C(name, _init)(buffer_t buffer, size_t size) \ + { \ + assert (buffer != NULL); \ + assert( M_POWEROF2_P(size)); \ assert (0 < size && size <= UINT_MAX); \ assert(((policy) & (BUFFER_STACK|BUFFER_THREAD_UNSAFE|BUFFER_PUSH_OVERWRITE)) == 0); \ 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_t), NULL, size); \ - if (buffer->Tab == NULL) { \ - M_MEMORY_FULL (size*sizeof(M_C(name, _el_t) )); \ - return; \ - } \ + if (buffer->Tab == NULL) { \ + M_MEMORY_FULL (size*sizeof(M_C(name, _el_t) )); \ + return; \ + } \ if (!BUFFERI_POLICY_P((policy), BUFFER_PUSH_INIT_POP_MOVE)) { \ for(unsigned int j = 0; j < (unsigned int) size; j++) { \ - M_CALL_INIT(oplist, buffer->Tab[j].x); \ + M_CALL_INIT(oplist, buffer->Tab[j].x); \ } \ - } \ + } \ QUEUEI_SPSC_CONTRACT(buffer); \ - } \ - \ - static inline void \ - M_C(name, _clear)(buffer_t buffer) \ - { \ + } \ + \ + static inline void \ + M_C(name, _clear)(buffer_t buffer) \ + { \ QUEUEI_SPSC_CONTRACT(buffer); \ if (!BUFFERI_POLICY_P((policy), BUFFER_PUSH_INIT_POP_MOVE)) { \ for(unsigned int j = 0; j < buffer->size; j++) { \ M_CALL_CLEAR(oplist, buffer->Tab[j].x); \ - } \ + } \ } else { \ unsigned int iP = atomic_load_explicit(&buffer->prodIdx, memory_order_relaxed); \ unsigned int i = iP & (buffer->size -1); \ @@ -1066,33 +1069,33 @@ M_C(name, _init)(buffer_t v, size_t size) \ j = 0; \ } \ } \ - M_CALL_FREE(oplist, buffer->Tab); \ + M_CALL_FREE(oplist, buffer->Tab); \ buffer->Tab = NULL; /* safer */ \ - } \ - \ + } \ + \ /* Deferred evaluation for the definition, so that all arguments are evaluated before further expansion */ #define BUFFERI_OPLIST_P1(arg) BUFFERI_OPLIST_P2 arg /* Validation of the given oplist */ -#define BUFFERI_OPLIST_P2(name, oplist) \ +#define BUFFERI_OPLIST_P2(name, oplist) \ M_IF_OPLIST(oplist)(BUFFERI_OPLIST_P3, BUFFERI_OPLIST_FAILURE)(name, oplist) /* Prepare a clean compilation failure */ -#define BUFFERI_OPLIST_FAILURE(name, oplist) \ +#define BUFFERI_OPLIST_FAILURE(name, oplist) \ ((M_LIB_ERROR(ARGUMENT_OF_BUFFER_OPLIST_IS_NOT_AN_OPLIST, name, oplist))) /* OPLIST defininition of a buffer */ -#define BUFFERI_OPLIST_P3(name, oplist) \ +#define BUFFERI_OPLIST_P3(name, oplist) \ (INIT(M_C(name, _int_init)) \ - ,INIT_SET(M_C(name, _init_set)) \ - ,SET(M_C(name, _set)) \ - ,CLEAR(M_C(name, _clear)) \ - ,TYPE(M_C(name,_t)) \ - ,SUBTYPE(M_C(name, _type_t)) \ - ,CLEAN(M_C(name,_clean)) \ - ,PUSH(M_C(name,_push)) \ + ,INIT_SET(M_C(name, _init_set)) \ + ,SET(M_C(name, _set)) \ + ,CLEAR(M_C(name, _clear)) \ + ,TYPE(M_C(name,_t)) \ + ,SUBTYPE(M_C(name, _type_t)) \ + ,CLEAN(M_C(name,_clean)) \ + ,PUSH(M_C(name,_push)) \ ,POP(M_C(name,_pop)) \ ,OPLIST(oplist) \ ,TEST_EMPTY(M_C(name, _empty_p)), \ diff --git a/m-c-mempool.h b/m-c-mempool.h index d3b93de4..c6a9fdad 100644 --- a/m-c-mempool.h +++ b/m-c-mempool.h @@ -225,7 +225,7 @@ M_BEGIN_PROTECTED_CODE memory_order_relaxed)) { \ break; \ } \ - /* Failure: perform a random exponential backoff */ \ + /* Failure: perform a random exponential backoff */ \ m_core_backoff_wait(bkoff); \ } \ } \ @@ -243,7 +243,7 @@ M_BEGIN_PROTECTED_CODE /* 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_t) list, \ - m_gc_ticket_t age, m_core_backoff_t bkoff) \ + m_gc_ticket_t age, m_core_backoff_t bkoff) \ { \ M_C(name, _lf_node_t) *head; \ M_C(name, _lf_node_t) *tail; \ diff --git a/m-core.h b/m-core.h index ec09b9af..b6656671 100644 --- a/m-core.h +++ b/m-core.h @@ -1351,7 +1351,7 @@ M_BEGIN_PROTECTED_CODE #define M_IF_NARGS_EQ2(...) M_IF(M_EQUAL(M_NARGS(__VA_ARGS__), 2)) /* If NDEBUG macro is defined - M_IF_DEBUG(code if NDEBUG is not defined) + M_IF_DEBUG(code if NDEBUG is not defined) Note: not 100% robust */ #define M_TEST_NDEBUG_P() M_C3(M_, NDEBUG, _TEST) #define M_NDEBUG_TEST 0 @@ -1374,7 +1374,7 @@ M_BEGIN_PROTECTED_CODE #define f(...) M_APPLY(f, M_IF_DEFAULT1(0, __VA_ARGS__)) This need to be called within a M_APPLY macro. */ -#define M_IF_DEFAULT1(value, ...) \ +#define M_IF_DEFAULT1(value, ...) \ __VA_ARGS__ M_IF_NARGS_EQ1(__VA_ARGS__)(M_DEFERRED_COMMA value, ) /* Helper macro to redefine a function with a default values: @@ -2484,7 +2484,7 @@ m_core_hash (const void *str, size_t length) #define M_MEMCMP2_DEFAULT(a,b) (M_CHECK_SAME(a, b), memcmp(&(a), &(b), sizeof (a))) #define M_SWAP_DEFAULT(el1, el2) do { \ char _tmp[sizeof (el1)]; \ - M_CHECK_SAME(el1, el2); \ + M_CHECK_SAME(el1, el2); \ memcpy(&_tmp, &(el1), sizeof (el1)); \ memcpy(&(el1), &(el2), sizeof (el1)); \ memcpy(&(el2), &_tmp, sizeof (el1)); \ @@ -2737,12 +2737,12 @@ m_core_parse2_enum (const char str[], const char **endptr) /* Perform a preprocessing M_IF if both methods exist in the oplist. Example: M_IF_METHOD2(HASH, CMP, oplist) (define function with HASH & CMP method, ) */ -#define M_IF_METHOD2(method1, method2, oplist) \ +#define M_IF_METHOD2(method1, method2, oplist) \ M_IF(M_AND(M_TEST_METHOD_P(method1, oplist), M_TEST_METHOD_P(method2, oplist))) /* Perform a preprocessing M_IF if at least one method exists in the oplist. Example: M_IF_AT_LEAST_METHOD(HASH, CMP, oplist) (define function with HASH or CMP method, ) */ -#define M_IF_AT_LEAST_METHOD(method1, method2, oplist) \ +#define M_IF_AT_LEAST_METHOD(method1, method2, oplist) \ M_IF(M_OR(M_TEST_METHOD_P(method1, oplist), M_TEST_METHOD_P(method2, oplist))) /* Perform a preprocessing M_IF if both methods exists in both oplist. @@ -2753,7 +2753,7 @@ m_core_parse2_enum (const char str[], const char **endptr) /* Perform a preprocessing M_IF if the method exists for all oplist. Example: M_IF_METHOD_ALL(HASH, oplist1, oplist2) (define function with HASH method, ) */ -#define M_IF_METHOD_ALL(method, ...) \ +#define M_IF_METHOD_ALL(method, ...) \ M_IF(M_REDUCE2(M_TEST_METHOD_P, M_AND, method, __VA_ARGS__)) /* Perform a preprocessing M_IF if both methods exist for all oplist. @@ -2770,18 +2770,18 @@ m_core_parse2_enum (const char str[], const char **endptr) /* Perform an INIT_MOVE if present, or emulate it using INIT_SET/CLEAR */ #define M_DO_INIT_MOVE(oplist, dest, src) do { \ M_IF_METHOD(INIT_MOVE, oplist)(M_CALL_INIT_MOVE(oplist, (dest), (src)), \ - M_CALL_INIT_SET(oplist, (dest), (src)) ; \ - M_CALL_CLEAR(oplist, (src) )); \ + M_CALL_INIT_SET(oplist, (dest), (src)) ; \ + M_CALL_CLEAR(oplist, (src) )); \ } while (0) /* Perform a MOVE if present, or emulate it using CLEAR/INIT_MOVE if possible, or with SET/CLEAR otherwise */ #define M_DO_MOVE(oplist, dest, src) do { \ M_IF_METHOD(MOVE, oplist) (M_CALL_MOVE(oplist, (dest), (src)), \ - M_IF_METHOD(INIT_MOVE, oplist)(M_CALL_CLEAR(oplist, (dest)); \ - M_CALL_INIT_MOVE(oplist, (dest), (src)), \ - M_CALL_SET(oplist, (dest), (src)); \ - M_CALL_CLEAR(oplist, (src)) \ + M_IF_METHOD(INIT_MOVE, oplist)(M_CALL_CLEAR(oplist, (dest)); \ + M_CALL_INIT_MOVE(oplist, (dest), (src)), \ + M_CALL_SET(oplist, (dest), (src)); \ + M_CALL_CLEAR(oplist, (src)) \ )); \ } while (0) @@ -2800,13 +2800,13 @@ m_core_parse2_enum (const char str[], const char **endptr) otherwise it returns the argument. Global oplist is limited to typedef types. */ -#define M_GLOBAL_OPLIST(a) \ +#define M_GLOBAL_OPLIST(a) \ M_IF( M_OPLIST_P(a))(M_GLOBALI_ID, M_GLOBALI_OPLIST_ELSE)(a) #define M_GLOBALI_ID(a) a #define M_GLOBALI_OPLIST_ELSE(a) M_GLOBALI_OPLIST_ELSE2(a, M_C(M_OPL_, a)()) #define M_GLOBALI_OPLIST_ELSE2(a, op) M_IF( M_OPLIST_P (op))(op, a) -#define M_GLOBAL_TYPE(a) \ +#define M_GLOBAL_TYPE(a) \ M_IF( M_OPLIST_P(a))(M_GLOBALI_TYPE_GET, M_GLOBALI_ID)(a) #define M_GLOBALI_TYPE_GET(a) M_GET_TYPE a @@ -3086,13 +3086,13 @@ m_core_parse2_enum (const char str[], const char **endptr) an expression. */ #if defined(__cplusplus) -# define M_STATIC_ASSERT(cond, error, msg) \ +# define M_STATIC_ASSERT(cond, error, msg) \ ([] { static_assert(cond, #error ": " msg); } ()) #elif defined(__GNUC__) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L -# define M_STATIC_ASSERT(cond, error, msg) \ +# define M_STATIC_ASSERT(cond, error, msg) \ M_ATTR_EXTENSION ({ static_assert(cond, #error ": " msg); }) #else -# define M_STATIC_ASSERT(cond, error, msg) \ +# define M_STATIC_ASSERT(cond, error, msg) \ ((void) sizeof(struct { int error : !!(cond);})) #endif diff --git a/m-dict.h b/m-dict.h index 5ad826af..d59711ac 100644 --- a/m-dict.h +++ b/m-dict.h @@ -56,7 +56,7 @@ M_BEGIN_PROTECTED_CODE \ DICTI_SHASH_DEF2_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ ((name, key_type, M_GLOBAL_OPLIST_OR_DEF(key_type)(), __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)() ), \ - (name, key_type, __VA_ARGS__))) \ + (name, key_type, __VA_ARGS__))) \ M_END_PROTECTED_CODE @@ -84,7 +84,7 @@ M_BEGIN_PROTECTED_CODE \ DICTI_SET_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ ((name, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)()), \ - (name, __VA_ARGS__))) \ + (name, __VA_ARGS__))) \ M_END_PROTECTED_CODE @@ -94,10 +94,10 @@ USAGE: DICT_OASET_DEF(name, key_type[, key_oplist]) */ #define DICT_OASET_DEF(name, ...) \ - M_BEGIN_PROTECTED_CODE \ + M_BEGIN_PROTECTED_CODE \ DICTI_OASET_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ ((name, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)()), \ - (name, __VA_ARGS__))) \ + (name, __VA_ARGS__))) \ M_END_PROTECTED_CODE @@ -107,17 +107,17 @@ OR DICT_OPLIST(name) */ -#define DICT_OPLIST(...) \ - M_IF_NARGS_EQ1(__VA_ARGS__) \ +#define DICT_OPLIST(...) \ + M_IF_NARGS_EQ1(__VA_ARGS__) \ (DICTI_OPLIST_P1((__VA_ARGS__, M_DEFAULT_OPLIST, M_DEFAULT_OPLIST )), \ DICTI_OPLIST_P1((__VA_ARGS__ ))) /* Define the oplist of a dictionnary (DICT_SET_DEF). USAGE: DICT_SET_OPLIST(name[, oplist of the key type]) */ -#define DICT_SET_OPLIST(...) \ - M_IF_NARGS_EQ1(__VA_ARGS__) \ - (DICTI_SET_OPLIST_P1((__VA_ARGS__, M_DEFAULT_OPLIST)), \ +#define DICT_SET_OPLIST(...) \ + M_IF_NARGS_EQ1(__VA_ARGS__) \ + (DICTI_SET_OPLIST_P1((__VA_ARGS__, M_DEFAULT_OPLIST)), \ DICTI_SET_OPLIST_P1((__VA_ARGS__ ))) @@ -150,20 +150,20 @@ M_CHECK_COMPATIBLE_OPLIST(name, 2, value_type, value_oplist) \ \ TUPLE_DEF2(M_C(name, _pair), (key, key_type, key_oplist), (value, value_type, value_oplist)) \ - \ - M_IF_METHOD(MEMPOOL, key_oplist) \ - ( \ - LIST_DEF(M_C(name, _list_pair), M_C(name, _pair_t), \ - M_OPEXTEND(TUPLE_OPLIST(M_C(name, _pair), key_oplist, value_oplist), \ - MEMPOOL(M_GET_MEMPOOL key_oplist), MEMPOOL_LINKAGE(M_GET_MEMPOOL_LINKAGE key_oplist))) \ - , \ - LIST_DEF(M_C(name, _list_pair), M_C(name, _pair_t), \ - TUPLE_OPLIST(M_C(name, _pair), key_oplist, value_oplist)) \ + \ + M_IF_METHOD(MEMPOOL, key_oplist) \ + ( \ + LIST_DEF(M_C(name, _list_pair), M_C(name, _pair_t), \ + M_OPEXTEND(TUPLE_OPLIST(M_C(name, _pair), key_oplist, value_oplist), \ + MEMPOOL(M_GET_MEMPOOL key_oplist), MEMPOOL_LINKAGE(M_GET_MEMPOOL_LINKAGE key_oplist))) \ + , \ + LIST_DEF(M_C(name, _list_pair), M_C(name, _pair_t), \ + TUPLE_OPLIST(M_C(name, _pair), key_oplist, value_oplist)) \ ) \ - \ - ARRAY_DEF(M_C(name, _array_list_pair), M_C(name, _list_pair_t), \ - LIST_OPLIST(M_C(name, _list_pair), TUPLE_OPLIST(M_C(name, _pair), key_oplist, value_oplist))) \ - \ + \ + ARRAY_DEF(M_C(name, _array_list_pair), M_C(name, _list_pair_t), \ + LIST_OPLIST(M_C(name, _list_pair), TUPLE_OPLIST(M_C(name, _pair), key_oplist, value_oplist))) \ + \ DICTI_FUNC_DEF2_P5(name, key_type, key_oplist, value_type, value_oplist, 0, 0, M_C(name, _t), M_C(name, _it_t)) @@ -188,25 +188,25 @@ M_STATIC_FAILURE(M_LIB_NOT_AN_OPLIST, "(DICT_STOREHASH_DEF2): at least one of the given argument is not a valid oplist: " M_AS_STR(key_oplist) " / " M_AS_STR(value_oplist) ) #define DICTI_SHASH_DEF2_P4(name, key_type, key_oplist, value_type, value_oplist) \ - \ + \ M_CHECK_COMPATIBLE_OPLIST(name, 1, key_type, key_oplist) \ M_CHECK_COMPATIBLE_OPLIST(name, 2, value_type, value_oplist) \ \ TUPLE_DEF2(M_C(name, _pair), (hash, size_t, M_DEFAULT_OPLIST), (key, key_type, key_oplist), (value, value_type, value_oplist)) \ - \ - M_IF_METHOD(MEMPOOL, key_oplist) \ - ( \ - LIST_DEF(M_C(name, _list_pair), M_C(name, _pair_t), \ - M_OPEXTEND(TUPLE_OPLIST(M_C(name, _pair), key_oplist, value_oplist), \ - MEMPOOL(M_GET_MEMPOOL key_oplist), MEMPOOL_LINKAGE(M_GET_MEMPOOL_LINKAGE key_oplist))) \ - , \ - LIST_DEF(M_C(name, _list_pair), M_C(name, _pair_t), \ + \ + M_IF_METHOD(MEMPOOL, key_oplist) \ + ( \ + LIST_DEF(M_C(name, _list_pair), M_C(name, _pair_t), \ + M_OPEXTEND(TUPLE_OPLIST(M_C(name, _pair), key_oplist, value_oplist), \ + MEMPOOL(M_GET_MEMPOOL key_oplist), MEMPOOL_LINKAGE(M_GET_MEMPOOL_LINKAGE key_oplist))) \ + , \ + LIST_DEF(M_C(name, _list_pair), M_C(name, _pair_t), \ TUPLE_OPLIST(M_C(name, _pair), M_DEFAULT_OPLIST, key_oplist, value_oplist)) \ ) \ - \ - ARRAY_DEF(M_C(name, _array_list_pair), M_C(name, _list_pair_t), \ - LIST_OPLIST(M_C(name, _list_pair), TUPLE_OPLIST(M_C(name, _pair), M_DEFAULT_OPLIST, key_oplist, value_oplist))) \ - \ + \ + ARRAY_DEF(M_C(name, _array_list_pair), M_C(name, _list_pair_t), \ + LIST_OPLIST(M_C(name, _list_pair), TUPLE_OPLIST(M_C(name, _pair), M_DEFAULT_OPLIST, key_oplist, value_oplist))) \ + \ DICTI_FUNC_DEF2_P5(name, key_type, key_oplist, value_type, value_oplist, 0, 1, M_C(name, _t), M_C(name, _it_t)) @@ -221,28 +221,28 @@ M_IF_OPLIST(key_oplist)(DICTI_SET_DEF_P4, DICTI_SET_DEF_FAILURE)(name, key_type, key_oplist) /* Stop processing with a compilation failure */ -#define DICTI_SET_DEF_FAILURE(name, key_type, key_oplist)\ +#define DICTI_SET_DEF_FAILURE(name, key_type, key_oplist) \ M_STATIC_FAILURE(M_LIB_NOT_AN_OPLIST, "(DICT_SET_DEF): the given argument is not a valid oplist: " M_AS_STR(key_oplist) ) #define DICTI_SET_DEF_P4(name, key_type, key_oplist) \ - \ + \ M_CHECK_COMPATIBLE_OPLIST(name, 1, key_type, key_oplist) \ \ - TUPLE_DEF2(M_C(name, _pair), (key, key_type, key_oplist)) \ - \ - M_IF_METHOD(MEMPOOL, key_oplist) \ - ( \ - LIST_DEF(M_C(name, _list_pair), M_C(name, _pair_t), \ - M_OPEXTEND(TUPLE_OPLIST(M_C(name, _pair), key_oplist), \ - MEMPOOL(M_GET_MEMPOOL key_oplist), MEMPOOL_LINKAGE(M_GET_MEMPOOL_LINKAGE key_oplist))) \ - , \ + TUPLE_DEF2(M_C(name, _pair), (key, key_type, key_oplist)) \ + \ + M_IF_METHOD(MEMPOOL, key_oplist) \ + ( \ + LIST_DEF(M_C(name, _list_pair), M_C(name, _pair_t), \ + M_OPEXTEND(TUPLE_OPLIST(M_C(name, _pair), key_oplist), \ + MEMPOOL(M_GET_MEMPOOL key_oplist), MEMPOOL_LINKAGE(M_GET_MEMPOOL_LINKAGE key_oplist))) \ + , \ LIST_DEF(M_C(name, _list_pair), M_C(name, _pair_t), TUPLE_OPLIST(M_C(name, _pair), key_oplist)) \ ) \ - \ - ARRAY_DEF(M_C(name, _array_list_pair), M_C(name, _list_pair_t), \ - LIST_OPLIST(M_C(name, _list_pair), TUPLE_OPLIST(M_C(name, _pair), key_oplist))) \ \ - DICTI_FUNC_DEF2_P5(name, key_type, key_oplist, key_type, \ + ARRAY_DEF(M_C(name, _array_list_pair), M_C(name, _list_pair_t), \ + LIST_OPLIST(M_C(name, _list_pair), TUPLE_OPLIST(M_C(name, _pair), key_oplist))) \ + \ + DICTI_FUNC_DEF2_P5(name, key_type, key_oplist, key_type, \ M_EMPTY_OPLIST, 1, 0, M_C(name, _t), M_C(name, _it_t)) @@ -252,9 +252,9 @@ /* NOTE: \ if isSet is true, all methods of value_oplist are NOP methods */ \ \ - typedef struct M_C(name, _s) { \ + typedef struct M_C(name, _s) { \ size_t used, lower_limit, upper_limit; \ - M_C(name, _array_list_pair_t) table; \ + M_C(name, _array_list_pair_t) table; \ } dict_t[1]; \ \ typedef struct M_C(name, _s) *M_C(name, _ptr); \ @@ -268,17 +268,17 @@ typedef key_type M_C(name, _key_type_t); \ typedef value_type M_C(name, _value_type_t); \ \ - typedef struct M_C(name, _it_s) { \ - M_C(name, _array_list_pair_it_t) array_it; \ - M_C(name, _list_pair_it_t) list_it; \ - } dict_it_t[1]; \ + typedef struct M_C(name, _it_s) { \ + M_C(name, _array_list_pair_it_t) array_it; \ + M_C(name, _list_pair_it_t) list_it; \ + } dict_it_t[1]; \ \ static inline void \ - M_C(name, _init)(dict_t map) \ + M_C(name, _init)(dict_t map) \ { \ - assert (map != NULL); \ + assert (map != NULL); \ map->used = 0; \ - M_C(name, _array_list_pair_init)(map->table); \ + M_C(name, _array_list_pair_init)(map->table); \ M_C(name, _array_list_pair_resize)(map->table, DICTI_INITIAL_SIZE); \ map->lower_limit = DICTI_LOWER_BOUND(DICTI_INITIAL_SIZE); \ map->upper_limit = DICTI_UPPER_BOUND(DICTI_INITIAL_SIZE); \ @@ -286,75 +286,75 @@ } \ \ static inline void \ - M_C(name, _init_set)(dict_t map, const dict_t org) \ + M_C(name, _init_set)(dict_t map, const dict_t org) \ { \ DICTI_CONTRACT(name, org); \ assert (map != org); \ map->used = org->used; \ map->lower_limit = org->lower_limit; \ map->upper_limit = org->upper_limit; \ - M_C(name, _array_list_pair_init_set)(map->table, org->table); \ + M_C(name, _array_list_pair_init_set)(map->table, org->table); \ DICTI_CONTRACT(name, map); \ } \ \ static inline void \ - M_C(name, _set)(dict_t map, const dict_t org) \ + M_C(name, _set)(dict_t map, const dict_t org) \ { \ DICTI_CONTRACT(name, map); \ DICTI_CONTRACT(name, org); \ map->used = org->used; \ map->lower_limit = org->lower_limit; \ map->upper_limit = org->upper_limit; \ - M_C(name, _array_list_pair_set)(map->table, org->table); \ + M_C(name, _array_list_pair_set)(map->table, org->table); \ DICTI_CONTRACT(name, map); \ } \ \ static inline void \ - M_C(name,_clear)(dict_t map) \ + M_C(name,_clear)(dict_t map) \ { \ DICTI_CONTRACT(name, map); \ - M_C(name, _array_list_pair_clear)(map->table); \ + M_C(name, _array_list_pair_clear)(map->table); \ } \ \ static inline void \ - M_C(name, _init_move)(dict_t map, dict_t org) \ + M_C(name, _init_move)(dict_t map, dict_t org) \ { \ DICTI_CONTRACT(name, org); \ map->used = org->used; \ map->lower_limit = org->lower_limit; \ map->upper_limit = org->upper_limit; \ - M_C(name, _array_list_pair_init_move)(map->table, org->table); \ + M_C(name, _array_list_pair_init_move)(map->table, org->table); \ DICTI_CONTRACT(name, map); \ } \ - \ + \ static inline void \ - M_C(name, _swap)(dict_t d1, dict_t d2) \ + M_C(name, _swap)(dict_t d1, dict_t d2) \ { \ DICTI_CONTRACT(name, d1); \ DICTI_CONTRACT(name, d2); \ M_SWAP (size_t, d1->used, d2->used); \ M_SWAP (size_t, d1->lower_limit, d2->lower_limit); \ M_SWAP (size_t, d1->upper_limit, d2->upper_limit); \ - M_C(name, _array_list_pair_swap)(d1->table, d2->table); \ + M_C(name, _array_list_pair_swap)(d1->table, d2->table); \ DICTI_CONTRACT(name, d1); \ DICTI_CONTRACT(name, d2); \ } \ - \ + \ static inline void \ - M_C(name, _move)(dict_t map, dict_t org) \ + M_C(name, _move)(dict_t map, dict_t org) \ { \ DICTI_CONTRACT(name, map); \ DICTI_CONTRACT(name, org); \ assert (map != org); \ - M_C(name,_clear)(map); \ - M_C(name,_init_move)(map, org); \ + M_C(name,_clear)(map); \ + M_C(name,_init_move)(map, org); \ DICTI_CONTRACT(name, map); \ } \ - \ + \ static inline void \ - M_C(name,_clean)(dict_t map) \ + M_C(name,_clean)(dict_t map) \ { \ - M_C(name, _array_list_pair_clean)(map->table); \ + M_C(name, _array_list_pair_clean)(map->table); \ M_C(name, _array_list_pair_resize)(map->table, DICTI_INITIAL_SIZE); \ map->lower_limit = DICTI_LOWER_BOUND(DICTI_INITIAL_SIZE); \ map->upper_limit = DICTI_UPPER_BOUND(DICTI_INITIAL_SIZE); \ @@ -363,32 +363,32 @@ } \ \ static inline bool \ - M_C(name,_empty_p)(const dict_t map) \ + M_C(name,_empty_p)(const dict_t map) \ { \ DICTI_CONTRACT(name, map); \ return map->used == 0; \ } \ \ static inline size_t \ - M_C(name,_size)(const dict_t map) \ + M_C(name,_size)(const dict_t map) \ { \ DICTI_CONTRACT(name, map); \ return map->used; \ } \ \ static inline value_type * \ - M_C(name, _get)(const dict_t map, key_type const key) \ + M_C(name, _get)(const dict_t map, key_type const key) \ { \ DICTI_CONTRACT(name, map); \ size_t hash = M_CALL_HASH(key_oplist, key); \ size_t i = hash & (M_C(name, _array_list_pair_size)(map->table) - 1); \ - const M_C(name, _list_pair_t) *list_ptr = \ + const M_C(name, _list_pair_t) *list_ptr = \ M_C(name, _array_list_pair_cget)(map->table, i); \ - M_C(name, _list_pair_it_t) it; \ - for(M_C(name, _list_pair_it)(it, *list_ptr); \ - !M_C(name, _list_pair_end_p)(it); \ - M_C(name, _list_pair_next)(it)) { \ - M_C(name, _pair_t) *ref = M_C(name, _list_pair_ref)(it); \ + M_C(name, _list_pair_it_t) it; \ + for(M_C(name, _list_pair_it)(it, *list_ptr); \ + !M_C(name, _list_pair_end_p)(it); \ + M_C(name, _list_pair_next)(it)) { \ + M_C(name, _pair_t) *ref = M_C(name, _list_pair_ref)(it); \ M_IF(isStoreHash)(if ((*ref)->hash != hash) { continue; }, ) \ if (M_CALL_EQUAL(key_oplist, (*ref)->key, key)) \ return &(*ref)->M_IF(isSet)(key, value); \ @@ -403,37 +403,37 @@ } \ \ static inline void \ - M_C(name, _int_resize_up)(dict_t map) \ + M_C(name, _int_resize_up)(dict_t map) \ { \ /* NOTE: Contract may not be fullfilled here */ \ - size_t old_size = M_C(name, _array_list_pair_size)(map->table); \ + size_t old_size = M_C(name, _array_list_pair_size)(map->table); \ size_t new_size = old_size * 2; \ - if (M_UNLIKELY (new_size <= old_size)) { \ - M_MEMORY_FULL((size_t)-1); \ - } \ - /* Resize the table of the dictionnary */ \ - M_C(name, _array_list_pair_resize)(map->table, new_size); \ + if (M_UNLIKELY (new_size <= old_size)) { \ + M_MEMORY_FULL((size_t)-1); \ + } \ + /* Resize the table of the dictionnary */ \ + M_C(name, _array_list_pair_resize)(map->table, new_size); \ /* Move the items to the new upper part */ \ for(size_t i = 0; i < old_size; i++) { \ - M_C(name, _list_pair_t) *list = \ - M_C(name, _array_list_pair_get)(map->table, i); \ - if (M_C(name, _list_pair_empty_p)(*list)) \ + M_C(name, _list_pair_t) *list = \ + M_C(name, _array_list_pair_get)(map->table, i); \ + if (M_C(name, _list_pair_empty_p)(*list)) \ continue; \ /* We need to scan each item and recompute its hash to know \ if it remains inplace or shall be moved to the upper part.*/ \ - M_C(name, _list_pair_it_t) it; \ - M_C(name, _list_pair_it)(it, *list); \ - while (!M_C(name, _list_pair_end_p)(it)) { \ - M_C(name, _pair_ptr) pair = *M_C(name, _list_pair_ref)(it); \ + M_C(name, _list_pair_it_t) it; \ + M_C(name, _list_pair_it)(it, *list); \ + while (!M_C(name, _list_pair_end_p)(it)) { \ + M_C(name, _pair_ptr) pair = *M_C(name, _list_pair_ref)(it); \ size_t hash = M_IF(isStoreHash)(pair->hash, M_CALL_HASH(key_oplist, pair->key)); \ if ((hash & (new_size-1)) >= old_size) { \ assert( (hash & (new_size-1)) == (i + old_size)); \ - M_C(name, _list_pair_t) *new_list = \ - M_C(name, _array_list_pair_get)(map->table, i + old_size); \ - M_C(name, _list_pair_splice_back)(*new_list, *list, it); \ + M_C(name, _list_pair_t) *new_list = \ + M_C(name, _array_list_pair_get)(map->table, i + old_size); \ + M_C(name, _list_pair_splice_back)(*new_list, *list, it); \ /* Splice_back has updated the iterator to the next one */ \ } else { \ - M_C(name, _list_pair_next)(it); \ + M_C(name, _list_pair_next)(it); \ } \ } \ } \ @@ -442,46 +442,46 @@ } \ \ static inline void \ - M_C(name, _int_resize_down)(dict_t map) \ + M_C(name, _int_resize_down)(dict_t map) \ { \ /* NOTE: Contract may not be fullfilled here */ \ - size_t old_size = M_C(name, _array_list_pair_size)(map->table); \ + size_t old_size = M_C(name, _array_list_pair_size)(map->table); \ assert ((old_size % 2) == 0); \ size_t new_size = old_size / 2; \ assert (new_size >= DICTI_INITIAL_SIZE); \ /* Move all items from the upper part to the lower part of the table */ \ - /* NOTE: We don't need to recompute the hash to move them! */ \ + /* NOTE: We don't need to recompute the hash to move them! */ \ for(size_t i = new_size; i < old_size; i++) { \ - M_C(name, _list_pair_t) *list = \ - M_C(name, _array_list_pair_get)(map->table, i); \ - if (M_C(name, _list_pair_empty_p)(*list)) \ + M_C(name, _list_pair_t) *list = \ + M_C(name, _array_list_pair_get)(map->table, i); \ + if (M_C(name, _list_pair_empty_p)(*list)) \ continue; \ - M_C(name, _list_pair_t) *new_list = \ - M_C(name, _array_list_pair_get)(map->table, i - new_size); \ - M_C(name, _list_pair_splice)(*new_list, *list); \ + M_C(name, _list_pair_t) *new_list = \ + M_C(name, _array_list_pair_get)(map->table, i - new_size); \ + M_C(name, _list_pair_splice)(*new_list, *list); \ } \ /* Resize the table of the dictionary */ \ - M_C(name, _array_list_pair_resize)(map->table, new_size); \ + M_C(name, _array_list_pair_resize)(map->table, new_size); \ map->upper_limit = DICTI_UPPER_BOUND(new_size); \ map->lower_limit = DICTI_LOWER_BOUND(new_size); \ } \ - \ + \ static inline void \ M_IF(isSet)(M_C(name, _push), M_C(name, _set_at)) \ (dict_t map, key_type const key \ M_IF(isSet)(, M_DEFERRED_COMMA value_type const value)) \ { \ DICTI_CONTRACT(name, map); \ - \ + \ size_t hash = M_CALL_HASH(key_oplist, key); \ size_t i = hash & (M_C(name, _array_list_pair_size)(map->table) - 1); \ - M_C(name, _list_pair_t) *list_ptr = \ + M_C(name, _list_pair_t) *list_ptr = \ M_C(name, _array_list_pair_get)(map->table, i); \ - M_C(name, _list_pair_it_t) it; \ - for(M_C(name, _list_pair_it)(it, *list_ptr); \ - !M_C(name, _list_pair_end_p)(it); \ - M_C(name, _list_pair_next)(it)) { \ - M_C(name, _pair_ptr) ref = *M_C(name, _list_pair_ref)(it); \ + M_C(name, _list_pair_it_t) it; \ + for(M_C(name, _list_pair_it)(it, *list_ptr); \ + !M_C(name, _list_pair_end_p)(it); \ + M_C(name, _list_pair_next)(it)) { \ + M_C(name, _pair_ptr) ref = *M_C(name, _list_pair_ref)(it); \ M_IF(isStoreHash)(if (ref->hash != hash) continue;, ) \ if (M_CALL_EQUAL(key_oplist,ref->key, key)) { \ M_CALL_SET(value_oplist, ref->value, value); \ @@ -490,28 +490,28 @@ } \ M_C(name, _pair_init_set2)(*M_C(name, _list_pair_push_raw)(*list_ptr), \ M_IF(isStoreHash)(hash M_DEFERRED_COMMA,) \ - key \ + key \ M_IF(isSet)(, M_DEFERRED_COMMA value)); \ map->used ++; \ if (M_UNLIKELY (map->used > map->upper_limit) ) \ - M_C(name,_int_resize_up)(map); \ + M_C(name,_int_resize_up)(map); \ DICTI_CONTRACT(name, map); \ } \ - \ + \ static inline value_type * \ M_C(name, _get_at)(dict_t map, key_type const key) \ { \ DICTI_CONTRACT(name, map); \ - \ + \ size_t hash = M_CALL_HASH(key_oplist, key); \ size_t i = hash & (M_C(name, _array_list_pair_size)(map->table) - 1); \ - M_C(name, _list_pair_t) *list_ptr = \ + M_C(name, _list_pair_t) *list_ptr = \ M_C(name, _array_list_pair_get)(map->table, i); \ - M_C(name, _list_pair_it_t) it; \ - for(M_C(name, _list_pair_it)(it, *list_ptr); \ - !M_C(name, _list_pair_end_p)(it); \ - M_C(name, _list_pair_next)(it)) { \ - M_C(name, _pair_ptr) ref = *M_C(name, _list_pair_ref)(it); \ + M_C(name, _list_pair_it_t) it; \ + for(M_C(name, _list_pair_it)(it, *list_ptr); \ + !M_C(name, _list_pair_end_p)(it); \ + M_C(name, _list_pair_next)(it)) { \ + M_C(name, _pair_ptr) ref = *M_C(name, _list_pair_ref)(it); \ M_IF(isStoreHash)(if (ref->hash != hash) continue;, ) \ if (M_CALL_EQUAL(key_oplist, ref->key, key)) { \ return &ref->M_IF(isSet)(key, value); \ @@ -522,7 +522,7 @@ M_C(name, _pair_set_key)(*ref, key); \ map->used ++; \ if (M_UNLIKELY (map->used > map->upper_limit) ) { \ - M_C(name,_int_resize_up)(map); \ + M_C(name,_int_resize_up)(map); \ /* Even if the array is being resized, the pointer 'ref' \ shall still point to the same item in the bucket (it may still \ be in a different bucket) */ \ @@ -532,110 +532,110 @@ } \ \ static inline bool \ - M_C(name, _erase)(dict_t map, key_type const key) \ + M_C(name, _erase)(dict_t map, key_type const key) \ { \ DICTI_CONTRACT(name, map); \ \ bool ret = false; \ size_t hash = M_CALL_HASH(key_oplist, key); \ size_t i = hash & (M_C(name, _array_list_pair_size)(map->table) - 1); \ - M_C(name, _list_pair_t) *list_ptr = \ + M_C(name, _list_pair_t) *list_ptr = \ M_C(name, _array_list_pair_get)(map->table, i); \ - M_C(name, _list_pair_it_t) it; \ - for(M_C(name, _list_pair_it)(it, *list_ptr); \ - !M_C(name, _list_pair_end_p)(it); \ - M_C(name, _list_pair_next)(it)) { \ - M_C(name, _pair_ptr) ref = *M_C(name, _list_pair_ref)(it); \ + M_C(name, _list_pair_it_t) it; \ + for(M_C(name, _list_pair_it)(it, *list_ptr); \ + !M_C(name, _list_pair_end_p)(it); \ + M_C(name, _list_pair_next)(it)) { \ + M_C(name, _pair_ptr) ref = *M_C(name, _list_pair_ref)(it); \ M_IF(isStoreHash)(if (ref->hash != hash) continue;, ) \ if (M_CALL_EQUAL(key_oplist, ref->key, key)) { \ - M_C(name, _list_pair_remove)(*list_ptr, it); \ + M_C(name, _list_pair_remove)(*list_ptr, it); \ map->used --; \ ret = true; \ break; \ } \ } \ if (M_UNLIKELY (map->used < map->lower_limit) ) \ - M_C(name, _int_resize_down)(map); \ + M_C(name, _int_resize_down)(map); \ return ret; \ } \ \ - static inline void \ - M_C(name, _it)(dict_it_t it, const dict_t d) \ - { \ - DICTI_CONTRACT(name, d); \ - M_C(name, _array_list_pair_it)(it->array_it, d->table); \ - M_C(name, _list_pair_t) *ref = \ - M_C(name, _array_list_pair_ref)(it->array_it); \ - M_C(name, _list_pair_it)(it->list_it, *ref); \ - while (M_C(name, _list_pair_end_p)(it->list_it)) { \ - M_C(name, _array_list_pair_next)(it->array_it); \ - if (M_UNLIKELY (M_C(name, _array_list_pair_end_p)(it->array_it))) \ - break; \ - ref = M_C(name, _array_list_pair_ref)(it->array_it); \ - M_C(name, _list_pair_it)(it->list_it, *ref); \ - } \ - } \ - \ - static inline void \ - M_C(name, _it_set)(dict_it_t it, const dict_it_t ref) \ - { \ - assert (it != NULL && ref != NULL); \ - M_C(name, _array_list_pair_it_set)(it->array_it, \ - ref->array_it); \ - M_C(name, _list_pair_it_set)(it->list_it, ref->list_it); \ - } \ - \ - static inline void \ - M_C(name, _it_end)(dict_it_t it, const dict_t d) \ - { \ - DICTI_CONTRACT(name, d); \ - M_C(name, _array_list_pair_it_end)(it->array_it, d->table); \ - } \ - \ - static inline bool \ - M_C(name, _end_p)(const dict_it_t it) \ - { \ - assert (it != NULL); \ - return M_C(name, _list_pair_end_p)(it->list_it); \ - } \ - \ - static inline void \ - M_C(name, _next)(dict_it_t it) \ - { \ - assert(it != NULL); \ - M_C(name, _list_pair_next)(it->list_it); \ - M_C(name, _list_pair_t) *ref; \ - while (M_C(name, _list_pair_end_p)(it->list_it)) { \ - M_C(name, _array_list_pair_next)(it->array_it); \ - if (M_C(name, _array_list_pair_end_p)(it->array_it)) \ - break; \ - ref = M_C(name, _array_list_pair_ref)(it->array_it); \ - M_C(name, _list_pair_it)(it->list_it, *ref); \ - } \ - } \ - \ - static inline bool \ - M_C(name, _last_p)(const dict_it_t it) \ - { \ - assert (it != NULL); \ - dict_it_t it2; \ - M_C(name,_it_set)(it2, it); \ - M_C(name, _next)(it2); \ - return M_C(name, _end_p)(it2); \ - } \ - \ - static inline bool \ - M_C(name, _it_equal_p)(const dict_it_t it1, const dict_it_t it2) \ - { \ - assert (it1 != NULL && it2 != NULL); \ - return M_C(name, _list_pair_it_equal_p)(it1->list_it, \ - it2->list_it); \ - } \ - \ + static inline void \ + M_C(name, _it)(dict_it_t it, const dict_t d) \ + { \ + DICTI_CONTRACT(name, d); \ + M_C(name, _array_list_pair_it)(it->array_it, d->table); \ + M_C(name, _list_pair_t) *ref = \ + M_C(name, _array_list_pair_ref)(it->array_it); \ + M_C(name, _list_pair_it)(it->list_it, *ref); \ + while (M_C(name, _list_pair_end_p)(it->list_it)) { \ + M_C(name, _array_list_pair_next)(it->array_it); \ + if (M_UNLIKELY (M_C(name, _array_list_pair_end_p)(it->array_it))) \ + break; \ + ref = M_C(name, _array_list_pair_ref)(it->array_it); \ + M_C(name, _list_pair_it)(it->list_it, *ref); \ + } \ + } \ + \ + static inline void \ + M_C(name, _it_set)(dict_it_t it, const dict_it_t ref) \ + { \ + assert (it != NULL && ref != NULL); \ + M_C(name, _array_list_pair_it_set)(it->array_it, \ + ref->array_it); \ + M_C(name, _list_pair_it_set)(it->list_it, ref->list_it); \ + } \ + \ + static inline void \ + M_C(name, _it_end)(dict_it_t it, const dict_t d) \ + { \ + DICTI_CONTRACT(name, d); \ + M_C(name, _array_list_pair_it_end)(it->array_it, d->table); \ + } \ + \ + static inline bool \ + M_C(name, _end_p)(const dict_it_t it) \ + { \ + assert (it != NULL); \ + return M_C(name, _list_pair_end_p)(it->list_it); \ + } \ + \ + static inline void \ + M_C(name, _next)(dict_it_t it) \ + { \ + assert(it != NULL); \ + M_C(name, _list_pair_next)(it->list_it); \ + M_C(name, _list_pair_t) *ref; \ + while (M_C(name, _list_pair_end_p)(it->list_it)) { \ + M_C(name, _array_list_pair_next)(it->array_it); \ + if (M_C(name, _array_list_pair_end_p)(it->array_it)) \ + break; \ + ref = M_C(name, _array_list_pair_ref)(it->array_it); \ + M_C(name, _list_pair_it)(it->list_it, *ref); \ + } \ + } \ + \ + static inline bool \ + M_C(name, _last_p)(const dict_it_t it) \ + { \ + assert (it != NULL); \ + dict_it_t it2; \ + M_C(name,_it_set)(it2, it); \ + M_C(name, _next)(it2); \ + return M_C(name, _end_p)(it2); \ + } \ + \ + static inline bool \ + M_C(name, _it_equal_p)(const dict_it_t it1, const dict_it_t it2) \ + { \ + assert (it1 != NULL && it2 != NULL); \ + return M_C(name, _list_pair_it_equal_p)(it1->list_it, \ + it2->list_it); \ + } \ + \ static inline M_C(name, _type_t) * \ - M_C(name, _ref)(const dict_it_t it) \ - { \ - assert(it != NULL); \ + M_C(name, _ref)(const dict_it_t it) \ + { \ + assert(it != NULL); \ /* NOTE: partially unsafe if the user modify the 'key' \ in a non equivalent way */ \ M_IF(isSet)( \ @@ -643,25 +643,25 @@ , \ return *M_C(name, _list_pair_ref)(it->list_it); \ ) \ - } \ - \ + } \ + \ static inline const M_C(name, _type_t) * \ M_C(name, _cref)(const dict_it_t it) \ - { \ - assert(it != NULL); \ + { \ + assert(it != NULL); \ M_IF(isSet)( \ return &(*M_C(name, _list_pair_cref)(it->list_it))->key; \ , \ return *M_C(name, _list_pair_cref)(it->list_it); \ ) \ - } \ + } \ \ - M_IF_METHOD(EQUAL, value_oplist)( \ + M_IF_METHOD(EQUAL, value_oplist)( \ static inline bool \ M_C(name, _equal_p)(const dict_t dict1, const dict_t dict2) \ - { \ - assert (dict1 != NULL && dict2 != NULL); \ - /* NOTE: Key type has mandatory equal operator */ \ + { \ + assert (dict1 != NULL && dict2 != NULL); \ + /* NOTE: Key type has mandatory equal operator */ \ /* First the easy cases */ \ if (M_LIKELY (dict1->used != dict2->used)) \ return false; \ @@ -683,8 +683,8 @@ return false; \ } \ return true; \ - } \ - , /* no value equal */ ) \ + } \ + , /* no value equal */ ) \ \ DICTI_FUNC_ADDITIONAL_DEF2(name, key_type, key_oplist, value_type, value_oplist, isSet, dict_t, dict_it_t) @@ -692,8 +692,8 @@ /* Define additional functions for dictionnary (Common for all kinds of dictionnary). Do not used any fields of the dictionnary but the public API */ #define DICTI_FUNC_ADDITIONAL_DEF2(name, key_type, key_oplist, value_type, value_oplist, isSet, dict_t, dict_it_t) \ - \ - M_IF_METHOD_BOTH(GET_STR, key_oplist, value_oplist)( \ + \ + M_IF_METHOD_BOTH(GET_STR, key_oplist, value_oplist)( \ static inline void \ M_C(name, _get_str)(string_t str, const dict_t dict, const bool append) \ { \ @@ -701,9 +701,9 @@ (append ? string_cat_str : string_set_str) (str, "{"); \ dict_it_t it; \ bool print_comma = false; \ - for (M_C(name, _it)(it, dict) ; \ - !M_C(name, _end_p)(it); \ - M_C(name, _next)(it)){ \ + for (M_C(name, _it)(it, dict) ; \ + !M_C(name, _end_p)(it); \ + M_C(name, _next)(it)){ \ if (print_comma) \ string_push_back (str, ','); \ const M_C(name, _type_t) *item = M_C(name, _cref)(it); \ @@ -719,19 +719,19 @@ string_push_back (str, '}'); \ STRINGI_CONTRACT(str); \ } \ - , /* no GET_STR */ ) \ + , /* no GET_STR */ ) \ \ M_IF_METHOD_BOTH(OUT_STR, key_oplist, value_oplist)( \ static inline void \ - M_C(name, _out_str)(FILE *file, const dict_t dict) \ + M_C(name, _out_str)(FILE *file, const dict_t dict) \ { \ assert (file != NULL); \ fputc ('{', file); \ dict_it_t it; \ bool print_comma = false; \ - for (M_C(name, _it)(it, dict) ; \ - !M_C(name, _end_p)(it); \ - M_C(name, _next)(it)){ \ + for (M_C(name, _it)(it, dict) ; \ + !M_C(name, _end_p)(it); \ + M_C(name, _next)(it)){ \ if (print_comma) \ fputc (',', file); \ const M_C(name, _type_t) *item = M_C(name, _cref)(it); \ @@ -746,8 +746,8 @@ } \ fputc ('}', file); \ } \ - , /* no OUT_STR */ ) \ - \ + , /* no OUT_STR */ ) \ + \ M_IF_METHOD_BOTH(PARSE_STR, key_oplist, value_oplist)( \ static inline bool \ M_C(name, _parse_str)(dict_t dict, const char str[], const char **endp) \ @@ -789,13 +789,13 @@ return success; \ } \ , /* no PARSE_STR */ ) \ - \ + \ M_IF_METHOD_BOTH(IN_STR, key_oplist, value_oplist)( \ static inline bool \ - M_C(name, _in_str)(dict_t dict, FILE *file) \ + M_C(name, _in_str)(dict_t dict, FILE *file) \ { \ assert (file != NULL); \ - M_C(name, _clean)(dict); \ + M_C(name, _clean)(dict); \ int c = fgetc(file); \ if (M_UNLIKELY (c != '{')) return false; \ c = fgetc(file); \ @@ -824,20 +824,20 @@ M_C(name, _set_at)(dict, key, value); \ ) \ do { c = fgetc(file); } while (isspace(c)); \ - } while (c == ','); \ + } while (c == ','); \ M_CALL_CLEAR(key_oplist, key); \ M_IF(isSet)(, \ M_CALL_CLEAR(value_oplist, value); \ ) \ return c == '}'; \ } \ - , /* no IN_STR */ ) \ + , /* no IN_STR */ ) \ \ M_IF_METHOD_BOTH(OUT_SERIAL, key_oplist, value_oplist)( \ static inline m_serial_return_code_t \ M_C(name, _out_serial)(m_serial_write_t f, dict_t const t1) \ { \ - assert (f != NULL && f->m_interface != NULL); \ + assert (f != NULL && f->m_interface != NULL); \ m_serial_local_t local; \ m_serial_return_code_t ret; \ const M_C(name, _type_t) *item; \ @@ -845,18 +845,18 @@ dict_it_t it; \ /* Format is different between associative container \ & set container */ \ - M_IF(isSet)( \ + M_IF(isSet)( \ ret = f->m_interface->write_array_start(local, f, M_C(name, _size)(t1)); \ for (M_C(name, _it)(it, t1) ; \ !M_C(name, _end_p)(it); \ M_C(name, _next)(it)){ \ item = M_C(name, _cref)(it); \ if (first_done) \ - ret |= f->m_interface->write_array_next(local, f); \ + ret |= f->m_interface->write_array_next(local, f); \ ret |= M_CALL_OUT_SERIAL(key_oplist, f, *item); \ first_done = true; \ } \ - ret |= f->m_interface->write_array_end(local, f); \ + ret |= f->m_interface->write_array_end(local, f); \ , \ ret = f->m_interface->write_map_start(local, f, M_C(name, _size)(t1)); \ for (M_C(name, _it)(it, t1) ; \ @@ -864,13 +864,13 @@ M_C(name, _next)(it)){ \ item = M_C(name, _cref)(it); \ if (first_done) \ - ret |= f->m_interface->write_map_next(local, f); \ + ret |= f->m_interface->write_map_next(local, f); \ ret |= M_CALL_OUT_SERIAL(key_oplist, f, item->key); \ - ret |= f->m_interface->write_map_value(local, f); \ + ret |= f->m_interface->write_map_value(local, f); \ ret |= M_CALL_OUT_SERIAL(value_oplist, f, item->value); \ first_done = true; \ } \ - ret |= f->m_interface->write_map_end(local, f); \ + ret |= f->m_interface->write_map_end(local, f); \ ) \ return ret & M_SERIAL_FAIL; \ } \ @@ -880,12 +880,12 @@ static inline m_serial_return_code_t \ M_C(name, _in_serial)(dict_t t1, m_serial_read_t f) \ { \ - assert (f != NULL && f->m_interface != NULL); \ + assert (f != NULL && f->m_interface != NULL); \ m_serial_local_t local; \ m_serial_return_code_t ret; \ size_t estimated_size = 0; \ key_type key; \ - M_C(name,_clean)(t1); \ + M_C(name,_clean)(t1); \ M_IF(isSet)( \ ret = f->m_interface->read_array_start(local, f, &estimated_size); \ if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) return ret; \ @@ -898,18 +898,18 @@ M_CALL_CLEAR(key_oplist, key); \ , \ value_type value; \ - ret = f->m_interface->read_map_start(local, f, &estimated_size); \ + ret = f->m_interface->read_map_start(local, f, &estimated_size); \ if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) return ret; \ M_CALL_INIT(key_oplist, key); \ - M_CALL_INIT (value_oplist, value); \ - do { \ + M_CALL_INIT (value_oplist, value); \ + do { \ ret = M_CALL_IN_SERIAL(key_oplist, key, f); \ if (ret != M_SERIAL_OK_DONE) return M_SERIAL_FAIL; \ - ret = f->m_interface->read_map_value(local, f); \ + ret = f->m_interface->read_map_value(local, f); \ if (ret != M_SERIAL_OK_CONTINUE) return M_SERIAL_FAIL; \ ret = M_CALL_IN_SERIAL(value_oplist, value, f); \ if (ret != M_SERIAL_OK_DONE) return M_SERIAL_FAIL; \ - M_C(name, _set_at)(t1, key, value); \ + M_C(name, _set_at)(t1, key, value); \ } while ((ret = f->m_interface->read_map_next(local, f)) == M_SERIAL_OK_CONTINUE); \ M_CALL_CLEAR(key_oplist, key); \ M_CALL_CLEAR(value_oplist, value); \ @@ -917,41 +917,41 @@ return ret; \ } \ , /* no in_serial */ ) \ - \ + \ M_IF(isSet)( \ - static inline void \ + static inline void \ M_C(name, _splice)(dict_t d1, dict_t d2) \ - { \ + { \ dict_it_t it; \ - /* NOTE: Despite using set_at, the accessing of the item in d1 \ - is not as random as other uses of the HASH table as d2 \ - uses the same order than d1 */ \ - for (M_C(name, _it)(it, d2); !M_C(name, _end_p)(it); M_C(name, _next)(it)){ \ + /* NOTE: Despite using set_at, the accessing of the item in d1 \ + is not as random as other uses of the HASH table as d2 \ + uses the same order than d1 */ \ + for (M_C(name, _it)(it, d2); !M_C(name, _end_p)(it); M_C(name, _next)(it)){ \ const M_C(name, _type_t) *item = M_C(name, _cref)(it); \ M_C(name, _push)(d1, *item); \ - } \ - M_C(name, _clean)(d2); \ - } \ + } \ + M_C(name, _clean)(d2); \ + } \ , \ M_IF_METHOD(UPDATE, value_oplist)( \ - static inline void \ + static inline void \ M_C(name, _splice)(dict_t d1, dict_t d2) \ - { \ + { \ dict_it_t it; \ - /* NOTE: Despite using set_at, the accessing of the item in d1 \ - is not as random as other uses of the HASH table as d2 \ - uses the same order than d1 */ \ - for (M_C(name, _it)(it, d2); !M_C(name, _end_p)(it); M_C(name, _next)(it)){ \ - const struct M_C(name, _pair_s) *item = M_C(name, _cref)(it); \ - value_type *ptr = M_C(name, _get)(d1, item->key); \ - if (ptr == NULL) { \ - M_C(name, _set_at)(d1, item->key, item->value); \ - } else { \ - M_CALL_UPDATE(value_oplist, *ptr, item->value); \ - } \ - } \ - M_C(name, _clean)(d2); \ - } \ + /* NOTE: Despite using set_at, the accessing of the item in d1 \ + is not as random as other uses of the HASH table as d2 \ + uses the same order than d1 */ \ + for (M_C(name, _it)(it, d2); !M_C(name, _end_p)(it); M_C(name, _next)(it)){ \ + const struct M_C(name, _pair_s) *item = M_C(name, _cref)(it); \ + value_type *ptr = M_C(name, _get)(d1, item->key); \ + if (ptr == NULL) { \ + M_C(name, _set_at)(d1, item->key, item->value); \ + } else { \ + M_CALL_UPDATE(value_oplist, *ptr, item->value); \ + } \ + } \ + M_C(name, _clean)(d2); \ + } \ , /* NO UPDATE */) ) \ \ /* HASH method for dictionnary itself seems hard to implement: \ @@ -972,39 +972,39 @@ #define DICTI_OPLIST_P1(arg) DICTI_OPLIST_P2 arg /* Validation of the given oplists */ -#define DICTI_OPLIST_P2(name, key_oplist, value_oplist) \ +#define DICTI_OPLIST_P2(name, key_oplist, value_oplist) \ M_IF_OPLIST(key_oplist)(DICTI_OPLIST_P3, DICTI_OPLIST_FAILURE)(name, key_oplist, value_oplist) -#define DICTI_OPLIST_P3(name, key_oplist, value_oplist) \ +#define DICTI_OPLIST_P3(name, key_oplist, value_oplist) \ M_IF_OPLIST(value_oplist)(DICTI_OPLIST_P4, DICTI_OPLIST_FAILURE)(name, key_oplist, value_oplist) /* Prepare a clean compilation failure */ -#define DICTI_OPLIST_FAILURE(name, key_oplist, value_oplist) \ +#define DICTI_OPLIST_FAILURE(name, key_oplist, value_oplist) \ ((M_LIB_ERROR(ARGUMENT_OF_DICT_OPLIST_IS_NOT_AN_OPLIST, name, key_oplist, value_oplist))) /* Define the oplist of a dictionnary NOTE: IT_REF is not exported so that the contained appears as not modifiable by algorithm.*/ -#define DICTI_OPLIST_P4(name, key_oplist, value_oplist) \ - (INIT(M_C(name, _init)), \ - INIT_SET(M_C(name, _init_set)), \ +#define DICTI_OPLIST_P4(name, key_oplist, value_oplist) \ + (INIT(M_C(name, _init)), \ + INIT_SET(M_C(name, _init_set)), \ INIT_WITH(API_1(M_INIT_KEY_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_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)), \ CLEAN(M_C(name, _clean)), \ - TYPE(M_C(name, _t)), \ + TYPE(M_C(name, _t)), \ SUBTYPE(M_C(name, _type_t)), \ TEST_EMPTY(M_C(name,_empty_p)), \ - IT_TYPE(M_C(name, _it_t)), \ - IT_FIRST(M_C(name,_it)), \ - IT_SET(M_C(name, _it_set)), \ - IT_END(M_C(name,_it_end)), \ - IT_END_P(M_C(name,_end_p)), \ - IT_LAST_P(M_C(name,_last_p)), \ - IT_NEXT(M_C(name,_next)), \ - IT_CREF(M_C(name,_cref)) \ + IT_TYPE(M_C(name, _it_t)), \ + IT_FIRST(M_C(name,_it)), \ + IT_SET(M_C(name, _it_set)), \ + IT_END(M_C(name,_it_end)), \ + IT_END_P(M_C(name,_end_p)), \ + IT_LAST_P(M_C(name,_last_p)), \ + IT_NEXT(M_C(name,_next)), \ + IT_CREF(M_C(name,_cref)) \ ,KEY_TYPE(M_C(name, _key_type_t)) \ ,VALUE_TYPE(M_C(name, _value_type_t)) \ ,SET_KEY(M_C(name, _set_at)) \ @@ -1020,7 +1020,7 @@ ,M_IF_METHOD_BOTH(IN_STR, key_oplist, value_oplist)(IN_STR(M_C(name, _in_str)),) \ ,M_IF_METHOD_BOTH(OUT_SERIAL, key_oplist, value_oplist)(OUT_SERIAL(M_C(name, _out_serial)),) \ ,M_IF_METHOD_BOTH(IN_SERIAL, key_oplist, value_oplist)(IN_SERIAL(M_C(name, _in_serial)),) \ - ,M_IF_METHOD(EQUAL, value_oplist)(EQUAL(M_C(name, _equal_p)),) \ + ,M_IF_METHOD(EQUAL, value_oplist)(EQUAL(M_C(name, _equal_p)),) \ ,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW key_oplist),) \ ,M_IF_METHOD(REALLOC, oplist)(REALLOC(M_GET_REALLOC key_oplist),) \ ,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL key_oplist),) \ @@ -1031,28 +1031,28 @@ #define DICTI_SET_OPLIST_P1(arg) DICTI_SET_OPLIST_P2 arg /* Validation of the given oplist */ -#define DICTI_SET_OPLIST_P2(name, oplist) \ +#define DICTI_SET_OPLIST_P2(name, oplist) \ M_IF_OPLIST(oplist)(DICTI_SET_OPLIST_P3, DICTI_SET_OPLIST_FAILURE)(name, oplist) /* Prepare a clean compilation failure */ -#define DICTI_SET_OPLIST_FAILURE(name, oplist) \ +#define DICTI_SET_OPLIST_FAILURE(name, oplist) \ ((M_LIB_ERROR(ARGUMENT_OF_DICT_SET_OPLIST_IS_NOT_AN_OPLIST, name, oplist))) /* Define the oplist of a set */ #define DICTI_SET_OPLIST_P3(name, oplist) \ - (INIT(M_C(name, _init)), \ - INIT_SET(M_C(name, _init_set)), \ + (INIT(M_C(name, _init)), \ + INIT_SET(M_C(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_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)), \ CLEAN(M_C(name, _clean)), \ - TYPE(M_C(name, _t)), \ + TYPE(M_C(name, _t)), \ SUBTYPE(M_C(name, _type_t)), \ TEST_EMPTY(M_C(name,_empty_p)), \ - PUSH(M_C(name,_push)), \ + PUSH(M_C(name,_push)), \ KEY_TYPE(M_C(name, _key_type_t)), \ VALUE_TYPE(M_C(name, _key_type_t)), \ GET_KEY(M_C(name, _get)), \ @@ -1061,15 +1061,15 @@ KEY_OPLIST(oplist), \ VALUE_OPLIST(oplist), \ GET_SIZE(M_C(name, _size)), \ - IT_TYPE(M_C(name, _it_t)), \ - IT_FIRST(M_C(name,_it)), \ - IT_SET(M_C(name, _it_set)), \ - IT_END(M_C(name,_it_end)), \ - IT_END_P(M_C(name,_end_p)), \ - IT_LAST_P(M_C(name,_last_p)), \ - IT_NEXT(M_C(name,_next)), \ - IT_REF(M_C(name,_ref)), \ - IT_CREF(M_C(name,_cref)) \ + IT_TYPE(M_C(name, _it_t)), \ + IT_FIRST(M_C(name,_it)), \ + IT_SET(M_C(name, _it_set)), \ + IT_END(M_C(name,_it_end)), \ + IT_END_P(M_C(name,_end_p)), \ + IT_LAST_P(M_C(name,_last_p)), \ + IT_NEXT(M_C(name,_next)), \ + IT_REF(M_C(name,_ref)), \ + IT_CREF(M_C(name,_cref)) \ ,OPLIST(oplist) \ ,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)),) \ @@ -1130,13 +1130,14 @@ typedef enum { #define DICTI_OA_UPPER_BOUND 0.7 #endif -#define DICTI_OA_CONTRACT(dict) do { \ - assert ( (dict) != NULL); \ - assert( (dict)->lower_limit <= (dict)->count && (dict)->count <= (dict)->upper_limit ); \ - assert( (dict)->data != NULL); \ - assert( M_POWEROF2_P((dict)->mask+1)); \ - assert( (dict)->mask+1 >= DICTI_INITIAL_SIZE); \ - assert( (dict)->count <= (dict)->mask+1); \ +#define DICTI_OA_CONTRACT(dict) do { \ + assert ( (dict) != NULL); \ + assert( (dict)->lower_limit <= (dict)->count); \ + assert( (dict)->count <= (dict)->upper_limit ); \ + assert( (dict)->data != NULL); \ + assert( M_POWEROF2_P((dict)->mask+1)); \ + assert( (dict)->mask+1 >= DICTI_INITIAL_SIZE); \ + assert( (dict)->count <= (dict)->mask+1); \ } while (0) #define DICTI_OA_DEF_P1(args) DICTI_OA_DEF_P2 args @@ -1160,11 +1161,11 @@ typedef enum { #define DICTI_OASET_DEF_P1(args) DICTI_OASET_DEF_P2 args /* Validate the value oplist before going further */ -#define DICTI_OASET_DEF_P2(name, key_type, key_oplist) \ +#define DICTI_OASET_DEF_P2(name, key_type, key_oplist) \ M_IF_OPLIST(key_oplist)(DICTI_OASET_DEF_P4, DICTI_OASET_DEF_FAILURE)(name, key_type, key_oplist) /* Stop processing with a compilation failure */ -#define DICTI_OASET_DEF_FAILURE(name, key_type, key_oplist) \ +#define DICTI_OASET_DEF_FAILURE(name, key_type, key_oplist) \ M_STATIC_FAILURE(M_LIB_NOT_AN_OPLIST, "(DICT_OASET_DEF): the given argument is not a valid oplist: " M_AS_STR(key_oplist) ) #define DICTI_OASET_DEF_P4(name, key_type, key_oplist) \ @@ -1172,15 +1173,15 @@ typedef enum { DICTI_OA_LOWER_BOUND, DICTI_OA_UPPER_BOUND, M_C(name,_t), M_C(name, _it_t) ) #define DICTI_OA_DEF_P5(name, key_type, key_oplist, value_type, value_oplist, isSet, coeff_down, coeff_up, dict_t, dict_it_t) \ - \ + \ /* NOTE: \ if isSet is true, all methods of value_oplist are NOP methods */ \ \ - typedef struct M_C(name, _pair_s) { \ + typedef struct M_C(name, _pair_s) { \ key_type key; \ M_IF(isSet)( , value_type value;) \ - } M_C(name, _pair_t); \ - \ + } M_C(name, _pair_t); \ + \ M_IF(isSet)( \ typedef key_type M_C(name, _type_t); \ , \ @@ -1192,38 +1193,38 @@ typedef enum { M_CHECK_COMPATIBLE_OPLIST(name, 2, value_type, value_oplist) \ \ /* NOTE: We don't want a real oplist for this sub type */ \ - ARRAY_DEF(M_C(name, _array_pair), M_C(name, _pair_t), \ + ARRAY_DEF(M_C(name, _array_pair), M_C(name, _pair_t), \ (INIT(M_NOTHING_DEFAULT), SET(M_MEMCPY_DEFAULT), \ INIT_SET(M_MEMCPY_DEFAULT), CLEAR(M_NOTHING_DEFAULT))) \ \ - typedef struct M_C(name,_s) { \ + typedef struct M_C(name,_s) { \ size_t mask, count, count_delete; \ size_t upper_limit, lower_limit; \ - M_C(name, _pair_t) *data; \ + M_C(name, _pair_t) *data; \ } dict_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_C(name, _it_s) { \ + \ + typedef struct M_C(name, _it_s) { \ const struct M_C(name,_s) *dict; \ size_t index; \ } dict_it_t[1]; \ \ static inline void \ - M_C(name,_int_limit)(dict_t dict, size_t size) \ + M_C(name,_int_limit)(dict_t dict, size_t size) \ { \ dict->upper_limit = (size_t) ((double) size * coeff_up) - 1; \ dict->lower_limit = (size <= DICTI_INITIAL_SIZE) ? 0 : (size_t) ((double) size * coeff_down) ; \ } \ \ static inline void \ - M_C(name, _init)(dict_t dict) \ + M_C(name, _init)(dict_t dict) \ { \ assert(0 <= (coeff_down) && (coeff_down)*2 < (coeff_up) && (coeff_up) < 1); \ dict->mask = DICTI_INITIAL_SIZE-1; \ dict->count = 0; \ dict->count_delete = 0; \ - M_C(name,_int_limit)(dict, DICTI_INITIAL_SIZE); \ + M_C(name,_int_limit)(dict, DICTI_INITIAL_SIZE); \ dict->data = M_CALL_REALLOC(key_oplist, M_C(name, _pair_t), NULL, DICTI_INITIAL_SIZE); \ if (dict->data == NULL) { \ M_MEMORY_FULL(sizeof (M_C(name, _pair_t)) * DICTI_INITIAL_SIZE); \ @@ -1234,9 +1235,9 @@ typedef enum { } \ DICTI_OA_CONTRACT(dict); \ } \ - \ + \ static inline void \ - M_C(name, _clear)(dict_t dict) \ + M_C(name, _clear)(dict_t dict) \ { \ DICTI_OA_CONTRACT(dict); \ for(size_t i = 0; i <= dict->mask; i++) { \ @@ -1251,16 +1252,16 @@ typedef enum { dict->mask = 0; \ dict->data = NULL; \ } \ - \ + \ static inline value_type * \ - M_C(name, _get)(const dict_t dict, key_type const key) \ + M_C(name, _get)(const dict_t dict, key_type const key) \ { \ DICTI_OA_CONTRACT(dict); \ - /* NOTE: Key can not be the representation of empty or deleted */ \ - assert (!M_CALL_OOR_EQUAL(key_oplist, key, DICTI_OA_EMPTY)); \ - assert (!M_CALL_OOR_EQUAL(key_oplist, key, DICTI_OA_DELETED)); \ - \ - M_C(name, _pair_t) *const data = dict->data; \ + /* NOTE: Key can not be the representation of empty or deleted */ \ + assert (!M_CALL_OOR_EQUAL(key_oplist, key, DICTI_OA_EMPTY)); \ + assert (!M_CALL_OOR_EQUAL(key_oplist, key, DICTI_OA_DELETED)); \ + \ + M_C(name, _pair_t) *const data = dict->data; \ const size_t mask = dict->mask; \ size_t p = M_CALL_HASH(key_oplist, key) & mask; \ \ @@ -1269,7 +1270,7 @@ typedef enum { return &data[p].M_IF(isSet)(key, value); \ else if (M_LIKELY (M_CALL_OOR_EQUAL(key_oplist, data[p].key, DICTI_OA_EMPTY)) ) \ return NULL; \ - \ + \ /* Unlikely case */ \ size_t s = 1; \ do { \ @@ -1278,7 +1279,7 @@ typedef enum { return &data[p].M_IF(isSet)(key, value); \ assert (s <= dict->mask); \ } while (!M_CALL_OOR_EQUAL(key_oplist, data[p].key, DICTI_OA_EMPTY) ); \ - \ + \ return NULL; \ } \ \ @@ -1290,10 +1291,10 @@ typedef enum { \ M_IF_DEBUG( \ static inline bool \ - M_C(name,_int_control_after_resize)(const dict_t h) \ + M_C(name,_int_control_after_resize)(const dict_t h) \ { \ - /* This function checks if the reshashing of the dict is ok */ \ - M_C(name, _pair_t) *data = h->data; \ + /* This function checks if the reshashing of the dict is ok */ \ + M_C(name, _pair_t) *data = h->data; \ size_t empty = 0; \ size_t del = 0; \ for(size_t i = 0 ; i <= h->mask ; i++) { \ @@ -1307,17 +1308,17 @@ typedef enum { ) \ \ static inline void \ - M_C(name,_int_resize_up)(dict_t h, size_t newSize, bool updateLimit) \ + M_C(name,_int_resize_up)(dict_t h, size_t newSize, bool updateLimit) \ { \ size_t oldSize = h->mask+1; \ assert (newSize >= oldSize); \ assert (M_POWEROF2_P(newSize)); \ - M_C(name, _pair_t) *data = h->data; \ - /* resize can be called just to delete the items */ \ + M_C(name, _pair_t) *data = h->data; \ + /* resize can be called just to delete the items */ \ if (newSize > oldSize) { \ data = M_CALL_REALLOC(key_oplist, M_C(name, _pair_t), data, newSize); \ if (M_UNLIKELY (data == NULL) ) { \ - M_MEMORY_FULL(sizeof (M_C(name, _pair_t)) * newSize); \ + M_MEMORY_FULL(sizeof (M_C(name, _pair_t)) * newSize); \ return ; \ } \ \ @@ -1328,11 +1329,11 @@ typedef enum { \ /* Then let's rehash all the entries in their **exact** position. \ If we can't, let's put them in the 'tmp' array. \ - It has been measured that the size of this 'tmp' array is \ - around 6% of the size of updated dictionnary. \ + It has been measured that the size of this 'tmp' array is \ + around 6% of the size of updated dictionnary. \ NOTE: This should be much cache friendly than typical hash code */ \ - M_C(name, _array_pair_t) tmp; \ - M_C(name, _array_pair_init)(tmp); \ + M_C(name, _array_pair_t) tmp; \ + M_C(name, _array_pair_init)(tmp); \ const size_t mask = (newSize -1); \ \ for(size_t i = 0 ; i < oldSize; i++) { \ @@ -1360,7 +1361,7 @@ typedef enum { while (M_C(name, _array_pair_size)(tmp) > 0) { \ M_C(name, _pair_t) const *item = M_C(name, _array_pair_back)(tmp); \ size_t p = M_CALL_HASH(key_oplist, item->key) & mask; \ - /* NOTE: since the first pass, the bucket might be free now */ \ + /* NOTE: since the first pass, the bucket might be free now */ \ if (!M_CALL_OOR_EQUAL(key_oplist, data[p].key, DICTI_OA_EMPTY)) { \ size_t s = 1; \ do { \ @@ -1371,31 +1372,31 @@ typedef enum { M_C(name, _array_pair_pop_move)(&data[p], tmp); \ } \ \ - M_C(name, _array_pair_clear) (tmp); \ + M_C(name, _array_pair_clear) (tmp); \ h->mask = newSize-1; \ h->count_delete = h->count; \ - if (updateLimit == true) { \ - M_C(name,_int_limit)(h, newSize); \ - } \ + if (updateLimit == true) { \ + M_C(name,_int_limit)(h, newSize); \ + } \ h->data = data; \ - M_IF_DEBUG (assert (M_C(name,_int_control_after_resize)(h));) \ + M_IF_DEBUG (assert (M_C(name,_int_control_after_resize)(h));) \ DICTI_OA_CONTRACT(h); \ } \ - \ + \ static inline void \ M_IF(isSet)(M_C(name, _push), M_C(name,_set_at)) \ (dict_t dict, key_type const key \ M_IF(isSet)(, M_DEFERRED_COMMA value_type const value) ) \ { \ DICTI_OA_CONTRACT(dict); \ - /* NOTE: key can not be the representation of empty or deleted */ \ + /* NOTE: key can not be the representation of empty or deleted */ \ assert (!M_CALL_OOR_EQUAL(key_oplist, key, DICTI_OA_EMPTY)); \ assert (!M_CALL_OOR_EQUAL(key_oplist, key, DICTI_OA_DELETED)); \ - \ - M_C(name, _pair_t) *const data = dict->data; \ + \ + M_C(name, _pair_t) *const data = dict->data; \ const size_t mask = dict->mask; \ size_t p = M_CALL_HASH(key_oplist, key) & mask; \ - \ + \ /* NOTE: Likely cache miss */ \ if (M_UNLIKELY (M_CALL_EQUAL(key_oplist, data[p].key, key)) ) { \ M_CALL_SET(value_oplist, data[p].value, value); \ @@ -1414,10 +1415,10 @@ typedef enum { assert (s <= dict->mask); \ if (M_CALL_OOR_EQUAL(key_oplist, data[p].key, DICTI_OA_DELETED) && delPos == (size_t)-1) delPos = p; \ } while (!M_CALL_OOR_EQUAL(key_oplist, data[p].key, DICTI_OA_EMPTY) ); \ - if (delPos != SIZE_MAX) { \ - p = delPos; \ - dict->count_delete --; \ - } \ + if (delPos != SIZE_MAX) { \ + p = delPos; \ + dict->count_delete --; \ + } \ } \ \ M_CALL_INIT_SET(key_oplist, data[p].key, key); \ @@ -1427,29 +1428,29 @@ typedef enum { \ if (M_UNLIKELY (dict->count_delete >= dict->upper_limit)) { \ size_t newSize = dict->mask+1; \ - if (dict->count > (dict->mask / 2)) { \ - newSize += newSize; \ - if (M_UNLIKELY (newSize <= dict->mask+1)) { \ - M_MEMORY_FULL((size_t)-1); \ - } \ - } \ - M_C(name,_int_resize_up)(dict, newSize, true); \ + if (dict->count > (dict->mask / 2)) { \ + newSize += newSize; \ + if (M_UNLIKELY (newSize <= dict->mask+1)) { \ + M_MEMORY_FULL((size_t)-1); \ + } \ + } \ + M_C(name,_int_resize_up)(dict, newSize, true); \ } \ DICTI_OA_CONTRACT(dict); \ } \ - \ + \ static inline value_type * \ - M_C(name,_get_at)(dict_t dict, key_type const key) \ + M_C(name,_get_at)(dict_t dict, key_type const key) \ { \ DICTI_OA_CONTRACT(dict); \ - /* NOTE: key can not be the representation of empty or deleted */ \ + /* NOTE: key can not be the representation of empty or deleted */ \ assert (!M_CALL_OOR_EQUAL(key_oplist, key, DICTI_OA_EMPTY)); \ assert (!M_CALL_OOR_EQUAL(key_oplist, key, DICTI_OA_DELETED)); \ - \ - M_C(name, _pair_t) *const data = dict->data; \ + \ + M_C(name, _pair_t) *const data = dict->data; \ const size_t mask = dict->mask; \ size_t p = M_CALL_HASH(key_oplist, key) & mask; \ - \ + \ if (M_CALL_EQUAL(key_oplist, data[p].key, key)) { \ return &data[p].M_IF(isSet)(key, value); \ } \ @@ -1465,10 +1466,10 @@ typedef enum { assert (s <= dict->mask); \ if (M_CALL_OOR_EQUAL(key_oplist, data[p].key, DICTI_OA_DELETED) && delPos == (size_t)-1) delPos = p; \ } while (!M_CALL_OOR_EQUAL(key_oplist, data[p].key, DICTI_OA_EMPTY) ); \ - if (delPos != SIZE_MAX) { \ - p = delPos; \ - dict->count_delete --; \ - } \ + if (delPos != SIZE_MAX) { \ + p = delPos; \ + dict->count_delete --; \ + } \ } \ \ M_CALL_INIT_SET(key_oplist, data[p].key, key); \ @@ -1478,32 +1479,32 @@ typedef enum { \ if (M_UNLIKELY (dict->count_delete >= dict->upper_limit)) { \ size_t newSize = dict->mask+1; \ - if (dict->count > (dict->mask / 2)) { \ - newSize += newSize; \ - if (M_UNLIKELY (newSize <= dict->mask+1)) { \ - M_MEMORY_FULL((size_t)-1); \ - } \ - } \ - M_C(name,_int_resize_up)(dict, newSize, true); \ - /* data is now invalid */ \ - return M_C(name, _get)(dict, key); \ + if (dict->count > (dict->mask / 2)) { \ + newSize += newSize; \ + if (M_UNLIKELY (newSize <= dict->mask+1)) { \ + M_MEMORY_FULL((size_t)-1); \ + } \ + } \ + M_C(name,_int_resize_up)(dict, newSize, true); \ + /* data is now invalid */ \ + return M_C(name, _get)(dict, key); \ } \ DICTI_OA_CONTRACT(dict); \ return &data[p].M_IF(isSet)(key, value); \ } \ \ static inline void \ - M_C(name,_int_resize_down)(dict_t h, size_t newSize) \ + M_C(name,_int_resize_down)(dict_t h, size_t newSize) \ { \ size_t oldSize = h->mask+1; \ assert (newSize <= oldSize && M_POWEROF2_P(newSize)); \ if (M_UNLIKELY (newSize < DICTI_INITIAL_SIZE)) \ newSize = DICTI_INITIAL_SIZE; \ const size_t mask = newSize -1; \ - M_C(name, _pair_t) *data = h->data; \ - M_C(name, _array_pair_t) tmp; \ - M_C(name, _array_pair_init)(tmp); \ - \ + M_C(name, _pair_t) *data = h->data; \ + M_C(name, _array_pair_t) tmp; \ + M_C(name, _array_pair_init)(tmp); \ + \ /* Pass 1: scan lower entries, and move them if needed */ \ for(size_t i = 0; i < newSize; i++) { \ if (M_CALL_OOR_EQUAL(key_oplist, data[i].key, DICTI_OA_EMPTY)) \ @@ -1555,29 +1556,29 @@ typedef enum { } \ M_C(name, _array_pair_pop_move)(&data[p], tmp); \ } \ - \ - M_C(name, _array_pair_clear) (tmp); \ + \ + M_C(name, _array_pair_clear) (tmp); \ h->count_delete = h->count; \ if (newSize != oldSize) { \ h->mask = newSize-1; \ - M_C(name,_int_limit)(h, newSize); \ + M_C(name,_int_limit)(h, newSize); \ h->data = M_CALL_REALLOC(key_oplist, M_C(name, _pair_t), data, newSize); \ assert (h->data != NULL); \ } \ - M_IF_DEBUG (assert (M_C(name,_int_control_after_resize)(h));) \ + M_IF_DEBUG (assert (M_C(name,_int_control_after_resize)(h));) \ assert (h->lower_limit < h->count && h->count < h->upper_limit); \ DICTI_OA_CONTRACT(h); \ } \ \ static inline bool \ - M_C(name,_erase)(dict_t dict, const key_type key) \ + M_C(name,_erase)(dict_t dict, const key_type key) \ { \ DICTI_OA_CONTRACT(dict); \ - /* NOTE: key can't be the representation of empty or deleted */ \ + /* NOTE: key can't be the representation of empty or deleted */ \ assert (!M_CALL_OOR_EQUAL(key_oplist, key, DICTI_OA_EMPTY)); \ assert (!M_CALL_OOR_EQUAL(key_oplist, key, DICTI_OA_DELETED)); \ \ - M_C(name, _pair_t) *const data = dict->data; \ + M_C(name, _pair_t) *const data = dict->data; \ const size_t mask = dict->mask; \ size_t p = M_CALL_HASH(key_oplist, key) & mask; \ \ @@ -1599,7 +1600,7 @@ typedef enum { assert (dict->count >= 1); \ dict->count--; \ if (M_UNLIKELY (dict->count < dict->lower_limit)) { \ - M_C(name,_int_resize_down)(dict, (dict->mask+1) >> 1); \ + M_C(name,_int_resize_down)(dict, (dict->mask+1) >> 1); \ } \ DICTI_OA_CONTRACT(dict); \ return true; \ @@ -1613,14 +1614,14 @@ typedef enum { } \ \ static inline size_t \ - M_C(name,_size)(const dict_t dict) \ + M_C(name,_size)(const dict_t dict) \ { \ DICTI_OA_CONTRACT(dict); \ return dict->count; \ } \ \ static inline void \ - M_C(name, _init_set)(dict_t map, const dict_t org) \ + M_C(name, _init_set)(dict_t map, const dict_t org) \ { \ DICTI_OA_CONTRACT(org); \ assert (map != org); \ @@ -1631,7 +1632,7 @@ typedef enum { map->lower_limit = org->lower_limit; \ map->data = M_CALL_REALLOC(key_oplist, M_C(name, _pair_t), NULL, map->mask+1); \ if (map->data == NULL) { \ - M_MEMORY_FULL(sizeof (M_C(name, _pair_t)) * (map->mask+1)); \ + M_MEMORY_FULL(sizeof (M_C(name, _pair_t)) * (map->mask+1)); \ return ; \ } \ for(size_t i = 0; i <= org->mask; i++) { \ @@ -1646,21 +1647,21 @@ typedef enum { } \ DICTI_OA_CONTRACT(map); \ } \ - \ + \ static inline void \ - M_C(name, _set)(dict_t map, const dict_t org) \ + M_C(name, _set)(dict_t map, const dict_t org) \ { \ DICTI_OA_CONTRACT(map); \ DICTI_OA_CONTRACT(org); \ if (M_LIKELY (map != org)) { \ - M_C(name, _clear)(map); \ - M_C(name, _init_set)(map, org); \ + M_C(name, _clear)(map); \ + M_C(name, _init_set)(map, org); \ } \ DICTI_OA_CONTRACT(map); \ } \ - \ + \ static inline void \ - M_C(name, _init_move)(dict_t map, dict_t org) \ + M_C(name, _init_move)(dict_t map, dict_t org) \ { \ DICTI_OA_CONTRACT(org); \ assert (map != org); \ @@ -1675,21 +1676,21 @@ typedef enum { org->data = NULL; \ DICTI_OA_CONTRACT(map); \ } \ - \ + \ static inline void \ - M_C(name, _move)(dict_t map, dict_t org) \ + M_C(name, _move)(dict_t map, dict_t org) \ { \ DICTI_OA_CONTRACT(map); \ DICTI_OA_CONTRACT(org); \ if (M_LIKELY (map != org)) { \ - M_C(name, _clear)(map); \ - M_C(name, _init_move)(map, org); \ + M_C(name, _clear)(map); \ + M_C(name, _init_move)(map, org); \ } \ DICTI_OA_CONTRACT(map); \ } \ - \ + \ static inline void \ - M_C(name, _swap)(dict_t d1, dict_t d2) \ + M_C(name, _swap)(dict_t d1, dict_t d2) \ { \ DICTI_OA_CONTRACT(d1); \ DICTI_OA_CONTRACT(d2); \ @@ -1698,13 +1699,13 @@ typedef enum { M_SWAP (size_t, d1->count_delete, d2->count_delete); \ M_SWAP (size_t, d1->upper_limit, d2->upper_limit); \ M_SWAP (size_t, d1->lower_limit, d2->lower_limit); \ - M_SWAP (M_C(name, _pair_t) *, d1->data, d2->data); \ + M_SWAP (M_C(name, _pair_t) *, d1->data, d2->data); \ DICTI_OA_CONTRACT(d1); \ DICTI_OA_CONTRACT(d2); \ } \ - \ + \ static inline void \ - M_C(name, _clean)(dict_t d) \ + M_C(name, _clean)(dict_t d) \ { \ DICTI_OA_CONTRACT(d); \ for(size_t i = 0; i <= d->mask; i++) { \ @@ -1717,18 +1718,18 @@ typedef enum { d->count = 0; \ d->count_delete = 0; \ d->mask = DICTI_INITIAL_SIZE-1; \ - M_C(name,_int_limit)(d, DICTI_INITIAL_SIZE); \ - d->data = M_CALL_REALLOC(key_oplist, M_C(name, _pair_t), \ + M_C(name,_int_limit)(d, DICTI_INITIAL_SIZE); \ + d->data = M_CALL_REALLOC(key_oplist, M_C(name, _pair_t), \ d->data, DICTI_INITIAL_SIZE); \ assert(d->data != NULL); \ for(size_t i = 0; i <= d->mask; i++) { \ M_CALL_OOR_SET(key_oplist, d->data[i].key, DICTI_OA_EMPTY); \ - } \ + } \ DICTI_OA_CONTRACT(d); \ } \ - \ + \ static inline void \ - M_C(name, _it)(dict_it_t it, const dict_t d) \ + M_C(name, _it)(dict_it_t it, const dict_t d) \ { \ DICTI_OA_CONTRACT(d); \ assert (it != NULL); \ @@ -1741,9 +1742,9 @@ typedef enum { } \ it->index = i; \ } \ - \ + \ static inline void \ - M_C(name, _it_set)(dict_it_t it, const dict_it_t ref) \ + M_C(name, _it_set)(dict_it_t it, const dict_it_t ref) \ { \ assert (it != NULL); \ assert (ref != NULL); \ @@ -1751,7 +1752,7 @@ typedef enum { it->index = ref->index; \ DICTI_OA_CONTRACT (it->dict); \ } \ - \ + \ static inline void \ M_C(name, _it_last)(dict_it_t it, const dict_t d) \ { \ @@ -1766,7 +1767,7 @@ typedef enum { } \ it->index = i; \ } \ - \ + \ static inline void \ M_C(name, _it_end)(dict_it_t it, const dict_t d) \ { \ @@ -1775,17 +1776,17 @@ typedef enum { it->dict = d; \ it->index = d->mask+1; \ } \ - \ + \ static inline bool \ - M_C(name, _end_p)(const dict_it_t it) \ + M_C(name, _end_p)(const dict_it_t it) \ { \ assert (it != NULL); \ DICTI_OA_CONTRACT (it->dict); \ return it->index > it->dict->mask; \ } \ - \ + \ static inline void \ - M_C(name, _next)(dict_it_t it) \ + M_C(name, _next)(dict_it_t it) \ { \ assert (it != NULL); \ DICTI_OA_CONTRACT (it->dict); \ @@ -1799,7 +1800,7 @@ typedef enum { } \ \ static inline void \ - M_C(name, _previous)(dict_it_t it) \ + M_C(name, _previous)(dict_it_t it) \ { \ assert (it != NULL); \ DICTI_OA_CONTRACT (it->dict); \ @@ -1812,26 +1813,26 @@ typedef enum { } \ it->index = i; \ } \ - \ + \ static inline bool \ - M_C(name, _last_p)(const dict_it_t it) \ + M_C(name, _last_p)(const dict_it_t it) \ { \ assert (it != NULL); \ dict_it_t it2; \ - M_C(name,_it_set)(it2, it); \ - M_C(name, _next)(it2); \ - return M_C(name, _end_p)(it2); \ + M_C(name,_it_set)(it2, it); \ + M_C(name, _next)(it2); \ + return M_C(name, _end_p)(it2); \ } \ - \ + \ static inline bool \ - M_C(name, _it_equal_p)(const dict_it_t it1,const dict_it_t it2) \ + M_C(name, _it_equal_p)(const dict_it_t it1,const dict_it_t it2) \ { \ assert (it1 != NULL && it2 != NULL); \ DICTI_OA_CONTRACT (it1->dict); \ DICTI_OA_CONTRACT (it2->dict); \ return it1->dict == it2->dict && it1->index == it2->index; \ } \ - \ + \ static inline M_C(name, _type_t) * \ M_C(name, _ref)(const dict_it_t it) \ { \ @@ -1843,39 +1844,41 @@ typedef enum { assert (!M_CALL_OOR_EQUAL(key_oplist, it->dict->data[i].key, DICTI_OA_DELETED)); \ return &it->dict->data[i] M_IF(isSet)(.key, ); \ } \ - \ + \ static inline const M_C(name, _type_t) * \ - M_C(name, _cref)(const dict_it_t it) \ + M_C(name, _cref)(const dict_it_t it) \ { \ return M_CONST_CAST(M_C(name, _type_t), M_C(name, _ref)(it)); \ } \ - \ - static inline void \ - M_C(name,_reserve)(dict_t dict, size_t capacity) \ - { \ - DICTI_OA_CONTRACT(dict); \ - size_t size; \ - /* Get the size which will allow to fit this capacity */ \ + \ + static inline void \ + M_C(name,_reserve)(dict_t dict, size_t capacity) \ + { \ + DICTI_OA_CONTRACT(dict); \ + size_t size; \ + /* Get the size which will allow to fit this capacity \ + NOTE: Stricly speaking we need to perform a round up to ensure \ + that no reallocation of the hash map occurs up to capacity */ \ size = (size_t) m_core_roundpow2 ((uint64_t) ((double) capacity * (1.0 / coeff_up))); \ /* Test for overflow of the computation */ \ - if (M_UNLIKELY (size < capacity)) { \ - M_MEMORY_FULL((size_t)-1); \ - } \ - assert (M_POWEROF2_P(size)); \ - if (size > dict->mask+1) { \ + if (M_UNLIKELY (size < capacity)) { \ + M_MEMORY_FULL((size_t)-1); \ + } \ + assert (M_POWEROF2_P(size)); \ + if (size > dict->mask+1) { \ dict->upper_limit = (size_t) ((double) size * coeff_up) - 1; \ - M_C(name,_int_resize_up)(dict, size, false); \ - } \ - DICTI_OA_CONTRACT(dict); \ - } \ - \ - M_IF_METHOD(EQUAL, value_oplist)( \ + M_C(name,_int_resize_up)(dict, size, false); \ + } \ + DICTI_OA_CONTRACT(dict); \ + } \ + \ + M_IF_METHOD(EQUAL, value_oplist)( \ static inline bool \ M_C(name, _equal_p)(const dict_t dict1, const dict_t dict2) \ - { \ - DICTI_OA_CONTRACT(dict1); \ + { \ + DICTI_OA_CONTRACT(dict1); \ DICTI_OA_CONTRACT(dict2); \ - /* NOTE: Key type has mandatory equal operator */ \ + /* NOTE: Key type has mandatory equal operator */ \ /* Easy case */ \ if (M_LIKELY (dict1->count != dict2->count)) \ return false; \ @@ -1894,8 +1897,8 @@ typedef enum { return false; \ } \ return true; \ - } \ - , /* no value equal */ ) \ + } \ + , /* no value equal */ ) \ \ DICTI_FUNC_ADDITIONAL_DEF2(name, key_type, key_oplist, value_type, value_oplist, isSet, dict_t, dict_it_t) diff --git a/m-funcobj.h b/m-funcobj.h index 1216bb80..bf8ee828 100644 --- a/m-funcobj.h +++ b/m-funcobj.h @@ -89,22 +89,22 @@ */ /* Specialization of the OPLIST in function if there is at least one member or not */ -#define FUNCOBJI_INS_NO_ATTR_OPLIST(name) \ +#define FUNCOBJI_INS_NO_ATTR_OPLIST(name) \ (NAME(name), TYPE(M_C(name, _t)), \ CLEAR(M_C(name, _clear)), \ INIT(M_C(name,_init)) \ ) /* Validate the oplist before going further */ -#define FUNCOBJI_INS_ATTR_OPLIST_P1(name, ...) \ +#define FUNCOBJI_INS_ATTR_OPLIST_P1(name, ...) \ M_IF(M_REDUCE(M_OPLIST_P, M_AND, __VA_ARGS__))(FUNCOBJI_INS_ATTR_OPLIST_P3, FUNCOBJI_INS_ATTR_OPLIST_FAILURE)(name, __VA_ARGS__) /* Prepare a clean compilation failure */ -#define FUNCOBJI_INS_ATTR_OPLIST_FAILURE(name, ...) \ +#define FUNCOBJI_INS_ATTR_OPLIST_FAILURE(name, ...) \ ((M_LIB_ERROR(ONE_ARGUMENT_OF_FUNC_OBJ_INS_OPLIST_IS_NOT_AN_OPLIST, name, __VA_ARGS__))) /* Define at least the oplist */ -#define FUNCOBJI_INS_ATTR_OPLIST_P3(name, ...) \ +#define FUNCOBJI_INS_ATTR_OPLIST_P3(name, ...) \ (NAME(name), TYPE(M_C(name, _t)), \ INIT_WITH(M_C(name, _init_with)), \ CLEAR(M_C(name, _clear)), \ @@ -216,21 +216,21 @@ FUNCOBJI_INS_ATTR_DEF_P2(name, base_name, param_list, callback_core, FUNCOBJI_INJECT_GLOBAL(__VA_ARGS__) ) /* Inject the oplist within the list of arguments */ -#define FUNCOBJI_INJECT_GLOBAL(...) \ +#define FUNCOBJI_INJECT_GLOBAL(...) \ M_MAP_C(FUNCOBJI_INJECT_OPLIST_A, __VA_ARGS__) /* Transform (x, type) into (x, type, oplist) if there is global registered oplist or (x, type, M_DEFAULT_OPLIST) if there is no global one, or keep (x, type, oplist) if oplist was already present */ -#define FUNCOBJI_INJECT_OPLIST_A( duo_or_trio ) \ +#define FUNCOBJI_INJECT_OPLIST_A( duo_or_trio ) \ FUNCOBJI_INJECT_OPLIST_B duo_or_trio -#define FUNCOBJI_INJECT_OPLIST_B( f, ... ) \ +#define FUNCOBJI_INJECT_OPLIST_B( f, ... ) \ M_IF_NARGS_EQ1(__VA_ARGS__)( (f, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)()), (f, __VA_ARGS__) ) // Test if all third argument of all arguments is an oplist -#define FUNCOBJI_IF_ALL_OPLIST(...) \ +#define FUNCOBJI_IF_ALL_OPLIST(...) \ M_IF(M_REDUCE(FUNCOBJI_IS_OPLIST_P, M_AND, __VA_ARGS__)) // Test if the third argument is an oplist -#define FUNCOBJI_IS_OPLIST_P(a) \ +#define FUNCOBJI_IS_OPLIST_P(a) \ M_OPLIST_P(M_RET_ARG3 a) /* Validate the oplist before going further */ @@ -297,24 +297,24 @@ /* Define a numbered type of a parameter of the callback*/ -#define FUNCOBJI_BASE_TYPE(name, num, type) \ +#define FUNCOBJI_BASE_TYPE(name, num, type) \ typedef type M_C4(name, _param_, num, _t); /* Define a list of the type of arguments for a function definition */ -#define FUNCOBJI_BASE_ARGLIST(name, num, type) \ +#define FUNCOBJI_BASE_ARGLIST(name, num, type) \ M_DEFERRED_COMMA type M_C(param_, num) /* Define a list of arguments for a function call */ -#define FUNCOBJI_BASE_ARGCALL(name, num, type) \ +#define FUNCOBJI_BASE_ARGCALL(name, num, type) \ M_DEFERRED_COMMA M_C(param_, num) /* Helper macros */ /* arg = (name, type [, oplist]) */ -#define FUNCOBJI_INS_ATTR_STRUCT(arg) \ +#define FUNCOBJI_INS_ATTR_STRUCT(arg) \ M_RET_ARG2 arg M_RET_ARG1 arg; -#define FUNCOBJI_INS_ATTR_LIST(arg) \ +#define FUNCOBJI_INS_ATTR_LIST(arg) \ M_DEFERRED_COMMA M_RET_ARG2 arg const M_RET_ARG1 arg #define FUNCOBJI_INS_ATTR_INIT(arg) \ @@ -327,12 +327,12 @@ M_CALL_CLEAR(M_RET_ARG3 arg, obj -> M_RET_ARG1 arg); /* Define the list of arguments of the instance of the callback */ -#define FUNCOBJI_INS_ARGLIST(name, num, param) \ +#define FUNCOBJI_INS_ARGLIST(name, num, param) \ M_DEFERRED_COMMA M_C4(name, _param_, num, _t) param /* Macros for testing for a method presence in all the attributes */ -#define FUNCOBJI_TEST_METHOD2_P(method, op) \ +#define FUNCOBJI_TEST_METHOD2_P(method, op) \ M_TEST_METHOD_P(method, op) #define FUNCOBJI_TEST_METHOD1_P(method, arg) \ M_APPLY(FUNCOBJI_TEST_METHOD2_P, method, M_RET_ARG3 arg) @@ -340,7 +340,7 @@ M_IF(M_REDUCE2(FUNCOBJI_TEST_METHOD1_P, M_AND, method, __VA_ARGS__)) /* Macro for checking compatible type and oplist for all the attributes */ -#define FUNCOBJI_CONTROL_ALL_OPLIST(name, ...) \ +#define FUNCOBJI_CONTROL_ALL_OPLIST(name, ...) \ M_MAP2(FUNCOBJI_CONTROL_OPLIST, name, __VA_ARGS__) #define FUNCOBJI_CONTROL_OPLIST(name, a) \ M_CHECK_COMPATIBLE_OPLIST(name, M_RET_ARG1 a, M_RET_ARG2 a, M_RET_ARG3 a) diff --git a/m-i-list.h b/m-i-list.h index 5c6c756d..b9691974 100644 --- a/m-i-list.h +++ b/m-i-list.h @@ -38,7 +38,7 @@ ... } tmp_str_t; */ -#define ILIST_INTERFACE(name, type) \ +#define ILIST_INTERFACE(name, type) \ struct ilist_head_s name /* Define a doubly-linked intrusive list of a given type. @@ -57,7 +57,7 @@ ILIST_OPLIST(name [, oplist_of_the_type]) */ #define ILIST_OPLIST(...) \ ILISTI_OPLIST_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ - ((__VA_ARGS__, M_DEFAULT_OPLIST), \ + ((__VA_ARGS__, M_DEFAULT_OPLIST), \ (__VA_ARGS__ ))) @@ -73,37 +73,37 @@ typedef struct ilist_head_s { #define ILISTI_OPLIST_P1(arg) ILISTI_OPLIST_P2 arg /* Validation of the given oplist */ -#define ILISTI_OPLIST_P2(name, oplist) \ +#define ILISTI_OPLIST_P2(name, oplist) \ M_IF_OPLIST(oplist)(ILISTI_OPLIST_P3, ILISTI_OPLIST_FAILURE)(name, oplist) /* Prepare a clean compilation failure */ -#define ILISTI_OPLIST_FAILURE(name, oplist) \ +#define ILISTI_OPLIST_FAILURE(name, oplist) \ ((M_LIB_ERROR(ARGUMENT_OF_ILIST_OPLIST_IS_NOT_AN_OPLIST, name, oplist))) /* Define the oplist of an ilist of type */ -#define ILISTI_OPLIST_P3(name, oplist) \ - (INIT(M_C(name, _init)), \ - CLEAR(M_C(name, _clear)), \ +#define ILISTI_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)), \ - TYPE(M_C(name,_t)), \ + TYPE(M_C(name,_t)), \ CLEAN(M_C(name,_clean)), \ - SUBTYPE(M_C(name,_type_t)), \ + SUBTYPE(M_C(name,_type_t)), \ TEST_EMPTY(M_C(name,_empty_p)), \ - IT_TYPE(M_C(name,_it_t)), \ - 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)),), \ + IT_TYPE(M_C(name,_it_t)), \ + 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)),), \ OPLIST(oplist), \ SPLICE_BACK(M_C(name,_splice_back)) \ ,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW oplist),) \ @@ -111,7 +111,7 @@ typedef struct ilist_head_s { ) /* Contract respected by all intrusive lists */ -#define ILISTI_CONTRACT(name, list) do { \ +#define ILISTI_CONTRACT(name, list) do { \ assert(list != NULL); \ assert(list->name.prev != NULL); \ assert(list->name.next != NULL); \ @@ -131,11 +131,11 @@ typedef struct ilist_head_s { #define ILISTI_DEF_P1(arg) ILISTI_DEF_P2 arg /* Validate the oplist before going further */ -#define ILISTI_DEF_P2(name, type, oplist, list_t, it_t) \ +#define ILISTI_DEF_P2(name, type, oplist, list_t, it_t) \ M_IF_OPLIST(oplist)(ILISTI_DEF_P3, ILISTI_DEF_FAILURE)(name, type, oplist, list_t, it_t) /* Stop processing with a compilation failure */ -#define ILISTI_DEF_FAILURE(name, type, oplist, list_t, it_t) \ +#define ILISTI_DEF_FAILURE(name, type, oplist, list_t, it_t) \ M_STATIC_FAILURE(M_LIB_NOT_AN_OPLIST, "(ILIST_DEF): the given argument is not a valid oplist: " #oplist) /* Definition of the type and function for an intrusive doubly-linked list. @@ -147,65 +147,65 @@ typedef struct ilist_head_s { it_t: iterator of the intrusive list (name##_it_t) */ #define ILISTI_DEF_P3(name, type, oplist, list_t, it_t) \ - \ - typedef struct M_C(name, _s) { \ + \ + typedef struct M_C(name, _s) { \ struct ilist_head_s name; \ } list_t[1]; \ typedef struct M_C(name, _s) *M_C(name, _ptr); \ typedef const struct M_C(name, _s) *M_C(name, _srcptr); \ \ - typedef type M_C(name, _type_t); \ + typedef type M_C(name, _type_t); \ \ - typedef struct M_C(name, _it_s) { \ + typedef struct M_C(name, _it_s) { \ struct ilist_head_s *head; \ struct ilist_head_s *previous; \ struct ilist_head_s *current; \ struct ilist_head_s *next; \ } it_t[1]; \ - \ + \ M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \ \ - static inline void M_C(name, _init)(list_t list) \ + static inline void M_C(name, _init)(list_t list) \ { \ assert (list != NULL); \ list->name.next = &list->name; \ list->name.prev = &list->name; \ - ILISTI_CONTRACT(name, list); \ + ILISTI_CONTRACT(name, list); \ } \ \ - static inline void M_C(name, _clean)(list_t list) \ + static inline void M_C(name, _clean)(list_t list) \ { \ - ILISTI_CONTRACT(name, list); \ - for(struct ilist_head_s *it = list->name.next, *next ; \ - it != &list->name; it = next) { \ + ILISTI_CONTRACT(name, list); \ + for(struct ilist_head_s *it = list->name.next, *next ; \ + it != &list->name; it = next) { \ /* Cannot check node contract as previous node may be deleted */ \ - type *obj = M_TYPE_FROM_FIELD(type, it, \ - struct ilist_head_s, name); \ - /* Read next now before the object is destroyed */ \ - next = it->next; \ - assert (next != NULL); \ - M_CALL_CLEAR(oplist, *obj); \ + type *obj = M_TYPE_FROM_FIELD(type, it, \ + struct ilist_head_s, name); \ + /* Read next now before the object is destroyed */ \ + next = it->next; \ + assert (next != NULL); \ + M_CALL_CLEAR(oplist, *obj); \ /* Delete also the object if a DELETE operand is registered */ \ - M_IF_METHOD(DEL, oplist)(M_CALL_DEL(oplist, obj), (void) 0); \ - } \ + M_IF_METHOD(DEL, oplist)(M_CALL_DEL(oplist, obj), (void) 0); \ + } \ /* Nothing remains in the list anymore */ \ list->name.next = &list->name; \ list->name.prev = &list->name; \ - ILISTI_CONTRACT(name, list); \ + ILISTI_CONTRACT(name, list); \ } \ \ - static inline void M_C(name, _clear)(list_t list) \ + static inline void M_C(name, _clear)(list_t list) \ { \ - M_C(name, _clean)(list); \ + M_C(name, _clean)(list); \ } \ \ - static inline bool M_C(name, _empty_p)(const list_t list) \ + static inline bool M_C(name, _empty_p)(const list_t list) \ { \ - ILISTI_CONTRACT(name, list); \ + ILISTI_CONTRACT(name, list); \ return list->name.next == &list->name; \ } \ \ - \ + \ static inline void M_C(name, _init_move)(list_t list, list_t ref) \ { \ ILISTI_CONTRACT(name, ref); \ @@ -219,18 +219,18 @@ typedef struct ilist_head_s { } \ ref->name.next = NULL; \ ref->name.prev = NULL; \ - ILISTI_CONTRACT(name, list); \ + ILISTI_CONTRACT(name, list); \ } \ - \ + \ static inline void M_C(name, _move)(list_t list, list_t ref) \ { \ M_C(name, _clear)(list); \ M_C(name, _init_move)(list, ref); \ } \ \ - static inline size_t M_C(name, _size)(const list_t list) \ + static inline size_t M_C(name, _size)(const list_t list) \ { \ - ILISTI_CONTRACT(name, list); \ + ILISTI_CONTRACT(name, list); \ size_t s = 0; \ for(const struct ilist_head_s *it = list->name.next ; \ it != &list->name; it = it->next) { \ @@ -240,28 +240,28 @@ typedef struct ilist_head_s { return s; \ } \ \ - static inline void M_C(name, _push_back)(list_t list, type *obj) \ + static inline void M_C(name, _push_back)(list_t list, type *obj) \ { \ - ILISTI_CONTRACT(name, list); \ - assert (obj != NULL); \ + ILISTI_CONTRACT(name, list); \ + assert (obj != NULL); \ struct ilist_head_s *prev = list->name.prev; \ list->name.prev = &obj->name; \ obj->name.prev = prev; \ obj->name.next = &list->name; \ prev->next = &obj->name; \ - ILISTI_CONTRACT(name, list); \ + ILISTI_CONTRACT(name, list); \ } \ \ - static inline void M_C(name, _push_front)(list_t list, type *obj) \ + static inline void M_C(name, _push_front)(list_t list, type *obj) \ { \ - ILISTI_CONTRACT(name, list); \ - assert (obj != NULL); \ + ILISTI_CONTRACT(name, list); \ + assert (obj != NULL); \ struct ilist_head_s *next = list->name.next; \ list->name.next = &obj->name; \ obj->name.next = next; \ obj->name.prev = &list->name; \ next->prev = &obj->name; \ - ILISTI_CONTRACT(name, list); \ + ILISTI_CONTRACT(name, list); \ } \ \ static inline void M_C(name, _push_after)(type *obj_pos, type *obj) \ @@ -274,14 +274,14 @@ typedef struct ilist_head_s { next->prev = &obj->name; \ } \ \ - static inline void M_C(name, _init_field)(type *obj) \ + static inline void M_C(name, _init_field)(type *obj) \ { \ assert (obj != NULL); \ obj->name.next = NULL; \ obj->name.prev = NULL; \ } \ \ - static inline void M_C(name, _unlink)(type *obj) \ + static inline void M_C(name, _unlink)(type *obj) \ { \ assert (obj != NULL); \ struct ilist_head_s *next = obj->name.next; \ @@ -294,50 +294,50 @@ typedef struct ilist_head_s { } \ \ static inline type * \ - M_C(name, _back)(const list_t list) \ + M_C(name, _back)(const list_t list) \ { \ - ILISTI_CONTRACT(name, list); \ - assert(!M_C(name, _empty_p)(list)); \ + ILISTI_CONTRACT(name, list); \ + assert(!M_C(name, _empty_p)(list)); \ return M_TYPE_FROM_FIELD(type, list->name.prev, \ struct ilist_head_s, name); \ } \ - \ + \ static inline type * \ - M_C(name, _front)(const list_t list) \ + M_C(name, _front)(const list_t list) \ { \ - ILISTI_CONTRACT(name, list); \ - assert(!M_C(name, _empty_p)(list)); \ + ILISTI_CONTRACT(name, list); \ + assert(!M_C(name, _empty_p)(list)); \ return M_TYPE_FROM_FIELD(type, list->name.next, \ struct ilist_head_s, name); \ } \ \ - static inline type * \ - M_C(name, _next_obj)(const list_t list, type const *obj) \ - { \ - ILISTI_CONTRACT(name, list); \ - assert (obj != NULL); \ + static inline type * \ + M_C(name, _next_obj)(const list_t list, type const *obj) \ + { \ + ILISTI_CONTRACT(name, list); \ + assert (obj != NULL); \ ILISTI_NODE_CONTRACT(&obj->name); \ - return obj->name.next == &list->name ? NULL : \ - M_TYPE_FROM_FIELD(type, obj->name.next, \ - struct ilist_head_s, name); \ - } \ - \ - static inline type * \ - M_C(name, _previous_obj)(const list_t list, type const *obj) \ - { \ - ILISTI_CONTRACT(name, list); \ - assert (obj != NULL); \ + return obj->name.next == &list->name ? NULL : \ + M_TYPE_FROM_FIELD(type, obj->name.next, \ + struct ilist_head_s, name); \ + } \ + \ + static inline type * \ + M_C(name, _previous_obj)(const list_t list, type const *obj) \ + { \ + ILISTI_CONTRACT(name, list); \ + assert (obj != NULL); \ ILISTI_NODE_CONTRACT(&obj->name); \ - return obj->name.prev == &list->name ? NULL : \ - M_TYPE_FROM_FIELD(type, obj->name.prev, \ - struct ilist_head_s, name); \ - } \ - \ + return obj->name.prev == &list->name ? NULL : \ + M_TYPE_FROM_FIELD(type, obj->name.prev, \ + struct ilist_head_s, name); \ + } \ + \ static inline void \ M_C(name, _it)(it_t it, const list_t list) \ { \ - ILISTI_CONTRACT(name, list); \ - assert (it != NULL); \ + ILISTI_CONTRACT(name, list); \ + assert (it != NULL); \ it->head = list->name.next->prev; \ it->current = list->name.next; \ it->next = list->name.next->next; \ @@ -355,19 +355,19 @@ typedef struct ilist_head_s { it->previous = cit->previous; \ ILISTI_NODE_CONTRACT(it->current); \ } \ - \ + \ static inline void \ - M_C(name, _it_last)(it_t it, list_t const list) \ + M_C(name, _it_last)(it_t it, list_t const list) \ { \ - ILISTI_CONTRACT(name, list); \ - assert (it != NULL); \ + ILISTI_CONTRACT(name, list); \ + assert (it != NULL); \ it->head = list->name.next->prev; \ it->current = list->name.prev; \ it->next = it->head; \ it->previous = list->name.prev->prev; \ ILISTI_NODE_CONTRACT(it->current); \ } \ - \ + \ static inline void \ M_C(name, _it_end)(it_t it, list_t const list) \ { \ @@ -378,23 +378,23 @@ typedef struct ilist_head_s { it->previous = list->name.prev; \ ILISTI_NODE_CONTRACT(it->current); \ } \ - \ + \ static inline bool \ - M_C(name, _end_p)(const it_t it) \ + M_C(name, _end_p)(const it_t it) \ { \ assert (it != NULL); \ ILISTI_NODE_CONTRACT(it->current); \ return it->current == it->head; \ } \ - \ + \ static inline bool \ M_C(name, _last_p)(const it_t it) \ { \ assert (it != NULL); \ ILISTI_NODE_CONTRACT(it->current); \ - return it->next == it->head || it->current == it->head; \ + return it->next == it->head || it->current == it->head; \ } \ - \ + \ static inline void \ M_C(name, _next)(it_t it) \ { \ @@ -424,7 +424,7 @@ typedef struct ilist_head_s { assert (it->next != NULL && it->previous != NULL); \ ILISTI_NODE_CONTRACT(it->current); \ } \ - \ + \ static inline bool \ M_C(name, _it_equal_p)(const it_t it1, const it_t it2 ) \ { \ @@ -432,130 +432,130 @@ typedef struct ilist_head_s { /* No need to check for next & previous */ \ return it1->head == it2->head && it1->current == it2->current; \ } \ - \ + \ static inline type * \ - M_C(name, _ref)(const it_t it) \ + M_C(name, _ref)(const it_t it) \ { \ assert (it != NULL && it->current != NULL); \ ILISTI_NODE_CONTRACT(it->current); \ /* check if 'it' was not deleted */ \ assert (it->current->next == it->next); \ assert (it->current->prev == it->previous); \ - assert (!M_C(name, _end_p)(it)); \ + assert (!M_C(name, _end_p)(it)); \ return M_TYPE_FROM_FIELD(type, it->current, \ - struct ilist_head_s, name); \ + struct ilist_head_s, name); \ } \ - \ + \ static inline type const * \ - M_C(name, _cref)(const it_t it) \ + M_C(name, _cref)(const it_t it) \ { \ - type *ptr = M_C(name, _ref)(it); \ + type *ptr = M_C(name, _ref)(it); \ return M_CONST_CAST(type, ptr); \ } \ - \ - static inline void \ - M_C(name, _remove)(list_t list, it_t it) \ + \ + static inline void \ + M_C(name, _remove)(list_t list, it_t it) \ { \ - ILISTI_CONTRACT(name, list); \ + ILISTI_CONTRACT(name, list); \ ILISTI_NODE_CONTRACT(it->current); \ - (void)list; /* list param is not used */ \ - type *obj = M_TYPE_FROM_FIELD(type, it->current, \ - struct ilist_head_s, name); \ - M_C(name, _unlink)(obj); \ - M_CALL_CLEAR(oplist, obj); \ + (void)list; /* list param is not used */ \ + type *obj = M_TYPE_FROM_FIELD(type, it->current, \ + struct ilist_head_s, name); \ + M_C(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_IF_METHOD(NEW, oplist)( \ - static inline void \ - M_C(name, _insert)(list_t list, it_t it, type x) \ + M_C(name, _next)(it); \ + } \ + \ + M_IF_METHOD(NEW, oplist)( \ + static inline void \ + M_C(name, _insert)(list_t list, it_t it, type x) \ { \ - ILISTI_CONTRACT(name, list); \ + ILISTI_CONTRACT(name, list); \ ILISTI_NODE_CONTRACT(it->current); \ type *p = M_CALL_NEW(oplist, type); \ - if (M_UNLIKELY (p == NULL)) { \ - M_MEMORY_FULL (sizeof (type)); \ - return ; \ - } \ - M_CALL_INIT_SET(oplist, *p, x); \ - type *obj = M_C(name, _ref)(it); \ - M_C(name, _push_after)(obj, p); \ - it->current = p; \ - (void) list; \ - ILISTI_CONTRACT(name, list); \ - } \ - , /* NEW not defined */) \ - \ + if (M_UNLIKELY (p == NULL)) { \ + M_MEMORY_FULL (sizeof (type)); \ + return ; \ + } \ + M_CALL_INIT_SET(oplist, *p, x); \ + type *obj = M_C(name, _ref)(it); \ + M_C(name, _push_after)(obj, p); \ + it->current = p; \ + (void) list; \ + ILISTI_CONTRACT(name, list); \ + } \ + , /* NEW not defined */) \ + \ static inline type * \ - M_C(name, _pop_back)(list_t list) \ + M_C(name, _pop_back)(list_t list) \ { \ - ILISTI_CONTRACT(name, list); \ - assert (!M_C(name, _empty_p)(list)); \ - type *obj = M_C(name, _back)(list); \ + ILISTI_CONTRACT(name, list); \ + assert (!M_C(name, _empty_p)(list)); \ + type *obj = M_C(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_C(name, _pop_front)(list_t list) \ { \ - ILISTI_CONTRACT(name, list); \ - assert (!M_C(name, _empty_p)(list)); \ - type *obj = M_C(name, _front)(list); \ + ILISTI_CONTRACT(name, list); \ + assert (!M_C(name, _empty_p)(list)); \ + type *obj = M_C(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_C(name, _splice)(list_t list1, list_t list2) \ { \ - ILISTI_CONTRACT(name, list1); \ - ILISTI_CONTRACT(name, list2); \ - struct ilist_head_s *midle1 = list1->name.prev; \ - struct ilist_head_s *midle2 = list2->name.next; \ - midle1->next = midle2; \ - midle2->prev = midle1; \ - list1->name.prev = list2->name.prev; \ - list2->name.prev->next = &list1->name; \ - list2->name.next = &list2->name; \ - list2->name.prev = &list2->name; \ - ILISTI_CONTRACT(name, list1); \ - ILISTI_CONTRACT(name, list2); \ - } \ - \ + ILISTI_CONTRACT(name, list1); \ + ILISTI_CONTRACT(name, list2); \ + struct ilist_head_s *midle1 = list1->name.prev; \ + struct ilist_head_s *midle2 = list2->name.next; \ + midle1->next = midle2; \ + midle2->prev = midle1; \ + list1->name.prev = list2->name.prev; \ + list2->name.prev->next = &list1->name; \ + list2->name.next = &list2->name; \ + list2->name.prev = &list2->name; \ + ILISTI_CONTRACT(name, list1); \ + ILISTI_CONTRACT(name, list2); \ + } \ + \ static inline void \ - M_C(name, _splice_back)(list_t nv, list_t ov, it_t it) \ + M_C(name, _splice_back)(list_t nv, list_t ov, it_t it) \ { \ - ILISTI_CONTRACT(name, nv); \ - ILISTI_CONTRACT(name, ov); \ + ILISTI_CONTRACT(name, nv); \ + ILISTI_CONTRACT(name, ov); \ ILISTI_NODE_CONTRACT(it->current); \ - assert (it != NULL); \ - (void) ov; \ - type *obj = M_C(name, _ref)(it); \ - M_C(name, _unlink)(obj); \ - M_C(name, _push_back)(nv, obj); \ + 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); \ - ILISTI_CONTRACT(name, nv); \ - ILISTI_CONTRACT(name, ov); \ - } \ - \ - static inline void \ + ILISTI_CONTRACT(name, nv); \ + ILISTI_CONTRACT(name, ov); \ + } \ + \ + static inline void \ M_C(name, _splice_at)(list_t nlist, it_t npos, \ list_t olist, it_t opos) \ { \ - ILISTI_CONTRACT(name, nlist); \ - ILISTI_CONTRACT(name, olist); \ + ILISTI_CONTRACT(name, nlist); \ + ILISTI_CONTRACT(name, olist); \ assert (npos != NULL && opos != NULL); \ - assert (!M_C(name, _end_p)(opos)); \ + assert (!M_C(name, _end_p)(opos)); \ /* npos may be end */ \ (void) olist, (void) nlist; \ - type *obj = M_C(name, _ref)(opos); \ + type *obj = M_C(name, _ref)(opos); \ struct ilist_head_s *ref = npos->current; \ /* Remove object */ \ - M_C(name, _unlink)(obj); \ + M_C(name, _unlink)(obj); \ /* Push 'obj' after 'ref' */ \ struct ilist_head_s *next = ref->next; \ ref->next = &obj->name; \ @@ -568,15 +568,15 @@ typedef struct ilist_head_s { npos->previous = ref; \ npos->current = &obj->name; \ npos->next = next; \ - ILISTI_CONTRACT(name, nlist); \ - ILISTI_CONTRACT(name, olist); \ - } \ - \ - static inline void \ - M_C(name, _swap)(list_t d, list_t e) \ - { \ - ILISTI_CONTRACT(name, d); \ - ILISTI_CONTRACT(name, e); \ + ILISTI_CONTRACT(name, nlist); \ + ILISTI_CONTRACT(name, olist); \ + } \ + \ + static inline void \ + M_C(name, _swap)(list_t d, list_t e) \ + { \ + ILISTI_CONTRACT(name, d); \ + ILISTI_CONTRACT(name, e); \ struct ilist_head_s *d_item = d->name.next; \ struct ilist_head_s *e_item = e->name.next; \ d->name.next = e_item == &e->name ? &d->name : e_item; \ @@ -589,13 +589,13 @@ typedef struct ilist_head_s { d->name.prev->next = &d->name; \ e->name.next->prev = &e->name; \ e->name.prev->next = &e->name; \ - ILISTI_CONTRACT(name, d); \ - ILISTI_CONTRACT(name, e); \ - } \ - \ - static inline void \ + ILISTI_CONTRACT(name, d); \ + ILISTI_CONTRACT(name, e); \ + } \ + \ + static inline void \ M_C(name, _reverse)(list_t list) \ - { \ + { \ ILISTI_CONTRACT(name, list); \ struct ilist_head_s *next, *it; \ for(it = list->name.next ; it != &list->name; it = next) { \ @@ -607,7 +607,7 @@ typedef struct ilist_head_s { it->next = it->prev; \ it->prev = next; \ ILISTI_CONTRACT(name, list); \ - } \ + } \ \ LISTI_ITBASE_DEF(name, type, oplist, list_t, it_t) diff --git a/m-i-shared.h b/m-i-shared.h index baedca09..98de07a5 100644 --- a/m-i-shared.h +++ b/m-i-shared.h @@ -42,7 +42,7 @@ M_BEGIN_PROTECTED_CODE name: name of the intrusive shared pointer. 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 ISHARED_PTR_INTERFACE(name, type) \ +#define ISHARED_PTR_INTERFACE(name, type) \ atomic_int M_C(name, _cpt) @@ -52,7 +52,7 @@ M_BEGIN_PROTECTED_CODE M_BEGIN_PROTECTED_CODE \ ISHAREDI_PTR_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ ((name, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)() ), \ - (name, __VA_ARGS__ ))) \ + (name, __VA_ARGS__ ))) \ M_END_PROTECTED_CODE @@ -62,23 +62,23 @@ M_BEGIN_PROTECTED_CODE #define ISHAREDI_PTR_OPLIST_P1(arg) ISHAREDI_PTR_OPLIST_P2 arg /* Validation of the given oplist */ -#define ISHAREDI_PTR_OPLIST_P2(name, oplist) \ +#define ISHAREDI_PTR_OPLIST_P2(name, oplist) \ M_IF_OPLIST(oplist)(ISHAREDI_PTR_OPLIST_P3, ISHAREDI_PTR_OPLIST_FAILURE)(name, oplist) /* Prepare a clean compilation failure */ -#define ISHAREDI_PTR_OPLIST_FAILURE(name, oplist) \ +#define ISHAREDI_PTR_OPLIST_FAILURE(name, oplist) \ ((M_LIB_ERROR(ARGUMENT_OF_ISHARED_PTR_OPLIST_IS_NOT_AN_OPLIST, name, oplist))) // Define the oplist #define ISHAREDI_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)), \ - CLEAN(M_C(name, _clean) M_IPTR), \ + INIT_SET(API_4(M_C(name, _init_set))), \ + SET(M_C(name, _set) M_IPTR), \ + CLEAR(M_C(name, _clear)), \ + CLEAN(M_C(name, _clean) M_IPTR), \ TYPE(M_C(name, _t)), \ OPLIST(oplist), \ - SUBTYPE(M_C(name, _type_t)) \ + SUBTYPE(M_C(name, _type_t)) \ ,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),) \ @@ -92,47 +92,47 @@ M_BEGIN_PROTECTED_CODE M_IF_OPLIST(oplist)(ISHAREDI_PTR_DEF_P3, ISHAREDI_PTR_DEF_FAILURE)(name, type, oplist) /* Stop processing with a compilation failure */ -#define ISHAREDI_PTR_DEF_FAILURE(name, type, oplist) \ +#define ISHAREDI_PTR_DEF_FAILURE(name, type, oplist) \ M_STATIC_FAILURE(M_LIB_NOT_AN_OPLIST, "(ISHARED_PTR_DEF): the given argument is not a valid oplist: " #oplist) #define ISHAREDI_PTR_DEF_P3(name, type, oplist) \ \ - typedef type *M_C(name,_t); \ - typedef type M_C(name, _type_t); \ + typedef type *M_C(name,_t); \ + typedef type M_C(name, _type_t); \ \ M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \ \ static inline M_C(name,_t) \ - M_C(name, _init)(type *ptr) \ - { \ + M_C(name, _init)(type *ptr) \ + { \ if (M_LIKELY (ptr != NULL)) \ atomic_init(&ptr->M_C(name, _cpt), 1); \ return ptr; \ - } \ - \ + } \ + \ static inline M_C(name,_t) \ - M_C(name, _init_set)(M_C(name,_t) shared) \ - { \ - if (M_LIKELY (shared != NULL)) { \ - int n = atomic_fetch_add(&(shared->M_C(name, _cpt)), 1); \ - (void) n; \ - } \ + M_C(name, _init_set)(M_C(name,_t) shared) \ + { \ + if (M_LIKELY (shared != NULL)) { \ + int n = atomic_fetch_add(&(shared->M_C(name, _cpt)), 1); \ + (void) n; \ + } \ return shared; \ - } \ - \ + } \ + \ static inline void M_ATTR_DEPRECATED \ M_C(name, _init_set2)(M_C(name,_t) *ptr, M_C(name,_t) shared) \ - { \ + { \ assert (ptr != NULL); \ - *ptr = M_C(name, _init_set)(shared); \ - } \ - \ + *ptr = M_C(name, _init_set)(shared); \ + } \ + \ M_IF_DISABLED_METHOD(NEW, oplist) \ ( /* Nothing to do */, M_IF_METHOD(INIT, oplist) \ ( \ static inline M_C(name,_t) \ M_C(name, _init_new)(void) \ - { \ + { \ type *ptr = M_CALL_NEW(oplist, type); \ if (ptr == NULL) { \ M_MEMORY_FULL(sizeof(type)); \ @@ -141,45 +141,45 @@ M_BEGIN_PROTECTED_CODE M_CALL_INIT(oplist, *ptr); \ atomic_init (&ptr->M_C(name, _cpt), 1); \ return ptr; \ - } \ + } \ , /* End of INIT */) \ /* End of NEW */) \ - \ - static inline void \ + \ + static inline void \ M_C(name, _clear)(M_C(name,_t) shared) \ - { \ - if (shared != NULL) { \ - if (atomic_fetch_sub(&(shared->M_C(name, _cpt)), 1) == 1) { \ + { \ + if (shared != NULL) { \ + if (atomic_fetch_sub(&(shared->M_C(name, _cpt)), 1) == 1) { \ M_CALL_CLEAR(oplist, *shared); \ M_IF_DISABLED_METHOD(DEL, oplist)(, M_CALL_DEL(oplist, shared);) \ - } \ + } \ } \ - } \ - \ - static inline void \ + } \ + \ + static inline void \ M_C(name, _clear_ptr)(M_C(name,_t) *shared) \ - { \ + { \ assert(shared != NULL); \ M_C(name, _clear)(*shared); \ *shared = NULL; \ - } \ - \ - static inline void \ + } \ + \ + static inline void \ M_C(name, _clean)(M_C(name,_t) *shared) \ - { \ - M_C(name, _clear)(*shared); \ + { \ + M_C(name, _clear)(*shared); \ *shared = NULL; \ } \ \ - static inline void \ + static inline void \ M_C(name, _set)(M_C(name,_t) *ptr, M_C(name,_t)shared) \ - { \ + { \ assert (ptr != NULL); \ if (M_LIKELY (*ptr != shared)) { \ - M_C(name, _clear)(*ptr); \ - *ptr = M_C(name, _init_set)(shared); \ + M_C(name, _clear)(*ptr); \ + *ptr = M_C(name, _init_set)(shared); \ } \ - } \ + } \ \ M_END_PROTECTED_CODE diff --git a/m-rbtree.h b/m-rbtree.h index eb0351da..9b25ea6e 100644 --- a/m-rbtree.h +++ b/m-rbtree.h @@ -1118,7 +1118,7 @@ typedef enum { size_t estimated_size = 0; \ type key; \ M_C(name,_clean)(t1); \ - ret = f->m_interface->read_array_start(local, f, &estimated_size); \ + ret = f->m_interface->read_array_start(local, f, &estimated_size); \ if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) return ret; \ M_CALL_INIT(oplist, key); \ do { \ diff --git a/m-string.h b/m-string.h index ebaa89ca..eaf809c0 100644 --- a/m-string.h +++ b/m-string.h @@ -578,7 +578,7 @@ string_search_char (const string_t v, char c, size_t start) STRINGI_CONTRACT (v); assert (start <= string_size(v)); const char *p = M_ASSIGN_CAST(const char*, - strchr(string_get_cstr(v)+start, c)); + strchr(string_get_cstr(v)+start, c)); return p == NULL ? STRING_FAILURE : (size_t) (p-string_get_cstr(v)); } @@ -596,7 +596,7 @@ string_search_rchar (const string_t v, char c, size_t start) // by scanning backward from the bottom of the string (which is // possible since we know the size) const char *p = M_ASSIGN_CAST(const char*, - strrchr(string_get_cstr(v)+start, c)); + strrchr(string_get_cstr(v)+start, c)); return p == NULL ? STRING_FAILURE : (size_t) (p-string_get_cstr(v)); } @@ -610,7 +610,7 @@ string_search_str (const string_t v, const char str[], size_t start) assert (start <= string_size(v)); M_ASSUME (str != NULL); const char *p = M_ASSIGN_CAST(const char*, - strstr(string_get_cstr(v)+start, str)); + strstr(string_get_cstr(v)+start, str)); return p == NULL ? STRING_FAILURE : (size_t) (p-string_get_cstr(v)); } @@ -636,7 +636,7 @@ string_search_pbrk(const string_t v1, const char first_of[], size_t start) assert (start <= string_size(v1)); M_ASSUME (first_of != NULL); const char *p = M_ASSIGN_CAST(const char*, - strpbrk(string_get_cstr(v1)+start, first_of)); + strpbrk(string_get_cstr(v1)+start, first_of)); return p == NULL ? STRING_FAILURE : (size_t) (p-string_get_cstr(v1)); } @@ -1652,14 +1652,14 @@ namespace m_string { EXT_ALGO(STRING_SPLIT), \ OOR_EQUAL(string_oor_equal_p), OOR_SET(string_oor_set) \ ,SUBTYPE(string_unicode_t) \ - ,IT_TYPE(string_it_t) \ + ,IT_TYPE(string_it_t) \ ,IT_FIRST(string_it) \ ,IT_END(string_it_end) \ - ,IT_SET(string_it_set) \ - ,IT_END_P(string_end_p) \ - ,IT_EQUAL_P(string_it_equal_p) \ - ,IT_NEXT(string_next) \ - ,IT_CREF(string_cref) \ + ,IT_SET(string_it_set) \ + ,IT_END_P(string_end_p) \ + ,IT_EQUAL_P(string_it_equal_p) \ + ,IT_NEXT(string_next) \ + ,IT_CREF(string_cref) \ ) /* Register the OPLIST as a global one */ @@ -1669,31 +1669,31 @@ namespace m_string { /* Macro encapsulation to give a default value of 0 for start offset */ /* Search for a character in a string (string, character[, start=0]) */ -#define string_search_char(v, ...) \ +#define string_search_char(v, ...) \ M_APPLY(string_search_char, v, M_IF_DEFAULT1(0, __VA_ARGS__)) /* Reverse Search for a character in a string (string, character[, start=0]) */ -#define string_search_rchar(v, ...) \ +#define string_search_rchar(v, ...) \ M_APPLY(string_search_rchar, v, M_IF_DEFAULT1(0, __VA_ARGS__)) /* Search for a C string in a string (string, c_string[, start=0]) */ -#define string_search_str(v, ...) \ +#define string_search_str(v, ...) \ M_APPLY(string_search_str, v, M_IF_DEFAULT1(0, __VA_ARGS__)) /* Search for a string in a string (string, string[, start=0]) */ -#define string_search(v, ...) \ +#define string_search(v, ...) \ M_APPLY(string_search, v, M_IF_DEFAULT1(0, __VA_ARGS__)) /* PBRK for a string in a string (string, string[, start=0]) */ -#define string_search_pbrk(v, ...) \ +#define string_search_pbrk(v, ...) \ M_APPLY(string_search_pbrk, v, M_IF_DEFAULT1(0, __VA_ARGS__)) /* Replace a C string to another C string in a string (string, c_src_string, c_dst_string, [, start=0]) */ -#define string_replace_str(v, s1, ...) \ +#define string_replace_str(v, s1, ...) \ M_APPLY(string_replace_str, v, s1, M_IF_DEFAULT1(0, __VA_ARGS__)) /* Replace a string to another string in a string (string, src_string, dst_string, [, start=0]) */ -#define string_replace(v, s1, ...) \ +#define string_replace(v, s1, ...) \ M_APPLY(string_replace, v, s1, M_IF_DEFAULT1(0, __VA_ARGS__)) /* Strim a string from the given set of characters (default is " \n\r\t") */ @@ -1706,17 +1706,17 @@ namespace m_string { /* Select either the string function or the str function depending on the b operade to the function. func1 is the string function / func2 is the str function. */ -# define STRINGI_SELECT2(func1,func2,a,b) \ - _Generic((b)+0, \ - char*: func2, \ - const char *: func2, \ - default : func1 \ +# define STRINGI_SELECT2(func1,func2,a,b) \ + _Generic((b)+0, \ + char*: func2, \ + const char *: func2, \ + default : func1 \ )(a,b) -# define STRINGI_SELECT3(func1,func2,a,b,c) \ - _Generic((b)+0, \ - char*: func2, \ - const char *: func2, \ - default : func1 \ +# define STRINGI_SELECT3(func1,func2,a,b,c) \ + _Generic((b)+0, \ + char*: func2, \ + const char *: func2, \ + default : func1 \ )(a,b,c) /* Init & Set the string a to the string (or C string) b (constructor) */ @@ -1739,9 +1739,9 @@ namespace m_string { #undef string_search /* Search for a string in a string (or C string) (string, string[, start=0]) */ -#define string_search(v, ...) \ - M_APPLY(STRINGI_SELECT3, string_search, string_search_str, \ - v, M_IF_DEFAULT1(0, __VA_ARGS__)) +#define string_search(v, ...) \ + M_APPLY(STRINGI_SELECT3, string_search, string_search_str, \ + v, M_IF_DEFAULT1(0, __VA_ARGS__)) /* Internal Macro: Provide GET_STR method to default type */ #undef M_GET_STR_METHOD_FOR_DEFAULT_TYPE @@ -2131,7 +2131,7 @@ namespace m_string { } }; } -#define BOUNDED_STRING_CTE(name, string) \ +#define BOUNDED_STRING_CTE(name, string) \ ((const struct M_C(name, _s) *)(m_string::m_bounded_string(string).s)) #endif