1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#ifndef ANDROID_PDX_RPC_MACROS_H_
2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define ANDROID_PDX_RPC_MACROS_H_
3e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
4e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Macros to apply other macros over all elements in a list.
5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//
6e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// For example, for a macro A(x) and B(x, y):
7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// - FOR_EACH(A, 1, 2, 3) -> A(1) A(2) A(3).
8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// - FOR_EACH_BINARY(B, z, 1, 2, 3) -> B(z, 1) B(z, 2) B(z, 3)
9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// - FOR_EACH_LIST(A, 1, 2, 3) -> A(1), B(2), C(3)
10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// - FOR_EACH_BINARY_LIST(B, z, 1, 2, 3) -> B(z, 1), B(z, 2), B(z, 3)
11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//
12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Empty lists are supported and will produce no output.
13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Recursive expansion macros.
15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define _PDX_EXPAND0(...) __VA_ARGS__
16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define _PDX_EXPAND1(...) _PDX_EXPAND0(_PDX_EXPAND0(_PDX_EXPAND0(__VA_ARGS__)))
17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define _PDX_EXPAND2(...) _PDX_EXPAND1(_PDX_EXPAND1(_PDX_EXPAND1(__VA_ARGS__)))
18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define _PDX_EXPAND3(...) _PDX_EXPAND2(_PDX_EXPAND2(_PDX_EXPAND2(__VA_ARGS__)))
19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define _PDX_EXPAND4(...) _PDX_EXPAND3(_PDX_EXPAND3(_PDX_EXPAND3(__VA_ARGS__)))
20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define _PDX_EXPAND(...) _PDX_EXPAND4(_PDX_EXPAND4(_PDX_EXPAND4(__VA_ARGS__)))
21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Required to workaround a bug in the VC++ preprocessor.
23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define _PDX_INDIRECT_EXPAND(macro, args) macro args
24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Defines a step separation for macro expansion.
26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define _PDX_SEPARATOR
27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Clears any remaining contents wrapped in parentheses.
29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define _PDX_CLEAR(...)
30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Introduces a first dummy argument and _PDX_CLEAR as second argument.
32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define _PDX_CLEAR_IF_LAST() _, _PDX_CLEAR
33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Returns the first argument of a list.
35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define _PDX_FIRST_ARG(first, ...) first
36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Returns the second argument of a list.
38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define _PDX_SECOND_ARG(_, second, ...) second
39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Expands the arguments and introduces a separator.
41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define _PDX_EXPAND_NEXT_FUNC(_, next_func, ...)        \
42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  _PDX_INDIRECT_EXPAND(_PDX_SECOND_ARG, (_, next_func)) \
43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  _PDX_SEPARATOR
44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Returns next_func if the next element is not (), or _PDX_CLEAR
46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// otherwise.
47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//
48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// _PDX_CLEAR_IF_LAST inserts an extra first dummy argument if peek is ().
49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define _PDX_NEXT_FUNC(next_element, next_func) \
50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  _PDX_EXPAND_NEXT_FUNC(_PDX_CLEAR_IF_LAST next_element, next_func)
51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Macros for the unary version of PDX_FOR_EACH.
53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Applies the unary macro. Duplicated for macro recursive expansion.
55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define _PDX_APPLY_1(macro, head, next, ...) \
56e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  macro(head) _PDX_NEXT_FUNC(next, _PDX_APPLY_2)(macro, next, __VA_ARGS__)
57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
58e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Applies the unary macro. Duplicated for macro recursive expansion.
59e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define _PDX_APPLY_2(macro, head, next, ...) \
60e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  macro(head) _PDX_NEXT_FUNC(next, _PDX_APPLY_1)(macro, next, __VA_ARGS__)
61e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
62e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Stops expansion if __VA_ARGS__ is empty, calling _PDX_APPLY_1
63e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// otherwise.
64e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define _PDX_HANDLE_EMPTY_ARGS(macro, ...)                    \
65e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  _PDX_NEXT_FUNC(_PDX_FIRST_ARG(__VA_ARGS__()), _PDX_APPLY_1) \
66e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  (macro, __VA_ARGS__, ())
67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
68e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Applies a unary macro over all the elements in a list.
69e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define PDX_FOR_EACH(macro, ...) \
70e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  _PDX_EXPAND(_PDX_HANDLE_EMPTY_ARGS(macro, __VA_ARGS__))
71e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
72e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Applies the unary macro at the end of a list. Duplicated for macro recursive
73e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// expansion.
74e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define _PDX_APPLY_LIST_1(macro, head, next, ...) \
75e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  , macro(head)                                   \
76e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        _PDX_NEXT_FUNC(next, _PDX_APPLY_LIST_2)(macro, next, __VA_ARGS__)
77e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
78e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Applies the unary macro at the end of a list. Duplicated for macro recursive
79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// expansion.
80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define _PDX_APPLY_LIST_2(macro, head, next, ...) \
81e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  , macro(head)                                   \
82e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        _PDX_NEXT_FUNC(next, _PDX_APPLY_LIST_1)(macro, next, __VA_ARGS__)
83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Applies the unary macro at the start of a list.
85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define _PDX_APPLY_LIST_0(macro, head, next, ...) \
86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  macro(head) _PDX_NEXT_FUNC(next, _PDX_APPLY_LIST_1)(macro, next, __VA_ARGS__)
87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Stops expansion if __VA_ARGS__ is empty, calling _PDX_APPLY_LIST_0
89e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// otherwise.
90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define _PDX_HANDLE_EMPTY_LIST(macro, ...)                         \
91e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  _PDX_NEXT_FUNC(_PDX_FIRST_ARG(__VA_ARGS__()), _PDX_APPLY_LIST_0) \
92e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  (macro, __VA_ARGS__, ())
93e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Applies a unary macro over all the elements in a list.
95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define PDX_FOR_EACH_LIST(macro, ...) \
96e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  _PDX_EXPAND(_PDX_HANDLE_EMPTY_LIST(macro, __VA_ARGS__))
97e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
98e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Macros for the binary version of PDX_FOR_EACH.
99e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
100e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Applies the binary macro. Duplicated for macro recursive expansion.
101e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define _PDX_APPLY_BINARY_1(macro, arg, head, next, ...) \
102e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  macro(arg, head)                                       \
103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      _PDX_NEXT_FUNC(next, _PDX_APPLY_BINARY_2)(macro, arg, next, __VA_ARGS__)
104e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
105e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Applies the binary macro. Duplicated for macro recursive expansion.
106e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define _PDX_APPLY_BINARY_2(macro, arg, head, next, ...) \
107e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  macro(arg, head)                                       \
108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      _PDX_NEXT_FUNC(next, _PDX_APPLY_BINARY_1)(macro, arg, next, __VA_ARGS__)
109e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
110e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Version of _PDX_HANDLE_EMPTY_ARGS that takes 1 fixed argument for a
111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// binary macro.
112e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define _PDX_HANDLE_EMPTY_ARGS_BINARY(macro, arg, ...)               \
113e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  _PDX_NEXT_FUNC(_PDX_FIRST_ARG(__VA_ARGS__()), _PDX_APPLY_BINARY_1) \
114e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  (macro, arg, __VA_ARGS__, ())
115e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
116e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Applies a binary macro over all the elements in a list and a given argument.
117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define PDX_FOR_EACH_BINARY(macro, arg, ...) \
118e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  _PDX_EXPAND(_PDX_HANDLE_EMPTY_ARGS_BINARY(macro, arg, __VA_ARGS__))
119e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
120e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Applies the binary macro at the end of a list. Duplicated for macro recursive
121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// expansion.
122e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define _PDX_APPLY_BINARY_LIST_1(macro, arg, head, next, ...)        \
123e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  , macro(arg, head) _PDX_NEXT_FUNC(next, _PDX_APPLY_BINARY_LIST_2)( \
124e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        macro, arg, next, __VA_ARGS__)
125e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
126e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Applies the binary macro at the end of a list. Duplicated for macro recursive
127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// expansion.
128e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define _PDX_APPLY_BINARY_LIST_2(macro, arg, head, next, ...)        \
129e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  , macro(arg, head) _PDX_NEXT_FUNC(next, _PDX_APPLY_BINARY_LIST_1)( \
130e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        macro, arg, next, __VA_ARGS__)
131e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
132e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Applies the binary macro at the start of a list. Duplicated for macro
133e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// recursive expansion.
134e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define _PDX_APPLY_BINARY_LIST_0(macro, arg, head, next, ...)      \
135e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  macro(arg, head) _PDX_NEXT_FUNC(next, _PDX_APPLY_BINARY_LIST_1)( \
136e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      macro, arg, next, __VA_ARGS__)
137e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
138e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Version of _PDX_HANDLE_EMPTY_LIST that takes 1 fixed argument for a
139e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// binary macro.
140e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define _PDX_HANDLE_EMPTY_LIST_BINARY(macro, arg, ...)                    \
141e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  _PDX_NEXT_FUNC(_PDX_FIRST_ARG(__VA_ARGS__()), _PDX_APPLY_BINARY_LIST_0) \
142e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  (macro, arg, __VA_ARGS__, ())
143e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
144e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Applies a binary macro over all the elements in a list and a given argument.
145e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define PDX_FOR_EACH_BINARY_LIST(macro, arg, ...) \
146e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  _PDX_EXPAND(_PDX_HANDLE_EMPTY_LIST_BINARY(macro, arg, __VA_ARGS__))
147e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
148e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#endif  // ANDROID_PDX_RPC_MACROS_H_
149