115 #ifndef TINYFORMAT_H_INCLUDED 116 #define TINYFORMAT_H_INCLUDED 126 #define TINYFORMAT_ERROR(reasonString) throw tinyformat::format_error(reasonString) 130 #define TINYFORMAT_USE_VARIADIC_TEMPLATES 141 #ifndef TINYFORMAT_ERROR 142 # define TINYFORMAT_ERROR(reason) assert(0 && reason) 145 #if !defined(TINYFORMAT_USE_VARIADIC_TEMPLATES) && !defined(TINYFORMAT_NO_VARIADIC_TEMPLATES) 146 # ifdef __GXX_EXPERIMENTAL_CXX0X__ 147 # define TINYFORMAT_USE_VARIADIC_TEMPLATES 151 #if defined(__GLIBCXX__) && __GLIBCXX__ < 20080201 154 # define TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND 160 # define TINYFORMAT_HIDDEN __attribute__((visibility("hidden"))) 162 # define TINYFORMAT_HIDDEN 178 template <
typename T1,
typename T2>
188 static const T1&
makeT1();
192 # pragma warning(push) 193 # pragma warning(disable:4244) 194 # pragma warning(disable:4267) 203 # pragma warning(pop) 212 template<
int n>
struct is_wchar<const wchar_t[n]> {};
218 template<typename T, typename fmtT, bool convertible = is_convertible<T, fmtT>::value>
221 static void invoke(std::ostream& ,
const T& ) { assert(0); }
225 template<
typename T,
typename fmtT>
228 static void invoke(std::ostream& out,
const T& value)
229 { out << static_cast<fmtT>(value); }
232 #ifdef TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND 233 template<typename T, bool convertible = is_convertible<T, int>::value>
234 struct formatZeroIntegerWorkaround
236 static bool invoke(std::ostream& ,
const T& ) {
return false; }
239 struct formatZeroIntegerWorkaround<T,
true>
241 static bool invoke(std::ostream& out,
const T& value)
243 if (static_cast<int>(value) == 0 && out.flags() & std::ios::showpos)
251 #endif // TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND 255 template<typename T, bool convertible = is_convertible<T,int>::value>
261 "integer for use as variable width or precision");
269 static int invoke(
const T& value) {
return static_cast<int>(value); }
276 std::ostringstream tmp;
278 std::string result = tmp.str();
279 out.write(result.c_str(), (std::min)(ntrunc, static_cast<int>(result.size())));
281 #define TINYFORMAT_DEFINE_FORMAT_TRUNCATED_CSTR(type) \ 282 inline void formatTruncated(std::ostream& out, type* value, int ntrunc) \ 284 std::streamsize len = 0; \ 285 while(len < ntrunc && value[len] != 0) \ 287 out.write(value, len); \ 293 #undef TINYFORMAT_DEFINE_FORMAT_TRUNCATED_CSTR 316 const char* fmtEnd,
int ntrunc,
const T& value)
318 #ifndef TINYFORMAT_ALLOW_WCHAR_STRINGS 331 if(canConvertToChar && *(fmtEnd-1) ==
'c')
333 else if(canConvertToVoidPtr && *(fmtEnd-1) ==
'p')
335 #ifdef TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND 336 else if(detail::formatZeroIntegerWorkaround<T>::invoke(out, value)) ;
350 #define TINYFORMAT_DEFINE_FORMATVALUE_CHAR(charType) \ 351 inline void formatValue(std::ostream& out, const char* , \ 352 const char* fmtEnd, int , charType value) \ 354 switch(*(fmtEnd-1)) \ 356 case 'u': case 'd': case 'i': case 'o': case 'X': case 'x': \ 357 out << static_cast<int>(value); break; \ 359 out << value; break; \ 366 #undef TINYFORMAT_DEFINE_FORMATVALUE_CHAR 374 #define TINYFORMAT_ARGTYPES(n) TINYFORMAT_ARGTYPES_ ## n 375 #define TINYFORMAT_VARARGS(n) TINYFORMAT_VARARGS_ ## n 376 #define TINYFORMAT_PASSARGS(n) TINYFORMAT_PASSARGS_ ## n 377 #define TINYFORMAT_PASSARGS_TAIL(n) TINYFORMAT_PASSARGS_TAIL_ ## n 415 #define TINYFORMAT_ARGTYPES_1 class T1 416 #define TINYFORMAT_ARGTYPES_2 class T1, class T2 417 #define TINYFORMAT_ARGTYPES_3 class T1, class T2, class T3 418 #define TINYFORMAT_ARGTYPES_4 class T1, class T2, class T3, class T4 419 #define TINYFORMAT_ARGTYPES_5 class T1, class T2, class T3, class T4, class T5 420 #define TINYFORMAT_ARGTYPES_6 class T1, class T2, class T3, class T4, class T5, class T6 421 #define TINYFORMAT_ARGTYPES_7 class T1, class T2, class T3, class T4, class T5, class T6, class T7 422 #define TINYFORMAT_ARGTYPES_8 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8 423 #define TINYFORMAT_ARGTYPES_9 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9 424 #define TINYFORMAT_ARGTYPES_10 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10 425 #define TINYFORMAT_ARGTYPES_11 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11 426 #define TINYFORMAT_ARGTYPES_12 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12 427 #define TINYFORMAT_ARGTYPES_13 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13 428 #define TINYFORMAT_ARGTYPES_14 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14 429 #define TINYFORMAT_ARGTYPES_15 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 430 #define TINYFORMAT_ARGTYPES_16 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15, class T16 432 #define TINYFORMAT_VARARGS_1 const T1& v1 433 #define TINYFORMAT_VARARGS_2 const T1& v1, const T2& v2 434 #define TINYFORMAT_VARARGS_3 const T1& v1, const T2& v2, const T3& v3 435 #define TINYFORMAT_VARARGS_4 const T1& v1, const T2& v2, const T3& v3, const T4& v4 436 #define TINYFORMAT_VARARGS_5 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5 437 #define TINYFORMAT_VARARGS_6 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6 438 #define TINYFORMAT_VARARGS_7 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7 439 #define TINYFORMAT_VARARGS_8 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8 440 #define TINYFORMAT_VARARGS_9 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9 441 #define TINYFORMAT_VARARGS_10 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10 442 #define TINYFORMAT_VARARGS_11 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11 443 #define TINYFORMAT_VARARGS_12 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11, const T12& v12 444 #define TINYFORMAT_VARARGS_13 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11, const T12& v12, const T13& v13 445 #define TINYFORMAT_VARARGS_14 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11, const T12& v12, const T13& v13, const T14& v14 446 #define TINYFORMAT_VARARGS_15 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11, const T12& v12, const T13& v13, const T14& v14, const T15& v15 447 #define TINYFORMAT_VARARGS_16 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11, const T12& v12, const T13& v13, const T14& v14, const T15& v15, const T16& v16 449 #define TINYFORMAT_PASSARGS_1 v1 450 #define TINYFORMAT_PASSARGS_2 v1, v2 451 #define TINYFORMAT_PASSARGS_3 v1, v2, v3 452 #define TINYFORMAT_PASSARGS_4 v1, v2, v3, v4 453 #define TINYFORMAT_PASSARGS_5 v1, v2, v3, v4, v5 454 #define TINYFORMAT_PASSARGS_6 v1, v2, v3, v4, v5, v6 455 #define TINYFORMAT_PASSARGS_7 v1, v2, v3, v4, v5, v6, v7 456 #define TINYFORMAT_PASSARGS_8 v1, v2, v3, v4, v5, v6, v7, v8 457 #define TINYFORMAT_PASSARGS_9 v1, v2, v3, v4, v5, v6, v7, v8, v9 458 #define TINYFORMAT_PASSARGS_10 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 459 #define TINYFORMAT_PASSARGS_11 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11 460 #define TINYFORMAT_PASSARGS_12 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12 461 #define TINYFORMAT_PASSARGS_13 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13 462 #define TINYFORMAT_PASSARGS_14 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14 463 #define TINYFORMAT_PASSARGS_15 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 464 #define TINYFORMAT_PASSARGS_16 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16 466 #define TINYFORMAT_PASSARGS_TAIL_1 467 #define TINYFORMAT_PASSARGS_TAIL_2 , v2 468 #define TINYFORMAT_PASSARGS_TAIL_3 , v2, v3 469 #define TINYFORMAT_PASSARGS_TAIL_4 , v2, v3, v4 470 #define TINYFORMAT_PASSARGS_TAIL_5 , v2, v3, v4, v5 471 #define TINYFORMAT_PASSARGS_TAIL_6 , v2, v3, v4, v5, v6 472 #define TINYFORMAT_PASSARGS_TAIL_7 , v2, v3, v4, v5, v6, v7 473 #define TINYFORMAT_PASSARGS_TAIL_8 , v2, v3, v4, v5, v6, v7, v8 474 #define TINYFORMAT_PASSARGS_TAIL_9 , v2, v3, v4, v5, v6, v7, v8, v9 475 #define TINYFORMAT_PASSARGS_TAIL_10 , v2, v3, v4, v5, v6, v7, v8, v9, v10 476 #define TINYFORMAT_PASSARGS_TAIL_11 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11 477 #define TINYFORMAT_PASSARGS_TAIL_12 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12 478 #define TINYFORMAT_PASSARGS_TAIL_13 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13 479 #define TINYFORMAT_PASSARGS_TAIL_14 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14 480 #define TINYFORMAT_PASSARGS_TAIL_15 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 481 #define TINYFORMAT_PASSARGS_TAIL_16 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16 483 #define TINYFORMAT_FOREACH_ARGNUM(m) \ 484 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) m(15) m(16) 506 :
m_value(static_cast<const void*>(&value)),
511 void format(std::ostream& out,
const char* fmtBegin,
512 const char* fmtEnd,
int ntrunc)
const 529 const char* fmtEnd,
int ntrunc,
const void* value)
531 formatValue(out, fmtBegin, fmtEnd, ntrunc, *static_cast<const T*>(value));
542 const char* fmtEnd,
int ntrunc,
const void* value);
552 for(;*c >=
'0' && *c <=
'9'; ++c)
553 i = 10*i + (*c -
'0');
571 out.write(fmt, c - fmt);
574 out.write(fmt, c - fmt);
598 int& ntrunc,
const char* fmtStart,
600 int& argIndex,
int numFormatters)
604 TINYFORMAT_ERROR(
"tinyformat: Not enough conversion specifiers in format string");
612 out.unsetf(std::ios::adjustfield | std::ios::basefield |
613 std::ios::floatfield | std::ios::showbase | std::ios::boolalpha |
614 std::ios::showpoint | std::ios::showpos | std::ios::uppercase);
615 bool precisionSet =
false;
616 bool widthSet =
false;
618 const char* c = fmtStart + 1;
625 out.setf(std::ios::showpoint | std::ios::showbase);
629 if(!(out.flags() & std::ios::left))
634 out.setf(std::ios::internal, std::ios::adjustfield);
639 out.setf(std::ios::left, std::ios::adjustfield);
643 if(!(out.flags() & std::ios::showpos))
644 spacePadPositive =
true;
647 out.setf(std::ios::showpos);
648 spacePadPositive =
false;
657 if(*c >=
'0' && *c <=
'9')
666 if(argIndex < numFormatters)
667 width = formatters[argIndex++].
toInt();
669 TINYFORMAT_ERROR(
"tinyformat: Not enough arguments to read variable width");
674 out.setf(std::ios::left, std::ios::adjustfield);
688 if(argIndex < numFormatters)
689 precision = formatters[argIndex++].
toInt();
691 TINYFORMAT_ERROR(
"tinyformat: Not enough arguments to read variable precision");
695 if(*c >=
'0' && *c <=
'9')
700 out.precision(precision);
704 while(*c ==
'l' || *c ==
'h' || *c ==
'L' ||
705 *c ==
'j' || *c ==
'z' || *c ==
't')
710 bool intConversion =
false;
713 case 'u':
case 'd':
case 'i':
714 out.setf(std::ios::dec, std::ios::basefield);
715 intConversion =
true;
718 out.setf(std::ios::oct, std::ios::basefield);
719 intConversion =
true;
722 out.setf(std::ios::uppercase);
725 out.setf(std::ios::hex, std::ios::basefield);
726 intConversion =
true;
729 out.setf(std::ios::uppercase);
732 out.setf(std::ios::scientific, std::ios::floatfield);
733 out.setf(std::ios::dec, std::ios::basefield);
736 out.setf(std::ios::uppercase);
739 out.setf(std::ios::fixed, std::ios::floatfield);
742 out.setf(std::ios::uppercase);
745 out.setf(std::ios::dec, std::ios::basefield);
747 out.flags(out.flags() & ~
std::ios::floatfield);
751 "are not supported");
758 ntrunc =
static_cast<int>(out.precision());
760 out.setf(std::ios::boolalpha);
768 "terminated by end of string");
773 if(intConversion && precisionSet && !widthSet)
779 out.width(out.precision() + widthExtra);
780 out.setf(std::ios::internal, std::ios::adjustfield);
793 std::streamsize origWidth = out.width();
794 std::streamsize origPrecision = out.precision();
795 std::ios::fmtflags origFlags = out.flags();
796 char origFill = out.fill();
798 for (
int argIndex = 0; argIndex < numFormatters; ++argIndex)
802 bool spacePadPositive =
false;
805 formatters, argIndex, numFormatters);
806 if (argIndex >= numFormatters)
812 const FormatArg& arg = formatters[argIndex];
814 if(!spacePadPositive)
815 arg.
format(out, fmt, fmtEnd, ntrunc);
822 std::ostringstream tmpStream;
823 tmpStream.copyfmt(out);
824 tmpStream.setf(std::ios::showpos);
825 arg.
format(tmpStream, fmt, fmtEnd, ntrunc);
826 std::string result = tmpStream.str();
827 for(
size_t i = 0, iend = result.size(); i < iend; ++i)
828 if(result[i] ==
'+') result[i] =
' ';
837 TINYFORMAT_ERROR(
"tinyformat: Too many conversion specifiers in format string");
840 out.width(origWidth);
841 out.precision(origPrecision);
842 out.flags(origFlags);
861 friend void vformat(std::ostream& out,
const char* fmt,
880 #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES 881 template<
typename... Args>
885 { static_assert(
sizeof...(args) == N,
"Number of args must be N"); }
886 #else // C++98 version 888 # define TINYFORMAT_MAKE_FORMATLIST_CONSTRUCTOR(n) \ 890 template<TINYFORMAT_ARGTYPES(n)> \ 891 explicit FormatListN(TINYFORMAT_VARARGS(n)) \ 892 : FormatList(&m_formatterStore[0], n) \ 893 { assert(n == N); init(0, TINYFORMAT_PASSARGS(n)); } \ 895 template<TINYFORMAT_ARGTYPES(n)> \ 896 void init(int i, TINYFORMAT_VARARGS(n)) \ 898 m_formatterStore[i] = FormatArg(v1); \ 899 init(i+1 TINYFORMAT_PASSARGS_TAIL(n)); \ 903 # undef TINYFORMAT_MAKE_FORMATLIST_CONSTRUCTOR 922 #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES 930 template<
typename... Args>
936 #else // C++98 version 940 return detail::FormatListN<0>();
942 #define TINYFORMAT_MAKE_MAKEFORMATLIST(n) \ 943 template<TINYFORMAT_ARGTYPES(n)> \ 944 detail::FormatListN<n> makeFormatList(TINYFORMAT_VARARGS(n)) \ 946 return detail::FormatListN<n>(TINYFORMAT_PASSARGS(n)); \ 949 #undef TINYFORMAT_MAKE_MAKEFORMATLIST 963 #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES 966 template<
typename... Args>
967 void format(std::ostream& out,
const char* fmt,
const Args&... args)
974 template<
typename... Args>
975 std::string
format(
const char* fmt,
const Args&... args)
977 std::ostringstream oss;
978 format(oss, fmt, args...);
983 template<
typename... Args>
984 void printf(
const char* fmt,
const Args&... args)
986 format(std::cout, fmt, args...);
989 template<
typename... Args>
990 void printfln(
const char* fmt,
const Args&... args)
992 format(std::cout, fmt, args...);
996 #else // C++98 version 998 inline void format(std::ostream& out,
const char* fmt)
1003 inline std::string
format(
const char* fmt)
1005 std::ostringstream oss;
1010 inline void printf(
const char* fmt)
1015 inline void printfln(
const char* fmt)
1021 #define TINYFORMAT_MAKE_FORMAT_FUNCS(n) \ 1023 template<TINYFORMAT_ARGTYPES(n)> \ 1024 void format(std::ostream& out, const char* fmt, TINYFORMAT_VARARGS(n)) \ 1026 vformat(out, fmt, makeFormatList(TINYFORMAT_PASSARGS(n))); \ 1029 template<TINYFORMAT_ARGTYPES(n)> \ 1030 std::string format(const char* fmt, TINYFORMAT_VARARGS(n)) \ 1032 std::ostringstream oss; \ 1033 format(oss, fmt, TINYFORMAT_PASSARGS(n)); \ 1037 template<TINYFORMAT_ARGTYPES(n)> \ 1038 void printf(const char* fmt, TINYFORMAT_VARARGS(n)) \ 1040 format(std::cout, fmt, TINYFORMAT_PASSARGS(n)); \ 1043 template<TINYFORMAT_ARGTYPES(n)> \ 1044 void printfln(const char* fmt, TINYFORMAT_VARARGS(n)) \ 1046 format(std::cout, fmt, TINYFORMAT_PASSARGS(n)); \ 1047 std::cout << '\n'; \ 1051 #undef TINYFORMAT_MAKE_FORMAT_FUNCS 1056 template<
typename... Args>
1057 std::string
format(
const std::string &fmt,
const Args&... args)
1059 std::ostringstream oss;
1060 format(oss, fmt.c_str(), args...);
1066 #define strprintf tinyformat::format 1068 #endif // TINYFORMAT_H_INCLUDED