【NanoLog】工作线程源码剖析
NanoLogCpp17.h
NANO_LOG宏
使用示例:
NANO_LOG(NOTICE, “Hello World! This is an integer %d and a double %lf\r\n”, 1, 2.0);
#define NANO_LOG(severity, format, ...)
第一个参数是LogLevel:一个enum类型,表示日志消息的级别。
第二个参数format:是格式化字符串
会被调用
constexpr int numNibbles = NanoLogInternal::getNumNibblesNeeded(format);
template<size_t N>
constexpr int
getNumNibblesNeeded(const char (&fmt)[N])
{
int numNibbles = 0;
for (int i = 0; i < countFmtParams(fmt); ++i) {
ParamType t = getParamInfo(fmt, i);
if (t == NON_STRING || t == DYNAMIC_PRECISION || t == DYNAMIC_WIDTH)
++numNibbles;
}
return numNibbles;
}
getNumNibblesNeeded是一个constexpr函数,如果参数在编译期已知,就可以在编译期间进行运算了。还是一个模板函数,根据fmt的数组长度会泛化不同的函数。
countFmtParames会根据fmt计算出有多少个参数,最后得到需要多少个numNibbles: 存储所有参数所需的nibbles数量
constexpr int nParams = NanoLogInternal::countFmtParams(format);
nParams就从fmt中获得一共有多少个参数
- numNibbles:格式化字符串中,非字符串类型的参数个数,比如
%d
,%l
等参数的个数 - nParams: 格式化字符串中,参数的个数,相当于是
%
的个数
下面这些必须是 "静态 "的,这样我们就可以保存这些变量的指针,并让它们在调用之后继续存在。静态的logId被用来将这个局部范围(与#NANO_LOG的扩展相联系)与一个ID联系起来,paramTypes数组被压缩函数使用,该函数在另一个线程中被调用在一个更晚的时间调用。
//paramTypes在编译期就算出来了,是一个存放参数类型,长度为参数个数的数组。
//通过调用analyzeFormaString模板函数,模板参数是参数个数,函数实参是格式化字符串
static constexpr std::array<NanoLogInternal::ParamType, nParams> paramTypes = \
NanoLogInternal::analyzeFormatString<nParams>(format); \
static int logId = NanoLogInternal::UNASSIGNED