file Utils/util_macros.hpp
[No description available] More…
Defines
Name | |
---|---|
FAIL(x) | |
APPEND_TOKEN(s, data, elem) | |
DUMMY | |
DUMMYARG(…) | |
FIRST_ARG(A1, …) | |
REMFIRST(…) | |
REMFIRST_I(A1, …) | |
APPLY(macro, args) | |
APPLY_I(macro, args) | |
STRIP_PARENS(x) | |
STRIP_PARENS_I(…) | |
EVAL_PAR(test, x) | |
EVAL_PAR_I(test, x) | |
TEST_ARITY(…) | |
TEST_ARITY_I(a, b, c, …) | |
MAYBE_STRIP_PARENS(cond, x) | |
MAYBE_STRIP_PARENS_I(cond, x) | |
MAYBE_STRIP_PARENS_1(x) | |
MAYBE_STRIP_PARENS_2(x) | |
MAYBE_STRIP_PARENS_2_I(…) | |
HAS_PARENS(x) | |
HAS_PARENS_I(…) | |
EVAL_HASP(test, x) | |
EVAL_HASP_I(test, x) | |
CHECK_PARENS(cond, x) | |
CHECK_PARENS_I(cond, x) | |
CHECK_PARENS_1(x) | |
CHECK_PARENS_2(x) | |
_ARG128(_0, _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, _90, _91, _92, _93, _94, _95, _96, _97, _98, _99, _100, _101, _102, _103, _104, _105, _106, _107, _108, _109, _110, _111, _112, _113, _114, _115, _116, _117, _118, _119, _120, _121, _122, _123, _124, _125, _126, _127, …) | |
HAS_COMMA(…) | |
ISEMPTY(ARG) | |
ISEMPTY_I(A) | |
ISEMPTY_II(…) | |
_129ONES() | |
INSERT_NONEMPTY(ARG) | |
INSERT_NONEMPTY_I0(ARG) | |
INSERT_NONEMPTY_I1(…) | |
PAIR_ELEMENT0(TPLE) | |
PAIR_ELEMENT0_I(A, B) | |
PAIR_ELEMENT1(TPLE) | |
PAIR_ELEMENT1_I(A, B) | |
void_void | |
int_int | |
float_float | |
double_double | |
bool_bool | |
char_char | |
string_string | |
ModelParameters_ModelParameters | |
IS_TYPE(COMPTYPE, TYPE) | |
IS_EQUAL(A, B) | |
IF_EQUAL(A, B, C) | |
IF_NOT_EQUAL(A, B, C) | |
IF_ELSE_EQUAL(A, B, C, D) | |
EMPTY_TOKEN_TESTER | |
IS_EMPTY(A) | |
IF_EMPTY(A, B) | |
IF_NOT_EMPTY(A, B) | |
IF_ELSE_EMPTY(A, B, C) | |
VA_NARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, N, …) | |
VA_NARGS(…) | |
VARARG_IMPL2(base, count, …) | |
VARARG_IMPL(base, count, …) | |
VARARG(base, …) | |
VA_NARGS_NESTED_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, N, …) | |
VA_NARGS_NESTED(…) | |
VARARG_NESTED_IMPL2(base, count, …) | |
VARARG_NESTED_IMPL(base, count, …) | |
VARARG_NESTED(base, …) | |
VA_NARGS_AB_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, N, …) | |
VA_NARGS_AB(…) | |
VARARG_AB_IMPL2(base, A, B, count, …) | |
VARARG_AB_IMPL(base, A, B, count, …) | |
VARARG_AB(base, A, B, …) | |
VARARG_SWITCH_ON_GT_ONE_TESTER_1 | |
VA_NARGS_SWITCH_ON_GT_ONE_IMPL(_1, _2, _3, N, …) | |
VA_NARGS_SWITCH_ON_GT_ONE(…) | |
VARARG_SWITCH_ON_GT_ONE_IMPL2(base, count, …) | |
VARARG_SWITCH_ON_GT_ONE_IMPL(base, count, …) | |
VARARG_SWITCH_ON_GT_ONE(base, …) | |
VARARG_SWITCH_ON_GT_ONE_A_TESTER_1 | |
VA_NARGS_SWITCH_ON_GT_ONE_A_IMPL(_1, _2, _3, N, …) | |
VA_NARGS_SWITCH_ON_GT_ONE_A(…) | |
VARARG_SWITCH_ON_GT_ONE_A_IMPL2(base, A, count, …) | |
VARARG_SWITCH_ON_GT_ONE_A_IMPL(base, A, count, …) | |
VARARG_SWITCH_ON_GT_ONE_A(base, A, …) | |
VARARG_SWITCH_ON_GT_ONE_ABC_TESTER_1 | |
VA_NARGS_SWITCH_ON_GT_ONE_ABC_IMPL(_1, _2, _3, N, …) | |
VA_NARGS_SWITCH_ON_GT_ONE_ABC(…) | |
VARARG_SWITCH_ON_GT_ONE_ABC_IMPL2(base, A, B, C, count, …) | |
VARARG_SWITCH_ON_GT_ONE_ABC_IMPL(base, A, B, C, count, …) | |
VARARG_SWITCH_ON_GT_ONE_ABC(base, A, B, C, …) | |
VARARG_SWITCH_ON_GT_TWO_ABC_TESTER_2 | |
VARARG_SWITCH_ON_GT_TWO_ABC_TESTER_1 | |
VA_NARGS_SWITCH_ON_GT_TWO_ABC_IMPL(_1, _2, _3, _4, N, …) | |
VA_NARGS_SWITCH_ON_GT_TWO_ABC(…) | |
VARARG_SWITCH_ON_GT_TWO_ABC_IMPL2(base, A, B, C, count, …) | |
VARARG_SWITCH_ON_GT_TWO_ABC_IMPL(base, A, B, C, count, …) | |
VARARG_SWITCH_ON_GT_TWO_ABC(base, A, B, C, …) | |
CHECK_N(x, n, …) | |
CHECK(…) | |
PROBE(x) | |
DEFINED_PROBE(NAME) | |
DEFINED_PROBE_PROXY(…) | |
DEFINED_PROBE_PRIMITIVE(x) | |
DEFINED_PROBE_COMBINE_(…) | |
DEFINED(NAME) | |
IF_DEFINED(NAME, ACTION) Do ACTION if NAME is defined. | |
IF_NOT_DEFINED(NAME, ACTION) Do ACTION if NAME is undefined. | |
IF_ELSE_DEFINED(NAME, IF, ELSE) Do IF if NAME is defined, otherwise do ELSE. | |
TOKEN_DEFINED(A) | |
IF_TOKEN_DEFINED(A, B) | |
IF_TOKEN_UNDEFINED(A, B) | |
IF_ELSE_TOKEN_DEFINED(A, B, C) | |
DEFINED_MODULE | |
DEFINED_CAPABILITY | |
DEFINED_FUNCTION | |
DEFINED_CONDITIONAL_DEPENDENCY | |
POP_LAST(…) | |
POP_LAST_1(x1) | |
POP_LAST_2(x1, x2) | |
POP_LAST_3(x1, x2, x3) | |
POP_LAST_4(x1, x2, x3, x4) | |
POP_LAST_5(x1, x2, x3, x4, x5) | |
POP_LAST_6(x1, x2, x3, x4, x5, x6) | |
POP_LAST_7(x1, x2, x3, x4, x5, x6, x7) | |
POP_LAST_8(x1, x2, x3, x4, x5, x6, x7, x8) | |
POP_LAST_9(x1, x2, x3, x4, x5, x6, x7, x8, x9) | |
POP_LAST_10(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) | |
etc_etc | |
LAST_ARG_VARIADIC(T) | |
IS_ELLIPSIS(ELEM) | |
STRIP_VARIADIC_ARG(T) | |
CONVERT_VARIADIC_ARG(T) | |
IF_ELSEIF_9(VAR1, _1, VAR2, _2, VAR3, _3, VAR4, _4, _5) | |
IF_ELSEIF_7(VAR1, _1, VAR2, _2, VAR3, _3, _4) | |
IF_ELSEIF_5(VAR1, _1, VAR2, _2, _3) | |
IF_ELSEIF(…) | |
BRACED_INIT_LIST(…) | |
MAKE_STATIC_VECTOR(TYPE, NAME, TUPLE) | |
MAKE_STATIC_SET(TYPE, NAME, TUPLE) | |
CALL_WITH_SILENCED_STDERR(FUNCTION_CALL) |
Detailed Description
Author: Pat Scott (patscott@physics.mcgill.ca)
Date:
- 2013 Apr, Oct
- 2014 Mar
General small utility macros.
Authors:
Macros Documentation
define FAIL
#define FAIL(
x
)
static_assert(false,"GAMBIT precompiler error: " x);
define APPEND_TOKEN
#define APPEND_TOKEN(
s,
data,
elem
)
CAT(elem,data)
define DUMMY
#define DUMMY
define DUMMYARG
#define DUMMYARG(
...
)
define FIRST_ARG
#define FIRST_ARG(
A1,
...
)
A1
define REMFIRST
#define REMFIRST(
...
)
REMFIRST_I(__VA_ARGS__)
define REMFIRST_I
#define REMFIRST_I(
A1,
...
)
(__VA_ARGS__)
define APPLY
#define APPLY(
macro,
args
)
APPLY_I(macro, args)
define APPLY_I
#define APPLY_I(
macro,
args
)
macro args
define STRIP_PARENS
#define STRIP_PARENS(
x
)
EVAL_PAR((STRIP_PARENS_I x), x)
define STRIP_PARENS_I
#define STRIP_PARENS_I(
...
)
1,1
define EVAL_PAR
#define EVAL_PAR(
test,
x
)
EVAL_PAR_I(test, x)
define EVAL_PAR_I
#define EVAL_PAR_I(
test,
x
)
MAYBE_STRIP_PARENS(TEST_ARITY test, x)
define TEST_ARITY
#define TEST_ARITY(
...
)
APPLY(TEST_ARITY_I, (__VA_ARGS__, 2, 1, 0))
define TEST_ARITY_I
#define TEST_ARITY_I(
a,
b,
c,
...
)
c
define MAYBE_STRIP_PARENS
#define MAYBE_STRIP_PARENS(
cond,
x
)
MAYBE_STRIP_PARENS_I(cond, x)
define MAYBE_STRIP_PARENS_I
#define MAYBE_STRIP_PARENS_I(
cond,
x
)
CAT(MAYBE_STRIP_PARENS_, cond)(x)
define MAYBE_STRIP_PARENS_1
#define MAYBE_STRIP_PARENS_1(
x
)
x
define MAYBE_STRIP_PARENS_2
#define MAYBE_STRIP_PARENS_2(
x
)
APPLY(MAYBE_STRIP_PARENS_2_I, x)
define MAYBE_STRIP_PARENS_2_I
#define MAYBE_STRIP_PARENS_2_I(
...
)
__VA_ARGS__
define HAS_PARENS
#define HAS_PARENS(
x
)
EVAL_HASP((HAS_PARENS_I x), x)
define HAS_PARENS_I
#define HAS_PARENS_I(
...
)
1,1
define EVAL_HASP
#define EVAL_HASP(
test,
x
)
EVAL_HASP_I(test, x)
define EVAL_HASP_I
#define EVAL_HASP_I(
test,
x
)
CHECK_PARENS(TEST_ARITY test, x)
define CHECK_PARENS
#define CHECK_PARENS(
cond,
x
)
CHECK_PARENS_I(cond, x)
define CHECK_PARENS_I
#define CHECK_PARENS_I(
cond,
x
)
CAT(CHECK_PARENS_, cond)(x)
define CHECK_PARENS_1
#define CHECK_PARENS_1(
x
)
0
define CHECK_PARENS_2
#define CHECK_PARENS_2(
x
)
1
define _ARG128
#define _ARG128(
_0,
_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,
_90,
_91,
_92,
_93,
_94,
_95,
_96,
_97,
_98,
_99,
_100,
_101,
_102,
_103,
_104,
_105,
_106,
_107,
_108,
_109,
_110,
_111,
_112,
_113,
_114,
_115,
_116,
_117,
_118,
_119,
_120,
_121,
_122,
_123,
_124,
_125,
_126,
_127,
...
)
_127
define HAS_COMMA
#define HAS_COMMA(
...
)
_ARG128(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0)
define ISEMPTY
#define ISEMPTY(
ARG
)
ISEMPTY_I(_129ONES STRIP_PARENS(ARG) ())
define ISEMPTY_I
#define ISEMPTY_I(
A
)
ISEMPTY_II(A,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,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)
define ISEMPTY_II
#define ISEMPTY_II(
...
)
_ARG128(__VA_ARGS__)
define _129ONES
#define _129ONES(
)
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, \
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\
1,1,1,1,1,1,1,1,1,1,1,1
define INSERT_NONEMPTY
#define INSERT_NONEMPTY(
ARG
)
CAT(INSERT_NONEMPTY_I,ISEMPTY(ARG))(ARG)
define INSERT_NONEMPTY_I0
#define INSERT_NONEMPTY_I0(
ARG
)
,STRIP_PARENS(ARG)
define INSERT_NONEMPTY_I1
#define INSERT_NONEMPTY_I1(
...
)
DUMMYARG(__VA_ARGS__)
define PAIR_ELEMENT0
#define PAIR_ELEMENT0(
TPLE
)
PAIR_ELEMENT0_I TPLE
define PAIR_ELEMENT0_I
#define PAIR_ELEMENT0_I(
A,
B
)
A
define PAIR_ELEMENT1
#define PAIR_ELEMENT1(
TPLE
)
PAIR_ELEMENT1_I TPLE
define PAIR_ELEMENT1_I
#define PAIR_ELEMENT1_I(
A,
B
)
B
define void_void
#define void_void 1)(1
define int_int
#define int_int 1)(1
define float_float
#define float_float 1)(1
define double_double
#define double_double 1)(1
define bool_bool
#define bool_bool 1)(1
define char_char
#define char_char 1)(1
define string_string
#define string_string 1)(1
define ModelParameters_ModelParameters
#define ModelParameters_ModelParameters 1)(1
define IS_TYPE
#define IS_TYPE(
COMPTYPE,
TYPE
)
BOOST_PP_EQUAL(BOOST_PP_SEQ_SIZE((CAT_3(COMPTYPE,_,TYPE))),2)
define IS_EQUAL
#define IS_EQUAL(
A,
B
)
IS_TYPE(A,B)
define IF_EQUAL
#define IF_EQUAL(
A,
B,
C
)
BOOST_PP_IIF(IS_EQUAL(A,B),C,)
define IF_NOT_EQUAL
#define IF_NOT_EQUAL(
A,
B,
C
)
BOOST_PP_IIF(IS_EQUAL(A,B), ,C)
define IF_ELSE_EQUAL
#define IF_ELSE_EQUAL(
A,
B,
C,
D
)
BOOST_PP_IIF(IS_EQUAL(A,B),C,D)
define EMPTY_TOKEN_TESTER
#define EMPTY_TOKEN_TESTER 1)(1
define IS_EMPTY
#define IS_EMPTY(
A
)
IS_EQUAL(CAT(A,EMPTY),TOKEN_TESTER)
define IF_EMPTY
#define IF_EMPTY(
A,
B
)
BOOST_PP_IIF(IS_EMPTY(A),B,)
define IF_NOT_EMPTY
#define IF_NOT_EMPTY(
A,
B
)
BOOST_PP_IIF(IS_EMPTY(A), ,B)
define IF_ELSE_EMPTY
#define IF_ELSE_EMPTY(
A,
B,
C
)
BOOST_PP_IIF(IS_EMPTY(A),B,C)
define VA_NARGS_IMPL
#define VA_NARGS_IMPL(
_1,
_2,
_3,
_4,
_5,
_6,
_7,
_8,
_9,
_10,
_11,
N,
...
)
N
define VA_NARGS
#define VA_NARGS(
...
)
VA_NARGS_IMPL(X,__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
define VARARG_IMPL2
#define VARARG_IMPL2(
base,
count,
...
)
CAT_3(base,_,count)(__VA_ARGS__)
define VARARG_IMPL
#define VARARG_IMPL(
base,
count,
...
)
VARARG_IMPL2(base, count, __VA_ARGS__)
define VARARG
#define VARARG(
base,
...
)
VARARG_IMPL(base, VA_NARGS(__VA_ARGS__), __VA_ARGS__)
define VA_NARGS_NESTED_IMPL
#define VA_NARGS_NESTED_IMPL(
_1,
_2,
_3,
_4,
_5,
_6,
_7,
_8,
_9,
_10,
_11,
N,
...
)
N
define VA_NARGS_NESTED
#define VA_NARGS_NESTED(
...
)
VA_NARGS_NESTED_IMPL(X,__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
define VARARG_NESTED_IMPL2
#define VARARG_NESTED_IMPL2(
base,
count,
...
)
CAT_3(base,_,count)(__VA_ARGS__)
define VARARG_NESTED_IMPL
#define VARARG_NESTED_IMPL(
base,
count,
...
)
VARARG_NESTED_IMPL2(base, count, __VA_ARGS__)
define VARARG_NESTED
#define VARARG_NESTED(
base,
...
)
VARARG_NESTED_IMPL(base, VA_NARGS_NESTED(__VA_ARGS__), __VA_ARGS__)
define VA_NARGS_AB_IMPL
#define VA_NARGS_AB_IMPL(
_1,
_2,
_3,
_4,
_5,
_6,
_7,
_8,
_9,
_10,
_11,
N,
...
)
N
define VA_NARGS_AB
#define VA_NARGS_AB(
...
)
VA_NARGS_AB_IMPL(X,__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
define VARARG_AB_IMPL2
#define VARARG_AB_IMPL2(
base,
A,
B,
count,
...
)
CAT_3(base,_,count)(A, B, __VA_ARGS__)
define VARARG_AB_IMPL
#define VARARG_AB_IMPL(
base,
A,
B,
count,
...
)
VARARG_AB_IMPL2(base, A, B, count, __VA_ARGS__)
define VARARG_AB
#define VARARG_AB(
base,
A,
B,
...
)
VARARG_AB_IMPL(base, A, B, VA_NARGS_AB(__VA_ARGS__), __VA_ARGS__)
define VARARG_SWITCH_ON_GT_ONE_TESTER_1
#define VARARG_SWITCH_ON_GT_ONE_TESTER_1 1)(1
define VA_NARGS_SWITCH_ON_GT_ONE_IMPL
#define VA_NARGS_SWITCH_ON_GT_ONE_IMPL(
_1,
_2,
_3,
N,
...
)
IF_ELSE_EQUAL(VARARG_SWITCH_ON_GT_ONE_TESTER,N,N,MORE)
define VA_NARGS_SWITCH_ON_GT_ONE
#define VA_NARGS_SWITCH_ON_GT_ONE(
...
)
VA_NARGS_SWITCH_ON_GT_ONE_IMPL(X,__VA_ARGS__, 2, 1, 0)
define VARARG_SWITCH_ON_GT_ONE_IMPL2
#define VARARG_SWITCH_ON_GT_ONE_IMPL2(
base,
count,
...
)
CAT_3(base,_,count)(__VA_ARGS__)
define VARARG_SWITCH_ON_GT_ONE_IMPL
#define VARARG_SWITCH_ON_GT_ONE_IMPL(
base,
count,
...
)
VARARG_SWITCH_ON_GT_ONE_IMPL2(base, count, __VA_ARGS__)
define VARARG_SWITCH_ON_GT_ONE
#define VARARG_SWITCH_ON_GT_ONE(
base,
...
)
VARARG_SWITCH_ON_GT_ONE_IMPL(base, VA_NARGS_SWITCH_ON_GT_ONE(__VA_ARGS__), __VA_ARGS__)
define VARARG_SWITCH_ON_GT_ONE_A_TESTER_1
#define VARARG_SWITCH_ON_GT_ONE_A_TESTER_1 1)(1
define VA_NARGS_SWITCH_ON_GT_ONE_A_IMPL
#define VA_NARGS_SWITCH_ON_GT_ONE_A_IMPL(
_1,
_2,
_3,
N,
...
)
IF_ELSE_EQUAL(VARARG_SWITCH_ON_GT_ONE_A_TESTER,N,N,MORE)
define VA_NARGS_SWITCH_ON_GT_ONE_A
#define VA_NARGS_SWITCH_ON_GT_ONE_A(
...
)
VA_NARGS_SWITCH_ON_GT_ONE_A_IMPL(X,__VA_ARGS__, 2, 1, 0)
define VARARG_SWITCH_ON_GT_ONE_A_IMPL2
#define VARARG_SWITCH_ON_GT_ONE_A_IMPL2(
base,
A,
count,
...
)
CAT_3(base,_,count)(A, __VA_ARGS__)
define VARARG_SWITCH_ON_GT_ONE_A_IMPL
#define VARARG_SWITCH_ON_GT_ONE_A_IMPL(
base,
A,
count,
...
)
VARARG_SWITCH_ON_GT_ONE_A_IMPL2(base, A, count, __VA_ARGS__)
define VARARG_SWITCH_ON_GT_ONE_A
#define VARARG_SWITCH_ON_GT_ONE_A(
base,
A,
...
)
VARARG_SWITCH_ON_GT_ONE_A_IMPL(base, A, VA_NARGS_SWITCH_ON_GT_ONE_A(__VA_ARGS__), __VA_ARGS__)
define VARARG_SWITCH_ON_GT_ONE_ABC_TESTER_1
#define VARARG_SWITCH_ON_GT_ONE_ABC_TESTER_1 1)(1
define VA_NARGS_SWITCH_ON_GT_ONE_ABC_IMPL
#define VA_NARGS_SWITCH_ON_GT_ONE_ABC_IMPL(
_1,
_2,
_3,
N,
...
)
IF_ELSE_EQUAL(VARARG_SWITCH_ON_GT_ONE_ABC_TESTER,N,N,MORE)
define VA_NARGS_SWITCH_ON_GT_ONE_ABC
#define VA_NARGS_SWITCH_ON_GT_ONE_ABC(
...
)
VA_NARGS_SWITCH_ON_GT_ONE_ABC_IMPL(X,__VA_ARGS__, 2, 1, 0)
define VARARG_SWITCH_ON_GT_ONE_ABC_IMPL2
#define VARARG_SWITCH_ON_GT_ONE_ABC_IMPL2(
base,
A,
B,
C,
count,
...
)
CAT_3(base,_,count)(A, B, C, __VA_ARGS__)
define VARARG_SWITCH_ON_GT_ONE_ABC_IMPL
#define VARARG_SWITCH_ON_GT_ONE_ABC_IMPL(
base,
A,
B,
C,
count,
...
)
VARARG_SWITCH_ON_GT_ONE_ABC_IMPL2(base, A, B, C, count, __VA_ARGS__)
define VARARG_SWITCH_ON_GT_ONE_ABC
#define VARARG_SWITCH_ON_GT_ONE_ABC(
base,
A,
B,
C,
...
)
VARARG_SWITCH_ON_GT_ONE_ABC_IMPL(base, A, B, C, VA_NARGS_SWITCH_ON_GT_ONE_ABC(__VA_ARGS__), __VA_ARGS__)
define VARARG_SWITCH_ON_GT_TWO_ABC_TESTER_2
#define VARARG_SWITCH_ON_GT_TWO_ABC_TESTER_2 1)(1
define VARARG_SWITCH_ON_GT_TWO_ABC_TESTER_1
#define VARARG_SWITCH_ON_GT_TWO_ABC_TESTER_1 1)(1
define VA_NARGS_SWITCH_ON_GT_TWO_ABC_IMPL
#define VA_NARGS_SWITCH_ON_GT_TWO_ABC_IMPL(
_1,
_2,
_3,
_4,
N,
...
)
IF_ELSE_EQUAL(VARARG_SWITCH_ON_GT_TWO_ABC_TESTER,\
BOOST_PP_TUPLE_ELEM(0,(STRIP_PARENS(N))),N,MORE)
define VA_NARGS_SWITCH_ON_GT_TWO_ABC
#define VA_NARGS_SWITCH_ON_GT_TWO_ABC(
...
)
VA_NARGS_SWITCH_ON_GT_TWO_ABC_IMPL(X,__VA_ARGS__, 3, 2, 1, 0)
define VARARG_SWITCH_ON_GT_TWO_ABC_IMPL2
#define VARARG_SWITCH_ON_GT_TWO_ABC_IMPL2(
base,
A,
B,
C,
count,
...
)
CAT_3(base,_,count)(A, B, C, __VA_ARGS__)
define VARARG_SWITCH_ON_GT_TWO_ABC_IMPL
#define VARARG_SWITCH_ON_GT_TWO_ABC_IMPL(
base,
A,
B,
C,
count,
...
)
VARARG_SWITCH_ON_GT_TWO_ABC_IMPL2(base, A, B, C, count, __VA_ARGS__)
define VARARG_SWITCH_ON_GT_TWO_ABC
#define VARARG_SWITCH_ON_GT_TWO_ABC(
base,
A,
B,
C,
...
)
VARARG_SWITCH_ON_GT_TWO_ABC_IMPL(base, A, B, C, VA_NARGS_SWITCH_ON_GT_TWO_ABC(__VA_ARGS__), __VA_ARGS__)
define CHECK_N
#define CHECK_N(
x,
n,
...
)
n
define CHECK
#define CHECK(
...
)
CHECK_N(__VA_ARGS__, 0, 0)
define PROBE
#define PROBE(
x
)
x, 1
define DEFINED_PROBE
#define DEFINED_PROBE(
NAME
)
DEFINED_PROBE_PROXY( DEFINED_##NAME )
define DEFINED_PROBE_PROXY
#define DEFINED_PROBE_PROXY(
...
)
DEFINED_PROBE_PRIMITIVE(__VA_ARGS__)
define DEFINED_PROBE_PRIMITIVE
#define DEFINED_PROBE_PRIMITIVE(
x
)
DEFINED_PROBE_COMBINE_ x
define DEFINED_PROBE_COMBINE_
#define DEFINED_PROBE_COMBINE_(
...
)
PROBE(X)
define DEFINED
#define DEFINED(
NAME
)
CHECK(DEFINED_PROBE(NAME))
Returns 1 or 0 depending on whether a corresponding DEFINED_
#defined
or not.
define IF_DEFINED
#define IF_DEFINED(
NAME,
ACTION
)
BOOST_PP_IF(DEFINED(NAME), ACTION, )
Do ACTION if NAME is defined.
define IF_NOT_DEFINED
#define IF_NOT_DEFINED(
NAME,
ACTION
)
BOOST_PP_IF(DEFINED(NAME), , ACTION)
Do ACTION if NAME is undefined.
define IF_ELSE_DEFINED
#define IF_ELSE_DEFINED(
NAME,
IF,
ELSE
)
BOOST_PP_IF(DEFINED(NAME), IF, ELSE)
Do IF if NAME is defined, otherwise do ELSE.
define TOKEN_DEFINED
#define TOKEN_DEFINED(
A
)
BOOST_PP_NOT(DEFINED(A))
define IF_TOKEN_DEFINED
#define IF_TOKEN_DEFINED(
A,
B
)
BOOST_PP_IIF(DEFINED(A),BOOST_PP_EMPTY(),B)
define IF_TOKEN_UNDEFINED
#define IF_TOKEN_UNDEFINED(
A,
B
)
BOOST_PP_IIF(DEFINED(A),B,BOOST_PP_EMPTY())
define IF_ELSE_TOKEN_DEFINED
#define IF_ELSE_TOKEN_DEFINED(
A,
B,
C
)
BOOST_PP_IIF(DEFINED(A),C,B)
define DEFINED_MODULE
#define DEFINED_MODULE ()
define DEFINED_CAPABILITY
#define DEFINED_CAPABILITY ()
define DEFINED_FUNCTION
#define DEFINED_FUNCTION ()
define DEFINED_CONDITIONAL_DEPENDENCY
#define DEFINED_CONDITIONAL_DEPENDENCY ()
define POP_LAST
#define POP_LAST(
...
)
CAT(POP_LAST_, BOOST_PP_VARIADIC_SIZE __VA_ARGS__) __VA_ARGS__
Pop the last argument off a Boost preprocessor sequence
define POP_LAST_1
#define POP_LAST_1(
x1
)
define POP_LAST_2
#define POP_LAST_2(
x1,
x2
)
x1
define POP_LAST_3
#define POP_LAST_3(
x1,
x2,
x3
)
x1, x2
define POP_LAST_4
#define POP_LAST_4(
x1,
x2,
x3,
x4
)
x1, x2, x3
define POP_LAST_5
#define POP_LAST_5(
x1,
x2,
x3,
x4,
x5
)
x1, x2, x3, x4
define POP_LAST_6
#define POP_LAST_6(
x1,
x2,
x3,
x4,
x5,
x6
)
x1, x2, x3, x4, x5
define POP_LAST_7
#define POP_LAST_7(
x1,
x2,
x3,
x4,
x5,
x6,
x7
)
x1, x2, x3, x4, x5, x6
define POP_LAST_8
#define POP_LAST_8(
x1,
x2,
x3,
x4,
x5,
x6,
x7,
x8
)
x1, x2, x3, x4, x5, x6, x7
define POP_LAST_9
#define POP_LAST_9(
x1,
x2,
x3,
x4,
x5,
x6,
x7,
x8,
x9
)
x1, x2, x3, x4, x5, x6, x7, x8
define POP_LAST_10
#define POP_LAST_10(
x1,
x2,
x3,
x4,
x5,
x6,
x7,
x8,
x9,
x10
)
x1, x2, x3, x4, x5, x6, x7, x8, x9
define etc_etc
#define etc_etc 1)(1
Macros for dealing with variadic function arguments in backend functions
define LAST_ARG_VARIADIC
#define LAST_ARG_VARIADIC(
T
)
IS_ELLIPSIS(BOOST_PP_TUPLE_ELEM(BOOST_PP_SUB(BOOST_PP_VARIADIC_SIZE T,1),T))
define IS_ELLIPSIS
#define IS_ELLIPSIS(
ELEM
)
IS_EQUAL(etc,ELEM)
define STRIP_VARIADIC_ARG
#define STRIP_VARIADIC_ARG(
T
)
BOOST_PP_IIF(LAST_ARG_VARIADIC(T), (POP_LAST(T)), T)
define CONVERT_VARIADIC_ARG
#define CONVERT_VARIADIC_ARG(
T
)
BOOST_PP_IIF(LAST_ARG_VARIADIC(T), (POP_LAST(T), ...), T)
define IF_ELSEIF_9
#define IF_ELSEIF_9(
VAR1,
_1,
VAR2,
_2,
VAR3,
_3,
VAR4,
_4,
_5
)
BOOST_PP_IF(VAR1, _1, \
BOOST_PP_IF(VAR2, _2, \
BOOST_PP_IF(VAR3, _3, \
BOOST_PP_IF(VAR4, _4, _5))))
define IF_ELSEIF_7
#define IF_ELSEIF_7(
VAR1,
_1,
VAR2,
_2,
VAR3,
_3,
_4
)
BOOST_PP_IF(VAR1, _1, \
BOOST_PP_IF(VAR2, _2, \
BOOST_PP_IF(VAR3, _3, _4)))
define IF_ELSEIF_5
#define IF_ELSEIF_5(
VAR1,
_1,
VAR2,
_2,
_3
)
BOOST_PP_IF(VAR1, _1, \
BOOST_PP_IF(VAR2, _2, _3))
define IF_ELSEIF
#define IF_ELSEIF(
...
)
VARARG_NESTED(IF_ELSEIF, __VA_ARGS__)
define BRACED_INIT_LIST
#define BRACED_INIT_LIST(
...
)
{ __VA_ARGS__ }
Macro for defining a static const vector easily. With C++11 could use initialiser lists, but this is not available in all the compilers we want to support. Use this as a replacement. e.g. static const std::vector
define MAKE_STATIC_VECTOR
#define MAKE_STATIC_VECTOR(
TYPE,
NAME,
TUPLE
)
static const TYPE NAME##_array[] = BRACED_INIT_LIST TUPLE; \
static const std::vector<TYPE> NAME(NAME##_array, Utils::endA( NAME##_array ));
define MAKE_STATIC_SET
#define MAKE_STATIC_SET(
TYPE,
NAME,
TUPLE
)
static const TYPE NAME##_array[] = BRACED_INIT_LIST(TUPLE); \
static const std::set<TYPE> NAME(NAME##_array, Utils::endA( NAME##_array ));
define CALL_WITH_SILENCED_STDERR
#define CALL_WITH_SILENCED_STDERR(
FUNCTION_CALL
)
int fd; \
fpos_t pos; \
fflush(stderr); \
fgetpos(stderr, &pos); \
fd = dup(fileno(stderr)); \
freopen("/dev/null", "w", stderr); \
\
(FUNCTION_CALL); \
\
fflush(stderr); \
dup2(fd, fileno(stderr)); \
close(fd); \
clearerr(stderr); \
fsetpos(stderr, &pos);
Macro to redirect stderr to /dev/null for a single function call, for use with particularly noisy external libraries
Source code
// GAMBIT: Global and Modular BSM Inference Tool
// *********************************************
/// \file
///
/// General small utility macros.
///
/// *********************************************
///
/// Authors:
/// <!-- add name and date if you modify -->
///
/// \author Pat Scott
/// (patscott@physics.mcgill.ca)
/// \date 2013 Apr, Oct
/// \date 2014 Mar
///
/// *********************************************
#ifndef __util_macros_hpp__
#define __util_macros_hpp__
#include <unistd.h>
#include "gambit/Utils/boost_fallbacks.hpp"
#include "gambit/Utils/cats.hpp"
#include "gambit/Utils/stringify.hpp" // stringification macro
#include "gambit/Utils/local_info.hpp" // Local information macro.
#include "gambit/Utils/export_symbols.hpp" // macro for controlling symbol visibility
#include <boost/preprocessor/seq/size.hpp>
#include <boost/preprocessor/tuple/elem.hpp>
#include <boost/preprocessor/control/if.hpp>
#include <boost/preprocessor/comparison/equal.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/punctuation/comma.hpp>
#include <boost/preprocessor/punctuation/paren.hpp>
/// \name Compile-time error macro.
#define FAIL(x) static_assert(false,"GAMBIT precompiler error: " x);
/// \name Token appendment macro for use with BOOST_PP_SEQ_TRANSFORM
#define APPEND_TOKEN(s,data,elem) CAT(elem,data)
/// \name Dummy macros
/// Dummy macros that expand to nothing.
/// @{
#define DUMMY
#define DUMMYARG(...)
/// @}
/// \name Macro returning only the first argument passed
#define FIRST_ARG(A1,...) A1
/// \name Macro returning all but the first argument passed
/// @{
#define REMFIRST(...) REMFIRST_I(__VA_ARGS__)
#define REMFIRST_I(A1,...) (__VA_ARGS__)
/// @}
/// \name Macro chain for stripping parantheses off an argument
/// Usage: STRIP_PARENS(x). Example: STRIP_PARENS((y,z)) expands to y,z
/// @{
#define APPLY(macro, args) APPLY_I(macro, args)
#define APPLY_I(macro, args) macro args
#define STRIP_PARENS(x) EVAL_PAR((STRIP_PARENS_I x), x)
#define STRIP_PARENS_I(...) 1,1
#define EVAL_PAR(test, x) EVAL_PAR_I(test, x)
#define EVAL_PAR_I(test, x) MAYBE_STRIP_PARENS(TEST_ARITY test, x)
#define TEST_ARITY(...) APPLY(TEST_ARITY_I, (__VA_ARGS__, 2, 1, 0))
#define TEST_ARITY_I(a,b,c,...) c
#define MAYBE_STRIP_PARENS(cond, x) MAYBE_STRIP_PARENS_I(cond, x)
#define MAYBE_STRIP_PARENS_I(cond, x) CAT(MAYBE_STRIP_PARENS_, cond)(x)
#define MAYBE_STRIP_PARENS_1(x) x
#define MAYBE_STRIP_PARENS_2(x) APPLY(MAYBE_STRIP_PARENS_2_I, x)
#define MAYBE_STRIP_PARENS_2_I(...) __VA_ARGS__
/// @}
/// \name Macro chain checking if the argument has parantheses
/// Usage: HAS_PARENS(x). Example: HAS_PARENS((y,z)) expands to 1
/// @{
#define HAS_PARENS(x) EVAL_HASP((HAS_PARENS_I x), x)
#define HAS_PARENS_I(...) 1,1
#define EVAL_HASP(test, x) EVAL_HASP_I(test, x)
#define EVAL_HASP_I(test, x) CHECK_PARENS(TEST_ARITY test, x)
#define CHECK_PARENS(cond, x) CHECK_PARENS_I(cond, x)
#define CHECK_PARENS_I(cond, x) CAT(CHECK_PARENS_, cond)(x)
#define CHECK_PARENS_1(x) 0
#define CHECK_PARENS_2(x) 1
/// @}
/// \name Macro chain checking if the argument(s) passed has commas. Accepts up to 128 arguments.
/// Example: HAS_COMMA(1,2,3) expands to 1; HAS_COMMA(1) expands to 0
/// @{
#define _ARG128(_0, _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, _90, _91, _92, _93, _94, _95, \
_96, _97, _98, _99, _100, _101, _102, _103, _104, _105, _106, _107, _108, _109, \
_110, _111, _112, _113, _114, _115, _116, _117, _118, _119, _120, _121, _122, _123, _124, _125, _126, _127, ...) _127
#define HAS_COMMA(...) _ARG128(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0)
/// @}
/// \name Macro chain checking if the argument passed is empty
/// Example: ISEMPTY() expands to 1; ISEMPTY(1,2,3) expands to 0
/// @{
#define ISEMPTY(ARG) ISEMPTY_I(_129ONES STRIP_PARENS(ARG) ())
#define ISEMPTY_I(A) ISEMPTY_II(A,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,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)
#define ISEMPTY_II(...) _ARG128(__VA_ARGS__)
#define _129ONES() 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, \
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\
1,1,1,1,1,1,1,1,1,1,1,1
/// @}
/// \name Macro that expands to the argument list with a comma in front
/// if the (bracket enclosed) argument list is not empty.
/// If the agrument list is empty, expands to nothing.
/// @{
#define INSERT_NONEMPTY(ARG) CAT(INSERT_NONEMPTY_I,ISEMPTY(ARG))(ARG)
#define INSERT_NONEMPTY_I0(ARG) ,STRIP_PARENS(ARG)
#define INSERT_NONEMPTY_I1(...) DUMMYARG(__VA_ARGS__)
/// @}
/// \name Boost 2-tuple access macros
/// Used to avoid possible reentrancy issues with multiple use of BOOST_PP_TUPLE_ELEM.
/// @{
#define PAIR_ELEMENT0(TPLE) PAIR_ELEMENT0_I TPLE
#define PAIR_ELEMENT0_I(A,B) A
#define PAIR_ELEMENT1(TPLE) PAIR_ELEMENT1_I TPLE
#define PAIR_ELEMENT1_I(A,B) B
/// @}
/// \name Type comparison macros
/// Macros to evaluate whether two intrinsic types are identical or not.
/// Example use: define a macro that evaluates to 1 if token X = void, 0
/// otherwise.
/// \code
/// #define X_IS_VOID(X) IS_TYPE(X, void)
/// \endcode
/// @{
#define void_void 1)(1
#define int_int 1)(1
#define float_float 1)(1
#define double_double 1)(1
#define bool_bool 1)(1
#define char_char 1)(1
#define string_string 1)(1
#define ModelParameters_ModelParameters 1)(1
#define IS_TYPE(COMPTYPE,TYPE) BOOST_PP_EQUAL(BOOST_PP_SEQ_SIZE((CAT_3(COMPTYPE,_,TYPE))),2)
/// @}
/// \name String comparison macros.
/// Macros for evaluating whether tokens are equal or not for certain special values, and
/// for then switching on the result.
/// Define your special values, such as "myToken" locally as
/// \code
/// #define myToken_myToken 1)(1
/// Just like the IS_TYPE macro, so redirects to that.
/// \endcode
/// @{
#define IS_EQUAL(A,B) IS_TYPE(A,B)
#define IF_EQUAL(A,B,C) BOOST_PP_IIF(IS_EQUAL(A,B),C,)
#define IF_NOT_EQUAL(A,B,C) BOOST_PP_IIF(IS_EQUAL(A,B), ,C)
#define IF_ELSE_EQUAL(A,B,C,D) BOOST_PP_IIF(IS_EQUAL(A,B),C,D)
/// @}
/// \name Empty token test macros.
/// Macros for evaluating whether certain tokens are empty or not, and
/// for then switching on the result.
/// @{
#define EMPTY_TOKEN_TESTER 1)(1
#define IS_EMPTY(A) IS_EQUAL(CAT(A,EMPTY),TOKEN_TESTER)
#define IF_EMPTY(A,B) BOOST_PP_IIF(IS_EMPTY(A),B,)
#define IF_NOT_EMPTY(A,B) BOOST_PP_IIF(IS_EMPTY(A), ,B)
#define IF_ELSE_EMPTY(A,B,C) BOOST_PP_IIF(IS_EMPTY(A),B,C)
/// @}
/// \name General variadic macro expanders
/// Generic variadic macro expanders for 1 to 10 arguments.
/// Example use: redirect EXAMPLE according to whether it is called
/// with 2, 3 or 4 arguments.
/// \code
/// #define EXAMPLE_4(_1, _2, _3, _4) DOSTUFF(_1, _2, _3, _4)
/// #define EXAMPLE_3(_1, _2, _3) DOSTUFF(_1, _2, _3, foo)
/// #define EXAMPLE_2(_1, _2) DOSTUFF(_1, _2, foo, bar)
/// #define EXAMPLE(...) VARARG(EXAMPLE, __VA_ARGS__)
/// \endcode
/// @{
#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, N, ...) N
#define VA_NARGS(...) VA_NARGS_IMPL(X,__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#define VARARG_IMPL2(base, count, ...) CAT_3(base,_,count)(__VA_ARGS__)
#define VARARG_IMPL(base, count, ...) VARARG_IMPL2(base, count, __VA_ARGS__)
#define VARARG(base, ...) VARARG_IMPL(base, VA_NARGS(__VA_ARGS__), __VA_ARGS__)
/// @}
/// \name Duplicate of variadic macro expanders, to allow nesting.
/// @{
#define VA_NARGS_NESTED_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, N, ...) N
#define VA_NARGS_NESTED(...) VA_NARGS_NESTED_IMPL(X,__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#define VARARG_NESTED_IMPL2(base, count, ...) CAT_3(base,_,count)(__VA_ARGS__)
#define VARARG_NESTED_IMPL(base, count, ...) VARARG_NESTED_IMPL2(base, count, __VA_ARGS__)
#define VARARG_NESTED(base, ...) VARARG_NESTED_IMPL(base, VA_NARGS_NESTED(__VA_ARGS__), __VA_ARGS__)
/// @}
/// \name Variadic macro expanders taking 3 leading arguments
/// @{
#define VA_NARGS_AB_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, N, ...) N
#define VA_NARGS_AB(...) VA_NARGS_AB_IMPL(X,__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#define VARARG_AB_IMPL2(base, A, B, count, ...) CAT_3(base,_,count)(A, B, __VA_ARGS__)
#define VARARG_AB_IMPL(base, A, B, count, ...) VARARG_AB_IMPL2(base, A, B, count, __VA_ARGS__)
#define VARARG_AB(base, A, B, ...) VARARG_AB_IMPL(base, A, B, VA_NARGS_AB(__VA_ARGS__), __VA_ARGS__)
/// @}
/// \name Variadic macro expanders for distinguishing between 1 and >1 variadic argument
/// @{
#define VARARG_SWITCH_ON_GT_ONE_TESTER_1 1)(1
#define VA_NARGS_SWITCH_ON_GT_ONE_IMPL(_1, _2, _3, N, ...) IF_ELSE_EQUAL(VARARG_SWITCH_ON_GT_ONE_TESTER,N,N,MORE)
#define VA_NARGS_SWITCH_ON_GT_ONE(...) VA_NARGS_SWITCH_ON_GT_ONE_IMPL(X,__VA_ARGS__, 2, 1, 0)
#define VARARG_SWITCH_ON_GT_ONE_IMPL2(base, count, ...) CAT_3(base,_,count)(__VA_ARGS__)
#define VARARG_SWITCH_ON_GT_ONE_IMPL(base, count, ...) VARARG_SWITCH_ON_GT_ONE_IMPL2(base, count, __VA_ARGS__)
#define VARARG_SWITCH_ON_GT_ONE(base, ...) VARARG_SWITCH_ON_GT_ONE_IMPL(base, VA_NARGS_SWITCH_ON_GT_ONE(__VA_ARGS__), __VA_ARGS__)
/// @}
/// \name Variadic macro expanders for distinguishing between 1 and >1 variadic argument, taking 1 leading argument
/// @{
#define VARARG_SWITCH_ON_GT_ONE_A_TESTER_1 1)(1
#define VA_NARGS_SWITCH_ON_GT_ONE_A_IMPL(_1, _2, _3, N, ...) IF_ELSE_EQUAL(VARARG_SWITCH_ON_GT_ONE_A_TESTER,N,N,MORE)
#define VA_NARGS_SWITCH_ON_GT_ONE_A(...) VA_NARGS_SWITCH_ON_GT_ONE_A_IMPL(X,__VA_ARGS__, 2, 1, 0)
#define VARARG_SWITCH_ON_GT_ONE_A_IMPL2(base, A, count, ...) CAT_3(base,_,count)(A, __VA_ARGS__)
#define VARARG_SWITCH_ON_GT_ONE_A_IMPL(base, A, count, ...) VARARG_SWITCH_ON_GT_ONE_A_IMPL2(base, A, count, __VA_ARGS__)
#define VARARG_SWITCH_ON_GT_ONE_A(base, A, ...) VARARG_SWITCH_ON_GT_ONE_A_IMPL(base, A, VA_NARGS_SWITCH_ON_GT_ONE_A(__VA_ARGS__), __VA_ARGS__)
/// @}
/// \name Variadic macro expanders for distinguishing between 1 and >1 variadic argument, taking 3 leading arguments
/// @{
#define VARARG_SWITCH_ON_GT_ONE_ABC_TESTER_1 1)(1
#define VA_NARGS_SWITCH_ON_GT_ONE_ABC_IMPL(_1, _2, _3, N, ...) IF_ELSE_EQUAL(VARARG_SWITCH_ON_GT_ONE_ABC_TESTER,N,N,MORE)
#define VA_NARGS_SWITCH_ON_GT_ONE_ABC(...) VA_NARGS_SWITCH_ON_GT_ONE_ABC_IMPL(X,__VA_ARGS__, 2, 1, 0)
#define VARARG_SWITCH_ON_GT_ONE_ABC_IMPL2(base, A, B, C, count, ...) CAT_3(base,_,count)(A, B, C, __VA_ARGS__)
#define VARARG_SWITCH_ON_GT_ONE_ABC_IMPL(base, A, B, C, count, ...) VARARG_SWITCH_ON_GT_ONE_ABC_IMPL2(base, A, B, C, count, __VA_ARGS__)
#define VARARG_SWITCH_ON_GT_ONE_ABC(base, A, B, C, ...) VARARG_SWITCH_ON_GT_ONE_ABC_IMPL(base, A, B, C, VA_NARGS_SWITCH_ON_GT_ONE_ABC(__VA_ARGS__), __VA_ARGS__)
/// @}
/// \name Variadic macro expanders for distinguishing between 1, 2 and >2 variadic arguments, taking 3 leading arguments
/// @{
#define VARARG_SWITCH_ON_GT_TWO_ABC_TESTER_2 1)(1
#define VARARG_SWITCH_ON_GT_TWO_ABC_TESTER_1 1)(1
#define VA_NARGS_SWITCH_ON_GT_TWO_ABC_IMPL(_1, _2, _3, _4, N, ...) IF_ELSE_EQUAL(VARARG_SWITCH_ON_GT_TWO_ABC_TESTER,\
BOOST_PP_TUPLE_ELEM(0,(STRIP_PARENS(N))),N,MORE)
#define VA_NARGS_SWITCH_ON_GT_TWO_ABC(...) VA_NARGS_SWITCH_ON_GT_TWO_ABC_IMPL(X,__VA_ARGS__, 3, 2, 1, 0)
#define VARARG_SWITCH_ON_GT_TWO_ABC_IMPL2(base, A, B, C, count, ...) CAT_3(base,_,count)(A, B, C, __VA_ARGS__)
#define VARARG_SWITCH_ON_GT_TWO_ABC_IMPL(base, A, B, C, count, ...) VARARG_SWITCH_ON_GT_TWO_ABC_IMPL2(base, A, B, C, count, __VA_ARGS__)
#define VARARG_SWITCH_ON_GT_TWO_ABC(base, A, B, C, ...) VARARG_SWITCH_ON_GT_TWO_ABC_IMPL(base, A, B, C, VA_NARGS_SWITCH_ON_GT_TWO_ABC(__VA_ARGS__), __VA_ARGS__)
/// @}
/// \name Bottom-level definition-checking macros
/// Generic macros that can be used from within other macros
/// to test whether or not some other macro is defined.
/// To count as "defined" for the purposes of these macros, there
/// must exist a macro definition of the following form:
/// \code
/// #define DEFINED_FOO ()
/// \endcode
/// If this definition exists, DEFINED(FOO) will return 1. It is up to
/// you to actually create a matching macro FOO when you create DEFINED_FOO,
/// and then do something with the information that DEFINED provides about
/// the existence of DEFINED_FOO (and presumably also FOO).
///
/// Typically these macros would be used to switch behaviour on a flag
/// passed to a macro. See \link START_FUNCTION() START_FUNCTION \endlink
/// in module_macros_common.hpp for a detailed worked example.
/// @{
#define CHECK_N(x, n, ...) n
#define CHECK(...) CHECK_N(__VA_ARGS__, 0, 0)
#define PROBE(x) x, 1
#define DEFINED_PROBE(NAME) DEFINED_PROBE_PROXY( DEFINED_##NAME ) // concatenate DEFINED_ prefix with function name
#define DEFINED_PROBE_PROXY(...) DEFINED_PROBE_PRIMITIVE(__VA_ARGS__) // expand arguments
#define DEFINED_PROBE_PRIMITIVE(x) DEFINED_PROBE_COMBINE_ x // collapse again
#define DEFINED_PROBE_COMBINE_(...) PROBE(X)
/// Returns 1 or 0 depending on whether a corresponding DEFINED_<NAME> () macro has been
/// \code #defined \endcode or not.
#define DEFINED(NAME) CHECK(DEFINED_PROBE(NAME))
/// @}
/// \name High-level definition-checking macros.
/// These are just nice wrappers around \link DEFINED() DEFINED\endlink for specific logical cases.
/// @{
/// Do ACTION if NAME is defined.
#define IF_DEFINED(NAME,ACTION) BOOST_PP_IF(DEFINED(NAME), ACTION, )
/// Do ACTION if NAME is undefined.
#define IF_NOT_DEFINED(NAME,ACTION) BOOST_PP_IF(DEFINED(NAME), , ACTION)
/// Do IF if NAME is defined, otherwise do ELSE.
#define IF_ELSE_DEFINED(NAME,IF,ELSE) BOOST_PP_IF(DEFINED(NAME), IF, ELSE)
/// @}
/// \name Sneaky redefinition of \link DEFINED() DEFINED\endlink to allow testing whether specific tokens are defined.
/// @{
#define TOKEN_DEFINED(A) BOOST_PP_NOT(DEFINED(A))
#define IF_TOKEN_DEFINED(A,B) BOOST_PP_IIF(DEFINED(A),BOOST_PP_EMPTY(),B)
#define IF_TOKEN_UNDEFINED(A,B) BOOST_PP_IIF(DEFINED(A),B,BOOST_PP_EMPTY())
#define IF_ELSE_TOKEN_DEFINED(A,B,C) BOOST_PP_IIF(DEFINED(A),C,B)
#define DEFINED_MODULE ()
#define DEFINED_CAPABILITY ()
#define DEFINED_FUNCTION ()
#define DEFINED_CONDITIONAL_DEPENDENCY ()
/// @}
/// Pop the last argument off a Boost preprocessor sequence
/// @{
#define POP_LAST(...) CAT(POP_LAST_, BOOST_PP_VARIADIC_SIZE __VA_ARGS__) __VA_ARGS__
#define POP_LAST_1(x1)
#define POP_LAST_2(x1, x2) x1
#define POP_LAST_3(x1, x2, x3) x1, x2
#define POP_LAST_4(x1, x2, x3, x4) x1, x2, x3
#define POP_LAST_5(x1, x2, x3, x4, x5) x1, x2, x3, x4
#define POP_LAST_6(x1, x2, x3, x4, x5, x6) x1, x2, x3, x4, x5
#define POP_LAST_7(x1, x2, x3, x4, x5, x6, x7) x1, x2, x3, x4, x5, x6
#define POP_LAST_8(x1, x2, x3, x4, x5, x6, x7, x8) x1, x2, x3, x4, x5, x6, x7
#define POP_LAST_9(x1, x2, x3, x4, x5, x6, x7, x8, x9) x1, x2, x3, x4, x5, x6, x7, x8
#define POP_LAST_10(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) x1, x2, x3, x4, x5, x6, x7, x8, x9
/// @}
/// Macros for dealing with variadic function arguments in backend functions
/// @{
#define etc_etc 1)(1
#define LAST_ARG_VARIADIC(T) IS_ELLIPSIS(BOOST_PP_TUPLE_ELEM(BOOST_PP_SUB(BOOST_PP_VARIADIC_SIZE T,1),T))
#define IS_ELLIPSIS(ELEM) IS_EQUAL(etc,ELEM)
#define STRIP_VARIADIC_ARG(T) BOOST_PP_IIF(LAST_ARG_VARIADIC(T), (POP_LAST(T)), T)
#define CONVERT_VARIADIC_ARG(T) BOOST_PP_IIF(LAST_ARG_VARIADIC(T), (POP_LAST(T), ...), T)
/// @}
/// \name Preprocessor switch-case statements
/// @{
#define IF_ELSEIF_9(VAR1, _1, VAR2, _2, VAR3, _3, VAR4, _4, _5) \
BOOST_PP_IF(VAR1, _1, \
BOOST_PP_IF(VAR2, _2, \
BOOST_PP_IF(VAR3, _3, \
BOOST_PP_IF(VAR4, _4, _5))))
#define IF_ELSEIF_7(VAR1, _1, VAR2, _2, VAR3, _3, _4) \
BOOST_PP_IF(VAR1, _1, \
BOOST_PP_IF(VAR2, _2, \
BOOST_PP_IF(VAR3, _3, _4)))
#define IF_ELSEIF_5(VAR1, _1, VAR2, _2, _3) \
BOOST_PP_IF(VAR1, _1, \
BOOST_PP_IF(VAR2, _2, _3))
#define IF_ELSEIF(...) VARARG_NESTED(IF_ELSEIF, __VA_ARGS__)
/// @}
/// Macro for defining a static const vector easily. With C++11 could use initialiser lists, but
/// this is not available in all the compilers we want to support. Use this as a replacement.
/// e.g.
/// static const std::vector<int> myvector = {1,2,3,4}; // Not possible in all compilers we support.
/// becomes
/// MAKE_STATIC_VECTOR(int,myvector,(1,2,3,4))
#define BRACED_INIT_LIST(...) { __VA_ARGS__ }
#define MAKE_STATIC_VECTOR(TYPE,NAME,TUPLE) \
static const TYPE NAME##_array[] = BRACED_INIT_LIST TUPLE; \
static const std::vector<TYPE> NAME(NAME##_array, Utils::endA( NAME##_array ));
#define MAKE_STATIC_SET(TYPE,NAME,TUPLE) \
static const TYPE NAME##_array[] = BRACED_INIT_LIST(TUPLE); \
static const std::set<TYPE> NAME(NAME##_array, Utils::endA( NAME##_array ));
/// Macro to redirect stderr to /dev/null for a single function call,
/// for use with particularly noisy external libraries
#define CALL_WITH_SILENCED_STDERR(FUNCTION_CALL) \
int fd; \
fpos_t pos; \
fflush(stderr); \
fgetpos(stderr, &pos); \
fd = dup(fileno(stderr)); \
freopen("/dev/null", "w", stderr); \
\
(FUNCTION_CALL); \
\
fflush(stderr); \
dup2(fd, fileno(stderr)); \
close(fd); \
clearerr(stderr); \
fsetpos(stderr, &pos);
#endif //defined __util_macros_hpp__
Updated on 2024-07-18 at 13:53:32 +0000