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>
183 struct fail {
char dummy[2]; };
186 static fail tryConvert(...);
188 static const T1& makeT1();
192 # pragma warning(push) 193 # pragma warning(disable:4244) 194 # pragma warning(disable:4267) 200 static const bool value =
201 sizeof(tryConvert(makeT1())) ==
sizeof(
succeed);
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>
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) 502 : m_value(static_cast<const void*>(&value)),
504 m_toIntImpl(&toIntImpl<T>)
507 void format(std::ostream& out,
const char* fmtBegin,
508 const char* fmtEnd,
int ntrunc)
const 510 m_formatImpl(out, fmtBegin, fmtEnd, ntrunc, m_value);
515 return m_toIntImpl(m_value);
521 const char* fmtEnd,
int ntrunc,
const void* value)
523 formatValue(out, fmtBegin, fmtEnd, ntrunc, *static_cast<const T*>(value));
533 void (*m_formatImpl)(std::ostream& out,
const char* fmtBegin,
534 const char* fmtEnd,
int ntrunc,
const void* value);
535 int (*m_toIntImpl)(
const void* value);
544 for(;*c >=
'0' && *c <=
'9'; ++
c)
545 i = 10*i + (*c -
'0');
563 out.write(fmt, c - fmt);
566 out.write(fmt, c - fmt);
590 int& ntrunc,
const char* fmtStart,
592 int& argIndex,
int numFormatters)
596 TINYFORMAT_ERROR(
"tinyformat: Not enough conversion specifiers in format string");
604 out.unsetf(std::ios::adjustfield | std::ios::basefield |
605 std::ios::floatfield | std::ios::showbase | std::ios::boolalpha |
606 std::ios::showpoint | std::ios::showpos | std::ios::uppercase);
607 bool precisionSet =
false;
608 bool widthSet =
false;
610 const char*
c = fmtStart + 1;
617 out.setf(std::ios::showpoint | std::ios::showbase);
621 if(!(out.flags() & std::ios::left))
626 out.setf(std::ios::internal, std::ios::adjustfield);
631 out.setf(std::ios::left, std::ios::adjustfield);
635 if(!(out.flags() & std::ios::showpos))
636 spacePadPositive =
true;
639 out.setf(std::ios::showpos);
640 spacePadPositive =
false;
649 if(*c >=
'0' && *c <=
'9')
658 if(argIndex < numFormatters)
659 width = formatters[argIndex++].
toInt();
661 TINYFORMAT_ERROR(
"tinyformat: Not enough arguments to read variable width");
666 out.setf(std::ios::left, std::ios::adjustfield);
680 if(argIndex < numFormatters)
681 precision = formatters[argIndex++].
toInt();
683 TINYFORMAT_ERROR(
"tinyformat: Not enough arguments to read variable precision");
687 if(*c >=
'0' && *c <=
'9')
692 out.precision(precision);
696 while(*c ==
'l' || *c ==
'h' || *c ==
'L' ||
697 *c ==
'j' || *c ==
'z' || *c ==
't')
702 bool intConversion =
false;
705 case 'u':
case 'd':
case 'i':
706 out.setf(std::ios::dec, std::ios::basefield);
707 intConversion =
true;
710 out.setf(std::ios::oct, std::ios::basefield);
711 intConversion =
true;
714 out.setf(std::ios::uppercase);
716 out.setf(std::ios::hex, std::ios::basefield);
717 intConversion =
true;
720 out.setf(std::ios::uppercase);
722 out.setf(std::ios::scientific, std::ios::floatfield);
723 out.setf(std::ios::dec, std::ios::basefield);
726 out.setf(std::ios::uppercase);
728 out.setf(std::ios::fixed, std::ios::floatfield);
731 out.setf(std::ios::uppercase);
733 out.setf(std::ios::dec, std::ios::basefield);
735 out.flags(out.flags() & ~
std::ios::floatfield);
739 "are not supported");
746 ntrunc =
static_cast<int>(out.precision());
748 out.setf(std::ios::boolalpha);
756 "terminated by end of string");
761 if(intConversion && precisionSet && !widthSet)
767 out.width(out.precision() + widthExtra);
768 out.setf(std::ios::internal, std::ios::adjustfield);
781 std::streamsize origWidth = out.width();
782 std::streamsize origPrecision = out.precision();
783 std::ios::fmtflags origFlags = out.flags();
784 char origFill = out.fill();
786 for (
int argIndex = 0; argIndex < numFormatters; ++argIndex)
790 bool spacePadPositive =
false;
793 formatters, argIndex, numFormatters);
794 if (argIndex >= numFormatters)
800 const FormatArg& arg = formatters[argIndex];
802 if(!spacePadPositive)
803 arg.
format(out, fmt, fmtEnd, ntrunc);
810 std::ostringstream tmpStream;
811 tmpStream.copyfmt(out);
812 tmpStream.setf(std::ios::showpos);
813 arg.
format(tmpStream, fmt, fmtEnd, ntrunc);
814 std::string result = tmpStream.str();
815 for(
size_t i = 0, iend = result.size(); i < iend; ++i)
816 if(result[i] ==
'+') result[i] =
' ';
825 TINYFORMAT_ERROR(
"tinyformat: Too many conversion specifiers in format string");
828 out.width(origWidth);
829 out.precision(origPrecision);
830 out.flags(origFlags);
847 : m_formatters(formatters), m_N(N) { }
849 friend void vformat(std::ostream& out,
const char* fmt,
868 #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES 869 template<
typename... Args>
873 { static_assert(
sizeof...(args) == N,
"Number of args must be N"); }
874 #else // C++98 version 876 # define TINYFORMAT_MAKE_FORMATLIST_CONSTRUCTOR(n) \ 878 template<TINYFORMAT_ARGTYPES(n)> \ 879 FormatListN(TINYFORMAT_VARARGS(n)) \ 880 : FormatList(&m_formatterStore[0], n) \ 881 { assert(n == N); init(0, TINYFORMAT_PASSARGS(n)); } \ 883 template<TINYFORMAT_ARGTYPES(n)> \ 884 void init(int i, TINYFORMAT_VARARGS(n)) \ 886 m_formatterStore[i] = FormatArg(v1); \ 887 init(i+1 TINYFORMAT_PASSARGS_TAIL(n)); \ 891 # undef TINYFORMAT_MAKE_FORMATLIST_CONSTRUCTOR 910 #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES 918 template<
typename... Args>
924 #else // C++98 version 930 #define TINYFORMAT_MAKE_MAKEFORMATLIST(n) \ 931 template<TINYFORMAT_ARGTYPES(n)> \ 932 detail::FormatListN<n> makeFormatList(TINYFORMAT_VARARGS(n)) \ 934 return detail::FormatListN<n>(TINYFORMAT_PASSARGS(n)); \ 937 #undef TINYFORMAT_MAKE_MAKEFORMATLIST 945 inline void vformat(std::ostream& out,
const char* fmt, FormatListRef list)
951 #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES 954 template<
typename... Args>
955 void format(std::ostream& out,
const char* fmt,
const Args&... args)
962 template<
typename... Args>
963 std::string
format(
const char* fmt,
const Args&... args)
965 std::ostringstream oss;
966 format(oss, fmt, args...);
971 template<
typename... Args>
972 void printf(
const char* fmt,
const Args&... args)
974 format(std::cout, fmt, args...);
977 template<
typename... Args>
978 void printfln(
const char* fmt,
const Args&... args)
980 format(std::cout, fmt, args...);
984 #else // C++98 version 986 inline void format(std::ostream& out,
const char* fmt)
991 inline std::string
format(
const char* fmt)
993 std::ostringstream oss;
998 inline void printf(
const char* fmt)
1003 inline void printfln(
const char* fmt)
1009 #define TINYFORMAT_MAKE_FORMAT_FUNCS(n) \ 1011 template<TINYFORMAT_ARGTYPES(n)> \ 1012 void format(std::ostream& out, const char* fmt, TINYFORMAT_VARARGS(n)) \ 1014 vformat(out, fmt, makeFormatList(TINYFORMAT_PASSARGS(n))); \ 1017 template<TINYFORMAT_ARGTYPES(n)> \ 1018 std::string format(const char* fmt, TINYFORMAT_VARARGS(n)) \ 1020 std::ostringstream oss; \ 1021 format(oss, fmt, TINYFORMAT_PASSARGS(n)); \ 1025 template<TINYFORMAT_ARGTYPES(n)> \ 1026 void printf(const char* fmt, TINYFORMAT_VARARGS(n)) \ 1028 format(std::cout, fmt, TINYFORMAT_PASSARGS(n)); \ 1031 template<TINYFORMAT_ARGTYPES(n)> \ 1032 void printfln(const char* fmt, TINYFORMAT_VARARGS(n)) \ 1034 format(std::cout, fmt, TINYFORMAT_PASSARGS(n)); \ 1035 std::cout << '\n'; \ 1039 #undef TINYFORMAT_MAKE_FORMAT_FUNCS 1044 template<
typename... Args>
1045 std::string
format(
const std::string &fmt,
const Args&... args)
1047 std::ostringstream oss;
1048 format(oss, fmt.c_str(), args...);
1054 #define strprintf tfm::format 1056 #endif // TINYFORMAT_H_INCLUDED
std::hash for asio::adress
assert(len-trim+(2 *lenIndices)<=WIDTH)