Skip to content

Instantly share code, notes, and snippets.

@kbauer
Last active February 19, 2016 15:42
Show Gist options
  • Save kbauer/d651bae52ab2f72b8d1e to your computer and use it in GitHub Desktop.
Save kbauer/d651bae52ab2f72b8d1e to your computer and use it in GitHub Desktop.
A C preprocessor macro that allows executing code depending on the number of arguments in `__VA_ARGS__`. Test with `gcc -std=c99 -E`. Original version of an `_IFEMPTY` macro was discarded because it depended on the GCC extension syntax `## __VA_ARGS__`.
/// Usage: _ISONEARG() -> 1
/// _ISONEARG(A) -> 1
/// _ISONEARG(A,B,...) -> 0
///
/// Alternative to _IFEMPTY, that works with standard C.
/// Works for up to 100 arguments.
///
/// Examples:
///
/// "_ISONEARG()" -> 1
/// "_ISONEARG(1)" -> 1
/// "_ISONEARG(1,2)" -> 0
/// "_IFONEARG(then, else)" -> then
/// "_IFONEARG(then, else, 1)" -> then
/// "_IFONEARG(then, else, 1, 2)" -> else
///
/// Implementation Notes:
///
/// - The _IFONEARG_PROTECT mechanism was implemented to allow
/// constructs like _IFONEARG(M(),...) where M() expands
/// to something containing a comma (,).
#define _ISONEARG(...) _ISONEARG_(__VA_ARGS__,\
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1)
#define _ISONEARG_( \
_001,_002,_003,_004,_005,_006,_007,_008,_009,_010, \
_011,_012,_013,_014,_015,_016,_017,_018,_019,_020, \
_021,_022,_023,_024,_025,_026,_027,_028,_029,_030, \
_031,_032,_033,_034,_035,_036,_037,_038,_039,_040, \
_041,_042,_043,_044,_045,_046,_047,_048,_049,_050, \
_051,_052,_053,_054,_055,_056,_057,_058,_059,_060, \
_061,_062,_063,_064,_065,_066,_067,_068,_069,_070, \
_071,_072,_073,_074,_075,_076,_077,_078,_079,_080, \
_081,_082,_083,_084,_085,_086,_087,_088,_089,_090, \
_091,_092,_093,_094,_095,_096,_097,_098,_099,_100, \
N,...) N
#define _IFONEARG_PROTECT(...) __VA_ARGS__
#define _IFONEARG(T,E,...)\
_IFONEARG_C2(_IFONEARG_IFTHEN_,_ISONEARG(__VA_ARGS__))\
(_IFONEARG_PROTECT(T),_IFONEARG_PROTECT(E))
#define _IFONEARG_C2(A,B) _IFONEARG_C2_(A,B)
#define _IFONEARG_C2_(A,B) A ## B
#define _IFONEARG_IFTHEN_0(T,E) E
#define _IFONEARG_IFTHEN_1(T,E) T
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment