tetl 0.1.0
Embedded Template Library
Loading...
Searching...
No Matches
add_sat.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSL-1.0
2
3#ifndef TETL_NUMERIC_ADD_SAT_HPP
4#define TETL_NUMERIC_ADD_SAT_HPP
5
15
16namespace etl {
17
18namespace detail {
19
20template <etl::builtin_integer Int>
21[[nodiscard]] constexpr auto add_sat_fallback(Int x, Int y) noexcept -> Int
22{
23 constexpr auto min = etl::numeric_limits<Int>::min();
24 constexpr auto max = etl::numeric_limits<Int>::max();
25
26 if constexpr (sizeof(Int) < sizeof(int) and etl::same_as<decltype(x + y), int>) {
27 return Int(etl::clamp(x + y, int(min), int(max)));
28 } else if constexpr (sizeof(Int) < sizeof(unsigned) and etl::same_as<decltype(x + y), unsigned>) {
29 return Int(etl::clamp(x + y, unsigned(min), unsigned(max)));
30 } else if constexpr (sizeof(Int) == 2 and is_signed_v<Int>) {
32 } else if constexpr (sizeof(Int) == 2 and is_unsigned_v<Int>) {
34 } else if constexpr (sizeof(Int) == 4 and is_signed_v<Int>) {
36 } else if constexpr (sizeof(Int) == 4 and is_unsigned_v<Int>) {
38 } else {
39 if (x >= 0) {
40 if (max - x < y) {
41 return max;
42 }
43 } else {
44 if (y < min - x) {
45 return min;
46 }
47 }
48 return x + y;
49 }
50}
51
52} // namespace detail
53
55template <etl::builtin_integer Int>
56[[nodiscard]] constexpr auto add_sat(Int x, Int y) noexcept -> Int
57{
58#if defined(__GNUC__) or defined(__clang__)
59 constexpr auto min = etl::numeric_limits<Int>::min();
60 constexpr auto max = etl::numeric_limits<Int>::max();
61
62 if (Int sum{0}; not __builtin_add_overflow(x, y, &sum)) {
63 return sum;
64 }
65 if constexpr (is_unsigned_v<Int>) {
66 return max;
67 } else {
68 if (x > Int(0)) {
69 return max;
70 }
71 return min;
72 }
73#else
74 return etl::detail::add_sat_fallback(x, y);
75#endif
76}
77
78} // namespace etl
79
80#endif // TETL_NUMERIC_ADD_SAT_HPP
constexpr auto clamp(Type const &v, Type const &lo, Type const &hi, Compare comp) -> Type const &
If v compares less than lo, returns lo; otherwise if hi compares less than v, returns hi; otherwise r...
Definition clamp.hpp:17
constexpr auto min(Type const &a, Type const &b, Compare comp) noexcept -> Type const &
Returns the smaller of a and b, using a compare function.
Definition min.hpp:13
constexpr auto max(Type const &a, Type const &b, Compare comp) noexcept -> Type const &
Returns the greater of a and b, using a compare function.
Definition max.hpp:13
constexpr auto add_sat(Int x, Int y) noexcept -> Int
Definition add_sat.hpp:56
Definition adjacent_find.hpp:8
constexpr bool is_signed_v
Definition is_signed.hpp:30
TETL_BUILTIN_INT32 int32_t
Signed integer type with width of exactly 32 bits.
Definition int_t.hpp:17
TETL_BUILTIN_INT64 int64_t
Signed integer type with width of exactly 64 bits.
Definition int_t.hpp:20
TETL_BUILTIN_UINT64 uint64_t
Unsigned integer type with width of exactly 64 bits.
Definition uint_t.hpp:20
constexpr bool is_unsigned_v
Definition is_unsigned.hpp:33
TETL_BUILTIN_UINT32 uint32_t
Unsigned integer type with width of exactly 32 bits.
Definition uint_t.hpp:17
static constexpr auto max() noexcept
Definition numeric_limits.hpp:21
static constexpr auto min() noexcept
Definition numeric_limits.hpp:20