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 151 #ifndef TINYFORMAT_ASSERT 153 # define TINYFORMAT_ASSERT(cond) assert(cond) 156 #ifndef TINYFORMAT_ERROR 158 # define TINYFORMAT_ERROR(reason) assert(0 && reason) 161 #if !defined(TINYFORMAT_USE_VARIADIC_TEMPLATES) && !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 192 template <
unsigned num_params>
197 operator const char*() {
return fmt; }
213 template <
typename T1,
typename T2>
223 static const T1&
makeT1();
227 # pragma warning(push) 228 # pragma warning(disable:4244) 229 # pragma warning(disable:4267) 238 # pragma warning(pop) 247 template<
int n>
struct is_wchar<const wchar_t[n]> {};
253 template<typename T, typename fmtT, bool convertible = is_convertible<T, fmtT>::value>
260 template<
typename T,
typename fmtT>
264 { out << static_cast<fmtT>(value); }
267 #ifdef TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND 268 template<typename T, bool convertible = is_convertible<T, int>::value>
269 struct formatZeroIntegerWorkaround
271 static bool invoke(std::ostream& ,
const T& ) {
return false; }
274 struct formatZeroIntegerWorkaround<
T,true>
276 static bool invoke(std::ostream&
out,
const T& value)
278 if (static_cast<int>(value) == 0 &&
out.flags() & std::ios::showpos) {
285 #endif // TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND 289 template<typename T, bool convertible = is_convertible<T,int>::value>
295 "integer for use as variable width or precision");
303 static int invoke(
const T& value) {
return static_cast<int>(value); }
310 std::ostringstream tmp;
312 std::string
result = tmp.str();
313 out.write(
result.c_str(), (std::min)(ntrunc, static_cast<int>(
result.size())));
315 #define TINYFORMAT_DEFINE_FORMAT_TRUNCATED_CSTR(type) \ 316 inline void formatTruncated(std::ostream& out, type* value, int ntrunc) \ 318 std::streamsize len = 0; \ 319 while (len < ntrunc && value[len] != 0) \ 321 out.write(value, len); \ 327 #undef TINYFORMAT_DEFINE_FORMAT_TRUNCATED_CSTR 350 const char* fmtEnd,
int ntrunc,
const T& value)
352 #ifndef TINYFORMAT_ALLOW_WCHAR_STRINGS 365 if (canConvertToChar && *(fmtEnd-1) ==
'c')
367 else if (canConvertToVoidPtr && *(fmtEnd-1) ==
'p')
369 #ifdef TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND 370 else if (detail::formatZeroIntegerWorkaround<T>::invoke(
out, value)) ;
372 else if (ntrunc >= 0) {
383 #define TINYFORMAT_DEFINE_FORMATVALUE_CHAR(charType) \ 384 inline void formatValue(std::ostream& out, const char* , \ 385 const char* fmtEnd, int , charType value) \ 387 switch (*(fmtEnd-1)) { \ 388 case 'u': case 'd': case 'i': case 'o': case 'X': case 'x': \ 389 out << static_cast<int>(value); break; \ 391 out << value; break; \ 398 #undef TINYFORMAT_DEFINE_FORMATVALUE_CHAR 406 #define TINYFORMAT_ARGTYPES(n) TINYFORMAT_ARGTYPES_ ## n 407 #define TINYFORMAT_VARARGS(n) TINYFORMAT_VARARGS_ ## n 408 #define TINYFORMAT_PASSARGS(n) TINYFORMAT_PASSARGS_ ## n 409 #define TINYFORMAT_PASSARGS_TAIL(n) TINYFORMAT_PASSARGS_TAIL_ ## n 447 #define TINYFORMAT_ARGTYPES_1 class T1 448 #define TINYFORMAT_ARGTYPES_2 class T1, class T2 449 #define TINYFORMAT_ARGTYPES_3 class T1, class T2, class T3 450 #define TINYFORMAT_ARGTYPES_4 class T1, class T2, class T3, class T4 451 #define TINYFORMAT_ARGTYPES_5 class T1, class T2, class T3, class T4, class T5 452 #define TINYFORMAT_ARGTYPES_6 class T1, class T2, class T3, class T4, class T5, class T6 453 #define TINYFORMAT_ARGTYPES_7 class T1, class T2, class T3, class T4, class T5, class T6, class T7 454 #define TINYFORMAT_ARGTYPES_8 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8 455 #define TINYFORMAT_ARGTYPES_9 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9 456 #define TINYFORMAT_ARGTYPES_10 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10 457 #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 458 #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 459 #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 460 #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 461 #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 462 #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 464 #define TINYFORMAT_VARARGS_1 const T1& v1 465 #define TINYFORMAT_VARARGS_2 const T1& v1, const T2& v2 466 #define TINYFORMAT_VARARGS_3 const T1& v1, const T2& v2, const T3& v3 467 #define TINYFORMAT_VARARGS_4 const T1& v1, const T2& v2, const T3& v3, const T4& v4 468 #define TINYFORMAT_VARARGS_5 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5 469 #define TINYFORMAT_VARARGS_6 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6 470 #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 471 #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 472 #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 473 #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 474 #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 475 #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 476 #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 477 #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 478 #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 479 #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 481 #define TINYFORMAT_PASSARGS_1 v1 482 #define TINYFORMAT_PASSARGS_2 v1, v2 483 #define TINYFORMAT_PASSARGS_3 v1, v2, v3 484 #define TINYFORMAT_PASSARGS_4 v1, v2, v3, v4 485 #define TINYFORMAT_PASSARGS_5 v1, v2, v3, v4, v5 486 #define TINYFORMAT_PASSARGS_6 v1, v2, v3, v4, v5, v6 487 #define TINYFORMAT_PASSARGS_7 v1, v2, v3, v4, v5, v6, v7 488 #define TINYFORMAT_PASSARGS_8 v1, v2, v3, v4, v5, v6, v7, v8 489 #define TINYFORMAT_PASSARGS_9 v1, v2, v3, v4, v5, v6, v7, v8, v9 490 #define TINYFORMAT_PASSARGS_10 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 491 #define TINYFORMAT_PASSARGS_11 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11 492 #define TINYFORMAT_PASSARGS_12 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12 493 #define TINYFORMAT_PASSARGS_13 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13 494 #define TINYFORMAT_PASSARGS_14 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14 495 #define TINYFORMAT_PASSARGS_15 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 496 #define TINYFORMAT_PASSARGS_16 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16 498 #define TINYFORMAT_PASSARGS_TAIL_1 499 #define TINYFORMAT_PASSARGS_TAIL_2 , v2 500 #define TINYFORMAT_PASSARGS_TAIL_3 , v2, v3 501 #define TINYFORMAT_PASSARGS_TAIL_4 , v2, v3, v4 502 #define TINYFORMAT_PASSARGS_TAIL_5 , v2, v3, v4, v5 503 #define TINYFORMAT_PASSARGS_TAIL_6 , v2, v3, v4, v5, v6 504 #define TINYFORMAT_PASSARGS_TAIL_7 , v2, v3, v4, v5, v6, v7 505 #define TINYFORMAT_PASSARGS_TAIL_8 , v2, v3, v4, v5, v6, v7, v8 506 #define TINYFORMAT_PASSARGS_TAIL_9 , v2, v3, v4, v5, v6, v7, v8, v9 507 #define TINYFORMAT_PASSARGS_TAIL_10 , v2, v3, v4, v5, v6, v7, v8, v9, v10 508 #define TINYFORMAT_PASSARGS_TAIL_11 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11 509 #define TINYFORMAT_PASSARGS_TAIL_12 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12 510 #define TINYFORMAT_PASSARGS_TAIL_13 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13 511 #define TINYFORMAT_PASSARGS_TAIL_14 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14 512 #define TINYFORMAT_PASSARGS_TAIL_15 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 513 #define TINYFORMAT_PASSARGS_TAIL_16 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16 515 #define TINYFORMAT_FOREACH_ARGNUM(m) \ 516 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) 534 :
m_value(static_cast<const void*>(&value)),
540 const char* fmtEnd,
int ntrunc)
const 557 const char* fmtEnd,
int ntrunc,
const void* value)
559 formatValue(
out, fmtBegin, fmtEnd, ntrunc, *static_cast<const T*>(value));
570 const char* fmtEnd,
int ntrunc,
const void* value){
nullptr};
580 for (;*c >=
'0' && *c <=
'9'; ++c)
581 i = 10*i + (*c -
'0');
592 int& argIndex,
int numArgs)
594 if (*c >=
'0' && *c <=
'9') {
597 else if (*c ==
'*') {
600 if (positionalMode) {
603 TINYFORMAT_ERROR(
"tinyformat: Non-positional argument used after a positional one");
604 if (pos >= 0 && pos < numArgs)
605 n =
args[pos].toInt();
611 if (argIndex < numArgs)
612 n =
args[argIndex++].toInt();
614 TINYFORMAT_ERROR(
"tinyformat: Not enough arguments to read variable width or precision");
633 out.write(fmt, c - fmt);
636 else if (*c ==
'%') {
637 out.write(fmt, c - fmt);
681 bool& spacePadPositive,
682 int& ntrunc,
const char* fmtStart,
684 int& argIndex,
int numArgs)
692 out.unsetf(std::ios::adjustfield | std::ios::basefield |
693 std::ios::floatfield | std::ios::showbase | std::ios::boolalpha |
694 std::ios::showpoint | std::ios::showpos | std::ios::uppercase);
695 bool precisionSet =
false;
696 bool widthSet =
false;
698 const char* c = fmtStart + 1;
702 if (*c >=
'0' && *c <=
'9') {
703 const char tmpc = *c;
707 if (value > 0 && value <= numArgs)
708 argIndex = value - 1;
712 positionalMode =
true;
714 else if (positionalMode) {
715 TINYFORMAT_ERROR(
"tinyformat: Non-positional argument used after a positional one");
722 out.setf(std::ios::internal, std::ios::adjustfield);
731 else if (positionalMode) {
732 TINYFORMAT_ERROR(
"tinyformat: Non-positional argument used after a positional one");
740 out.setf(std::ios::showpoint | std::ios::showbase);
744 if (!(
out.flags() & std::ios::left)) {
748 out.setf(std::ios::internal, std::ios::adjustfield);
753 out.setf(std::ios::left, std::ios::adjustfield);
757 if (!(
out.flags() & std::ios::showpos))
758 spacePadPositive =
true;
761 out.setf(std::ios::showpos);
762 spacePadPositive =
false;
773 args, argIndex, numArgs);
778 out.setf(std::ios::left, std::ios::adjustfield);
789 args, argIndex, numArgs);
792 precisionSet = precision >= 0;
794 out.precision(precision);
797 while (*c ==
'l' || *c ==
'h' || *c ==
'L' ||
798 *c ==
'j' || *c ==
'z' || *c ==
't') {
804 bool intConversion =
false;
806 case 'u':
case 'd':
case 'i':
807 out.setf(std::ios::dec, std::ios::basefield);
808 intConversion =
true;
811 out.setf(std::ios::oct, std::ios::basefield);
812 intConversion =
true;
815 out.setf(std::ios::uppercase);
818 out.setf(std::ios::hex, std::ios::basefield);
819 intConversion =
true;
822 out.setf(std::ios::uppercase);
825 out.setf(std::ios::scientific, std::ios::floatfield);
826 out.setf(std::ios::dec, std::ios::basefield);
829 out.setf(std::ios::uppercase);
832 out.setf(std::ios::fixed, std::ios::floatfield);
835 out.setf(std::ios::uppercase);
844 out.setf(std::ios::fixed | std::ios::scientific, std::ios::floatfield);
847 out.setf(std::ios::uppercase);
850 out.setf(std::ios::dec, std::ios::basefield);
852 out.flags(
out.flags() & ~
std::ios::floatfield);
859 ntrunc =
static_cast<int>(
out.precision());
861 out.setf(std::ios::boolalpha);
869 "terminated by end of string");
874 if (intConversion && precisionSet && !widthSet) {
879 out.width(
out.precision() + widthExtra);
880 out.setf(std::ios::internal, std::ios::adjustfield);
893 std::streamsize origWidth =
out.width();
894 std::streamsize origPrecision =
out.precision();
895 std::ios::fmtflags origFlags =
out.flags();
896 char origFill =
out.fill();
900 bool positionalMode =
false;
905 if (!positionalMode && argIndex < numArgs) {
906 TINYFORMAT_ERROR(
"tinyformat: Not enough conversion specifiers in format string");
910 bool spacePadPositive =
false;
913 args, argIndex, numArgs);
916 if (argIndex >= numArgs) {
917 TINYFORMAT_ERROR(
"tinyformat: Too many conversion specifiers in format string");
922 if (!spacePadPositive) {
930 std::ostringstream tmpStream;
931 tmpStream.copyfmt(
out);
932 tmpStream.setf(std::ios::showpos);
933 arg.
format(tmpStream, fmt, fmtEnd, ntrunc);
934 std::string
result = tmpStream.str();
935 for (
size_t i = 0, iend =
result.size(); i < iend; ++i) {
947 out.width(origWidth);
948 out.precision(origPrecision);
949 out.flags(origFlags);
968 friend void vformat(std::ostream&
out,
const char* fmt,
987 #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES 988 template<
typename... Args>
992 { static_assert(
sizeof...(
args) == N,
"Number of args must be N"); }
993 #else // C++98 version 995 # define TINYFORMAT_MAKE_FORMATLIST_CONSTRUCTOR(n) \ 997 template<TINYFORMAT_ARGTYPES(n)> \ 998 FormatListN(TINYFORMAT_VARARGS(n)) \ 999 : FormatList(&m_formatterStore[0], n) \ 1000 { TINYFORMAT_ASSERT(n == N); init(0, TINYFORMAT_PASSARGS(n)); } \ 1002 template<TINYFORMAT_ARGTYPES(n)> \ 1003 void init(int i, TINYFORMAT_VARARGS(n)) \ 1005 m_formatterStore[i] = FormatArg(v1); \ 1006 init(i+1 TINYFORMAT_PASSARGS_TAIL(n)); \ 1010 # undef TINYFORMAT_MAKE_FORMATLIST_CONSTRUCTOR 1034 #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES 1042 template<
typename... Args>
1048 #else // C++98 version 1052 return detail::FormatListN<0>();
1054 #define TINYFORMAT_MAKE_MAKEFORMATLIST(n) \ 1055 template<TINYFORMAT_ARGTYPES(n)> \ 1056 detail::FormatListN<n> makeFormatList(TINYFORMAT_VARARGS(n)) \ 1058 return detail::FormatListN<n>(TINYFORMAT_PASSARGS(n)); \ 1061 #undef TINYFORMAT_MAKE_MAKEFORMATLIST 1075 #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES 1078 template<
typename... Args>
1086 template<
typename... Args>
1089 std::ostringstream oss;
1095 template<
typename... Args>
1101 template<
typename... Args>
1109 #else // C++98 version 1111 inline void format(std::ostream&
out,
const char* fmt)
1116 inline std::string
format(
const char* fmt)
1118 std::ostringstream oss;
1123 inline void printf(
const char* fmt)
1128 inline void printfln(
const char* fmt)
1134 #define TINYFORMAT_MAKE_FORMAT_FUNCS(n) \ 1136 template<TINYFORMAT_ARGTYPES(n)> \ 1137 void format(std::ostream& out, const char* fmt, TINYFORMAT_VARARGS(n)) \ 1139 vformat(out, fmt, makeFormatList(TINYFORMAT_PASSARGS(n))); \ 1142 template<TINYFORMAT_ARGTYPES(n)> \ 1143 std::string format(const char* fmt, TINYFORMAT_VARARGS(n)) \ 1145 std::ostringstream oss; \ 1146 format(oss, fmt, TINYFORMAT_PASSARGS(n)); \ 1150 template<TINYFORMAT_ARGTYPES(n)> \ 1151 void printf(const char* fmt, TINYFORMAT_VARARGS(n)) \ 1153 format(std::cout, fmt, TINYFORMAT_PASSARGS(n)); \ 1156 template<TINYFORMAT_ARGTYPES(n)> \ 1157 void printfln(const char* fmt, TINYFORMAT_VARARGS(n)) \ 1159 format(std::cout, fmt, TINYFORMAT_PASSARGS(n)); \ 1160 std::cout << '\n'; \ 1164 #undef TINYFORMAT_MAKE_FORMAT_FUNCS 1172 #define strprintf tfm::format 1174 #endif // TINYFORMAT_H_INCLUDED
std::unique_ptr< interfaces::Init > init
#define T(expected, seed, data)