Does Boost or the standard library support the ability to check if casting is lossless?

I am looking for a standard library or Boost function that can lead a number to another primitive type without loss and somehow tell me whether there was lossless casting (or throw an exception if it is not). Here are some examples:

auto x = lossless_cast<double>(1u); // ok, double can represent 1 auto x = lossless_cast<int>(1.2); // fail, int can't represent 1.2 auto x = lossless_cast<int>(1E200); // fail, int can't represent 1E200 

boost::numeric_cast is close in that it picks up throws dropped out of the numerical range of the target type, but not if they are lossless, but within the target type (see my second example).

There is an SO question for the C language that provides some manual solutions for this problem , but I am after solving the boost or standard library, mainly with the following functions:

 template <typename out, typename in> out lossless_cast(in in_value) { out out_value = static_cast<out>(in_value); if (static_cast<in>(out_value) != in_value) throw; // some exception return out_value; } 

Is this functionality available?

+6
source share
1 answer

I am sure that there is nothing pre-rolled in the standard and I do not know anything in boost, but it is a large library. Any implementation using casting should be careful with undefined behavior for values ​​outside the range of 4.9 [conv.fpint], but since boost::numeric_cast<> supposedly handles this, you can use:

 template <typename U, typename T> inline U is_lossless(T t) { U u = boost::numeric_cast<U>(t); T t2 = boost::numeric_cast<T>(u); // throw if now out-of-range if (t != t2) throw whatever-you-like; return u; } 

The need for numeric_cast<> when restoring t2 least obvious: it ensures that u is still in range, as this is possible for a value other than say int64_t x to double y for success, but approximate with an integral value in y than outside range for int64_t , so dropping from double has undefined behavior.

The legality / reliability of the above requires that boost::numeric_cast<> correctly avoid undefined behavior that I have not tested yet.

+3
source

Source: https://habr.com/ru/post/986938/


All Articles