# define NDEBUG_LOCATION_NONNULL(_num) (_num)
#endif
+/** Check if a given variable is the _const or not
+ *
+ * @param[in] _type The base type of the variable (should not be marked const)
+ * @param[in] _var to check.
+ */
+#define IS_CONST(_type, _var) \
+ _Generic((_var), \
+ _type: false, \
+ const _type: true \
+ )
+
+/** Check if a given variable is the const or unconst version of a type
+ *
+ * Expands to _var if _var matches type, otherwise throws a compiler error.
+ *
+ * Useful for creating typesafe wrapper macros around functions which take
+ * void *s.
+ *
+ * @param[in] _type The base type of the variable (should not be marked const)
+ * @param[in] _var to check.
+ */
+#define IS_TYPE(_type, _var) \
+ _Generic((_var), \
+ _type: _var, \
+ const _type: _var \
+ )
/*
* Mark variables as unused
*/
* in the current list.
* - The first item returned by the iterator.
*/
-#define fr_dcursor_iter_mod_init(_cursor, _head, _iter, _iter_uctx, _insert, _remove, _mod_uctx) \
+#define fr_dcursor_iter_mod_init(_cursor, _list, _iter, _iter_uctx, _insert, _remove, _mod_uctx) \
_fr_dcursor_init(_cursor, \
- _head, \
+ _list, \
_iter, \
_iter_uctx, \
_insert, \
_remove, \
_mod_uctx, \
- _Generic((_head), \
- fr_dlist_head_t * : false, \
- fr_dlist_head_t const * : true \
- ))
+ IS_CONST(fr_dlist_head_t *, _head))
/** Initialise a cursor with a custom iterator
*
NULL, \
NULL, \
NULL, \
- _Generic((_head), \
- fr_dlist_head_t * : false, \
- fr_dlist_head_t const * : true \
- ))
+ IS_CONST(fr_dlist_head_t *, _head))
/** Initialise a cursor
*
NULL, \
NULL, \
NULL, \
- _Generic((_head), \
- fr_dlist_head_t * : false, \
- fr_dlist_head_t const * : true \
- ))
+ IS_CONST(fr_dlist_head_t *, _head))
/** Setup a cursor to iterate over attribute items in dlists
*
_list, \
_iter, \
_uctx, \
- _Generic((_list), \
- fr_pair_list_t * : false, \
- fr_pair_list_t const * : true \
- ))
+ IS_CONST(fr_pair_list_t *, _list))
fr_pair_t *_fr_pair_dcursor_iter_init(fr_dcursor_t *cursor, fr_pair_list_t const *list,
fr_dcursor_iter_t iter, void const *uctx,
bool is_const) CC_HINT(nonnull);
#define fr_pair_dcursor_init(_cursor, _list) \
_fr_pair_dcursor_init(_cursor, \
_list, \
- _Generic((_list), \
- fr_pair_list_t * : false, \
- fr_pair_list_t const * : true \
- ))
+ IS_CONST(fr_pair_list_t *, _list))
fr_pair_t *_fr_pair_dcursor_init(fr_dcursor_t *cursor, fr_pair_list_t const *list,
bool is_const) CC_HINT(nonnull);
_fr_pair_dcursor_by_da_init(_cursor, \
_list, \
_da, \
- _Generic((_list), \
- fr_pair_list_t * : false, \
- fr_pair_list_t const * : true \
- ))
+ IS_CONST(fr_pair_list_t *, _list))
fr_pair_t *_fr_pair_dcursor_by_da_init(fr_dcursor_t *cursor,
fr_pair_list_t const *list, fr_dict_attr_t const *da,
bool is_const) CC_HINT(nonnull);
_fr_pair_dcursor_by_ancestor_init(_cursor, \
_list, \
_da, \
- _Generic((_list), \
- fr_pair_list_t * : false, \
- fr_pair_list_t const * : true \
- ))
+ IS_CONST(fr_pair_list_t *, _list))
fr_pair_t *_fr_pair_dcursor_by_ancestor_init(fr_dcursor_t *cursor,
fr_pair_list_t const *list, fr_dict_attr_t const *da,
bool is_const) CC_HINT(nonnull);
char const * : (char const *)(_len_or_end) \
), \
.p_i = _start, \
- .is_const = _Generic((_start), \
- char * : false, \
- char const * : true \
- ) \
+ .is_const = IS_CONST(char *, _start) \
})
/** Creates a compound literal to pass into functions which accept a sbuff
char const * : (char const *)(_len_or_end) \
), \
.p_i = _start, \
- .is_const = _Generic((_start), \
- char * : false, \
- char const * : true \
- ) \
+ .is_const = IS_CONST(char *, _start) \
})
char * : (char const *)(_len_or_end), \
char const * : (char const *)(_len_or_end) \
), \
-_Generic((_start), \
- char * : false, \
- char const * : true \
-))
+IS_CONST(char *, _start))
/** Initialise a special sbuff which automatically reads in more data as the buffer is exhausted
*