userver: userver/utils/numeric_cast.hpp Source File
Loading...
Searching...
No Matches
numeric_cast.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/utils/numeric_cast.hpp
4/// @brief @copybrief utils::numeric_cast
5
6#include <stdexcept>
7
8#include <fmt/format.h>
9
10#include <userver/compiler/demangle.hpp>
11
12USERVER_NAMESPACE_BEGIN
13
14namespace utils {
15
16namespace impl {
17
18template <typename T>
19using PrintableValue = std::conditional_t<(sizeof(T) > 1), T, int>;
20
21}
22
23/// Detects loss of range when a numeric type is converted, and throws an
24/// exception if the range cannot be preserved
25///
26/// ## Example usage:
27///
28/// @snippet utils/numeric_cast_test.cpp Sample utils::numeric_cast usage
29template <typename U, typename T>
30constexpr U numeric_cast(T input) {
31 static_assert(std::is_integral_v<T>);
32 static_assert(std::is_integral_v<U>);
33
34 U result = input;
35 if (static_cast<T>(result) != input || ((result < 0) != (input < 0))) {
36 throw std::runtime_error(fmt::format(
37 "Failed to convert {} {} into {} due to integer overflow",
38 compiler::GetTypeName<T>(),
39 static_cast<impl::PrintableValue<T>>(input),
40 compiler::GetTypeName<U>()
41 ));
42 }
43 return result;
44}
45
46} // namespace utils
47
48USERVER_NAMESPACE_END