I have a number of places in which I wish to use std::enable_if certain templates only if simple static cast from template type A to template type B (both of which are numeric) will not result in any loss of data. However I am not sure what existing type_traits, if any, I should use or if I should write my own.
For example, casting from uint16_t to uint32_t, from float to double, even from int to double is not going to lose any precision or negative sign. But casting from double to int or int to uint32_t would obviously be problematic.
I've monkeyed around a bit, testing is_trivially_constructible, is_assignable, is_constructible, etc etc. but I don't see one that will warn me if I try to go from float to int.
Am I missing something that's in the library currently or should I just write it myself?
(I already know how to write it. It's simple. Just want to make sure I don't reinvent the wheel).
I am answering my own question this because someone asked me to post my trait and comments don't seem to have formatting.
Some notes about why I did what I did here:
FINAL VERSION (edited 3-FEB-2018)
StackOverflow tells me that someone just gave me points for this today. So I guess people might actually be using it. In that case, I suppose I should present my entire, current version which addresses the flaws I mentioned above.
I'm sure there are better ways to do this and I know C++14/17/etc allow me to do this far less verbosely but I was forced to make this work on VS versions all the way back to VS2012 so I couldn't take advantage of alias templates and the like.
Therefore I did this by writing some helper traits and then composed my final "is_safe_numeric_cast" trait from them. I think it makes things more readable.
I think the header
<limits>
gives you the primitives you'll need to build the full traits.Here's a trait to check whether one integral would narrow when converted to another (of similar signed-ness):