------------------------------------------------------------------------------
| 780 | |
| 781 | //------------------------------------------------------------------------------ |
| 782 | inline void formatImpl(std::ostream& out, const char* fmt, |
| 783 | const detail::FormatArg* formatters, |
| 784 | int numFormatters) |
| 785 | { |
| 786 | // Saved stream state |
| 787 | std::streamsize origWidth = out.width(); |
| 788 | std::streamsize origPrecision = out.precision(); |
| 789 | std::ios::fmtflags origFlags = out.flags(); |
| 790 | char origFill = out.fill(); |
| 791 | |
| 792 | for (int argIndex = 0; argIndex < numFormatters; ++argIndex) |
| 793 | { |
| 794 | // Parse the format string |
| 795 | fmt = printFormatStringLiteral(out, fmt); |
| 796 | bool spacePadPositive = false; |
| 797 | int ntrunc = -1; |
| 798 | const char* fmtEnd = streamStateFromFormat(out, spacePadPositive, ntrunc, fmt, |
| 799 | formatters, argIndex, numFormatters); |
| 800 | if (argIndex >= numFormatters) |
| 801 | { |
| 802 | // Check args remain after reading any variable width/precision |
| 803 | TINYFORMAT_ERROR("tinyformat: Not enough format arguments"); |
| 804 | return; |
| 805 | } |
| 806 | const FormatArg& arg = formatters[argIndex]; |
| 807 | // Format the arg into the stream. |
| 808 | if(!spacePadPositive) |
| 809 | arg.format(out, fmt, fmtEnd, ntrunc); |
| 810 | else |
| 811 | { |
| 812 | // The following is a special case with no direct correspondence |
| 813 | // between stream formatting and the printf() behaviour. Simulate |
| 814 | // it crudely by formatting into a temporary string stream and |
| 815 | // munging the resulting string. |
| 816 | std::ostringstream tmpStream; |
| 817 | tmpStream.copyfmt(out); |
| 818 | tmpStream.setf(std::ios::showpos); |
| 819 | arg.format(tmpStream, fmt, fmtEnd, ntrunc); |
| 820 | std::string result = tmpStream.str(); // allocates... yuck. |
| 821 | for(size_t i = 0, iend = result.size(); i < iend; ++i) |
| 822 | if(result[i] == '+') result[i] = ' '; |
| 823 | out << result; |
| 824 | } |
| 825 | fmt = fmtEnd; |
| 826 | } |
| 827 | |
| 828 | // Print remaining part of format string. |
| 829 | fmt = printFormatStringLiteral(out, fmt); |
| 830 | if(*fmt != '\0') |
| 831 | TINYFORMAT_ERROR("tinyformat: Too many conversion specifiers in format string"); |
| 832 | |
| 833 | // Restore stream state |
| 834 | out.width(origWidth); |
| 835 | out.precision(origPrecision); |
| 836 | out.flags(origFlags); |
| 837 | out.fill(origFill); |
| 838 | } |
| 839 |