Sen API
Sen Libraries
Loading...
Searching...
No Matches
checked_conversions.h
Go to the documentation of this file.
1// === checked_conversions.h ===========================================================================================
2// Sen Infrastructure
3// Released under the Apache License v2.0 (SPDX-License-Identifier Apache-2.0).
4// See the LICENSE.txt file for more information.
5// © Airbus SAS, Airbus Helicopters, and Airbus Defence and Space SAU/GmbH/SAS.
6// =====================================================================================================================
7
8#ifndef SEN_CORE_BASE_CHECKED_CONVERSIONS_H
9#define SEN_CORE_BASE_CHECKED_CONVERSIONS_H
10
11// sen
15
16// std
17#include <cassert>
18#include <cmath>
19#include <limits>
20#include <string>
21#include <string_view>
22#include <tuple>
23#include <type_traits>
24
25namespace sen::std_util
26{
27
30void reportToStandardError(std::string_view message);
31
33{
34 static void report(const std::string_view message)
35 {
36 reportToStandardError(message);
37 SEN_ASSERT(false);
38 }
39};
40
42{
43 static void report(std::string_view message) { trace(std::string(message)); }
44};
45
47{
48 static void report(std::string_view message);
49};
50
52{
53 static void report(std::string_view message) { std::ignore = message; }
54};
55
58{
59 static void report(std::string_view message) { throwRuntimeError(std::string(message)); }
60};
61
62namespace impl
63{
74template <typename ToType, typename FromType, typename ReportPolicy = ReportPolicyIgnore>
75ToType conversionImpl(FromType from)
76{
77 if constexpr (std::is_same_v<ToType, bool>)
78 {
79 return static_cast<bool>(from);
80 }
81 else if constexpr (std::is_floating_point_v<ToType> || std::is_floating_point_v<FromType>)
82 {
83 if constexpr (std::is_same_v<FromType, ToType>)
84 {
85 return from;
86 }
87 else
88 {
89 // NaN compares false against every bound, so it reaches the cast below,
90 // where converting it to an integer is undefined. A floating-point target
91 // is left alone: there the cast is defined and NaN is worth keeping.
92 if constexpr (!std::is_floating_point_v<ToType>)
93 {
94 if (std::isnan(static_cast<float64_t>(from)))
95 {
96 ReportPolicy::report("the value is not a number");
97 return ToType {};
98 }
99 }
100
101 if (std::isless(static_cast<float64_t>(from), static_cast<float64_t>(std::numeric_limits<ToType>::lowest())))
102 {
103 ReportPolicy::report("the value is too small for the target type");
104 return std::numeric_limits<ToType>::lowest();
105 }
106
107 if (std::isgreater(static_cast<float64_t>(from), static_cast<float64_t>(std::numeric_limits<ToType>::max())))
108 {
109 ReportPolicy::report("the value is too large for the target type");
110 return std::numeric_limits<ToType>::max();
111 }
112
113 return static_cast<ToType>(from);
114 }
115 }
116 else
117 {
118 if (sen::std_util::cmp_less(from, std::numeric_limits<ToType>::lowest()))
119 {
120 ReportPolicy::report("the value is too small for the target type");
121 return std::numeric_limits<ToType>::lowest();
122 }
123
124 if (sen::std_util::cmp_greater(from, std::numeric_limits<ToType>::max()))
125 {
126 ReportPolicy::report("the value is too large for the target type");
127 return std::numeric_limits<ToType>::max();
128 }
129
130 return static_cast<ToType>(from);
131 }
132}
133
134} // namespace impl
135
148template <typename ToType, typename ReportPolicy = ReportPolicyAssertion, typename FromType>
149[[nodiscard]] ToType checkedConversion(FromType from)
150{
152}
153
166template <typename ToType, typename ReportPolicy = ReportPolicyIgnore, typename FromType>
167[[nodiscard]] ToType ignoredLossyConversion(FromType from)
168{
170}
171
172} // namespace sen::std_util
173
174#endif // SEN_CORE_BASE_CHECKED_CONVERSIONS_H
The following macros implement a replacement of assert that is connected to the overall fault handlin...
#define SEN_ASSERT(expr)
Checks an intermediate result produced by a procedure (not an input or output). NOLINTNEXTLINE.
Definition assert.h:41
void throwRuntimeError(const std::string &err)
Throws an exception that attempts to collect the stack trace.
void trace()
Prints the current stack trace to stderr.
double float64_t
Definition numbers.h:17
Definition checked_conversions.h:63
ToType conversionImpl(FromType from)
Safely convert between two different integral types. If the value stored in from cannot be represente...
Definition checked_conversions.h:75
Definition bits.h:26
ToType ignoredLossyConversion(FromType from)
Safely convert between two different integral types. If the value stored in from cannot be represente...
Definition checked_conversions.h:167
void reportToStandardError(std::string_view message)
Writes to standard error. Out of line so this header, which every user of the conversion helpers incl...
constexpr bool cmp_greater(T t, U u) noexcept
Definition integer_compare.h:83
constexpr bool cmp_less(T t, U u) noexcept
Definition integer_compare.h:63
ToType checkedConversion(FromType from)
Safely convert between two different integral types. If the value stored in from cannot be represente...
Definition checked_conversions.h:149
Definition checked_conversions.h:33
static void report(const std::string_view message)
Definition checked_conversions.h:34
Definition checked_conversions.h:52
static void report(std::string_view message)
Definition checked_conversions.h:53
Definition checked_conversions.h:47
static void report(std::string_view message)
Refuses the conversion instead of returning a clamped value.
Definition checked_conversions.h:58
static void report(std::string_view message)
Definition checked_conversions.h:59
Definition checked_conversions.h:42
static void report(std::string_view message)
Definition checked_conversions.h:43