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