#include <iostream>
#include <sstream>
#include <cstdint>
struct Callback
{
virtual void dosomething(uint8_t level, const char *msg) = 0;
};
Callback *callback = nullptr;
void log_impl(std::ostream&) {}
template<typename T, typename ... Args>
void log_impl(std::ostream &os, const T &first_arg, const Args&... args)
{
os << first_arg;
log_impl(os, args...);
}
template<typename ... Args>
void log(uint8_t level, const Args&... args)
{
std::ostringstream msg;
log_impl(msg, args...);
callback->dosomething(level, msg.str().c_str()); // some api
}
struct MyCallback : Callback
{
void dosomething(uint8_t level, const char *msg) override { std::cout << "[" << int(level) << "]: " << msg << std::endl; }
};
int main()
{
MyCallback cb;
callback = &cb;
log(1, "Hello ", "World", '!', " ", 12345);
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3N0cmVhbT4KI2luY2x1ZGUgPGNzdGRpbnQ+CgpzdHJ1Y3QgQ2FsbGJhY2sKewoJdmlydHVhbCB2b2lkIGRvc29tZXRoaW5nKHVpbnQ4X3QgbGV2ZWwsIGNvbnN0IGNoYXIgKm1zZykgPSAwOwp9OwoKQ2FsbGJhY2sgKmNhbGxiYWNrID0gbnVsbHB0cjsKCnZvaWQgbG9nX2ltcGwoc3RkOjpvc3RyZWFtJikge30KCnRlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lIC4uLiBBcmdzPgp2b2lkIGxvZ19pbXBsKHN0ZDo6b3N0cmVhbSAmb3MsIGNvbnN0IFQgJmZpcnN0X2FyZywgY29uc3QgQXJncyYuLi4gYXJncykKewogICAgb3MgPDwgZmlyc3RfYXJnOwogICAgbG9nX2ltcGwob3MsIGFyZ3MuLi4pOwp9Cgp0ZW1wbGF0ZTx0eXBlbmFtZSAuLi4gQXJncz4Kdm9pZCBsb2codWludDhfdCBsZXZlbCwgY29uc3QgQXJncyYuLi4gYXJncykKewogICAgc3RkOjpvc3RyaW5nc3RyZWFtIG1zZzsKICAgIGxvZ19pbXBsKG1zZywgYXJncy4uLik7CiAgICBjYWxsYmFjay0+ZG9zb21ldGhpbmcobGV2ZWwsIG1zZy5zdHIoKS5jX3N0cigpKTsgLy8gc29tZSBhcGkKfQoKc3RydWN0IE15Q2FsbGJhY2sgOiBDYWxsYmFjawp7Cgl2b2lkIGRvc29tZXRoaW5nKHVpbnQ4X3QgbGV2ZWwsIGNvbnN0IGNoYXIgKm1zZykgb3ZlcnJpZGUgeyBzdGQ6OmNvdXQgPDwgIlsiIDw8IGludChsZXZlbCkgPDwgIl06ICIgPDwgbXNnIDw8IHN0ZDo6ZW5kbDsgfQp9OwoKaW50IG1haW4oKQp7CglNeUNhbGxiYWNrIGNiOwoJY2FsbGJhY2sgPSAmY2I7CgoJbG9nKDEsICJIZWxsbyAiLCAiV29ybGQiLCAnIScsICIgIiwgMTIzNDUpOwoKCXJldHVybiAwOwp9