util: add name lookup to tristate handling

And make it more obvious that _val isn't something you should access directly.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer 2020-08-11 11:06:34 +10:00
parent b717837b14
commit 2a98906b32

View file

@ -65,7 +65,7 @@
#include <stdbool.h>
typedef struct {
unsigned val;
unsigned _val;
} tristate;
/* Implementation detail:
@ -81,7 +81,7 @@ static const unsigned _TRISTATE_TYPE_MASK = ~0x3;
/* implementation detail, ignore */
static inline void _tristate_check_type(const tristate *t1, unsigned type) {
assert((t1->val & _TRISTATE_TYPE_MASK) == type || !"Invalid tristate type comparison");
assert((t1->_val & _TRISTATE_TYPE_MASK) == type || !"Invalid tristate type comparison");
}
/**
@ -107,24 +107,30 @@ static inline void _tristate_check_type(const tristate *t1, unsigned type) {
static const unsigned tristate_val_##_on = _TRISTATE_TYPE_##_on##_off | 3; \
static const unsigned tristate_val_##_off = _TRISTATE_TYPE_##_on##_off | 2; \
static const unsigned tristate_val_##_none = _TRISTATE_TYPE_##_on##_off | 0; \
static const tristate tristate_##_on = { .val = tristate_val_##_on }; \
static const tristate tristate_##_off = { .val = tristate_val_##_off }; \
static const tristate tristate_##_none = { .val = tristate_val_##_none }; \
static const tristate tristate_##_on = { ._val = tristate_val_##_on }; \
static const tristate tristate_##_off = { ._val = tristate_val_##_off }; \
static const tristate tristate_##_none = { ._val = tristate_val_##_none }; \
static inline bool tristate_is_##_on(tristate t) { \
_tristate_check_type(&t, _TRISTATE_TYPE_##_on##_off); \
return t.val == tristate_##_on.val; \
return t._val == tristate_##_on._val; \
} \
static inline bool tristate_is_##_off(tristate t) { \
_tristate_check_type(&t, _TRISTATE_TYPE_##_on##_off); \
return t.val == tristate_##_off.val; \
return t._val == tristate_##_off._val; \
} \
static inline bool tristate_is_##_none(tristate t) { \
_tristate_check_type(&t, _TRISTATE_TYPE_##_on##_off); \
return t.val == tristate_##_none.val; \
return t._val == tristate_##_none._val; \
} \
static inline signed char tristate_##_on##_off_value(tristate t) { \
static inline signed char tristate_##_on##_off##_value(tristate t) { \
_tristate_check_type(&t, _TRISTATE_TYPE_##_on##_off); \
return t.val; \
return t._val; \
} \
static inline const char *tristate_##_on##_off##_name(tristate t) { \
if (tristate_is_##_on(t)) return #_on; \
if (tristate_is_##_off(t)) return #_off; \
if (tristate_is_##_none(t)) return #_none; \
assert(!"Invalid tristate value"); \
} \
struct __useless_struct_to_allow_trailing_semicolon__