116#ifndef TINYFORMAT_H_INCLUDED 
  117#define TINYFORMAT_H_INCLUDED 
  141#ifndef TINYFORMAT_ASSERT 
  142#   define TINYFORMAT_ASSERT(cond) assert(cond) 
  145#ifndef TINYFORMAT_ERROR 
  146#   define TINYFORMAT_ERROR(reason) assert(0 && reason) 
  149#if !defined(TINYFORMAT_USE_VARIADIC_TEMPLATES) && !defined(TINYFORMAT_NO_VARIADIC_TEMPLATES) 
  150#   ifdef __GXX_EXPERIMENTAL_CXX0X__ 
  151#       define TINYFORMAT_USE_VARIADIC_TEMPLATES 
  155#if defined(__GLIBCXX__) && __GLIBCXX__ < 20080201 
  158#   define TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND 
  164#   define TINYFORMAT_HIDDEN __attribute__((visibility("hidden"))) 
  166#   define TINYFORMAT_HIDDEN 
  175template <
typename T1, 
typename T2>
 
  189#       pragma warning(push) 
  190#       pragma warning(disable:4244) 
  191#       pragma warning(disable:4267) 
 
  209template<
int n> 
struct is_wchar<const wchar_t[n]> {};
 
  215template<typename T, typename fmtT, bool convertible = is_convertible<T, fmtT>::value>
 
  222template<
typename T, 
typename fmtT>
 
  225    static void invoke(std::ostream& out, 
const T& value)
 
  226        { out << static_cast<fmtT>(value); }
 
 
 
  229#ifdef TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND 
  230template<typename T, bool convertible = is_convertible<T, int>::value>
 
  231struct formatZeroIntegerWorkaround
 
  233    static bool invoke(std::ostream& , 
const T& ) { 
return false; }
 
  236struct formatZeroIntegerWorkaround<T,true>
 
  238    static bool invoke(std::ostream& out, 
const T& value)
 
  240        if (
static_cast<int>(value) == 0 && out.flags() & std::ios::showpos)
 
  252template<typename T, bool convertible = is_convertible<T,int>::value>
 
  258                         "integer for use as variable width or precision");
 
 
 
  266    static int invoke(
const T& value) { 
return static_cast<int>(value); }
 
 
  273    std::ostringstream tmp;
 
  275    std::string result = tmp.str();
 
  276    out.write(result.c_str(), (std::min)(ntrunc, 
static_cast<int>(result.size())));
 
 
  278#define TINYFORMAT_DEFINE_FORMAT_TRUNCATED_CSTR(type)       \ 
  279inline void formatTruncated(std::ostream& out, type* value, int ntrunc) \ 
  281    std::streamsize len = 0;                                \ 
  282    while(len < ntrunc && value[len] != 0)                  \ 
  284    out.write(value, len);                                  \ 
 
  290#undef TINYFORMAT_DEFINE_FORMAT_TRUNCATED_CSTR 
 
  313                        const char* fmtEnd, 
int ntrunc, 
const T& value)
 
  315#ifndef TINYFORMAT_ALLOW_WCHAR_STRINGS 
  328    if(canConvertToChar && *(fmtEnd-1) == 
'c')
 
  330    else if(canConvertToVoidPtr && *(fmtEnd-1) == 
'p')
 
  332#ifdef TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND 
  333    else if(detail::formatZeroIntegerWorkaround<T>::invoke(out, value)) ;
 
 
  347#define TINYFORMAT_DEFINE_FORMATVALUE_CHAR(charType)                  \ 
  348inline void formatValue(std::ostream& out, const char* ,  \ 
  349                        const char* fmtEnd, int , charType value) \ 
  351    switch(*(fmtEnd-1))                                               \ 
  353        case 'u': case 'd': case 'i': case 'o': case 'X': case 'x':   \ 
  354            out << static_cast<int>(value); break;                    \ 
  356            out << value;                   break;                    \ 
  363#undef TINYFORMAT_DEFINE_FORMATVALUE_CHAR 
  371#define TINYFORMAT_ARGTYPES(n) TINYFORMAT_ARGTYPES_ ## n 
  372#define TINYFORMAT_VARARGS(n) TINYFORMAT_VARARGS_ ## n 
  373#define TINYFORMAT_PASSARGS(n) TINYFORMAT_PASSARGS_ ## n 
  374#define TINYFORMAT_PASSARGS_TAIL(n) TINYFORMAT_PASSARGS_TAIL_ ## n 
  412#define TINYFORMAT_ARGTYPES_1 class T1 
  413#define TINYFORMAT_ARGTYPES_2 class T1, class T2 
  414#define TINYFORMAT_ARGTYPES_3 class T1, class T2, class T3 
  415#define TINYFORMAT_ARGTYPES_4 class T1, class T2, class T3, class T4 
  416#define TINYFORMAT_ARGTYPES_5 class T1, class T2, class T3, class T4, class T5 
  417#define TINYFORMAT_ARGTYPES_6 class T1, class T2, class T3, class T4, class T5, class T6 
  418#define TINYFORMAT_ARGTYPES_7 class T1, class T2, class T3, class T4, class T5, class T6, class T7 
  419#define TINYFORMAT_ARGTYPES_8 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8 
  420#define TINYFORMAT_ARGTYPES_9 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9 
  421#define TINYFORMAT_ARGTYPES_10 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10 
  422#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 
  423#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 
  424#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 
  425#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 
  426#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 
  427#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 
  429#define TINYFORMAT_VARARGS_1 const T1& v1 
  430#define TINYFORMAT_VARARGS_2 const T1& v1, const T2& v2 
  431#define TINYFORMAT_VARARGS_3 const T1& v1, const T2& v2, const T3& v3 
  432#define TINYFORMAT_VARARGS_4 const T1& v1, const T2& v2, const T3& v3, const T4& v4 
  433#define TINYFORMAT_VARARGS_5 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5 
  434#define TINYFORMAT_VARARGS_6 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6 
  435#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 
  436#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 
  437#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 
  438#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 
  439#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 
  440#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 
  441#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 
  442#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 
  443#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 
  444#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 
  446#define TINYFORMAT_PASSARGS_1 v1 
  447#define TINYFORMAT_PASSARGS_2 v1, v2 
  448#define TINYFORMAT_PASSARGS_3 v1, v2, v3 
  449#define TINYFORMAT_PASSARGS_4 v1, v2, v3, v4 
  450#define TINYFORMAT_PASSARGS_5 v1, v2, v3, v4, v5 
  451#define TINYFORMAT_PASSARGS_6 v1, v2, v3, v4, v5, v6 
  452#define TINYFORMAT_PASSARGS_7 v1, v2, v3, v4, v5, v6, v7 
  453#define TINYFORMAT_PASSARGS_8 v1, v2, v3, v4, v5, v6, v7, v8 
  454#define TINYFORMAT_PASSARGS_9 v1, v2, v3, v4, v5, v6, v7, v8, v9 
  455#define TINYFORMAT_PASSARGS_10 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 
  456#define TINYFORMAT_PASSARGS_11 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11 
  457#define TINYFORMAT_PASSARGS_12 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12 
  458#define TINYFORMAT_PASSARGS_13 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13 
  459#define TINYFORMAT_PASSARGS_14 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14 
  460#define TINYFORMAT_PASSARGS_15 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 
  461#define TINYFORMAT_PASSARGS_16 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16 
  463#define TINYFORMAT_PASSARGS_TAIL_1 
  464#define TINYFORMAT_PASSARGS_TAIL_2 , v2 
  465#define TINYFORMAT_PASSARGS_TAIL_3 , v2, v3 
  466#define TINYFORMAT_PASSARGS_TAIL_4 , v2, v3, v4 
  467#define TINYFORMAT_PASSARGS_TAIL_5 , v2, v3, v4, v5 
  468#define TINYFORMAT_PASSARGS_TAIL_6 , v2, v3, v4, v5, v6 
  469#define TINYFORMAT_PASSARGS_TAIL_7 , v2, v3, v4, v5, v6, v7 
  470#define TINYFORMAT_PASSARGS_TAIL_8 , v2, v3, v4, v5, v6, v7, v8 
  471#define TINYFORMAT_PASSARGS_TAIL_9 , v2, v3, v4, v5, v6, v7, v8, v9 
  472#define TINYFORMAT_PASSARGS_TAIL_10 , v2, v3, v4, v5, v6, v7, v8, v9, v10 
  473#define TINYFORMAT_PASSARGS_TAIL_11 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11 
  474#define TINYFORMAT_PASSARGS_TAIL_12 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12 
  475#define TINYFORMAT_PASSARGS_TAIL_13 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13 
  476#define TINYFORMAT_PASSARGS_TAIL_14 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14 
  477#define TINYFORMAT_PASSARGS_TAIL_15 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 
  478#define TINYFORMAT_PASSARGS_TAIL_16 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16 
  480#define TINYFORMAT_FOREACH_ARGNUM(m) \ 
  481    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) 
 
  503            : 
m_value(static_cast<const void*>(&value)),
 
 
  508        void format(std::ostream& out, 
const char* fmtBegin,
 
  509                    const char* fmtEnd, 
int ntrunc)
 const 
 
  526                        const char* fmtEnd, 
int ntrunc, 
const void* value)
 
  528            formatValue(out, fmtBegin, fmtEnd, ntrunc, *
static_cast<const T*
>(value));
 
 
  539                             const char* fmtEnd, 
int ntrunc, 
const void* value);
 
 
  549    for(;*c >= 
'0' && *c <= 
'9'; ++c)
 
  550        i = 10*i + (*c - 
'0');
 
 
  568                out.write(fmt, c - fmt);
 
  571                out.write(fmt, c - fmt);
 
 
  595                                         int& ntrunc, 
const char* fmtStart,
 
  597                                         int& argIndex, 
int numFormatters)
 
  601        TINYFORMAT_ERROR(
"tinyformat: Not enough conversion specifiers in format string");
 
  609    out.unsetf(std::ios::adjustfield | std::ios::basefield |
 
  610               std::ios::floatfield | std::ios::showbase | std::ios::boolalpha |
 
  611               std::ios::showpoint | std::ios::showpos | std::ios::uppercase);
 
  612    bool precisionSet = 
false;
 
  613    bool widthSet = 
false;
 
  615    const char* c = fmtStart + 1;
 
  622                out.setf(std::ios::showpoint | std::ios::showbase);
 
  626                if(!(out.flags() & std::ios::left))
 
  631                    out.setf(std::ios::internal, std::ios::adjustfield);
 
  636                out.setf(std::ios::left, std::ios::adjustfield);
 
  640                if(!(out.flags() & std::ios::showpos))
 
  641                    spacePadPositive = 
true;
 
  644                out.setf(std::ios::showpos);
 
  645                spacePadPositive = 
false;
 
  654    if(*c >= 
'0' && *c <= 
'9')
 
  663        if(argIndex < numFormatters)
 
  664            width = formatters[argIndex++].
toInt();
 
  666            TINYFORMAT_ERROR(
"tinyformat: Not enough arguments to read variable width");
 
  671            out.setf(std::ios::left, std::ios::adjustfield);
 
  685            if(argIndex < numFormatters)
 
  686                precision = formatters[argIndex++].
toInt();
 
  688                TINYFORMAT_ERROR(
"tinyformat: Not enough arguments to read variable precision");
 
  692            if(*c >= 
'0' && *c <= 
'9')
 
  697        out.precision(precision);
 
  701    while(*c == 
'l' || *c == 
'h' || *c == 
'L' ||
 
  702          *c == 
'j' || *c == 
'z' || *c == 
't')
 
  707    bool intConversion = 
false;
 
  710        case 'u': 
case 'd': 
case 'i':
 
  711            out.setf(std::ios::dec, std::ios::basefield);
 
  712            intConversion = 
true;
 
  715            out.setf(std::ios::oct, std::ios::basefield);
 
  716            intConversion = 
true;
 
  719            out.setf(std::ios::uppercase);
 
  722            out.setf(std::ios::hex, std::ios::basefield);
 
  723            intConversion = 
true;
 
  726            out.setf(std::ios::uppercase);
 
  729            out.setf(std::ios::scientific, std::ios::floatfield);
 
  730            out.setf(std::ios::dec, std::ios::basefield);
 
  733            out.setf(std::ios::uppercase);
 
  736            out.setf(std::ios::fixed, std::ios::floatfield);
 
  739            out.setf(std::ios::uppercase);
 
  742            out.setf(std::ios::dec, std::ios::basefield);
 
  744            out.flags(out.flags() & ~std::ios::floatfield);
 
  748                             "are not supported");
 
  755                ntrunc = 
static_cast<int>(out.precision());
 
  757            out.setf(std::ios::boolalpha);
 
  765                             "terminated by end of string");
 
  770    if(intConversion && precisionSet && !widthSet)
 
  776        out.width(out.precision() + widthExtra);
 
  777        out.setf(std::ios::internal, std::ios::adjustfield);
 
 
  790    std::streamsize origWidth = out.width();
 
  791    std::streamsize origPrecision = out.precision();
 
  792    std::ios::fmtflags origFlags = out.flags();
 
  793    char origFill = out.fill();
 
  795    for (
int argIndex = 0; argIndex < numFormatters; ++argIndex)
 
  799        bool spacePadPositive = 
false;
 
  802                                                   formatters, argIndex, numFormatters);
 
  803        if (argIndex >= numFormatters)
 
  809        const FormatArg& arg = formatters[argIndex];
 
  811        if(!spacePadPositive)
 
  812            arg.
format(out, fmt, fmtEnd, ntrunc);
 
  819            std::ostringstream tmpStream;
 
  820            tmpStream.copyfmt(out);
 
  821            tmpStream.setf(std::ios::showpos);
 
  822            arg.
format(tmpStream, fmt, fmtEnd, ntrunc);
 
  823            std::string result = tmpStream.str(); 
 
  824            for(
size_t i = 0, iend = result.size(); i < iend; ++i)
 
  825                if(result[i] == 
'+') result[i] = 
' ';
 
  834        TINYFORMAT_ERROR(
"tinyformat: Too many conversion specifiers in format string");
 
  837    out.width(origWidth);
 
  838    out.precision(origPrecision);
 
  839    out.flags(origFlags);
 
 
  858        friend void vformat(std::ostream& out, 
const char* fmt,
 
 
  877#ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES 
  878        template<
typename... Args>
 
  882        { 
static_assert(
sizeof...(args) == N, 
"Number of args must be N"); }
 
  885#       define TINYFORMAT_MAKE_FORMATLIST_CONSTRUCTOR(n)                \ 
  887        template<TINYFORMAT_ARGTYPES(n)>                                \ 
  888        FormatListN(TINYFORMAT_VARARGS(n))                              \ 
  889            : FormatList(&m_formatterStore[0], n)                       \ 
  890        { TINYFORMAT_ASSERT(n == N); init(0, TINYFORMAT_PASSARGS(n)); } \ 
  892        template<TINYFORMAT_ARGTYPES(n)>                                \ 
  893        void init(int i, TINYFORMAT_VARARGS(n))                         \ 
  895            m_formatterStore[i] = FormatArg(v1);                        \ 
  896            init(i+1 TINYFORMAT_PASSARGS_TAIL(n));                      \ 
 
  900#       undef TINYFORMAT_MAKE_FORMATLIST_CONSTRUCTOR 
 
  919#ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES 
  927template<
typename... Args>
 
  928detail::FormatListN<
sizeof...(Args)> 
makeFormatList(
const Args&... args)
 
  930    return detail::FormatListN<
sizeof...(args)>(args...);
 
  939#define TINYFORMAT_MAKE_MAKEFORMATLIST(n)                     \ 
  940template<TINYFORMAT_ARGTYPES(n)>                              \ 
  941detail::FormatListN<n> makeFormatList(TINYFORMAT_VARARGS(n))  \ 
  943    return detail::FormatListN<n>(TINYFORMAT_PASSARGS(n));    \ 
 
  946#undef TINYFORMAT_MAKE_MAKEFORMATLIST 
  960#ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES 
  963template<
typename... Args>
 
  964void format(std::ostream& out, 
const char* fmt, 
const Args&... args)
 
  971template<
typename... Args>
 
  972std::string 
format(
const char* fmt, 
const Args&... args)
 
  974    std::ostringstream oss;
 
  975    format(oss, fmt, args...);
 
  980template<
typename... Args>
 
  981void printf(
const char* fmt, 
const Args&... args)
 
  983    format(std::cout, fmt, args...);
 
  986template<
typename... Args>
 
  987void printfln(
const char* fmt, 
const Args&... args)
 
  989    format(std::cout, fmt, args...);
 
  996inline void format(std::ostream& out, 
const char* fmt)
 
 
 1003    std::ostringstream oss;
 
 
 1019#define TINYFORMAT_MAKE_FORMAT_FUNCS(n)                                   \ 
 1021template<TINYFORMAT_ARGTYPES(n)>                                          \ 
 1022void format(std::ostream& out, const char* fmt, TINYFORMAT_VARARGS(n))    \ 
 1024    vformat(out, fmt, makeFormatList(TINYFORMAT_PASSARGS(n)));            \ 
 1027template<TINYFORMAT_ARGTYPES(n)>                                          \ 
 1028std::string format(const char* fmt, TINYFORMAT_VARARGS(n))                \ 
 1030    std::ostringstream oss;                                               \ 
 1031    format(oss, fmt, TINYFORMAT_PASSARGS(n));                             \ 
 1035template<TINYFORMAT_ARGTYPES(n)>                                          \ 
 1036void printf(const char* fmt, TINYFORMAT_VARARGS(n))                       \ 
 1038    format(std::cout, fmt, TINYFORMAT_PASSARGS(n));                       \ 
 1041template<TINYFORMAT_ARGTYPES(n)>                                          \ 
 1042void printfln(const char* fmt, TINYFORMAT_VARARGS(n))                     \ 
 1044    format(std::cout, fmt, TINYFORMAT_PASSARGS(n));                       \ 
 1045    std::cout << '\n';                                                    \ 
 
 1049#undef TINYFORMAT_MAKE_FORMAT_FUNCS