Make M*LIB stricter for INIT_MOVE operator:

* either the default INIT_MOVE operator works ('=')
* either an INIT_MOVE method is defined
* or it is disabled.
As a consequence, fix usage of testobj_t and mpz_t in the repository

The emulation layer of INIT_MOVE using INIT_SET+CLEAR is removed:
it wasn't working correctly with the local memory context
(INIT_MOVE doesn't need any local memory context to work,
 whereas INIT_SET/CLEAR does)
Remove macro M_DO_INIT_MOVE as it is now useless and uses M_CALL_INIT_MOVE.

The INIT_MOVE default method no longer sets the old 'src' to '0':
it was useless (it doesn't catch any error) and complicates compiler parsing.

Fix POD & A1 & CSTR & classic oplists definition (missing INIT_MOVE operators).
This commit is contained in:
Patrick Pelissier committed 2025-05-07 21:02:24 +02:00
1 parent 3a39ce5a4a
commit d548117538
19 files changed
+126 -157

No files matched your search

+16 -9
View File
@@ -356,7 +356,7 @@ Here is another example with a complete type (with proper initialization & clear
#include <stdio.h>
#include <gmp.h>
#include "m-array.h"
ARRAY_DEF(array_mpz, mpz_t, (INIT(mpz_init), INIT_SET(mpz_init_set), SET(mpz_set), CLEAR(mpz_clear)) )
ARRAY_DEF(array_mpz, mpz_t, (INIT(mpz_init), INIT_SET(mpz_init_set), SET(mpz_set), CLEAR(mpz_clear), INIT_MOVE(M_COPY_A1_DEFAULT)) )
int main(void) {
array_mpz_t array ; /* array_mpz_t has been define above */
array_mpz_init(array); /* All type needs to be initialized */
@@ -401,7 +401,7 @@ We can also write the same example shorter:
// Register the oplist of a mpz_t.
#define M_OPL_mpz_t() (INIT(mpz_init), INIT_SET(mpz_init_set), \
SET(mpz_set), CLEAR(mpz_clear))
SET(mpz_set), CLEAR(mpz_clear), INIT_MOVE(M_COPY_A1_DEFAULT))
// Define an instance of an array of mpz_t (both type and function)
ARRAY_DEF(array_mpz, mpz_t)
// Register the oplist of the created instance of array of mpz_t
@@ -786,7 +786,7 @@ void mpz_clear(mpz_t z); // Destructor of the object z
A basic oplist will be:
```C
(INIT(mpz_init),SET(mpz_set),INIT_SET(mpz_init_set),CLEAR(mpz_clear),TYPE(mpz_t))
(INIT(mpz_init),SET(mpz_set),INIT_SET(mpz_init_set),CLEAR(mpz_clear), INIT_MOVE(M_COPY_A1_DEFAULT),TYPE(mpz_t))
```
Much more complete oplist can be built for this type however, enabling much more powerful generation:
@@ -803,7 +803,7 @@ Example:
```C
#define M_OPL_mpz_t() (INIT(mpz_init),SET(mpz_set), \
INIT_SET(mpz_init_set),CLEAR(mpz_clear),TYPE(mpz_t))
INIT_SET(mpz_init_set),CLEAR(mpz_clear), INIT_MOVE(M_COPY_A1_DEFAULT),TYPE(mpz_t))
```
This can simplify a lot `OPLIST` usage and it is recommended.
@@ -841,7 +841,7 @@ The API Adaptation to use shall be embedded in the `OPLIST` definition.
For example:
```C
(INIT(API_0(mpz_init)), SET(API_0(mpz_set)), INIT_SET(API_0(mpz_init_set)), CLEAR(API_0(mpz_clear)))
(INIT(API_0(mpz_init)), SET(API_0(mpz_set)), INIT_SET(API_0(mpz_init_set)), CLEAR(API_0(mpz_clear)), INIT_MOVE(M_COPY_A1_DEFAULT))
```
The default adaptation is API_0 (i.e. no adaptation between operator interface and method interface).
@@ -1174,6 +1174,11 @@ perl -i -e 's/;/;\n/g' test-file.i
cc -std=c99 -c -Wall test-file.i
```
If you get the error "assignment to expression with array type", it means that the library
tries using the default '=' operator to set an object which is not compatible:
give the right method to the needed operator (usually `INIT_MOVE` or `INIT_SET`) in its oplist
or use the proper oplist of the type.
If there is a warning reported by the compiler in the generated code,
then there is definitely an **error** you should fix (except if it reports
shadowed variables), in particular cast evolving pointers.
@@ -1311,6 +1316,8 @@ and you shall use a typedef as an intermediary named type for such types.
The output parameters are listed fist, then the input/output parameters and finally the input parameters.
The oplist shall also provide the `INIT_MOVE` operator if the default instance (aka '=' operator) is not working for this type (for example for array of size 1, in which case the method `M_COPY_A1_DEFAULT` is likely to work), or disable the operator.
This generic interface is specified as follow:
##### `void name_init(name_t container)`
@@ -1773,7 +1780,7 @@ Example:
#define MPZ_OUT_STR(stream, x) mpz_out_str(stream, 0, x)
LIST_DEF(list_mpz, mpz_t, \
(INIT(mpz_init), INIT_SET(mpz_init_set), SET(mpz_set), \
CLEAR(mpz_clear), OUT_STR(MPZ_OUT_STR)))
CLEAR(mpz_clear), INIT_MOVE(M_COPY_A1_DEFAULT), OUT_STR(MPZ_OUT_STR)))
int main(void) {
list_mpz_t a;
@@ -1973,7 +1980,7 @@ Example:
#define MPZ_OUT_STR(stream, x) mpz_out_str(stream, 0, x)
LIST_DUAL_PUSH_DEF(list_mpz, mpz_t, \
(INIT(mpz_init), INIT_SET(mpz_init_set), SET(mpz_set), \
CLEAR(mpz_clear), OUT_STR(MPZ_OUT_STR)))
CLEAR(mpz_clear), INIT_MOVE(M_COPY_A1_DEFAULT), OUT_STR(MPZ_OUT_STR)))
int main(void) {
list_mpz_t a;
@@ -2132,7 +2139,7 @@ Example:
#define MPZ_OUT_STR(stream, x) mpz_out_str(stream, 0, x)
ARRAY_DEF(array_mpz, mpz_t, \
(INIT(mpz_init), INIT_SET(mpz_init_set), SET(mpz_set), \
CLEAR(mpz_clear), OUT_STR(MPZ_OUT_STR)))
CLEAR(mpz_clear), INIT_MOVE(M_COPY_A1_DEFAULT), OUT_STR(MPZ_OUT_STR)))
int main(void) {
array_mpz_t a;
@@ -2339,7 +2346,7 @@ Example:
#include "m-deque.h"
DEQUE_DEF(deque_mpz, mpz_t, \
(INIT(mpz_init), INIT_SET(mpz_init_set), SET(mpz_set), CLEAR(mpz_clear)))
(INIT(mpz_init), INIT_SET(mpz_init_set), SET(mpz_set), CLEAR(mpz_clear), INIT_MOVE(M_COPY_A1_DEFAULT)))
int main(void) {
deque_mpz_t a;
+2
View File
@@ -99,3 +99,5 @@ V0.8.0 : * The prototypes of REALLOC / FREE operators are incompatible:
* m-buffer push / pop no longer return a bool (it was undocumented)
* Remove MEMPOOL support from list & R/B tree
* m-mempool: Header is obsolete (and no longer useful at all as lists & RB Tree no longer can use it. To remove?). Use new M_USE_POOL interface to pass local pool context.
* M*LIB becomes stricter for INIT_MOVE: Emulation layer using CLEAR+INIT_SET when missing INIT_MOVE operator has been removed: either default INIT_MOVE operator (operator '=') is working, or a methode is provided for INIT_MOVE or it is disabled.
(It's because supporting emulation layer with new memory context parameter was complicated)
+3 -3
View File
@@ -1,7 +1,7 @@
*Long term issues*
==========================================================
* TODO #34 : Pass old size arguments to memory allocator :ENHANCEMENT:
* DONE #34 : Pass old size arguments to memory allocator :ENHANCEMENT:
** State
@@ -53,7 +53,7 @@ function due to the copy of the object one per one. Each copied sub object
may throw an exception, so we always need to have the container in a correct
state so that it can be cleanup.
* TODO #32 : User specialization fields in the container :ENHANCEMENT:
* DONE #32 : User specialization fields in the container :ENHANCEMENT:
** State
Some methods of a contained object may need to have some options that
@@ -452,7 +452,7 @@ as DPRIORITY_QUEUE_DEF ?
NOTE: Needs for such container?
On hold until a user needs it.
* TODO #23 : Strict MOVE semantic to clarify :ENHANCEMENT:
* DONE #23 : Strict MOVE semantic to clarify :ENHANCEMENT:
** State
+3 -1
View File
@@ -35,6 +35,7 @@ mpz_fast_hash(const mpz_t z)
#define M_OPL_mpz_t() \
(INIT(mpz_init), INIT_SET(mpz_init_set), SET(mpz_set), CLEAR(mpz_clear), \
INIT_WITH(API_1(M_INIT_WITH_THROUGH_EMPLACE_TYPE)), \
INIT_MOVE(M_COPY_A1_DEFAULT) \
EQUAL( API( mpz_cmp, EQ(0), ARG1, ARG2)), \
CMP(mpz_cmp), \
HASH(mpz_fast_hash), \
@@ -77,7 +78,8 @@ mpfr_fast_hash (const mpfr_t f)
/* Define the OPLIST of a mpfr_t and register it globally */
#define M_OPL_mpfr_t() \
(INIT(mpfr_init), INIT_SET(API(mpfr_init_set, VOID, ARG1, ARG2, MPFR_RNDN)), SET(API(mpfr_set, VOID, ARG1, ARG2, MPFR_RNDN)), CLEAR(mpfr_clear), \
INIT_WITH(API_1(M_INIT_WITH_THROUGH_EMPLACE_TYPE)), \
INIT_WITH(API_1(M_INIT_WITH_THROUGH_EMPLACE_TYPE)), \
INIT_MOVE(M_COPY_A1_DEFAULT) \
EQUAL( API( mpfr_cmp, EQ(0), ARG1, ARG2)), \
CMP(mpfr_cmp), \
HASH(mpfr_fast_hash), \
+7 -22
View File
@@ -173,7 +173,6 @@
#define M_ARRA4_DEF_P3(name, type, oplist, array_t, it_t) \
M_ARRA4_DEF_TYPE(name, type, oplist, array_t, it_t) \
M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \
/* TODO: Check if type has not disabled INIT_MOVE */ \
M_ARRA4_DEF_CORE(name, type, oplist, array_t, it_t) \
M_ARRA4_DEF_IO(name, type, oplist, array_t, it_t) \
M_EMPLACE_QUEUE_DEF(name, array_t, _emplace_back, oplist, M_ARRA4_EMPLACE_DEF)
@@ -365,16 +364,14 @@
} \
, /* No INIT */ ) \
\
M_IF_AT_LEAST_METHOD(INIT_SET, INIT_MOVE, oplist)( \
M_P(void, name, _push_move, array_t v, type *x) \
{ \
M_ASSERT (x != NULL); \
type *data = M_F(name, _push_raw) M_R(v); \
if (M_UNLIKELY (data == NULL) ) \
return; \
M_DO_INIT_MOVE (oplist, *data, *x); \
M_CALL_INIT_MOVE (oplist, *data, *x); \
} \
, /* INIT_SET | INIT_MOVE */ ) \
\
M_IF_METHOD(INIT_SET, oplist)( \
M_P(void, name, _push_at, array_t v, size_t key, type const x) \
@@ -490,7 +487,6 @@
} \
, /* No INIT */) \
\
M_IF_AT_LEAST_METHOD(SET, INIT_MOVE, oplist)( \
M_P(void, name, _pop_back, type *dest, array_t v) \
{ \
M_ARRA4_CONTRACT(v); \
@@ -505,11 +501,7 @@
} \
M_ARRA4_CONTRACT(v); \
} \
, /* SET | INIT_MOVE */ ) \
\
M_IF_AT_LEAST_METHOD(INIT_SET, INIT_MOVE, oplist)( \
/* FIXME: type has to be trivially movable (imposed by array) ! */ \
/* FIXME: Really allocation or allocation free? */ \
M_INLINE void \
M_F(name, _pop_move)(type *dest, array_t v) \
{ \
@@ -518,11 +510,9 @@
M_ASSERT_INDEX(0, v->size); \
M_ASSERT (dest != NULL); \
v->size--; \
/* FIXME: M_DO_INIT_MOVE may use INIT_SET so allocator !*/ \
M_DO_INIT_MOVE (oplist, *dest, v->ptr[v->size]); \
M_CALL_INIT_MOVE (oplist, *dest, v->ptr[v->size]); \
M_ARRA4_CONTRACT(v); \
} \
, /* INIT_SET | INIT_MOVE */ ) \
\
/* TODO: Factorize all INIT dependent methods within the same IF*/ \
M_IF_METHOD(INIT, oplist)( \
@@ -556,14 +546,12 @@
return v->alloc; \
} \
\
M_IF_AT_LEAST_METHOD(SET, INIT_MOVE, oplist)( \
M_P(void, name, _pop_at, type *dest, array_t v, size_t i) \
{ \
M_ARRA4_CONTRACT(v); \
M_ASSERT_POOL(); \
M_ASSERT (v->size > 0 && v->ptr != NULL); \
M_ASSERT_INDEX(i, v->size); \
/* FIXME: type is trivially movable */ \
if (dest) \
M_DO_MOVE (oplist, *dest, v->ptr[i]); \
else \
@@ -580,7 +568,6 @@
M_F(name, _pop_at) M_R(NULL, a, i); \
return true; \
} \
, /* SET | INIT_MOVE */ ) \
\
M_IF_METHOD(INIT, oplist)( \
M_P(void, name, _insert_v, array_t v, size_t i, size_t num) \
@@ -644,7 +631,6 @@
M_ARRA4_CONTRACT(v2); \
} \
\
M_IF_AT_LEAST_METHOD(INIT_SET,INIT_MOVE,oplist) ( \
M_INLINE void \
M_F(name, _swap_at)(array_t v, size_t i, size_t j) \
{ \
@@ -653,12 +639,11 @@
M_ASSERT_INDEX(i, v->size); \
M_ASSERT_INDEX(j, v->size); \
type tmp; \
M_DO_INIT_MOVE(oplist, tmp, v->ptr[i]); \
M_DO_INIT_MOVE(oplist, v->ptr[i], v->ptr[j]); \
M_DO_INIT_MOVE(oplist, v->ptr[j], tmp); \
M_CALL_INIT_MOVE(oplist, tmp, v->ptr[i]); \
M_CALL_INIT_MOVE(oplist, v->ptr[i], v->ptr[j]); \
M_CALL_INIT_MOVE(oplist, v->ptr[j], tmp); \
M_ARRA4_CONTRACT(v); \
} \
, /* INIT_SET | INIT_MOVE */ ) \
\
M_INLINE type * \
M_F(name, _get)(const array_t v, size_t i) \
@@ -849,7 +834,7 @@
k += n1+n2; \
for (;;) { \
if (M_CALL_CMP(oplist, *el1, *el2) <= 0) { \
M_DO_INIT_MOVE(oplist, *dest, *el1); \
M_CALL_INIT_MOVE(oplist, *dest, *el1); \
dest++; \
el1++; \
if (M_UNLIKELY(-- n1 == 0)) { \
@@ -860,7 +845,7 @@
break; \
} \
} else { \
M_DO_INIT_MOVE(oplist, *dest, *el2); \
M_CALL_INIT_MOVE(oplist, *dest, *el2); \
dest++; \
el2++; \
if (M_UNLIKELY(-- n2 == 0)) { \
+6 -6
View File
@@ -541,7 +541,7 @@ M_N(void, name, _init, buffer_t v, size_t size) \
if (!M_BUFF3R_POLICY_P((policy), M_BUFFER_PUSH_INIT_POP_MOVE)) { \
M_CALL_SET(oplist, *data, v->data[v->idx_cons].x); \
} else { \
M_DO_INIT_MOVE (oplist, *data, v->data[v->idx_cons].x); \
M_CALL_INIT_MOVE (oplist, *data, v->data[v->idx_cons].x); \
} \
v->idx_cons = (v->idx_cons == M_BUFF3R_SIZE(m_size)-1) ? 0 : (v->idx_cons + 1); \
} else { \
@@ -550,7 +550,7 @@ M_N(void, name, _init, buffer_t v, size_t size) \
if (!M_BUFF3R_POLICY_P((policy), M_BUFFER_PUSH_INIT_POP_MOVE)) { \
M_CALL_SET(oplist, *data, v->data[v->idx_prod].x); \
} else { \
M_DO_INIT_MOVE (oplist, *data, v->data[v->idx_prod].x); \
M_CALL_INIT_MOVE (oplist, *data, v->data[v->idx_prod].x); \
} \
} \
\
@@ -767,7 +767,7 @@ M_N(void, name, _init, buffer_t v, size_t size) \
if (!M_BUFF3R_POLICY_P((policy), M_BUFFER_PUSH_INIT_POP_MOVE)) { \
M_CALL_SET(oplist, *ptr, table->Tab[i].x); \
} else { \
M_DO_INIT_MOVE (oplist, *ptr, table->Tab[i].x); \
M_CALL_INIT_MOVE (oplist, *ptr, table->Tab[i].x); \
} \
atomic_store_explicit(&table->Tab[i].seq, 2*iC + 1, memory_order_release); \
M_QU3UE_MPMC_CONTRACT(table); \
@@ -971,7 +971,7 @@ M_N(void, name, _init, buffer_t v, size_t size) \
if (!M_BUFF3R_POLICY_P((policy), M_BUFFER_PUSH_INIT_POP_MOVE)) { \
M_DO_MOVE(oplist, table->Tab[i].x, *x); \
} else { \
M_DO_INIT_MOVE(oplist, table->Tab[i].x, *x); \
M_CALL_INIT_MOVE(oplist, table->Tab[i].x, *x); \
} \
atomic_store_explicit(&table->prodIdx, w+1, memory_order_release); \
M_QU3UE_SPSC_CONTRACT(table); \
@@ -993,7 +993,7 @@ M_N(void, name, _init, buffer_t v, size_t size) \
if (!M_BUFF3R_POLICY_P((policy), M_BUFFER_PUSH_INIT_POP_MOVE)) { \
M_CALL_SET(oplist, *ptr , table->Tab[i].x); \
} else { \
M_DO_INIT_MOVE (oplist, *ptr, table->Tab[i].x); \
M_CALL_INIT_MOVE (oplist, *ptr, table->Tab[i].x); \
} \
atomic_store_explicit(&table->consoIdx, r+1, memory_order_release); \
M_QU3UE_SPSC_CONTRACT(table); \
@@ -1044,7 +1044,7 @@ M_N(void, name, _init, buffer_t v, size_t size) \
if (!M_BUFF3R_POLICY_P((policy), M_BUFFER_PUSH_INIT_POP_MOVE)) { \
M_CALL_SET(oplist, ptr[k], table->Tab[i].x); \
} else { \
M_DO_INIT_MOVE (oplist, ptr[k], table->Tab[i].x); \
M_CALL_INIT_MOVE (oplist, ptr[k], table->Tab[i].x); \
} \
} \
atomic_store_explicit(&table->consoIdx, r+max, memory_order_release); \
+43 -56
View File
@@ -3545,7 +3545,7 @@ M_INLINE size_t m_core_cstr_hash(const char str[])
/* Get the given method */
#define M_GET_INIT(...) M_GET_METHOD(INIT, M_INIT_DEFAULT, __VA_ARGS__)
#define M_GET_INIT_SET(...) M_GET_METHOD(INIT_SET, M_SET_DEFAULT, __VA_ARGS__)
#define M_GET_INIT_MOVE(...) M_GET_METHOD(INIT_MOVE, M_NO_DEF_INIT_MOVE, __VA_ARGS__)
#define M_GET_INIT_MOVE(...) M_GET_METHOD(INIT_MOVE, M_SET_DEFAULT, __VA_ARGS__)
#define M_GET_INIT_WITH(...) M_GET_METHOD(INIT_WITH, M_NO_DEF_INIT_WITH, __VA_ARGS__)
#define M_GET_SET(...) M_GET_METHOD(SET, M_SET_DEFAULT, __VA_ARGS__)
#define M_GET_MOVE(...) M_GET_METHOD(MOVE, M_NO_DEF_MOVE, __VA_ARGS__)
@@ -3869,12 +3869,6 @@ M_INLINE size_t m_core_cstr_hash(const char str[])
"The " #operator " operator has no method associated in the given OPLIST."),\
(return_type) 0)
// TODO: Use default INIT_MOVE which assume trivially movable type
// by getting throught API_2 the oplist and the size of the type
// If no type defined and no INIT_MOVE defined, just use sizeof (dst)
// Most types are trivially movable. Can remove macro M_DO_INIT_MOVE to use M_CALL_INIT_MOVE
// If disabled in oplist, M_CALL_INIT_MOVE will generate an error.
#define M_NO_DEF_INIT_MOVE(...) M_NO_DEFAULT(INIT_MOVE, void)
#define M_NO_DEF_INIT_WITH(...) M_NO_DEFAULT(INIT_WITH, void)
#define M_NO_DEF_MOVE(...) M_NO_DEFAULT(MOVE, void)
#define M_NO_DEF_SWAP(...) M_NO_DEFAULT(SWAP, void)
@@ -4063,9 +4057,7 @@ M_INLINE size_t m_core_cstr_hash(const char str[])
/* NOTE: Theses operators are NOT compatible with the '[1]' tricks
if the variable is defined as a parameter of a function
(sizeof (a) is not portable). */
#define M_MOVE_DEFAULT(a,b) (M_CHECK_SAME(a, b), M_MEMCPY_DEFAULT(a, b), memset(&(b), 0, sizeof (a)))
#define M_MEMCPY_DEFAULT(a,b) (M_CHECK_SAME(a, b), memcpy(&(a), &(b), sizeof (a)))
#define M_MEMSET_DEFAULT(a) (memset(&(a), 0, sizeof (a)))
#define M_RESET_DEFAULT(a) (memset(&(a), 0, sizeof (a)))
#define M_MEMCMP1_DEFAULT(a,b) (M_CHECK_SAME(a, b), memcmp(&(a), &(b), sizeof (a)) == 0)
#define M_MEMCMP2_DEFAULT(a,b) (M_CHECK_SAME(a, b), memcmp(&(a), &(b), sizeof (a)))
#define M_SWAP_DEFAULT(el1, el2) do { \
@@ -4076,28 +4068,35 @@ M_INLINE size_t m_core_cstr_hash(const char str[])
memcpy(&(el2), &_tmp, sizeof (el1)); \
} while (0)
/* Default oplist for plain structure */
#define M_POD_OPLIST \
(INIT(M_RESET_DEFAULT), INIT_SET(M_SET_DEFAULT), SET(M_SET_DEFAULT), CLEAR(M_NOTHING_DEFAULT), \
EQUAL(M_MEMCMP1_DEFAULT), CMP(M_MEMCMP2_DEFAULT), HASH(M_HASH_POD_DEFAULT), SWAP(M_SWAP_DEFAULT), \
INIT_MOVE(M_SET_DEFAULT) )
/* NOTE: Theses operators are to be used with the '[1]' tricks
if the variable is defined as a parameter of a function
(sizeof (a) is not portable). */
#define M_MOVE_A1_DEFAULT(a,b) (M_CHECK_SAME(a[0], b[0]), M_MEMCPY_A1_DEFAULT(a, b), M_MEMSET_A1_DEFAULT(b))
#define M_MEMCPY_A1_DEFAULT(a,b) (M_CHECK_SAME(a[0], b[0]), memcpy(&(a[0]), &(b[0]), sizeof (a[0])))
#define M_MEMSET_A1_DEFAULT(a) (memset(&(a[0]), 0, sizeof (a[0])))
#define M_COPY_A1_DEFAULT(a,b) (M_CHECK_SAME(a[0], b[0]), memcpy(&(a[0]), &(b[0]), sizeof (a[0])))
#define M_RESET_A1_DEFAULT(a) (memset(&(a[0]), 0, sizeof (a[0])))
#define M_MEMCMP1_A1_DEFAULT(a,b) (M_CHECK_SAME(a[0],b[0]), memcmp(&(a[0]), &(b[0]), sizeof (a[0])) == 0)
#define M_MEMCMP2_A1_DEFAULT(a,b) (M_CHECK_SAME(a[0], b[0]), memcmp(&(a[0]), &(b[0]), sizeof (a[0])))
#define M_HASH_A1_DEFAULT(a) (m_core_hash((const void*) &(a[0]), sizeof (a[0])) )
#define M_SWAP_A1_DEFAULT(a, b) do { \
char _tmp[sizeof (a[0])]; \
M_CHECK_SAME(a[0], b[0]); \
memcpy(&_tmp, &(a[0]), sizeof (a[0])); \
memcpy(&(a[0]), &(b[0]), sizeof (a[0])); \
memcpy(&(b[0]), &_tmp, sizeof (a[0])); \
} while (0)
/* Default oplist for plain structure */
#define M_POD_OPLIST \
(INIT(M_MEMSET_DEFAULT), INIT_SET(M_MEMCPY_DEFAULT), SET(M_MEMCPY_DEFAULT), \
CLEAR(M_NOTHING_DEFAULT), EQUAL(M_MEMCMP1_DEFAULT), CMP(M_MEMCMP2_DEFAULT), \
HASH(M_HASH_POD_DEFAULT), SWAP(M_SWAP_DEFAULT))
/* Default oplist for a structure defined with an array of size 1 */
/* Default oplist for a structure defined with an array of size 1.
MOVE operator is not defined since the object may need to release some data */
#define M_A1_OPLIST \
(INIT(M_MEMSET_A1_DEFAULT), INIT_SET(M_MEMCPY_A1_DEFAULT), SET(M_MEMCPY_A1_DEFAULT), \
CLEAR(M_NOTHING_DEFAULT), EQUAL(M_MEMCMP1_A1_DEFAULT), CMP(M_MEMCMP2_A1_DEFAULT), \
HASH(M_HASH_A1_DEFAULT))
(INIT(M_RESET_A1_DEFAULT), INIT_SET(M_COPY_A1_DEFAULT), SET(M_COPY_A1_DEFAULT), CLEAR(M_NOTHING_DEFAULT), \
EQUAL(M_MEMCMP1_A1_DEFAULT), CMP(M_MEMCMP2_A1_DEFAULT), HASH(M_HASH_A1_DEFAULT), SWAP(M_SWAP_A1_DEFAULT), \
INIT_MOVE(M_COPY_A1_DEFAULT) )
/* Oplist for a type that does nothing and shall not be instanciated */
@@ -4122,7 +4121,7 @@ M_INLINE size_t m_core_cstr_hash(const char str[])
# define M_BASIC_OPLIST \
(INIT(M_INIT_BASIC), INIT_SET(M_SET_BASIC), SET(M_SET_BASIC), \
CLEAR(M_NOTHING_DEFAULT), EQUAL(M_EQUAL_BASIC), CMP(M_CMP_BASIC), \
INIT_MOVE(M_MOVE_DEFAULT), MOVE(M_MOVE_DEFAULT) , \
INIT_MOVE(M_SET_DEFAULT), MOVE(M_SET_DEFAULT) , \
RESET(M_INIT_BASIC), PROPERTIES( (NOCLEAR(1)) ), \
ADD(M_ADD_DEFAULT), SUB(M_SUB_DEFAULT), \
MUL(M_MUL_DEFAULT), DIV(M_DIV_DEFAULT), \
@@ -4135,7 +4134,7 @@ M_INLINE size_t m_core_cstr_hash(const char str[])
# define M_BASIC_OPLIST \
(INIT(M_INIT_BASIC), INIT_SET(M_SET_BASIC), SET(M_SET_BASIC), \
CLEAR(M_NOTHING_DEFAULT), EQUAL(M_EQUAL_BASIC), CMP(M_CMP_BASIC), \
INIT_MOVE(M_MOVE_DEFAULT), MOVE(M_MOVE_DEFAULT) , \
INIT_MOVE(M_SET_DEFAULT), MOVE(M_SET_DEFAULT) , \
RESET(M_INIT_BASIC), PROPERTIES( (NOCLEAR(1)) ), \
ADD(M_ADD_DEFAULT), SUB(M_SUB_DEFAULT), \
MUL(M_MUL_DEFAULT), DIV(M_DIV_DEFAULT), \
@@ -4148,7 +4147,7 @@ M_INLINE size_t m_core_cstr_hash(const char str[])
# define M_BASIC_OPLIST \
(INIT(M_INIT_BASIC), INIT_SET(M_SET_BASIC), SET(M_SET_BASIC), \
CLEAR(M_NOTHING_DEFAULT), EQUAL(M_EQUAL_BASIC), CMP(M_CMP_BASIC), \
INIT_MOVE(M_MOVE_DEFAULT), MOVE(M_MOVE_DEFAULT) , \
INIT_MOVE(M_SET_DEFAULT), MOVE(M_SET_DEFAULT) , \
RESET(M_INIT_BASIC), PROPERTIES( (NOCLEAR(1)) ), \
ADD(M_ADD_DEFAULT), SUB(M_SUB_DEFAULT), \
MUL(M_MUL_DEFAULT), DIV(M_DIV_DEFAULT), \
@@ -4179,7 +4178,7 @@ M_INLINE size_t m_core_cstr_hash(const char str[])
(INIT(API_1(M_ENUM_INIT)), INIT_SET(M_SET_DEFAULT), \
SET(M_SET_DEFAULT), CLEAR(M_NOTHING_DEFAULT), \
EQUAL(M_EQUAL_DEFAULT), CMP(M_CMP_DEFAULT), \
INIT_MOVE(M_MOVE_DEFAULT), MOVE(M_MOVE_DEFAULT) , \
INIT_MOVE(M_SET_DEFAULT), MOVE(M_SET_DEFAULT) , \
HASH(M_HASH_POD_DEFAULT), SWAP(M_SWAP_DEFAULT), \
TYPE(type), OPLIST(init), \
IN_STR(API_1(M_ENUM_FSCAN)), OUT_STR(M_ENUM_FPRINT), \
@@ -4192,7 +4191,7 @@ M_INLINE size_t m_core_cstr_hash(const char str[])
(INIT(API_1(M_ENUM_INIT)), INIT_SET(M_SET_DEFAULT), \
SET(M_SET_DEFAULT), CLEAR(M_NOTHING_DEFAULT), \
EQUAL(M_EQUAL_DEFAULT), CMP(M_CMP_DEFAULT), \
INIT_MOVE(M_MOVE_DEFAULT), MOVE(M_MOVE_DEFAULT) , \
INIT_MOVE(M_SET_DEFAULT), MOVE(M_SET_DEFAULT) , \
HASH(M_HASH_POD_DEFAULT), SWAP(M_SWAP_DEFAULT), \
TYPE(type), OPLIST(init), \
IN_SERIAL(API_1(M_ENUM_IN_SERIAL)), OUT_SERIAL(M_ENUM_OUT_SERIAL), \
@@ -4255,32 +4254,29 @@ m_core_parse2_enum (const char str[], const char **endptr)
/* Default oplist for standard types of pointers.
*/
#define M_PTR_OPLIST \
(INIT(M_INIT_DEFAULT), INIT_SET(M_SET_DEFAULT), SET(M_SET_DEFAULT), \
CLEAR(M_NOTHING_DEFAULT), EQUAL(M_EQUAL_DEFAULT), \
INIT_MOVE(M_MOVE_DEFAULT), MOVE(M_MOVE_DEFAULT) , \
SWAP(M_SWAP_DEFAULT) )
(INIT(M_INIT_DEFAULT), INIT_SET(M_SET_DEFAULT), SET(M_SET_DEFAULT), CLEAR(M_NOTHING_DEFAULT), \
EQUAL(M_EQUAL_DEFAULT), SWAP(M_SWAP_DEFAULT) \
INIT_MOVE(M_SET_DEFAULT), MOVE(M_SET_DEFAULT) )
/* Default oplist for complex objects with "classic" names for methods.
/* Default oplist for complex objects (using [1] trick) with "classic" names for methods.
*/
#define M_CLASSIC_OPLIST(name) ( \
INIT(M_F(name, _init)), \
INIT_SET(M_F(name, _init_set)), \
SET(M_F(name, _set)), \
CLEAR(M_F(name, _clear)), \
TYPE(M_F(name, _t)) )
INIT(M_F(name, _init)), INIT_SET(M_F(name, _init_set)), SET(M_F(name, _set)), CLEAR(M_F(name, _clear)), \
INIT_MOVE(M_COPY_A1_DEFAULT), TYPE(M_F(name, _t)) )
/* OPLIST for 'const char *' string (with NO memory allocation).
/* Default oplist for 'const char *' string (with NO memory allocation).
*/
#define M_CSTR_EQUAL(a,b) (strcmp((a),(b)) == 0)
#define M_CSTR_OUT_STR(file, str) fprintf(file, "%s", str)
#define M_CSTR_OPLIST (INIT(M_INIT_DEFAULT), INIT_SET(M_SET_DEFAULT), \
SET(M_SET_DEFAULT), CLEAR(M_NOTHING_DEFAULT), \
HASH(m_core_cstr_hash), EQUAL(M_CSTR_EQUAL), \
CMP(strcmp), TYPE(const char *), \
OUT_STR(M_CSTR_OUT_STR) )
#define M_CSTR_OPLIST \
(INIT(M_INIT_DEFAULT), INIT_SET(M_SET_DEFAULT), SET(M_SET_DEFAULT), CLEAR(M_NOTHING_DEFAULT), \
HASH(m_core_cstr_hash), EQUAL(M_CSTR_EQUAL), CMP(strcmp), SWAP(M_SWAP_DEFAULT), \
INIT_MOVE(M_SET_DEFAULT), MOVE(M_SET_DEFAULT), TYPE(const char *), \
OUT_STR(M_CSTR_OUT_STR) )
/****************************************************************************/
/* From an oplist (...) return ... (Like M_ID but for OPLIST) */
#define M_OPFLAT(...) __VA_ARGS__
@@ -4365,15 +4361,6 @@ m_core_parse2_enum (const char str[], const char **endptr)
so that the first argument becomes a pointer to the destination (OBSOLETE MACRO) */
#define M_IPTR(...) ( & __VA_ARGS__ )
/* Perform an INIT_MOVE if present, or emulate it using INIT_SET/CLEAR */
/* FIXME: Use INIT_MOVE if present or assume trivially movable otherwise? */
/* A non trivially movable type shall provide an INIT_MOVE method or disable it */
#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) )); \
} 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 { \
@@ -4756,8 +4743,8 @@ m_core_parse2_enum (const char str[], const char **endptr)
so it reverses the final order.
*/
#define M_INIT_VAI(oplist, dest, ...) \
(void)(M_CALL_INIT(oplist, dest) , \
M_MAP2_C(M_INIT_VAI_FUNC, (dest, oplist) , __VA_ARGS__) \
(void)(M_CALL_INIT(oplist, dest) , \
M_MAP2_C(M_INIT_VAI_FUNC, (dest, oplist) , __VA_ARGS__) \
M_IF_METHOD(REVERSE, oplist)(M_DEFERRED_COMMA M_CALL_REVERSE(oplist, dest), ) \
)
#define M_INIT_VAI_FUNC(d, a) \
+2 -2
View File
@@ -309,7 +309,7 @@
{ \
M_ASSERT (x != NULL); \
type *p = M_F(name, _push_back_raw)M_R(d); \
M_DO_INIT_MOVE (oplist, *p, *x); \
M_CALL_INIT_MOVE (oplist, *p, *x); \
} \
\
M_P(type *, name, _push_front_raw, deque_t d) \
@@ -358,7 +358,7 @@
{ \
M_ASSERT (x != NULL); \
type *p = M_F(name, _push_front_raw)M_R(d); \
M_DO_INIT_MOVE (oplist, *p, *x); \
M_CALL_INIT_MOVE (oplist, *p, *x); \
} \
\
M_P(void, name, _pop_back, type *ptr, deque_t d) \
+12 -12
View File
@@ -1421,8 +1421,8 @@ enum m_d1ct_oa_element_e {
\
/* NOTE: We don't want a real oplist for this sub type */ \
M_ARRAY_DEF(M_F(name, _array_pair), M_F(name, _pair_ct), \
(INIT(M_NOTHING_DEFAULT), SET(M_MEMCPY_DEFAULT), \
INIT_SET(M_MEMCPY_DEFAULT), CLEAR(M_NOTHING_DEFAULT))) \
(INIT(M_NOTHING_DEFAULT), SET(M_SET_DEFAULT), \
INIT_SET(M_SET_DEFAULT), CLEAR(M_NOTHING_DEFAULT))) \
\
typedef struct M_F(name,_s) { \
size_t mask, count, count_delete; \
@@ -1576,12 +1576,12 @@ enum m_d1ct_oa_element_e {
if (p != i) { \
if (M_LIKELY (M_CALL_OOR_EQUAL(key_oplist, data[p].key, M_D1CT_OA_EMPTY) \
|| M_CALL_OOR_EQUAL(key_oplist, data[p].key, M_D1CT_OA_DELETED))) { \
M_DO_INIT_MOVE(key_oplist, data[p].key, data[i].key); \
M_DO_INIT_MOVE(value_oplist, data[p].value, data[i].value); \
M_CALL_INIT_MOVE(key_oplist, data[p].key, data[i].key); \
M_CALL_INIT_MOVE(value_oplist, data[p].value, data[i].value); \
} else { \
M_F(name, _pair_ct) *ptr = M_F(name, _array_pair_push_raw)M_R(tmp); \
M_DO_INIT_MOVE(key_oplist, ptr->key, data[i].key); \
M_DO_INIT_MOVE(value_oplist, ptr->value, data[i].value); \
M_CALL_INIT_MOVE(key_oplist, ptr->key, data[i].key); \
M_CALL_INIT_MOVE(value_oplist, ptr->value, data[i].value); \
} \
M_CALL_OOR_SET(key_oplist, data[i].key, M_D1CT_OA_EMPTY); \
} \
@@ -1750,12 +1750,12 @@ enum m_d1ct_oa_element_e {
if (p != i) { \
if (M_CALL_OOR_EQUAL(key_oplist, data[p].key, M_D1CT_OA_EMPTY) \
|| M_CALL_OOR_EQUAL(key_oplist, data[p].key, M_D1CT_OA_DELETED)) { \
M_DO_INIT_MOVE(key_oplist, data[p].key, data[i].key); \
M_DO_INIT_MOVE(value_oplist, data[p].value, data[i].value); \
M_CALL_INIT_MOVE(key_oplist, data[p].key, data[i].key); \
M_CALL_INIT_MOVE(value_oplist, data[p].value, data[i].value); \
} else { \
M_F(name, _pair_ct) *ptr = M_F(name, _array_pair_push_raw)M_R(tmp); \
M_DO_INIT_MOVE(key_oplist, ptr->key, data[i].key); \
M_DO_INIT_MOVE(value_oplist, ptr->value, data[i].value); \
M_CALL_INIT_MOVE(key_oplist, ptr->key, data[i].key); \
M_CALL_INIT_MOVE(value_oplist, ptr->value, data[i].value); \
} \
M_CALL_OOR_SET(key_oplist, data[i].key, M_D1CT_OA_EMPTY); \
} \
@@ -1773,8 +1773,8 @@ enum m_d1ct_oa_element_e {
M_ASSERT (s <= h->mask); \
} while (!M_CALL_OOR_EQUAL(key_oplist, data[p].key, M_D1CT_OA_EMPTY) ); \
} \
M_DO_INIT_MOVE(key_oplist, data[p].key, data[i].key); \
M_DO_INIT_MOVE(value_oplist, data[p].value, data[i].value); \
M_CALL_INIT_MOVE(key_oplist, data[p].key, data[i].key); \
M_CALL_INIT_MOVE(value_oplist, data[p].value, data[i].value); \
} \
} \
/* Pass 3: scan moved entries and move them back */ \
+5 -5
View File
@@ -307,14 +307,14 @@
type *data = M_F(name, _push_raw)M_R(v); \
if (M_UNLIKELY (data == NULL)) \
return; \
M_DO_INIT_MOVE (oplist, *data, *x); \
M_CALL_INIT_MOVE (oplist, *data, *x); \
} \
\
M_P(void, name, _pop_move, type *data, list_t v) \
{ \
M_L1ST_CONTRACT(v); \
M_ASSERT(*v != NULL && data != NULL); \
M_DO_INIT_MOVE (oplist, *data, (*v)->data); \
M_CALL_INIT_MOVE (oplist, *data, (*v)->data); \
struct M_F(name, _s) *tofree = *v; \
*v = (*v)->next; \
M_CALL_DEL(oplist, tofree); \
@@ -1057,7 +1057,7 @@
type *data = M_F(name, _push_back_raw)M_R(v); \
if (M_UNLIKELY (data == NULL)) \
return; \
M_DO_INIT_MOVE (oplist, *data, *x); \
M_CALL_INIT_MOVE (oplist, *data, *x); \
} \
\
M_P(void, name, _push_move, list_t v, type *x) \
@@ -1091,7 +1091,7 @@
M_ASSERT (v->back != NULL); \
M_ASSERT (data != NULL); \
struct M_F(name, _s) *tofree = v->back; \
M_DO_INIT_MOVE (oplist, *data, tofree->data); \
M_CALL_INIT_MOVE (oplist, *data, tofree->data); \
v->back = tofree->next; \
M_CALL_DEL(oplist, tofree); \
/* Update front too if the list became empty */ \
@@ -1149,7 +1149,7 @@
type *data = M_F(name, _push_front_raw)(v); \
if (M_UNLIKELY (data == NULL)) \
return; \
M_DO_INIT_MOVE (oplist, *data, *x); \
M_CALL_INIT_MOVE (oplist, *data, *x); \
} \
\
M_IF_METHOD(INIT, oplist)( \
+1
View File
@@ -2357,6 +2357,7 @@ namespace m_lib {
INIT_SET(M_F(name,_init_set)), \
SET(M_F(name,_set)), \
CLEAR(M_F(name,_clear)), \
INIT_MOVE(M_COPY_A1_DEFAULT), \
NAME(name), \
INIT_WITH( API_1(M_BOUNDED_STR1NG_INIT_WITH)), \
HASH(M_F(name,_hash)), \
+5 -5
View File
@@ -476,7 +476,7 @@ typedef int32_t m_tr33_index_t;
\
M_P(it_t, name, _move_up, it_t pos, type *data) { \
it_t it = M_F(name, _insert_up_raw)M_R(pos); \
M_DO_INIT_MOVE(oplist, it.tree->tab[it.index].data, *data); \
M_CALL_INIT_MOVE(oplist, it.tree->tab[it.index].data, *data); \
M_TR33_IT_CONTRACT(it, true); \
return it; \
} \
@@ -510,7 +510,7 @@ typedef int32_t m_tr33_index_t;
\
M_P(it_t, name, _move_down, it_t pos, type *data) { \
it_t it = M_F(name, _insert_down_raw)M_R(pos); \
M_DO_INIT_MOVE(oplist, it.tree->tab[it.index].data, *data); \
M_CALL_INIT_MOVE(oplist, it.tree->tab[it.index].data, *data); \
M_TR33_IT_CONTRACT(it, true); \
return it; \
} \
@@ -544,7 +544,7 @@ typedef int32_t m_tr33_index_t;
\
M_P(it_t, name, _move_child, it_t pos, type *data) { \
it_t it = M_F(name, _insert_child_raw)M_R(pos); \
M_DO_INIT_MOVE(oplist, it.tree->tab[it.index].data, *data); \
M_CALL_INIT_MOVE(oplist, it.tree->tab[it.index].data, *data); \
M_TR33_IT_CONTRACT(it, true); \
return it; \
} \
@@ -581,7 +581,7 @@ typedef int32_t m_tr33_index_t;
\
M_P(it_t, name, _move_left, it_t pos, type *data) { \
it_t it = M_F(name, _insert_left_raw)M_R(pos); \
M_DO_INIT_MOVE(oplist, it.tree->tab[it.index].data, *data); \
M_CALL_INIT_MOVE(oplist, it.tree->tab[it.index].data, *data); \
M_TR33_IT_CONTRACT(it, true); \
return it; \
} \
@@ -612,7 +612,7 @@ typedef int32_t m_tr33_index_t;
\
M_P(it_t, name, _move_right, it_t pos, type *data) { \
it_t it = M_F(name, _insert_right_raw)M_R(pos); \
M_DO_INIT_MOVE(oplist, it.tree->tab[it.index].data, *data); \
M_CALL_INIT_MOVE(oplist, it.tree->tab[it.index].data, *data); \
M_TR33_IT_CONTRACT(it, true); \
return it; \
} \
+3 -3
View File
@@ -33,9 +33,9 @@ END_COVERAGE
#define ARRAY_UINT_OPLIST ARRAY_OPLIST(array_uint)
// Array with the minimum number of methods.
ARRAY_DEF(array_min_z, testobj_t, (INIT_SET(testobj_init_set), SET(testobj_set), CLEAR(testobj_clear)))
ARRAY_DEF(array_min2_z, testobj_t, (INIT(testobj_init), CLEAR(testobj_clear)))
ARRAY_DEF(array_min3_z, testobj_t, (CLEAR(testobj_clear)))
ARRAY_DEF(array_min_z, testobj_t, (INIT_SET(testobj_init_set), SET(testobj_set), CLEAR(testobj_clear), INIT_MOVE(M_COPY_A1_DEFAULT) ))
ARRAY_DEF(array_min2_z, testobj_t, (INIT(testobj_init), CLEAR(testobj_clear), INIT_MOVE(M_COPY_A1_DEFAULT) ) )
ARRAY_DEF(array_min3_z, testobj_t, (CLEAR(testobj_clear), INIT_MOVE(M_COPY_A1_DEFAULT)))
ARRAY_DEF(array_ulong, uint64_t)
ARRAY_DEF(array_string, string_t)
+10 -23
View File
@@ -746,65 +746,54 @@ typedef struct { int b,c; } ts;
static void f_ti(ti x)
{
ti y;
M_MOVE_A1_DEFAULT(y,x);
M_COPY_A1_DEFAULT(y,x);
assert(y[0] == 9);
assert(x[0] == 0);
}
static void f_ts(ts x)
{
ts y;
M_MOVE_DEFAULT(y,x);
M_SET_DEFAULT(y,x);
assert(y.b == 2);
assert(y.c == 3);
assert(x.b == 0);
assert(x.c == 0);
}
static void f_ts2(ts *x)
{
ts y;
M_MOVE_DEFAULT(y,*x);
M_SET_DEFAULT(y,*x);
assert(y.b == 2);
assert(y.c == 3);
assert(x->b == 0);
assert(x->c == 0);
}
static void test_move_default(void)
{
int o, p;
o = 9;
M_MOVE_DEFAULT(p, o);
M_SET_DEFAULT(p, o);
assert(p == 9);
assert(o == 0);
double u, k;
k = -1.0;
u = 9.5;
M_MOVE_DEFAULT(k, u);
M_SET_DEFAULT(k, u);
assert(k == 9.5);
assert(u == 0.0); // NOTE: memset(0) sets an IEEE-754 number to 0.0
int *ptr = &o, *m;
M_MOVE_DEFAULT(m, ptr);
assert( ptr == NULL);
assert( m == &o);
M_SET_DEFAULT(m, ptr);
(void)m;
ti x, y;
x[0] = 9;
M_MOVE_A1_DEFAULT(y, x);
M_COPY_A1_DEFAULT(y, x);
assert(y[0] == 9);
assert(x[0] == 0);
x[0] = 9;
f_ti(x);
assert(x[0] == 0);
ts y2, x2 = { 2, 3};
M_MOVE_DEFAULT(y2, x2);
M_SET_DEFAULT(y2, x2);
assert(y2.b == 2 && y2.c == 3);
assert(x2.b == 0 && x2.c == 0);
x2.b = 2; x2.c = 3;
f_ts(x2);
@@ -812,8 +801,6 @@ static void test_move_default(void)
assert(x2.c == 3);
f_ts2(&x2);
assert(x2.b == 0);
assert(x2.c == 0);
}
static void test_builtin(void)
+1 -1
View File
@@ -35,7 +35,7 @@ END_COVERAGE
DEQUE_DEF(deque_mpz, testobj_t, TESTOBJ_OPLIST)
// Deque with the minimum number of methods.
DEQUE_DEF(deque_min_z, testobj_t, (INIT_SET(testobj_init_set), SET(testobj_set), CLEAR(testobj_clear)))
DEQUE_DEF(deque_min_z, testobj_t, (INIT_SET(testobj_init_set), SET(testobj_set), CLEAR(testobj_clear), INIT_MOVE(M_COPY_A1_DEFAULT) ))
// Dequeue of an enumerate
typedef enum {
+2 -2
View File
@@ -35,8 +35,8 @@ LIST_DUAL_PUSH_DEF(list2_mpz, testobj_t, TESTOBJ_OPLIST)
#define LIST2_DOUBLE_OPLIST LIST_OPLIST(list2_double)
// Array with the minimum number of methods.
LIST_DEF(list_min_z, testobj_t, (INIT_SET(testobj_init_set), SET(testobj_set), CLEAR(testobj_clear)))
LIST_DUAL_PUSH_DEF(list2_min_z, testobj_t, (INIT_SET(testobj_init_set), SET(testobj_set), CLEAR(testobj_clear)))
LIST_DEF(list_min_z, testobj_t, (INIT_SET(testobj_init_set), SET(testobj_set), CLEAR(testobj_clear), INIT_MOVE(M_COPY_A1_DEFAULT) ))
LIST_DUAL_PUSH_DEF(list2_min_z, testobj_t, (INIT_SET(testobj_init_set), SET(testobj_set), CLEAR(testobj_clear), INIT_MOVE(M_COPY_A1_DEFAULT)))
LIST_DEF(list_string, string_t)
#define M_OPL_list_string_t() LIST_OPLIST(list_string, STRING_OPLIST)
-5
View File
@@ -295,31 +295,26 @@ static void test_basic(void)
tree_move_up(it2, &data);
tree_get_str(s, t, false);
assert(string_equal_str_p(s, "[{0,[{-1,[{3}]},{10,[{2,[{1,[{5}]}]}]}]}]"));
assert(data == 0);
data = 11;
tree_move_left(it2, &data);
tree_get_str(s, t, false);
assert(string_equal_str_p(s, "[{0,[{-1,[{3}]},{10,[{11},{2,[{1,[{5}]}]}]}]}]"));
assert(data == 0);
data = 12;
tree_move_right(it2, &data);
tree_get_str(s, t, false);
assert(string_equal_str_p(s, "[{0,[{-1,[{3}]},{10,[{11},{2,[{1,[{5}]}]},{12}]}]}]"));
assert(data == 0);
data = 13;
tree_move_child(it2, &data);
tree_get_str(s, t, false);
assert(string_equal_str_p(s, "[{0,[{-1,[{3}]},{10,[{11},{2,[{13},{1,[{5}]}]},{12}]}]}]"));
assert(data == 0);
data = 14;
tree_move_down(it2, &data);
tree_get_str(s, t, false);
assert(string_equal_str_p(s, "[{0,[{-1,[{3}]},{10,[{11},{2,[{14,[{13},{1,[{5}]}]}]},{12}]}]}]"));
assert(data == 0);
tree_it_set(&it, root);
assert(tree_it_equal_p(it, root));
+1
View File
@@ -236,6 +236,7 @@ static inline size_t test_obj_except__hash(const test_obj_except__t z)
INIT_SET(test_obj_except__init_set), \
SET(test_obj_except__set), \
CLEAR(test_obj_except__clear), \
INIT_MOVE(M_COPY_A1_DEFAULT), \
TYPE(test_obj_except__t), \
ADD(test_obj_except__add), \
OUT_STR(test_obj_except__out_str), \
+4 -2
View File
@@ -227,11 +227,12 @@ static inline void testobj_str(string_t str, const testobj_t z, bool append)
// This enables testing good macro expansion in OPLIST usage
#define testobj_clear_indirect(op, x) testobj_clear(x)
#define TESTOBJ_OPLIST \
#define TESTOBJ_OPLIST \
(INIT(testobj_init), \
INIT_SET(testobj_init_set), \
SET(testobj_set), \
CLEAR(API_1(testobj_clear_indirect)), \
INIT_MOVE(M_COPY_A1_DEFAULT), \
TYPE(testobj_t), \
OUT_STR(testobj_out_str), \
IN_STR(testobj_in_str), \
@@ -242,11 +243,12 @@ static inline void testobj_str(string_t str, const testobj_t z, bool append)
EMPLACE_TYPE( LIST( (_ui, testobj_init_set_ui, unsigned int), (_str, testobj_init_set_str, const char *), ( /*empty*/, testobj_init_set, testobj_t) ) ) \
)
#define TESTOBJ_CMP_OPLIST \
#define TESTOBJ_CMP_OPLIST \
(INIT(testobj_init), \
INIT_SET(testobj_init_set), \
SET(testobj_set), \
CLEAR(testobj_clear), \
INIT_MOVE(M_COPY_A1_DEFAULT), \
TYPE(testobj_t), \
OUT_STR(testobj_out_str), \
IN_STR(testobj_in_str), \