Notinlist
Notinlist

Reputation: 16640

boost::numeric_cast functionality without exception

We would like to have a checked numeric conversion between two numeric types without triggering exception throwing on failure. Something like:

bool numeric_cast(Source s, Target &t)

The boost error handling is hooked in our project with generating call stack and some other expensive things. I have places where the failure of the conversion is likely and I don't want to pay that high price on every failure.

Upvotes: 0

Views: 578

Answers (1)

ForEveR
ForEveR

Reputation: 55887

As I see from headers there is only one way to throw exception in numeric_cast - it's overflow.

You can write overflow_policy (or use silent_overflow_handler for this case). But you should write specialization for

template <typename Target, typename Source, typename EnableIf = void>
struct numeric_cast_traits
{
    typedef def_overflow_handler    overflow_policy;
    typedef UseInternalRangeChecker range_checking_policy;
    typedef Trunc<Source>           rounding_policy;
};

I'm not right... It looks to me, that it will be more simple to rewrite numeric_cast function really

template <typename Target, typename Source> 
inline Target numeric_cast( Source arg )
{
    typedef numeric::conversion_traits<Target, Source>   conv_traits;
    typedef numeric::numeric_cast_traits<Target, Source> cast_traits;
    typedef boost::numeric::converter
        <
            Target,
            Source, 
            conv_traits,
            typename cast_traits::overflow_policy, 
            typename cast_traits::rounding_policy, 
            boost::numeric::raw_converter< conv_traits >,
            typename cast_traits::range_checking_policy
        > converter;
    return converter::convert(arg);
}

It should look like

template <typename Target, typename Source> 
inline Target numeric_cast( Source arg )
{
    typedef numeric::conversion_traits<Target, Source>   conv_traits;
    typedef numeric::numeric_cast_traits<Target, Source> cast_traits;
    typedef boost::numeric::converter
        <
            Target,
            Source, 
            conv_traits,
            my_overflow_policy,
            typename cast_traits::rounding_policy,
            boost::numeric::raw_converter< conv_traits >,
            typename cast_traits::range_checking_policy
        > converter;
    return converter::convert(arg);
}

Also, you can define BOOST_NO_EXCEPTIONS and then it will simply throw, without boost::throw_exception.

Upvotes: 7

Related Questions