diff options
| -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 | 
