How to check overflow in duration_cast

I need to convert one kind of std::chrono::duration to another type, but I need to know when such a conversion is impossible, because the value will not be displayed.

I did not find any tools in the standard library to check this. The cppreference page does not indicate what happens if the value is out of range, only floating point to integer conversion can be undefined. (in my case, I need to convert from an integer to an integer).

+5
source share
1 answer

There is not a one-time solution, but a solution that is suitable for many use cases, is to use a double based on duration to check the range. Maybe something like:

 #include <chrono> #include <iostream> #include <stdexcept> template <class Duration, class Rep, class Period> Duration checked_convert(std::chrono::duration<Rep, Period> d) { using namespace std::chrono; using S = duration<double, typename Duration::period>; constexpr S m = Duration::min(); constexpr SM = Duration::max(); S s = d; if (s < m || s > M) throw std::overflow_error("checked_convert"); return duration_cast<Duration>(s); } int main() { using namespace std::chrono; std::cout << checked_convert<nanoseconds>(10'000h).count() << "ns\n"; std::cout << checked_convert<nanoseconds>(10'000'000h).count() << "ns\n"; } 

For me, these outputs are:

 36000000000000000ns libc++abi.dylib: terminating with uncaught exception of type std::overflow_error: checked_convert 
+2
source

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


All Articles