userver: userver/utils/numeric_cast.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
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>(), static_cast<impl::PrintableValue<T>>(input),
39 compiler::GetTypeName<U>()));
40 }
41 return result;
42}
43
44} // namespace utils
45
46USERVER_NAMESPACE_END