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) 514 :
m_value(static_cast<const void*>(&value)),
520 const char* fmtEnd,
int ntrunc)
const 537 const char* fmtEnd,
int ntrunc,
const void* value)
539 formatValue(
out, fmtBegin, fmtEnd, ntrunc, *static_cast<const T*>(value));
550 const char* fmtEnd,
int ntrunc,
const void* value){
nullptr};
560 for (;*c >=
'0' && *c <=
'9'; ++c)
561 i = 10*i + (*c -
'0');
572 int& argIndex,
int numArgs)
574 if (*c >=
'0' && *c <=
'9') {
577 else if (*c ==
'*') {
580 if (positionalMode) {
583 TINYFORMAT_ERROR(
"tinyformat: Non-positional argument used after a positional one");
584 if (pos >= 0 && pos < numArgs)
585 n =
args[pos].toInt();
591 if (argIndex < numArgs)
592 n =
args[argIndex++].toInt();
594 TINYFORMAT_ERROR(
"tinyformat: Not enough arguments to read variable width or precision");
613 out.write(fmt, c - fmt);
616 else if (*c ==
'%') {
617 out.write(fmt, c - fmt);
661 bool& spacePadPositive,
662 int& ntrunc,
const char* fmtStart,
664 int& argIndex,
int numArgs)
672 out.unsetf(std::ios::adjustfield | std::ios::basefield |
673 std::ios::floatfield | std::ios::showbase | std::ios::boolalpha |
674 std::ios::showpoint | std::ios::showpos | std::ios::uppercase);
675 bool precisionSet =
false;
676 bool widthSet =
false;
678 const char* c = fmtStart + 1;
682 if (*c >=
'0' && *c <=
'9') {
683 const char tmpc = *c;
687 if (value > 0 && value <= numArgs)
688 argIndex = value - 1;
692 positionalMode =
true;
694 else if (positionalMode) {
695 TINYFORMAT_ERROR(
"tinyformat: Non-positional argument used after a positional one");
702 out.setf(std::ios::internal, std::ios::adjustfield);
711 else if (positionalMode) {
712 TINYFORMAT_ERROR(
"tinyformat: Non-positional argument used after a positional one");
720 out.setf(std::ios::showpoint | std::ios::showbase);
724 if (!(
out.flags() & std::ios::left)) {
728 out.setf(std::ios::internal, std::ios::adjustfield);
733 out.setf(std::ios::left, std::ios::adjustfield);
737 if (!(
out.flags() & std::ios::showpos))
738 spacePadPositive =
true;
741 out.setf(std::ios::showpos);
742 spacePadPositive =
false;
753 args, argIndex, numArgs);
758 out.setf(std::ios::left, std::ios::adjustfield);
769 args, argIndex, numArgs);
772 precisionSet = precision >= 0;
774 out.precision(precision);
777 while (*c ==
'l' || *c ==
'h' || *c ==
'L' ||
778 *c ==
'j' || *c ==
'z' || *c ==
't') {
784 bool intConversion =
false;
786 case 'u':
case 'd':
case 'i':
787 out.setf(std::ios::dec, std::ios::basefield);
788 intConversion =
true;
791 out.setf(std::ios::oct, std::ios::basefield);
792 intConversion =
true;
795 out.setf(std::ios::uppercase);
798 out.setf(std::ios::hex, std::ios::basefield);
799 intConversion =
true;
802 out.setf(std::ios::uppercase);
805 out.setf(std::ios::scientific, std::ios::floatfield);
806 out.setf(std::ios::dec, std::ios::basefield);
809 out.setf(std::ios::uppercase);
812 out.setf(std::ios::fixed, std::ios::floatfield);
815 out.setf(std::ios::uppercase);
824 out.setf(std::ios::fixed | std::ios::scientific, std::ios::floatfield);
827 out.setf(std::ios::uppercase);
830 out.setf(std::ios::dec, std::ios::basefield);
832 out.flags(
out.flags() & ~
std::ios::floatfield);
839 ntrunc =
static_cast<int>(
out.precision());
841 out.setf(std::ios::boolalpha);
849 "terminated by end of string");
854 if (intConversion && precisionSet && !widthSet) {
859 out.width(
out.precision() + widthExtra);
860 out.setf(std::ios::internal, std::ios::adjustfield);
873 std::streamsize origWidth =
out.width();
874 std::streamsize origPrecision =
out.precision();
875 std::ios::fmtflags origFlags =
out.flags();
876 char origFill =
out.fill();
880 bool positionalMode =
false;
885 if (!positionalMode && argIndex < numArgs) {
886 TINYFORMAT_ERROR(
"tinyformat: Not enough conversion specifiers in format string");
890 bool spacePadPositive =
false;
893 args, argIndex, numArgs);
896 if (argIndex >= numArgs) {
897 TINYFORMAT_ERROR(
"tinyformat: Too many conversion specifiers in format string");
902 if (!spacePadPositive) {
910 std::ostringstream tmpStream;
911 tmpStream.copyfmt(
out);
912 tmpStream.setf(std::ios::showpos);
913 arg.
format(tmpStream, fmt, fmtEnd, ntrunc);
914 std::string result = tmpStream.str();
915 for (
size_t i = 0, iend = result.size(); i < iend; ++i) {
916 if (result[i] ==
'+')
927 out.width(origWidth);
928 out.precision(origPrecision);
929 out.flags(origFlags);
948 friend void vformat(std::ostream&
out,
const char* fmt,
967 #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES 968 template<
typename... Args>
972 { static_assert(
sizeof...(
args) == N,
"Number of args must be N"); }
973 #else // C++98 version 975 # define TINYFORMAT_MAKE_FORMATLIST_CONSTRUCTOR(n) \ 977 template<TINYFORMAT_ARGTYPES(n)> \ 978 FormatListN(TINYFORMAT_VARARGS(n)) \ 979 : FormatList(&m_formatterStore[0], n) \ 980 { TINYFORMAT_ASSERT(n == N); init(0, TINYFORMAT_PASSARGS(n)); } \ 982 template<TINYFORMAT_ARGTYPES(n)> \ 983 void init(int i, TINYFORMAT_VARARGS(n)) \ 985 m_formatterStore[i] = FormatArg(v1); \ 986 init(i+1 TINYFORMAT_PASSARGS_TAIL(n)); \ 990 # undef TINYFORMAT_MAKE_FORMATLIST_CONSTRUCTOR 1014 #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES 1022 template<
typename... Args>
1028 #else // C++98 version 1032 return detail::FormatListN<0>();
1034 #define TINYFORMAT_MAKE_MAKEFORMATLIST(n) \ 1035 template<TINYFORMAT_ARGTYPES(n)> \ 1036 detail::FormatListN<n> makeFormatList(TINYFORMAT_VARARGS(n)) \ 1038 return detail::FormatListN<n>(TINYFORMAT_PASSARGS(n)); \ 1041 #undef TINYFORMAT_MAKE_MAKEFORMATLIST 1055 #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES 1058 template<
typename... Args>
1066 template<
typename... Args>
1069 std::ostringstream oss;
1075 template<
typename... Args>
1081 template<
typename... Args>
1089 #else // C++98 version 1091 inline void format(std::ostream&
out,
const char* fmt)
1096 inline std::string
format(
const char* fmt)
1098 std::ostringstream oss;
1103 inline void printf(
const char* fmt)
1108 inline void printfln(
const char* fmt)
1114 #define TINYFORMAT_MAKE_FORMAT_FUNCS(n) \ 1116 template<TINYFORMAT_ARGTYPES(n)> \ 1117 void format(std::ostream& out, const char* fmt, TINYFORMAT_VARARGS(n)) \ 1119 vformat(out, fmt, makeFormatList(TINYFORMAT_PASSARGS(n))); \ 1122 template<TINYFORMAT_ARGTYPES(n)> \ 1123 std::string format(const char* fmt, TINYFORMAT_VARARGS(n)) \ 1125 std::ostringstream oss; \ 1126 format(oss, fmt, TINYFORMAT_PASSARGS(n)); \ 1130 template<TINYFORMAT_ARGTYPES(n)> \ 1131 void printf(const char* fmt, TINYFORMAT_VARARGS(n)) \ 1133 format(std::cout, fmt, TINYFORMAT_PASSARGS(n)); \ 1136 template<TINYFORMAT_ARGTYPES(n)> \ 1137 void printfln(const char* fmt, TINYFORMAT_VARARGS(n)) \ 1139 format(std::cout, fmt, TINYFORMAT_PASSARGS(n)); \ 1140 std::cout << '\n'; \ 1144 #undef TINYFORMAT_MAKE_FORMAT_FUNCS 1149 template<
typename... Args>
1152 std::ostringstream oss;
1161 #define strprintf tfm::format 1163 #endif // TINYFORMAT_H_INCLUDED
std::unique_ptr< interfaces::Init > init
#define T(expected, seed, data)