Using boost::numeric_cast<>
You could probably do something like this:
#include <limits>
template<typename Target, typename Source>
Target saturation_cast(Source src) {
try {
return boost::numeric_cast<Target>(src);
}
catch (const boost::negative_overflow &e) {
return std::numeric_limits<Target>::lowest();
/* Or, before C++11:
if (std::numeric_limits<Target>::is_integer)
return std::numeric_limits<Target>::min();
else
return -std::numeric_limits<Target>::max();
*/
}
catch (const boost::positive_overflow &e) {
return std::numeric_limits<Target>::max();
}
}
(For types that support it the error cases could also return -inf/+inf).
This way you let Boost's numeric_cast
determine if the value is out of bounds and can then react accordingly.