可变参数`ELEM`宏观供C使用 [英] Varargs `ELEM` macro for use with C

查看:100
本文介绍了可变参数`ELEM`宏观供C使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道如果theres普遍使用,在 ELEM 比较宏观其中:

I was wondering if theres an ELEM comparison macro in general use, where:

(V == ||一== v B)

可以替换为:

ELEM(V,A,B)

当然,这可以用宏做的,

Of course this can be done with a macro,

的#define ELEM(V,A,B)(((五)==(a)条)||((V)==(B)))

不过那你最终需要定义与说法计数多个宏。

However Then you end up needing to define multiple macros with argument counts.

使用我想出了这个简单的Python脚本:

Using a simple python script I came up with this:

 #define ELEM2(v, a, b) \
        (((v) == (a)) || ((v) == (b)))
 #define ELEM3(v, a, b, c) \
        (ELEM2(v, a, b) || ((v) == (c)))
 #define ELEM4(v, a, b, c, d) \
        (ELEM3(v, a, b, c) || ((v) == (d)))
 #define ELEM5(v, a, b, c, d, e) \
        (ELEM4(v, a, b, c, d) || ((v) == (e)))
 #define ELEM6(v, a, b, c, d, e, f) \
        (ELEM5(v, a, b, c, d, e) || ((v) == (f)))
 #define ELEM7(v, a, b, c, d, e, f, g) \
        (ELEM6(v, a, b, c, d, e, f) || ((v) == (g)))
 #define ELEM8(v, a, b, c, d, e, f, g, h) \
        (ELEM7(v, a, b, c, d, e, f, g) || ((v) == (h)))
 #define ELEM9(v, a, b, c, d, e, f, g, h, i) \
        (ELEM8(v, a, b, c, d, e, f, g, h) || ((v) == (i)))
 #define ELEM10(v, a, b, c, d, e, f, g, h, i, j) \
        (ELEM9(v, a, b, c, d, e, f, g, h, i) || ((v) == (j)))
 #define ELEM11(v, a, b, c, d, e, f, g, h, i, j, k) \
        (ELEM10(v, a, b, c, d, e, f, g, h, i, j) || ((v) == (k)))
 #define ELEM12(v, a, b, c, d, e, f, g, h, i, j, k, l) \
        (ELEM11(v, a, b, c, d, e, f, g, h, i, j, k) || ((v) == (l)))
 #define ELEM13(v, a, b, c, d, e, f, g, h, i, j, k, l, m) \
        (ELEM12(v, a, b, c, d, e, f, g, h, i, j, k, l) || ((v) == (m)))
 #define ELEM14(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n) \
        (ELEM13(v, a, b, c, d, e, f, g, h, i, j, k, l, m) || ((v) == (n)))
 #define ELEM15(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) \
        (ELEM14(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n) || ((v) == (o)))
 #define ELEM16(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) \
        (ELEM15(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) || ((v) == (p)))

从这个python3脚本:

From this python3-script:

ELEM_TOTAL = 16
for i in range(2, ELEM_TOTAL + 1):
    print("#define ELEM%d(" % i, end="")
    print("v, ", end="")
    args = [chr(ord('a') + j) for j in range(i)]
    print(", ".join(args), end="")
    print(") \\\n       (", end="")
    if i == 2:
        print("((v) == (a)) || ((v) == (b))", end="")
    else:
        print("ELEM%d(v, %s) || ((v) == (%s))" % (i - 1, ", ".join(args[:-1]), args[-1]), end="")
    print(")")

但如果有常用的任何 ELEM 宏其接受可变数量的参数,而且我想知道至少有足够的便携式与流行的C编译器的工作(海合会,锵,英特尔,MCVC)。

But I was wondering if there are any ELEM macros in common use which accept a variable number of arguments and are at least portable enough to work with popular C compilers (GCC, Clang, Intel, MCVC).

推荐答案

根据答案来这个问题,我有一个可变参数ELEM宏我觉得挺作品可移植的,尽管它取决于 __ __ VA_ARGS ,但不认为这能有所帮助。

Based on the answer to this question, I have a varargs ELEM macro I think works quite portably, though it depends on __VA_ARGS__ but dont think that can be helped.

使用示例:

if (ELEM(var, A, B)) {
    ....
}
else if (ELEM(var, C, D, E, F, G)) {
    ....
}

执行力度:

#include <stdio.h>

/* ------ */
/* Macros */

/* internal helpers */
#define _VA_NARGS_GLUE(x, y) x y
#define _VA_NARGS_RETURN_COUNT(_1_, _2_, _3_, _4_, _5_, _6_, _7_, _8_, _9_, _10_, _11_, _12_, _13_, _14_, _15_, _16_, count, ...) count
#define _VA_NARGS_EXPAND(args) _VA_NARGS_RETURN_COUNT args
#define _VA_NARGS_COUNT_MAX16(...) _VA_NARGS_EXPAND((__VA_ARGS__, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))

#define _VA_NARGS_OVERLOAD_MACRO2(name, count) name##count
#define _VA_NARGS_OVERLOAD_MACRO1(name, count) _VA_NARGS_OVERLOAD_MACRO2(name, count)
#define _VA_NARGS_OVERLOAD_MACRO(name,  count) _VA_NARGS_OVERLOAD_MACRO1(name, count)

/* expose for re-use */
#define VA_NARGS_CALL_OVERLOAD(name, ...) _VA_NARGS_GLUE(_VA_NARGS_OVERLOAD_MACRO(name, _VA_NARGS_COUNT_MAX16(__VA_ARGS__)), (__VA_ARGS__))

/* ---------- */
/* ELEM Macro */

/* internal helpers*/
#define _VA_ELEM3(v, a, b) \
       (((v) == (a)) || ((v) == (b)))
#define _VA_ELEM4(v, a, b, c) \
       (_VA_ELEM3(v, a, b) || ((v) == (c)))
#define _VA_ELEM5(v, a, b, c, d) \
       (_VA_ELEM4(v, a, b, c) || ((v) == (d)))
#define _VA_ELEM6(v, a, b, c, d, e) \
       (_VA_ELEM5(v, a, b, c, d) || ((v) == (e)))
#define _VA_ELEM7(v, a, b, c, d, e, f) \
       (_VA_ELEM6(v, a, b, c, d, e) || ((v) == (f)))
#define _VA_ELEM8(v, a, b, c, d, e, f, g) \
       (_VA_ELEM7(v, a, b, c, d, e, f) || ((v) == (g)))
#define _VA_ELEM9(v, a, b, c, d, e, f, g, h) \
       (_VA_ELEM8(v, a, b, c, d, e, f, g) || ((v) == (h)))
#define _VA_ELEM10(v, a, b, c, d, e, f, g, h, i) \
       (_VA_ELEM9(v, a, b, c, d, e, f, g, h) || ((v) == (i)))
#define _VA_ELEM11(v, a, b, c, d, e, f, g, h, i, j) \
       (_VA_ELEM10(v, a, b, c, d, e, f, g, h, i) || ((v) == (j)))
#define _VA_ELEM12(v, a, b, c, d, e, f, g, h, i, j, k) \
       (_VA_ELEM11(v, a, b, c, d, e, f, g, h, i, j) || ((v) == (k)))
#define _VA_ELEM13(v, a, b, c, d, e, f, g, h, i, j, k, l) \
       (_VA_ELEM12(v, a, b, c, d, e, f, g, h, i, j, k) || ((v) == (l)))
#define _VA_ELEM14(v, a, b, c, d, e, f, g, h, i, j, k, l, m) \
       (_VA_ELEM13(v, a, b, c, d, e, f, g, h, i, j, k, l) || ((v) == (m)))
#define _VA_ELEM15(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n) \
       (_VA_ELEM14(v, a, b, c, d, e, f, g, h, i, j, k, l, m) || ((v) == (n)))
#define _VA_ELEM16(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) \
       (_VA_ELEM15(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n) || ((v) == (o)))
#define _VA_ELEM17(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) \
       (_VA_ELEM16(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) || ((v) == (p)))
/* reusable ELEM macro */
#define ELEM(...) VA_NARGS_CALL_OVERLOAD(_VA_ELEM, __VA_ARGS__)

/* ------- */
/* Example */


int main(void)
{
    int i;

    i = 1 + 1;
    printf("Test 1+1, in (3, 2, 1)? -> %d\n", ELEM(i, 3, 2, 1));

    i = 22;
    printf("Test 22, in (2/4, 10*2, 42, 100, 44/3)? -> %d\n", ELEM(i, 2 / 4, 10 * 2, 42, 100, 44 / 3));
    return 0;
}

请注意, _VA_ELEM#这个python3脚本生成的:

Note, _VA_ELEM# generated with this python3-script:

ELEM_TOTAL = 16
for i in range(2, ELEM_TOTAL + 1):
    print("#define _VA_ELEM%d(" % (i + 1), end="")
    print("v, ", end="")
    args = [chr(ord('a') + j) for j in range(i)]
    print(", ".join(args), end="")
    print(") \\\n       (", end="")
    if i == 2:
        print("((v) == (a)) || ((v) == (b))", end="")
    else:
        print("_VA_ELEM%d(v, %s) || ((v) == (%s))" % (i, ", ".join(args[:-1]), args[-1]), end="")
    print(")")

这篇关于可变参数`ELEM`宏观供C使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆