Function atoi

Synopsis

#include <src/c4/charconv.hpp>

template <class T>
bool atoi(csubstr str, T *C4_RESTRICT v)

Description

Convert a trimmed string to a signed integral value. The string can be formatted as decimal, binary (prefix 0b or 0B), octal (prefix 0o or 0O) or hexadecimal (prefix 0x or 0X). Strings with leading zeroes are considered as decimal. Every character in the input string is read for the conversion; it must not contain any leading or trailing whitespace.

Returns
true if the conversion was successful.
Note
overflow is not detected: the return status is true even if the conversion would return a value outside of the type's range, in which case the result will wrap around the type's range. This is similar to, just like the native.
See
atoi_first() if the string is not trimmed to the value to read.

Mentioned in

Source

Lines 765-856 in src/c4/charconv.hpp.

template<class T>
bool atoi(csubstr str, T * C4_RESTRICT v)
{
    C4_STATIC_ASSERT(std::is_integral<T>::value);
    C4_STATIC_ASSERT(std::is_signed<T>::value);

    if(C4_UNLIKELY(str.len == 0))
    {
        return false;
    }

    T sign = 1;
    size_t start = 0;
    if(str.str[0] == '-')
    {
        if(C4_UNLIKELY(str.len == 1))
        {
            return false;
        }
        ++start;
        sign = -1;
    }

    if(str.str[start] != '0')
    {
        if(C4_UNLIKELY( ! read_dec(str.sub(start), v)))
        {
            return false;
        }
    }
    else
    {
        if(str.len == start+1)
        {
            *v = 0; // because the first character is 0
            return true;
        }
        else
        {
            char pfx = str.str[start+1];
            if(pfx == 'x' || pfx == 'X') // hexadecimal
            {
                if(C4_UNLIKELY(str.len <= start + 2))
                {
                    return false;
                }
                if(C4_UNLIKELY( ! read_hex(str.sub(start + 2), v)))
                {
                    return false;
                }
            }
            else if(pfx == 'b' || pfx == 'B') // binary
            {
                if(C4_UNLIKELY(str.len <= start + 2))
                {
                    return false;
                }
                if(C4_UNLIKELY( ! read_bin(str.sub(start + 2), v)))
                {
                    return false;
                }
            }
            else if(pfx == 'o' || pfx == 'O') // octal
            {
                if(C4_UNLIKELY(str.len <= start + 2))
                {
                    return false;
                }
                if(C4_UNLIKELY( ! read_oct(str.sub(start + 2), v)))
                {
                    return false;
                }
            }
            else
            {
                // we know the first character is 0
                auto fno = str.first_not_of('0', start + 1);
                if(fno == csubstr::npos)
                {
                    *v = 0;
                    return true;
                }
                if(C4_UNLIKELY( ! read_dec(str.sub(fno), v)))
                {
                    return false;
                }
            }
        }
    }
    *v *= sign;
    return true;
}





Add Discussion as Guest

Log in