101 #ifndef TINYFORMAT_H_INCLUDED 102 #define TINYFORMAT_H_INCLUDED 112 #define TINYFORMAT_ERROR(reasonString) throw std::runtime_error(reasonString) 126 #ifndef TINYFORMAT_ERROR 127 # define TINYFORMAT_ERROR(reason) assert(0 && reason) 130 #if !defined(TINYFORMAT_USE_VARIADIC_TEMPLATES) && !defined(TINYFORMAT_NO_VARIADIC_TEMPLATES) 131 # ifdef __GXX_EXPERIMENTAL_CXX0X__ 132 # define TINYFORMAT_USE_VARIADIC_TEMPLATES 137 # define TINYFORMAT_NOINLINE __attribute__((noinline)) 138 #elif defined(_MSC_VER) 139 # define TINYFORMAT_NOINLINE __declspec(noinline) 141 # define TINYFORMAT_NOINLINE 144 #if defined(__GLIBCXX__) && __GLIBCXX__ < 20080201 147 # define TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND 156 template <
typename T1,
typename T2>
166 static const T1&
makeT1();
170 # pragma warning(push) 171 # pragma warning(disable:4244) 172 # pragma warning(disable:4267) 181 # pragma warning(pop) 196 template<typename T, typename fmtT, bool convertible = is_convertible<T, fmtT>::value>
199 static void invoke(std::ostream& ,
const T& ) { assert(0); }
203 template<
typename T,
typename fmtT>
207 { out << static_cast<fmtT>(value); }
210 #ifdef TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND 211 template<typename T, bool convertible = is_convertible<T, int>::value>
212 struct formatZeroIntegerWorkaround
214 static bool invoke(std::ostream& ,
const T& ) {
return false; }
217 struct formatZeroIntegerWorkaround<T,true>
219 static bool invoke(std::ostream&
out,
const T& value)
221 if (static_cast<int>(value) == 0 &&
out.flags() & std::ios::showpos)
229 #endif // TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND 233 template<typename T, bool convertible = is_convertible<T,int>::value>
239 "integer for use as variable width or precision");
247 static int invoke(
const T& value) {
return static_cast<int>(value); }
269 const char* fmtEnd,
const T& value)
271 #ifndef TINYFORMAT_ALLOW_WCHAR_STRINGS 284 if(canConvertToChar && *(fmtEnd-1) ==
'c')
286 else if(canConvertToVoidPtr && *(fmtEnd-1) ==
'p')
288 #ifdef TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND 289 else if(detail::formatZeroIntegerWorkaround<T>::invoke(
out, value)) ;
297 #define TINYFORMAT_DEFINE_FORMATVALUE_CHAR(charType) \ 298 inline void formatValue(std::ostream& out, const char* , \ 299 const char* fmtEnd, charType value) \ 301 switch(*(fmtEnd-1)) \ 303 case 'u': case 'd': case 'i': case 'o': case 'X': case 'x': \ 304 out << static_cast<int>(value); break; \ 306 out << value; break; \ 313 #undef TINYFORMAT_DEFINE_FORMATVALUE_CHAR 321 #define TINYFORMAT_ARGTYPES(n) TINYFORMAT_ARGTYPES_ ## n 322 #define TINYFORMAT_VARARGS(n) TINYFORMAT_VARARGS_ ## n 323 #define TINYFORMAT_PASSARGS(n) TINYFORMAT_PASSARGS_ ## n 324 #define TINYFORMAT_PASSARGS_TAIL(n) TINYFORMAT_PASSARGS_TAIL_ ## n 362 #define TINYFORMAT_ARGTYPES_1 class T1 363 #define TINYFORMAT_ARGTYPES_2 class T1, class T2 364 #define TINYFORMAT_ARGTYPES_3 class T1, class T2, class T3 365 #define TINYFORMAT_ARGTYPES_4 class T1, class T2, class T3, class T4 366 #define TINYFORMAT_ARGTYPES_5 class T1, class T2, class T3, class T4, class T5 367 #define TINYFORMAT_ARGTYPES_6 class T1, class T2, class T3, class T4, class T5, class T6 368 #define TINYFORMAT_ARGTYPES_7 class T1, class T2, class T3, class T4, class T5, class T6, class T7 369 #define TINYFORMAT_ARGTYPES_8 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8 370 #define TINYFORMAT_ARGTYPES_9 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9 371 #define TINYFORMAT_ARGTYPES_10 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10 372 #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 373 #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 374 #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 375 #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 376 #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 377 #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 379 #define TINYFORMAT_VARARGS_1 const T1& v1 380 #define TINYFORMAT_VARARGS_2 const T1& v1, const T2& v2 381 #define TINYFORMAT_VARARGS_3 const T1& v1, const T2& v2, const T3& v3 382 #define TINYFORMAT_VARARGS_4 const T1& v1, const T2& v2, const T3& v3, const T4& v4 383 #define TINYFORMAT_VARARGS_5 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5 384 #define TINYFORMAT_VARARGS_6 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6 385 #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 386 #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 387 #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 388 #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 389 #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 390 #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 391 #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 392 #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 393 #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 394 #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 396 #define TINYFORMAT_PASSARGS_1 v1 397 #define TINYFORMAT_PASSARGS_2 v1, v2 398 #define TINYFORMAT_PASSARGS_3 v1, v2, v3 399 #define TINYFORMAT_PASSARGS_4 v1, v2, v3, v4 400 #define TINYFORMAT_PASSARGS_5 v1, v2, v3, v4, v5 401 #define TINYFORMAT_PASSARGS_6 v1, v2, v3, v4, v5, v6 402 #define TINYFORMAT_PASSARGS_7 v1, v2, v3, v4, v5, v6, v7 403 #define TINYFORMAT_PASSARGS_8 v1, v2, v3, v4, v5, v6, v7, v8 404 #define TINYFORMAT_PASSARGS_9 v1, v2, v3, v4, v5, v6, v7, v8, v9 405 #define TINYFORMAT_PASSARGS_10 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 406 #define TINYFORMAT_PASSARGS_11 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11 407 #define TINYFORMAT_PASSARGS_12 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12 408 #define TINYFORMAT_PASSARGS_13 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13 409 #define TINYFORMAT_PASSARGS_14 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14 410 #define TINYFORMAT_PASSARGS_15 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 411 #define TINYFORMAT_PASSARGS_16 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16 413 #define TINYFORMAT_PASSARGS_TAIL_1 414 #define TINYFORMAT_PASSARGS_TAIL_2 , v2 415 #define TINYFORMAT_PASSARGS_TAIL_3 , v2, v3 416 #define TINYFORMAT_PASSARGS_TAIL_4 , v2, v3, v4 417 #define TINYFORMAT_PASSARGS_TAIL_5 , v2, v3, v4, v5 418 #define TINYFORMAT_PASSARGS_TAIL_6 , v2, v3, v4, v5, v6 419 #define TINYFORMAT_PASSARGS_TAIL_7 , v2, v3, v4, v5, v6, v7 420 #define TINYFORMAT_PASSARGS_TAIL_8 , v2, v3, v4, v5, v6, v7, v8 421 #define TINYFORMAT_PASSARGS_TAIL_9 , v2, v3, v4, v5, v6, v7, v8, v9 422 #define TINYFORMAT_PASSARGS_TAIL_10 , v2, v3, v4, v5, v6, v7, v8, v9, v10 423 #define TINYFORMAT_PASSARGS_TAIL_11 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11 424 #define TINYFORMAT_PASSARGS_TAIL_12 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12 425 #define TINYFORMAT_PASSARGS_TAIL_13 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13 426 #define TINYFORMAT_PASSARGS_TAIL_14 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14 427 #define TINYFORMAT_PASSARGS_TAIL_15 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 428 #define TINYFORMAT_PASSARGS_TAIL_16 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16 430 #define TINYFORMAT_FOREACH_ARGNUM(m) \ 431 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) 475 TINYFORMAT_ERROR(
"tinyformat: Too many conversion specifiers in format string");
488 void accept(
const T& value);
496 for(;*c >=
'0' && *c <=
'9'; ++c)
497 i = 10*i + (*c -
'0');
510 # define TINYFORMAT_DEFINE_FORMAT_C_STRING_TRUNCATE(type) \ 511 static bool formatCStringTruncate(std::ostream& out, type* value, \ 512 std::streamsize truncLen) \ 514 std::streamsize len = 0; \ 515 while(len < truncLen && value[len] != 0) \ 517 out.write(value, len); \ 525 # undef TINYFORMAT_DEFINE_FORMAT_C_STRING_TRUNCATE 542 out.write(fmt, static_cast<std::streamsize>(c - fmt));
545 out.write(fmt, static_cast<std::streamsize>(c - fmt));
556 unsigned int& extraFlags,
557 const char* fmtStart,
559 int variablePrecision);
588 const char* fmtEnd = 0;
629 std::ostringstream tmpStream;
630 tmpStream.copyfmt(
m_out);
632 tmpStream.setf(std::ios::showpos);
642 std::string
result = tmpStream.str();
645 for(
size_t i = 0, iend =
result.size(); i < iend; ++i)
669 unsigned int& extraFlags,
670 const char* fmtStart,
672 int variablePrecision)
676 TINYFORMAT_ERROR(
"tinyformat: Not enough conversion specifiers in format string");
684 out.unsetf(std::ios::adjustfield | std::ios::basefield |
685 std::ios::floatfield | std::ios::showbase | std::ios::boolalpha |
686 std::ios::showpoint | std::ios::showpos | std::ios::uppercase);
688 bool precisionSet =
false;
689 bool widthSet =
false;
690 const char* c = fmtStart + 1;
697 out.setf(std::ios::showpoint | std::ios::showbase);
701 if(!(
out.flags() & std::ios::left))
706 out.setf(std::ios::internal, std::ios::adjustfield);
711 out.setf(std::ios::left, std::ios::adjustfield);
715 if(!(
out.flags() & std::ios::showpos))
719 out.setf(std::ios::showpos);
726 if(*c >=
'0' && *c <=
'9')
734 if(variableWidth < 0)
738 out.setf(std::ios::left, std::ios::adjustfield);
739 variableWidth = -variableWidth;
741 out.width(variableWidth);
754 precision = variablePrecision;
758 if(*c >=
'0' && *c <=
'9')
763 out.precision(precision);
767 while(*c ==
'l' || *c ==
'h' || *c ==
'L' ||
768 *c ==
'j' || *c ==
'z' || *c ==
't')
773 bool intConversion =
false;
776 case 'u':
case 'd':
case 'i':
777 out.setf(std::ios::dec, std::ios::basefield);
778 intConversion =
true;
781 out.setf(std::ios::oct, std::ios::basefield);
782 intConversion =
true;
785 out.setf(std::ios::uppercase);
787 out.setf(std::ios::hex, std::ios::basefield);
788 intConversion =
true;
791 out.setf(std::ios::uppercase);
793 out.setf(std::ios::scientific, std::ios::floatfield);
794 out.setf(std::ios::dec, std::ios::basefield);
797 out.setf(std::ios::uppercase);
799 out.setf(std::ios::fixed, std::ios::floatfield);
802 out.setf(std::ios::uppercase);
804 out.setf(std::ios::dec, std::ios::basefield);
806 out.flags(
out.flags() & ~
std::ios::floatfield);
810 "are not supported");
819 out.setf(std::ios::boolalpha);
827 "terminated by end of string");
830 if(intConversion && precisionSet && !widthSet)
836 out.width(
out.precision());
837 out.setf(std::ios::internal, std::ios::adjustfield);
851 #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES 853 template<
typename T1>
861 template<
typename T1,
typename... Args>
862 void format(FormatIterator& fmtIter,
const T1& value1,
const Args&... args)
864 fmtIter.accept(value1);
876 #define TINYFORMAT_MAKE_FORMAT_DETAIL(n) \ 877 template<TINYFORMAT_ARGTYPES(n)> \ 878 void format(detail::FormatIterator& fmtIter, TINYFORMAT_VARARGS(n)) \ 880 fmtIter.accept(v1); \ 881 format(fmtIter TINYFORMAT_PASSARGS_TAIL(n)); \ 885 #undef TINYFORMAT_MAKE_FORMAT_DETAIL 887 #endif // End C++98 variadic template emulation for format() 895 #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES 898 template<
typename T1,
typename... Args>
899 void format(std::ostream&
out,
const char* fmt,
const T1& v1,
const Args&... args)
901 detail::FormatIterator fmtIter(
out, fmt);
902 format(fmtIter, v1, args...);
905 template<
typename T1,
typename... Args>
906 std::string
format(
const char* fmt,
const T1& v1,
const Args&... args)
908 std::ostringstream oss;
909 format(oss, fmt, v1, args...);
913 template<
typename T1,
typename... Args>
914 std::string
format(
const std::string &fmt,
const T1& v1,
const Args&... args)
916 std::ostringstream oss;
917 format(oss, fmt.c_str(), v1, args...);
921 template<
typename T1,
typename... Args>
922 void printf(
const char* fmt,
const T1& v1,
const Args&... args)
924 format(std::cout, fmt, v1, args...);
930 #define TINYFORMAT_MAKE_FORMAT_FUNCS(n) \ 932 template<TINYFORMAT_ARGTYPES(n)> \ 933 void format(std::ostream& out, const char* fmt, TINYFORMAT_VARARGS(n)) \ 935 tinyformat::detail::FormatIterator fmtIter(out, fmt); \ 936 tinyformat::detail::format(fmtIter, TINYFORMAT_PASSARGS(n)); \ 939 template<TINYFORMAT_ARGTYPES(n)> \ 940 std::string format(const char* fmt, TINYFORMAT_VARARGS(n)) \ 942 std::ostringstream oss; \ 943 tinyformat::format(oss, fmt, TINYFORMAT_PASSARGS(n)); \ 947 template<TINYFORMAT_ARGTYPES(n)> \ 948 std::string format(const std::string &fmt, TINYFORMAT_VARARGS(n)) \ 950 std::ostringstream oss; \ 951 tinyformat::format(oss, fmt.c_str(), TINYFORMAT_PASSARGS(n)); \ 955 template<TINYFORMAT_ARGTYPES(n)> \ 956 void printf(const char* fmt, TINYFORMAT_VARARGS(n)) \ 958 tinyformat::format(std::cout, fmt, TINYFORMAT_PASSARGS(n)); \ 962 #undef TINYFORMAT_MAKE_FORMAT_FUNCS 969 #define TINYFORMAT_WRAP_FORMAT_EXTRA_ARGS 970 #define TINYFORMAT_WRAP_FORMAT_N(n, returnType, funcName, funcDeclSuffix, \ 971 bodyPrefix, streamName, bodySuffix) \ 972 template<TINYFORMAT_ARGTYPES(n)> \ 973 returnType funcName(TINYFORMAT_WRAP_FORMAT_EXTRA_ARGS const char* fmt, \ 974 TINYFORMAT_VARARGS(n)) funcDeclSuffix \ 977 tinyformat::format(streamName, fmt, TINYFORMAT_PASSARGS(n)); \ 981 #define TINYFORMAT_WRAP_FORMAT(returnType, funcName, funcDeclSuffix, \ 982 bodyPrefix, streamName, bodySuffix) \ 984 returnType funcName(TINYFORMAT_WRAP_FORMAT_EXTRA_ARGS const char* fmt \ 988 tinyformat::detail::FormatIterator(streamName, fmt).finish(); \ 991 TINYFORMAT_WRAP_FORMAT_N(1 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ 992 TINYFORMAT_WRAP_FORMAT_N(2 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ 993 TINYFORMAT_WRAP_FORMAT_N(3 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ 994 TINYFORMAT_WRAP_FORMAT_N(4 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ 995 TINYFORMAT_WRAP_FORMAT_N(5 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ 996 TINYFORMAT_WRAP_FORMAT_N(6 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ 997 TINYFORMAT_WRAP_FORMAT_N(7 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ 998 TINYFORMAT_WRAP_FORMAT_N(8 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ 999 TINYFORMAT_WRAP_FORMAT_N(9 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ 1000 TINYFORMAT_WRAP_FORMAT_N(10, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ 1001 TINYFORMAT_WRAP_FORMAT_N(11, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ 1002 TINYFORMAT_WRAP_FORMAT_N(12, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ 1003 TINYFORMAT_WRAP_FORMAT_N(13, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ 1004 TINYFORMAT_WRAP_FORMAT_N(14, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ 1005 TINYFORMAT_WRAP_FORMAT_N(15, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ 1006 TINYFORMAT_WRAP_FORMAT_N(16, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ 1011 #define strprintf tfm::format 1013 #endif // TINYFORMAT_H_INCLUDED