Skip to content

Commit

Permalink
Add support of INITçWITH for variant
Browse files Browse the repository at this point in the history
in C11 / provided all types of the variant are exclusive.
  • Loading branch information
P-p-H-d committed May 15, 2024
1 parent 4549f4a commit 1ae904d
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 3 deletions.
46 changes: 43 additions & 3 deletions m-variant.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,17 @@
typedef struct M_F(name, _s) *M_F(name, _ptr); \
typedef const struct M_F(name, _s) *M_F(name, _srcptr); \
/* Define internal type for oplist */ \
typedef name_t M_F(name, _ct);
typedef name_t M_F(name, _ct); \
/* Save alias for the types of arguments */ \
M_MAP3(M_VAR1ANT_DEFINE_GENTYPE_ELE, name, __VA_ARGS__)

#define M_VAR1ANT_DEFINE_GENTYPE_ELE(name, num, a) \
typedef \
M_IF_METHOD(GENTYPE, M_VAR1ANT_GET_OPLIST a)( M_GET_GENTYPE M_VAR1ANT_GET_OPLIST a, M_VAR1ANT_GET_TYPE a) \
M_C4(m_var1ant_, name, _gentype_, num); \
typedef const \
M_IF_METHOD(GENTYPE, M_VAR1ANT_GET_OPLIST a)( M_GET_GENTYPE M_VAR1ANT_GET_OPLIST a, M_VAR1ANT_GET_TYPE a) \
M_C4(m_var1ant_, name, _const_gentype_, num);

#define M_VAR1ANT_DEFINE_UNION_ELE(name, a) \
, M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value)
Expand Down Expand Up @@ -312,15 +322,22 @@

/* Define the INIT_SET of a given type function. */
#define M_VAR1ANT_DEFINE_INIT_SETTER_FIELD(name, ...) \
M_MAP2(M_VAR1ANT_DEFINE_INIT_SETTER_FIELD_FUNC, name, __VA_ARGS__)
M_MAP3(M_VAR1ANT_DEFINE_INIT_SETTER_FIELD_FUNC, name, __VA_ARGS__)

#define M_VAR1ANT_DEFINE_INIT_SETTER_FIELD_FUNC(name, a) \
#define M_VAR1ANT_DEFINE_INIT_SETTER_FIELD_FUNC(name, num, a) \
M_INLINE void \
M_C3(name, _init_set_, M_VAR1ANT_GET_FIELD a)(M_F(name,_ct) my, \
M_VAR1ANT_GET_TYPE a const M_VAR1ANT_GET_FIELD a ) { \
my->type = M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value); \
M_VAR1ANT_CALL_INIT_SET(a, my -> value. M_VAR1ANT_GET_FIELD a, \
M_VAR1ANT_GET_FIELD a); \
} \
M_INLINE void \
M_C4(m_var1ant_, name, _init_set_, num)(M_F(name,_ct) my, \
M_VAR1ANT_GET_TYPE a const M_VAR1ANT_GET_FIELD a ) { \
my->type = M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value); \
M_VAR1ANT_CALL_INIT_SET(a, my -> value. M_VAR1ANT_GET_FIELD a, \
M_VAR1ANT_GET_FIELD a); \
}


Expand Down Expand Up @@ -763,6 +780,8 @@ M_INLINE void \
NAME(name), \
TYPE(M_F(name,_ct)), GENTYPE(struct M_F(name,_s)*), \
EMPTY_P(M_F(name,_empty_p)), \
SIZE( M_NARGS(__VA_ARGS__) ), \
INIT_WITH( API_1(M_VAR1ANT_INIT_WITH) ), \
M_IF_METHOD_ALL(HASH, __VA_ARGS__)(HASH(M_F(name, _hash)),), \
M_IF_METHOD_ALL(EQUAL, __VA_ARGS__)(EQUAL(M_F(name, _equal_p)),), \
M_IF_METHOD_ALL(GET_STR, __VA_ARGS__)(GET_STR(M_F(name, _get_str)),), \
Expand Down Expand Up @@ -797,6 +816,27 @@ M_INLINE void \

/********************************** INTERNAL *********************************/

/* INIT_WITH macro using _Generic
Expand as:
_Generic ( (x),
M_C4(m_var1ant_, name, _gentype_, num) : M_C4(m_var1ant_, name, _init_set_, num)(x, M_AS_TYPE() ),
...
)
*/
#define M_VAR1ANT_INIT_WITH(oplist, dest, src) \
M_VAR1ANT_INIT_WITH_B(M_GET_NAME oplist, M_GET_SIZE oplist, dest, src)
#define M_VAR1ANT_INIT_WITH_B(name, num, dest, src) \
_Generic( (src), \
M_MAP2(M_VAR1ANT_INIT_WITH_FUNC, (name,dest,src), M_SEQ(1, num)) \
struct m_var1ant_dummy_s *: abort() )
#define M_VAR1ANT_INIT_WITH_FUNC(triplet, num) \
M_VAR1ANT_INIT_WITH_FUNC_EXPAND(M_TRIPLE_1 triplet, M_TRIPLE_2 triplet, M_TRIPLE_3 triplet, num)
#define M_VAR1ANT_INIT_WITH_FUNC_EXPAND(name, dest, src, num) \
M_C4(m_var1ant_, name, _gentype_, num) : M_C4(m_var1ant_, name, _init_set_, num)(dest, M_AS_TYPE(M_C4(m_var1ant_, name, _gentype_, num), src) ), \
M_C4(m_var1ant_, name, _const_gentype_, num): M_C4(m_var1ant_, name, _init_set_, num)(dest, M_AS_TYPE(M_C4(m_var1ant_, name, _const_gentype_, num), src) ),

/********************************** INTERNAL *********************************/

#if M_USE_SMALL_NAME
#define VARIANT_DEF2 M_VARIANT_DEF2
#define VARIANT_DEF2_AS M_VARIANT_DEF2_AS
Expand Down
10 changes: 10 additions & 0 deletions tests/test-mvariant.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,16 @@ static void test_double (void)
M_LET(v, Vector) {
assert (vector_empty_p(v) );
}
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
M_LET( (r, (2)), rvariant2_t) {
assert( rvariant2_value_p(r));
assert( *rvariant2_get_value(r) == 2);
}
M_LET( (r, (M_STRING_CTE("Hello"))), rvariant2_t) {
assert( rvariant2_name_p(r));
assert( string_equal_str_p(*rvariant2_get_name(r), "Hello"));
}
#endif
}

int main(void)
Expand Down

0 comments on commit 1ae904d

Please sign in to comment.