mirror of
https://github.com/fmtlib/fmt.git
synced 2026-04-30 19:09:22 +08:00
Replace the dummy arg from compound initializers in the C API with more macro magic (#4696)
The dummy argument {fmt_int} was there as a workaround for MSVC and to
avoid needing to rely on another GCC extension for zero-size arrays. Use
macro magic similar to FMT_NARG() instead that replaces the problematic
zero-size array with NULL.
In order to avoid a quadratic number of expansions, defer creating the
mapped argument list until after selection of whether to use NULL or
the fmt_arg array.
Signed-off-by: Ferdinand Bachmann <ferdinand.bachmann@yrlf.at>
This commit is contained in:
parent
ab4f661521
commit
eb03303099
@ -130,7 +130,7 @@ typedef enum {} fmt_signed_char;
|
||||
# define FMT_NARG_(_id, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, \
|
||||
_13, _14, _15, _16, N, ...) \
|
||||
N
|
||||
# define FMT_NARG(...) \
|
||||
# define FMT_NARG(_dummy, ...) \
|
||||
FMT_NARG_(dummy, ##__VA_ARGS__, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, \
|
||||
4, 3, 2, 1, 0)
|
||||
|
||||
@ -166,13 +166,24 @@ typedef enum {} fmt_signed_char;
|
||||
f(n), f(o), f(p), f(q)
|
||||
|
||||
# define FMT_MAP(f, ...) \
|
||||
FMT_CAT(FMT_MAP_, FMT_NARG(__VA_ARGS__))(f, ##__VA_ARGS__)
|
||||
FMT_CAT(FMT_MAP_, FMT_NARG(, ##__VA_ARGS__))(f, ##__VA_ARGS__)
|
||||
|
||||
// select between two expressions depending on whether __VA_ARGS__ is empty
|
||||
// expands to e if __VA_ARGS__ is empty and n otherwise
|
||||
# define FMT_VA_SELECT(e, n, ...) \
|
||||
FMT_NARG_(dummy, ##__VA_ARGS__, n, n, n, n, n, n, n, n, n, n, n, n, n, n, \
|
||||
n, n, e)
|
||||
|
||||
# define FMT_MAKE_NULL(...) NULL
|
||||
# define FMT_MAKE_ARGLIST(...) \
|
||||
(fmt_arg[]) { FMT_MAP(FMT_MAKE_ARG, ##__VA_ARGS__) }
|
||||
# define FMT_EXPAND(v) v
|
||||
|
||||
# define fmt_format(buffer, size, fmt, ...) \
|
||||
fmt_vformat( \
|
||||
(buffer), (size), (fmt), \
|
||||
(fmt_arg[]){{fmt_int}, FMT_MAP(FMT_MAKE_ARG, ##__VA_ARGS__)} + 1, \
|
||||
FMT_NARG(__VA_ARGS__))
|
||||
fmt_vformat((buffer), (size), (fmt), \
|
||||
FMT_EXPAND(FMT_VA_SELECT(FMT_MAKE_NULL, FMT_MAKE_ARGLIST, \
|
||||
##__VA_ARGS__)(__VA_ARGS__)), \
|
||||
FMT_NARG(, ##__VA_ARGS__))
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user