diff options
Diffstat (limited to 'optional.h')
-rw-r--r-- | optional.h | 31 |
1 files changed, 22 insertions, 9 deletions
@@ -1,10 +1,18 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: MIT */ /** * optional.h - Macros for optional types * * Copyright (C) 2023 Yaroslav de la Peña Smirnov * - * Poor man's optional "type templates" for C + * Documentation + * ============= + * + * Poor man's optional "type templates" for C. + * + * An object of optional type is an object that may or may not hold an object of + * a certain type inside itself at any time. Before declaring a variable of a + * certain OPTIONAL type, said OPTIONAL type should be declared with the + * OPTIONALDEC macro. */ #ifndef OPTIONAL_H @@ -13,11 +21,16 @@ #include <stdbool.h> /** + * OPTIONALDEC - declare OPTIONAL type that holds data of type @T + * @T: the type of data to hold. + */ +#define OPTIONALDEC(T) struct __OPTIONAL_##T { bool has; T data; } + +/** * OPTIONAL - declare an object that optionally holds type @T * @T: the type of data to hold. - * @name: the name of the variable or struct field. */ -#define OPTIONAL(T, name) struct { bool has; T data; } name +#define OPTIONAL(T) struct __OPTIONAL_##T /** * OPTNONE - initialize an OPTIONAL object to hold nothing. @@ -42,19 +55,19 @@ * @d: data to hold. */ #define opt_set_some(opt, d) \ - (opt.has = true, opt.data = d) + ((opt).has = true, (opt).data = d) /** * opt_has - true if an OPTIONAL object has something. * @opt: OPTIONAL object. */ -#define opt_has(opt) (opt.has) +#define opt_has(opt) ((opt).has) /** * opt_hasnt - true if an OPTIONAL object has nothing. * @opt: OPTIONAL object. */ -#define opt_hasnt(opt) (!opt.has) +#define opt_hasnt(opt) (!(opt).has) /** * opt_unwrap - if there's something in @src, copy it to @dst. @@ -64,13 +77,13 @@ * Returns true if there was something, false if there wasn't. */ #define opt_unwrap(src, dst) \ - (opt_has(src) ? (dst = src.data, true) : (false)) + (opt_has(src) ? (dst = (src).data, true) : (false)) /** * opt_default - get something from @src or default to @def. * @src: OPTIONAL object to get data from. * @def: default value if there's nothing. */ -#define opt_default(src, def) opt_has(src) ? src.data : def +#define opt_default(src, def) opt_has(src) ? (src).data : def #endif |