124 #ifndef TINYFORMAT_H_INCLUDED 125 #define TINYFORMAT_H_INCLUDED 135 #define TINYFORMAT_ERROR(reasonString) throw tinyformat::format_error(reasonString) 139 #define TINYFORMAT_USE_VARIADIC_TEMPLATES 149 #ifndef TINYFORMAT_ASSERT 151 # define TINYFORMAT_ASSERT(cond) assert(cond) 154 #ifndef TINYFORMAT_ERROR 156 # define TINYFORMAT_ERROR(reason) assert(0 && reason) 159 #if !defined(TINYFORMAT_USE_VARIADIC_TEMPLATES) && !defined(TINYFORMAT_NO_VARIADIC_TEMPLATES) 160 # ifdef __GXX_EXPERIMENTAL_CXX0X__ 161 # define TINYFORMAT_USE_VARIADIC_TEMPLATES 165 #if defined(__GLIBCXX__) && __GLIBCXX__ < 20080201 168 # define TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND 174 # define TINYFORMAT_HIDDEN __attribute__((visibility("hidden"))) 176 # define TINYFORMAT_HIDDEN 193 template <
typename T1,
typename T2>
203 static const T1&
makeT1();
207 # pragma warning(push) 208 # pragma warning(disable:4244) 209 # pragma warning(disable:4267) 218 # pragma warning(pop) 227 template<
int n>
struct is_wchar<const wchar_t[n]> {};
233 template<typename T, typename fmtT, bool convertible = is_convertible<T, fmtT>::value>
240 template<
typename T,
typename fmtT>
244 { out << static_cast<fmtT>(value); }
247 #ifdef TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND 248 template<typename T, bool convertible = is_convertible<T, int>::value>
249 struct formatZeroIntegerWorkaround
251 static bool invoke(std::ostream& ,
const T& ) {
return false; }
254 struct formatZeroIntegerWorkaround<
T,true>
256 static bool invoke(std::ostream&
out,
const T& value)
258 if (static_cast<int>(value) == 0 &&
out.flags() & std::ios::showpos) {
265 #endif // TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND 269 template<typename T, bool convertible = is_convertible<T,int>::value>
275 "integer for use as variable width or precision");
283 static int invoke(
const T& value) {
return static_cast<int>(value); }
290 std::ostringstream tmp;
292 std::string result = tmp.str();
293 out.write(result.c_str(), (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) \ 298 std::streamsize len = 0; \ 299 while (len < ntrunc && value[len] != 0) \ 301 out.write(value, len); \ 307 #undef TINYFORMAT_DEFINE_FORMAT_TRUNCATED_CSTR 330 const char* fmtEnd,
int ntrunc,
const T& value)
332 #ifndef TINYFORMAT_ALLOW_WCHAR_STRINGS 345 if (canConvertToChar && *(fmtEnd-1) ==
'c')
347 else if (canConvertToVoidPtr && *(fmtEnd-1) ==
'p')
349 #ifdef TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND 350 else if (detail::formatZeroIntegerWorkaround<T>::invoke(
out, value)) ;
352 else if (ntrunc >= 0) {
363 #define TINYFORMAT_DEFINE_FORMATVALUE_CHAR(charType) \ 364 inline void formatValue(std::ostream& out, const char* , \ 365 const char* fmtEnd, int , charType value) \ 367 switch (*(fmtEnd-1)) { \ 368 case 'u': case 'd': case 'i': case 'o': case 'X': case 'x': \ 369 out << static_cast<int>(value); break; \ 371 out << value; break; \ 378 #undef TINYFORMAT_DEFINE_FORMATVALUE_CHAR 386 #define TINYFORMAT_ARGTYPES(n) TINYFORMAT_ARGTYPES_ ## n 387 #define TINYFORMAT_VARARGS(n) TINYFORMAT_VARARGS_ ## n 388 #define TINYFORMAT_PASSARGS(n) TINYFORMAT_PASSARGS_ ## n 389 #define TINYFORMAT_PASSARGS_TAIL(n) TINYFORMAT_PASSARGS_TAIL_ ## n 427 #define TINYFORMAT_ARGTYPES_1 class T1 428 #define TINYFORMAT_ARGTYPES_2 class T1, class T2 429 #define TINYFORMAT_ARGTYPES_3 class T1, class T2, class T3 430 #define TINYFORMAT_ARGTYPES_4 class T1, class T2, class T3, class T4 431 #define TINYFORMAT_ARGTYPES_5 class T1, class T2, class T3, class T4, class T5 432 #define TINYFORMAT_ARGTYPES_6 class T1, class T2, class T3, class T4, class T5, class T6 433 #define TINYFORMAT_ARGTYPES_7 class T1, class T2, class T3, class T4, class T5, class T6, class T7 434 #define TINYFORMAT_ARGTYPES_8 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8 435 #define TINYFORMAT_ARGTYPES_9 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9 436 #define TINYFORMAT_ARGTYPES_10 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10 437 #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 438 #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 439 #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 440 #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 441 #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 442 #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 444 #define TINYFORMAT_VARARGS_1 const T1& v1 445 #define TINYFORMAT_VARARGS_2 const T1& v1, const T2& v2 446 #define TINYFORMAT_VARARGS_3 const T1& v1, const T2& v2, const T3& v3 447 #define TINYFORMAT_VARARGS_4 const T1& v1, const T2& v2, const T3& v3, const T4& v4 448 #define TINYFORMAT_VARARGS_5 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5 449 #define TINYFORMAT_VARARGS_6 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6 450 #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 451 #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 452 #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 453 #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 454 #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 455 #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 456 #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 457 #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 458 #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 459 #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 461 #define TINYFORMAT_PASSARGS_1 v1 462 #define TINYFORMAT_PASSARGS_2 v1, v2 463 #define TINYFORMAT_PASSARGS_3 v1, v2, v3 464 #define TINYFORMAT_PASSARGS_4 v1, v2, v3, v4 465 #define TINYFORMAT_PASSARGS_5 v1, v2, v3, v4, v5 466 #define TINYFORMAT_PASSARGS_6 v1, v2, v3, v4, v5, v6 467 #define TINYFORMAT_PASSARGS_7 v1, v2, v3, v4, v5, v6, v7 468 #define TINYFORMAT_PASSARGS_8 v1, v2, v3, v4, v5, v6, v7, v8 469 #define TINYFORMAT_PASSARGS_9 v1, v2, v3, v4, v5, v6, v7, v8, v9 470 #define TINYFORMAT_PASSARGS_10 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 471 #define TINYFORMAT_PASSARGS_11 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11 472 #define TINYFORMAT_PASSARGS_12 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12 473 #define TINYFORMAT_PASSARGS_13 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13 474 #define TINYFORMAT_PASSARGS_14 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14 475 #define TINYFORMAT_PASSARGS_15 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 476 #define TINYFORMAT_PASSARGS_16 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16 478 #define TINYFORMAT_PASSARGS_TAIL_1 479 #define TINYFORMAT_PASSARGS_TAIL_2 , v2 480 #define TINYFORMAT_PASSARGS_TAIL_3 , v2, v3 481 #define TINYFORMAT_PASSARGS_TAIL_4 , v2, v3, v4 482 #define TINYFORMAT_PASSARGS_TAIL_5 , v2, v3, v4, v5 483 #define TINYFORMAT_PASSARGS_TAIL_6 , v2, v3, v4, v5, v6 484 #define TINYFORMAT_PASSARGS_TAIL_7 , v2, v3, v4, v5, v6, v7 485 #define TINYFORMAT_PASSARGS_TAIL_8 , v2, v3, v4, v5, v6, v7, v8 486 #define TINYFORMAT_PASSARGS_TAIL_9 , v2, v3, v4, v5, v6, v7, v8, v9 487 #define TINYFORMAT_PASSARGS_TAIL_10 , v2, v3, v4, v5, v6, v7, v8, v9, v10 488 #define TINYFORMAT_PASSARGS_TAIL_11 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11 489 #define TINYFORMAT_PASSARGS_TAIL_12 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12 490 #define TINYFORMAT_PASSARGS_TAIL_13 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13 491 #define TINYFORMAT_PASSARGS_TAIL_14 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14 492 #define TINYFORMAT_PASSARGS_TAIL_15 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 493 #define TINYFORMAT_PASSARGS_TAIL_16 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16 495 #define TINYFORMAT_FOREACH_ARGNUM(m) \ 496 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) 515 :
m_value(static_cast<const void*>(&value)),
521 const char* fmtEnd,
int ntrunc)
const 538 const char* fmtEnd,
int ntrunc,
const void* value)
540 formatValue(
out, fmtBegin, fmtEnd, ntrunc, *static_cast<const T*>(value));
551 const char* fmtEnd,
int ntrunc,
const void* value){
nullptr};
561 for (;*c >=
'0' && *c <=
'9'; ++c)
562 i = 10*i + (*c -
'0');
573 int& argIndex,
int numArgs)
575 if (*c >=
'0' && *c <=
'9') {
578 else if (*c ==
'*') {
581 if (positionalMode) {
584 TINYFORMAT_ERROR(
"tinyformat: Non-positional argument used after a positional one");
585 if (pos >= 0 && pos < numArgs)
586 n =
args[pos].toInt();
592 if (argIndex < numArgs)
593 n =
args[argIndex++].toInt();
595 TINYFORMAT_ERROR(
"tinyformat: Not enough arguments to read variable width or precision");
614 out.write(fmt, c - fmt);
617 else if (*c ==
'%') {
618 out.write(fmt, c - fmt);
662 bool& spacePadPositive,
663 int& ntrunc,
const char* fmtStart,
665 int& argIndex,
int numArgs)
673 out.unsetf(std::ios::adjustfield | std::ios::basefield |
674 std::ios::floatfield | std::ios::showbase | std::ios::boolalpha |
675 std::ios::showpoint | std::ios::showpos | std::ios::uppercase);
676 bool precisionSet =
false;
677 bool widthSet =
false;
679 const char* c = fmtStart + 1;
683 if (*c >=
'0' && *c <=
'9') {
684 const char tmpc = *c;
688 if (value > 0 && value <= numArgs)
689 argIndex = value - 1;
693 positionalMode =
true;
695 else if (positionalMode) {
696 TINYFORMAT_ERROR(
"tinyformat: Non-positional argument used after a positional one");
703 out.setf(std::ios::internal, std::ios::adjustfield);
712 else if (positionalMode) {
713 TINYFORMAT_ERROR(
"tinyformat: Non-positional argument used after a positional one");
721 out.setf(std::ios::showpoint | std::ios::showbase);
725 if (!(
out.flags() & std::ios::left)) {
729 out.setf(std::ios::internal, std::ios::adjustfield);
734 out.setf(std::ios::left, std::ios::adjustfield);
738 if (!(
out.flags() & std::ios::showpos))
739 spacePadPositive =
true;
742 out.setf(std::ios::showpos);
743 spacePadPositive =
false;
754 args, argIndex, numArgs);
759 out.setf(std::ios::left, std::ios::adjustfield);
770 args, argIndex, numArgs);
773 precisionSet = precision >= 0;
775 out.precision(precision);
778 while (*c ==
'l' || *c ==
'h' || *c ==
'L' ||
779 *c ==
'j' || *c ==
'z' || *c ==
't') {
785 bool intConversion =
false;
787 case 'u':
case 'd':
case 'i':
788 out.setf(std::ios::dec, std::ios::basefield);
789 intConversion =
true;
792 out.setf(std::ios::oct, std::ios::basefield);
793 intConversion =
true;
796 out.setf(std::ios::uppercase);
799 out.setf(std::ios::hex, std::ios::basefield);
800 intConversion =
true;
803 out.setf(std::ios::uppercase);
806 out.setf(std::ios::scientific, std::ios::floatfield);
807 out.setf(std::ios::dec, std::ios::basefield);
810 out.setf(std::ios::uppercase);
813 out.setf(std::ios::fixed, std::ios::floatfield);
816 out.setf(std::ios::uppercase);
825 out.setf(std::ios::fixed | std::ios::scientific, std::ios::floatfield);
828 out.setf(std::ios::uppercase);
831 out.setf(std::ios::dec, std::ios::basefield);
833 out.flags(
out.flags() & ~
std::ios::floatfield);
840 ntrunc =
static_cast<int>(
out.precision());
842 out.setf(std::ios::boolalpha);
850 "terminated by end of string");
855 if (intConversion && precisionSet && !widthSet) {
860 out.width(
out.precision() + widthExtra);
861 out.setf(std::ios::internal, std::ios::adjustfield);
874 std::streamsize origWidth =
out.width();
875 std::streamsize origPrecision =
out.precision();
876 std::ios::fmtflags origFlags =
out.flags();
877 char origFill =
out.fill();
881 bool positionalMode =
false;
886 if (!positionalMode && argIndex < numArgs) {
887 TINYFORMAT_ERROR(
"tinyformat: Not enough conversion specifiers in format string");
891 bool spacePadPositive =
false;
894 args, argIndex, numArgs);
897 if (argIndex >= numArgs) {
898 TINYFORMAT_ERROR(
"tinyformat: Too many conversion specifiers in format string");
903 if (!spacePadPositive) {
911 std::ostringstream tmpStream;
912 tmpStream.copyfmt(
out);
913 tmpStream.setf(std::ios::showpos);
914 arg.
format(tmpStream, fmt, fmtEnd, ntrunc);
915 std::string result = tmpStream.str();
916 for (
size_t i = 0, iend = result.size(); i < iend; ++i) {
917 if (result[i] ==
'+')
928 out.width(origWidth);
929 out.precision(origPrecision);
930 out.flags(origFlags);
949 friend void vformat(std::ostream&
out,
const char* fmt,
968 #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES 969 template<
typename... Args>
973 { static_assert(
sizeof...(
args) == N,
"Number of args must be N"); }
974 #else // C++98 version 976 # define TINYFORMAT_MAKE_FORMATLIST_CONSTRUCTOR(n) \ 978 template<TINYFORMAT_ARGTYPES(n)> \ 979 FormatListN(TINYFORMAT_VARARGS(n)) \ 980 : FormatList(&m_formatterStore[0], n) \ 981 { TINYFORMAT_ASSERT(n == N); init(0, TINYFORMAT_PASSARGS(n)); } \ 983 template<TINYFORMAT_ARGTYPES(n)> \ 984 void init(int i, TINYFORMAT_VARARGS(n)) \ 986 m_formatterStore[i] = FormatArg(v1); \ 987 init(i+1 TINYFORMAT_PASSARGS_TAIL(n)); \ 991 # undef TINYFORMAT_MAKE_FORMATLIST_CONSTRUCTOR 1015 #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES 1023 template<
typename... Args>
1029 #else // C++98 version 1033 return detail::FormatListN<0>();
1035 #define TINYFORMAT_MAKE_MAKEFORMATLIST(n) \ 1036 template<TINYFORMAT_ARGTYPES(n)> \ 1037 detail::FormatListN<n> makeFormatList(TINYFORMAT_VARARGS(n)) \ 1039 return detail::FormatListN<n>(TINYFORMAT_PASSARGS(n)); \ 1042 #undef TINYFORMAT_MAKE_MAKEFORMATLIST 1056 #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES 1059 template<
typename... Args>
1067 template<
typename... Args>
1070 std::ostringstream oss;
1076 template<
typename... Args>
1082 template<
typename... Args>
1090 #else // C++98 version 1092 inline void format(std::ostream&
out,
const char* fmt)
1097 inline std::string
format(
const char* fmt)
1099 std::ostringstream oss;
1104 inline void printf(
const char* fmt)
1109 inline void printfln(
const char* fmt)
1115 #define TINYFORMAT_MAKE_FORMAT_FUNCS(n) \ 1117 template<TINYFORMAT_ARGTYPES(n)> \ 1118 void format(std::ostream& out, const char* fmt, TINYFORMAT_VARARGS(n)) \ 1120 vformat(out, fmt, makeFormatList(TINYFORMAT_PASSARGS(n))); \ 1123 template<TINYFORMAT_ARGTYPES(n)> \ 1124 std::string format(const char* fmt, TINYFORMAT_VARARGS(n)) \ 1126 std::ostringstream oss; \ 1127 format(oss, fmt, TINYFORMAT_PASSARGS(n)); \ 1131 template<TINYFORMAT_ARGTYPES(n)> \ 1132 void printf(const char* fmt, TINYFORMAT_VARARGS(n)) \ 1134 format(std::cout, fmt, TINYFORMAT_PASSARGS(n)); \ 1137 template<TINYFORMAT_ARGTYPES(n)> \ 1138 void printfln(const char* fmt, TINYFORMAT_VARARGS(n)) \ 1140 format(std::cout, fmt, TINYFORMAT_PASSARGS(n)); \ 1141 std::cout << '\n'; \ 1145 #undef TINYFORMAT_MAKE_FORMAT_FUNCS 1150 template<
typename... Args>
1153 std::ostringstream oss;
1162 #define strprintf tfm::format 1164 #endif // TINYFORMAT_H_INCLUDED
std::unique_ptr< interfaces::Init > init
#define T(expected, seed, data)