diff options
author | amatanhead <[email protected]> | 2022-02-10 16:50:04 +0300 |
---|---|---|
committer | Daniil Cherednik <[email protected]> | 2022-02-10 16:50:04 +0300 |
commit | 8879605a63ac17539be5b3bd41b529791f4d4b02 (patch) | |
tree | 5739c7303cbe09d02b881e25bb294a4a173422a0 /util/generic/va_args_gen.py | |
parent | 830fe7ae4073c2707f3f3138303ccc56052c0327 (diff) |
Restoring authorship annotation for <[email protected]>. Commit 1 of 2.
Diffstat (limited to 'util/generic/va_args_gen.py')
-rwxr-xr-x | util/generic/va_args_gen.py | 308 |
1 files changed, 154 insertions, 154 deletions
diff --git a/util/generic/va_args_gen.py b/util/generic/va_args_gen.py index 232b53fca6d..823f7f2252b 100755 --- a/util/generic/va_args_gen.py +++ b/util/generic/va_args_gen.py @@ -1,99 +1,99 @@ #!/usr/bin/env python -""" -Generates some handy macros for preprocessor metaprogramming. - -""" - -from __future__ import print_function +""" +Generates some handy macros for preprocessor metaprogramming. +""" + +from __future__ import print_function + import sys -import textwrap - -if sys.version_info >= (3, 0, 0): - xrange = range +import textwrap +if sys.version_info >= (3, 0, 0): + xrange = range + def generate(limit): - print('#pragma once') - print(textwrap.dedent(''' - /// @file va_args.h - /// - /// Some handy macros for preprocessor metaprogramming. - '''.rstrip())) - print('') - command = ' '.join(sys.argv) - print('// NOTE: this file has been generated with "{}", do not edit -- use the generator instead'.format(command)) - print('') - print('// DO_NOT_STYLE') - print('') - print('#include <util/system/defaults.h>') - print('') - - pass_va_args() - count(limit) - get_elem(limit) - map_args(limit) + print('#pragma once') + print(textwrap.dedent(''' + /// @file va_args.h + /// + /// Some handy macros for preprocessor metaprogramming. + '''.rstrip())) + print('') + command = ' '.join(sys.argv) + print('// NOTE: this file has been generated with "{}", do not edit -- use the generator instead'.format(command)) + print('') + print('// DO_NOT_STYLE') + print('') + print('#include <util/system/defaults.h>') + print('') + + pass_va_args() + count(limit) + get_elem(limit) + map_args(limit) map_args_n(limit) - map_args_with_last(limit) + map_args_with_last(limit) map_args_with_last_n(limit) - all_but_last(limit) - last(limit) - impl_dispatcher() - - -def pass_va_args(): - print(textwrap.dedent(''' - /** - * Triggers another level of macro expansion, use whenever passing __VA_ARGS__ to another macro. - * - * Used merely for working around an MSVC++ bug. - * See http://stackoverflow.com/questions/5134523/msvc-doesnt-expand-va-args-correctly - */ - '''.rstrip())) - print('#define Y_PASS_VA_ARGS(x) x') - - -def count(limit): - print(textwrap.dedent(''' - /** - * Count number of arguments in `__VA_ARGS__`. - * Doesn't work with empty arguments list. - */ - '''.rstrip())) - numbers = ', '.join(map(str, xrange(limit, -1, -1))) - u_numbers = ', '.join(map('_{}'.format, xrange(limit, 0, -1))) - print('#define Y_COUNT_ARGS(...) Y_PASS_VA_ARGS(' - '__Y_COUNT_ARGS(__VA_ARGS__, {}))'.format(numbers)) - print('#define __Y_COUNT_ARGS({}, N, ...) N'.format(u_numbers)) - - -def get_elem(limit): - print(textwrap.dedent(''' - /** - * Get the i-th element from `__VA_ARGS__`. - */ - '''.rstrip())) - print('#define Y_GET_ARG(N, ...) Y_PASS_VA_ARGS(Y_PASS_VA_ARGS(Y_CAT(__Y_GET_ARG_, ' - 'N))(__VA_ARGS__))') - for i in xrange(0, limit + 1): - args = ', '.join(map('_{}'.format, xrange(i + 1))) - print('#define __Y_GET_ARG_{}({}, ...) _{}'.format(i, args, i)) - - -def map_args(limit): - print(textwrap.dedent(''' - /** - * Expands a macro for each of the variable arguments. - * Doesn't work with empty arguments list. - */ - '''.rstrip())) - print('#define Y_MAP_ARGS(ACTION, ...) Y_PASS_VA_ARGS(Y_PASS_VA_ARGS(Y_CAT(' - '__Y_MAP_ARGS_, Y_COUNT_ARGS(__VA_ARGS__)))(ACTION, __VA_ARGS__))') - print('#define __Y_MAP_ARGS_0(...)') - print('#define __Y_MAP_ARGS_1(ACTION, x, ...) ACTION(x)') - for i in xrange(2, limit + 1): - print('#define __Y_MAP_ARGS_{}(ACTION, x, ...) ACTION(x) Y_PASS_VA_ARGS(__Y_MAP_ARGS_{}(' - 'ACTION, __VA_ARGS__))'.format(i, i - 1)) + all_but_last(limit) + last(limit) + impl_dispatcher() + + +def pass_va_args(): + print(textwrap.dedent(''' + /** + * Triggers another level of macro expansion, use whenever passing __VA_ARGS__ to another macro. + * + * Used merely for working around an MSVC++ bug. + * See http://stackoverflow.com/questions/5134523/msvc-doesnt-expand-va-args-correctly + */ + '''.rstrip())) + print('#define Y_PASS_VA_ARGS(x) x') + + +def count(limit): + print(textwrap.dedent(''' + /** + * Count number of arguments in `__VA_ARGS__`. + * Doesn't work with empty arguments list. + */ + '''.rstrip())) + numbers = ', '.join(map(str, xrange(limit, -1, -1))) + u_numbers = ', '.join(map('_{}'.format, xrange(limit, 0, -1))) + print('#define Y_COUNT_ARGS(...) Y_PASS_VA_ARGS(' + '__Y_COUNT_ARGS(__VA_ARGS__, {}))'.format(numbers)) + print('#define __Y_COUNT_ARGS({}, N, ...) N'.format(u_numbers)) + + +def get_elem(limit): + print(textwrap.dedent(''' + /** + * Get the i-th element from `__VA_ARGS__`. + */ + '''.rstrip())) + print('#define Y_GET_ARG(N, ...) Y_PASS_VA_ARGS(Y_PASS_VA_ARGS(Y_CAT(__Y_GET_ARG_, ' + 'N))(__VA_ARGS__))') + for i in xrange(0, limit + 1): + args = ', '.join(map('_{}'.format, xrange(i + 1))) + print('#define __Y_GET_ARG_{}({}, ...) _{}'.format(i, args, i)) + + +def map_args(limit): + print(textwrap.dedent(''' + /** + * Expands a macro for each of the variable arguments. + * Doesn't work with empty arguments list. + */ + '''.rstrip())) + print('#define Y_MAP_ARGS(ACTION, ...) Y_PASS_VA_ARGS(Y_PASS_VA_ARGS(Y_CAT(' + '__Y_MAP_ARGS_, Y_COUNT_ARGS(__VA_ARGS__)))(ACTION, __VA_ARGS__))') + print('#define __Y_MAP_ARGS_0(...)') + print('#define __Y_MAP_ARGS_1(ACTION, x, ...) ACTION(x)') + for i in xrange(2, limit + 1): + print('#define __Y_MAP_ARGS_{}(ACTION, x, ...) ACTION(x) Y_PASS_VA_ARGS(__Y_MAP_ARGS_{}(' + 'ACTION, __VA_ARGS__))'.format(i, i - 1)) def map_args_n(limit): @@ -113,21 +113,21 @@ def map_args_n(limit): 'ACTION, __VA_ARGS__))'.format(i, i, i - 1)) -def map_args_with_last(limit): - print(textwrap.dedent(''' - /** - * Expands a macro for each of the variable arguments. - * Doesn't work with empty arguments list. - */ - '''.rstrip())) - print('#define Y_MAP_ARGS_WITH_LAST(ACTION, LAST_ACTION, ...) Y_PASS_VA_ARGS(Y_PASS_VA_ARGS(' - 'Y_CAT(__Y_MAP_ARGS_WITH_LAST_, Y_COUNT_ARGS(__VA_ARGS__)))(ACTION, LAST_ACTION, ' - '__VA_ARGS__))') - print('#define __Y_MAP_ARGS_WITH_LAST_0(...)') - print('#define __Y_MAP_ARGS_WITH_LAST_1(ACTION, LAST_ACTION, x, ...) LAST_ACTION(x)') - for i in xrange(2, limit + 1): - print('#define __Y_MAP_ARGS_WITH_LAST_{}(ACTION, LAST_ACTION, x, ...) ACTION(x) Y_PASS_VA_ARGS(' - '__Y_MAP_ARGS_WITH_LAST_{}(ACTION, LAST_ACTION, __VA_ARGS__))'.format(i, i - 1)) +def map_args_with_last(limit): + print(textwrap.dedent(''' + /** + * Expands a macro for each of the variable arguments. + * Doesn't work with empty arguments list. + */ + '''.rstrip())) + print('#define Y_MAP_ARGS_WITH_LAST(ACTION, LAST_ACTION, ...) Y_PASS_VA_ARGS(Y_PASS_VA_ARGS(' + 'Y_CAT(__Y_MAP_ARGS_WITH_LAST_, Y_COUNT_ARGS(__VA_ARGS__)))(ACTION, LAST_ACTION, ' + '__VA_ARGS__))') + print('#define __Y_MAP_ARGS_WITH_LAST_0(...)') + print('#define __Y_MAP_ARGS_WITH_LAST_1(ACTION, LAST_ACTION, x, ...) LAST_ACTION(x)') + for i in xrange(2, limit + 1): + print('#define __Y_MAP_ARGS_WITH_LAST_{}(ACTION, LAST_ACTION, x, ...) ACTION(x) Y_PASS_VA_ARGS(' + '__Y_MAP_ARGS_WITH_LAST_{}(ACTION, LAST_ACTION, __VA_ARGS__))'.format(i, i - 1)) def map_args_with_last_n(limit): @@ -148,60 +148,60 @@ def map_args_with_last_n(limit): '__Y_MAP_ARGS_WITH_LAST_N_{}(ACTION, LAST_ACTION, __VA_ARGS__))'.format(i, i, i - 1)) -def all_but_last(limit): - print(textwrap.dedent(''' - /** - * Get all elements but the last one from `__VA_ARGS__`. - * Doesn't work with empty arguments list. - */ - '''.rstrip())) - print('#define Y_ALL_BUT_LAST(...) Y_PASS_VA_ARGS(Y_PASS_VA_ARGS(Y_CAT(__Y_ALL_BUT_LAST_, ' - 'Y_COUNT_ARGS(__VA_ARGS__)))(__VA_ARGS__))') - print('#define __Y_ALL_BUT_LAST_0(...)') - print('#define __Y_ALL_BUT_LAST_1(...)') - for i in xrange(2, limit + 1): - args = ', '.join(map('_{}'.format, xrange(i - 1))) - print('#define __Y_ALL_BUT_LAST_{}({}, ...) {}'.format(i, args, args)) - - -def last(limit): - print(textwrap.dedent(''' - /** - * Get the last element from `__VA_ARGS__`. - * Doesn't work with empty arguments list. - */ - '''.rstrip())) - print('#define Y_LAST(...) Y_PASS_VA_ARGS(' - 'Y_GET_ARG(Y_COUNT_ARGS(__VA_ARGS__), , __VA_ARGS__, {}))'.format(',' * limit)) - - -def impl_dispatcher(): - print(textwrap.dedent(''' - /** - * Macros for implementing overload by number of arguments. - * - * Example usage: - * - * @code{cpp} - * #define I1(arg1) Cout << Y_STRINGIZE(arg1) << Endl; - * #define I2(arg1, arg2) Cout << Y_STRINGIZE(arg1) << ';' << Y_STRINGIZE(arg2) << Endl; - * - * #define Y_PRINT(...) Y_PASS_VA_ARGS(Y_MACRO_IMPL_DISPATCHER_2(__VA_ARGS__, I2, I1)(__VA_ARGS__)) - * @endcode - */ - '''.rstrip())) - print('/// @{') - for i in xrange(2, 11): - args = ', '.join(map('_{}'.format, xrange(i))) - print('#define Y_MACRO_IMPL_DISPATCHER_{}({}, IMPL, ...) IMPL'.format(i, args)) - print('/// }@') - - +def all_but_last(limit): + print(textwrap.dedent(''' + /** + * Get all elements but the last one from `__VA_ARGS__`. + * Doesn't work with empty arguments list. + */ + '''.rstrip())) + print('#define Y_ALL_BUT_LAST(...) Y_PASS_VA_ARGS(Y_PASS_VA_ARGS(Y_CAT(__Y_ALL_BUT_LAST_, ' + 'Y_COUNT_ARGS(__VA_ARGS__)))(__VA_ARGS__))') + print('#define __Y_ALL_BUT_LAST_0(...)') + print('#define __Y_ALL_BUT_LAST_1(...)') + for i in xrange(2, limit + 1): + args = ', '.join(map('_{}'.format, xrange(i - 1))) + print('#define __Y_ALL_BUT_LAST_{}({}, ...) {}'.format(i, args, args)) + + +def last(limit): + print(textwrap.dedent(''' + /** + * Get the last element from `__VA_ARGS__`. + * Doesn't work with empty arguments list. + */ + '''.rstrip())) + print('#define Y_LAST(...) Y_PASS_VA_ARGS(' + 'Y_GET_ARG(Y_COUNT_ARGS(__VA_ARGS__), , __VA_ARGS__, {}))'.format(',' * limit)) + + +def impl_dispatcher(): + print(textwrap.dedent(''' + /** + * Macros for implementing overload by number of arguments. + * + * Example usage: + * + * @code{cpp} + * #define I1(arg1) Cout << Y_STRINGIZE(arg1) << Endl; + * #define I2(arg1, arg2) Cout << Y_STRINGIZE(arg1) << ';' << Y_STRINGIZE(arg2) << Endl; + * + * #define Y_PRINT(...) Y_PASS_VA_ARGS(Y_MACRO_IMPL_DISPATCHER_2(__VA_ARGS__, I2, I1)(__VA_ARGS__)) + * @endcode + */ + '''.rstrip())) + print('/// @{') + for i in xrange(2, 11): + args = ', '.join(map('_{}'.format, xrange(i))) + print('#define Y_MACRO_IMPL_DISPATCHER_{}({}, IMPL, ...) IMPL'.format(i, args)) + print('/// }@') + + def main(): if len(sys.argv) > 2: - sys.stderr.write('Usage: {} [limit=50]\n'.format(sys.argv[0])) + sys.stderr.write('Usage: {} [limit=50]\n'.format(sys.argv[0])) sys.exit(1) - limit = 50 + limit = 50 if len(sys.argv) == 2: limit = int(sys.argv[1]) generate(limit) |