C/C++__VA_ARGS__学习--自动打印函数的参数和返回值
通过__VA_ARGS__,自动打印函数的参数和返回值
一.参考
二.输出
bash
input:A StructA= StructA[1,2,3,4,10,11,12,13,]
input:B StructB*= StructB[26,27,28,29,StructA[1,2,3,4,10,11,12,13,]]
input:C int= 1000
input:D float= 2000.2
output:ret "StructA"= StructA[101,2,3,4,10,11,12,13,]
三.代码
cpp
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/types.h>
#include <iostream>
#include <string>
#include <algorithm>
#define IDENTITY(x) x
#define FL_CONCAT(x, y) x##y
// 计算 __VA_ARGS__ 参数个数,最大支持64个参数 https://blog.csdn.net/10km/article/details/80769615
#define FL_TYPEVALUES_COUNT(...) FL_INTERNAL_ARG_COUNT_PRIVATE(0, ##__VA_ARGS__,\
64, 63, 62, 61, 60, \
59, 58, 57, 56, 55, 54, 53, 52, 51, 50, \
49, 48, 47, 46, 45, 44, 43, 42, 41, 40, \
39, 38, 37, 36, 35, 34, 33, 32, 31, 30, \
29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \
19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \
9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#define FL_INTERNAL_ARG_COUNT_PRIVATE(\
_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, \
_10, _11, _12, _13, _14, _15, _16, _17, _18, _19, \
_20, _21, _22, _23, _24, _25, _26, _27, _28, _29, \
_30, _31, _32, _33, _34, _35, _36, _37, _38, _39, \
_40, _41, _42, _43, _44, _45, _46, _47, _48, _49, \
_50, _51, _52, _53, _54, _55, _56, _57, _58, _59, \
_60, _61, _62, _63, _64, N, ...) N
#define FL_TYPEVALUES0()
#define FL_TYPEVALUES2(t, v) t v
#define FL_TYPEVALUES4(t, v, ...) FL_TYPEVALUES2(t, v), IDENTITY(FL_TYPEVALUES2(__VA_ARGS__))
#define FL_TYPEVALUES6(t, v, ...) FL_TYPEVALUES2(t, v), IDENTITY(FL_TYPEVALUES4(__VA_ARGS__))
#define FL_TYPEVALUES8(t, v, ...) FL_TYPEVALUES2(t, v), IDENTITY(FL_TYPEVALUES6(__VA_ARGS__))
#define FL_TYPEVALUES10(t, v, ...) FL_TYPEVALUES2(t, v), IDENTITY(FL_TYPEVALUES8(__VA_ARGS__))
#define FL_VALUES_0()
#define FL_VALUES_2(t, v) v
#define FL_VALUES_4(t, v, ...) FL_VALUES_2(t, v), FL_VALUES_2(__VA_ARGS__)
#define FL_VALUES_6(t, v, ...) FL_VALUES_2(t, v), FL_VALUES_4(__VA_ARGS__)
#define FL_VALUES_8(t, v, ...) FL_VALUES_2(t, v), FL_VALUES_6(__VA_ARGS__)
#define FL_VALUES_10(t, v, ...) FL_VALUES_2(t, v), FL_VALUES_8(__VA_ARGS__)
#define FL_VALUES_12(t, v, ...) FL_VALUES_2(t, v), FL_VALUES_10(__VA_ARGS__)
#define FL_TYPEVALUES__(count, ...) IDENTITY(FL_CONCAT(FL_TYPEVALUES, count)(__VA_ARGS__))
#define FL_TYPEVALUES_(count, ...) FL_TYPEVALUES__(count, __VA_ARGS__)
#define FL_TYPEVALUES(...) FL_TYPEVALUES_(FL_TYPEVALUES_COUNT(__VA_ARGS__), __VA_ARGS__)
#define FL_VALUES__(count, ...) FL_VALUES_##count(__VA_ARGS__)
#define FL_VALUES_(count, ...) FL_VALUES__(count, __VA_ARGS__)
#define FL_VALUES(...) FL_VALUES_(FL_TYPEVALUES_COUNT(__VA_ARGS__), __VA_ARGS__)
template <typename T>
void PRINT_V(T name) {
std::cout << name;
}
template <typename T>
void PRINT_V(T* name) {
std::cout << *name;
}
#define PRINT_ARGS2(t, v) \
printf("input:%s %s= ",#v, #t); \
PRINT_V(v); \
printf("\n"); \
fflush(stdout);
#define PRINT_ARGS4(t, v, ...) PRINT_ARGS2(t, v) PRINT_ARGS2(__VA_ARGS__)
#define PRINT_ARGS6(t, v, ...) PRINT_ARGS2(t, v) PRINT_ARGS4(__VA_ARGS__)
#define PRINT_ARGS8(t, v, ...) PRINT_ARGS2(t, v) PRINT_ARGS6(__VA_ARGS__)
#define PRINT_ARGS10(t, v, ...) PRINT_ARGS2(t, v) PRINT_ARGS8(__VA_ARGS__)
#define PRINT_ARGS12(t, v, ...) PRINT_ARGS2(t, v) PRINT_ARGS10(__VA_ARGS__)
#define PRINT_ARGS__(count, ...) PRINT_ARGS##count(__VA_ARGS__)
#define PRINT_ARGS_(count, ...) PRINT_ARGS__(count, __VA_ARGS__)
#define PRINT_ARGS(...) PRINT_ARGS_(FL_TYPEVALUES_COUNT(__VA_ARGS__), __VA_ARGS__)
#define PRINT_RET(t, v) printf("output:%s %s= ",#v, #t); PRINT_V(v); printf("\n"); fflush(stdout);
#define SDK_PROXY(t, name, ...) \
t internal_##name(FL_TYPEVALUES(__VA_ARGS__)); \
t name(FL_TYPEVALUES(__VA_ARGS__)) { \
PRINT_ARGS(__VA_ARGS__); \
t ret = internal_##name(FL_VALUES(__VA_ARGS__)); \
PRINT_RET(#t, ret); \
return ret; \
} \
t internal_##name(FL_TYPEVALUES(__VA_ARGS__))
struct StructA
{
int A;
char B;
float C;
char* D;
int E[4];
friend std::ostream & operator<<(std::ostream &out, StructA &A)
{
out << "StructA["<<A.A <<","<< A.B<<","<<A.C<<","<<A.D<<",";
std::for_each(std::begin(A.E),
std::end(A.E),
[](const int &e) {
std::cout << e << ",";
});
out<<"]";
return out;
}
};
struct StructB
{
int A[4];
StructA B;
friend std::ostream & operator<<(std::ostream &out, StructB &A)
{
out << "StructB[";
std::for_each(std::begin(A.A),
std::end(A.A),
[](const int &e) {
std::cout << e << ",";
});
out<< A.B<<"]";
return out;
}
};
StructA user_api(StructA A,StructB* B);
SDK_PROXY(StructA, user_api,StructA,A,StructB*,B,int,C,float,D)
{
StructA ret=A;
ret.A+=100;
return ret;
}
int main(int argc,char*argv[])
{
StructA A;
StructB B;
A.A=1;
A.B='2';
A.C=3.0;
A.D="4";
int array0[]={10,11,12,13};
std::copy(std::begin(array0), std::end(array0), std::begin(A.E));
B.B=A;
int array1[]={26,27,28,29};
std::copy(std::begin(array1), std::end(array1), std::begin(B.A));
StructA ret=user_api(A,&B,1000,2000.2);
return 0;
}