Example #1
0
inline stlsoft::basic_shim_string<ff_char_t, 64> real_helper_4(
    double const&       value
,   int                 minimumWidth
,   int                 precision
,   ff_char_t const*    specifier
)
{
    ff_char_t   type    =   'f';
    ff_char_t   fmt_[]  =   FASTFORMAT_LITERAL_STRING("%-01234567890123456789.01234567890123456789f");
    ff_char_t*  fmt     =   fmt_;

    if(NULL != specifier)
    {
        type = *specifier;
    }

    if( default_width_sentinel_() == minimumWidth &&
        precision < 0)
    {
        fmt[1] = type;
        fmt[2] = '\0';
    }
    else
    {
        if(default_width_sentinel_() == minimumWidth)
        {
            minimumWidth = 0;
        }
        if(precision < 0)
        {
            precision = 0;
        }

        // Performance tests show a substantial advantage in using
        // integer_to_string() over fastformat_util_snprintf()

#if 0

        int n = fastformat_util_snprintf(&fmt[0], STLSOFT_NUM_ELEMENTS(fmt_) - 1, FASTFORMAT_LITERAL_STRING("%%%d.%d%c"), minimumWidth, precision, type);

        FASTFORMAT_CONTRACT_ENFORCE_ASSUMPTION((n > 0) && (n < int(STLSOFT_NUM_ELEMENTS(fmt_)) - 1));

        fmt[n] = '\0';

#else /* ? 0 */

        const size_t    fmtDim  =   STLSOFT_NUM_ELEMENTS(fmt_) - 1;
        ff_char_t*      end     =   &fmt[fmtDim];
        size_t          n1;
        size_t          n2;

        stlsoft::integer_to_string(end - 21, 21, precision, &n1);
        *--end = type;
        end -= n1;
        stlsoft::integer_to_string(end - 21, 21, minimumWidth, &n2);
        *--end = '.';
        end -= n2;
        *--end = '%';
        fmt = end;

#endif /* 0 */
    }

    return real_helper_2(value, fmt);
}
inline S change_windows_replacement_parameters_to_fastformat(S const& str)
{
    typedef ss_typename_type_k S::const_iterator    iter_t;

    enum state_t
    {
        normal, percent, number
    }       state   =   normal;
    S       str2;
    int     index   =   0;

    str2.reserve(str.size() + 10);

    { for(iter_t begin = str.begin(); begin != str.end(); ++begin)
    {
        bool isNumber = false;

        switch(*begin)
        {
            case    '0':
            case    '1':
            case    '2':
            case    '3':
            case    '4':
            case    '5':
            case    '6':
            case    '7':
            case    '8':
            case    '9':
                isNumber = true;
        }

        if( number == state &&
            !isNumber)
        {
            ff_char_t   parameter[32];
            int         cch = fastformat_util_snprintf(&parameter[0], STLSOFT_NUM_ELEMENTS(parameter), FASTFORMAT_LITERAL_STRING("{%d}"), index - 1);

            str2.append(parameter, size_t(cch));
            str2.append(1u, *begin);

            state = normal;
        }
        else
        {
            switch(*begin)
            {
                case    '%':
                    switch(state)
                    {
                        default:
                        case    number:
                            FASTFORMAT_CONTRACT_ENFORCE_UNEXPECTED_CONDITION_INTERNAL("unexpected state");
                        case    normal:
                            state = percent;
                            break;
                        case    percent:
                            state = normal;
                            str2.append(1, '%');
                            break;
                    }
                    break;
                case    '0':
                case    '1':
                case    '2':
                case    '3':
                case    '4':
                case    '5':
                case    '6':
                case    '7':
                case    '8':
                case    '9':
                    switch(state)
                    {
                        default:
                            FASTFORMAT_CONTRACT_ENFORCE_UNEXPECTED_CONDITION_INTERNAL("unexpected state");
                        case    normal:
                            str2.append(1, *begin);
                            break;
                        case    percent:
                            state = number;
                            index = (*begin - '0');
                            break;
                        case    number:
                            index = (10 * index) + (*begin - '0');
                            break;
                    }
                    break;
                default:
                    state = normal;
                    str2.append(1, *begin);
                    break;
            }
        }
    }}

    if(number == state)
	{
        ff_char_t   parameter[32];
        int         cch = fastformat_util_snprintf(&parameter[0], STLSOFT_NUM_ELEMENTS(parameter), FASTFORMAT_LITERAL_STRING("{%d}"), index - 1);

        str2.append(parameter, size_t(cch));
    }

    return str2;
}
Example #3
0
inline stlsoft::basic_shim_string<ff_char_t, 64> real_helper_2(
    double const&       value
,   ff_char_t const*    fmt
)
{
    typedef stlsoft::basic_shim_string<ff_char_t, 64>   result_t;

    enum { maxRepeats = 4 };

#if _STLSOFT_VER < 0x010a0000 && \
    defined(_STLSOFT_1_10_VER) && \
    _STLSOFT_1_10_VER < 0x010a0109

    /* Using STLSoft 1.10.1 alpha 1 - alpha 8 */

# error This class cannot work with STLSoft 1.10 versions between 1.10.1 alpha 1 and 1.10.1 alpha 9. Please download the latest version of STLSoft 1.10 alpha

#elif _STLSOFT_VER >= 0x010a0000 || \
      defined(_STLSOFT_1_10_VER)

    /* Using STLSoft 1.10+ version of basic_shim_string */

    // We use the public interface of the shim string.

    result_t result(64);

# ifndef STLSOFT_CF_THROW_BAD_ALLOC
    if(!result.empty())
# endif /* !STLSOFT_CF_THROW_BAD_ALLOC */
    {
        // Unlike integral types, the string representation of floating
        // point values do not have a known maximum length, so we must be
        // flexible.
        //
        // However, some implementations of snprintf() return -1 instead of
        // the length that would be required, so we cannot assume -1
        // indicates error. To handle this, we double the size of the buffer
        // up to four times, at which point we admit defeat.

        { for(int i = 0;; )
        {
            int n = fastformat_util_snprintf(result.data(), result.size() - 1, fmt, value);

            if(n > int(result.size()))
            {
                // An implementation that does it correctly, so just resize
                // to the desired size and go again

                // This'll only return false when exception-handling is
                // suppressed, but the code is correct without preprocessor
                // logic in either case, so leave as is
                if(!result.resize(n))
                {
                    result.truncate(0);
                    break;
                }
            }
            else if(n < 0)
            {
                if(maxRepeats == ++i)
                {
                    result.truncate(0);
                    break;
                }
                else
                {
                    // This'll only return false when exception-handling is
                    // suppressed, but the code is correct without preprocessor
                    // logic in either case, so leave as is
                    if(!result.resize(1u + result.size() * 2))
                    {
                        result.truncate(0);
                        break;
                    }
                }
            }
            else
            {
                // It's worked!
                //
                // We must nul-terminate, and resize, so that the shim string's
                // length is evaluated correctly
                result.truncate(size_t(n));

                break;
            }
        }}
    }

    return result;

#else /* ? STLSoft 1.x */

    /* Using STLSoft 1.9+ version of basic_shim_string */

    // We have to use the internal buffer, which means that we are
    // relying on the internal workings of shim string, which is ugly.
    // With 1.10, we don't need to do this.

    result_t                result(64);
    result_t::buffer_type&  buffer = result.get_buffer();

# ifndef STLSOFT_CF_THROW_BAD_ALLOC
    if(!buffer.empty())
# endif /* !STLSOFT_CF_THROW_BAD_ALLOC */
    {
        // Unlike integral types, the string representation of floating
        // point values do not have a known maximum length, so we must be
        // flexible.
        //
        // However, some implementations of snprintf() return -1 instead of
        // the length that would be required, so we cannot assume -1
        // indicates error. To handle this, we double the size of the buffer
        // up to four times, at which point we admit defeat.

        { for(int i = 0;; )
        {
            int n = fastformat_util_snprintf(&buffer[0], buffer.size() - 1, fmt, value);

            if(n > int(buffer.size() - 1))
            {
                // An implementation that does it correctly, so just resize
                // to the desired size and go again

                // This'll only return false when exception-handling is
                // suppressed, but the code is correct without preprocessor
                // logic in either case, so leave as is
                if(!buffer.resize(size_t(n) + 1u))
                {
                    buffer.resize(1u);
                    break;
                }
            }
            else if(n < 0)
            {
                if(maxRepeats == ++i)
                {
                    break;
                }
                else
                {
                    // This'll only return false when exception-handling is
                    // suppressed, but the code is correct without preprocessor
                    // logic in either case, so leave as is
                    if(!buffer.resize(1u + buffer.size() * 2))
                    {
                        buffer.resize(1u);
                        break;
                    }
                }
            }
            else
            {
                // It's worked!
                //
                // We must nul-terminate, and resize, so that the shim string's
                // length is evaluated correctly
                buffer[size_t(n)] = '\0';

                buffer.resize(size_t(n) + 1u);

                break;
            }
        }}
    }

    return result;
#endif /* STLSoft 1.x */
}