#ifndef BOOST_NUMERIC_CAST_HPP #define BOOST_NUMERIC_CAST_HPP #include #include /* Contributed by Kevlin Henney (kevlin@acm.org) numeric_cast A static_cast, implicit_cast or implicit conversion will not detect failure to preserve range for numeric casts. The numeric_cast template function is intended for conversions between numeric types and is similar to static_cast and certain (dubious) implicit conversions in this respect, except that they detect loss of numeric range. numeric_cast throws an exception when a runtime value preservation check fails. The requirements on the argument and result types are: * Both argument and result types are CopyConstructible [20.1.3]. * Both argument and result types are Numeric, which is defined by numeric_limits<>::is_specialized being true. * Ther argument can be converted to the result type using static_cast. numeric_cast synopsis class bad_numeric_cast : public std::bad_cast {...}; template inline bool is_numeric_castable(Source arg); // returns: true iff, in converting arg from Source to Target, // there is no loss of negative range, no underflow, and no // overflow, as determined by numeric_limits template inline Target numeric_cast(Source arg); // throws: bad_numeric_cast if !is_numeric_castable(arg) // returns: static_cast(arg) numeric_cast example #include void ariane(double vx) { ... unsigned short dx = numeric_cast(vx); ... } */ namespace boost // numeric_cast and supporting players { // exception used to indicate runtime numeric_cast failure class bad_numeric_cast : public std::bad_cast { public: // constructors, destructors and assignment operator defaulted // function inlined for brevity and consistency with rest of library virtual const char *what() const { return "bad numeric cast: loss of range in numeric_cast"; } }; // predicate function to determine numeric castability template inline bool is_numeric_castable(Source arg) { // typedefs abbreviating respective trait classes typedef std::numeric_limits arg_traits; typedef std::numeric_limits result_traits; // typedefs that act as compile time assertions // (to be replaced by boost compile time assertions // as and when they become available and are stable) typedef bool argument_must_be_numeric[arg_traits::is_specialized]; typedef bool result_must_be_numeric[result_traits::is_specialized]; // runtime predicate implementation return !(arg < 0 && !result_traits::is_signed) && // loss of negative range !(arg_traits::is_signed && arg < result_traits::min()) && // underflow !(arg > result_traits::max()); // overflow } // cast operator function template inline Target numeric_cast(Source arg) { if(!is_numeric_castable(arg)) throw bad_numeric_cast(); return static_cast(arg); } } #endif