reactor-c
C Runtime for Lingua Franca
Loading...
Searching...
No Matches
reaction_macros.h
Go to the documentation of this file.
1
27// Prevent inclusion twice in a row without an intervening inclusion of reaction_macros_undef.h.
28#ifndef REACTION_MACROS_H
29#define REACTION_MACROS_H
30
31// NOTE: According to the "Swallowing the Semicolon" section on this page:
32// https://gcc.gnu.org/onlinedocs/gcc-3.0.1/cpp_3.html
33// some of the following macros should use an odd do-while construct to avoid
34// problems with if ... else statements that do not use braces around the
35// two branches. Specifically, if the macro expands to more than one statement,
36// then the odd construct is needed.
37
48#define lf_set_present(out) lf_set_present((lf_port_base_t*)out)
49
72#define lf_set(out, val) \
73 do { \
74 out->value = val; \
75 lf_set_present(out); \
76 if (((token_template_t*)out)->token != NULL) { \
77 /* The cast "*((void**) &out->value)" is a hack to make the code */ \
78 /* compile with non-token types where value is not a pointer. */ \
79 lf_token_t* token = _lf_initialize_token_with_value((token_template_t*)out, *((void**)&out->value), 1); \
80 } \
81 } while (0)
82
95#ifndef __cplusplus
96#define lf_set_array(out, val, len) \
97 do { \
98 lf_set_present(out); \
99 lf_token_t* token = _lf_initialize_token_with_value((token_template_t*)out, val, len); \
100 out->value = token->value; \
101 out->length = len; \
102 } while (0)
103#else
104#define lf_set_array(out, val, len) \
105 do { \
106 lf_set_present(out); \
107 lf_token_t* token = _lf_initialize_token_with_value((token_template_t*)out, val, len); \
108 out->value = static_cast<decltype(out->value)>(token->value); \
109 out->length = len; \
110 } while (0)
111#endif
112
123#ifndef __cplusplus
124#define lf_set_token(out, newtoken) \
125 do { \
126 lf_set_present(out); \
127 _lf_replace_template_token((token_template_t*)out, newtoken); \
128 out->value = newtoken->value; \
129 out->length = newtoken->length; \
130 } while (0)
131#else
132#define lf_set_token(out, newtoken) \
133 do { \
134 lf_set_present(out); \
135 _lf_replace_template_token((token_template_t*)out, newtoken); \
136 out->value = static_cast<decltype(out->value)>(newtoken->value); \
137 out->length = newtoken->length; \
138 } while (0)
139#endif
140
151#define lf_set_destructor(out, dtor) ((token_type_t*)out)->destructor = dtor
152
163#define lf_set_copy_constructor(out, cpy_ctor) ((token_type_t*)out)->copy_constructor = cpy_ctor
164
165#ifdef MODAL_REACTORS
166
174#define lf_set_mode(mode) _LF_SET_MODE_WITH_TYPE(mode, _lf_##mode##_change_type)
175
176#endif // MODAL_REACTORS
177
179// For simplicity and backward compatability, don't require the environment-pointer when calling the timing API.
180// As long as this is done from the context of a reaction, `self` is in scope and is a pointer to the self-struct
181// of the current reactor.
182
186#define lf_tag() lf_tag(self->base.environment)
187
191#define lf_time_logical() lf_time_logical(self->base.environment)
192
197#define lf_time_logical_elapsed() lf_time_logical_elapsed(self->base.environment)
198
199#endif // REACTION_MACROS_H