blob: 30576f579806134153350d3e18ad3fab5781997a (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
/* SPDX-License-Identifier: MIT */
/**
* optional.h - Macros for optional types
*
* Copyright (C) 2023 Yaroslav de la Peña Smirnov
*
* 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
#define OPTIONAL_H
#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.
*/
#define OPTIONAL(T) struct __OPTIONAL_##T
/**
* OPTNONE - initialize an OPTIONAL object to hold nothing.
*/
#define OPTNONE { .has = false }
/**
* OPTSOME - initialize an OPTIONAL object to hold something.
* @d: data to hold.
*/
#define OPTSOME(d) { .has = true, .data = d }
/**
* opt_set_none - set an OPTIONAL object to hold nothing.
* @opt: OPTIONAL object.
*/
#define opt_set_none(opt) opt.has = false
/**
* opt_set_some - set an OPTIONAL object to hold something.
* @opt: OPTIONAL object.
* @d: data to hold.
*/
#define opt_set_some(opt, 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)
/**
* opt_hasnt - true if an OPTIONAL object has nothing.
* @opt: OPTIONAL object.
*/
#define opt_hasnt(opt) (!(opt).has)
/**
* opt_unwrap - if there's something in @src, copy it to @dst.
* @src: OPTIONAL object to copy data of type T from.
* @dst: variable of type T to copy to.
*
* 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_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
#endif
|