Lior Kogan
Lior Kogan

Reputation: 20688

Catching overflows with boost::lexical_cast

I want to catch boost::lexicat_cast overflows the same way I can catch boost::numeric_cast overflows. Is it possible?

The first try block below throws a boost::numeric::negative_overflow.

The second block does not throw an exception (isn't this a lexical_cast bug?)

Though unsigned int is used in the example below, I am looking for a method that would work for any integer type.

#include <boost/numeric/conversion/cast.hpp>
#include <boost/lexical_cast.hpp>

int main()
{
    unsigned int i;

    try
    {
        int d =-23;
        i = boost::numeric_cast<unsigned int>(d);
    }
    catch (const boost::numeric::bad_numeric_cast& e)
    {
        std::cout << e.what() << std::endl;
    }

    std::cout << i << std::endl; // 4294967273

    try
    {
        char c[] = "-23";
        i = boost::lexical_cast<unsigned int>(c);
    }
    catch (const boost::bad_lexical_cast& e)
    {
        std::cout << e.what() << std::endl;
    }

    std::cout << i << std::endl; // 4294967273

    return 0;
}

Upvotes: 1

Views: 363

Answers (1)

sehe
sehe

Reputation: 394054

You could write what you want using a modicum of Spirit:

Live On Coliru

#include <boost/spirit/include/qi.hpp>
#include <iostream>

template <typename Out, typename In> Out numeric_lexical_cast(In const& range) {

    Out value;

    {
        using namespace boost::spirit::qi;
        using std::begin;
        using std::end;

        if (!parse(begin(range), end(range), auto_ >> eoi, value)) {
            struct bad_numeric_lexical_cast : std::domain_error {
                bad_numeric_lexical_cast() : std::domain_error("bad_numeric_lexical_cast") {}
            };
            throw bad_numeric_lexical_cast();
        }
    }

    return value;
}

int main()
{
    for (std::string const& input : { "23", "-23" }) try {
        std::cout << " == input: " << input << " -> ";
        auto i = numeric_lexical_cast<unsigned int>(input);
        std::cout << i << std::endl;
    } catch (std::exception const& e) {
        std::cout << e.what() << std::endl;
    }
}

Prints

 == input: 23 -> 23
 == input: -23 -> bad_numeric_lexical_cast

Upvotes: 1

Related Questions