1 /****************************************************************************** 2 * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") 3 * All rights reserved. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 *****************************************************************************/ 18 #ifndef COMMON_MACRO_TRICK_H_ 19 #define COMMON_MACRO_TRICK_H_ 20 21 #pragma once 22 23 ///////////////// variadic macro //////////////////////// 24 25 #if 1 26 // a little more complex version that works with GCC and visual studio 27 28 /// http://stackoverflow.com/questions/9183993/msvc-variadic-macro-expansion 29 #define COUNT_ARGS_IMPL2(_1, _2, _3, _4, _5, _6, _7, _8 , _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, N, ...) N 30 #define COUNT_ARGS_IMPL(args) COUNT_ARGS_IMPL2 args 31 #define COUNT_ARGS(...) COUNT_ARGS_IMPL((__VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)) 32 33 #define MACRO_CHOOSE_HELPER2(base, count) base##count 34 #define MACRO_CHOOSE_HELPER1(base, count) MACRO_CHOOSE_HELPER2(base, count) 35 #define MACRO_CHOOSE_HELPER(base, count) MACRO_CHOOSE_HELPER1(base, count) 36 37 #define MACRO_GLUE(x, y) x y 38 #define VARARG(base, ...) MACRO_GLUE(MACRO_CHOOSE_HELPER(base, COUNT_ARGS(__VA_ARGS__)),(__VA_ARGS__)) 39 // usage 40 /* 41 #define fun1(a) xxxx 42 #define fun2(a, b) xxxx 43 #define fun3(a, b, c) xxxx 44 45 #define fun(...) VARARG(fun, __VA_ARGS__) 46 47 int main(){ 48 fun(1); // calls fun1(1) 49 fun(1, 2); // calls fun2(1,2) 50 fun(1, 2, 3); // calls fun3(1,2,3) 51 } 52 53 */ 54 55 56 #else 57 // a concise version that only works with GCC 58 59 /// http://stackoverflow.com/questions/2124339/c-preprocessor-va-args-number-of-arguments 60 61 #define VA_NARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8 , _9, _10, N, ...) N 62 #define VA_NARGS(...) VA_NARGS_IMPL(X,##__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) 63 #define VARARG_IMPL2(base, count, ...) base##count(__VA_ARGS__) 64 #define VARARG_IMPL(base, count, ...) VARARG_IMPL2(base, count, __VA_ARGS__) 65 #define VARARG(base, ...) VARARG_IMPL(base, VA_NARGS(__VA_ARGS__), __VA_ARGS__) 66 67 #endif 68 // #define NUMARGS(...) (sizeof((int[]){__VA_ARGS__})/sizeof(int)) 69 70 ///////////////// end of variadic macro ////////////////////// 71 72 73 74 #endif /* COMMON_MACRO_TRICK_H_ */ 75