Suppose in the below function:
template<typename T, typename U>
bool IsRepresentable(U u);
that T
and U
are non-bool integral types.
If the integer value of u
is representable in T
then IsRepresentable
should return true
, otherwise it should return false
.
What's the best way to implement IsRepresentable
in C++17? (or is there an exisiting similar function in the standard library?)
(My current thinking was a constexpr if-else chain around std::is_signed
/ sizeof
/ std::numeric_limits
- but am I missing some easier or more straightforward way?)
The best I can imagine, in a simple way, is check if T(u) == u
and the signs of u
and T(u)
are the same
I mean something as
template <typename T, typename U>
bool IsRepresentable (U const & u)
{ return (T(u) == u) && (T(u) > T(0)) == (u > U(0)); }
As an alternative to accepted answer, I suggest You use a boost::numeric_cast. Sample usage:
https://coliru.stacked-crooked.com/a/c39d5c9e7aed26ad
#include <boost/numeric/conversion/cast.hpp>
#include <iostream>
int main()
{
using boost::numeric_cast;
using boost::numeric::bad_numeric_cast;
using boost::numeric::positive_overflow;
using boost::numeric::negative_overflow;
try
{
int i=42;
short s=numeric_cast<short>(i); // This conversion succeeds (is in range)
}
catch(negative_overflow& e) {
std::cout << e.what();
}
catch(positive_overflow& e) {
std::cout << e.what();
}
try
{
int i=70000;
short s=numeric_cast<short>(i); // ad numeric conversion: positive overflow
}
catch(negative_overflow& e) {
std::cout << e.what();
}
catch(positive_overflow& e) {
std::cout << e.what();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With