Search code examples
c++boostboost-spirit

boost::spirit::qi - whats wrong with this hex parse?


Consider following code:

{
        std::string input = "FFFFFFF";
        int result = 0;
        auto itBeg = input.cbegin();
        auto itEnd = input.cend();
        if(!bsq::parse(itBeg, itEnd, bsq::int_parser<int, 16>(), result) || itBeg != itEnd)
        {
            throw std::exception();
        }
        std::cout << input << " means " << result << std::endl;
    }
    {
        std::string input = "FFFFFFFF";
        int result = 0;
        auto itBeg = input.cbegin();
        auto itEnd = input.cend();
        if(!bsq::parse(itBeg, itEnd, bsq::hex, result) || itBeg != itEnd)
        {
            throw std::exception();
        }
        std::cout << input << " means " << result << std::endl;
    }
    {
        std::string input = "FFFFFFFF";
        int result = 0;
        auto itBeg = input.cbegin();
        auto itEnd = input.cend();
        if(!bsq::parse(itBeg, itEnd, bsq::int_parser<int, 16>(), result) || itBeg != itEnd)
        {
            throw std::exception();
        }
        std::cout << input << " means " << result << std::endl;
    }

the first parse works fine on 0xFFFFFFF (note, 7 hex digits) second one works ok on 0xFFFFFFFF (8 hex digits) the third one fails and I cant understand why. isnt int_parser<T, 16> is essentially the same as bsq::hex?
Live on Coliru


Solution

  • the third one fails and I cant understand why

    You're using a signed parser, and hitting a type width boundary. Change it to:

    bsq::uint_parser<unsigned int, 16>(), result)
    

    (live demo)


    isnt int_parser<T, 16> is essentially the same as bsq::hex?

    No.

    The documentation says that boost::spirit::qi::hex will

    Parse an unsigned integer using [..] radix 16