summaryrefslogtreecommitdiff
path: root/libmisc/include/libmisc/private.h
blob: 0eb8c42e4d9e29a78eedb10c66c90338171d3a79 (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
/* libmisc/private.h - Utilities to hide struct fields
 *
 * Copyright (C) 2024  Luke T. Shumaker <lukeshu@lukeshu.com>
 * SPDX-License-Identifier: AGPL-3.0-or-later
 */

#ifndef _LIBMISC_CPPUTIL_H_
#define _LIBMISC_CPPUTIL_H_

/* primitive utilities */

#define _SECOND(a, b, ...) b

#define _CAT(a, b) a ## b
#define _CAT2(a, b) _CAT(a, b)
#define _EAT(...)
#define _EXPAND(...) __VA_ARGS__

/* conditionals */

#define _T xxTxx
#define _F xxFxx

#define _SENTINEL() bogus, _T /* a magic sentinel value */
#define _IS_SENTINEL(...) _SECOND(__VA_ARGS__, _F)

#define _IF(cond) _CAT(_IF__, cond) /* _IF(cond)(then)(else) */
#define _IF__xxTxx(...) __VA_ARGS__ _EAT
#define _IF__xxFxx(...) _EXPAND

/* high-level functionality */

#define YES _SENTINEL()
#define BEGIN_PRIVATE(name) _IF(_IS_SENTINEL(IMPLEMENTATION_FOR_##name))()(struct {)
#define END_PRIVATE(name)   _IF(_IS_SENTINEL(IMPLEMENTATION_FOR_##name))()(} _CAT2(_HIDDEN_, __COUNTER__);)

#endif /* _LIBMISC_CPPUTIL_H_ */