125 #ifndef TINYFORMAT_H_INCLUDED 126 #define TINYFORMAT_H_INCLUDED 136 #define TINYFORMAT_ERROR(reasonString) \ 137 throw tinyformat::format_error(reasonString) 141 #define TINYFORMAT_USE_VARIADIC_TEMPLATES 150 #ifndef TINYFORMAT_ASSERT 152 #define TINYFORMAT_ASSERT(cond) assert(cond) 155 #ifndef TINYFORMAT_ERROR 157 #define TINYFORMAT_ERROR(reason) assert(0 && reason) 160 #if !defined(TINYFORMAT_USE_VARIADIC_TEMPLATES) && \ 161 !defined(TINYFORMAT_NO_VARIADIC_TEMPLATES) 162 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 163 #define TINYFORMAT_USE_VARIADIC_TEMPLATES 167 #if defined(__GLIBCXX__) && __GLIBCXX__ < 20080201 170 #define TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND 176 #define TINYFORMAT_HIDDEN __attribute__((visibility("hidden"))) 178 #define TINYFORMAT_HIDDEN 203 static fail tryConvert(...);
204 static succeed tryConvert(
const T2 &);
205 static const T1 &makeT1();
210 #pragma warning(push) 211 #pragma warning(disable : 4244) 212 #pragma warning(disable : 4267) 218 static const bool value =
219 sizeof(tryConvert(makeT1())) ==
sizeof(
succeed);
231 template <
int n>
struct is_wchar<const wchar_t[n]> {};
236 template <
typename T,
typename fmtT,
239 static void invoke(std::ostream & ,
const T & ) {
245 template <
typename T,
typename fmtT>
247 static void invoke(std::ostream &out,
const T &value) {
248 out << static_cast<fmtT>(value);
252 #ifdef TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND 253 template <typename T, bool convertible = is_convertible<T, int>::value>
254 struct formatZeroIntegerWorkaround {
255 static bool invoke(std::ostream & ,
const T & ) {
259 template <
typename T>
struct formatZeroIntegerWorkaround<T, true> {
260 static bool invoke(std::ostream &out,
const T &value) {
261 if (static_cast<int>(value) == 0 &&
262 out.flags() & std::ios::showpos) {
269 #endif // TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND 273 template <typename T, bool convertible = is_convertible<T, int>::value>
277 "integer for use as variable width or precision");
283 static int invoke(
const T &value) {
return static_cast<int>(value); }
287 template <
typename T>
289 std::ostringstream tmp;
291 std::string result = tmp.str();
292 out.write(result.c_str(),
293 (std::min)(ntrunc, static_cast<int>(result.size())));
295 #define TINYFORMAT_DEFINE_FORMAT_TRUNCATED_CSTR(type) \ 296 inline void formatTruncated(std::ostream &out, type *value, int ntrunc) { \ 297 std::streamsize len = 0; \ 298 while (len < ntrunc && value[len] != 0) \ 300 out.write(value, len); \ 306 #undef TINYFORMAT_DEFINE_FORMAT_TRUNCATED_CSTR 325 template <
typename T>
327 const char *fmtEnd,
int ntrunc,
const T &value) {
328 #ifndef TINYFORMAT_ALLOW_WCHAR_STRINGS 341 const bool canConvertToVoidPtr =
343 if (canConvertToChar && *(fmtEnd - 1) ==
'c')
345 else if (canConvertToVoidPtr && *(fmtEnd - 1) ==
'p')
347 #ifdef TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND 348 else if (detail::formatZeroIntegerWorkaround<T>::invoke(out, value))
351 else if (ntrunc >= 0) {
360 #define TINYFORMAT_DEFINE_FORMATVALUE_CHAR(charType) \ 361 inline void formatValue(std::ostream &out, const char * , \ 362 const char *fmtEnd, int , charType value) { \ 363 switch (*(fmtEnd - 1)) { \ 370 out << static_cast<int>(value); \ 381 #undef TINYFORMAT_DEFINE_FORMATVALUE_CHAR 388 #define TINYFORMAT_ARGTYPES(n) TINYFORMAT_ARGTYPES_##n 389 #define TINYFORMAT_VARARGS(n) TINYFORMAT_VARARGS_##n 390 #define TINYFORMAT_PASSARGS(n) TINYFORMAT_PASSARGS_##n 391 #define TINYFORMAT_PASSARGS_TAIL(n) TINYFORMAT_PASSARGS_TAIL_##n 429 #define TINYFORMAT_ARGTYPES_1 class T1 430 #define TINYFORMAT_ARGTYPES_2 class T1, class T2 431 #define TINYFORMAT_ARGTYPES_3 class T1, class T2, class T3 432 #define TINYFORMAT_ARGTYPES_4 class T1, class T2, class T3, class T4 433 #define TINYFORMAT_ARGTYPES_5 class T1, class T2, class T3, class T4, class T5 434 #define TINYFORMAT_ARGTYPES_6 \ 435 class T1, class T2, class T3, class T4, class T5, class T6 436 #define TINYFORMAT_ARGTYPES_7 \ 437 class T1, class T2, class T3, class T4, class T5, class T6, class T7 438 #define TINYFORMAT_ARGTYPES_8 \ 439 class T1, class T2, class T3, class T4, class T5, class T6, class T7, \ 441 #define TINYFORMAT_ARGTYPES_9 \ 442 class T1, class T2, class T3, class T4, class T5, class T6, class T7, \ 444 #define TINYFORMAT_ARGTYPES_10 \ 445 class T1, class T2, class T3, class T4, class T5, class T6, class T7, \ 446 class T8, class T9, class T10 447 #define TINYFORMAT_ARGTYPES_11 \ 448 class T1, class T2, class T3, class T4, class T5, class T6, class T7, \ 449 class T8, class T9, class T10, class T11 450 #define TINYFORMAT_ARGTYPES_12 \ 451 class T1, class T2, class T3, class T4, class T5, class T6, class T7, \ 452 class T8, class T9, class T10, class T11, class T12 453 #define TINYFORMAT_ARGTYPES_13 \ 454 class T1, class T2, class T3, class T4, class T5, class T6, class T7, \ 455 class T8, class T9, class T10, class T11, class T12, class T13 456 #define TINYFORMAT_ARGTYPES_14 \ 457 class T1, class T2, class T3, class T4, class T5, class T6, class T7, \ 458 class T8, class T9, class T10, class T11, class T12, class T13, \ 460 #define TINYFORMAT_ARGTYPES_15 \ 461 class T1, class T2, class T3, class T4, class T5, class T6, class T7, \ 462 class T8, class T9, class T10, class T11, class T12, class T13, \ 464 #define TINYFORMAT_ARGTYPES_16 \ 465 class T1, class T2, class T3, class T4, class T5, class T6, class T7, \ 466 class T8, class T9, class T10, class T11, class T12, class T13, \ 467 class T14, class T15, class T16 469 #define TINYFORMAT_VARARGS_1 const T1 &v1 470 #define TINYFORMAT_VARARGS_2 const T1 &v1, const T2 &v2 471 #define TINYFORMAT_VARARGS_3 const T1 &v1, const T2 &v2, const T3 &v3 472 #define TINYFORMAT_VARARGS_4 \ 473 const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4 474 #define TINYFORMAT_VARARGS_5 \ 475 const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5 476 #define TINYFORMAT_VARARGS_6 \ 477 const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, \ 479 #define TINYFORMAT_VARARGS_7 \ 480 const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, \ 481 const T6 &v6, const T7 &v7 482 #define TINYFORMAT_VARARGS_8 \ 483 const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, \ 484 const T6 &v6, const T7 &v7, const T8 &v8 485 #define TINYFORMAT_VARARGS_9 \ 486 const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, \ 487 const T6 &v6, const T7 &v7, const T8 &v8, const T9 &v9 488 #define TINYFORMAT_VARARGS_10 \ 489 const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, \ 490 const T6 &v6, const T7 &v7, const T8 &v8, const T9 &v9, const T10 &v10 491 #define TINYFORMAT_VARARGS_11 \ 492 const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, \ 493 const T6 &v6, const T7 &v7, const T8 &v8, const T9 &v9, \ 494 const T10 &v10, const T11 &v11 495 #define TINYFORMAT_VARARGS_12 \ 496 const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, \ 497 const T6 &v6, const T7 &v7, const T8 &v8, const T9 &v9, \ 498 const T10 &v10, const T11 &v11, const T12 &v12 499 #define TINYFORMAT_VARARGS_13 \ 500 const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, \ 501 const T6 &v6, const T7 &v7, const T8 &v8, const T9 &v9, \ 502 const T10 &v10, const T11 &v11, const T12 &v12, const T13 &v13 503 #define TINYFORMAT_VARARGS_14 \ 504 const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, \ 505 const T6 &v6, const T7 &v7, const T8 &v8, const T9 &v9, \ 506 const T10 &v10, const T11 &v11, const T12 &v12, const T13 &v13, \ 508 #define TINYFORMAT_VARARGS_15 \ 509 const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, \ 510 const T6 &v6, const T7 &v7, const T8 &v8, const T9 &v9, \ 511 const T10 &v10, const T11 &v11, const T12 &v12, const T13 &v13, \ 512 const T14 &v14, const T15 &v15 513 #define TINYFORMAT_VARARGS_16 \ 514 const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, \ 515 const T6 &v6, const T7 &v7, const T8 &v8, const T9 &v9, \ 516 const T10 &v10, const T11 &v11, const T12 &v12, const T13 &v13, \ 517 const T14 &v14, const T15 &v15, const T16 &v16 519 #define TINYFORMAT_PASSARGS_1 v1 520 #define TINYFORMAT_PASSARGS_2 v1, v2 521 #define TINYFORMAT_PASSARGS_3 v1, v2, v3 522 #define TINYFORMAT_PASSARGS_4 v1, v2, v3, v4 523 #define TINYFORMAT_PASSARGS_5 v1, v2, v3, v4, v5 524 #define TINYFORMAT_PASSARGS_6 v1, v2, v3, v4, v5, v6 525 #define TINYFORMAT_PASSARGS_7 v1, v2, v3, v4, v5, v6, v7 526 #define TINYFORMAT_PASSARGS_8 v1, v2, v3, v4, v5, v6, v7, v8 527 #define TINYFORMAT_PASSARGS_9 v1, v2, v3, v4, v5, v6, v7, v8, v9 528 #define TINYFORMAT_PASSARGS_10 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 529 #define TINYFORMAT_PASSARGS_11 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11 530 #define TINYFORMAT_PASSARGS_12 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12 531 #define TINYFORMAT_PASSARGS_13 \ 532 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13 533 #define TINYFORMAT_PASSARGS_14 \ 534 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14 535 #define TINYFORMAT_PASSARGS_15 \ 536 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 537 #define TINYFORMAT_PASSARGS_16 \ 538 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16 540 #define TINYFORMAT_PASSARGS_TAIL_1 541 #define TINYFORMAT_PASSARGS_TAIL_2 , v2 542 #define TINYFORMAT_PASSARGS_TAIL_3 , v2, v3 543 #define TINYFORMAT_PASSARGS_TAIL_4 , v2, v3, v4 544 #define TINYFORMAT_PASSARGS_TAIL_5 , v2, v3, v4, v5 545 #define TINYFORMAT_PASSARGS_TAIL_6 , v2, v3, v4, v5, v6 546 #define TINYFORMAT_PASSARGS_TAIL_7 , v2, v3, v4, v5, v6, v7 547 #define TINYFORMAT_PASSARGS_TAIL_8 , v2, v3, v4, v5, v6, v7, v8 548 #define TINYFORMAT_PASSARGS_TAIL_9 , v2, v3, v4, v5, v6, v7, v8, v9 549 #define TINYFORMAT_PASSARGS_TAIL_10 , v2, v3, v4, v5, v6, v7, v8, v9, v10 550 #define TINYFORMAT_PASSARGS_TAIL_11 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11 551 #define TINYFORMAT_PASSARGS_TAIL_12 \ 552 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12 553 #define TINYFORMAT_PASSARGS_TAIL_13 \ 554 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13 555 #define TINYFORMAT_PASSARGS_TAIL_14 \ 556 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14 557 #define TINYFORMAT_PASSARGS_TAIL_15 \ 558 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 559 #define TINYFORMAT_PASSARGS_TAIL_16 \ 560 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16 562 #define TINYFORMAT_FOREACH_ARGNUM(m) \ 563 m(1) m(2) m(3) m(4) m(5) m(6) m(7) m(8) m(9) m(10) m(11) m(12) m(13) m(14) \ 575 FormatArg() : m_value(NULL), m_formatImpl(NULL), m_toIntImpl(NULL) {}
577 template <
typename T>
579 : m_value(static_cast<const void *>(&value)),
580 m_formatImpl(&
formatImpl<T>), m_toIntImpl(&toIntImpl<T>) {}
582 void format(std::ostream &out,
const char *fmtBegin,
const char *fmtEnd,
586 m_formatImpl(out, fmtBegin, fmtEnd, ntrunc, m_value);
592 return m_toIntImpl(m_value);
596 template <
typename T>
598 formatImpl(std::ostream &out,
const char *fmtBegin,
const char *fmtEnd,
599 int ntrunc,
const void *value) {
601 *static_cast<const T *>(value));
604 template <
typename T>
610 void (*m_formatImpl)(std::ostream &out,
const char *fmtBegin,
611 const char *fmtEnd,
int ntrunc,
const void *value);
612 int (*m_toIntImpl)(
const void *value);
619 for (; *c >=
'0' && *c <=
'9'; ++c)
620 i = 10 * i + (*c -
'0');
632 int &argIndex,
int numArgs) {
633 if (*c >=
'0' && *c <=
'9') {
635 }
else if (*c ==
'*') {
638 if (positionalMode) {
642 "after a positional one");
643 if (pos >= 0 && pos < numArgs)
644 n = args[pos].
toInt();
647 "tinyformat: Positional argument out of range");
650 if (argIndex < numArgs)
651 n = args[argIndex++].
toInt();
654 "variable width or precision");
672 out.write(fmt, c - fmt);
674 }
else if (*c ==
'%') {
675 out.write(fmt, c - fmt);
676 if (*(c + 1) !=
'%')
return c;
719 bool &positionalMode,
720 bool &spacePadPositive,
721 int &ntrunc,
const char *fmtStart,
723 int &argIndex,
int numArgs) {
730 out.unsetf(std::ios::adjustfield | std::ios::basefield |
731 std::ios::floatfield | std::ios::showbase |
732 std::ios::boolalpha | std::ios::showpoint |
733 std::ios::showpos | std::ios::uppercase);
734 bool precisionSet =
false;
735 bool widthSet =
false;
737 const char *c = fmtStart + 1;
741 if (*c >=
'0' && *c <=
'9') {
742 const char tmpc = *c;
746 if (value > 0 && value <= numArgs)
747 argIndex = value - 1;
750 "tinyformat: Positional argument out of range");
752 positionalMode =
true;
753 }
else if (positionalMode) {
755 "after a positional one");
761 out.setf(std::ios::internal, std::ios::adjustfield);
769 }
else if (positionalMode) {
779 out.setf(std::ios::showpoint | std::ios::showbase);
783 if (!(out.flags() & std::ios::left)) {
787 out.setf(std::ios::internal, std::ios::adjustfield);
792 out.setf(std::ios::left, std::ios::adjustfield);
796 if (!(out.flags() & std::ios::showpos))
797 spacePadPositive =
true;
800 out.setf(std::ios::showpos);
801 spacePadPositive =
false;
817 out.setf(std::ios::left, std::ios::adjustfield);
831 precisionSet = precision >= 0;
832 if (precisionSet) out.precision(precision);
835 while (*c ==
'l' || *c ==
'h' || *c ==
'L' || *c ==
'j' || *c ==
'z' ||
842 bool intConversion =
false;
847 out.setf(std::ios::dec, std::ios::basefield);
848 intConversion =
true;
851 out.setf(std::ios::oct, std::ios::basefield);
852 intConversion =
true;
855 out.setf(std::ios::uppercase);
859 out.setf(std::ios::hex, std::ios::basefield);
860 intConversion =
true;
863 out.setf(std::ios::uppercase);
866 out.setf(std::ios::scientific, std::ios::floatfield);
867 out.setf(std::ios::dec, std::ios::basefield);
870 out.setf(std::ios::uppercase);
873 out.setf(std::ios::fixed, std::ios::floatfield);
876 out.setf(std::ios::uppercase);
886 out.setf(std::ios::fixed | std::ios::scientific,
887 std::ios::floatfield);
890 out.setf(std::ios::uppercase);
893 out.setf(std::ios::dec, std::ios::basefield);
895 out.flags(out.flags() & ~
std::ios::floatfield);
901 if (precisionSet) ntrunc =
static_cast<int>(out.precision());
903 out.setf(std::ios::boolalpha);
908 "tinyformat: %n conversion spec not supported");
912 "terminated by end of string");
917 if (intConversion && precisionSet && !widthSet) {
922 out.width(out.precision() + widthExtra);
923 out.setf(std::ios::internal, std::ios::adjustfield);
933 std::streamsize origWidth = out.width();
934 std::streamsize origPrecision = out.precision();
935 std::ios::fmtflags origFlags = out.flags();
936 char origFill = out.fill();
941 bool positionalMode =
false;
946 if (!positionalMode && argIndex < numArgs) {
948 "specifiers in format string");
952 bool spacePadPositive =
false;
956 ntrunc, fmt, args, argIndex, numArgs);
960 if (argIndex >= numArgs) {
967 if (!spacePadPositive) {
968 arg.
format(out, fmt, fmtEnd, ntrunc);
974 std::ostringstream tmpStream;
975 tmpStream.copyfmt(out);
976 tmpStream.setf(std::ios::showpos);
977 arg.
format(tmpStream, fmt, fmtEnd, ntrunc);
978 std::string result = tmpStream.str();
979 for (
size_t i = 0, iend = result.size(); i < iend; ++i) {
980 if (result[i] ==
'+') result[i] =
' ';
984 if (!positionalMode) ++argIndex;
989 out.width(origWidth);
990 out.precision(origPrecision);
991 out.flags(origFlags);
1007 friend void vformat(std::ostream &out,
const char *fmt,
1023 #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES 1024 template <
typename... Args>
1026 :
FormatList(&m_formatterStore[0], N), m_formatterStore{
1028 static_assert(
sizeof...(args) == N,
"Number of args must be N");
1030 #else // C++98 version 1032 #define TINYFORMAT_MAKE_FORMATLIST_CONSTRUCTOR(n) \ 1034 template <TINYFORMAT_ARGTYPES(n)> \ 1035 FormatListN(TINYFORMAT_VARARGS(n)) : FormatList(&m_formatterStore[0], n) { \ 1036 TINYFORMAT_ASSERT(n == N); \ 1037 init(0, TINYFORMAT_PASSARGS(n)); \ 1040 template <TINYFORMAT_ARGTYPES(n)> \ 1041 void init(int i, TINYFORMAT_VARARGS(n)) { \ 1042 m_formatterStore[i] = FormatArg(v1); \ 1043 init(i + 1 TINYFORMAT_PASSARGS_TAIL(n)); \ 1047 #undef TINYFORMAT_MAKE_FORMATLIST_CONSTRUCTOR 1052 &m_formatterStore[0]);
1071 #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES 1079 template <
typename... Args>
1084 #else // C++98 version 1089 #define TINYFORMAT_MAKE_MAKEFORMATLIST(n) \ 1090 template <TINYFORMAT_ARGTYPES(n)> \ 1091 detail::FormatListN<n> makeFormatList(TINYFORMAT_VARARGS(n)) { \ 1092 return detail::FormatListN<n>(TINYFORMAT_PASSARGS(n)); \ 1095 #undef TINYFORMAT_MAKE_MAKEFORMATLIST 1103 inline void vformat(std::ostream &out,
const char *fmt, FormatListRef list) {
1107 #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES 1110 template <
typename... Args>
1111 void format(std::ostream &out,
const char *fmt,
const Args &... args) {
1117 template <
typename... Args>
1118 std::string
format(
const char *fmt,
const Args &... args) {
1119 std::ostringstream oss;
1120 format(oss, fmt, args...);
1125 template <
typename... Args>
void printf(
const char *fmt,
const Args &... args) {
1126 format(std::cout, fmt, args...);
1129 template <
typename... Args>
1131 format(std::cout, fmt, args...);
1135 #else // C++98 version 1137 inline void format(std::ostream &out,
const char *fmt) {
1141 inline std::string
format(
const char *fmt) {
1142 std::ostringstream oss;
1147 inline void printf(
const char *fmt) {
1151 inline void printfln(
const char *fmt) {
1156 #define TINYFORMAT_MAKE_FORMAT_FUNCS(n) \ 1158 template <TINYFORMAT_ARGTYPES(n)> \ 1159 void format(std::ostream &out, const char *fmt, TINYFORMAT_VARARGS(n)) { \ 1160 vformat(out, fmt, makeFormatList(TINYFORMAT_PASSARGS(n))); \ 1163 template <TINYFORMAT_ARGTYPES(n)> \ 1164 std::string format(const char *fmt, TINYFORMAT_VARARGS(n)) { \ 1165 std::ostringstream oss; \ 1166 format(oss, fmt, TINYFORMAT_PASSARGS(n)); \ 1170 template <TINYFORMAT_ARGTYPES(n)> \ 1171 void printf(const char *fmt, TINYFORMAT_VARARGS(n)) { \ 1172 format(std::cout, fmt, TINYFORMAT_PASSARGS(n)); \ 1175 template <TINYFORMAT_ARGTYPES(n)> \ 1176 void printfln(const char *fmt, TINYFORMAT_VARARGS(n)) { \ 1177 format(std::cout, fmt, TINYFORMAT_PASSARGS(n)); \ 1178 std::cout << '\n'; \ 1182 #undef TINYFORMAT_MAKE_FORMAT_FUNCS 1187 template <
typename... Args>
1188 std::string
format(
const std::string &fmt,
const Args &... args) {
1189 std::ostringstream oss;
1190 format(oss, fmt.c_str(), args...);
1201 #define strprintf tfm::format 1203 #endif // TINYFORMAT_H_INCLUDED