printf 整数类型都用 uint8_t
#include <iostream>
#include <string>
#include <tuple>
#include <utility>
#include <array>
#include <string>
template<char...>
struct STRING
{
};
template<typename>
struct STRING_LITERAL;
template<char... S>
struct STRING_LITERAL<STRING<S...>>
{
static const char s[sizeof...(S)+1];
};
template<char... S>
const char STRING_LITERAL<STRING<S...>>::s[sizeof...(S)+1] = {S..., 0};
template<typename>
struct MOD;
template<>
struct MOD<unsigned char>
{
using TYPE = STRING<'h', 'h', 'u'>;
};
template<>
struct MOD<signed char>
{
using TYPE = STRING<'h', 'h', 'u'>;
};
template<>
struct MOD<unsigned short>
{
using TYPE = STRING<'h', 'u'>;
};
template<typename, typename>
struct CONCAT;
template<char... S1, char... S2>
struct CONCAT<STRING<S1...>, STRING<S2...>>
{
using TYPE = STRING<S1..., S2...>;
};
template<char...>
struct CONVERT;
template<>
struct CONVERT<> {
using TYPE = STRING<>;
};
template<char... S>
struct CONVERT<'`', '`', S...>
{
using TYPE = typename CONCAT<STRING<'`'>, typename CONVERT<S...>::TYPE>::TYPE;
};
template<char... S>
struct CONVERT<'`', '8', 'u', S...>
{
using TYPE = typename CONCAT<typename MOD<uint8_t>::TYPE, typename CONVERT<S...>::TYPE>::TYPE;
};
template<char... S>
struct CONVERT<'`', '8', 'd', S...>
{
using TYPE = typename CONCAT<typename MOD<int8_t>::TYPE, typename CONVERT<S...>::TYPE>::TYPE;
};
template<char C, char... S>
struct CONVERT<C, S...>
{
using TYPE = typename CONCAT<STRING<C>, typename CONVERT<S...>::TYPE>::TYPE;
};
template<typename, typename>
struct MAKE_STRING;
template<typename S, template<typename U, U...> class T, typename U, U... I>
struct MAKE_STRING<S, T<U, I...>>
{
using TYPE = typename CONVERT<S{}.s[I]...>::TYPE;
};
template<typename S>
using FORMAT_STRING = STRING_LITERAL<typename MAKE_STRING<S, std::make_index_sequence<sizeof(S)-1>>::TYPE>;
#define FORMAT(str) ({ struct S { const char s[sizeof(str)] = (str); }; FORMAT_STRING<S>::s;})
int main()
{
uint8_t x = 100;
printf(FORMAT("``%`8u\n"), x);
}